Skip to content

Commit 186c07c

Browse files
committed
feat: Adding custom date formats
1 parent 2196366 commit 186c07c

31 files changed

+2011
-571
lines changed

pages/date-input/common.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
export const generatePlaceholder = (monthOnly: boolean, isIso: boolean) => {
4+
const separator = isIso ? '-' : '/';
5+
return `YYYY${separator}${monthOnly ? 'MM' : 'MM' + separator + 'DD'}`;
6+
};
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import React from 'react';
4+
5+
import Box from '~components/box';
6+
import DateInput, { DateInputProps } from '~components/date-input';
7+
8+
import createPermutations from '../utils/permutations';
9+
import PermutationsView from '../utils/permutations-view';
10+
import ScreenshotArea from '../utils/screenshot-area';
11+
import { generatePlaceholder } from './common';
12+
13+
const permutations = createPermutations<DateInputProps>([
14+
{
15+
value: ['', '2020-01-01'],
16+
placeholder: ['', 'applied'],
17+
format: ['slashed', 'iso', 'long-localized'],
18+
inputFormat: ['slashed', 'iso'],
19+
ariaLabel: ['Some label'],
20+
invalid: [false, true],
21+
readOnly: [false, true],
22+
disabled: [false, true],
23+
},
24+
]);
25+
26+
export default function DateInputPermutations() {
27+
return (
28+
<Box padding="l">
29+
<h1>Date Input permutations</h1>
30+
<ScreenshotArea disableAnimations={true}>
31+
<PermutationsView
32+
permutations={permutations}
33+
render={permutation => (
34+
<DateInput
35+
onChange={() => {
36+
/*empty handler to suppress react controlled property warning*/
37+
}}
38+
{...permutation}
39+
granularity="day"
40+
locale="en-US"
41+
placeholder={
42+
permutation.placeholder
43+
? generatePlaceholder(
44+
false,
45+
permutation.format === 'iso' ||
46+
(permutation.format === 'long-localized' && permutation.inputFormat === 'iso')
47+
)
48+
: ''
49+
}
50+
/>
51+
)}
52+
/>
53+
</ScreenshotArea>
54+
</Box>
55+
);
56+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import React from 'react';
4+
5+
import Box from '~components/box';
6+
import DateInput, { DateInputProps } from '~components/date-input';
7+
8+
import createPermutations from '../utils/permutations';
9+
import PermutationsView from '../utils/permutations-view';
10+
import ScreenshotArea from '../utils/screenshot-area';
11+
12+
const locales = [
13+
'ar',
14+
'de',
15+
'en-GB',
16+
'en-US',
17+
'es',
18+
'fr',
19+
'he',
20+
'id',
21+
'it',
22+
'ja',
23+
'ko',
24+
'ms',
25+
'pt-BR',
26+
'th',
27+
'tr',
28+
'vi',
29+
'zh-CN',
30+
'zh-TW',
31+
];
32+
const permutations = createPermutations<DateInputProps>([
33+
{
34+
value: ['2020-01-01'],
35+
format: ['long-localized'],
36+
locale: [...locales],
37+
granularity: ['day', 'month'],
38+
},
39+
]);
40+
41+
export default function DateInputPermutations() {
42+
return (
43+
<Box padding="l">
44+
<h1>Date Input permutations</h1>
45+
<ScreenshotArea disableAnimations={true}>
46+
<PermutationsView
47+
permutations={permutations}
48+
render={permutation => (
49+
<DateInput
50+
onChange={() => {
51+
/*empty handler to suppress react controlled property warning*/
52+
}}
53+
{...permutation}
54+
/>
55+
)}
56+
/>
57+
</ScreenshotArea>
58+
</Box>
59+
);
60+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import React from 'react';
4+
5+
import Box from '~components/box';
6+
import DateInput, { DateInputProps } from '~components/date-input';
7+
8+
import createPermutations from '../utils/permutations';
9+
import PermutationsView from '../utils/permutations-view';
10+
import ScreenshotArea from '../utils/screenshot-area';
11+
import { generatePlaceholder } from './common';
12+
13+
const permutations = createPermutations<DateInputProps>([
14+
{
15+
value: ['', '2020-01'],
16+
placeholder: ['', 'applied'],
17+
format: ['slashed', 'iso', 'long-localized'],
18+
inputFormat: ['slashed', 'iso'],
19+
ariaLabel: ['Some label'],
20+
invalid: [false, true],
21+
readOnly: [false, true],
22+
disabled: [false, true],
23+
},
24+
]);
25+
26+
export default function DateInputPermutations() {
27+
return (
28+
<Box padding="l">
29+
<h1>Date Input permutations</h1>
30+
<ScreenshotArea disableAnimations={true}>
31+
<PermutationsView
32+
permutations={permutations}
33+
render={permutation => (
34+
<DateInput
35+
onChange={() => {
36+
/*empty handler to suppress react controlled property warning*/
37+
}}
38+
{...permutation}
39+
granularity="month"
40+
locale="en-US"
41+
placeholder={
42+
permutation.placeholder
43+
? generatePlaceholder(
44+
true,
45+
permutation.format === 'iso' ||
46+
(permutation.format === 'long-localized' && permutation.inputFormat === 'iso')
47+
)
48+
: ''
49+
}
50+
/>
51+
)}
52+
/>
53+
</ScreenshotArea>
54+
</Box>
55+
);
56+
}

pages/date-input/simple.page.tsx

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,27 @@ export type DateInputDemoContext = React.Context<
1212
AppContextType<{
1313
monthOnly?: boolean;
1414
hasValue?: boolean;
15+
readonly?: boolean;
16+
disabled?: boolean;
17+
inputFormat?: DateInputProps.InputFormat | '';
18+
format?: DateInputProps.Format | '';
19+
locale?: DateInputProps['locale'] | '';
1520
}>
1621
>;
1722

1823
export default function DateInputScenario() {
1924
const { urlParams, setUrlParams } = useContext(AppContext as DateInputDemoContext);
2025
const initValue = '2025-02-14';
2126
const hasValue = urlParams.hasValue ?? false;
27+
const inputFormat = urlParams.inputFormat ?? '';
28+
const disabled = urlParams.disabled ?? false;
29+
const readonly = urlParams.readonly ?? false;
30+
const format = urlParams.format ?? '';
31+
const locale = urlParams.locale ?? 'en-US';
32+
const monthOnly = urlParams.monthOnly ?? false;
2233
const [value, setValue] = useState<DateInputProps['value']>('');
34+
const isIso = (format === 'long-localized' && inputFormat === 'iso') || inputFormat === 'iso';
35+
const inputFormatPlaceholderText = `YYYY${isIso ? '-' : '/'}MM${monthOnly ? `` : `${isIso ? '-' : '/'}DD`}`;
2336

2437
useEffect(() => {
2538
if (hasValue) {
@@ -37,14 +50,85 @@ export default function DateInputScenario() {
3750
<Checkbox checked={hasValue} onChange={({ detail }) => setUrlParams({ hasValue: detail.checked })}>
3851
Has initial value
3952
</Checkbox>
53+
<Checkbox checked={readonly} onChange={({ detail }) => setUrlParams({ readonly: detail.checked })}>
54+
Read-only
55+
</Checkbox>
56+
<Checkbox checked={disabled} onChange={({ detail }) => setUrlParams({ disabled: detail.checked })}>
57+
Disabled
58+
</Checkbox>
59+
<Checkbox checked={monthOnly} onChange={({ detail }) => setUrlParams({ monthOnly: detail.checked })}>
60+
Month-only
61+
</Checkbox>
62+
<label>
63+
Format
64+
<select
65+
value={format}
66+
onChange={event =>
67+
setUrlParams({
68+
format: event.currentTarget.value as DateInputProps.InputFormat,
69+
})
70+
}
71+
>
72+
<option value="slashed">Slashed (Default)</option>
73+
<option value="iso">Iso</option>
74+
<option value="long-localized">Long localized</option>
75+
</select>
76+
</label>
77+
<label>
78+
Input format
79+
<select
80+
value={inputFormat}
81+
disabled={format !== 'long-localized'}
82+
onChange={event =>
83+
setUrlParams({
84+
inputFormat: event.currentTarget.value as DateInputProps.InputFormat,
85+
})
86+
}
87+
>
88+
<option value="slashed">Slashed (Default)</option>
89+
<option value="iso">Iso</option>
90+
</select>
91+
</label>
92+
<label>
93+
Locale
94+
<select
95+
value={locale}
96+
onChange={event =>
97+
setUrlParams({
98+
locale: event.currentTarget.value as DateInputProps['locale'],
99+
})
100+
}
101+
>
102+
<option value="ar">ar</option>
103+
<option value="en-US">en-US</option>
104+
<option value="en-GB">en-GB</option>
105+
<option value="de">de</option>
106+
<option value="es">es</option>
107+
<option value="fr">fr</option>
108+
<option value="it">it</option>
109+
<option value="ja">ja</option>
110+
<option value="ko">ko</option>
111+
<option value="tr">tr</option>
112+
<option value="pt-BR">pt-BR</option>
113+
<option value="ru">ru</option>
114+
<option value="zh-CN">zh-CN</option>
115+
<option value="zh-TW">zh-TW</option>
116+
</select>
117+
</label>
40118
</SpaceBetween>
41119
<DateInput
42120
className="testing-date-input"
43121
name="date"
44-
ariaLabel="Enter the date in YYYY/MM/DD"
45-
placeholder="YYYY/MM/DD"
122+
ariaLabel={`Enter the date in ${inputFormatPlaceholderText}`}
123+
placeholder={inputFormatPlaceholderText}
46124
onChange={e => setValue(e.detail.value)}
47125
value={value}
126+
readOnly={readonly}
127+
disabled={disabled}
128+
format={format === '' ? undefined : format}
129+
inputFormat={inputFormat === '' ? undefined : inputFormat}
130+
granularity={monthOnly ? 'month' : 'day'}
131+
locale={locale}
48132
/>
49133
<b>Raw value</b>
50134
<pre>{JSON.stringify(value, undefined, 2)}</pre>

pages/date-input/permutations.page.tsx renamed to pages/date-input/value-permutations.page.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@ import ScreenshotArea from '../utils/screenshot-area';
1111

1212
const permutations = createPermutations<DateInputProps>([
1313
{
14-
value: ['', '2020-01-01'],
15-
placeholder: ['', 'YYYY/MM/DD'],
16-
ariaLabel: ['Some label'],
17-
invalid: [false, true],
18-
readOnly: [false, true],
19-
disabled: [false, true],
14+
value: ['2020', '2020-01', '2020-01-01'],
15+
format: ['slashed', 'iso', 'long-localized'],
16+
inputFormat: ['slashed', 'iso'],
17+
granularity: ['day', 'month'],
2018
},
2119
]);
2220

@@ -33,6 +31,7 @@ export default function DateInputPermutations() {
3331
/*empty handler to suppress react controlled property warning*/
3432
}}
3533
{...permutation}
34+
locale="en-US"
3635
/>
3736
)}
3837
/>

pages/date-picker/common.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
export const generatePlaceholder = (monthOnly: boolean, isIso: boolean) => {
4+
const separator = isIso ? '-' : '/';
5+
return `YYYY${separator}${monthOnly ? 'MM' : 'MM' + separator + 'DD'}`;
6+
};
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import React from 'react';
4+
import MockDate from 'mockdate';
5+
6+
import { Box, DatePicker, DatePickerProps, SpaceBetween } from '~components';
7+
8+
import createPermutations from '../utils/permutations';
9+
import PermutationsView from '../utils/permutations-view';
10+
import ScreenshotArea from '../utils/screenshot-area';
11+
12+
// Mock the date in order to have the current day styling in place for screenshot testing.
13+
MockDate.set(new Date(2020, 9, 8));
14+
15+
const openCalendarAriaLabel = (selectedDate: string | null) =>
16+
'Choose Date' + (selectedDate ? `, selected date is ${selectedDate}` : '');
17+
18+
const permutations = createPermutations<DatePickerProps>([
19+
{
20+
value: ['2020-03-01'],
21+
todayAriaLabel: ['Today'],
22+
nextMonthAriaLabel: ['Next Month'],
23+
previousMonthAriaLabel: ['Previous Month'],
24+
name: ['date-picker-name'],
25+
locale: ['en-US', 'de'],
26+
ariaLabel: ['date-picker-label'],
27+
granularity: ['day', 'month'],
28+
openCalendarAriaLabel: [openCalendarAriaLabel],
29+
format: ['iso', 'long-localized', 'slashed'],
30+
inputFormat: ['iso', 'slashed'],
31+
},
32+
]);
33+
34+
export default function DatePickerScenario() {
35+
return (
36+
<Box padding="s">
37+
<h1>Date picker permutations</h1>
38+
<ScreenshotArea>
39+
<SpaceBetween size="m">
40+
<PermutationsView permutations={permutations} render={permutation => <DatePicker {...permutation} />} />
41+
</SpaceBetween>
42+
</ScreenshotArea>
43+
</Box>
44+
);
45+
}

pages/date-picker/permutations.page.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ const permutations = createPermutations<DatePickerProps>([
3030
name: ['date-picker-name'],
3131
ariaLabel: ['date-picker-label'],
3232
openCalendarAriaLabel: [openCalendarAriaLabel],
33+
format: ['iso', 'long-localized', 'slashed'],
34+
inputFormat: ['iso', 'slashed'],
3335
},
3436
]);
3537

0 commit comments

Comments
 (0)