Skip to content

feat: add support for Devanagari & Bengali decimal numbering systems #6715

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

Merged
merged 6 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/@internationalized/number/src/NumberParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface Symbols {
}

const CURRENCY_SIGN_REGEX = new RegExp('^.*\\(.*\\).*$');
const NUMBERING_SYSTEMS = ['latn', 'arab', 'hanidec'];
const NUMBERING_SYSTEMS = ['latn', 'arab', 'hanidec', 'deva', 'beng'];

/**
* A NumberParser can be used to perform locale-aware parsing of numbers from Unicode strings,
Expand Down
8 changes: 8 additions & 0 deletions packages/@internationalized/number/test/NumberParser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,14 @@ describe('NumberParser', function () {

expect(new NumberParser('en-US', {style: 'decimal'}).getNumberingSystem('一二')).toBe('hanidec');
expect(new NumberParser('en-US', {style: 'decimal'}).getNumberingSystem('一二.五')).toBe('hanidec');

expect(new NumberParser('en-US', {style: 'decimal'}).getNumberingSystem('१२३४')).toBe('deva');
expect(new NumberParser('en-US', {style: 'decimal'}).getNumberingSystem('१२४,२')).toBe('deva');
expect(new NumberParser('en-US', {style: 'decimal'}).getNumberingSystem('२.३५१')).toBe('deva');

expect(new NumberParser('en-US', {style: 'decimal'}).getNumberingSystem('১২৩')).toBe('beng');
expect(new NumberParser('en-US', {style: 'decimal'}).getNumberingSystem('১.২৫৩')).toBe('beng');
expect(new NumberParser('en-US', {style: 'decimal'}).getNumberingSystem('১২৮,৪')).toBe('beng');
});
});
});
22 changes: 22 additions & 0 deletions packages/@react-spectrum/numberfield/test/NumberField.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2020,6 +2020,28 @@ describe('NumberField', function () {
expect(textField).toHaveAttribute('value', formatter.format(21));
});

it.each(locales)('%s can have devanagari numerals entered', async (locale) => {
let {textField} = renderNumberField({onChange: onChangeSpy, formatOptions: {style: 'currency', currency: 'USD'}}, {locale});

act(() => {textField.focus();});
await user.keyboard('२१');
act(() => {textField.blur();});

let formatter = new Intl.NumberFormat(locale + '-u-nu-deva', {style: 'currency', currency: 'USD'});
expect(textField).toHaveAttribute('value', formatter.format(21));
});

it.each(locales)('%s can have bengali numerals entered', async (locale) => {
let {textField} = renderNumberField({onChange: onChangeSpy, formatOptions: {style: 'currency', currency: 'USD'}}, {locale});

act(() => {textField.focus();});
await user.keyboard('২১');
act(() => {textField.blur();});

let formatter = new Intl.NumberFormat(locale + '-u-nu-beng', {style: 'currency', currency: 'USD'});
expect(textField).toHaveAttribute('value', formatter.format(21));
});

describe('beforeinput', () => {
let getTargetRanges = InputEvent.prototype.getTargetRanges;
beforeEach(() => {
Expand Down
2 changes: 2 additions & 0 deletions packages/dev/docs/pages/react-aria/home/I18n.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ export function I18n() {
<SelectItem id="latn">Latin</SelectItem>
<SelectItem id="arab">Arabic</SelectItem>
<SelectItem id="hanidec">Hanidec</SelectItem>
<SelectItem id="deva">Devanagari</SelectItem>
<SelectItem id="beng">Bengali</SelectItem>
</Select>
<Select label="Number Format" selectedKey={numberFormat} onSelectionChange={updateNumberFormat}>
<SelectItem id="decimal">Decimal</SelectItem>
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/docs/pages/react-aria/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ import {A11y} from './home/A11y';

<Section className="orange-gradient-background">
<h2><GradientText>Ready for an</GradientText> <span className="bg-clip-text bg-gradient-to-b from-yellow-500 to-orange-600">international</span> <GradientText>audience.</GradientText></h2>
<p>React Aria is engineered for internationalization out of the box, including translations in over 30 languages, localized date and number formatting and parsing, support for 13 calendar systems, 3 numbering systems, right-to-left layout, and more.</p>
<p>React Aria is engineered for internationalization out of the box, including translations in over 30 languages, localized date and number formatting and parsing, support for 13 calendar systems, 5 numbering systems, right-to-left layout, and more.</p>
<LearnMoreLink href="internationalization.html" className="text-orange-700 dark:text-orange-600 hover:bg-orange-400/[15%]" />

```tsx snippet
Expand Down
2 changes: 1 addition & 1 deletion packages/react-aria-components/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Over 40 components with built-in behavior, adaptive interactions, top-tier acces
* 🎨 **Styleable** – React Aria is style-free out of the box, allowing you to build custom designs to fit your application or design system using any styling and animation solution. Each component is broken down into individual parts with built-in states, render props, and slots that make styling a breeze.
* 📱 **Adaptive** – React Aria ensures a great experience for users, no matter their device. All components are optimized for mouse, touch, keyboard, and screen reader interactions, with a meticulous attention to detail that makes your app feel responsive and natural on every platform.
* ♿️ **Accessible** – React Aria is designed with accessibility as a top priority, and battle tested in production applications. All components are built to work across a wide variety of devices and assistive technologies to ensure the best experience possible for all users.
* 🌍 **International** – React Aria is engineered for internationalization out of the box, including translations in over 30 languages, localized date and number formatting and parsing, support for 13 calendar systems, 3 numbering systems, right-to-left layout, and more.
* 🌍 **International** – React Aria is engineered for internationalization out of the box, including translations in over 30 languages, localized date and number formatting and parsing, support for 13 calendar systems, 5 numbering systems, right-to-left layout, and more.
* ⚙️ **Customizable** – React Aria offers a flexible and scalable API that lets you dive as deep into the details as you like. Start with high-level components with a built-in DOM structure and simple styling API, compose custom patterns with contexts, and for the ultimate control, drop down to the low-level Hook-based API. Mix and match as needed.

## Documentation
Expand Down
2 changes: 1 addition & 1 deletion packages/react-aria-components/docs/NumberField.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ the stepper buttons. `NumberField` helps achieve accessible number fields that s
formatting options and can be styled as needed.

* **Customizable formatting** – Support for internationalized number formatting and parsing including decimals, percentages, currency values, and units. Multiple currency formats are supported, including symbol, code, and name in standard or accounting notation.
* **International** – Support for the Latin, Arabic, and Han positional decimal numbering systems in [over 30 locales](internationalization.html#supported-locales). The numbering system is automatically detected from user input, and input method editors such as Pinyin are supported.
* **International** – Support for the Latin, Arabic, Devanagari, Bengali, and Han positional decimal numbering systems in [over 30 locales](internationalization.html#supported-locales). The numbering system is automatically detected from user input, and input method editors such as Pinyin are supported.
* **Validation** – Keyboard input is validated as the user types so that only numeric input is accepted, according to the locale and numbering system. Values are automatically rounded and clamped according to configurable decimal, minimum, maximum, and step values. Custom client and server-side validation is also supported.
* **Mobile friendly** – An appropriate software keyboard is automatically selected based on the allowed values for ease of use.
* **Accessible** – Follows the [spinbutton](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/) ARIA pattern, with support for arrow keys, scroll wheel, and stepper buttons to increment and decrement the value. Extensively tested across many devices and [assistive technologies](accessibility.html#testing) to ensure announcements and behaviors are consistent.
Expand Down