Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change PlainDateRange to an object #2741

Merged
merged 5 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/four-geckos-complain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sumup-oss/circuit-ui': major
---

Changed the `PlainDateRange` type from a tuple to an object with `start` and `end` properties. This affects the Calendar component's `selection` prop. Use the new `updatePlainDateRange` helper function to update a date range when a user selects a date.
6 changes: 3 additions & 3 deletions docs/introduction/2-getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ npm install @sumup-oss/circuit-ui
yarn add @sumup-oss/circuit-ui
```

Circuit UI relies on some mandatory peer dependencies, namely [@sumup-oss/design-tokens](https://www.npmjs.com/package/@sumup-oss/design-tokens), [@sumup-oss/icons](https://www.npmjs.com/package/@sumup-oss/icons), [@sumup-oss/intl](https://www.npmjs.com/package/@sumup-oss/intl), and [React](https://reactjs.org/). You should install them with the following command:
Circuit UI relies on some mandatory peer dependencies, namely [@sumup-oss/design-tokens](https://www.npmjs.com/package/@sumup-oss/design-tokens), [@sumup-oss/icons](https://www.npmjs.com/package/@sumup-oss/icons), [@sumup-oss/intl](https://www.npmjs.com/package/@sumup-oss/intl), [React](https://reactjs.org/), and [temporal-polyfill](https://www.npmjs.com/package/temporal-polyfill). You should install them with the following command:

```sh
# With npm:
npm install --save @sumup-oss/design-tokens @sumup-oss/icons @sumup-oss/intl react react-dom
npm install --save @sumup-oss/design-tokens @sumup-oss/icons @sumup-oss/intl react react-dom temporal-polyfill
# With yarn v1
yarn add @sumup-oss/design-tokens @sumup-oss/icons @sumup-oss/intl react react-dom
yarn add @sumup-oss/design-tokens @sumup-oss/icons @sumup-oss/intl react react-dom temporal-polyfill
```

We also recommend installing and configuring [`@sumup-oss/eslint-plugin-circuit-ui`](Packages/eslint-plugin-circuit-ui/Docs) and [`@sumup-oss/stylelint-plugin-circuit-ui`](Packages/stylelint-plugin-circuit-ui/Docs). The plugins will lint [Circuit UI custom properties](Features/Theme/Docs) and include codemods for Circuit UI breaking changes.
Expand Down
13 changes: 1 addition & 12 deletions packages/circuit-ui/components/Calendar/Calendar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,11 @@ The Calendar component displays a monthly date grid. This is a low-level compone
<Story of={Stories.Base} />
<Props />

## Dependencies

The Calendar component uses the experimental [`Temporal` API](https://tc39.es/proposal-temporal/docs/) which has reached [stage 3](https://github.com/tc39/proposals#stage-3) in the [ECMAScript proposal](https://github.com/tc39/proposal-temporal) process but isn't implemented in [most browsers](https://caniuse.com/temporal) yet. Circuit UI depends on a [polyfill](https://github.com/fullcalendar/temporal-polyfill) which you need to install to use the component in your application:

```bash
# npm
npm install temporal-polyfill
# yarn v1
yarn add temporal-polyfill
```

## Usage

### Selection

Use the `selection` prop to set the currently selected date or date range and the `onSelect` prop to update the selection when a user picks a different date. Use the `minDate` and `maxDate` props to restrict the available date range or use [modifiers](#modifiers) to disable individual days.
Use the `selection` prop to set the currently selected date or date range and the `onSelect` prop to update the selection when a user picks a different date. Use the exported `updatePlainDateRange` function to update a date range when a user selects a date. Use the `minDate` and `maxDate` props to restrict the available date range or use [modifiers](#modifiers) to disable individual days.

<Story of={Stories.Range} />

Expand Down
11 changes: 6 additions & 5 deletions packages/circuit-ui/components/Calendar/Calendar.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

.months {
display: flex;
isolation: isolate;
}

.month:not(:last-child) {
Expand Down Expand Up @@ -97,7 +98,7 @@
touch-action: manipulation;
cursor: pointer;
background: none;
border: 0;
border: 1px solid transparent;
border-radius: var(--cui-border-radius-circle);
}

Expand All @@ -114,17 +115,17 @@
}

.day[aria-current="date"] {
border: 1px solid var(--cui-border-normal);
border-color: var(--cui-border-normal);
}

.day:hover {
background: var(--cui-bg-normal-hovered);
border: 1px solid var(--cui-border-strong-hovered);
border-color: var(--cui-border-strong-hovered);
}

.day:active {
background: var(--cui-bg-normal-pressed);
border: 1px solid var(--cui-border-strong-pressed);
border-color: var(--cui-border-strong-pressed);
}

/* Selected */
Expand Down Expand Up @@ -203,7 +204,7 @@ td:not(:last-of-type) .range-end.last-day::before {
}

.day[aria-current="date"][aria-disabled="true"] {
border: 1px solid var(--cui-border-normal-disabled);
border-color: var(--cui-border-normal-disabled);
}

.day[aria-disabled="true"].selected,
Expand Down
13 changes: 6 additions & 7 deletions packages/circuit-ui/components/Calendar/Calendar.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
waitFor,
act,
} from '../../util/test-utils.js';
import type { PlainDateRange } from '../../util/date.js';

import { Calendar } from './Calendar.js';

Expand Down Expand Up @@ -224,10 +223,10 @@ describe('Calendar', () => {
});

it('should mark the selected date range', () => {
const selection = [
new Temporal.PlainDate(2020, 3, 15),
new Temporal.PlainDate(2020, 3, 25),
] satisfies PlainDateRange;
const selection = {
start: new Temporal.PlainDate(2020, 3, 15),
end: new Temporal.PlainDate(2020, 3, 25),
};
const { container } = render(
<Calendar {...baseProps} selection={selection} />,
);
Expand All @@ -236,8 +235,8 @@ describe('Calendar', () => {
expect(selectedDays).toHaveLength(11);

for (
let index = selection[0].day;
index <= selection[1].day;
let index = selection.start.day;
index <= selection.end.day;
index += 1
) {
const selectedDay = screen.getByRole('button', {
Expand Down
25 changes: 10 additions & 15 deletions packages/circuit-ui/components/Calendar/Calendar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ import isChromatic from 'chromatic/isChromatic';
import { Temporal } from 'temporal-polyfill';

import { Stack } from '../../../../.storybook/components/index.js';
import { getTodaysDate, type PlainDateRange } from '../../util/date.js';
import {
getTodaysDate,
updatePlainDateRange,
type PlainDateRange,
} from '../../util/date.js';

import { Calendar, type CalendarProps } from './Calendar.js';

Expand Down Expand Up @@ -118,26 +122,17 @@ export const Range = (args: CalendarProps) => {
const [selection, setSelection] = useState(args.selection as PlainDateRange);

const handleSelect = (date: Temporal.PlainDate) => {
setSelection((prevSelection) => {
if (
// Nothing selected yet
prevSelection.length === 0 ||
// Full range already selected
prevSelection.length === 2 ||
// Selected date is before previous start date
Temporal.PlainDate.compare(prevSelection[0], date) > 0
) {
return [date];
}
return [prevSelection[0], date];
});
setSelection((prevSelection) => updatePlainDateRange(prevSelection, date));
};

return <Calendar {...args} selection={selection} onSelect={handleSelect} />;
};

Range.args = {
...Base.args,
selection: [today.subtract({ days: 3 }), today.add({ days: 3 })],
selection: {
start: today.subtract({ days: 3 }),
end: today.add({ days: 3 }),
},
numberOfMonths: 2,
};
Loading