@servicetitan/docs-anvil-uikit-contrib 32.4.0 → 32.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/intl/API/intl-provider.mdx +22 -0
- package/docs/intl/API/intl-store-provider.mdx +23 -0
- package/docs/intl/API/intlstore.mdx +38 -0
- package/docs/intl/API/use-intl.mdx +64 -0
- package/docs/intl/dates.mdx +88 -0
- package/docs/intl/index.mdx +86 -0
- package/docs/intl/numbers.mdx +64 -0
- package/docs/intl/plurals.mdx +75 -0
- package/docs/tanstack-query-mobx.mdx +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: IntlProvider
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Applications must be wrapped with the `<IntlProvider>` component in order to access internationalization features throughout the application.
|
|
6
|
+
|
|
7
|
+
`locale` and `timeZone` may be passed to the provider via the `config` prop. `locale` defaults to `en-US` and `timeZone` defaults to the user's local time zone if not provided.
|
|
8
|
+
|
|
9
|
+
The config object must be wrapped with `useMemo` to avoid unnecessary re-renders.
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
import { IntlConfig, IntlProvider } from '@servicetitan/intl';
|
|
13
|
+
|
|
14
|
+
const locale = 'en-US';
|
|
15
|
+
const timeZone = 'America/Los_Angeles';
|
|
16
|
+
const intlConfig: IntlConfig = useMemo(() => ({ locale, timeZone }), [locale, timeZone]);
|
|
17
|
+
return (
|
|
18
|
+
<IntlProvider config={intlConfig}>
|
|
19
|
+
<App />
|
|
20
|
+
</IntlProvider>
|
|
21
|
+
);
|
|
22
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: IntlStoreProvider
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Applications may be wrapped with the `<IntlStoreProvider>` component in order to provide access to internationalization features in MobX stores.
|
|
6
|
+
|
|
7
|
+
`<IntlStoreProvider>` must be a child of `<IntlProvider>`, and should be placed as high in the component tree as possible to ensure all stores have access to the `IntlStore`.
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { IntlProvider } from '@servicetitan/intl';
|
|
11
|
+
import { IntlStoreProvider } from '@servicetitan/intl/mobx';
|
|
12
|
+
|
|
13
|
+
const locale = 'en-US';
|
|
14
|
+
const timeZone = 'America/Los_Angeles';
|
|
15
|
+
const intlConfig: IntlConfig = useMemo(() => ({ locale, timeZone }), [locale, timeZone]);
|
|
16
|
+
return (
|
|
17
|
+
<IntlProvider config={intlConfig}>
|
|
18
|
+
<IntlStoreProvider>
|
|
19
|
+
<App />
|
|
20
|
+
</IntlStoreProvider>
|
|
21
|
+
</IntlProvider>
|
|
22
|
+
);
|
|
23
|
+
```
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: IntlStore
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
The `IntlStore` is a dependency injected store that provides access to internationalization functionality in MobX stores in situations where formatting within React components is not possible.
|
|
6
|
+
|
|
7
|
+
:::note
|
|
8
|
+
It is preferred to use the [`useIntl` hook](./use-intl.mdx) instead of directly accessing the `IntlStore`, as it is preferred to do formatting in the "view" layer of your application vs the "data" layer.
|
|
9
|
+
:::
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
The `IntlStore` is an injectable store that maintains an [`intl`](https://formatjs.github.io/docs/react-intl/api#intlshape) object with the same formatting functions and locale information available through the [`useIntl`](./use-intl.mdx) hook. It extends the standard `react-intl` functionality with custom ServiceTitan formatters. The `IntlStore` is provided by a combination of [`IntlProvider`](./intl-provider.mdx) and [`IntlStoreProvider`](./intl-store-provider.mdx), and is updated when `IntlProvider`'s props change.
|
|
14
|
+
|
|
15
|
+
## Basic Usage
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { inject, injectable } from '@servicetitan/react-ioc';
|
|
19
|
+
import { IntlStore } from '@servicetitan/intl/mobx';
|
|
20
|
+
|
|
21
|
+
@injectable()
|
|
22
|
+
export class UserService {
|
|
23
|
+
constructor(@inject(IntlStore) private intlStore: IntlStore) {}
|
|
24
|
+
|
|
25
|
+
formatUserData(user: User) {
|
|
26
|
+
const intl = this.intlStore.intl;
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
joinDate: intl.formatDate(user.joinDate, { format: 'long' }),
|
|
30
|
+
balance: intl.formatNumber(user.balance, { style: 'currency', currency: 'USD' })
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Available Functions
|
|
37
|
+
|
|
38
|
+
See [`useIntl`](./use-intl.mdx#available-functions) for a list of functions and properties available in the `intl` object.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: useIntl
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
The `useIntl` hook is the primary way to access direct internationalization functions in your React components. It provides access to all formatting functions and locale information needed for internationalization.
|
|
6
|
+
|
|
7
|
+
:::note
|
|
8
|
+
If using [`react-intl` Formatted components](https://formatjs.github.io/docs/react-intl/components)--such as those described in [Dates and Time](../dates.mdx), [Numbers and Currency](../numbers.mdx), and [Plurals](../plurals.mdx) documentation--you do not need to use the `useIntl` hook directly.
|
|
9
|
+
:::
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
The `useIntl` hook extends the standard [`react-intl` `useIntl`](https://formatjs.github.io/docs/react-intl/api/#useintl-hook) hook with additional custom formatters specific to ServiceTitan applications. It returns an `intl` object that contains all the formatting functions and locale information.
|
|
14
|
+
|
|
15
|
+
## Basic Usage
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { useIntl } from '@servicetitan/intl';
|
|
19
|
+
|
|
20
|
+
function MyComponent() {
|
|
21
|
+
const intl = useIntl();
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div>
|
|
25
|
+
<p>Current locale: {intl.locale}</p>
|
|
26
|
+
<p>Current timezone: {intl.timeZone}</p>
|
|
27
|
+
<p>Formatted date: {intl.formatDate(new Date(), { format: 'short' })}</p>
|
|
28
|
+
<p>Formatted currency: {intl.formatNumber(1234.56, { style: 'currency', currency: 'USD' })}</p>
|
|
29
|
+
</div>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Available Functions
|
|
35
|
+
|
|
36
|
+
The [`intl`](https://formatjs.github.io/docs/react-intl/api#intlshape) object returned by `useIntl` provides access to [all standard `Format.js` formatting functions](https://formatjs.github.io/docs/react-intl/api#intlshape), plus custom ServiceTitan formatters:
|
|
37
|
+
|
|
38
|
+
### Standard Formatting Functions
|
|
39
|
+
|
|
40
|
+
- [`formatDate()`](../dates.mdx) - Format dates and times
|
|
41
|
+
- [`formatDisplayName()`](https://formatjs.github.io/docs/react-intl/api/#formatdisplayname) - Format display names for locales, currencies, etc.
|
|
42
|
+
- [`formatList()`](https://formatjs.github.io/docs/react-intl/api/#formatlist) - Format lists of items
|
|
43
|
+
- [`formatMessage()`](https://formatjs.github.io/docs/react-intl/api/#formatmessage) - Format messages with interpolation (note: translating messages is not yet configured within ServiceTitan)
|
|
44
|
+
- [`formatNumber()`](../numbers.mdx) - Format numbers and currency
|
|
45
|
+
- [`formatPlural()`](https://formatjs.github.io/docs/react-intl/api/#formatplural) - Handle pluralization
|
|
46
|
+
- [`formatRelativeTime()`](https://formatjs.github.io/docs/react-intl/api/#formatrelativetime) - Format relative time (e.g., "2 hours ago")
|
|
47
|
+
- [`formatTime()`](https://formatjs.github.io/docs/react-intl/api/#formattime) - Format time values
|
|
48
|
+
|
|
49
|
+
### Custom ServiceTitan Formatters
|
|
50
|
+
|
|
51
|
+
- [`formatPluralMessage()`](../plurals.mdx#formatpluralmessage) - Provide a number and messages associated with plural forms, and receive the appropriate message for the current locale and plural form
|
|
52
|
+
|
|
53
|
+
### Locale Information
|
|
54
|
+
|
|
55
|
+
- `locale` - Current locale (e.g., 'en-US')
|
|
56
|
+
- `timeZone` - Current time zone
|
|
57
|
+
- `messages` - Available messages for the current locale (note: translating messages is not yet configured within ServiceTitan)
|
|
58
|
+
|
|
59
|
+
## See Also
|
|
60
|
+
|
|
61
|
+
For detailed information about specific formatting functions and their options, refer to the Format.js documentation:
|
|
62
|
+
|
|
63
|
+
- [useIntl Hook Documentation](https://formatjs.github.io/docs/react-intl/api/#useintl-hook) which our `useIntl` is a wrapper around
|
|
64
|
+
- [Format.JS Imperative API](https://formatjs.github.io/docs/react-intl/api/) contains all of the formatting functions available on the `intl` object
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Dates and Times
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
import Tabs from '@theme/Tabs';
|
|
6
|
+
|
|
7
|
+
Dates and times can be formatted either by using the [`FormattedDate`](#formatteddate) component from `react-intl`, or via the [`formatDate`](#formatdate) function as part of the `intl` object, which can be retrieved via the [`useIntl`](./API/use-intl.mdx) hook or through the [`IntlStore`](./API/intlstore.mdx) store.
|
|
8
|
+
|
|
9
|
+
## Available Formats
|
|
10
|
+
|
|
11
|
+
The following standard ServiceTitan formats are available to use as part of date/time formatting. The formats follow the "Dates and time" section of the ["Style Guide - General guidelines"](https://servicetitan.atlassian.net/wiki/spaces/DTW/pages/262701057/Style+Guide+-+General+guidelines#Dates-and-time).
|
|
12
|
+
|
|
13
|
+
- `short` results in `09/02/25`
|
|
14
|
+
- `long` results in `September 2, 2025`
|
|
15
|
+
- `timeShort` results in `4:00 PM`
|
|
16
|
+
- `timeMedium` results in `4:00:00 PM`
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### FormattedDate
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { FormattedDate } from 'react-intl';
|
|
24
|
+
...
|
|
25
|
+
<FormattedDate value={new Date()} format="short" />
|
|
26
|
+
// Results in 09/02/25
|
|
27
|
+
<FormattedDate value={new Date()} format="long" />
|
|
28
|
+
// Results in September 2, 2025
|
|
29
|
+
<FormattedDate value={new Date()} format="timeShort" />
|
|
30
|
+
// Results in 4:00 PM
|
|
31
|
+
<FormattedDate value={new Date()} format="timeMedium" />
|
|
32
|
+
// Results in 4:00:00 PM
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### formatDate
|
|
36
|
+
|
|
37
|
+
<Tabs
|
|
38
|
+
defaultValue="hooks"
|
|
39
|
+
values={[
|
|
40
|
+
{ label: 'React hooks', value: 'hooks' },
|
|
41
|
+
{ label: 'Store', value: 'store' },
|
|
42
|
+
]}
|
|
43
|
+
>
|
|
44
|
+
<TabItem value="hooks">
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { useIntl } from '@servicetitan/intl';
|
|
48
|
+
...
|
|
49
|
+
const intl = useIntl();
|
|
50
|
+
...
|
|
51
|
+
intl.formatDate(new Date(), { format: 'short' });
|
|
52
|
+
// Results in 09/02/25
|
|
53
|
+
intl.formatDate(new Date(), { format: 'long' });
|
|
54
|
+
// Results in September 2, 2025
|
|
55
|
+
intl.formatDate(new Date(), { format: 'timeShort' });
|
|
56
|
+
// Results in 4:00 PM
|
|
57
|
+
intl.formatDate(new Date(), { format: 'timeMedium' });
|
|
58
|
+
// Results in 4:00:00 PM
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
</TabItem>
|
|
62
|
+
<TabItem value="store">
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
import { IntlStore } from '@servicetitan/intl/mobx';
|
|
66
|
+
...
|
|
67
|
+
@injectable()
|
|
68
|
+
class MyStore {
|
|
69
|
+
constructor(@inject(IntlStore) private readonly intlStore: IntlStore) {}
|
|
70
|
+
...
|
|
71
|
+
this.intlStore.intl.formatDate(new Date(), { format: 'short' });
|
|
72
|
+
// Results in 09/02/25
|
|
73
|
+
this.intlStore.intl.formatDate(new Date(), { format: 'long' });
|
|
74
|
+
// Results in September 2, 2025
|
|
75
|
+
this.intlStore.intl.formatDate(new Date(), { format: 'timeShort' });
|
|
76
|
+
// Results in 4:00 PM
|
|
77
|
+
this.intlStore.intl.formatDate(new Date(), { format: 'timeMedium' });
|
|
78
|
+
// Results in 4:00:00 PM
|
|
79
|
+
...
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
</TabItem>
|
|
84
|
+
</Tabs>
|
|
85
|
+
|
|
86
|
+
### Further customization
|
|
87
|
+
|
|
88
|
+
If you need to customize the formatting further, `FormattedDate` and `formatDate` accept the same options as the native `Intl.DateTimeFormat` API. See [`Intl.DateTimeFormat` for more information about those options](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat), and see Format.js [`FormattedDate` documentation](https://formatjs.github.io/docs/react-intl/components/#formatteddate) or [`formatDate` documentation](https://formatjs.github.io/docs/react-intl/api/#formatdate) for more information on how to use them.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Intl (Internationalization)
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
`@servicetitan/intl` is a solution for helping setup internationalization in React and MobX projects that is a light wrapper around [`Format.js`](https://formatjs.github.io/) and [`react-intl`](https://formatjs.github.io/docs/react-intl/). This library creates an internationalization API with a provided *locale* and *timeZone*, and provides that API to `react-intl` to be used within React context, as well as a store to be used within MobX.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
This project should be installed as one of your project's `dependencies`:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @servicetitan/intl
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This library has `peerDependencies` for:
|
|
16
|
+
- `"@servicetitan/react-ioc": ">=22.0.0"`
|
|
17
|
+
- `"react-intl": ">=7.1.11"`
|
|
18
|
+
|
|
19
|
+
### IntlProvider
|
|
20
|
+
|
|
21
|
+
Wrap your application in the `<IntlProvider>` component, providing `locale` and `timeZone` through the `config` prop:
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { IntlProvider } from '@servicetitan/intl';
|
|
25
|
+
|
|
26
|
+
const locale = 'en-US';
|
|
27
|
+
const timeZone = 'America/Los_Angeles';
|
|
28
|
+
const intlConfig: IntlConfig = useMemo(() => ({ locale, timeZone }), [locale, timeZone]);
|
|
29
|
+
return (
|
|
30
|
+
<IntlProvider config={intlConfig}>
|
|
31
|
+
<App />
|
|
32
|
+
</IntlProvider>
|
|
33
|
+
);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
`Format.js` and `react-intl` provide many components and utilities for handling internationalization, including caching and wrapping most of the [native `Intl` formatters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl). The following APIs are are particularly useful to us at this stage:
|
|
39
|
+
|
|
40
|
+
- [Formatting dates and time](./dates.mdx)
|
|
41
|
+
- [Formatting numbers and currency](./numbers.mdx)
|
|
42
|
+
- [Plurals](./plurals.mdx)
|
|
43
|
+
|
|
44
|
+
:::note
|
|
45
|
+
Translating messages is not yet supported, as we currently have no need for it. But using `@servicetitan/intl` ensures the framework is in place for when we do begin translating messages.
|
|
46
|
+
:::
|
|
47
|
+
|
|
48
|
+
## React Hooks vs Store
|
|
49
|
+
|
|
50
|
+
We recommend using the hooks API to access the internationalization API for most cases, as it is preferred to do formatting in the "view" layer of your application vs the "data" layer.
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import { useIntl } from '@servicetitan/intl';
|
|
54
|
+
|
|
55
|
+
function MyComponent() {
|
|
56
|
+
const intl = useIntl();
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<div>
|
|
60
|
+
<p>Formatted date: {intl.formatDate(new Date(), { format: 'short' })}</p>
|
|
61
|
+
<p>Formatted currency: {intl.formatNumber(1234.56, { style: 'currency', currency: 'USD' })}</p>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
However, if you have the need to access the internationalization API in MobX stores, you must use an additional wrapper component, [`<IntlStoreProvider>`](./API/intl-store-provider.mdx), and you can use the provided `IntlStore` to access the same functionality.
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { inject, injectable } from '@servicetitan/react-ioc';
|
|
71
|
+
import { IntlStore } from '@servicetitan/intl/mobx';
|
|
72
|
+
|
|
73
|
+
@injectable()
|
|
74
|
+
export class UserService {
|
|
75
|
+
constructor(@inject(IntlStore) private intlStore: IntlStore) {}
|
|
76
|
+
|
|
77
|
+
formatUserData(user: User) {
|
|
78
|
+
const intl = this.intlStore.intl;
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
joinDate: intl.formatDate(user.joinDate, { format: 'long' }),
|
|
82
|
+
balance: intl.formatNumber(user.balance, { style: 'currency', currency: 'USD' })
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Numbers and Currency
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
import Tabs from '@theme/Tabs';
|
|
6
|
+
|
|
7
|
+
Numbers and currency can be formatted either by using the `FormattedNumber` component from `react-intl`, or via the `formatNumber()` function as part of the `intl` object, which can be retrieved via the [`useIntl()`](./API/use-intl.mdx) hook or through the [`IntlStore`](./API/intlstore.mdx) store.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
### FormattedNumber
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { FormattedNumber } from 'react-intl';
|
|
15
|
+
...
|
|
16
|
+
<FormattedNumber value={1234.56} style="currency" currency="USD" />
|
|
17
|
+
<FormattedNumber value={0.75} style="percent" />
|
|
18
|
+
<FormattedNumber value={1234.567} maximumFractionDigits={2} />
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### formatNumber
|
|
22
|
+
|
|
23
|
+
<Tabs
|
|
24
|
+
defaultValue="hooks"
|
|
25
|
+
values={[
|
|
26
|
+
{ label: 'React hooks', value: 'hooks' },
|
|
27
|
+
{ label: 'Store', value: 'store' },
|
|
28
|
+
]}
|
|
29
|
+
>
|
|
30
|
+
<TabItem value="hooks">
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { useIntl } from '@servicetitan/intl';
|
|
34
|
+
...
|
|
35
|
+
const intl = useIntl();
|
|
36
|
+
...
|
|
37
|
+
intl.formatNumber(1234.56, { style: 'currency', currency: 'USD' });
|
|
38
|
+
intl.formatNumber(0.75, { style: 'percent' });
|
|
39
|
+
intl.formatNumber(1234.567, { maximumFractionDigits: 2 });
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
</TabItem>
|
|
43
|
+
<TabItem value="store">
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
import { IntlStore } from '@servicetitan/intl/mobx';
|
|
47
|
+
...
|
|
48
|
+
@injectable()
|
|
49
|
+
class MyStore {
|
|
50
|
+
constructor(@inject(IntlStore) private readonly intlStore: IntlStore) {}
|
|
51
|
+
...
|
|
52
|
+
this.intlStore.intl.formatNumber(1234.56, { style: 'currency', currency: 'USD' });
|
|
53
|
+
this.intlStore.intl.formatNumber(0.75, { style: 'percent' });
|
|
54
|
+
this.intlStore.intl.formatNumber(1234.567, { maximumFractionDigits: 2 });
|
|
55
|
+
...
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
</TabItem>
|
|
60
|
+
</Tabs>
|
|
61
|
+
|
|
62
|
+
### Further customization
|
|
63
|
+
|
|
64
|
+
If you need to customize the formatting further, `FormattedNumber` and `formatNumber` accept the same options as the native `Intl.NumberFormat` API. See [`Intl.NumberFormat` for more information about those options](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat), and see Format.js [`FormattedNumber` documentation](https://formatjs.github.io/docs/react-intl/components/#formattednumber) or [`formatNumber` documentation](https://formatjs.github.io/docs/react-intl/api/#formatnumber) for more information on how to use them.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Plurals
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
import Tabs from '@theme/Tabs';
|
|
6
|
+
|
|
7
|
+
Plurals can be formatted by using the `FormattedPlural` component from `react-intl`, or via the `formatPluralMessage()` function as part of the `intl` object, which can be retrieved via the [`useIntl()`](./API/use-intl.mdx) hook or through the [`IntlStore`](./API/intlstore.mdx) store.
|
|
8
|
+
|
|
9
|
+
[`FormattedPlural`](#formattedplural) and [`formatPluralMessage()`](#formatpluralmessage) are only meant to be used with one language. Since ServiceTitan currently only supports English, and [English only uses "one" and "other" forms](https://www.unicode.org/cldr/charts/42/supplemental/language_plural_rules.html#en), those will be the only forms you will use at this time.
|
|
10
|
+
|
|
11
|
+
:::note
|
|
12
|
+
When ServiceTitan eventually supports multiple languages, the library will be updated to support `FormattedMessage` and `formatMessage`.
|
|
13
|
+
:::
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### FormattedPlural
|
|
18
|
+
|
|
19
|
+
See Format.js [FormattedPlural documentation](https://formatjs.github.io/docs/react-intl/components/#formattedplural) for more information.
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { FormattedPlural } from 'react-intl';
|
|
23
|
+
...
|
|
24
|
+
<FormattedPlural value={5} one="item" other="items" />
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### formatPluralMessage
|
|
28
|
+
|
|
29
|
+
`formatPluralMessage` is a custom formatter which accepts a number value, an object of messages keyed by plural forms, and [`Intl.PluralRules` options](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules/PluralRules#options). It returns the message corresponding to the plural form of the value for the current locale.
|
|
30
|
+
|
|
31
|
+
| Name | Type | Description |
|
|
32
|
+
| :--------- | :-------------------- | :--------------------------------------------------- |
|
|
33
|
+
| `value` | `number` | The number value to determine the plural form. |
|
|
34
|
+
| `messages` | `PluralMessages` | An object containing messages keyed by plural forms. |
|
|
35
|
+
| `options?` | `FormatPluralOptions` | [Options to customize the pluralization behavior](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules/PluralRules#options). Defaults to using "cardinal".
|
|
36
|
+
|
|
37
|
+
<Tabs
|
|
38
|
+
defaultValue="hooks"
|
|
39
|
+
values={[
|
|
40
|
+
{ label: 'React hooks', value: 'hooks' },
|
|
41
|
+
{ label: 'Store', value: 'store' },
|
|
42
|
+
]}
|
|
43
|
+
>
|
|
44
|
+
<TabItem value="hooks">
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { useIntl } from '@servicetitan/intl';
|
|
48
|
+
...
|
|
49
|
+
const intl = useIntl();
|
|
50
|
+
...
|
|
51
|
+
intl.formatPluralMessage(1, { one: 'item', other: 'items' });
|
|
52
|
+
// Results in "item"
|
|
53
|
+
intl.formatPluralMessage(3, { one: 'item', other: 'items' });
|
|
54
|
+
// Results in "items"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
</TabItem>
|
|
58
|
+
<TabItem value="store">
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { IntlStore } from '@servicetitan/intl/mobx';
|
|
62
|
+
...
|
|
63
|
+
@injectable()
|
|
64
|
+
class MyStore {
|
|
65
|
+
constructor(@inject(IntlStore) private readonly intlStore: IntlStore) {}
|
|
66
|
+
...
|
|
67
|
+
this.intlStore.intl.formatPluralMessage(1, { one: 'item', other: 'items' });
|
|
68
|
+
// Results in "item"
|
|
69
|
+
this.intlStore.intl.formatPluralMessage(3, { one: 'item', other: 'items' });
|
|
70
|
+
// Results in "items"
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
</TabItem>
|
|
75
|
+
</Tabs>
|
|
@@ -4,7 +4,7 @@ title: TanStack Query MobX Integration
|
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
AppExample, HasInitialDataExample, NoInitialDataExample, PageExample, StaleTime0Example, StaleTime10MinutesExample
|
|
7
|
-
} from '@servicetitan/tanstack-query-mobx/
|
|
7
|
+
} from '@servicetitan/tanstack-query-mobx/demo';
|
|
8
8
|
|
|
9
9
|
import { CodeDemo } from '@site/src/components/code-demo';
|
|
10
10
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/docs-anvil-uikit-contrib",
|
|
3
|
-
"version": "32.
|
|
3
|
+
"version": "32.5.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,5 +16,5 @@
|
|
|
16
16
|
"cli": {
|
|
17
17
|
"webpack": false
|
|
18
18
|
},
|
|
19
|
-
"gitHead": "
|
|
19
|
+
"gitHead": "25988db91418cf6ff9018760bd03ef6c3d7ef8ec"
|
|
20
20
|
}
|