Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: NumberInput state change caused by +/- icons are improperly propagated #18417

Closed
2 tasks done
splatch opened this issue Jan 24, 2025 · 1 comment
Closed
2 tasks done

Comments

@splatch
Copy link

splatch commented Jan 24, 2025

Package

@carbon/react

Browser

Firefox

Package version

v1.74.0

React version

v18.3.1

Description

Hello, since I am not an IBMer and found no better place to ask I bring my inquiry and bug report here.

Recently I been trying to construct a larger form and attempted to do it with react-hook-form, however I found that this hook doesn't work with carbon form components. I have tried it with <NumberInput> for first, eventually had to swap carbonized inputs to plain ones. The hook worked fine with plain <input>, as well as <TextInput> from carbon. However, it doesn't work with number input itself.
As far I understand react-hook-form uses input events such onblur and onchange to track state of form. When I clicked the +/- buttons on number input, the onChange event received on number input points to the button, rather than input field itself.
Given that react-hook-form is just one of the tools out there I am keen to hear what's the recommended way to conduct form processing with carbon.

What I started with:

{Object.keys(data).map(key => {
    let id = key.replaceAll('\.', '_');
    return (
        <FormGroup key={id} legendText={key} style={{marginBottom: '20px'}}>
            <Controller name={id} control={control} defaultValue={data[key]} render={({ field }) => (
                <input {...field} pattern="\d+"></input>
            )}/>
        </FormGroup>
    )
})}

Below one works:

{Object.keys(data).map(key => {
    let id = key.replaceAll('\.', '_');
    return (
        <FormGroup key={id} legendText={key} style={{marginBottom: '20px'}}>
            <Controller name={id} control={control} defaultValue={data[key]} render={({ field }) => (
                <TextInput {...field}></TextInput>
            )}/>
        </FormGroup>
    )
})}

But this one doesn't - the field state is not recognized if +/- buttons are used:

{Object.keys(data).map(key => {
    let id = key.replaceAll('\.', '_');
    return (
        <FormGroup key={id} legendText={key} style={{marginBottom: '20px'}}>
            <Controller name={id} control={control} defaultValue={data[key]} render={({ field }) => (
                <NumberInput {...field}></NumberInput>
            )}/>
        </FormGroup>
    )
})}

Best regards,
Łukasz

Reproduction/example

N/A

Steps to reproduce

Code samples provided above - the event handling differs between NumberInput and TextInput.

Suggested Severity

None

Application/PAL

No response

Code of Conduct

@tay1orjones
Copy link
Member

Hey thanks for opening this issue. This is probably because NumberInput uses custom buttons for the steppers, which changes the event.target. The native browser stepper buttons probably don't do this, which is why it works for the native input. It works on the TextInput because it doesn't contain any stepper buttons like that.

If the library you're using is expecting a different target you could interrupt the onChange call or modify the call signature

// just pseudocode, something like the below

function handleOnChange (event) {
  if (event.target.type === "input") {
    // only call this w/ the raw event for inputs
    field.onChange(event);
  } else {
    // craft your own custom event
    const customEvent = { ... , target: ref.current }
    field.onChange(customEvent);
  }
}

const { onChange, ...fieldWithoutOnChange } = field;

<NumberInput ref={ref} onChange={handleOnChange} {...fieldWithoutOnChange}></NumberInput>

Hope this helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: ✅ Done
Development

No branches or pull requests

2 participants