Skip to content

Commit 426b691

Browse files
committed
feat: Add ability to control first month shown in date range picker
1 parent 6082b18 commit 426b691

14 files changed

Lines changed: 260 additions & 27 deletions

File tree

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pages/date-range-picker/common.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ interface DateRangePickerPageSettings {
2727
disabledDates?: DisabledDate;
2828
showDisabledReason?: boolean;
2929
hasValue?: boolean;
30+
absoluteMultiGridStartPeriod?: DateRangePickerProps.StartPeriod;
3031
}
3132

3233
const defaultSettings: Required<DateRangePickerPageSettings> = {
@@ -45,6 +46,7 @@ const defaultSettings: Required<DateRangePickerPageSettings> = {
4546
disabledDates: 'none',
4647
showDisabledReason: true,
4748
hasValue: true,
49+
absoluteMultiGridStartPeriod: 'current',
4850
};
4951

5052
export function useDateRangePickerSettings(
@@ -89,6 +91,7 @@ export function useDateRangePickerSettings(
8991
const disabledDates = urlParams.disabledDates ?? def('disabledDates');
9092
const showDisabledReason = parseBoolean(def('showDisabledReason'), urlParams.showDisabledReason);
9193
const hasValue = parseBoolean(def('hasValue'), urlParams.hasValue);
94+
const absoluteMultiGridStartPeriod = urlParams.absoluteMultiGridStartPeriod ?? def('absoluteMultiGridStartPeriod');
9295
const settings: Required<DateRangePickerPageSettings> = {
9396
dateOnly,
9497
monthOnly,
@@ -105,6 +108,7 @@ export function useDateRangePickerSettings(
105108
disabledDates,
106109
showDisabledReason,
107110
hasValue,
111+
absoluteMultiGridStartPeriod,
108112
};
109113
const setSettings = (settings: DateRangePickerPageSettings) => setUrlParams(settings);
110114

@@ -256,6 +260,7 @@ export function Settings({
256260
disabledDates,
257261
showDisabledReason,
258262
hasValue,
263+
absoluteMultiGridStartPeriod,
259264
},
260265
setSettings,
261266
}: {
@@ -274,6 +279,7 @@ export function Settings({
274279
const dateFormatOptions = [{ value: 'iso' }, { value: 'slashed' }, { value: 'long-localized' }];
275280
const inputDateFormat = [{ value: 'iso' }, { value: 'slashed' }];
276281
const timeFormatOptions = [{ value: 'hh:mm:ss' }, { value: 'hh:mm' }, { value: 'hh' }];
282+
const absoluteMultiGridStartPeriodOptions = [{ value: 'current' }, { value: 'previous' }];
277283
return (
278284
<SpaceBetween size="m" direction="horizontal">
279285
<FormField label="Range selector mode">
@@ -332,6 +338,20 @@ export function Settings({
332338
/>
333339
</FormField>
334340

341+
<FormField label="Start period">
342+
<Select
343+
options={absoluteMultiGridStartPeriodOptions}
344+
selectedOption={
345+
absoluteMultiGridStartPeriodOptions.find(o => o.value === absoluteMultiGridStartPeriod) ?? null
346+
}
347+
onChange={({ detail }) =>
348+
setSettings({
349+
absoluteMultiGridStartPeriod: detail.selectedOption.value as DateRangePickerProps.StartPeriod,
350+
})
351+
}
352+
/>
353+
</FormField>
354+
335355
<SpaceBetween direction="horizontal" size="s">
336356
<Checkbox checked={hasValue} onChange={({ detail }) => setSettings({ hasValue: detail.checked })}>
337357
Has initial value

pages/date-range-picker/month-calendar-permutations.page.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const permutations = createPermutations<DateRangePickerCalendarProps>([
3636
customAbsoluteRangeControl: [undefined],
3737
timeInputFormat: ['hh:mm:ss'] as const,
3838
absoluteFormat: ['long-localized'] as const,
39+
multiGridStartPeriod: ['current'] as const,
3940
})),
4041
// Disabled dates
4142
{
@@ -45,6 +46,7 @@ const permutations = createPermutations<DateRangePickerCalendarProps>([
4546
customAbsoluteRangeControl: [undefined],
4647
timeInputFormat: ['hh:mm:ss'] as const,
4748
absoluteFormat: ['long-localized'] as const,
49+
multiGridStartPeriod: ['current'] as const,
4850
},
4951
// Date-only
5052
{
@@ -54,6 +56,7 @@ const permutations = createPermutations<DateRangePickerCalendarProps>([
5456
customAbsoluteRangeControl: [undefined],
5557
timeInputFormat: ['hh:mm:ss'] as const,
5658
absoluteFormat: ['long-localized'] as const,
59+
multiGridStartPeriod: ['current'] as const,
5760
},
5861
// Custom control
5962
{
@@ -62,6 +65,7 @@ const permutations = createPermutations<DateRangePickerCalendarProps>([
6265
customAbsoluteRangeControl: [() => 'Custom control'],
6366
timeInputFormat: ['hh:mm:ss'] as const,
6467
absoluteFormat: ['long-localized'] as const,
68+
multiGridStartPeriod: ['current'] as const,
6569
},
6670
// Date input formats
6771
{
@@ -71,6 +75,7 @@ const permutations = createPermutations<DateRangePickerCalendarProps>([
7175
timeInputFormat: ['hh:mm:ss'] as const,
7276
dateInputFormat: ['iso', 'slashed'] as const,
7377
absoluteFormat: ['long-localized'] as const,
78+
multiGridStartPeriod: ['current'] as const,
7479
},
7580
// Time input formats
7681
{
@@ -79,6 +84,7 @@ const permutations = createPermutations<DateRangePickerCalendarProps>([
7984
customAbsoluteRangeControl: [undefined],
8085
timeInputFormat: ['hh:mm', 'hh'] as const,
8186
absoluteFormat: ['long-localized'] as const,
87+
multiGridStartPeriod: ['current'] as const,
8288
},
8389
]);
8490

pages/date-range-picker/range-calendar.page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export default function RangeCalendarScenario() {
3030
customAbsoluteRangeControl={undefined}
3131
timeInputFormat="hh:mm:ss"
3232
absoluteFormat="slashed"
33+
multiGridStartPeriod="current"
3334
/>
3435

3536
<Link id="focusable-after">Focusable element after</Link>

pages/date-range-picker/year-calendar-permutations.page.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const intervals = [
1919
['2022-02', '2022-03'], //next
2020
['2021-01', '2021-03'], //q1
2121
['2022-04', '2022-06'], //q2
22-
['2023-07', '2022-09'], //q3
22+
['2022-07', '2022-09'], //q3
2323
['2024-10', '2024-12'], //q4
2424
];
2525

@@ -33,6 +33,7 @@ const permutations = createPermutations<DateRangePickerCalendarProps>([
3333
customAbsoluteRangeControl: [undefined],
3434
timeInputFormat: ['hh:mm:ss'] as const,
3535
absoluteFormat: ['long-localized'] as const,
36+
multiGridStartPeriod: ['current', 'previous'] as const,
3637
})),
3738
// Disabled dates
3839
{
@@ -42,6 +43,7 @@ const permutations = createPermutations<DateRangePickerCalendarProps>([
4243
customAbsoluteRangeControl: [undefined],
4344
timeInputFormat: ['hh:mm:ss'] as const,
4445
absoluteFormat: ['long-localized'] as const,
46+
multiGridStartPeriod: ['current'] as const,
4547
},
4648
// Custom control
4749
{
@@ -50,6 +52,7 @@ const permutations = createPermutations<DateRangePickerCalendarProps>([
5052
customAbsoluteRangeControl: [() => 'Custom control'],
5153
timeInputFormat: ['hh:mm:ss'] as const,
5254
absoluteFormat: ['long-localized'] as const,
55+
multiGridStartPeriod: ['current'] as const,
5356
},
5457
// Input date formats
5558
{
@@ -59,6 +62,7 @@ const permutations = createPermutations<DateRangePickerCalendarProps>([
5962
timeInputFormat: ['hh:mm:ss'] as const,
6063
dateInputFormat: ['iso', 'slashed'] as const,
6164
absoluteFormat: ['long-localized'] as const,
65+
multiGridStartPeriod: ['current'] as const,
6266
},
6367
]);
6468

src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10816,6 +10816,22 @@ It can take the following values:
1081610816
"optional": true,
1081710817
"type": "string",
1081810818
},
10819+
{
10820+
"defaultValue": "'current'",
10821+
"description": "Specifies whether to start with the previous or current period (month or year)
10822+
when multiple calendar grids are displayed in absolute mode.",
10823+
"inlineType": {
10824+
"name": "DateRangePickerProps.StartPeriod",
10825+
"type": "union",
10826+
"values": [
10827+
"current",
10828+
"previous",
10829+
],
10830+
},
10831+
"name": "absoluteMultiGridStartPeriod",
10832+
"optional": true,
10833+
"type": "string",
10834+
},
1081910835
{
1082010836
"description": "Adds \`aria-describedby\` to the component. If you're using this component within a form field,
1082110837
don't set this property because the form field component automatically sets it.

src/date-range-picker/__tests__/date-range-picker-absolute.test.tsx

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,71 @@ describe('Date range picker', () => {
11541154
});
11551155
});
11561156

1157+
describe('absoluteMultiGridStartPeriod', () => {
1158+
test('defaults to "current" - header shows start date period on the left grid', () => {
1159+
const { wrapper } = renderDateRangePicker({
1160+
...defaultProps,
1161+
granularity,
1162+
value: { type: 'absolute', startDate: '2020-03-02T05:00:00+08:45', endDate: '2020-03-12T13:05:21+08:45' },
1163+
});
1164+
1165+
wrapper.findTrigger().click();
1166+
1167+
// Default "current" means the start date's month/year appears in the left grid
1168+
// For day: left=March 2020, right=April 2020, header shows "March 2020April 2020"
1169+
// For month: left=2020, right=2021, header shows "20202021"
1170+
const expectedResult = granularity === 'day' ? 'March 2020' : '20202021';
1171+
expect(wrapper.findDropdown()!.findHeader().getElement()).toHaveTextContent(expectedResult);
1172+
});
1173+
1174+
test('"current" explicitly set shows same as default', () => {
1175+
const { wrapper } = renderDateRangePicker({
1176+
...defaultProps,
1177+
granularity,
1178+
absoluteMultiGridStartPeriod: 'current',
1179+
value: { type: 'absolute', startDate: '2020-03-02T05:00:00+08:45', endDate: '2020-03-12T13:05:21+08:45' },
1180+
});
1181+
1182+
wrapper.findTrigger().click();
1183+
1184+
const expectedResult = granularity === 'day' ? 'March 2020' : '20202021';
1185+
expect(wrapper.findDropdown()!.findHeader().getElement()).toHaveTextContent(expectedResult);
1186+
});
1187+
1188+
test('"previous" shows the previous period on the left grid', () => {
1189+
const { wrapper } = renderDateRangePicker({
1190+
...defaultProps,
1191+
granularity,
1192+
absoluteMultiGridStartPeriod: 'previous',
1193+
value: { type: 'absolute', startDate: '2020-03-02T05:00:00+08:45', endDate: '2020-03-12T13:05:21+08:45' },
1194+
});
1195+
1196+
wrapper.findTrigger().click();
1197+
1198+
// "previous" means start date's month/year is shown on the right grid, previous on the left
1199+
// For day: left=February 2020, right=March 2020, header shows "February 2020March 2020"
1200+
// For month: left=2019, right=2020, header shows "20192020"
1201+
const expectedResult = granularity === 'day' ? 'February 2020' : '20192020';
1202+
expect(wrapper.findDropdown()!.findHeader().getElement()).toHaveTextContent(expectedResult);
1203+
});
1204+
1205+
test('"previous" allows start date to be visible in right grid', () => {
1206+
const { wrapper } = renderDateRangePicker({
1207+
...defaultProps,
1208+
granularity,
1209+
absoluteMultiGridStartPeriod: 'previous',
1210+
value: { type: 'absolute', startDate: '2021-06-15T00:00:00+08:45', endDate: '2021-06-20T23:59:59+08:45' },
1211+
});
1212+
1213+
wrapper.findTrigger().click();
1214+
1215+
// For day: left=May 2021, right=June 2021
1216+
// For month: left=2020, right=2021
1217+
const expectedResult = granularity === 'day' ? 'May 2021' : '20202021';
1218+
expect(wrapper.findDropdown()!.findHeader().getElement()).toHaveTextContent(expectedResult);
1219+
});
1220+
});
1221+
11571222
describe('i18n', () => {
11581223
describe.each([true, false] as const)('With dateOnly of %s', dateOnly => {
11591224
test('supports using absolute range with i18n defaults', () => {

0 commit comments

Comments
 (0)