@graphcommerce/next-ui 8.1.0-canary.8 → 9.0.0-canary.100
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/ActionCard/ActionCard.tsx +66 -39
- package/ActionCard/ActionCardAccordion.tsx +2 -1
- package/ActionCard/ActionCardLayout.tsx +1 -1
- package/ActionCard/ActionCardList.tsx +11 -10
- package/ActionCard/index.ts +0 -1
- package/Blog/BlogAuthor/BlogAuthor.tsx +2 -4
- package/Blog/BlogListItem/BlogListItem.tsx +2 -4
- package/Blog/BlogTags/BlogTag.tsx +4 -1
- package/Breadcrumbs/Breadcrumbs.tsx +195 -0
- package/Breadcrumbs/BreadcrumbsJsonLd.tsx +13 -0
- package/Breadcrumbs/BreadcrumbsList.tsx +101 -0
- package/Breadcrumbs/BreadcrumbsPopper.tsx +48 -0
- package/Breadcrumbs/index.ts +4 -0
- package/Breadcrumbs/jsonLdBreadcrumb.tsx +19 -0
- package/Breadcrumbs/types.ts +11 -0
- package/CHANGELOG.md +341 -98
- package/Config.graphqls +5 -0
- package/Document/DocumentBodyEnd.tsx +7 -0
- package/Document/DocumentBodyStart.tsx +7 -0
- package/Document/DocumentHeadEnd.tsx +7 -0
- package/Document/DocumentHeadStart.tsx +7 -0
- package/Document/index.ts +4 -0
- package/Footer/Footer.tsx +1 -1
- package/FramerScroller/SidebarGallery.tsx +54 -27
- package/FullPageMessage/FullPageMessage.tsx +1 -0
- package/Intl/DateTimeFormat/DateFormat.tsx +10 -0
- package/Intl/DateTimeFormat/DateTimeFormat.tsx +20 -0
- package/Intl/DateTimeFormat/TimeFormat.tsx +10 -0
- package/Intl/DateTimeFormat/index.ts +3 -0
- package/Intl/DateTimeFormat/toDate.ts +16 -0
- package/Intl/DisplayNames/DisplayNames.tsx +22 -0
- package/Intl/DisplayNames/index.ts +1 -0
- package/Intl/ListFormat.tsx +33 -0
- package/Intl/NumberFormat/CurrencyFormat.tsx +191 -0
- package/Intl/NumberFormat/NumberFormat.tsx +24 -0
- package/Intl/NumberFormat/PercentFormat.tsx +5 -0
- package/Intl/NumberFormat/UnitFormat.tsx +59 -0
- package/Intl/NumberFormat/index.ts +4 -0
- package/Intl/RelativeTimeFormat/RelativeTimeFormat.tsx +34 -0
- package/Intl/RelativeTimeFormat/RelativeToTimeFormat.tsx +35 -0
- package/Intl/RelativeTimeFormat/index.ts +2 -0
- package/Intl/RelativeTimeFormat/relativeTimeFormatAutoUnit.ts +23 -0
- package/Intl/index.ts +11 -0
- package/JsonLd/JsonLd.tsx +3 -2
- package/Layout/components/LayoutHeader.tsx +30 -10
- package/Layout/components/LayoutHeaderBack.tsx +20 -9
- package/Layout/components/LayoutHeaderClose.tsx +8 -2
- package/Layout/components/LayoutTitle.tsx +0 -5
- package/LayoutDefault/components/LayoutDefault.tsx +15 -13
- package/LazyHydrate/LazyHydrate.tsx +19 -3
- package/Overlay/components/OverlayBase.tsx +31 -6
- package/Overlay/components/OverlayHeader.tsx +27 -0
- package/Overlay/components/index.ts +1 -0
- package/PageLoadIndicator/PageLoadIndicator.tsx +25 -14
- package/PageMeta/PageMeta.tsx +1 -71
- package/PageMeta/canonicalize.ts +78 -0
- package/Pagination/PaginationExtended.tsx +103 -0
- package/Snackbar/MessageSnackbarImpl.tsx +60 -19
- package/Styles/responsiveVal.tsx +4 -5
- package/Styles/withEmotionCache.tsx +2 -2
- package/Theme/DarkLightModeThemeProvider.tsx +41 -19
- package/Theme/MuiButton.ts +11 -3
- package/TimeAgo/TimeAgo.tsx +3 -0
- package/hooks/index.ts +2 -1
- package/hooks/memoDeep.ts +38 -0
- package/hooks/useDateTimeFormat.ts +4 -4
- package/hooks/{useSsr.ts → useIsSsr.ts} +3 -0
- package/hooks/useLocale.ts +2 -2
- package/hooks/useNumberFormat.ts +4 -3
- package/hooks/useStorefrontConfig.ts +1 -9
- package/hooks/useUrlQuery.ts +6 -4
- package/icons.ts +55 -0
- package/index.ts +11 -2
- package/package.json +14 -14
- package/server.ts +9 -0
- package/utils/cssFlags.tsx +53 -0
- package/utils/getCssFlagInitScript.tsx +20 -0
- package/utils/normalizeLocale.ts +26 -0
- package/utils/robots.ts +41 -0
- package/utils/sitemap.ts +47 -0
- package/utils/storefrontConfig.ts +8 -0
- package/ActionCard/ActionCardListForm.tsx +0 -88
- package/icons/index.ts +0 -48
package/Config.graphqls
CHANGED
package/Footer/Footer.tsx
CHANGED
|
@@ -31,7 +31,14 @@ import { iconChevronLeft, iconChevronRight, iconFullscreen, iconFullscreenExit }
|
|
|
31
31
|
|
|
32
32
|
const MotionBox = styled(m.div)({})
|
|
33
33
|
|
|
34
|
-
type
|
|
34
|
+
type SidebarGalleryVariant = 'default' | 'oneColumn'
|
|
35
|
+
|
|
36
|
+
type OwnerState = {
|
|
37
|
+
zoomed: boolean
|
|
38
|
+
disableZoom: boolean
|
|
39
|
+
sticky: boolean
|
|
40
|
+
variantMd: SidebarGalleryVariant
|
|
41
|
+
}
|
|
35
42
|
const name = 'SidebarGallery' as const
|
|
36
43
|
const parts = [
|
|
37
44
|
'row',
|
|
@@ -60,6 +67,10 @@ export type SidebarGalleryProps = {
|
|
|
60
67
|
routeHash?: string
|
|
61
68
|
sx?: SxProps<Theme>
|
|
62
69
|
disableZoom?: boolean
|
|
70
|
+
disableSticky?: boolean
|
|
71
|
+
variantMd?: SidebarGalleryVariant
|
|
72
|
+
beforeScroller?: React.ReactNode
|
|
73
|
+
afterScroller?: React.ReactNode
|
|
63
74
|
} & Pick<ScrollerButtonProps, 'showButtons'>
|
|
64
75
|
|
|
65
76
|
export function SidebarGallery(props: SidebarGalleryProps) {
|
|
@@ -71,6 +82,10 @@ export function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
71
82
|
routeHash = 'gallery',
|
|
72
83
|
showButtons,
|
|
73
84
|
disableZoom = false,
|
|
85
|
+
disableSticky = false,
|
|
86
|
+
variantMd = 'default',
|
|
87
|
+
beforeScroller,
|
|
88
|
+
afterScroller,
|
|
74
89
|
} = props
|
|
75
90
|
|
|
76
91
|
const router = useRouter()
|
|
@@ -103,7 +118,7 @@ export function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
103
118
|
}
|
|
104
119
|
}
|
|
105
120
|
|
|
106
|
-
const classes = withState({ zoomed, disableZoom })
|
|
121
|
+
const classes = withState({ zoomed, disableZoom, sticky: !disableSticky, variantMd })
|
|
107
122
|
const theme = useTheme()
|
|
108
123
|
const windowRef = useRef(typeof window !== 'undefined' ? window : null)
|
|
109
124
|
|
|
@@ -144,25 +159,31 @@ export function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
144
159
|
display: 'grid',
|
|
145
160
|
gridTemplate: '"left" "right"',
|
|
146
161
|
[theme.breakpoints.up('md')]: {
|
|
147
|
-
|
|
148
|
-
theme.
|
|
149
|
-
|
|
162
|
+
'&:not(.variantMdOneColumn)': {
|
|
163
|
+
gridTemplate: `"left right" / 1fr calc(${responsiveVal(300, 500, undefined, theme.breakpoints.values.lg)} + ${
|
|
164
|
+
theme.page.horizontal
|
|
165
|
+
} * 2)`,
|
|
166
|
+
},
|
|
150
167
|
},
|
|
151
168
|
background:
|
|
152
169
|
theme.palette.mode === 'light'
|
|
153
170
|
? theme.palette.background.image
|
|
154
171
|
: theme.palette.background.paper,
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
172
|
+
|
|
173
|
+
'&:not(.variantMdOneColumn)': {
|
|
174
|
+
paddingRight: `calc((100% - ${theme.breakpoints.values.lg}px) / 2)`,
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
'&.zoomed': {
|
|
178
|
+
position: 'relative',
|
|
179
|
+
zIndex: theme.zIndex.modal,
|
|
180
|
+
marginTop: `calc(${theme.appShell.headerHeightSm} * -1)`,
|
|
181
|
+
[theme.breakpoints.up('md')]: {
|
|
182
|
+
marginTop: `calc(${theme.appShell.headerHeightMd} * -1 - ${theme.spacings.lg})`,
|
|
183
|
+
gridTemplateColumns: '1fr auto',
|
|
184
|
+
},
|
|
185
|
+
paddingRight: 0,
|
|
164
186
|
},
|
|
165
|
-
paddingRight: 0,
|
|
166
187
|
},
|
|
167
188
|
]}
|
|
168
189
|
>
|
|
@@ -183,11 +204,13 @@ export function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
183
204
|
width: '100%',
|
|
184
205
|
},
|
|
185
206
|
[theme.breakpoints.up('md')]: {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
207
|
+
'&:not(.variantMdOneColumn)': {
|
|
208
|
+
height: `max(${dvh(90)}, 40vw)`,
|
|
209
|
+
'&.sticky': {
|
|
210
|
+
position: 'sticky',
|
|
211
|
+
top: theme.appShell.headerHeightMd,
|
|
212
|
+
},
|
|
213
|
+
},
|
|
191
214
|
},
|
|
192
215
|
},
|
|
193
216
|
zoomed && {
|
|
@@ -201,6 +224,7 @@ export function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
201
224
|
if (!zoomed) document.body.style.overflow = ''
|
|
202
225
|
}}
|
|
203
226
|
>
|
|
227
|
+
{beforeScroller}
|
|
204
228
|
<Scroller
|
|
205
229
|
className={classes.scroller}
|
|
206
230
|
hideScrollbar
|
|
@@ -242,6 +266,7 @@ export function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
242
266
|
/>
|
|
243
267
|
))}
|
|
244
268
|
</Scroller>
|
|
269
|
+
{afterScroller}
|
|
245
270
|
<MotionBox
|
|
246
271
|
layout='position'
|
|
247
272
|
layoutDependency={zoomed}
|
|
@@ -333,9 +358,9 @@ export function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
333
358
|
>
|
|
334
359
|
{import.meta.graphCommerce.sidebarGallery?.paginationVariant ===
|
|
335
360
|
'THUMBNAILS_BOTTOM' ? (
|
|
336
|
-
<ScrollerThumbnails images={images} />
|
|
361
|
+
<ScrollerThumbnails layoutDependency={zoomed} images={images} />
|
|
337
362
|
) : (
|
|
338
|
-
<ScrollerDots />
|
|
363
|
+
<ScrollerDots layout />
|
|
339
364
|
)}
|
|
340
365
|
</Box>
|
|
341
366
|
</MotionBox>
|
|
@@ -353,10 +378,10 @@ export function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
353
378
|
},
|
|
354
379
|
zoomed && {
|
|
355
380
|
[theme.breakpoints.up('md')]: {
|
|
356
|
-
marginLeft: `calc((${responsiveVal(300, 500, theme.breakpoints.values.lg)} + ${
|
|
381
|
+
marginLeft: `calc((${responsiveVal(300, 500, undefined, theme.breakpoints.values.lg)} + ${
|
|
357
382
|
theme.page.horizontal
|
|
358
383
|
} * 2) * -1)`,
|
|
359
|
-
left: `calc(${responsiveVal(300, 500, theme.breakpoints.values.lg)} + ${
|
|
384
|
+
left: `calc(${responsiveVal(300, 500, undefined, theme.breakpoints.values.lg)} + ${
|
|
360
385
|
theme.page.horizontal
|
|
361
386
|
} * 2)`,
|
|
362
387
|
},
|
|
@@ -370,9 +395,11 @@ export function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
370
395
|
sx={{
|
|
371
396
|
boxSizing: 'border-box',
|
|
372
397
|
width: '100%',
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
398
|
+
'&:not(.variantMdOneColumn)': {
|
|
399
|
+
padding: `${theme.spacings.lg} ${theme.page.horizontal}`,
|
|
400
|
+
[theme.breakpoints.up('md')]: {
|
|
401
|
+
paddingLeft: theme.spacings.lg,
|
|
402
|
+
},
|
|
376
403
|
},
|
|
377
404
|
}}
|
|
378
405
|
>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DateTimeFormat, DateTimeFormatPropsType } from './DateTimeFormat'
|
|
2
|
+
|
|
3
|
+
type DateFormatOptions = Omit<
|
|
4
|
+
DateTimeFormatPropsType,
|
|
5
|
+
'timeStyle' | 'hour' | 'minute' | 'second' | 'timeZoneName'
|
|
6
|
+
>
|
|
7
|
+
|
|
8
|
+
export function DateFormat(props: DateFormatOptions) {
|
|
9
|
+
return <DateTimeFormat timeStyle={undefined} {...props} />
|
|
10
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useMemo } from 'react'
|
|
2
|
+
import { useLocale } from '../../hooks/useLocale'
|
|
3
|
+
import { useMemoObject } from '../../hooks/useMemoObject'
|
|
4
|
+
import { DateValue, toDate } from './toDate'
|
|
5
|
+
|
|
6
|
+
export function useDateTimeFormatter(props: Intl.DateTimeFormatOptions) {
|
|
7
|
+
const locale = useLocale()
|
|
8
|
+
const memoOptions = useMemoObject(props)
|
|
9
|
+
return useMemo(() => new Intl.DateTimeFormat(locale, memoOptions), [locale, memoOptions])
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type DateTimeFormatPropsType = { children: DateValue } & Intl.DateTimeFormatOptions
|
|
13
|
+
|
|
14
|
+
export function DateTimeFormat(props: DateTimeFormatPropsType) {
|
|
15
|
+
const { children } = props
|
|
16
|
+
const formatter = useDateTimeFormatter({ dateStyle: 'medium', timeStyle: 'short', ...props })
|
|
17
|
+
|
|
18
|
+
const dateValue = useMemo(() => toDate(children), [children])
|
|
19
|
+
return <span suppressHydrationWarning>{dateValue ? formatter.format(dateValue) : null}</span>
|
|
20
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DateTimeFormat, DateTimeFormatPropsType } from './DateTimeFormat'
|
|
2
|
+
|
|
3
|
+
type TimeFormatProps = Omit<
|
|
4
|
+
DateTimeFormatPropsType,
|
|
5
|
+
'dateStyle' | 'month' | 'day' | 'era' | 'month' | 'weekday' | 'year'
|
|
6
|
+
>
|
|
7
|
+
|
|
8
|
+
export function TimeFormat(props: TimeFormatProps) {
|
|
9
|
+
return <DateTimeFormat dateStyle={undefined} {...props} />
|
|
10
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type DateValue = Date | string | number | null | undefined
|
|
2
|
+
|
|
3
|
+
export function toDate(value: DateValue): Date | undefined {
|
|
4
|
+
let date: Date | undefined
|
|
5
|
+
|
|
6
|
+
if (value instanceof Date) {
|
|
7
|
+
date = value
|
|
8
|
+
} else if (typeof value === 'string') {
|
|
9
|
+
date = new Date(value.replace(/-/g, '/'))
|
|
10
|
+
} else if (typeof value === 'number') {
|
|
11
|
+
date = new Date(value)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (date && Number.isNaN(date.getTime())) return undefined
|
|
15
|
+
return date
|
|
16
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useMemo } from 'react'
|
|
2
|
+
import { useLocale } from '../../hooks/useLocale'
|
|
3
|
+
import { useMemoObject } from '../../hooks/useMemoObject'
|
|
4
|
+
|
|
5
|
+
export type UseDisplayNamesProps = Intl.DisplayNamesOptions
|
|
6
|
+
|
|
7
|
+
export function useDisplayNames(props: UseDisplayNamesProps) {
|
|
8
|
+
const locale = useLocale()
|
|
9
|
+
const memoOptions = useMemoObject(props)
|
|
10
|
+
return useMemo(() => new Intl.DisplayNames(locale, memoOptions), [locale, memoOptions])
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type DisplayNamesProps = UseDisplayNamesProps & {
|
|
14
|
+
code: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function DisplayNames(props: DisplayNamesProps) {
|
|
18
|
+
const { code, ...options } = props
|
|
19
|
+
const formatter = useDisplayNames(options)
|
|
20
|
+
|
|
21
|
+
return <span suppressHydrationWarning>{formatter.of(code)}</span>
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './DisplayNames'
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React, { useMemo } from 'react'
|
|
2
|
+
import { useLocale } from '../hooks'
|
|
3
|
+
|
|
4
|
+
type ListFormatProps = {
|
|
5
|
+
children: React.ReactNode[]
|
|
6
|
+
listStyle?: Intl.ListFormatOptions['style']
|
|
7
|
+
} & Omit<Intl.ListFormatOptions, 'style'>
|
|
8
|
+
|
|
9
|
+
export function ListFormat(props: ListFormatProps) {
|
|
10
|
+
const { children, localeMatcher, listStyle: style, type } = props
|
|
11
|
+
|
|
12
|
+
const locale = useLocale()
|
|
13
|
+
|
|
14
|
+
const formatter = useMemo(
|
|
15
|
+
() => new Intl.ListFormat(locale, { localeMatcher, style, type }),
|
|
16
|
+
[locale, localeMatcher, style, type],
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
const childArray = React.Children.toArray(children)
|
|
20
|
+
const fauxChildren = childArray.map((child, index) => `${index}`) ?? []
|
|
21
|
+
const parts = formatter.formatToParts(fauxChildren)
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
{parts.map((part, index) => (
|
|
26
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
27
|
+
<React.Fragment key={index}>
|
|
28
|
+
{part.type === 'literal' ? part.value : childArray[part.value]}
|
|
29
|
+
</React.Fragment>
|
|
30
|
+
))}
|
|
31
|
+
</>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { NumberFormat, NumberFormatPropsType } from './NumberFormat'
|
|
2
|
+
|
|
3
|
+
// https://en.wikipedia.org/wiki/ISO_4217#List_of_ISO_4217_currency_codes
|
|
4
|
+
type Currency =
|
|
5
|
+
| 'AED'
|
|
6
|
+
| 'AFN'
|
|
7
|
+
| 'ALL'
|
|
8
|
+
| 'AMD'
|
|
9
|
+
| 'ANG'
|
|
10
|
+
| 'AOA'
|
|
11
|
+
| 'ARS'
|
|
12
|
+
| 'AUD'
|
|
13
|
+
| 'AWG'
|
|
14
|
+
| 'AZN'
|
|
15
|
+
| 'BAM'
|
|
16
|
+
| 'BBD'
|
|
17
|
+
| 'BDT'
|
|
18
|
+
| 'BGN'
|
|
19
|
+
| 'BHD'
|
|
20
|
+
| 'BIF'
|
|
21
|
+
| 'BMD'
|
|
22
|
+
| 'BND'
|
|
23
|
+
| 'BOB'
|
|
24
|
+
| 'BOV'
|
|
25
|
+
| 'BRL'
|
|
26
|
+
| 'BSD'
|
|
27
|
+
| 'BTN'
|
|
28
|
+
| 'BWP'
|
|
29
|
+
| 'BYN'
|
|
30
|
+
| 'BZD'
|
|
31
|
+
| 'CAD'
|
|
32
|
+
| 'CDF'
|
|
33
|
+
| 'CHE'
|
|
34
|
+
| 'CHF'
|
|
35
|
+
| 'CHW'
|
|
36
|
+
| 'CLF'
|
|
37
|
+
| 'CLP'
|
|
38
|
+
| 'CNY'
|
|
39
|
+
| 'COP'
|
|
40
|
+
| 'COU'
|
|
41
|
+
| 'CRC'
|
|
42
|
+
| 'CUP'
|
|
43
|
+
| 'CVE'
|
|
44
|
+
| 'CZK'
|
|
45
|
+
| 'DJF'
|
|
46
|
+
| 'DKK'
|
|
47
|
+
| 'DOP'
|
|
48
|
+
| 'DZD'
|
|
49
|
+
| 'EGP'
|
|
50
|
+
| 'ERN'
|
|
51
|
+
| 'ETB'
|
|
52
|
+
| 'EUR'
|
|
53
|
+
| 'FJD'
|
|
54
|
+
| 'FKP'
|
|
55
|
+
| 'GBP'
|
|
56
|
+
| 'GEL'
|
|
57
|
+
| 'GHS'
|
|
58
|
+
| 'GIP'
|
|
59
|
+
| 'GMD'
|
|
60
|
+
| 'GNF'
|
|
61
|
+
| 'GTQ'
|
|
62
|
+
| 'GYD'
|
|
63
|
+
| 'HKD'
|
|
64
|
+
| 'HNL'
|
|
65
|
+
| 'HTG'
|
|
66
|
+
| 'HUF'
|
|
67
|
+
| 'IDR'
|
|
68
|
+
| 'ILS'
|
|
69
|
+
| 'INR'
|
|
70
|
+
| 'IQD'
|
|
71
|
+
| 'IRR'
|
|
72
|
+
| 'ISK'
|
|
73
|
+
| 'JMD'
|
|
74
|
+
| 'JOD'
|
|
75
|
+
| 'JPY'
|
|
76
|
+
| 'KES'
|
|
77
|
+
| 'KGS'
|
|
78
|
+
| 'KHR'
|
|
79
|
+
| 'KMF'
|
|
80
|
+
| 'KPW'
|
|
81
|
+
| 'KRW'
|
|
82
|
+
| 'KWD'
|
|
83
|
+
| 'KYD'
|
|
84
|
+
| 'KZT'
|
|
85
|
+
| 'LAK'
|
|
86
|
+
| 'LBP'
|
|
87
|
+
| 'LKR'
|
|
88
|
+
| 'LRD'
|
|
89
|
+
| 'LSL'
|
|
90
|
+
| 'LYD'
|
|
91
|
+
| 'MAD'
|
|
92
|
+
| 'MDL'
|
|
93
|
+
| 'MGA'
|
|
94
|
+
| 'MKD'
|
|
95
|
+
| 'MMK'
|
|
96
|
+
| 'MNT'
|
|
97
|
+
| 'MOP'
|
|
98
|
+
| 'MRU'
|
|
99
|
+
| 'MUR'
|
|
100
|
+
| 'MVR'
|
|
101
|
+
| 'MWK'
|
|
102
|
+
| 'MXN'
|
|
103
|
+
| 'MXV'
|
|
104
|
+
| 'MYR'
|
|
105
|
+
| 'MZN'
|
|
106
|
+
| 'NAD'
|
|
107
|
+
| 'NGN'
|
|
108
|
+
| 'NIO'
|
|
109
|
+
| 'NOK'
|
|
110
|
+
| 'NPR'
|
|
111
|
+
| 'NZD'
|
|
112
|
+
| 'OMR'
|
|
113
|
+
| 'PAB'
|
|
114
|
+
| 'PEN'
|
|
115
|
+
| 'PGK'
|
|
116
|
+
| 'PHP'
|
|
117
|
+
| 'PKR'
|
|
118
|
+
| 'PLN'
|
|
119
|
+
| 'PYG'
|
|
120
|
+
| 'QAR'
|
|
121
|
+
| 'RON'
|
|
122
|
+
| 'RSD'
|
|
123
|
+
| 'RUB'
|
|
124
|
+
| 'RWF'
|
|
125
|
+
| 'SAR'
|
|
126
|
+
| 'SBD'
|
|
127
|
+
| 'SCR'
|
|
128
|
+
| 'SDG'
|
|
129
|
+
| 'SEK'
|
|
130
|
+
| 'SGD'
|
|
131
|
+
| 'SHP'
|
|
132
|
+
| 'SLE'
|
|
133
|
+
| 'SLL'
|
|
134
|
+
| 'SOS'
|
|
135
|
+
| 'SRD'
|
|
136
|
+
| 'SSP'
|
|
137
|
+
| 'STN'
|
|
138
|
+
| 'SVC'
|
|
139
|
+
| 'SYP'
|
|
140
|
+
| 'SZL'
|
|
141
|
+
| 'THB'
|
|
142
|
+
| 'TJS'
|
|
143
|
+
| 'TMT'
|
|
144
|
+
| 'TND'
|
|
145
|
+
| 'TOP'
|
|
146
|
+
| 'TRY'
|
|
147
|
+
| 'TTD'
|
|
148
|
+
| 'TWD'
|
|
149
|
+
| 'TZS'
|
|
150
|
+
| 'UAH'
|
|
151
|
+
| 'UGX'
|
|
152
|
+
| 'USD'
|
|
153
|
+
| 'USN'
|
|
154
|
+
| 'UYI'
|
|
155
|
+
| 'UYU'
|
|
156
|
+
| 'UYW'
|
|
157
|
+
| 'UZS'
|
|
158
|
+
| 'VED'
|
|
159
|
+
| 'VES'
|
|
160
|
+
| 'VND'
|
|
161
|
+
| 'VUV'
|
|
162
|
+
| 'WST'
|
|
163
|
+
| 'XAF'
|
|
164
|
+
| 'XAG'
|
|
165
|
+
| 'XAU'
|
|
166
|
+
| 'XBA'
|
|
167
|
+
| 'XBB'
|
|
168
|
+
| 'XBC'
|
|
169
|
+
| 'XBD'
|
|
170
|
+
| 'XCD'
|
|
171
|
+
| 'XDR'
|
|
172
|
+
| 'XOF'
|
|
173
|
+
| 'XPD'
|
|
174
|
+
| 'XPF'
|
|
175
|
+
| 'XPT'
|
|
176
|
+
| 'XSU'
|
|
177
|
+
| 'XTS'
|
|
178
|
+
| 'XUA'
|
|
179
|
+
| 'XXX'
|
|
180
|
+
| 'YER'
|
|
181
|
+
| 'ZAR'
|
|
182
|
+
| 'ZMW'
|
|
183
|
+
| 'ZWL'
|
|
184
|
+
|
|
185
|
+
export type CurrencyFormatProps = Omit<NumberFormatPropsType, 'numberStyle'> & {
|
|
186
|
+
currency: Currency | (string & Record<never, never>)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function CurrencyFormat(props: CurrencyFormatProps) {
|
|
190
|
+
return <NumberFormat {...props} numberStyle='currency' />
|
|
191
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Box, SxProps, Theme } from '@mui/material'
|
|
2
|
+
import { useMemo } from 'react'
|
|
3
|
+
import { useLocale } from '../../hooks/useLocale'
|
|
4
|
+
import { useMemoObject } from '../../hooks/useMemoObject'
|
|
5
|
+
|
|
6
|
+
export type NumberFormatPropsType = {
|
|
7
|
+
children?: number | bigint | null | undefined
|
|
8
|
+
numberStyle: Intl.NumberFormatOptions['style']
|
|
9
|
+
sx?: SxProps<Theme>
|
|
10
|
+
} & Omit<Intl.NumberFormatOptions, 'style'>
|
|
11
|
+
|
|
12
|
+
export function NumberFormat(props: NumberFormatPropsType) {
|
|
13
|
+
const { children, numberStyle, ...options } = props
|
|
14
|
+
|
|
15
|
+
const memoOptions = useMemoObject({ ...options, style: numberStyle })
|
|
16
|
+
const locale = useLocale()
|
|
17
|
+
const formatter = useMemo(() => new Intl.NumberFormat(locale, memoOptions), [locale, memoOptions])
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<Box component='span' suppressHydrationWarning>
|
|
21
|
+
{children ? formatter.format(children) : null}
|
|
22
|
+
</Box>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { NumberFormatPropsType, NumberFormat } from './NumberFormat'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* https://tc39.es/ecma402/#table-sanctioned-single-unit-identifiers
|
|
5
|
+
*/
|
|
6
|
+
type Unit =
|
|
7
|
+
| 'acre'
|
|
8
|
+
| 'bit'
|
|
9
|
+
| 'byte'
|
|
10
|
+
| 'celsius'
|
|
11
|
+
| 'centimeter'
|
|
12
|
+
| 'day'
|
|
13
|
+
| 'degree'
|
|
14
|
+
| 'fahrenheit'
|
|
15
|
+
| 'fluid-ounce'
|
|
16
|
+
| 'foot'
|
|
17
|
+
| 'gallon'
|
|
18
|
+
| 'gigabit'
|
|
19
|
+
| 'gigabyte'
|
|
20
|
+
| 'gram'
|
|
21
|
+
| 'hectare'
|
|
22
|
+
| 'hour'
|
|
23
|
+
| 'inch'
|
|
24
|
+
| 'kilobit'
|
|
25
|
+
| 'kilobyte'
|
|
26
|
+
| 'kilogram'
|
|
27
|
+
| 'kilometer'
|
|
28
|
+
| 'liter'
|
|
29
|
+
| 'megabit'
|
|
30
|
+
| 'megabyte'
|
|
31
|
+
| 'meter'
|
|
32
|
+
| 'microsecond'
|
|
33
|
+
| 'mile'
|
|
34
|
+
| 'mile-scandinavian'
|
|
35
|
+
| 'milliliter'
|
|
36
|
+
| 'millimeter'
|
|
37
|
+
| 'millisecond'
|
|
38
|
+
| 'minute'
|
|
39
|
+
| 'month'
|
|
40
|
+
| 'nanosecond'
|
|
41
|
+
| 'ounce'
|
|
42
|
+
| 'percent'
|
|
43
|
+
| 'petabyte'
|
|
44
|
+
| 'pound'
|
|
45
|
+
| 'second'
|
|
46
|
+
| 'stone'
|
|
47
|
+
| 'terabit'
|
|
48
|
+
| 'terabyte'
|
|
49
|
+
| 'week'
|
|
50
|
+
| 'yard'
|
|
51
|
+
| 'year'
|
|
52
|
+
|
|
53
|
+
export type UnitFormatProps = Omit<NumberFormatPropsType, 'numberStyle'> & {
|
|
54
|
+
unit: Unit | (string & Record<never, never>)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function UnitFormat(props: UnitFormatProps) {
|
|
58
|
+
return <NumberFormat {...props} numberStyle='unit' />
|
|
59
|
+
}
|