Skip to content

Commit

Permalink
fix(uncontrolled ability): allows component to be uncontrolled as wel…
Browse files Browse the repository at this point in the history
…l controlled
  • Loading branch information
wmangimelli committed Sep 13, 2020
1 parent c13e01c commit 8afbd40
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,85 @@ storiesOf('TextInput', module)
cols={number('cols', 0, undefined, multilineGroup)}
isValid={boolean('isValid', true, errorMessageGroup)}
errorMessage={text('errorMessage', '', errorMessageGroup)}
defaultValue={text('defaultValue', '', generalGroup)}
type={text('type', '', generalGroup)}
onInput={onInputCallback}
onKeyPress={onKeyPressCallback}
onKeyDown={onKeyDownCallback}
onKeyUp={onKeyUpCallback}
onFocus={onFocusCallback}
onBlur={onBlurCallback}
multiLineIsResizable={boolean('multiLineIsResizable', false, multilineGroup)}
showCharacterCount={boolean('showCharacterCount', true, characterCountGroup)}
maxLength={select(
'maxLength',
{ 5: 5, 20: 20, 100: 100, none: undefined },
20,
characterCountGroup,
)}
allowTextBeyondMaxLength={boolean('allowTextBeyondMaxLength', false, characterCountGroup)}
/>
);
},
{ design },
).add(
'Uncontrolled Text Input',
() => {
const options = {
none: '',
...IconPaths,
};

// Setup callbacks to prevent unnecessary rendering
const onChangeCallback = useCallback(event => {
action('onChange')(event.target.value);
}, []);
const onDebounceCallback = useCallback(event => {
action('onDebounceCallback')(event.target.value);
}, []);
const onClearCallback = useCallback(() => {
setInputValue('');
action('onClear')();
}, []);
const onFocusCallback = useCallback(event => {
action('onFocusCallback')(event.target.value);
}, []);
const onBlurCallback = useCallback(event => {
action('onBlurCallback')(event.target.value);
}, []);
const onInputCallback = useCallback(event => {
action('onInputCallback')(event.target.value);
}, []);
const onKeyPressCallback = useCallback(event => {
action('onKeypressCallback')(event.key);
}, []);
const onKeyDownCallback = useCallback(event => {
action('onKeyDownCallback')(event.key);
}, []);
const onKeyUpCallback = useCallback(event => {
action('onKeyUpCallback')(event.key);
}, []);

const generalGroup = 'General';
const multilineGroup = 'Multiline';
const errorMessageGroup = 'Error messages';
const debounceGroup = 'Debounced';
const characterCountGroup = 'Character count';

return (
<TextInput
aria-label={text('ariaLabel', 'textInput', generalGroup)}
onChange={onChangeCallback}
debounceInterval={number('debounceInterval', 150, undefined, debounceGroup)}
debouncedOnChange={onDebounceCallback}
disabled={boolean('disabled', false, generalGroup)}
placeholder={text('placeholder', 'Placeholder', generalGroup)}
onClear={boolean('clearable', false, generalGroup) ? onClearCallback : undefined}
iconPrefix={select('iconPrefix', options, options.none, generalGroup)}
isMultiline={boolean('isMultiline?', false, multilineGroup)}
rows={number('rows', 0, undefined, multilineGroup)}
cols={number('cols', 0, undefined, multilineGroup)}
isValid={boolean('isValid', true, errorMessageGroup)}
errorMessage={text('errorMessage', '', errorMessageGroup)}
type={text('type', '', generalGroup)}
onInput={onInputCallback}
onKeyPress={onKeyPressCallback}
Expand Down
11 changes: 6 additions & 5 deletions packages/hs-react-ui/src/components/TextInput/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, {
ReactNode,
SyntheticEvent,
useCallback,
useState,
TextareaHTMLAttributes,
InputHTMLAttributes,
} from 'react';
Expand Down Expand Up @@ -144,14 +145,14 @@ const defaultCallback = () => {}; // eslint-disable-line @typescript-eslint/no-e

const TextInput = ({
// Destructure native HTML attributes to provide default values
defaultValue = '',
type = 'text',
disabled = false,
cols = 10,
rows = 10,

debouncedOnChange = defaultCallback,
onClear,
onChange,
iconPrefix,
isValid = true,
isMultiline,
Expand Down Expand Up @@ -186,13 +187,12 @@ const TextInput = ({
} else if (isMultiline) {
InputComponent = TextAreaInputContainer;
}
const displayValue = nativeHTMLAttributes.value || defaultValue;
const [displayValue, setDisplayValue] = useState(nativeHTMLAttributes.value || '');

return (
<StyledContainer disabled={disabled} isValid={isValid} {...containerProps}>
{iconPrefix && createIcon(StyledIconContainer, iconPrefix)}
<InputComponent
value={displayValue}
type={type}
disabled={disabled}
cols={cols}
Expand All @@ -204,8 +204,9 @@ const TextInput = ({
? e.target.value
: e.target.value.slice(0, maxLength);
}
if (nativeHTMLAttributes.onChange) {
nativeHTMLAttributes.onChange(e);
setDisplayValue(e.target.value);
if (onChange) {
onChange(e);
}
debouncedChange(e);
}}
Expand Down

0 comments on commit 8afbd40

Please sign in to comment.