Skip to content
Draft
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
232 changes: 232 additions & 0 deletions apps/docs/docs/components/other/Calendar/_mobileExamples.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
### Basic usage

A basic Calendar with date selection functionality. The Calendar component is used within the DatePicker and can also be used independently.

```jsx
function Example() {
const [selectedDate, setSelectedDate] = useState(new Date());

return <Calendar selectedDate={selectedDate} onPressDate={setSelectedDate} />;
}
```

### No selection

A Calendar without an initially selected date.

```jsx
function Example() {
const [selectedDate, setSelectedDate] = useState(null);

return <Calendar selectedDate={selectedDate} onPressDate={setSelectedDate} />;
}
```

### Seeding the calendar

The `seedDate` prop controls which month the Calendar opens to when there is no selected date value. Defaults to today when undefined.

```jsx
function Example() {
const [selectedDate, setSelectedDate] = useState(null);

const today = new Date(new Date().setHours(0, 0, 0, 0));
const seedDate = new Date(today.getFullYear(), today.getMonth() + 1, 15);

return <Calendar selectedDate={selectedDate} onPressDate={setSelectedDate} seedDate={seedDate} />;
}
```

### Minimum and maximum dates

Use `minDate` and `maxDate` to restrict the selectable date range. Navigation to dates before the `minDate` and after the `maxDate` is disabled. Make sure to provide the `disabledDateError` prop.

```jsx
function Example() {
const [selectedDate, setSelectedDate] = useState(new Date());

const today = new Date(new Date().setHours(0, 0, 0, 0));
const lastMonth15th = new Date(today.getFullYear(), today.getMonth() - 1, 15);
const nextMonth15th = new Date(today.getFullYear(), today.getMonth() + 1, 15);

return (
<Calendar
selectedDate={selectedDate}
onPressDate={setSelectedDate}
minDate={lastMonth15th}
maxDate={nextMonth15th}
disabledDateError="Date is outside allowed range"
/>
);
}
```

### Future dates only

Restrict selection to future dates by setting `minDate` to today.

```jsx
function Example() {
const [selectedDate, setSelectedDate] = useState(null);

const today = new Date(new Date().setHours(0, 0, 0, 0));

return (
<Calendar
selectedDate={selectedDate}
onPressDate={setSelectedDate}
minDate={today}
disabledDateError="Past dates are not available"
/>
);
}
```

### Highlighted dates

Use `highlightedDates` to visually emphasize specific dates or date ranges. A number is created for every individual date within a tuple range, so do not abuse this with massive ranges.

```jsx
function Example() {
const [selectedDate, setSelectedDate] = useState(new Date());

const today = new Date(new Date().setHours(0, 0, 0, 0));
const yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1);
const nextWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7);

return (
<Calendar
selectedDate={selectedDate}
onPressDate={setSelectedDate}
highlightedDates={[yesterday, today, nextWeek]}
/>
);
}
```

### Disabled dates

Use `disabledDates` to prevent selection of specific dates or date ranges. Make sure to provide the `disabledDateError` prop.

```jsx
function Example() {
const [selectedDate, setSelectedDate] = useState(null);

const today = new Date(new Date().setHours(0, 0, 0, 0));

// Disable weekends for demonstration
const getNextWeekendDates = (centerDate) => {
const weekends = [];
const currentDate = new Date(centerDate);

// Find next 4 weekends
for (let i = 0; i < 4; i++) {
// Find next Saturday
const daysUntilSaturday = (6 - currentDate.getDay() + 7) % 7 || 7;
currentDate.setDate(currentDate.getDate() + daysUntilSaturday);

const saturday = new Date(currentDate);
const sunday = new Date(currentDate);
sunday.setDate(sunday.getDate() + 1);

weekends.push([saturday, sunday]);

// Move to next week
currentDate.setDate(currentDate.getDate() + 7);
}

return weekends;
};

return (
<Calendar
selectedDate={selectedDate}
onPressDate={setSelectedDate}
disabledDates={getNextWeekendDates(today)}
disabledDateError="Weekends are not available"
/>
);
}
```

### Date ranges

Highlight a date range using a tuple `[startDate, endDate]`.

```jsx
function Example() {
const [selectedDate, setSelectedDate] = useState(new Date());

const today = new Date(new Date().setHours(0, 0, 0, 0));
const yesterday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1);
const nextWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7);

return (
<Calendar
selectedDate={selectedDate}
onPressDate={setSelectedDate}
highlightedDates={[[yesterday, nextWeek]]}
/>
);
}
```

### Hidden controls

Hide the navigation arrows with `hideControls`. This is typically used when `minDate` and `maxDate` are set to the first and last days of the same month.

```jsx
function Example() {
const [selectedDate, setSelectedDate] = useState(new Date());

const today = new Date(new Date().setHours(0, 0, 0, 0));
const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
const lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);

return (
<Calendar
selectedDate={selectedDate}
onPressDate={setSelectedDate}
minDate={firstDayOfMonth}
maxDate={lastDayOfMonth}
hideControls
/>
);
}
```

### Disabled

Disable the entire Calendar with the `disabled` prop.

```jsx
function Example() {
const selectedDate = new Date();

return <Calendar selectedDate={selectedDate} disabled />;
}
```

### Accessibility

Always provide accessibility labels for the navigation controls and error messages for disabled dates.

```jsx
function Example() {
const [selectedDate, setSelectedDate] = useState(new Date());

const today = new Date(new Date().setHours(0, 0, 0, 0));
const nextMonth = new Date(today.getFullYear(), today.getMonth() + 1, today.getDate());

return (
<Calendar
selectedDate={selectedDate}
onPressDate={setSelectedDate}
maxDate={nextMonth}
disabledDateError="Date is not available for selection"
nextArrowAccessibilityLabel="Go to next month"
previousArrowAccessibilityLabel="Go to previous month"
/>
);
}
```
11 changes: 11 additions & 0 deletions apps/docs/docs/components/other/Calendar/_mobilePropsTable.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import ComponentPropsTable from '@site/src/components/page/ComponentPropsTable';

import mobilePropsData from ':docgen/mobile/dates/Calendar/data';
import { sharedParentTypes } from ':docgen/_types/sharedParentTypes';
import { sharedTypeAliases } from ':docgen/_types/sharedTypeAliases';

<ComponentPropsTable
props={mobilePropsData}
sharedTypeAliases={sharedTypeAliases}
sharedParentTypes={sharedParentTypes}
/>
14 changes: 12 additions & 2 deletions apps/docs/docs/components/other/Calendar/index.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
id: calendar
title: Calendar
platform_switcher_options: { web: true, mobile: false }
platform_switcher_options: { web: true, mobile: true }
hide_title: true
---

Expand All @@ -10,16 +10,26 @@ import { ComponentHeader } from '@site/src/components/page/ComponentHeader';
import { ComponentTabsContainer } from '@site/src/components/page/ComponentTabsContainer';

import webPropsToc from ':docgen/web/dates/Calendar/toc-props';
import mobilePropsToc from ':docgen/mobile/dates/Calendar/toc-props';

import WebPropsTable from './_webPropsTable.mdx';
import MobilePropsTable from './_mobilePropsTable.mdx';
import MobileExamples, { toc as mobileExamplesToc } from './_mobileExamples.mdx';
import WebExamples, { toc as webExamplesToc } from './_webExamples.mdx';

import webMetadata from './webMetadata.json';
import mobileMetadata from './mobileMetadata.json';

<VStack gap={5}>
<ComponentHeader title="Calendar" webMetadata={webMetadata} />
<ComponentHeader title="Calendar" webMetadata={webMetadata} mobileMetadata={mobileMetadata} />
<ComponentTabsContainer
webPropsTable={<WebPropsTable />}
webExamples={<WebExamples />}
mobilePropsTable={<MobilePropsTable />}
mobileExamples={<MobileExamples />}
webExamplesToc={webExamplesToc}
mobileExamplesToc={mobileExamplesToc}
webPropsToc={webPropsToc}
mobilePropsToc={mobilePropsToc}
/>
</VStack>
11 changes: 11 additions & 0 deletions apps/docs/docs/components/other/Calendar/mobileMetadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"import": "import { Calendar } from '@coinbase/cds-mobile/dates/Calendar'",
"source": "https://github.com/coinbase/cds/blob/master/packages/mobile/src/dates/Calendar.tsx",
"description": "Calendar is a flexible, accessible date grid component for selecting dates, supporting keyboard navigation, disabled/highlighted dates, and custom rendering.",
"relatedComponents": [
{
"label": "DatePicker",
"url": "/components/other/DatePicker/"
}
]
}
Loading