From 7bc70c61a6120b0021f23dc5f69638a056c6875b Mon Sep 17 00:00:00 2001 From: Andrey Yamanov Date: Tue, 26 Sep 2023 11:54:29 +0400 Subject: [PATCH] feat(DateInput): use standard date format --- .changeset/smart-penguins-press.md | 5 +++ .../forms/DatePicker/DateInput.stories.tsx | 3 ++ src/components/forms/DatePicker/DateInput.tsx | 8 +++- .../forms/DatePicker/DatePicker.stories.tsx | 3 ++ .../forms/DatePicker/DatePicker.tsx | 11 ++++- .../forms/DatePicker/DatePickerInput.tsx | 8 +++- .../DatePicker/DateRangePicker.stories.tsx | 3 ++ .../forms/DatePicker/DateRangePicker.tsx | 17 +++++--- src/components/forms/DatePicker/utils.ts | 40 +++++++++++++++++++ 9 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 .changeset/smart-penguins-press.md diff --git a/.changeset/smart-penguins-press.md b/.changeset/smart-penguins-press.md new file mode 100644 index 00000000..22c200b9 --- /dev/null +++ b/.changeset/smart-penguins-press.md @@ -0,0 +1,5 @@ +--- +'@cube-dev/ui-kit': minor +--- + +Use standard date format for all date inputs. diff --git a/src/components/forms/DatePicker/DateInput.stories.tsx b/src/components/forms/DatePicker/DateInput.stories.tsx index b6213099..a00311b4 100644 --- a/src/components/forms/DatePicker/DateInput.stories.tsx +++ b/src/components/forms/DatePicker/DateInput.stories.tsx @@ -78,3 +78,6 @@ WithLimitedRange.args = { minValue: parseAbsoluteDate('2023-10-04'), maxValue: parseAbsoluteDate('2023-12-15'), }; + +export const WithLocale = Template.bind({}); +WithLocale.args = { useLocale: true }; diff --git a/src/components/forms/DatePicker/DateInput.tsx b/src/components/forms/DatePicker/DateInput.tsx index a348e7c0..c8e38e90 100644 --- a/src/components/forms/DatePicker/DateInput.tsx +++ b/src/components/forms/DatePicker/DateInput.tsx @@ -19,7 +19,7 @@ import { FieldBaseProps, ValidationState } from '../../../shared'; import { mergeProps } from '../../../utils/react'; import { useFieldProps, useFormProps } from '../Form'; -import { useFocusManagerRef } from './utils'; +import { formatSegments, useFocusManagerRef } from './utils'; import { DateInputBase } from './DateInputBase'; import { DatePickerSegment } from './DatePickerSegment'; import { DEFAULT_DATE_PROPS } from './props'; @@ -35,6 +35,7 @@ export interface CubeDateInputProps styles?: Styles; size?: 'small' | 'medium' | 'large' | (string & {}); validationState?: ValidationState; + useLocale?: boolean; } function DateInput( @@ -60,6 +61,7 @@ function DateInput( isReadOnly, isRequired, size = 'medium', + useLocale: useLocaleProp, } = props; let styles = extractStyles(props, CONTAINER_STYLES, wrapperStyles); @@ -72,6 +74,10 @@ function DateInput( createCalendar, }); + if (!useLocaleProp) { + state.segments = formatSegments(state.segments); + } + let fieldRef = useRef(null); let { labelProps, fieldProps } = useDateField(props, state, fieldRef); diff --git a/src/components/forms/DatePicker/DatePicker.stories.tsx b/src/components/forms/DatePicker/DatePicker.stories.tsx index 765fa187..597bc960 100644 --- a/src/components/forms/DatePicker/DatePicker.stories.tsx +++ b/src/components/forms/DatePicker/DatePicker.stories.tsx @@ -82,3 +82,6 @@ WithLimitedRange.args = { minValue: parseAbsoluteDate('2023-10-04'), maxValue: parseAbsoluteDate('2023-12-15'), }; + +export const WithLocale = Template.bind({}); +WithLocale.args = { useLocale: true }; diff --git a/src/components/forms/DatePicker/DatePicker.tsx b/src/components/forms/DatePicker/DatePicker.tsx index 359690c8..d9bdc908 100644 --- a/src/components/forms/DatePicker/DatePicker.tsx +++ b/src/components/forms/DatePicker/DatePicker.tsx @@ -41,6 +41,7 @@ export interface CubeDatePickerProps validationState?: ValidationState; maxVisibleMonths?: number; shouldFlip?: boolean; + useLocale?: boolean; } function DatePicker( @@ -56,7 +57,13 @@ function DatePicker( let styles = extractStyles(props, CONTAINER_STYLES); - let { size, placeholderValue, isDisabled, validationState } = props; + let { + size, + placeholderValue, + isDisabled, + validationState, + useLocale: useLocaleProp, + } = props; let targetRef = useRef(null); let state = useDatePickerState({ ...props, @@ -101,7 +108,7 @@ function DatePicker( validationState={validationState} size={size} > - + extends SpectrumDatePickerProps { hideValidationIcon?: boolean; maxGranularity?: SpectrumDatePickerProps['granularity']; + useLocale?: boolean; } export function DatePickerInput( props: CubeDatePickerInputProps, ) { - let { isDisabled, isReadOnly, isRequired } = props; + let { isDisabled, isReadOnly, isRequired, useLocale: useLocaleProp } = props; let ref = useRef(null); let { locale } = useLocale(); let state = useDateFieldState({ @@ -36,6 +38,10 @@ export function DatePickerInput( createCalendar, }); + if (!useLocaleProp) { + state.segments = formatSegments(state.segments); + } + let { fieldProps } = useDateField(props, state, ref); return ( diff --git a/src/components/forms/DatePicker/DateRangePicker.stories.tsx b/src/components/forms/DatePicker/DateRangePicker.stories.tsx index 8c397118..54797ba0 100644 --- a/src/components/forms/DatePicker/DateRangePicker.stories.tsx +++ b/src/components/forms/DatePicker/DateRangePicker.stories.tsx @@ -69,3 +69,6 @@ Disabled.args = { isDisabled: true }; export const Small = Template.bind({}); Small.args = { size: 'small' }; + +export const WithLocale = Template.bind({}); +WithLocale.args = { useLocale: true }; diff --git a/src/components/forms/DatePicker/DateRangePicker.tsx b/src/components/forms/DatePicker/DateRangePicker.tsx index a1b2f8fe..fa09cdad 100644 --- a/src/components/forms/DatePicker/DateRangePicker.tsx +++ b/src/components/forms/DatePicker/DateRangePicker.tsx @@ -32,7 +32,7 @@ import { dateMessages } from './intl'; const DateRangeDash = tasty({ 'aria-hidden': 'true', 'data-qa': 'DateRangeDash', - children: '–', + children: '––', styles: { padding: '0 .5x', }, @@ -50,6 +50,7 @@ export interface CubeDateRangePickerProps validationState?: ValidationState; maxVisibleMonths?: number; shouldFlip?: boolean; + useLocale?: boolean; } function DateRangePicker( @@ -65,8 +66,14 @@ function DateRangePicker( let styles = extractStyles(props, CONTAINER_STYLES); - let { size, shouldFlip, placeholderValue, isDisabled, validationState } = - props; + let { + size, + shouldFlip, + placeholderValue, + isDisabled, + validationState, + useLocale: useLocaleProp, + } = props; let targetRef = useRef(null); let state = useDateRangePickerState({ ...props, @@ -111,9 +118,9 @@ function DateRangePicker( size={size} styles={{ radius: 'left', border: 'top left bottom' }} > - + - + , @@ -73,3 +74,42 @@ export function useFocusManagerRef(ref: FocusableRef) { })); return domRef; } + +export function formatSegments(segments: DateSegment[]) { + segments = JSON.parse(JSON.stringify(segments)); + + segments.forEach((segment) => { + if (segment.type === 'literal') { + if (segment.text === '/') { + segment.text = '-'; + } + + if (segment.text === ', ') { + segment.text = ' '; + } + } + }); + + const year = segments.find((s) => s.type === 'year'); + + if (year) { + segments.splice(segments.indexOf(year), 1); + segments.unshift(year); + } + + const month = segments.find((s) => s.type === 'month'); + + if (month) { + segments.splice(segments.indexOf(month), 1); + segments.splice(2, 0, month); + } + + const day = segments.find((s) => s.type === 'day'); + + if (day) { + segments.splice(segments.indexOf(day), 1); + segments.splice(4, 0, day); + } + + return segments; +}