From e02fba61e87861068db3734e78723b15f9df6700 Mon Sep 17 00:00:00 2001 From: anuraghazra Date: Wed, 22 May 2024 22:01:16 +0530 Subject: [PATCH] chore: add dayjs to i18n locale map --- .../DatePicker/DatePicker.stories.tsx | 74 ++++---- .../components/DatePicker/DatePicker.web.tsx | 179 ++++++++++-------- .../blade/src/components/DatePicker/types.ts | 6 - .../blade/src/components/DatePicker/utils.ts | 148 +++++++++++++++ 4 files changed, 278 insertions(+), 129 deletions(-) create mode 100644 packages/blade/src/components/DatePicker/utils.ts diff --git a/packages/blade/src/components/DatePicker/DatePicker.stories.tsx b/packages/blade/src/components/DatePicker/DatePicker.stories.tsx index fb3195cdbad..9fd6c4898e6 100644 --- a/packages/blade/src/components/DatePicker/DatePicker.stories.tsx +++ b/packages/blade/src/components/DatePicker/DatePicker.stories.tsx @@ -1,6 +1,4 @@ import type { StoryFn, Meta } from '@storybook/react'; -import { DatesProvider } from '@mantine/dates'; -import { HeadlessMantineProvider } from '@mantine/core'; import dayjs from 'dayjs'; import React from 'react'; import type { CalendarProps, DatesRangeValue } from './types'; @@ -22,44 +20,40 @@ export const Calendar: StoryFn = ({ ...args }) => { return ( - - - setIsOpen(isOpen)} - value={date} - labelPosition="top" - onChange={(date) => { - console.log(date); - setDate(date); - }} - label={{ start: 'Start Date', end: 'End Date' }} - presets={[ - { - label: 'Past 3 days', - value: (date) => [dayjs(date).subtract(3, 'day').toDate(), date], - }, - { - label: 'Past 7 days', - value: (date) => [dayjs(date).subtract(7, 'day').toDate(), date], - }, - { - label: 'Past 30 days', - value: (date) => [dayjs(date).subtract(30, 'day').toDate(), date], - }, - { - label: 'Last Year', - value: (date) => [dayjs(date).subtract(1, 'year').toDate(), date], - }, - ]} - /> - - + setIsOpen(isOpen)} + value={date} + labelPosition="top" + onChange={(date) => { + console.log(date); + setDate(date); + }} + label={{ start: 'Start Date', end: 'End Date' }} + presets={[ + { + label: 'Past 3 days', + value: (date) => [dayjs(date).subtract(3, 'day').toDate(), date], + }, + { + label: 'Past 7 days', + value: (date) => [dayjs(date).subtract(7, 'day').toDate(), date], + }, + { + label: 'Past 30 days', + value: (date) => [dayjs(date).subtract(30, 'day').toDate(), date], + }, + { + label: 'Last Year', + value: (date) => [dayjs(date).subtract(1, 'year').toDate(), date], + }, + ]} + /> ); }; diff --git a/packages/blade/src/components/DatePicker/DatePicker.web.tsx b/packages/blade/src/components/DatePicker/DatePicker.web.tsx index 4b3d3aa40bd..d0215107910 100644 --- a/packages/blade/src/components/DatePicker/DatePicker.web.tsx +++ b/packages/blade/src/components/DatePicker/DatePicker.web.tsx @@ -2,9 +2,11 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { shiftTimezone, useDatesContext } from '@mantine/dates'; +import { DatesProvider, shiftTimezone, useDatesContext } from '@mantine/dates'; import React from 'react'; import { FloatingFocusManager, FloatingPortal } from '@floating-ui/react'; +import { useI18nContext } from '@razorpay/i18nify-react'; +import { HeadlessMantineProvider } from '@mantine/core'; import type { DatesRangeValue, DatePickerProps, DateSelectionType, PickerType } from './types'; import { Calendar } from './Calendar'; import { PresetSideBar } from './QuickSelection/PresetSideBar'; @@ -12,6 +14,7 @@ import { useDatesState } from './useDatesState'; import { DatePickerInput } from './DateInput'; import { usePopup } from './usePopup'; import { CalendarFooter } from './CalendarFooter'; +import { convertIntlToDayjsLocale } from './utils'; import BaseBox from '~components/Box/BaseBox'; import { useControllableState } from '~utils/useControllable'; import { useTheme } from '~utils'; @@ -53,12 +56,12 @@ const DatePicker = ({ onPickerChange, ...props }: DatePickerProps): React.ReactElement => { + const { i18nState } = useI18nContext(); const _selectionType = selectionType ?? 'single'; const { theme } = useTheme(); const ctx = useDatesContext(); const isSingle = _selectionType === 'single'; const [_, forceRerenderBottomSheet] = React.useReducer((x: number) => x + 1, 0); - const [selectedPreset, setSelectedPreset] = React.useState(null); const [_picker, setPicker] = useControllableState({ @@ -213,90 +216,100 @@ const DatePicker = ({ ); + const dateProviderValue = React.useMemo(() => { + return { + locale: convertIntlToDayjsLocale(i18nState?.locale ?? 'en-IN'), + }; + }, [i18nState?.locale]); + return ( - - - {isMobile ? ( - { - handleCancel(); - }} - > - - - {content} - {!isSingle && ( - { - const presetValue = preset?.(currentDate); - setControlledValue(presetValue); - setSelectedPreset(presetValue); - }} - /> - )} - - - - - - ) : ( - isMounted && ( - - + + + + {isMobile ? ( + { + handleCancel(); + }} > - - + + {content} + {!isSingle && ( + { + const presetValue = preset?.(currentDate); + setControlledValue(presetValue); + setSelectedPreset(presetValue); + }} + /> + )} + + + + + + ) : ( + isMounted && ( + + - {content} - - - - - ) - )} - + + + {content} + + + + + ) + )} + + + ); }; diff --git a/packages/blade/src/components/DatePicker/types.ts b/packages/blade/src/components/DatePicker/types.ts index 503ed6243f6..85f558c57ca 100644 --- a/packages/blade/src/components/DatePicker/types.ts +++ b/packages/blade/src/components/DatePicker/types.ts @@ -95,12 +95,6 @@ type CalendarProps = Pick< * @default false */ allowSingleDateInRange?: boolean; - /** - * Sets the locale for the calendar. - * - * @default 'en' - */ - locale?: string; /** * Callback which is called whenever the next button is clicked. diff --git a/packages/blade/src/components/DatePicker/utils.ts b/packages/blade/src/components/DatePicker/utils.ts new file mode 100644 index 00000000000..172bd73365d --- /dev/null +++ b/packages/blade/src/components/DatePicker/utils.ts @@ -0,0 +1,148 @@ +const dayjs_locales = [ + 'af', + 'ar', + 'ar-dz', + 'ar-kw', + 'ar-ly', + 'ar-ma', + 'ar-sa', + 'ar-tn', + 'az', + 'be', + 'bg', + 'bm', + 'bn', + 'bo', + 'br', + 'bs', + 'ca', + 'cs', + 'cv', + 'cy', + 'da', + 'de', + 'de-at', + 'de-ch', + 'dv', + 'el', + 'en', + 'en-au', + 'en-ca', + 'en-gb', + 'en-ie', + 'en-il', + 'en-nz', + 'en-SG', + 'eo', + 'es', + 'es-do', + 'es-us', + 'et', + 'eu', + 'fa', + 'fi', + 'fo', + 'fr', + 'fr-ca', + 'fr-ch', + 'fy', + 'ga', + 'gd', + 'gl', + 'gom-latn', + 'gu', + 'he', + 'hi', + 'hr', + 'hu', + 'hy-am', + 'id', + 'is', + 'it', + 'it-ch', + 'ja', + 'jv', + 'ka', + 'kk', + 'km', + 'kn', + 'ko', + 'ku', + 'ky', + 'lb', + 'lo', + 'lt', + 'lv', + 'me', + 'mi', + 'mk', + 'ml', + 'mn', + 'mr', + 'ms', + 'ms-my', + 'mt', + 'my', + 'nb', + 'ne', + 'nl', + 'nl-be', + 'nn', + 'oc-lnc', + 'pa-in', + 'pl', + 'pt', + 'pt-br', + 'ro', + 'ru', + 'sd', + 'se', + 'si', + 'sk', + 'sl', + 'sq', + 'sr', + 'sr-cyrl', + 'ss', + 'sv', + 'sw', + 'ta', + 'te', + 'tet', + 'tg', + 'th', + 'tl-ph', + 'tlh', + 'tr', + 'tzl', + 'tzm', + 'tzm-latn', + 'ug-cn', + 'uk', + 'ur', + 'uz', + 'uz-latn', + 'vi', + 'x-pseudo', + 'yo', + 'zh-cn', + 'zh-hk', + 'zh-tw', +]; + +// https://github.com/iamkun/dayjs/issues/732#issuecomment-554383261 +function patchLocale(locale: string): string | boolean { + if (['en', 'en-us'].includes(locale)) return 'en'; + if (locale === 'zn') return 'zh-cn'; + if (locale === 'no') return 'nb'; + if (dayjs_locales.includes(locale)) return locale; + return false; +} + +function convertIntlToDayjsLocale(lang: string): string { + lang = lang.toLowerCase(); + const locale = patchLocale(lang) || (lang.includes('-') && patchLocale(lang.split('-')[0])); + return `${locale}`; +} + +export { convertIntlToDayjsLocale };