diff --git a/components/atom/helpText/demo/package.json b/components/atom/helpText/demo/package.json index 9c30b8a8d3..cefbd64a69 100644 --- a/components/atom/helpText/demo/package.json +++ b/components/atom/helpText/demo/package.json @@ -13,7 +13,7 @@ "dependencies": { "@s-ui/react-atom-checkbox": "2", "@s-ui/react-atom-icon": "1", - "@s-ui/react-atom-input": "5", + "@s-ui/react-atom-input": "5.22.0-beta.0", "@s-ui/react-atom-label": "1", "@s-ui/react-atom-textarea": "2" } diff --git a/components/atom/input/demo/articles/ArticleAddonAndIcon.js b/components/atom/input/demo/articles/ArticleAddonAndIcon.js new file mode 100644 index 0000000000..15fcabe705 --- /dev/null +++ b/components/atom/input/demo/articles/ArticleAddonAndIcon.js @@ -0,0 +1,175 @@ +import {useState} from 'react' + +import PropTypes from 'prop-types' + +import { + AntDesignIcon, + Article, + Cell, + Code, + Grid, + H2, + Input, + ListItem, + Paragraph, + RadioButton, + RadioButtonGroup, + UnorderedList +} from '@s-ui/documentation-library' + +import AtomInput from '../../src/index.js' + +const ArticleAddonAndIcon = ({className}) => { + const [state, setState] = useState({}) + const {icon, iconValue, rightAddon, leftAddon} = state + const setStatus = (newState = {}) => setState({...state, ...newState}) + const valueIcon = iconValue ? ( + + ) : null + return ( +
+

Addon and Icon

+ + Input offers the possibility to add icons and contents on its left or + right positions + + + + leftAddon and rightAddon: use it as a label + for the input field + + + leftIcon and rightIcon: use it as a valid + symbol for the field + + + This field props can be combined all together. + + + + + + { + setStatus({icon: value}) + }} + fullWidth + > + + + + + + + setStatus({ + iconValue: value + }) + } + fullWidth + > + + } + /> + + } + /> + + } + /> + + } + /> + + } + /> + + } + /> + + } + /> + + } + /> + + + + setStatus({leftAddon: event.target.value})} + /> + + + setStatus({rightAddon: event.target.value})} + /> + + +
+ ) +} + +ArticleAddonAndIcon.propTypes = { + className: PropTypes.string +} + +ArticleAddonAndIcon.displayName = 'ArticleAddonAndIcon' + +export default ArticleAddonAndIcon diff --git a/components/atom/input/demo/articles/ArticleBorderless.js b/components/atom/input/demo/articles/ArticleBorderless.js new file mode 100644 index 0000000000..e43dffd126 --- /dev/null +++ b/components/atom/input/demo/articles/ArticleBorderless.js @@ -0,0 +1,58 @@ +import {useState} from 'react' + +import PropTypes from 'prop-types' + +import { + Article, + Cell, + Code, + Grid, + H2, + Paragraph, + RadioButton +} from '@s-ui/documentation-library' + +import AtomInput from '../../src/index.js' + +const ArticleBorderless = ({className}) => { + const [border, setBorder] = useState(true) + const [mode, setMode] = useState('light') + return ( +
+

No border

+ + The border of the input can be removed using the boolean prop{' '} + noBorder + + + + setBorder(!value)} + /> + + + setMode(value ? 'dark' : 'light')} + /> + + + + + +
+ ) +} + +ArticleBorderless.propTypes = { + className: PropTypes.string +} + +ArticleBorderless.displayName = 'ArticleBorderless' + +export default ArticleBorderless diff --git a/components/atom/input/demo/articles/ArticleDefault.js b/components/atom/input/demo/articles/ArticleDefault.js new file mode 100644 index 0000000000..d6f7f9e72e --- /dev/null +++ b/components/atom/input/demo/articles/ArticleDefault.js @@ -0,0 +1,25 @@ +import PropTypes from 'prop-types' + +import {Article, H2, Paragraph} from '@s-ui/documentation-library' + +import AtomInput from '../../src/index.js' + +const ArticleDefault = ({className}) => ( +
+

Default

+ + By default, the element gets the following look and feel. + +
+ +
+
+) + +ArticleDefault.propTypes = { + className: PropTypes.string +} + +ArticleDefault.displayName = 'ArticleDefault' + +export default ArticleDefault diff --git a/components/atom/input/demo/articles/ArticleDisabledReadOnly.js b/components/atom/input/demo/articles/ArticleDisabledReadOnly.js new file mode 100644 index 0000000000..589a875c73 --- /dev/null +++ b/components/atom/input/demo/articles/ArticleDisabledReadOnly.js @@ -0,0 +1,52 @@ +import PropTypes from 'prop-types' + +import { + Article, + Cell, + Code, + Grid, + H2, + Label, + Paragraph +} from '@s-ui/documentation-library' + +import AtomInput from '../../src/index.js' + +const ArticleDisabledReadOnly = ({className}) => { + return ( +
+

Disable and ReadOnly

+ + Input provides two different modes that blocks the component behavior + the difference between them is the appearance. + + + The developer can disable the component using the disabled{' '} + boolean prop. It can be blocked also using the readOnly{' '} + boolean propm, but it will look like the default input. + + + + + + + + + + + + + + + +
+ ) +} + +ArticleDisabledReadOnly.propTypes = { + className: PropTypes.string +} + +ArticleDisabledReadOnly.displayName = 'ArticleDisabledReadOnly' + +export default ArticleDisabledReadOnly diff --git a/components/atom/input/demo/articles/ArticleErrorStatus.js b/components/atom/input/demo/articles/ArticleErrorStatus.js new file mode 100644 index 0000000000..40ddd161c6 --- /dev/null +++ b/components/atom/input/demo/articles/ArticleErrorStatus.js @@ -0,0 +1,53 @@ +import PropTypes from 'prop-types' + +import { + Article, + Cell, + Code, + Grid, + H2, + Label, + Paragraph +} from '@s-ui/documentation-library' + +import AtomInput from '../../src/index.js' + +const ArticleErrorStatus = ({className}) => { + return ( +
+

Error State

+ + Input can show its error mode using the boolean prop{' '} + errorStatus + + + + + + + + + + + + + + + + + + + + + +
+ ) +} + +ArticleErrorStatus.propTypes = { + className: PropTypes.string +} + +ArticleErrorStatus.displayName = 'ArticleErrorStatus' + +export default ArticleErrorStatus diff --git a/components/atom/input/demo/articles/ArticleInlineForm.js b/components/atom/input/demo/articles/ArticleInlineForm.js new file mode 100644 index 0000000000..e4a39255ff --- /dev/null +++ b/components/atom/input/demo/articles/ArticleInlineForm.js @@ -0,0 +1,34 @@ +import PropTypes from 'prop-types' + +import { + Article, + Button, + Code, + H2, + H3, + Paragraph +} from '@s-ui/documentation-library' + +import AtomInput from '../../src/index.js' + +const ArticleInlineForm = ({className}) => ( +
+

Inline Form

+

Deprecated

+ + Input have its own way of provide a submision using the{' '} + button prop, you can pass a React node. + + Send} + /> +
+) + +ArticleInlineForm.propTypes = { + className: PropTypes.string +} + +ArticleInlineForm.displayName = 'ArticleInlineForm' + +export default ArticleInlineForm diff --git a/components/atom/input/demo/articles/ArticlePlaceholderValueAndDefaultValue.js b/components/atom/input/demo/articles/ArticlePlaceholderValueAndDefaultValue.js new file mode 100644 index 0000000000..9a2f609cdb --- /dev/null +++ b/components/atom/input/demo/articles/ArticlePlaceholderValueAndDefaultValue.js @@ -0,0 +1,89 @@ +import {useState} from 'react' + +import PropTypes from 'prop-types' + +import { + Article, + Cell, + Code, + Grid, + H2, + Input, + Label, + Paragraph +} from '@s-ui/documentation-library' + +import AtomInput from '../../src/index.js' + +const ArticlePlaceholderValueAndDefaultValue = ({className}) => { + const [placeholder, setPlaceholder] = useState('placeholder') + const [value, setValue] = useState(undefined) + const [defaultValue, setDefaultValue] = useState('default value') + return ( +
+

value, defaultValue and placeholder

+ + value: controlled component. + + + defaultValue: for uncontrolled component + + + placeholder: the placeholder for empty component value + hint. + + + + + + + + + + + + + setPlaceholder(event.target.value)} + /> + + + setDefaultValue(event.target.value)} + /> + + + setValue(event.target.value)} + /> + + + + + + setValue(event.target.value)} + /> + + +
+ ) +} + +ArticlePlaceholderValueAndDefaultValue.propTypes = { + className: PropTypes.string +} + +ArticlePlaceholderValueAndDefaultValue.displayName = + 'ArticlePlaceholderValueAndDefaultValue' + +export default ArticlePlaceholderValueAndDefaultValue diff --git a/components/atom/input/demo/articles/ArticleShape.js b/components/atom/input/demo/articles/ArticleShape.js new file mode 100644 index 0000000000..465298439a --- /dev/null +++ b/components/atom/input/demo/articles/ArticleShape.js @@ -0,0 +1,79 @@ +import {Fragment} from 'react' + +import PropTypes from 'prop-types' + +import { + Article, + Cell, + Code, + Grid, + H2, + Label, + Paragraph +} from '@s-ui/documentation-library' + +import AtomInput, {inputShapes, inputSizes} from '../../src/index.js' + +const ArticleShape = ({className}) => ( +
+

Shape

+ + The border radius of the input can be set using the shape{' '} + property. + + + {Object.entries({default: undefined, ...inputShapes}).map(([key]) => ( + + + + ))} + {Object.entries({default: undefined, ...inputShapes}).map( + ([key, value]) => ( + + + + ) + )} + + + In even preserves its own shaping combined with addons and sizes also. + + + + {Object.entries({default: undefined, ...inputShapes}).map(([key]) => ( + + + + ))} + {Object.entries({default: undefined, ...inputSizes}).map( + ([sizeKey, sizeValue]) => ( + + + + + {Object.entries({default: undefined, ...inputShapes}).map( + ([shapeKey, shapeValue]) => ( + + left} + rightAddon={right} + /> + + ) + )} + + ) + )} + +
+) + +ArticleShape.propTypes = { + className: PropTypes.string +} + +ArticleShape.displayName = 'ArticleShape' + +export default ArticleShape diff --git a/components/atom/input/demo/articles/ArticleSize.js b/components/atom/input/demo/articles/ArticleSize.js new file mode 100644 index 0000000000..b950df1d47 --- /dev/null +++ b/components/atom/input/demo/articles/ArticleSize.js @@ -0,0 +1,51 @@ +import PropTypes from 'prop-types' + +import { + Article, + Cell, + Code, + Grid, + H2, + Label, + Paragraph +} from '@s-ui/documentation-library' + +import AtomInput, {inputSizes} from '../../src/index.js' +import {flexCenteredStyle} from '../settings.js' + +const ArticleSize = ({className}) => ( +
+

Size

+ + The element gets {Object.values(inputSizes).length} different size + configurations using its size prop. + + + {[['default', undefined], ...Object.entries(inputSizes)].map( + ([key], index) => ( + + + + ) + )} + {[['default', undefined], ...Object.entries(inputSizes)].map( + ([key, value], index) => ( + + + + ) + )} + +
+) + +ArticleSize.propTypes = { + className: PropTypes.string +} + +ArticleSize.displayName = 'ArticleSize' + +export default ArticleSize diff --git a/components/atom/input/demo/articles/ArticleState.js b/components/atom/input/demo/articles/ArticleState.js new file mode 100644 index 0000000000..4ca0f238b1 --- /dev/null +++ b/components/atom/input/demo/articles/ArticleState.js @@ -0,0 +1,44 @@ +import PropTypes from 'prop-types' + +import { + Article, + Code, + Grid, + H2, + Label, + Paragraph +} from '@s-ui/documentation-library' + +import AtomInput, {inputStates} from '../../src/index.js' +import {stackMap} from '../settings.js' + +const ArticleState = ({className}) => { + return ( +
+

State

+ + Input has {Object.values(inputStates).length} different values. It can + be used giving a valid state prop to the component. + + + {stackMap( + [['undefined', undefined], ...Object.entries(inputStates)], + ([key], index) => ( + + ), + ([key, value], index) => ( + + ) + )} + +
+ ) +} + +ArticleState.propTypes = { + className: PropTypes.string +} + +ArticleState.displayName = 'ArticleState' + +export default ArticleState diff --git a/components/atom/input/demo/articles/ArticleType.js b/components/atom/input/demo/articles/ArticleType.js new file mode 100644 index 0000000000..84550183ef --- /dev/null +++ b/components/atom/input/demo/articles/ArticleType.js @@ -0,0 +1,133 @@ +import PropTypes from 'prop-types' + +import { + Anchor, + Article, + Cell, + Code, + Grid, + H2, + H4, + Paragraph +} from '@s-ui/documentation-library' + +import AtomInput, {inputTypes} from '../../src/index.js' + +const ArticleType = ({className}) => { + return ( +
+

Type

+ + AtomInput provides different types of usage depending on its{' '} + type value prop. + + + {[ + [ + 'TEXT', + {type: inputTypes.TEXT}, + { + description: + 'Elements of type text create basic single-line text fields' + } + ], + [ + 'DATE', + {type: inputTypes.DATE, charsSize: 10}, + { + description: + 'Create input fields that let the user enter a date, either with a textbox that validates the input or a special date picker interface. The resulting value includes the year, month, and day, but not the time. The time and datetime-local input types support time and date+time input.' + } + ], + [ + 'MASK', + { + type: inputTypes.MASK, + mask: {mask: 'ES00 0000 0000 00 0000000000'}, + placeholder: 'ES00 0000 0000 00 0000000000', + charsSize: 31 + }, + { + description: ( + <> + Let the user define its own mask for custom purposes. More + info at{' '} + + http://shorturl.at/foBF1 + + + ) + } + ], + [ + 'NUMBER', + { + type: inputTypes.NUMBER, + placeholder: 'Number only input', + charsSize: 10 + }, + { + description: ( + <> + A control for entering a number. Displays a spinner and adds + default validation when supported. Displays a numeric keypad + in some devices with dynamic keypads. Arrows for number inputs + are not shown due to:{' '} + + http://shorturl.at/tR149 + + + ) + } + ], + [ + 'PASSWORD', + {type: inputTypes.PASSWORD, placeholder: 'Password Input'}, + { + description: + 'A single-line text field whose value is obscured. Will alert user if site is not secure' + } + ], + [ + 'SUI_PASSWORD', + {type: inputTypes.SUI_PASSWORD, placeholder: 'Password Input'}, + { + description: + 'Like password but whith a show button for value displaying state' + } + ], + [ + 'TEL', + {type: inputTypes.TEL}, + { + description: + 'A control for entering a telephone number. Displays a telephone keypad in some devices with dynamic keypads.' + } + ], + [ + 'EMAIL', + {type: inputTypes.EMAIL}, + { + description: + 'A field for editing an email address. Looks like a text input, but has validation parameters and relevant keyboard in supporting browsers and devices with dynamic keyboards.' + } + ] + ].map(([key, props, {description} = {}], index) => ( + +

{key}

+ + {description} +
+ ))} +
+
+ ) +} + +ArticleType.propTypes = { + className: PropTypes.string +} + +ArticleType.displayName = 'ArticleType' + +export default ArticleType diff --git a/components/atom/input/demo/index.js b/components/atom/input/demo/index.js index 0ec18c7d12..68e14b5224 100644 --- a/components/atom/input/demo/index.js +++ b/components/atom/input/demo/index.js @@ -1,589 +1,17 @@ -import {useState} from 'react' - -import AtomInput, { - inputShapes, - inputSizes, - inputStates, - inputTypes -} from 'components/atom/input/src/index.js' - -import { - Anchor, - AntDesignIcon, - Article, - Box, - Button, - Cell, - Code, - Grid, - H1, - H2, - H3, - H4, - Input, - Label, - ListItem, - Paragraph, - RadioButton, - RadioButtonGroup, - UnorderedList -} from '@s-ui/documentation-library' - -import {flexCenteredStyle, stackMap} from './settings.js' - -const DefaultDemo = () => ( -
-

Default

- - By default, the element gets the following look and feel. - -
- -
-
-) - -const SizeDemo = () => ( -
-

Size

- - The element gets {Object.values(inputSizes).length} different size - configurations using its size prop. - - - {[['default', undefined], ...Object.entries(inputSizes)].map( - ([key], index) => ( - - - - ) - )} - {[['default', undefined], ...Object.entries(inputSizes)].map( - ([key, value], index) => ( - - - - ) - )} - -
-) - -const PlaceholderValueAndDefaultValueDemo = () => { - const [placeholder, setPlaceholder] = useState('placeholder') - const [value, setValue] = useState(undefined) - const [defaultValue, setDefaultValue] = useState('default value') - return ( -
-

value, defaultValue and placeholder

- - value: controlled component. - - - defaultValue: for uncontrolled component - - - placeholder: the placeholder for empty component value - hint. - - - - - - - - - - - - - setPlaceholder(event.target.value)} - /> - - - setDefaultValue(event.target.value)} - /> - - - setValue(event.target.value)} - /> - - - - - - setValue(event.target.value)} - /> - - -
- ) -} - -const TypeDemo = () => { - return ( -
-

Type

- - AtomInput provides diferent types of usage depending on its{' '} - type value prop. - - - {[ - [ - 'TEXT', - {type: inputTypes.TEXT}, - { - description: - 'Elements of type text create basic single-line text fields' - } - ], - [ - 'DATE', - {type: inputTypes.DATE, charsSize: 10}, - { - description: - 'Create input fields that let the user enter a date, either with a textbox that validates the input or a special date picker interface. The resulting value includes the year, month, and day, but not the time. The time and datetime-local input types support time and date+time input.' - } - ], - [ - 'MASK', - { - type: inputTypes.MASK, - mask: 'ES00 0000 0000 00 0000000000', - placeholder: 'ES00 0000 0000 00 0000000000', - charsSize: 31 - }, - { - description: ( - <> - Let the user define its own mask for custom purposes. More - info at{' '} - - http://shorturl.at/foBF1 - - - ) - } - ], - [ - 'NUMBER', - { - type: inputTypes.NUMBER, - placeholder: 'Number only input', - charsSize: 10 - }, - { - description: ( - <> - A control for entering a number. Displays a spinner and adds - default validation when supported. Displays a numeric keypad - in some devices with dynamic keypads. Arrows for number inputs - are not shown due to:{' '} - - http://shorturl.at/tR149 - - - ) - } - ], - [ - 'PASSWORD', - {type: inputTypes.PASSWORD, placeholder: 'Password Input'}, - { - description: - 'A single-line text field whose value is obscured. Will alert user if site is not secure' - } - ], - [ - 'SUI_PASSWORD', - {type: inputTypes.SUI_PASSWORD, placeholder: 'Password Input'}, - { - description: - 'Like password but whith a show button for value displaying state' - } - ], - [ - 'TEL', - {type: inputTypes.TEL}, - { - description: - 'A control for entering a telephone number. Displays a telephone keypad in some devices with dynamic keypads.' - } - ], - [ - 'EMAIL', - {type: inputTypes.EMAIL}, - { - description: - 'A field for editing an email address. Looks like a text input, but has validation parameters and relevant keyboard in supporting browsers and devices with dynamic keyboards.' - } - ] - ].map(([key, props, {description} = {}], index) => ( - -

{key}

- - {description} -
- ))} -
-
- ) -} - -const DisabledReadOnlyDemo = () => { - return ( -
-

Disable and ReadOnly

- - Input provides two different modes that blocks the component behavior - the difference between them is the appearance. - - - The developer can disable the component using the disabled{' '} - boolean prop. It can be blocked also using the readOnly{' '} - boolean propm, but it will look like the default input. - - - - - - - - - - - - - - - -
- ) -} - -const AddonAndIconDemo = () => { - const [state, setState] = useState({}) - const {icon, iconValue, rightAddon, leftAddon} = state - const setStatus = (newState = {}) => setState({...state, ...newState}) - const valueIcon = iconValue ? ( - - ) : null - return ( -
-

Addon and Icon

- - Input offers the possibility to add icons and contents on its left or - right positions - - - - leftAddon and rightAddon: use it as a label - for the input field - - - leftIcon and rightIcon: use it as a valid - symbol for the field - - - This field props can be combined all together. - - - - - - { - setStatus({icon: value}) - }} - fullWidth - > - - - - - - - setStatus({ - iconValue: value - }) - } - fullWidth - > - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - - - setStatus({leftAddon: event.target.value})} - /> - - - setStatus({rightAddon: event.target.value})} - /> - - -
- ) -} - -const BorderlessDemo = () => { - const [border, setBorder] = useState(true) - const [mode, setMode] = useState('light') - return ( -
-

No border

- - The border of the input can be removed using the boolean prop{' '} - noBorder - - - - setBorder(!value)} - /> - - - setMode(value ? 'dark' : 'light')} - /> - - - - - - - -
- ) -} - -const StateDemo = () => { - return ( -
-

State

- - Input has {Object.values(inputStates).length} different values. It can - be used giving a valid state prop to the component. - - - {stackMap( - [['undefined', undefined], ...Object.entries(inputStates)], - ([key], index) => ( - - ), - ([key, value], index) => ( - - ) - )} - -
- ) -} - -const ErrorStatusDemo = () => { - return ( -
-

Error State

- - Input can show its error mode using the boolean prop{' '} - errorStatus - - - - - - - - - - - - - - - - - - - - - -
- ) -} - -const InlineFormDemo = () => ( -
-

Inline Form

-

Deprecated

- - Input have its own way of provide a submision using the{' '} - button prop, you can pass a React node. - - Send} /> -
-) - -const ShapeDemo = () => ( -
-

Shape

- - The border radius of the input can be set using the shape{' '} - property. - - - {Object.entries({default: undefined, ...inputShapes}).map(([key]) => ( - - - - ))} - {Object.entries({default: undefined, ...inputShapes}).map( - ([key, value]) => ( - - - - ) - )} - - - In even preserves its own shaping combined with addons and sizes also. - - - - {Object.entries({default: undefined, ...inputShapes}).map(([key]) => ( - - - - ))} - {Object.entries({default: undefined, ...inputSizes}).map( - ([sizeKey, sizeValue]) => ( - <> - - - - {Object.entries({default: undefined, ...inputShapes}).map( - ([shapeKey, shapeValue]) => ( - - left} - rightAddon={right} - /> - - ) - )} - - ) - )} - -
-) +import {H1, Paragraph} from '@s-ui/documentation-library' + +import ArticleAddonAndIcon from './articles/ArticleAddonAndIcon.js' +import ArticleBorderless from './articles/ArticleBorderless.js' +import ArticleDefault from './articles/ArticleDefault.js' +import ArticleDisabledReadOnly from './articles/ArticleDisabledReadOnly.js' +import ArticleErrorStatus from './articles/ArticleErrorStatus.js' +import ArticleInlineForm from './articles/ArticleInlineForm.js' +import ArticlePlaceholderValueAndDefaultValue from './articles/ArticlePlaceholderValueAndDefaultValue.js' +import ArticleShape from './articles/ArticleShape.js' +import ArticleSize from './articles/ArticleSize.js' +import ArticleState from './articles/ArticleState.js' +import ArticleType from './articles/ArticleType.js' +import {CLASS_SECTION} from './settings.js' const Demo = () => (
@@ -594,27 +22,27 @@ const Demo = () => ( information. These include dates, passwords or even short answers. It’s a field where users can write alphanumeric texts. - +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
diff --git a/components/atom/input/demo/settings.js b/components/atom/input/demo/settings.js index b0aefee24e..4198ad96a5 100644 --- a/components/atom/input/demo/settings.js +++ b/components/atom/input/demo/settings.js @@ -13,3 +13,6 @@ export const stackMap = (arr = [], ...mappingCallbacks) => e(value, innerIndex + this.length * index) ) }, arr) + +const BASE_CLASS_DEMO = `DemoAtomInput` +export const CLASS_SECTION = `${BASE_CLASS_DEMO}-section` diff --git a/components/atom/input/package.json b/components/atom/input/package.json index 84c5ca087d..f435149f31 100644 --- a/components/atom/input/package.json +++ b/components/atom/input/package.json @@ -1,6 +1,6 @@ { "name": "@s-ui/react-atom-input", - "version": "5.22.0", + "version": "5.22.0-beta.0", "description": "", "main": "lib/index.js", "scripts": { @@ -11,7 +11,7 @@ "dependencies": { "@s-ui/react-hooks": "1", "@s-ui/react-primitive-polymorphic-element": "1", - "imask": "3.4.0" + "react-imask": "6.4.3" }, "peerDependencies": { "@s-ui/component-dependencies": "1" diff --git a/components/atom/input/src/Input/Component/index.scss b/components/atom/input/src/Input/Component/index.scss index 17bfbf0236..3fd7e18269 100644 --- a/components/atom/input/src/Input/Component/index.scss +++ b/components/atom/input/src/Input/Component/index.scss @@ -7,77 +7,29 @@ $class-read-only: '#{$base-class-input}--readOnly'; -webkit-appearance: none; @include sui-atom-input-input; - border-radius: $bdrs-atom-input; + background-color: transparent; min-height: auto; text-overflow: $tov-atom-input-placeholder; - &--charsSize { + padding-left: 0; + padding-right: 0; + border: 0 solid transparent; + &#{$base-class-input}--charsSize { width: inherit; } - &--hidden { + &#{$base-class-input}--hidden { display: none; } - &--readOnly { - background: $bgc-atom-input-read-only; - border: $bd-atom-input-read-only; - color: $c-atom-input-read-only; - } - - @include atom-input-shape-wrapper( - $base-class, - $base-class-input, - $bdrs-atom-input-shapes, - $sizes-atom-input, - $bdrs-atom-input, - $h-atom-input--m - ); - - &#{$base-class-input}--noBorder, - &#{$base-class-input}--noBorder:disabled { - border: 0; - &:focus { - border: 0; - box-shadow: none; - outline: 0; - } - } - &::placeholder { color: $c-atom-input-placeholder; } - &:disabled { - pointer-events: none; - - &:not(#{$class-read-only}) { - -webkit-text-fill-color: $c-atom-input-disabled; - - background: $bgc-atom-input-disabled; - border: $bd-atom-input-disabled; - color: $c-atom-input-disabled; - } - } - &:focus { - @include sui-atom-input-input-focus; - } - - @each $type, $attr in $sizes-atom-input { - &-size-#{$type} { - height: $attr; - min-height: $attr; - } + box-shadow: none; } - - @each $state, $color in $states-atom-input { - &.sui-AtomInput-input--#{$state} { - border-color: $color; - - &:focus { - box-shadow: $bxsh-atom-input-size $color; - } - } + &:focus-visible { + outline: 0; } &[type='number'] { diff --git a/components/atom/input/src/Input/Wrappers/Addons/InputAddons.js b/components/atom/input/src/Input/Wrappers/Addons/InputAddons.js index af4999be14..8fb49f887e 100644 --- a/components/atom/input/src/Input/Wrappers/Addons/InputAddons.js +++ b/components/atom/input/src/Input/Wrappers/Addons/InputAddons.js @@ -1,21 +1,14 @@ -import cx from 'classnames' import PropTypes from 'prop-types' import {INPUT_SHAPES, SIZES} from '../../../config.js' -import {ADDON_TYPES, BASE_CLASS_ADDON_WRAPPER, getClassName} from './config.js' +import {ADDON_TYPES, getClassName} from './config.js' const InputAddon = ({leftAddon, rightAddon, shape, size, children}) => { if (!(leftAddon || rightAddon)) { return children } return ( -
+ <> {leftAddon && ( {leftAddon} @@ -27,7 +20,7 @@ const InputAddon = ({leftAddon, rightAddon, shape, size, children}) => { {rightAddon} )} -
+ ) } diff --git a/components/atom/input/src/Input/Wrappers/Addons/config.js b/components/atom/input/src/Input/Wrappers/Addons/config.js index f561c5393b..2f4478da23 100644 --- a/components/atom/input/src/Input/Wrappers/Addons/config.js +++ b/components/atom/input/src/Input/Wrappers/Addons/config.js @@ -1,13 +1,12 @@ import cx from 'classnames' -import {BASE} from '../../../config.js' +import {BASE, BASE_CLASS_ITEM} from '../../../config.js' export const BASE_CLASS_ADDON = `${BASE}--withAddon` -export const BASE_CLASS_ADDON_WRAPPER = `${BASE_CLASS_ADDON}Wrapper` export const ADDON_TYPES = { LEFT: 'left', RIGHT: 'right' } export const getClassName = ({type}) => - cx(BASE_CLASS_ADDON, `${BASE_CLASS_ADDON}--${type}`) + cx(BASE_CLASS_ITEM, BASE_CLASS_ADDON, `${BASE_CLASS_ADDON}--${type}`) diff --git a/components/atom/input/src/Input/Wrappers/Addons/index.scss b/components/atom/input/src/Input/Wrappers/Addons/index.scss index e66319f7d0..aacf641e4e 100644 --- a/components/atom/input/src/Input/Wrappers/Addons/index.scss +++ b/components/atom/input/src/Input/Wrappers/Addons/index.scss @@ -1,34 +1,56 @@ -#{$base-class}--withAddon { - align-items: center; - background-color: $bgc-atom-input-addon; - border-color: $bdc-atom-input-addon; - border-style: solid; - color: $c-atom-input-addon; - display: flex; - flex-direction: column; - height: inherit; - justify-content: center; - line-height: inherit; - padding-left: $p-atom-input-addon-left; - padding-right: $p-atom-input-addon-right; +$base-class-addon: '#{$base-class}--withAddon'; - &--right { - border-width: $bdw-atom-input-addon-right; - } +#{$base-class} { + #{$base-class-addon} { + align-items: center; + background-color: $bgc-atom-input-addon; + border-color: $bdc-atom-input-addon; + border-style: solid; + color: $c-atom-input-addon; + display: flex; + flex-direction: column; + justify-content: center; + line-height: inherit; + padding-left: $p-atom-input-addon-left; + padding-right: $p-atom-input-addon-right; + width: auto; - &--left { - border-width: $bdw-atom-input-addon-left; - } + &#{$base-class-addon}--right { + border-left-width: 0; + } - &Wrapper { - display: flex; - @include atom-input-shape-wrapper( - $base-class, - #{'.sui-AtomInput--withAddonWrapper'}, - $bdrs-atom-input-shapes, - $sizes-atom-input, - $bdrs-atom-input, - $h-atom-input--m - ); + &#{$base-class-addon}--left { + border-right-width: 0; + } + } + @each $state, $color in $states-atom-input { + &#{$base-class}--status-#{$state} { + #{$base-class}-item { + &#{$base-class-addon} { + border-color: $bdc-atom-input-addon; + &#{$base-class-addon}--right { + border-left-color: $color; + } + &#{$base-class-addon}--left { + border-right-color: $color; + } + } + } + } + } + @each $state, $color in $states-atom-input { + &#{$base-class}--status-#{$state} { + #{$base-class}-item { + &#{$base-class-addon} { + border-color: $bdc-atom-input-addon; + &#{$base-class-addon}--right { + border-left-color: $color; + } + &#{$base-class-addon}--left { + border-right-color: $color; + } + } + } + } } } diff --git a/components/atom/input/src/Input/Wrappers/Button/InputButton.js b/components/atom/input/src/Input/Wrappers/Button/InputButton.js index fc6a62a687..87d1d5626a 100644 --- a/components/atom/input/src/Input/Wrappers/Button/InputButton.js +++ b/components/atom/input/src/Input/Wrappers/Button/InputButton.js @@ -1,6 +1,7 @@ +import cx from 'classnames' import PropTypes from 'prop-types' -import {BASE_CLASS_BUTTON} from './config.js' +import {BASE_CLASS_BUTTON, BASE_CLASS_ITEM} from './config.js' const InputButton = ({button, children}) => { if (button === undefined) { @@ -8,10 +9,12 @@ const InputButton = ({button, children}) => { } return ( -
-
{children}
-
{button}
-
+ <> + {children} + + {button} + + ) } InputButton.propTypes = { diff --git a/components/atom/input/src/Input/Wrappers/Button/config.js b/components/atom/input/src/Input/Wrappers/Button/config.js index 86a66b2c31..da59c18f38 100644 --- a/components/atom/input/src/Input/Wrappers/Button/config.js +++ b/components/atom/input/src/Input/Wrappers/Button/config.js @@ -1,3 +1,4 @@ -import {BASE} from '../../../config.js' +import {BASE, BASE_CLASS_ITEM} from '../../../config.js' +export {BASE_CLASS_ITEM} export const BASE_CLASS_BUTTON = `${BASE}--withButton` diff --git a/components/atom/input/src/Input/Wrappers/Button/index.scss b/components/atom/input/src/Input/Wrappers/Button/index.scss index ca26941a34..5274fe8589 100644 --- a/components/atom/input/src/Input/Wrappers/Button/index.scss +++ b/components/atom/input/src/Input/Wrappers/Button/index.scss @@ -1,13 +1,3 @@ -#{$base-class}--withButton { - display: flex; - width: 100%; - - &-input { - flex: 1; - width: 100%; - } - - &-button { - margin-left: $m-m; - } +#{$base-class}--withButton-button { + overflow: hidden; } diff --git a/components/atom/input/src/Input/Wrappers/Icons/InputIcons.js b/components/atom/input/src/Input/Wrappers/Icons/InputIcons.js index 22010b5f94..ce09bab509 100644 --- a/components/atom/input/src/Input/Wrappers/Icons/InputIcons.js +++ b/components/atom/input/src/Input/Wrappers/Icons/InputIcons.js @@ -2,13 +2,11 @@ import cx from 'classnames' import PropTypes from 'prop-types' import { - BASE_CLASS_ICON, BASE_CLASS_ICON_COMPONENT, BASE_CLASS_ICON_COMPONENT_HANDLER, BASE_CLASS_ICON_COMPONENT_LEFT, BASE_CLASS_ICON_COMPONENT_RIGHT, - BASE_CLASS_ICON_LEFT, - BASE_CLASS_ICON_RIGHT + BASE_CLASS_ICON_CONTENT_COMPONENT } from './config.js' const InputIcons = ({ @@ -18,9 +16,6 @@ const InputIcons = ({ onClickRightIcon, children }) => { - if (!(leftIcon || rightIcon)) { - return children - } const handleLeftClick = event => { onClickLeftIcon && onClickLeftIcon(event) } @@ -30,24 +25,22 @@ const InputIcons = ({ } return ( -
+ <> {leftIcon && ( - {leftIcon} + + {leftIcon} + )} {children} @@ -55,17 +48,20 @@ const InputIcons = ({ - {rightIcon} + + {rightIcon} + )} -
+ ) } diff --git a/components/atom/input/src/Input/Wrappers/Icons/config.js b/components/atom/input/src/Input/Wrappers/Icons/config.js index 4d415eb0d6..73e045e57b 100644 --- a/components/atom/input/src/Input/Wrappers/Icons/config.js +++ b/components/atom/input/src/Input/Wrappers/Icons/config.js @@ -1,14 +1,18 @@ -import {BASE} from '../../../config.js' +import { + BASE, + BASE_CLASS_AREA_FOCUSABLE, + BASE_CLASS_ITEM +} from '../../../config.js' export const ICON_TYPES = { LEFT: 'left', RIGHT: 'right' } +export {BASE_CLASS_ITEM, BASE_CLASS_AREA_FOCUSABLE} export const BASE_CLASS_ICON = `${BASE}--withIcon` -export const BASE_CLASS_ICON_LEFT = `${BASE_CLASS_ICON}--${ICON_TYPES.LEFT}` -export const BASE_CLASS_ICON_RIGHT = `${BASE_CLASS_ICON}--${ICON_TYPES.RIGHT}` export const BASE_CLASS_ICON_COMPONENT = `${BASE_CLASS_ICON}-icon` +export const BASE_CLASS_ICON_CONTENT_COMPONENT = `${BASE_CLASS_ICON_COMPONENT}--content` export const BASE_CLASS_ICON_COMPONENT_HANDLER = `${BASE_CLASS_ICON_COMPONENT}--withHandler` export const BASE_CLASS_ICON_COMPONENT_LEFT = `${BASE_CLASS_ICON_COMPONENT}--${ICON_TYPES.LEFT}` export const BASE_CLASS_ICON_COMPONENT_RIGHT = `${BASE_CLASS_ICON_COMPONENT}--${ICON_TYPES.RIGHT}` diff --git a/components/atom/input/src/Input/Wrappers/Icons/index.scss b/components/atom/input/src/Input/Wrappers/Icons/index.scss index f493df3295..f2e5d51fb6 100644 --- a/components/atom/input/src/Input/Wrappers/Icons/index.scss +++ b/components/atom/input/src/Input/Wrappers/Icons/index.scss @@ -1,25 +1,14 @@ -#{$base-class}--withIcon { - position: relative; - width: 100%; +@use 'sass:math'; - &--left #{$base-class-input} { - padding-left: $pl-atom-input-input; - } - - &--right #{$base-class-input} { - padding-right: $pr-atom-input-input; - } +$base-class-with-icon: '#{$base-class}--withIcon'; - &-icon { +#{$base-class} { + #{$base-class-with-icon}-icon { align-items: center; color: $c-atom-input-icon; display: flex; fill: $c-atom-input-icon; - height: $w-atom-input-icon; justify-content: center; - position: absolute; - top: $t-atom-input-icon; - transform: translateY($trf-ty-atom-input-icon); width: $w-atom-input-icon; pointer-events: none; @@ -29,16 +18,25 @@ } &--left { - left: $l-atom-input-icon; + #{$base-class-with-icon}-icon--content { + width: $w-atom-input-icon; + } } &--right { - right: $r-atom-input-icon; + #{$base-class-with-icon}-icon--content { + width: $w-atom-input-icon; + } } - - & > * { - height: 100%; - width: 100%; + } + @each $state, $color in $states-atom-input { + &#{$base-class}--status-#{$state} { + #{$base-class-with-icon}-icon { + #{$base-class-with-icon}-icon--content { + color: $color; + fill: $color; + } + } } } } diff --git a/components/atom/input/src/Input/index.js b/components/atom/input/src/Input/index.js index 1bdf066e20..c7e7348592 100644 --- a/components/atom/input/src/Input/index.js +++ b/components/atom/input/src/Input/index.js @@ -1,16 +1,31 @@ import {forwardRef} from 'react' +import cx from 'classnames' import PropTypes from 'prop-types' -import {SIZES} from '../config.js' -import Input, {inputSizes, inputStates} from './Component/index.js' +import { + BASE_CLASS_AREA_FOCUSABLE, + BASE_CLASS_ITEM, + SIZES, + TYPES +} from '../config.js' +import Mask from '../Mask/index.js' +import Password from '../Password/index.js' +import Input from './Component/index.js' import InputAddons from './Wrappers/Addons/InputAddons.js' import InputButton from './Wrappers/Button/InputButton.js' import InputIcons from './Wrappers/Icons/InputIcons.js' +const componentType = { + undefined: props => [Input, props], + [TYPES.SUI_PASSWORD]: ({type, ...props}) => [Password, {...props}], + [TYPES.MASK]: ({type, ...props}) => [Mask, {...props}] +} + const BaseInput = forwardRef( ( { + type, button, leftAddon, rightAddon, @@ -24,6 +39,10 @@ const BaseInput = forwardRef( }, forwardedRef ) => { + const [Component, passedProps] = componentType[type] + ? componentType[type]({type, size, ...inputProps}) + : componentType[undefined]({type, size, ...inputProps}) + return ( - - - {children} - - + + + + {children} + + + ) @@ -49,6 +70,8 @@ const BaseInput = forwardRef( ) BaseInput.propTypes = { + /* text, password, date or number */ + type: PropTypes.string, /** button html element */ button: PropTypes.node, /* inner react node element */ @@ -70,4 +93,4 @@ BaseInput.propTypes = { } export default BaseInput -export {inputSizes, inputStates, BaseInput} +export {BaseInput} diff --git a/components/atom/input/src/Mask/index.js b/components/atom/input/src/Mask/index.js index 1259d696a3..c621c4ba01 100644 --- a/components/atom/input/src/Mask/index.js +++ b/components/atom/input/src/Mask/index.js @@ -1,50 +1,43 @@ -import {forwardRef, useEffect, useRef, useState} from 'react' +import {forwardRef} from 'react' import PropTypes from 'prop-types' -import Input from '../Input/index.js' +import Input from '../Input/Component/index.js' +import useMask from './useMask.js' const MaskInput = forwardRef( - ({name, onChange, mask: maskOptions, ...props}, forwardedRef) => { - const [mask, setMask] = useState(null) - const refInput = useRef(null) - - useEffect(() => () => mask && mask.destroy(), [mask]) - - const handleChange = (ev, {value}) => { - typeof onChange === 'function' && onChange(ev, {value}) - } - - const handleFocus = () => { - if (!mask) { - import('imask').then(({default: IMask}) => { - setMask(new IMask(refInput.current, maskOptions)) - }) - } - } - - return ( - - ) + ( + {name, onChange, onComplete, mask, value, defaultValue, ...props}, + forwardedRef + ) => { + const {maskedValue, ref} = useMask({ + value, + defaultValue, + mask, + onChange, + onComplete, + forwardedRef + }) + + return } ) MaskInput.displayName = 'MaskInput' MaskInput.propTypes = { + /* The value of the control */ + value: PropTypes.string, + /* default value of the control */ + defaultValue: PropTypes.string, /* mask object, see https://unmanner.github.io/imaskjs/ */ mask: PropTypes.object.isRequired, /* The name of the control */ name: PropTypes.string, /* Event launched on every input change */ - onChange: PropTypes.func + onChange: PropTypes.func, + /* Event fired every onChange which completes teh mask */ + onComplete: PropTypes.func } export default MaskInput diff --git a/components/atom/input/src/Mask/useMask.js b/components/atom/input/src/Mask/useMask.js new file mode 100644 index 0000000000..9952688e5e --- /dev/null +++ b/components/atom/input/src/Mask/useMask.js @@ -0,0 +1,39 @@ +import {useEffect} from 'react' +import {useIMask} from 'react-imask' + +import useControlledState from '@s-ui/react-hooks/lib/useControlledState' +import useMergeRefs from '@s-ui/react-hooks/lib/useMergeRefs' + +import {isFunction} from '../config.js' + +const useMask = ({ + value: argValue, + defaultValue: argDefaultValue, + mask, + onChange, + onComplete, + forwardedRef +}) => { + const [value] = useControlledState(argValue, argDefaultValue) + const { + ref: refInput, + value: maskedValue = '', + setValue + } = useIMask( + {...mask}, + { + onAccept: (value, maskRef, event, ...args) => + isFunction(onChange) && onChange(event, {value, maskRef, ...args}), + onComplete: (value, maskRef, event, ...args) => + isFunction(onComplete) && onComplete(event, {value, maskRef, ...args}) + } + ) + const ref = useMergeRefs(refInput, forwardedRef) + useEffect( + () => value !== maskedValue && setValue(maskedValue), + [argValue, setValue, maskedValue, value] + ) + return Object.assign([maskedValue, ref], {maskedValue, ref}) +} + +export default useMask diff --git a/components/atom/input/src/Password/config.js b/components/atom/input/src/Password/config.js index c18b7ba0a2..e2bec087f5 100644 --- a/components/atom/input/src/Password/config.js +++ b/components/atom/input/src/Password/config.js @@ -1,6 +1,7 @@ -import {BASE_CLASS} from '../config.js' +import {BASE, BASE_CLASS_ITEM} from '../config.js' -export const BASE_CLASS_PASSWORD = `${BASE_CLASS}-password` +export {BASE_CLASS_ITEM} +export const BASE_CLASS_PASSWORD = `${BASE}-password` export const BASE_CLASS_PASSWORD_TOGGLE_BUTTON = `${BASE_CLASS_PASSWORD}--toggleButton` export const TEXT = 'text' diff --git a/components/atom/input/src/Password/index.js b/components/atom/input/src/Password/index.js index f26592e398..e6e4a69912 100644 --- a/components/atom/input/src/Password/index.js +++ b/components/atom/input/src/Password/index.js @@ -1,16 +1,12 @@ import {forwardRef, useState} from 'react' +import cx from 'classnames' import PropTypes from 'prop-types' import useControlledState from '@s-ui/react-hooks/lib/useControlledState' -import Input from '../Input/index.js' -import { - BASE_CLASS_PASSWORD, - BASE_CLASS_PASSWORD_TOGGLE_BUTTON, - PASSWORD, - TEXT -} from './config.js' +import Input from '../Input/Component/index.js' +import {BASE_CLASS_PASSWORD_TOGGLE_BUTTON, PASSWORD, TEXT} from './config.js' const Password = forwardRef( ( @@ -38,7 +34,7 @@ const Password = forwardRef( } return ( -
+ <> -
+ {type === PASSWORD ? pwShowLabel : pwHideLabel} -
-
+ + ) } ) diff --git a/components/atom/input/src/Password/styles/index.scss b/components/atom/input/src/Password/styles/index.scss index 6da24f47f1..ce2e2dbb0c 100644 --- a/components/atom/input/src/Password/styles/index.scss +++ b/components/atom/input/src/Password/styles/index.scss @@ -1,16 +1,11 @@ -$base-class-password: '#{$base-class-input}-password'; +$base-class-password: '#{$base-class}-password'; #{$base-class-password} { - position: relative; - width: 100%; - &--toggleButton { color: $c-atom-input-password-toggle-button; cursor: pointer; - position: absolute; - right: $r-atom-input-password-toggle-button; - top: 50%; - transform: translateY(-50%); user-select: none; + display: flex; + align-items: center; } } diff --git a/components/atom/input/src/config.js b/components/atom/input/src/config.js index 75c4f7aef1..97ad8f508e 100644 --- a/components/atom/input/src/config.js +++ b/components/atom/input/src/config.js @@ -6,6 +6,8 @@ export const COMPONENT = 'Input' export const BASE = `${PREFIX}-${CATEGORY}${COMPONENT}` +export const BASE_CLASS_ITEM = `${BASE}-item` +export const BASE_CLASS_AREA_FOCUSABLE = `${BASE}-area-focusable` export const BASE_CLASS = `${BASE}-input` // Enums @@ -59,9 +61,14 @@ export const getClassNames = ({ hideInput && `${BASE_CLASS}--hidden`, noBorder && `${BASE_CLASS}--noBorder`, readOnly && `${BASE_CLASS}--readOnly`, - errorState && `${BASE_CLASS}--${INPUT_STATES.ERROR}`, - errorState === false && `${BASE_CLASS}--${INPUT_STATES.SUCCESS}`, - state && `${BASE_CLASS}--${state}`, + errorState && `${BASE_CLASS}--status-${INPUT_STATES.ERROR}`, + errorState === false && `${BASE_CLASS}--status-${INPUT_STATES.SUCCESS}`, + state && `${BASE_CLASS}--status-${state}`, shape && `${BASE_CLASS}-shape-${shape}` ) } + +export const isFunction = fn => typeof fn === 'function' + +export const isValidSize = charSize => + Number.isInteger(charSize) && charSize >= 0 diff --git a/components/atom/input/src/index.js b/components/atom/input/src/index.js index 5ae81987c2..0e7cb44b9b 100644 --- a/components/atom/input/src/index.js +++ b/components/atom/input/src/index.js @@ -1,33 +1,70 @@ import {forwardRef} from 'react' +import cx from 'classnames' import PropTypes from 'prop-types' -import Input, {inputSizes, inputStates} from './Input/index.js' -import Mask from './Mask/index.js' -import Password from './Password/index.js' -import {INPUT_SHAPES, TYPES} from './config.js' +import Input from './Input/index.js' +import { + BASE, + INPUT_SHAPES, + INPUT_STATES, + isValidSize, + SIZES, + TYPES +} from './config.js' import {checkIfValidNumberInput} from './helper.js' -const AtomInput = forwardRef(({type, ...props}, ref) => { - switch (type) { - case 'sui-password': - return - case 'mask': - return - case 'number': - return ( +const AtomInput = forwardRef( + ( + { + type, + shape, + charsSize, + size = SIZES.MEDIUM, + noBorder, + errorState, + state, + disabled, + readOnly, + ...props + }, + ref + ) => { + return ( + - ) - - default: - return + + ) } -}) +) AtomInput.propTypes = { /** native types (text, date, ...), 'sui-password' */ @@ -88,7 +125,7 @@ AtomInput.propTypes = { disabled: PropTypes.bool, /** 's' or 'm', default: 'm' */ - size: PropTypes.oneOf(Object.values(inputSizes)), + size: PropTypes.oneOf(Object.values(SIZES)), /** width of input based in number of characters (native "size" attribute) */ charsSize: PropTypes.number, @@ -118,7 +155,7 @@ AtomInput.propTypes = { errorState: PropTypes.bool, /** 'success', 'error' or 'alert' */ - state: PropTypes.oneOf(Object.values(inputStates)), + state: PropTypes.oneOf(Object.values(INPUT_STATES)), /** value of the control */ value: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), @@ -142,7 +179,13 @@ AtomInput.propTypes = { inputMode: PropTypes.string, /** Sets the shape of the input field. It can be 'rounded', 'square' or 'circle' */ - shape: PropTypes.string + shape: PropTypes.string, + + /** Wether to hide the input border or not */ + noBorder: PropTypes.bool, + + /* This Boolean attribute prevents the user from interacting with the input but without disabled styles */ + readOnly: PropTypes.bool } AtomInput.displayName = 'AtomInput' @@ -150,8 +193,8 @@ AtomInput.displayName = 'AtomInput' export default AtomInput export { - inputSizes, - inputStates, + SIZES as inputSizes, + INPUT_STATES as inputStates, TYPES as inputTypes, INPUT_SHAPES as inputShapes } diff --git a/components/atom/input/src/mixins.scss b/components/atom/input/src/mixins.scss deleted file mode 100644 index 9985338e36..0000000000 --- a/components/atom/input/src/mixins.scss +++ /dev/null @@ -1,75 +0,0 @@ -@mixin atom-input-shape-wrapper( - $baseClass, - $baseClassName, - $shapeMap, - $sizesMap, - $bdrs-defaultValue, - $sz-defaultValue -) { - $this: &; - @if #{'sui-AtomInput-input'} == $baseClassName { - @each $shapeMapKey, $shapeMapValue in $shapeMap { - @if $shapeMapKey != 'circle' { - &#{$baseClassName}-shape-#{$shapeMapKey} { - border-radius: $shapeMapValue; - } - } @else { - @each $sizeKey, $sizeValue in $sizesMap { - &#{$baseClassName}-shape-#{$shapeMapKey}#{$baseClassName}-size-#{$sizeKey} { - border-radius: $sizeValue * 0.5; - } - } - } - } - } @else { - > *, - #{$baseClass}-input { - border-radius: 0; - } - > *:first-child { - border-top-left-radius: $bdrs-defaultValue; - border-bottom-left-radius: $bdrs-defaultValue; - } - > *:last-child { - border-top-right-radius: $bdrs-defaultValue; - border-bottom-right-radius: $bdrs-defaultValue; - } - @each $shapeMapKey, $shapeMapValue in $shapeMap { - &#{$baseClassName}-shape-#{$shapeMapKey} { - > *, - #{$baseClass}-input { - border-radius: 0; - } - @if $shapeMapKey != 'circle' { - border-radius: $shapeMapValue; - > *:first-child { - border-top-left-radius: $shapeMapValue; - border-bottom-left-radius: $shapeMapValue; - } - > *:last-child { - border-top-right-radius: $shapeMapValue; - border-bottom-right-radius: $shapeMapValue; - } - } @else { - @each $sizeKey, $sizeValue in $sizesMap { - &#{$baseClassName}-shape-#{$shapeMapKey}#{$baseClassName}-size-#{$sizeKey} { - border-radius: $sizeValue * 0.5; - > *, - #{$baseClass}-input { - border-radius: 0; - } - > *:first-child { - border-top-left-radius: $sizeValue * 0.5; - border-bottom-left-radius: $sizeValue * 0.5; - } - > *:last-child { - border-top-right-radius: $sizeValue * 0.5; - border-bottom-right-radius: $sizeValue * 0.5; - } - } - } - } - } - } - } -} diff --git a/components/atom/input/src/styles/index.scss b/components/atom/input/src/styles/index.scss index 6d42d354f5..cb92baa520 100644 --- a/components/atom/input/src/styles/index.scss +++ b/components/atom/input/src/styles/index.scss @@ -1,5 +1,115 @@ +@use 'sass:math'; + $base-class: '.sui-AtomInput'; +$base-class-area-focusable: '.sui-AtomInput-area-focusable'; @import '../Input/Component/index'; @import '../Input/Wrappers/index'; @import '../Password/index'; + +#{$base-class} { + display: flex; + align-items: stretch; + flex-grow: 1; + + #{$base-class}-item { + border: $bd-atom-input-base; + &:first-child { + border-bottom-left-radius: $bdrs-atom-input; + border-top-left-radius: $bdrs-atom-input; + border-left-width: $bdw-s; + } + &:last-child { + border-bottom-right-radius: $bdrs-atom-input; + border-top-right-radius: $bdrs-atom-input; + border-right-width: $bdw-s; + } + } + + &:not(#{$base-class}--has-charSize) { + #{$base-class-area-focusable} { + flex-grow: 1; + } + } + + @each $shapeMapKey, $shapeMapValue in $bdrs-atom-input-shapes { + &#{$base-class}-shape-#{$shapeMapKey} { + #{$base-class}-item { + &:first-child { + border-bottom-left-radius: $shapeMapValue; + border-top-left-radius: $shapeMapValue; + } + &:last-child { + border-bottom-right-radius: $shapeMapValue; + border-top-right-radius: $shapeMapValue; + } + } + } + } + + #{$base-class-area-focusable} { + display: flex; + padding-left: $pl-atom-input; + padding-right: $pr-atom-input; + background: $bgc-atom-input; + gap: math.div($p-l, 2); + &:focus-within { + border: $bd-atom-input-focus; + box-shadow: $bxsh-atom-input; + outline: 0 none; + } + } + + @each $state, $color in $states-atom-input { + &#{$base-class}--status-#{$state} { + #{$base-class}-item { + border-color: $color; + } + } + } + + &#{$base-class}--is-read-only { + #{$base-class-area-focusable} { + background: $bgc-atom-input-read-only; + border: $bd-atom-input-read-only; + color: $c-atom-input-read-only; + } + } + + &#{$base-class}--is-disabled { + #{$base-class-area-focusable} { + pointer-events: none; + } + &:not(#{$base-class}--is-read-only) { + #{$base-class-area-focusable} { + -webkit-text-fill-color: $c-atom-input-disabled; + background: $bgc-atom-input-disabled; + border: $bd-atom-input-disabled; + color: $c-atom-input-disabled; + } + } + } + + @each $type, $attr in $sizes-atom-input { + &#{$base-class}-size-#{$type} { + height: $attr; + min-height: $attr; + } + } + + &#{$base-class}-borderless { + &, + &#{$base-class}--is-disabled:not(#{$base-class}--is-read-only) { + #{$base-class}-item { + border-width: 0; + } + #{$base-class-area-focusable} { + padding-left: $pl-atom-input + $bdw-s; + padding-right: $pr-atom-input + $bdw-s; + &:focus-within { + box-shadow: none; + } + } + } + } +} diff --git a/components/atom/input/src/styles/settings.scss b/components/atom/input/src/styles/settings.scss index 13012356cd..72501a9dc4 100644 --- a/components/atom/input/src/styles/settings.scss +++ b/components/atom/input/src/styles/settings.scss @@ -1,3 +1 @@ @import '../settings.scss'; - -@import '../mixins.scss'; diff --git a/components/atom/label/demo/package.json b/components/atom/label/demo/package.json index c2ae6ef5ca..43f3e3e7c6 100644 --- a/components/atom/label/demo/package.json +++ b/components/atom/label/demo/package.json @@ -14,6 +14,6 @@ "@s-ui/react-atom-button": "1", "@s-ui/react-atom-checkbox": "2", "@s-ui/react-atom-icon": "1", - "@s-ui/react-atom-input": "5" + "@s-ui/react-atom-input": "5.22.0-beta.0" } } diff --git a/components/atom/slider/demo/package.json b/components/atom/slider/demo/package.json index fc29345c03..79cb48ff08 100644 --- a/components/atom/slider/demo/package.json +++ b/components/atom/slider/demo/package.json @@ -14,6 +14,6 @@ "@s-ui/react-atom-button": "1", "@s-ui/react-atom-checkbox": "2", "@s-ui/react-atom-icon": "1", - "@s-ui/react-atom-input": "5" + "@s-ui/react-atom-input": "5.22.0-beta.0" } } diff --git a/components/atom/spinner/demo/package.json b/components/atom/spinner/demo/package.json index bd200e02ec..aa77db2448 100644 --- a/components/atom/spinner/demo/package.json +++ b/components/atom/spinner/demo/package.json @@ -14,6 +14,6 @@ "@s-ui/react-atom-button": "1", "@s-ui/react-atom-checkbox": "2", "@s-ui/react-atom-icon": "1", - "@s-ui/react-atom-input": "5" + "@s-ui/react-atom-input": "5.22.0-beta.0" } } diff --git a/components/atom/tag/demo/articles/ArticleDesign.js b/components/atom/tag/demo/articles/ArticleDesign.js index 99ff42eaea..43bf315fb1 100644 --- a/components/atom/tag/demo/articles/ArticleDesign.js +++ b/components/atom/tag/demo/articles/ArticleDesign.js @@ -34,28 +34,32 @@ const ArticleDesign = ({className}) => { )} {Object.values(atomTagDesigns) .reverse() - .map((size, index) => ( + .map((design, index) => ( - + - + - + - + diff --git a/components/atom/tag/package.json b/components/atom/tag/package.json index 22fd9ce780..f4faa52886 100644 --- a/components/atom/tag/package.json +++ b/components/atom/tag/package.json @@ -1,6 +1,6 @@ { "name": "@s-ui/react-atom-tag", - "version": "2.44.0", + "version": "2.44.0-beta.0", "description": "", "main": "lib/index.js", "scripts": { diff --git a/components/atom/tag/src/_settings.scss b/components/atom/tag/src/_settings.scss index 05132670cf..084cf259cc 100644 --- a/components/atom/tag/src/_settings.scss +++ b/components/atom/tag/src/_settings.scss @@ -3,18 +3,42 @@ $bgc-atom-tag: color-variation($c-gray, 3) !default; $mw-label: 240px !default; // sizes +$h-atom-tag-xl: 48px !default; $h-atom-tag-l: 40px !default; $h-atom-tag-m: 32px !default; $h-atom-tag-s: 24px !default; +$h-atom-tag-xs: 16px !default; $m-atom-tag: $m-m !default; +$p-atom-tag-xl: 0 $p-l !default; $p-atom-tag-l: 0 $p-l !default; $p-atom-tag-m: 0 $p-l !default; $p-atom-tag-s: 0 $p-m !default; +$p-atom-tag-xs: 0 $p-m !default; -$p-atom-tag-hasIcon-hasClose: ( +$atom-tag-sizes: (xlarge, large, medium, small, xsmall) !default; + +$h-atom-tags: ( + xlarge: $h-atom-tag-xl, + large: $h-atom-tag-l, + medium: $h-atom-tag-m, + small: $h-atom-tag-s, + xsmall: $h-atom-tag-xs +) !default; + +$p-atom-tags: ( + xlarge: $p-atom-tag-xl, + large: $p-atom-tag-l, + medium: $p-atom-tag-m, small: $p-atom-tag-s, + xsmall: $p-atom-tag-xs +) !default; + +$p-atom-tag-hasIcon-hasClose: ( + xlarge: $p-atom-tag-xl, + large: $p-atom-tag-l, medium: $p-atom-tag-m, - large: $p-atom-tag-l + small: $p-atom-tag-s, + xsmall: $p-atom-tag-xs ) !default; // outline diff --git a/components/atom/tag/src/constants.js b/components/atom/tag/src/constants.js index b4c93e45dc..52840cb918 100644 --- a/components/atom/tag/src/constants.js +++ b/components/atom/tag/src/constants.js @@ -12,9 +12,11 @@ export const ACTIONABLE_ONLY_PROPS = [ export const STANDARD_ONLY_PROPS = ['closeIcon', 'onClose'] export const SIZES = { + XLARGE: 'xlarge', LARGE: 'large', MEDIUM: 'medium', - SMALL: 'small' + SMALL: 'small', + XSMALL: 'xsmall' } export const LINK_TYPES = { diff --git a/components/atom/tag/src/index.js b/components/atom/tag/src/index.js index 6304e2ab7e..6d118db803 100644 --- a/components/atom/tag/src/index.js +++ b/components/atom/tag/src/index.js @@ -11,43 +11,52 @@ import { } from './constants.js' import StandardTag from './Standard.js' -const AtomTag = props => { - const { - design, - href, - icon, - onClick, - responsive, - size, - type, - readOnly, - disabled, - isFitted = false - } = props +const AtomTag = ({ + design, + href, + icon, + iconPlacement = 'left', + onClick, + responsive, + size = SIZES.MEDIUM, + type, + readOnly, + disabled, + isFitted = false, + ...props +}) => { const isActionable = onClick || href - const classNames = cx( - 'sui-AtomTag', - `sui-AtomTag-${size}`, - design && `sui-AtomTag--${design}`, - icon && 'sui-AtomTag-hasIcon', - responsive && 'sui-AtomTag--responsive', - type && `sui-AtomTag--${type}`, - isFitted && 'sui-AtomTag--isFitted' - ) + const [Component, getter] = isActionable + ? [ActionableTag, getActionableProps] + : [StandardTag, getStandardProps] - return isActionable ? ( - - ) : ( - ) } @@ -119,11 +128,6 @@ AtomTag.propTypes = { isFitted: PropTypes.bool } -AtomTag.defaultProps = { - iconPlacement: 'left', - size: SIZES.MEDIUM -} - export default AtomTag export {DESIGNS as atomTagDesigns} export {LINK_TYPES as linkTypes} diff --git a/components/atom/tag/src/styles/index.scss b/components/atom/tag/src/styles/index.scss index 20738051f5..c96f3d7246 100644 --- a/components/atom/tag/src/styles/index.scss +++ b/components/atom/tag/src/styles/index.scss @@ -6,7 +6,6 @@ $base-class: '.sui-AtomTag'; align-content: center; background-color: $bgc-atom-tag; border: $bd-atom-tag; - border-radius: ceil($h-atom-tag-m * 0.5); box-sizing: border-box; cursor: default; display: inline-flex; @@ -103,7 +102,7 @@ $base-class: '.sui-AtomTag'; } } - &#{$self}--outline { + &#{$base-class}--design-outline { border-color: $c-atom-tag-actionable-invert; color: $c-atom-tag-actionable-invert; fill: $c-atom-tag-actionable-invert; @@ -119,50 +118,32 @@ $base-class: '.sui-AtomTag'; } } - &-small { - height: $h-atom-tag-s; - padding: $p-atom-tag-s; - &.sui-AtomTag-hasIcon.sui-AtomTag-hasClose { - padding: map-get($p-atom-tag-hasIcon-hasClose, 'small'); - } - - & .sui-AtomTag-label { - line-height: $h-atom-tag-s; - } - - .sui-AtomTag-closeable { - @include icon-secondary-clickable-area($h-atom-tag-s); - } - - .sui-AtomTag-icon { - margin-left: 0; - } - - .sui-AtomTag-secondary-icon { - margin-right: 0; - } - } + @each $atom-tag-size in $atom-tag-sizes { + &#{$base-class}--size-#{$atom-tag-size} { + height: map-get($h-atom-tags, $atom-tag-size); + padding: map-get($p-atom-tags, $atom-tag-size); + border-radius: ceil(map-get($h-atom-tags, $atom-tag-size) * 0.5); + &.sui-AtomTag-hasIcon.sui-AtomTag-hasClose { + padding: map-get($p-atom-tag-hasIcon-hasClose, $atom-tag-size); + } - &-medium { - &.sui-AtomTag-hasIcon.sui-AtomTag-hasClose { - padding: map-get($p-atom-tag-hasIcon-hasClose, 'medium'); - } - } + & .sui-AtomTag-label { + line-height: map-get($h-atom-tags, $atom-tag-size); + } - &-large { - border-radius: ceil($h-atom-tag-l * 0.5); - height: $h-atom-tag-l; - padding: $p-atom-tag-l; - &.sui-AtomTag-hasIcon.sui-AtomTag-hasClose { - padding: map-get($p-atom-tag-hasIcon-hasClose, 'large'); - } + .sui-AtomTag-closeable { + @include icon-secondary-clickable-area( + map-get($h-atom-tags, $atom-tag-size) + ); + } - & .sui-AtomTag-label { - line-height: $h-atom-tag-l; - } + .sui-AtomTag-icon { + margin-left: 0; + } - .sui-AtomTag-closeable { - @include icon-secondary-clickable-area($h-atom-tag-l); + .sui-AtomTag-secondary-icon { + margin-right: 0; + } } } @@ -182,22 +163,22 @@ $base-class: '.sui-AtomTag'; } } - &--outline { + &--design-outline { background-color: $bgc-atom-tag-outline; border: $bdw-atom-tag-outline solid $bc-atom-tag-outline; } - @each $name, $type in $atom-tag-types { - $bgc: map-get($type, bgc); - $c: map-get($type, c); - $bgc-hover: map-get($type, bgc-hover); - $c-hover: map-get($type, c-hover); - $bdc: map-get($type, bdc); - $bds: map-get($type, bds); - $bdw: map-get($type, bdw); - $bdc-hover: map-get($type, bdc-hover); - - &--#{$name} { + @each $type-name, $type-value in $atom-tag-types { + $bgc: map-get($type-value, bgc); + $c: map-get($type-value, c); + $bgc-hover: map-get($type-value, bgc-hover); + $c-hover: map-get($type-value, c-hover); + $bdc: map-get($type-value, bdc); + $bds: map-get($type-value, bds); + $bdw: map-get($type-value, bdw); + $bdc-hover: map-get($type-value, bdc-hover); + + &--type-#{$type-name} { background-color: $bgc; border-color: $bdc; border-style: $bds; @@ -212,7 +193,7 @@ $base-class: '.sui-AtomTag'; fill: $c; } - &#{$self}--outline { + &#{$self}--design-outline { border-color: $bgc; color: $bgc; background-color: $c; diff --git a/components/atom/tag/test/index.test.js b/components/atom/tag/test/index.test.js index d772bf9e56..ac1b5c9ea1 100644 --- a/components/atom/tag/test/index.test.js +++ b/components/atom/tag/test/index.test.js @@ -201,14 +201,16 @@ describe(json.name, () => { // Given const library = pkg const expected = { + XLARGE: 'xlarge', LARGE: 'large', MEDIUM: 'medium', - SMALL: 'small' + SMALL: 'small', + XSMALL: 'xsmall' } // When const {atomTagSizes: actual} = library - const {LARGE, MEDIUM, SMALL, ...others} = actual + const {XLARGE, LARGE, MEDIUM, SMALL, XSMALL, ...others} = actual // Then expect(Object.keys(others).length).to.equal(0) diff --git a/components/atom/textarea/package.json b/components/atom/textarea/package.json index b26903a7ff..897855ba55 100644 --- a/components/atom/textarea/package.json +++ b/components/atom/textarea/package.json @@ -10,7 +10,7 @@ }, "dependencies": { "@s-ui/react-atom-help-text": "1", - "@s-ui/react-atom-input": "5" + "@s-ui/react-atom-input": "5.22.0-beta.0" }, "peerDependencies": { "@s-ui/component-dependencies": "1" diff --git a/components/hook/usePortal/test/index.test.js b/components/hook/usePortal/test/index.test.js index 0373a773c8..a5eb5afbe6 100644 --- a/components/hook/usePortal/test/index.test.js +++ b/components/hook/usePortal/test/index.test.js @@ -10,9 +10,10 @@ import ReactDOM from 'react-dom' import {expect} from 'chai' import PropTypes from 'prop-types' - import sinon from 'sinon' + import {fireEvent, waitFor} from '@testing-library/react' + import json from '../package.json' import * as pkg from '../src/index.js' diff --git a/components/molecule/accordion/demo/package.json b/components/molecule/accordion/demo/package.json index dfacf1208d..5b060302e1 100644 --- a/components/molecule/accordion/demo/package.json +++ b/components/molecule/accordion/demo/package.json @@ -12,7 +12,7 @@ "license": "ISC", "dependencies": { "@s-ui/react-atom-icon": "1", - "@s-ui/react-atom-tag": "2", + "@s-ui/react-atom-tag": "2.44.0-beta.0", "lorem-ipsum": "2.0.4", "react-json-view": "1.21.3" } diff --git a/components/molecule/autosuggest/demo/package.json b/components/molecule/autosuggest/demo/package.json index cf9206a5b1..c3c6c5c349 100644 --- a/components/molecule/autosuggest/demo/package.json +++ b/components/molecule/autosuggest/demo/package.json @@ -16,8 +16,8 @@ "@s-ui/react-atom-icon": "1", "@s-ui/react-molecule-autosuggest-field": "2", "@s-ui/react-molecule-dropdown-option": "2", - "@s-ui/react-molecule-input-tags": "2", - "@s-ui/react-molecule-select": "1", + "@s-ui/react-molecule-input-tags": "2.25.0-beta.1", + "@s-ui/react-molecule-select": "1.57.0-beta.0", "axios": "0.21.4" } } diff --git a/components/molecule/autosuggest/package.json b/components/molecule/autosuggest/package.json index e74bba9fd6..0990807408 100644 --- a/components/molecule/autosuggest/package.json +++ b/components/molecule/autosuggest/package.json @@ -1,6 +1,6 @@ { "name": "@s-ui/react-molecule-autosuggest", - "version": "2.66.0", + "version": "2.66.0-beta.0", "description": "", "main": "lib/index.js", "scripts": { @@ -10,10 +10,10 @@ }, "dependencies": { "@s-ui/js": "2", - "@s-ui/react-atom-input": "5", + "@s-ui/react-atom-input": "5.22.0-beta.0", "@s-ui/react-hooks": "1", "@s-ui/react-molecule-dropdown-list": "2", - "@s-ui/react-molecule-input-tags": "2", + "@s-ui/react-molecule-input-tags": "2.25.0-beta.1", "@s-ui/react-primitive-injector": "1", "lodash.isequal": "4.5" }, diff --git a/components/molecule/autosuggest/src/components/InputWithClearUI/index.js b/components/molecule/autosuggest/src/components/InputWithClearUI/index.js index 70c8849133..10ee6c5a90 100644 --- a/components/molecule/autosuggest/src/components/InputWithClearUI/index.js +++ b/components/molecule/autosuggest/src/components/InputWithClearUI/index.js @@ -8,7 +8,7 @@ const InputWithClearUI = ({ onClickClear, isVisibleClear, iconClear, - rightIcon = , + rightIcon, children, ...props }) => { diff --git a/components/molecule/autosuggestField/demo/package.json b/components/molecule/autosuggestField/demo/package.json index 9bb12b8aec..606ca248dc 100644 --- a/components/molecule/autosuggestField/demo/package.json +++ b/components/molecule/autosuggestField/demo/package.json @@ -12,7 +12,7 @@ "license": "ISC", "dependencies": { "@s-ui/hoc": "1", - "@s-ui/react-molecule-autosuggest": "1", + "@s-ui/react-molecule-autosuggest": "2.66.0-beta.0", "@s-ui/react-molecule-dropdown-option": "2", "@s-ui/react-molecule-field": "1" } diff --git a/components/molecule/autosuggestField/package.json b/components/molecule/autosuggestField/package.json index 8fa02421af..48826b33ee 100644 --- a/components/molecule/autosuggestField/package.json +++ b/components/molecule/autosuggestField/package.json @@ -9,7 +9,7 @@ "build:styles": "cpx './src/**/*.scss' ./lib" }, "dependencies": { - "@s-ui/react-molecule-autosuggest": "2", + "@s-ui/react-molecule-autosuggest": "2.66.0-beta.0", "@s-ui/react-molecule-field": "1" }, "peerDependencies": { diff --git a/components/molecule/buttonGroup/demo/package.json b/components/molecule/buttonGroup/demo/package.json index 6ef4cd2ce5..8ddf887622 100644 --- a/components/molecule/buttonGroup/demo/package.json +++ b/components/molecule/buttonGroup/demo/package.json @@ -13,7 +13,7 @@ "dependencies": { "@s-ui/react-atom-button": "1", "@s-ui/react-atom-icon": "1", - "@s-ui/react-atom-input": "5", + "@s-ui/react-atom-input": "5.22.0-beta.0", "react-use": "17.4.0" } } diff --git a/components/molecule/dataCounter/package.json b/components/molecule/dataCounter/package.json index 87abbe2621..4baaf3b4f8 100644 --- a/components/molecule/dataCounter/package.json +++ b/components/molecule/dataCounter/package.json @@ -11,7 +11,7 @@ "dependencies": { "@s-ui/hoc": "1", "@s-ui/react-atom-button": "1", - "@s-ui/react-atom-input": "5", + "@s-ui/react-atom-input": "5.22.0-beta.0", "@s-ui/react-molecule-field": "1" }, "peerDependencies": { diff --git a/components/molecule/dropdownList/package.json b/components/molecule/dropdownList/package.json index 4a7f5e8273..847d518eb1 100644 --- a/components/molecule/dropdownList/package.json +++ b/components/molecule/dropdownList/package.json @@ -9,7 +9,7 @@ "build:styles": "cpx './src/**/*.scss' ./lib" }, "dependencies": { - "@s-ui/react-atom-input": "5", + "@s-ui/react-atom-input": "5.22.0-beta.0", "@s-ui/react-hooks": "1", "@s-ui/react-molecule-dropdown-option": "2", "@s-ui/react-primitive-injector": "1", diff --git a/components/molecule/dropdownOption/demo/package.json b/components/molecule/dropdownOption/demo/package.json index 6bf9ec4d8d..12bd984e71 100644 --- a/components/molecule/dropdownOption/demo/package.json +++ b/components/molecule/dropdownOption/demo/package.json @@ -11,7 +11,7 @@ "author": "", "license": "ISC", "dependencies": { - "@s-ui/react-atom-input": "5", + "@s-ui/react-atom-input": "5.22.0-beta.0", "@s-ui/react-hooks": "1", "lorem-ipsum": "2.0.4" } diff --git a/components/molecule/inputField/package.json b/components/molecule/inputField/package.json index 64c0db14df..09eaf0e649 100644 --- a/components/molecule/inputField/package.json +++ b/components/molecule/inputField/package.json @@ -9,7 +9,7 @@ "build:styles": "cpx './src/**/*.scss' ./lib" }, "dependencies": { - "@s-ui/react-atom-input": "5", + "@s-ui/react-atom-input": "5.22.0-beta.0", "@s-ui/react-molecule-field": "1" }, "peerDependencies": { diff --git a/components/molecule/inputTags/package.json b/components/molecule/inputTags/package.json index c49bbca278..1583f3a0c9 100644 --- a/components/molecule/inputTags/package.json +++ b/components/molecule/inputTags/package.json @@ -1,6 +1,6 @@ { "name": "@s-ui/react-molecule-input-tags", - "version": "2.25.0", + "version": "2.25.0-beta.1", "description": "", "main": "lib/index.js", "scripts": { @@ -9,8 +9,8 @@ "build:styles": "cpx './src/**/*.scss' ./lib" }, "dependencies": { - "@s-ui/react-atom-input": "5", - "@s-ui/react-atom-tag": "2", + "@s-ui/react-atom-input": "5.22.0-beta.0", + "@s-ui/react-atom-tag": "2.44.0-beta.0", "@s-ui/react-hooks": "1" }, "peerDependencies": { diff --git a/components/molecule/inputTags/src/config.js b/components/molecule/inputTags/src/config.js index 3e08958bd6..4e1ee64da9 100644 --- a/components/molecule/inputTags/src/config.js +++ b/components/molecule/inputTags/src/config.js @@ -1,3 +1,6 @@ +import {inputSizes} from '@s-ui/react-atom-input' +import {atomTagSizes} from '@s-ui/react-atom-tag' + export const BASE_CLASS = 'sui-AtomInput' export const CLASS_TAGS = `${BASE_CLASS}--withTags` export const CLASS_TAGS_FOCUS = `${CLASS_TAGS}--focus` @@ -12,4 +15,15 @@ export const isDuplicate = (values, newValue) => { return upperTags.includes(newValue.toUpperCase()) } +export const getInputToTagSize = inputSize => { + const conversor = { + [inputSizes.XSMALL]: atomTagSizes.XSMALL, + [inputSizes.SMALL]: atomTagSizes.SMALL, + [inputSizes.MEDIUM]: atomTagSizes.MEDIUM, + [inputSizes.LARGE]: atomTagSizes.LARGE, + [inputSizes.XLARGE]: atomTagSizes.XLARGE + } + return conversor[inputSize] +} + export const isFunction = fn => typeof fn === 'function' diff --git a/components/molecule/inputTags/src/index.js b/components/molecule/inputTags/src/index.js index 823c82910d..79da8ff01b 100644 --- a/components/molecule/inputTags/src/index.js +++ b/components/molecule/inputTags/src/index.js @@ -14,6 +14,7 @@ import { CLASS_TAGS_ERROR, CLASS_TAGS_FOCUS, CLASS_TAGS_SUCCESS, + getInputToTagSize, isDuplicate, isFunction } from './config.js' @@ -136,10 +137,11 @@ const MoleculeInputTags = forwardRef( label })} label={label} - size={atomTagSizes.SMALL} + size={getInputToTagSize(size)} responsive readOnly={readOnly} disabled={disabled} + isFitted /> ) })} @@ -156,6 +158,7 @@ const MoleculeInputTags = forwardRef( noBorder readOnly={readOnly} disabled={disabled} + size={size} placeholder={isEmpty ? placeholder : undefined} /> )} diff --git a/components/molecule/inputTags/src/styles/index.scss b/components/molecule/inputTags/src/styles/index.scss index e92b1804b2..f499e479bb 100644 --- a/components/molecule/inputTags/src/styles/index.scss +++ b/components/molecule/inputTags/src/styles/index.scss @@ -10,6 +10,7 @@ $class-input: '#{$base-class}-input'; display: flex; flex-wrap: wrap; padding: 0 0 0 $p-m; + gap: $p-base; &--focus { @include sui-atom-input-input-focus; @@ -22,6 +23,9 @@ $class-input: '#{$base-class}-input'; background-color: transparent; } } + &[aria-readonly='true'] { + background-color: $bgc-input-tag-read-only; + } & #{$class-input} { flex: 1; diff --git a/components/molecule/inputTags/src/styles/settings.scss b/components/molecule/inputTags/src/styles/settings.scss index 8fff321a6d..6c637513b9 100644 --- a/components/molecule/inputTags/src/styles/settings.scss +++ b/components/molecule/inputTags/src/styles/settings.scss @@ -1,3 +1,4 @@ $sizes-atom-input-paddings: m $p-m, s $p-s !default; -$bg-input-tag-disable: $c-gray-light-4 !default; +$bg-input-tag-disable: $bgc-atom-input-disabled; +$bgc-input-tag-read-only: $bgc-atom-input-read-only; $bdrs-molecule-input-tags: 0 !default; diff --git a/components/molecule/pagination/demo/package.json b/components/molecule/pagination/demo/package.json index e91ccbc06c..3f7e9f9cf8 100644 --- a/components/molecule/pagination/demo/package.json +++ b/components/molecule/pagination/demo/package.json @@ -12,7 +12,7 @@ "license": "ISC", "dependencies": { "@s-ui/react-atom-button": "1", - "@s-ui/react-atom-input": "5", + "@s-ui/react-atom-input": "5.22.0-beta.0", "@s-ui/react-layout-media-query": "1", "@s-ui/react-molecule-button-group": "2" } diff --git a/components/molecule/photoUploader/demo/package.json b/components/molecule/photoUploader/demo/package.json index 9a78a21592..f02b03078f 100644 --- a/components/molecule/photoUploader/demo/package.json +++ b/components/molecule/photoUploader/demo/package.json @@ -13,6 +13,6 @@ "dependencies": { "@s-ui/react-atom-button": "1", "@s-ui/react-molecule-dropdown-option": "2", - "@s-ui/react-molecule-select": "1" + "@s-ui/react-molecule-select": "1.57.0-beta.0" } } diff --git a/components/molecule/select/package.json b/components/molecule/select/package.json index 9a2b056e30..e193df4e77 100644 --- a/components/molecule/select/package.json +++ b/components/molecule/select/package.json @@ -1,6 +1,6 @@ { "name": "@s-ui/react-molecule-select", - "version": "1.57.0", + "version": "1.57.0-beta.0", "description": "", "main": "lib/index.js", "scripts": { @@ -10,10 +10,10 @@ }, "dependencies": { "@s-ui/js": "2", - "@s-ui/react-atom-input": "5", + "@s-ui/react-atom-input": "5.22.0-beta.0", "@s-ui/react-hooks": "1", "@s-ui/react-molecule-dropdown-list": "2", - "@s-ui/react-molecule-input-tags": "2", + "@s-ui/react-molecule-input-tags": "2.25.0-beta.1", "@s-ui/react-primitive-injector": "1" }, "peerDependencies": { diff --git a/components/molecule/select/src/components/MoleculeInputSelect.js b/components/molecule/select/src/components/MoleculeInputSelect.js index a4ac2f9d48..624e007a9e 100644 --- a/components/molecule/select/src/components/MoleculeInputSelect.js +++ b/components/molecule/select/src/components/MoleculeInputSelect.js @@ -20,8 +20,12 @@ const MoleculeInputSelect = props => { return (
- {children} - {iconArrow} + {iconArrow}} + {...props} + > + {children} +
) } diff --git a/components/molecule/select/src/components/MultipleSelection.js b/components/molecule/select/src/components/MultipleSelection.js index 17a718a43a..3d24d7e315 100644 --- a/components/molecule/select/src/components/MultipleSelection.js +++ b/components/molecule/select/src/components/MultipleSelection.js @@ -26,6 +26,7 @@ const MoleculeSelectFieldMultiSelection = props => { } = props const tags = values.map(value => optionsData[value]) + const isFull = () => maxTags && tags?.length >= maxTags const handleMultiSelection = (ev, {value: valueOptionSelected}) => { const handleToggle = ev => { @@ -42,8 +43,6 @@ const MoleculeSelectFieldMultiSelection = props => { const addToValues = () => [...values, valueOptionSelected] - const isFull = () => maxTags && tags?.length >= maxTags - if (isValueSelectedAlreadySelected()) { onChange(ev, {value: removeFromValues()}) } else if (!isFull()) { @@ -82,7 +81,7 @@ const MoleculeSelectFieldMultiSelection = props => { diff --git a/components/molecule/select/src/components/SingleSelection.js b/components/molecule/select/src/components/SingleSelection.js index 3cd9c56e94..34fc386db7 100644 --- a/components/molecule/select/src/components/SingleSelection.js +++ b/components/molecule/select/src/components/SingleSelection.js @@ -48,7 +48,7 @@ const MoleculeSelectSingleSelection = props => { size={selectSize} tabIndex={tabIndex} > - +