diff options
author | Emiliano Ciavatta | 2020-09-23 20:00:56 +0000 |
---|---|---|
committer | Emiliano Ciavatta | 2020-09-23 20:00:56 +0000 |
commit | 04ee54be31931111bf89e50e4e54ac92b9a19d7a (patch) | |
tree | 61bbec3298f74bca268ace675141d1dd42ec4c36 | |
parent | 8d07bfe5f17534b7301a064aeaf8ed8071f10a40 (diff) |
Add StringField
-rw-r--r-- | frontend/src/components/fields/StringField.js | 53 | ||||
-rw-r--r-- | frontend/src/components/fields/StringField.scss | 121 | ||||
-rw-r--r-- | frontend/src/utils.js | 4 |
3 files changed, 131 insertions, 47 deletions
diff --git a/frontend/src/components/fields/StringField.js b/frontend/src/components/fields/StringField.js index 09fe24d..aa23fe8 100644 --- a/frontend/src/components/fields/StringField.js +++ b/frontend/src/components/fields/StringField.js @@ -1,26 +1,55 @@ import React, {Component} from 'react'; import './StringField.scss'; +import {randomClassName} from "../../utils"; const classNames = require('classnames'); class StringField extends Component { render() { + const id = `field-${this.props.name || "noname"}-${randomClassName()}`; + const active = this.props.active || false; + const invalid = this.props.invalid || false; + const small = this.props.small || false; + const inline = this.props.inline || false; + const name = this.props.name || null; + const value = this.props.value || ""; + const type = this.props.type || "text"; + const error = this.props.error || null; + const handler = (e) => { + if (this.props.onChange) { + if (e == null) { + this.props.onChange(""); + } else { + this.props.onChange(e.target.value); + } + } + }; + return ( - <div className={classNames("field", "d-inline-block", {"field-active" : this.props.isActive}, - {"field-invalid": this.props.isInvalid})}> - <div className="input-group"> - <div className="field-name-wrapper"> - <span className="field-name" id={`field-${this.props.name}`}>{this.props.name}:</span> + <div className={classNames("field", "string-field", {"field-active" : active}, + {"field-invalid": invalid}, {"field-small": small}, {"field-inline": inline})}> + <div className="field-wrapper"> + { name && + <div className="field-name"> + <label id={id}>{name}:</label> + </div> + } + <div className="field-input"> + <div className="field-value"> + <input type={type} placeholder={this.props.defaultValue} aria-label={name} + aria-describedby={id} onChange={handler} value={value} /> + </div> + { value !== "" && + <div className="field-clear"> + <span onClick={() => handler(null)}>del</span> + </div> + } </div> - <input placeholder={this.props.defaultValue} aria-label={this.props.name} - aria-describedby={`filter-${this.props.name}`} className="field-value" - onChange={this.props.onValueChanged} value={this.props.value} /> </div> - - { this.props.active && - <div className="field-clear"> - <span className="filter-delete-icon" onClick={() => this.props.onValueChanged("")}>del</span> + {error && + <div className="field-error"> + error: {error} </div> } </div> diff --git a/frontend/src/components/fields/StringField.scss b/frontend/src/components/fields/StringField.scss index 7efac56..674815f 100644 --- a/frontend/src/components/fields/StringField.scss +++ b/frontend/src/components/fields/StringField.scss @@ -1,66 +1,117 @@ @import '../../colors.scss'; .field { - margin: 0 10px; - position: relative; - - .field-name-wrapper { - background-color: $color-primary-2; - padding: 3px 7px; - border-top-left-radius: 5px; - border-bottom-left-radius: 5px; - } + font-size: 0.9em; .field-name { - font-size: 13px; + label { + margin: 0; + } } - .field-value { - font-size: 13px; - padding-left: 0; - border-radius: 5px; + .field-input { + position: relative; - &:focus { + .field-value input { background-color: $color-primary-2; + width: 100%; + border: none; + color: $color-primary-4; + border-radius: 5px; + padding: 7px 10px; + + &:focus { + background-color: $color-primary-1; + color: $color-primary-4; + box-shadow: none; + outline: none; + } + + &[readonly] { + background-color: $color-primary-2; + border: none; + color: $color-primary-4; + } + + &[readonly]:focus { + background-color: $color-primary-1; + color: $color-primary-4; + box-shadow: none; + } } } &.field-active { - .field-name-wrapper { - background-color: $color-primary-4; - color: $color-primary-3; + &.field-inline .field-name { + background-color: $color-primary-4 !important; + color: $color-primary-3 !important; } - .field-value { - background-color: $color-primary-4; - color: $color-primary-3; + .field-value input { + background-color: $color-primary-4 !important; + color: $color-primary-3 !important; } } &.field-invalid { - .field-name-wrapper { - background-color: $color-secondary-2; - color: $color-primary-4; + &.field-inline .field-name { + background-color: $color-secondary-2 !important; + color: $color-primary-4 !important; } - .field-value { - background-color: $color-secondary-2; - color: $color-primary-4; + .field-value input { + background-color: $color-secondary-2 !important; + color: $color-primary-4 !important; + } + } + + &.field-small { + font-size: 0.8em; + } + + &.field-inline .field-wrapper { + display: flex; + + .field-name { + background-color: $color-primary-2; + padding: 6px 7px; + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; + } + + .field-input { + width: 100%; + + input { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + padding-left: 3px; + } + } + + &:focus-within .field-name { + background-color: $color-primary-1; } } - .field-delete { + .field-clear { position: absolute; - right: 10px; - top: 10px; + right: 8px; + top: 8px; z-index: 10; - font-size: 11px; + font-size: 0.9em; + font-weight: 600; letter-spacing: -0.5px; - color: $color-primary-2; cursor: pointer; + } - .field-delete-icon { - font-weight: 800; - } + &.field-active .field-clear { + color: $color-primary-2; + } + + .field-error { + padding: 5px 10px; + font-size: 0.9em; + color: $color-secondary-0; } } diff --git a/frontend/src/utils.js b/frontend/src/utils.js index 4991755..c81cdfc 100644 --- a/frontend/src/utils.js +++ b/frontend/src/utils.js @@ -82,3 +82,7 @@ export function formatSize(size) { return `${(size / 1000000).toFixed(1)}M`; } } + +export function randomClassName(size = 10) { + return Math.random().toString(36).substring(size); +} |