@servicetitan/docs-anvil-uikit-contrib 32.4.1 → 32.6.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.
@@ -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,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 [`MobxStoreProvider`](./mobx-store-provider.mdx).
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,27 @@
1
+ ---
2
+ title: MobxIntlProvider
3
+ ---
4
+
5
+ Applications wrapped with the `<MobxIntlProvider>` component are provided access to internationalization features both in components and in MobX stores. `<MobxIntlProvider>` is used instead of `<IntlProvider>`.
6
+
7
+ ```tsx
8
+ import { useMemo } from 'react';
9
+ import { IntlConfig } from '@servicetitan/intl';
10
+ import { MobxIntlProvider } from '@servicetitan/intl/mobx';
11
+
12
+ const ExampleApp = () => {
13
+ const currency = 'USD';
14
+ const locale = 'en-US';
15
+ const timeZone = 'America/Los_Angeles';
16
+ const intlConfig: IntlConfig = useMemo(
17
+ () => ({ currency, locale, timeZone }),
18
+ [currency, locale, timeZone]
19
+ );
20
+
21
+ return (
22
+ <MobxIntlProvider config={intlConfig}>
23
+ <App />
24
+ </MobxIntlProvider>
25
+ );
26
+ };
27
+ ```
@@ -0,0 +1,66 @@
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](../dates.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())}</p>
28
+ <p>Formatted currency: {intl.formatCurrency(1234.56)}</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
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 times
48
+
49
+ ### Custom ServiceTitan Formatters
50
+
51
+ - [`formatCurrency()`](../currency.mdx) - Format currency
52
+ - [`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
53
+
54
+ ### Locale Information
55
+
56
+ - `currency` - Current currency code (e.g., 'USD')
57
+ - `locale` - Current locale (e.g., 'en-US')
58
+ - `timeZone` - Current time zone
59
+ - `messages` - Available messages for the current locale (note: translating messages is not yet configured within ServiceTitan)
60
+
61
+ ## See Also
62
+
63
+ For detailed information about specific formatting functions and their options, refer to the Format.js documentation:
64
+
65
+ - [useIntl Hook Documentation](https://formatjs.github.io/docs/react-intl/api/#useintl-hook) which our `useIntl` is a wrapper around
66
+ - [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,92 @@
1
+ ---
2
+ title: Currency
3
+ ---
4
+
5
+ import Tabs from '@theme/Tabs';
6
+
7
+ Numbers can be formatted as currency either by using the `FormattedCurrency` component from `@servicetitan/intl`, or via the `formatCurrency()` 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
+ `FormattedCurrency` and `formatCurrency` will use the `currency` provided to the `IntlProvider` or `MobxIntlProvider` by default, but you can override this by providing a different currency code as a prop/option.
10
+
11
+ ## Usage
12
+
13
+ ### FormattedCurrency
14
+
15
+ ```
16
+ props: NumberFormatOptions &
17
+ {
18
+ value: number,
19
+ children: (formattedNumber: string) => ReactElement,
20
+ }
21
+ ```
22
+
23
+ ```tsx
24
+ import { FormattedCurrency } from '@servicetitan/intl';
25
+
26
+ function CurrencyExample() {
27
+ return (
28
+ <>
29
+ <p>Currency defaults to currency provided to IntlProvider/MobxIntlProvider, or USD</p>
30
+ <FormattedCurrency value={1234.56} />
31
+ <p>Use currency prop to specify a different currency</p>
32
+ <FormattedCurrency value={1234.56} currency="EUR" />
33
+ </>
34
+ );
35
+ };
36
+ ```
37
+
38
+ ### formatCurrency
39
+
40
+ <Tabs
41
+ defaultValue="hooks"
42
+ values={[
43
+ { label: 'React hooks', value: 'hooks' },
44
+ { label: 'Store', value: 'store' },
45
+ ]}
46
+ >
47
+ <TabItem value="hooks">
48
+
49
+ ```tsx
50
+ import { useIntl } from '@servicetitan/intl';
51
+
52
+ function CurrencyExample() {
53
+ const intl = useIntl();
54
+
55
+ return (
56
+ <>
57
+ <p>Currency defaults to currency provided to IntlProvider/MobxIntlProvider, or USD</p>
58
+ {intl.formatCurrency(1234.56)}
59
+ <p>Use currency prop to specify a different currency</p>
60
+ {intl.formatCurrency(1234.56, { style: 'currency', currency: 'EUR' })}
61
+ </>
62
+ );
63
+ };
64
+ ```
65
+
66
+ </TabItem>
67
+ <TabItem value="store">
68
+
69
+ ```tsx
70
+ import { IntlStore } from '@servicetitan/intl/mobx';
71
+
72
+ @injectable()
73
+ class CurrencyExampleStore {
74
+ constructor(@inject(IntlStore) private readonly intlStore: IntlStore) {}
75
+
76
+ formatCurrency() {
77
+ return [
78
+ // Currency defaults to currency provided to IntlProvider/MobxIntlProvider, or USD
79
+ this.intlStore.intl.formatCurrency(1234.56),
80
+ // Use currency prop to specify a different currency
81
+ this.intlStore.intl.formatCurrency(1234.56, { style: 'currency', currency: 'EUR' }),
82
+ ];
83
+ }
84
+ }
85
+ ```
86
+
87
+ </TabItem>
88
+ </Tabs>
89
+
90
+ ### Further customization
91
+
92
+ If you need to customize the formatting further, `FormattedCurrency` and `formatCurrency` accept the same options as the native `Intl.NumberFormat` API, but `style` is always set to `"currency"`, and `currency` defaults to `currency` from the `IntlProvider`/`MobxIntlProvider`. See [`Intl.NumberFormat` for more information about those options](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat).
@@ -0,0 +1,92 @@
1
+ ---
2
+ title: Dates
3
+ ---
4
+
5
+ import Tabs from '@theme/Tabs';
6
+
7
+ Dates can be formatted either by using the [`FormattedDate`](#formatteddate) component from `@servicetitan/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
+ :::note
10
+ `FormattedDate` is a wrapper around `react-intl`'s `FormattedDate` component, but defaults the `format` to *short*. Make sure you import it from `@servicetitan/intl`, not `react-intl`.
11
+ :::
12
+
13
+ ## Available Formats
14
+
15
+ The following standard ServiceTitan formats are available to use as part of date formatting. The *short* format is used if none is specified. 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).
16
+
17
+ - `short` results in `09/02/25` (default if no format is specified)
18
+ - `long` results in `September 2, 2025`
19
+
20
+ ## Usage
21
+
22
+ ### FormattedDate
23
+
24
+ ```tsx
25
+ import { FormattedDate } from '@servicetitan/intl';
26
+
27
+ function DateExample() {
28
+ const date = new Date('2025-09-02');
29
+
30
+ return (
31
+ <div>
32
+ <FormattedDate value={date} /> {/* "09/02/25" */}
33
+ <FormattedDate value={date} format="short" /> {/* "09/02/25" */}
34
+ <FormattedDate value={date} format="long" /> {/* "September 2, 2025" */}
35
+ </div>
36
+ );
37
+ }
38
+ ```
39
+
40
+ ### formatDate
41
+
42
+ <Tabs
43
+ defaultValue="hooks"
44
+ values={[
45
+ { label: 'React hooks', value: 'hooks' },
46
+ { label: 'Store', value: 'store' },
47
+ ]}
48
+ >
49
+ <TabItem value="hooks">
50
+
51
+ ```tsx
52
+ import { useIntl } from '@servicetitan/intl';
53
+
54
+ function DateExample() {
55
+ const intl = useIntl();
56
+
57
+ return (
58
+ <>
59
+ {intl.formatDate(new Date())} {/* "09/02/25" */}
60
+ {intl.formatDate(new Date(), { format: 'short' })} {/* "09/02/25" */}
61
+ {intl.formatDate(new Date(), { format: 'long' })} {/* "September 2, 2025" */}
62
+ </>
63
+ );
64
+ }
65
+ ```
66
+
67
+ </TabItem>
68
+ <TabItem value="store">
69
+
70
+ ```tsx
71
+ import { IntlStore } from '@servicetitan/intl/mobx';
72
+
73
+ @injectable()
74
+ class MyStore {
75
+ constructor(@inject(IntlStore) private readonly intlStore: IntlStore) {}
76
+
77
+ formatDate() {
78
+ return [
79
+ this.intlStore.intl.formatDate(new Date()), // 09/02/25
80
+ this.intlStore.intl.formatDate(new Date(), { format: 'short' }), // 09/02/25
81
+ this.intlStore.intl.formatDate(new Date(), { format: 'long' }), // September 2, 2025
82
+ ];
83
+ }
84
+ }
85
+ ```
86
+
87
+ </TabItem>
88
+ </Tabs>
89
+
90
+ ### Further customization
91
+
92
+ 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,120 @@
1
+ ---
2
+ title: Intl (Internationalization)
3
+ ---
4
+
5
+ import Tabs from '@theme/Tabs';
6
+ import TabItem from '@theme/TabItem';
7
+
8
+ `@servicetitan/intl` is a solution for helping setup internationalization in React projects (with optional MobX store) 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*, *timeZone*, and *currency*, and provides that API to `react-intl` to be used within React context, as well as a store to be used within MobX.
9
+
10
+ ## Setup
11
+
12
+ This project should be installed as one of your project's `dependencies`:
13
+
14
+ ```bash
15
+ npm install @servicetitan/intl
16
+ ```
17
+
18
+ This library has `peerDependencies` for:
19
+ - `"@servicetitan/react-ioc": ">=22.0.0"`
20
+ - `"react-intl": ">=7.1.11"`
21
+
22
+ ### Provider
23
+
24
+ Wrap your application with [`<IntlProvider>`](./API/intl-provider.mdx) or [`<MobxIntlProvider>`](./API/mobx-intl-provider.mdx), providing `locale`, `timeZone`, and `currency` through the `config` prop:
25
+
26
+ #### IntlProvider
27
+
28
+ [`IntlProvider`](./API/intl-provider.mdx) is the most basic provider, and should be used if you do not use Mobx.
29
+
30
+ ```tsx
31
+ import { IntlProvider } from '@servicetitan/intl';
32
+ ...
33
+ const locale = 'en-US';
34
+ const timeZone = 'America/Los_Angeles';
35
+ const currency = 'USD';
36
+ const intlConfig: IntlConfig = useMemo(() =>
37
+ ({ currency, locale, timeZone }), [currency, locale, timeZone]);
38
+ return (
39
+ <IntlProvider config={intlConfig}>
40
+ <App />
41
+ </IntlProvider>
42
+ );
43
+ ```
44
+
45
+ #### MobxIntlProvider
46
+
47
+ [`MobxIntlProvider`](./API/mobx-intl-provider.mdx) should be used if you are using Mobx, as it provides the [`IntlStore`](./API/intlstore.mdx) to access internationalization features in stores.
48
+
49
+ ```tsx
50
+ import { MobxIntlProvider } from '@servicetitan/intl/mobx';
51
+ ...
52
+ const locale = 'en-US';
53
+ const timeZone = 'America/Los_Angeles';
54
+ const currency = 'USD';
55
+ const intlConfig: IntlConfig = useMemo(() =>
56
+ ({ currency, locale, timeZone }), [currency, locale, timeZone]);
57
+ return (
58
+ <MobxIntlProvider config={intlConfig}>
59
+ <App />
60
+ </MobxIntlProvider>
61
+ );
62
+ ```
63
+
64
+ :::note
65
+ If you are doing work in the monolith, `MobxIntlProvider` has already been implemented for you, providing the `currency`, `locale`, and `timeZone` from available Business Units, Culture, Features, and Tenant stores. If you are instead implementing an MFE but would use the same monolith data, you should use the [`IntlProvider` from `@servicetitan/application-data/tanstack/intl`](/docs/frontend/application-data/intl-provider), which will likewise provide the `currency`, `locale`, and `timeZone` for you via monolith data stores.
66
+ :::
67
+
68
+ ## Features
69
+
70
+ `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:
71
+
72
+ - [Formatting currency](./currency.mdx)
73
+ - [Formatting dates](./dates.mdx)
74
+ - [Formatting numbers](./numbers.mdx)
75
+ - [Formatting times](./times.mdx)
76
+ - [Plurals](./plurals.mdx)
77
+
78
+ :::note
79
+ 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.
80
+ :::
81
+
82
+ ## React Hooks vs Store
83
+
84
+ 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.
85
+
86
+ ```tsx
87
+ import { useIntl } from '@servicetitan/intl';
88
+
89
+ function MyComponent() {
90
+ const intl = useIntl();
91
+
92
+ return (
93
+ <div>
94
+ <p>Formatted date: {intl.formatDate(new Date())}</p>
95
+ <p>Formatted currency: {intl.formatCurrency(1234.56)}</p>
96
+ </div>
97
+ );
98
+ }
99
+ ```
100
+
101
+ However, if you have the need to access the internationalization API in MobX stores, you must use the wrapper component [`<MobxStoreProvider>`](./API/mobx-intl-provider.mdx) instead of `<IntlProvider>`, and you can use the provided [`IntlStore`](./API/intlstore.mdx) to access the same functionality.
102
+
103
+ ```tsx
104
+ import { inject, injectable } from '@servicetitan/react-ioc';
105
+ import { IntlStore } from '@servicetitan/intl/mobx';
106
+
107
+ @injectable()
108
+ export class UserService {
109
+ constructor(@inject(IntlStore) private intlStore: IntlStore) {}
110
+
111
+ formatUserData(user: User) {
112
+ const intl = this.intlStore.intl;
113
+
114
+ return {
115
+ joinDate: intl.formatDate(user.joinDate),
116
+ balance: intl.formatCurrency(user.balance)
117
+ };
118
+ }
119
+ }
120
+ ```
@@ -0,0 +1,79 @@
1
+ ---
2
+ title: Numbers
3
+ ---
4
+
5
+ import Tabs from '@theme/Tabs';
6
+
7
+ Numbers 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
+ function NumberExample() {
17
+ return (
18
+ <>
19
+ <FormattedNumber value={0.75} style="percent" /> {/* "75%" */}
20
+ <FormattedNumber value={1234.567} maximumFractionDigits={2} /> {/* "1,234.57" */}
21
+ </>
22
+ );
23
+ }
24
+ ```
25
+
26
+ ### formatNumber
27
+
28
+ <Tabs
29
+ defaultValue="hooks"
30
+ values={[
31
+ { label: 'React hooks', value: 'hooks' },
32
+ { label: 'Store', value: 'store' },
33
+ ]}
34
+ >
35
+ <TabItem value="hooks">
36
+
37
+ ```tsx
38
+ import { useIntl } from '@servicetitan/intl';
39
+
40
+ function NumberExample() {
41
+ const intl = useIntl();
42
+
43
+ return (
44
+ <>
45
+ <p>{intl.formatNumber(0.75, { style: 'percent' })}</p> {/* "75%" */}
46
+ <p>{intl.formatNumber(1234.567, { maximumFractionDigits: 2 })}</p> {/* "1,234.57" */}
47
+ </>
48
+ );
49
+ }
50
+ ```
51
+
52
+ </TabItem>
53
+ <TabItem value="store">
54
+
55
+ ```tsx
56
+ import { inject, injectable } from '@servicetitan/react-ioc';
57
+ import { IntlStore } from '@servicetitan/intl/mobx';
58
+
59
+ @injectable()
60
+ class ReportService {
61
+ constructor(@inject(IntlStore) private readonly intlStore: IntlStore) {}
62
+
63
+ formatReportData() {
64
+ const intl = this.intlStore.intl;
65
+
66
+ return [
67
+ intl.formatNumber(0.75, { style: 'percent' }), // "75%"
68
+ intl.formatNumber(1234.567, { maximumFractionDigits: 2 }), // "1,234.57"
69
+ ];
70
+ }
71
+ }
72
+ ```
73
+
74
+ </TabItem>
75
+ </Tabs>
76
+
77
+ ### Further customization
78
+
79
+ 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>
@@ -0,0 +1,93 @@
1
+ ---
2
+ title: Times
3
+ ---
4
+
5
+ import Tabs from '@theme/Tabs';
6
+
7
+ Times can be formatted either by using the [`FormattedTime`](#formattedtime) component from `react-intl`, or via the [`formatTime`](#formattime) 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 time formatting. The *short* format is used if none is specified. 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 `4:00 PM` (default if no format is specified)
14
+ - `medium` results in `4:00:00 PM`
15
+
16
+ ## Usage
17
+
18
+ ### FormattedTime
19
+
20
+ ```tsx
21
+ import { FormattedTime } from 'react-intl';
22
+
23
+ function TimeExample() {
24
+ const time = new Date();
25
+
26
+ return (
27
+ <>
28
+ <FormattedTime value={time} /> {/* "4:00 PM" */}
29
+ <FormattedTime value={time} format="short" /> {/* "4:00 PM" */}
30
+ <FormattedTime value={time} format="medium" /> {/* "4:00:00 PM" */}
31
+ </>
32
+ );
33
+ }
34
+ ```
35
+
36
+ ### formatTime
37
+
38
+ <Tabs
39
+ defaultValue="hooks"
40
+ values={[
41
+ { label: 'React hooks', value: 'hooks' },
42
+ { label: 'Store', value: 'store' },
43
+ ]}
44
+ >
45
+ <TabItem value="hooks">
46
+
47
+ ```tsx
48
+ import { useIntl } from '@servicetitan/intl';
49
+
50
+ function TimeExample() {
51
+ const intl = useIntl();
52
+ const time = new Date();
53
+
54
+ return (
55
+ <>
56
+ <p>{intl.formatTime(time)}</p> {/* "4:00 PM" */}
57
+ <p>{intl.formatTime(time, { format: 'short' })}</p> {/* "4:00 PM" */}
58
+ <p>{intl.formatTime(time, { format: 'medium' })}</p> {/* "4:00:00 PM" */}
59
+ </>
60
+ );
61
+ }
62
+ ```
63
+
64
+ </TabItem>
65
+ <TabItem value="store">
66
+
67
+ ```tsx
68
+ import { inject, injectable } from '@servicetitan/react-ioc';
69
+ import { IntlStore } from '@servicetitan/intl/mobx';
70
+
71
+ @injectable()
72
+ class ScheduleService {
73
+ constructor(@inject(IntlStore) private readonly intlStore: IntlStore) {}
74
+
75
+ formatTime() {
76
+ const intl = this.intlStore.intl;
77
+ const time = new Date();
78
+
79
+ return [
80
+ intl.formatTime(time), // "4:00 PM"
81
+ intl.formatTime(time, { format: 'short' }), // "4:00 PM"
82
+ intl.formatTime(time, { format: 'medium' }), // "4:00:00 PM"
83
+ ];
84
+ }
85
+ }
86
+ ```
87
+
88
+ </TabItem>
89
+ </Tabs>
90
+
91
+ ### Further customization
92
+
93
+ If you need to customize the formatting further, `FormattedTime` and `formatTime` 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 [`FormattedTime` documentation](https://formatjs.github.io/docs/react-intl/components/#formattedtime) or [`formatTime` documentation](https://formatjs.github.io/docs/react-intl/api/#formattime) for more information on how to use them.
@@ -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/dist/demo';
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.4.1",
3
+ "version": "32.6.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": "5bc4f3c9c8a181df124fdc614964757e5490ea9b"
19
+ "gitHead": "91ddc9aa77c756301ac1b429a71e2c317b850ce7"
20
20
  }