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

feat: add Intl.ListFormat to useFormatter #327

Merged
merged 10 commits into from
Jun 20, 2023
Prev Previous commit
Next Next commit
Add docs and fix formatting
amannn committed Jun 19, 2023
commit 7dafd7e4305976c7fbec8b76a9ab0b53bb779dbd
4 changes: 4 additions & 0 deletions docs/components/CodeSnippets.tsx
Original file line number Diff line number Diff line change
@@ -406,6 +406,10 @@ function standards() {
.RelativeTimeFormat
</span>
</span>
<span className="line">
<span style={{color: 'var(--shiki-token-constant)'}}>Intl</span>
<span style={{color: 'var(--shiki-color-text)'}}>.ListFormat</span>
</span>
<span className="line"> </span>
<span className="line">
<span style={{color: 'var(--shiki-color-text)'}}>
1 change: 1 addition & 0 deletions docs/pages/docs/usage/_meta.json
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
"messages": "Messages",
"numbers": "Numbers",
"dates-times": "Dates and times",
"lists": "Lists",
"configuration": "Configuration",
"error-handling": "Error handling",
"typescript": "TypeScript",
11 changes: 9 additions & 2 deletions docs/pages/docs/usage/configuration.mdx
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ For consistent results in end-to-end tests, it can be helpful to mock this value

## Global formats

To achieve consistent date, time and number formatting across your app, you can define a set of global formats and pass them to the provider.
To achieve consistent date, time, number and list formatting across your app, you can define a set of global formats and pass them to the provider.

```js
<NextIntlProvider
@@ -61,6 +61,12 @@ To achieve consistent date, time and number formatting across your app, you can
precise: {
maximumFractionDigits: 5
}
},
list: {
enumeration: {
style: 'long',
type: 'conjunction'
}
}
}}
>
@@ -76,10 +82,11 @@ function Component() {

format.dateTime(new Date('2020-11-20T10:36:01.516Z'), 'short');
format.number(47.414329182, 'precise');
format.enumeration(['HTML', 'CSS', 'JavaScript'], 'enumeration');
}
```

Global formats can be referenced in messages too.
Global formats for numbers, dates and times can be referenced in messages too.

```js filename="en.json"
{
29 changes: 29 additions & 0 deletions docs/pages/docs/usage/lists.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import Callout from 'components/Callout';
import PartnerContentLink from 'components/PartnerContentLink';

# List formatting

Depending on the users locale, lists of items should be formatted differently (e.g. "HTML, CSS, and JavaScript" in `en-US` vs. "HTML, CSS und JavaScript" in `de-DE`).

List formatting can be applied with the `useFormatter` hook:

```js
import {useFormatter} from 'next-intl';

function Component() {
const format = useFormatter();

const items = ['HTML', 'CSS', 'JavaScript'];
format.list(items, {type: 'conjunction'});
}
```

See [the MDN docs about `ListFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat) to learn more about the options that you can provide to `list` ([interactive explorer](https://www.intl-explorer.com/ListFormat)).

Note that lists can can currently only be formatted via `useFormatter`,
there's now equivalent inline syntax for messages at this point.

<Callout>
To reuse list formats for multiple components, you can configure [global
formats](/docs/usage/configuration#global-formats).
</Callout>
5 changes: 4 additions & 1 deletion docs/pages/docs/usage/runtime-requirements-polyfills.mdx
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ Based on the features you're using, you have to make sure your browser supports
- Number formatting: `Intl.NumberFormat` ([compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#browser_compatibility))
- Pluralization: `Intl.PluralRules` ([compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules/PluralRules#browser_compatibility))
- Relative time formatting: `Intl.RelativeTimeFormat` ([compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat#browser_compatibility))
- List formatting: `Intl.ListFormat` ([compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat#browser_compatibility))

If you target a browser that doesn't support all the required APIs, consider using polyfills. [Polyfill.io](https://polyfill.io/v3/) is a valuable solution for this that helps you to load only the polyfills you need for a given locale.

@@ -36,7 +37,9 @@ function IntlPolyfills() {
'Intl.PluralRules',
`Intl.PluralRules.~locale.${locale}`,
'Intl.RelativeTimeFormat',
`Intl.RelativeTimeFormat.~locale.${locale}`
`Intl.RelativeTimeFormat.~locale.${locale}`,
'Intl.ListFormat',
`Intl.ListFormat.~locale.${locale}`
];

return (
9 changes: 3 additions & 6 deletions packages/use-intl/src/core/createFormatter.tsx
Original file line number Diff line number Diff line change
@@ -177,15 +177,12 @@ export default function createFormatter({
}
}

function list(
function list(
value: Iterable<string>,
formatOrOptions?: string | Intl.ListFormatOptions
) {
return getFormattedValue(
value,
formatOrOptions,
formats?.list,
(options) => new Intl.ListFormat(locale, options).format(value)
return getFormattedValue(value, formatOrOptions, formats?.list, (options) =>
new Intl.ListFormat(locale, options).format(value)
);
}

8 changes: 4 additions & 4 deletions packages/use-intl/test/core/createFormatter.test.tsx
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ it('formats a relative time', () => {
});

it('formats a list', () => {
expect(
intl.list(['apple', 'banana', 'orange'], {type: 'disjunction'})
).toBe('apple, banana, or orange');
})
expect(intl.list(['apple', 'banana', 'orange'], {type: 'disjunction'})).toBe(
'apple, banana, or orange'
);
});