diff --git a/components/common/CharLimitedFieldset/index.module.scss b/components/common/CharLimitedFieldset/index.module.scss deleted file mode 100644 index 9d7bb37d..00000000 --- a/components/common/CharLimitedFieldset/index.module.scss +++ /dev/null @@ -1,3 +0,0 @@ -.Joined .Input::placeholder { - color: var(--text-tertiary); -} diff --git a/components/common/CharLimitedFieldset/index.tsx b/components/common/CharLimitedFieldset/index.tsx deleted file mode 100644 index 36967461..00000000 --- a/components/common/CharLimitedFieldset/index.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import React, { - ForwardRefRenderFunction, - forwardRef, - useEffect, - useState, -} from 'react' - -import classNames from 'classnames' -import styles from './index.module.scss' - -interface Props extends React.HTMLProps { - fieldName: string - placeholder: string - value?: string - limit: number - error: string - onBlur?: (event: React.ChangeEvent) => void - onChange?: (event: React.ChangeEvent) => void -} - -const CharLimitedFieldset: ForwardRefRenderFunction = ( - { - fieldName, - placeholder, - value, - limit, - error, - onBlur, - onChange: onInputChange, - ...props - }, - ref -) => { - // States - const [currentCount, setCurrentCount] = useState( - () => limit - (value || '').length - ) - - // Hooks - useEffect(() => { - setCurrentCount(limit - (value || '').length) - }, [limit, value]) - - // Event handlers - const handleInputChange = (event: React.ChangeEvent) => { - const { value: inputValue } = event.currentTarget - setCurrentCount(limit - inputValue.length) - if (onInputChange) { - onInputChange(event) - } - } - - // Rendering methods - return ( -
-
- - {currentCount} -
- {error.length > 0 &&

{error}

} -
- ) -} - -export default forwardRef(CharLimitedFieldset) diff --git a/components/common/Input/index.module.scss b/components/common/Input/index.module.scss index 3557fa93..b6fc4f36 100644 --- a/components/common/Input/index.module.scss +++ b/components/common/Input/index.module.scss @@ -5,9 +5,42 @@ border-radius: $input-corner; box-sizing: border-box; display: block; - padding: calc($unit-2x - 2px); width: 100%; + &:not(.wrapper) { + padding: $unit * 1.5 $unit-2x; + } + + &.wrapper { + $offset: 2px; + + align-items: center; + background: var(--input-bg); + border-radius: $input-corner; + border: $offset solid transparent; + box-sizing: border-box; + position: relative; + + .counter { + color: var(--text-tertiary); + display: block; + font-weight: $bold; + line-height: 42px; + position: absolute; + right: $unit-2x; + top: 0; + } + + input { + background: transparent; + border-radius: $input-corner; + border: none; + box-sizing: border-box; + padding: $unit * 1.5 $unit-2x; + width: 100%; + } + } + &[type='number']::-webkit-inner-spin-button { -webkit-appearance: none; } @@ -23,11 +56,6 @@ &:hover { background-color: var(--input-bound-bg-hover); } - - &::placeholder { - /* Chrome, Firefox, Opera, Safari 10.1+ */ - color: var(--text-tertiary) !important; - } } &.AlignRight { @@ -39,17 +67,12 @@ } } -.inputError { - color: $error; - font-size: $font-tiny; - margin: $unit 0; - padding: calc($unit / 2) ($unit * 2); - min-width: 100%; - width: 0; +.counter { + display: none; } -.input::placeholder { - /* Chrome, Firefox, Opera, Safari 10.1+ */ +.input::placeholder, +.input > input::placeholder { color: var(--text-secondary); - opacity: 1; /* Firefox */ + opacity: 1; } diff --git a/components/common/Input/index.tsx b/components/common/Input/index.tsx index 6744cf37..da194a24 100644 --- a/components/common/Input/index.tsx +++ b/components/common/Input/index.tsx @@ -3,61 +3,79 @@ import classNames from 'classnames' import styles from './index.module.scss' -interface Props - extends React.DetailedHTMLProps< - React.InputHTMLAttributes, - HTMLInputElement - > { +interface Props extends React.ComponentProps<'input'> { bound?: boolean - visible?: string - error?: string - label?: string + hide1Password?: boolean + showCounter?: boolean } const defaultProps = { - visible: 'true', + bound: false, + hide1Password: true, + showCounter: false, } -const Input = React.forwardRef(function Input( - { value, visible, bound, error, label, ...props }: Props, +const Input = React.forwardRef(function input( + { value, bound, showCounter, ...props }: Props, forwardedRef ) { // States - const [inputValue, setInputValue] = useState('') + const [currentCount, setCurrentCount] = useState(() => + props.maxLength ? props.maxLength - (`${value}` || '').length : 0 + ) // Classes - const classes = classNames( + const wrapperClasses = classNames( { - [styles.input]: true, - [styles.bound]: bound, + [styles.wrapper]: showCounter, + [styles.input]: showCounter, + [styles.bound]: showCounter && bound, }, - props.className + showCounter && + props.className?.split(' ').map((className) => styles[className]) + ) + + const inputClasses = classNames( + { + [styles.input]: !showCounter, + [styles.bound]: !showCounter && bound, + }, + !showCounter && + props.className?.split(' ').map((className) => styles[className]) ) const { defaultValue, ...inputProps } = props - // Change value when prop updates + // Hooks useEffect(() => { - if (value) setInputValue(`${value}`) - }, [value]) + if (props.maxLength) + setCurrentCount(props.maxLength - (`${value}` || '').length) + }, [props.maxLength, value]) + // Event handlers function handleChange(event: React.ChangeEvent) { - setInputValue(event.target.value) if (props.onChange) props.onChange(event) } + // Rendering return ( - +
- {error && error.length > 0 &&

{error}

} - + {currentCount} +
) })