Skip to content

Commit

Permalink
Merge pull request #1667 from adevinta/fix-input-clear-btn-position
Browse files Browse the repository at this point in the history
fix(input): derivate input state from formField when possible
  • Loading branch information
Powerplex authored Nov 22, 2023
2 parents 33cd532 + 1d5f425 commit 4951a2f
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 12 deletions.
4 changes: 3 additions & 1 deletion packages/components/input/src/Input.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,9 @@ export const FieldInvalid: StoryFn = _args => {
<FormField name="title" state="error">
<FormField.Label>Title</FormField.Label>

<Input defaultValue="adevinta.com" />
<InputGroup>
<Input defaultValue="adevinta.com" />
</InputGroup>

<FormField.ErrorMessage>The URL is invalid</FormField.ErrorMessage>
</FormField>
Expand Down
29 changes: 18 additions & 11 deletions packages/components/input/src/InputGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ export const InputGroup = forwardRef<HTMLDivElement, PropsWithChildren<InputGrou
| undefined
const props = input?.props || {}

const field = useFormFieldControl()
const inputRef = useRef<HTMLInputElement>(null!)
const onClearRef = useRef(onClear)
const ref = useMergeRefs<HTMLInputElement>(input?.ref, inputRef)
Expand All @@ -67,19 +66,27 @@ export const InputGroup = forwardRef<HTMLDivElement, PropsWithChildren<InputGrou
props.defaultValue as string,
props.onValueChange
)

// Data derivated from FormField context
const field = useFormFieldControl()
const state = field.state ?? stateProp
const disabled = field.disabled || !!disabledProp
const readOnly = field.readOnly || !!readOnlyProp

// InputGroup elements (in visual order)
const leadingAddon = findElement('LeadingAddon')
const leadingIcon = findElement('LeadingIcon')
const clearButton = findElement('ClearButton')
const trailingIcon = state
? findElement('StateIndicator') || <InputStateIndicator />
: findElement('TrailingIcon')
const trailingAddon = findElement('TrailingAddon')
const stateIndicator = findElement('StateIndicator') || <InputStateIndicator />
const trailingIcon = state ? stateIndicator : findElement('TrailingIcon')

// Acknowledge which subComponents are used in the compound context
const hasLeadingAddon = !!leadingAddon
const hasTrailingAddon = !!trailingAddon
const hasLeadingIcon = !!leadingIcon
const hasTrailingIcon = !!trailingIcon || !!state
const disabled = field.disabled || !!disabledProp
const readOnly = field.readOnly || !!readOnlyProp
const hasClearButton = !!value && !!clearButton && !disabled && !readOnly

const handleChange: ChangeEventHandler<HTMLInputElement> = event => {
Expand All @@ -102,9 +109,9 @@ export const InputGroup = forwardRef<HTMLDivElement, PropsWithChildren<InputGrou

const current = useMemo(() => {
return {
state: stateProp,
disabled: !!disabledProp,
readOnly: !!readOnlyProp,
state,
disabled,
readOnly,
hasLeadingIcon,
hasTrailingIcon,
hasLeadingAddon,
Expand All @@ -113,9 +120,9 @@ export const InputGroup = forwardRef<HTMLDivElement, PropsWithChildren<InputGrou
onClear: handleClear,
}
}, [
stateProp,
disabledProp,
readOnlyProp,
state,
disabled,
readOnly,
hasLeadingIcon,
hasTrailingIcon,
hasLeadingAddon,
Expand Down

0 comments on commit 4951a2f

Please sign in to comment.