Skip to content

Commit

Permalink
feat(calendar): add base component
Browse files Browse the repository at this point in the history
  • Loading branch information
Lena Rashkovan committed Sep 25, 2024
1 parent 25abe50 commit c700660
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 0 deletions.
134 changes: 134 additions & 0 deletions src/components/experimental/Calendar/Calendar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import React, { ReactElement } from 'react';
import {
Calendar as BaseCalendar,
CalendarProps as BaseCalendarProps,
CalendarCell,
CalendarGrid as BaseCalendarGrid,
CalendarGridHeader,
CalendarGridBody,
CalendarHeaderCell,
Heading as BaseHeading,
DateValue,
Button as BaseButton
} from 'react-aria-components';
import styled from 'styled-components';
import { ChevronLeftIcon, ChevronRightIcon } from '../../../icons';
import { getSemanticValue } from '../../../essentials/experimental';
import { textStyles } from '../Text/Text';
import { get } from '../../../utils/experimental/themeGet';

const Header = styled.header`
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom: ${get('space.3')};
`;

const Button = styled(BaseButton)`
appearance: none;
background: none;
border: none;
display: flex;
cursor: pointer;
margin: 0;
padding: 0;
color: ${getSemanticValue('on-surface')};
outline: 0;
&[data-focused] {
outline: ${getSemanticValue('accent')} solid 0.125rem;
}
&[data-disabled] {
opacity: 0;
}
`;

const Heading = styled(BaseHeading)`
margin: 0;
color: ${getSemanticValue('on-surface')};
${textStyles.variants.title2}
`;

const CalendarGrid = styled(BaseCalendarGrid)`
border-collapse: collapse;
border-spacing: 0;
td {
padding: 0;
}
th {
padding: 0 0 ${get('space.1')};
}
`;

const WeekDay = styled(CalendarHeaderCell)`
color: ${getSemanticValue('on-surface')};
${textStyles.variants.label2}
`;

const Day = styled(CalendarCell)`
display: flex;
align-items: center;
justify-content: center;
color: ${getSemanticValue('on-surface')};
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
${textStyles.variants.label2}
transition: background ease 200ms;
&[data-focused] {
outline: ${getSemanticValue('accent')} solid 0.125rem;
}
&[data-hovered] {
cursor: pointer;
background: ${getSemanticValue('surface-variant')};
}
&[data-selected] {
outline: 0;
background: ${getSemanticValue('interactive-container')};
color: ${getSemanticValue('on-interactive-container')};
}
&[data-disabled] {
opacity: 0.38;
}
&[data-outside-month] {
opacity: 0;
}
`;

type CalendarProps<T extends DateValue> = BaseCalendarProps<T>;

function Calendar<T extends DateValue>(props: CalendarProps<T>): ReactElement {
return (
<BaseCalendar {...props}>
<Header>
<Button slot="previous">
<ChevronLeftIcon size={24} />
</Button>
<Heading />
<Button slot="next">
<ChevronRightIcon size={24} />
</Button>
</Header>
<CalendarGrid weekdayStyle="short">
<CalendarGridHeader>{weekDay => <WeekDay>{weekDay}</WeekDay>}</CalendarGridHeader>
<CalendarGridBody>
{date => (
<Day date={date}>
{({ formattedDate }) => (formattedDate.length > 1 ? formattedDate : `0${formattedDate}`)}
</Day>
)}
</CalendarGridBody>
</CalendarGrid>
</BaseCalendar>
);
}

export { Calendar };
36 changes: 36 additions & 0 deletions src/components/experimental/Calendar/docs/Calendar.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { I18nProvider } from 'react-aria-components';
import { getLocalTimeZone, today } from '@internationalized/date';
import { StoryObj, Meta } from '@storybook/react';
import React from 'react';
import { Calendar } from '../Calendar';

const meta: Meta = {
title: 'Experimental/Components/Calendar',
component: Calendar,
parameters: {
layout: 'centered'
},
decorators: [
Story => (
<I18nProvider locale="de-DE">
<Story />
</I18nProvider>
)
],
args: {
'aria-label': 'Appointment date',
defaultValue: today(getLocalTimeZone())
}
};

export default meta;

type Story = StoryObj<typeof Calendar>;

export const Default: Story = {};

export const WithMinValue: Story = {
args: {
minValue: today(getLocalTimeZone())
}
};
1 change: 1 addition & 0 deletions src/components/experimental/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { Button } from './Button/Button';
export { Calendar } from './Calendar/Calendar';
export { Chip } from './Chip/Chip';
export { Label } from './Label/Label';
export { Text } from './Text/Text';
Expand Down

0 comments on commit c700660

Please sign in to comment.