Skip to content

feat: numberfield announce pasted value #8604

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

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

snowystinger
Copy link
Member

Closes #4967

Split out of #6520

✅ Pull Request Checklist:

  • Included link to corresponding React Spectrum GitHub Issue.
  • Added/updated unit tests and storybook for this change (for new code or code which already has tests).
  • Filled out test instructions.
  • Updated documentation (if it already exists for this component).
  • Looked at the Accessibility Practices for this feature - Aria Practices

📝 Test Instructions:

🧢 Your Project:

@rspbot
Copy link

rspbot commented Jul 24, 2025

Copy link
Member

@LFDanLu LFDanLu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how best should we go about testing that this works with all kinds of locales/number formats? I was able to confirm the behavior with values like 3.000.000,25 and 1.000, but I guess it might be good enough that those pass since the parsing/formatting/validating is tested elsewhere

Comment on lines +200 to +202
let value = state.parser.parse(pastedText);
let reformattedValue = numberFormatter.format(value);
if (state.validate(reformattedValue)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does there exist a case where the pastedText is considered valid but is unable to be parsed? The description of parse seems to suggest that might be the case, but digging to see if that is the case. Just concerned if there are any cases where we make it here but end up not announcing that we couldn't parse the value

"numberField": "حقل رقمي"
"numberField": "حقل رقمي",
"pastedValue": "Pasted value: {value}",
"couldNotParseValue": "Could not understand value: {value}, try another format perhaps"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mega nit for more assertive message haha:

Suggested change
"couldNotParseValue": "Could not understand value: {value}, try another format perhaps"
"couldNotParseValue": "Could not understand value: {value}, please try another number format"

@devongovett
Copy link
Member

Couldn't the original problem from #4967 still exist? If you typed the value (rather than pasted) and then blurred, and our parsing resulted in something different, it wouldn't get announced. Should we just announce the formatted value on blur instead of paste?

@snowystinger
Copy link
Member Author

snowystinger commented Jul 26, 2025

Couldn't the original problem from #4967 still exist? If you typed the value (rather than pasted) and then blurred, and our parsing resulted in something different, it wouldn't get announced. Should we just announce the formatted value on blur instead of paste?

Yeah, I was debating this, as the changes also exposed parse on the state object, which I wasn't thrilled with, in case the parser suddenly changed one render to another

announcing in onBlur isn't quite right either, we don't know if the value is going to be accepted by a controlled component, so in that case the during paste was more "correct"

we could do it in an effect after, but then it gets hard to know if we're just announcing typing (based on inputValue) or if we base it on value, then we may get no announcement if it failed to write a new number and reverted

# Conflicts:
#	packages/@react-aria/numberfield/package.json
#	yarn.lock
@rspbot
Copy link

rspbot commented Jul 26, 2025

@rspbot
Copy link

rspbot commented Jul 26, 2025

## API Changes

react-aria-components

/react-aria-components:NumberFieldState

 NumberFieldState {
   canDecrement: boolean
   canIncrement: boolean
   commit: () => void
   commitValidation: () => void
   decrement: () => void
   decrementToMin: () => void
   defaultNumberValue: number
   displayValidation: ValidationResult
   increment: () => void
   incrementToMax: () => void
   inputValue: string
   maxValue?: number
   minValue?: number
   numberValue: number
+  parser: NumberParser
   realtimeValidation: ValidationResult
   resetValidation: () => void
   setInputValue: (string) => void
   setNumberValue: (number) => void
   validate: (string) => boolean
 }

@react-stately/color

/@react-stately/color:ColorChannelFieldState

 ColorChannelFieldState {
   canDecrement: boolean
   canIncrement: boolean
   colorValue: Color
   commit: () => void
   commitValidation: () => void
   decrement: () => void
   decrementToMin: () => void
   defaultColorValue: Color | null
   defaultNumberValue: number
   displayValidation: ValidationResult
   increment: () => void
   incrementToMax: () => void
   inputValue: string
   maxValue?: number
   minValue?: number
   numberValue: number
+  parser: NumberParser
   realtimeValidation: ValidationResult
   resetValidation: () => void
   setColorValue: (Color | null) => void
   setInputValue: (string) => void
   updateValidation: (ValidationResult) => void
   validate: (string) => boolean
 }

@react-stately/numberfield

/@react-stately/numberfield:NumberFieldState

 NumberFieldState {
   canDecrement: boolean
   canIncrement: boolean
   commit: () => void
   commitValidation: () => void
   decrement: () => void
   decrementToMin: () => void
   defaultNumberValue: number
   displayValidation: ValidationResult
   increment: () => void
   incrementToMax: () => void
   inputValue: string
   maxValue?: number
   minValue?: number
   numberValue: number
+  parser: NumberParser
   realtimeValidation: ValidationResult
   resetValidation: () => void
   setInputValue: (string) => void
   setNumberValue: (number) => void
   validate: (string) => boolean
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

useNumberField mutates number so screenreader users won’t know that their value has changed
4 participants