Skip to content

Commit 415f97a

Browse files
committed
feat: annotations
1 parent aa7dd3e commit 415f97a

File tree

4 files changed

+318
-49
lines changed

4 files changed

+318
-49
lines changed
Lines changed: 98 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,107 @@
11
import { Centering, DateSelect } from '@solved-ac/ui-react'
2-
import { Meta, StoryFn } from '@storybook/react'
2+
import { Meta, StoryObj } from '@storybook/react'
33
import React from 'react'
44

55
export default {
66
title: 'Components/DateSelect',
77
component: DateSelect,
8-
argTypes: {},
8+
argTypes: {
9+
locale: {
10+
control: 'text',
11+
description: 'The locale to use',
12+
},
13+
weekStartsOn: {
14+
defaultValue: 0,
15+
options: [0, 1, 2, 3, 4, 5, 6],
16+
control: {
17+
type: 'select',
18+
},
19+
description: 'The day of the week to start on',
20+
},
21+
chunks: {
22+
defaultValue: 1,
23+
options: [1, 2, 3, 4, 5, 6],
24+
control: {
25+
type: 'select',
26+
},
27+
description: 'The number of months to display at once',
28+
},
29+
annotations: {
30+
control: 'array',
31+
description: 'The annotations to display',
32+
defaultValue: [],
33+
},
34+
},
935
} as Meta<typeof DateSelect>
1036

11-
const Template: StoryFn<typeof DateSelect> = (args) => (
12-
<Centering>
13-
<DateSelect {...args} />
14-
</Centering>
15-
)
37+
type Story = StoryObj<typeof DateSelect>
1638

17-
export const Default = Template.bind({})
39+
export const Default: Story = {
40+
render: (args) => (
41+
<Centering>
42+
<DateSelect {...args} />
43+
</Centering>
44+
),
45+
}
46+
47+
const DAY = 1000 * 60 * 60 * 24
48+
49+
export const Annotations: Story = {
50+
render: (args) => (
51+
<Centering>
52+
<DateSelect {...args} />
53+
</Centering>
54+
),
55+
args: {
56+
annotations: [
57+
{
58+
title: "I'm a title",
59+
color: '#e3f44f',
60+
start: new Date().toISOString().split('T')[0],
61+
end: new Date(Date.now() + DAY * 7).toISOString().split('T')[0],
62+
},
63+
{
64+
title: "I'm a title",
65+
color: '#c1ecff',
66+
start: new Date(Date.now() - DAY * 17).toISOString().split('T')[0],
67+
end: new Date(Date.now() - DAY * 5).toISOString().split('T')[0],
68+
},
69+
{
70+
title: "I'm a title",
71+
color: '#ffd2bd',
72+
start: new Date(Date.now() + DAY * 4).toISOString().split('T')[0],
73+
end: new Date(Date.now() + DAY * 16).toISOString().split('T')[0],
74+
},
75+
{
76+
title: "I'm a title",
77+
color: '#ffc8fb',
78+
start: new Date(Date.now() + DAY * 9).toISOString().split('T')[0],
79+
end: new Date(Date.now() + DAY * 9).toISOString().split('T')[0],
80+
},
81+
{
82+
title: "I'm a title",
83+
color: '#f9ffc1',
84+
start: new Date(Date.now() + DAY * 16).toISOString().split('T')[0],
85+
end: new Date(Date.now() + DAY * 17).toISOString().split('T')[0],
86+
},
87+
{
88+
title: "I'm a title",
89+
color: '#d7ffc0',
90+
start: new Date(Date.now() + DAY * 24).toISOString().split('T')[0],
91+
end: new Date(Date.now() + DAY * 28).toISOString().split('T')[0],
92+
},
93+
{
94+
title: "I'm a title",
95+
color: '#b9b7b4',
96+
start: new Date(Date.now() + DAY * 21).toISOString().split('T')[0],
97+
end: new Date(Date.now() + DAY * 25).toISOString().split('T')[0],
98+
},
99+
{
100+
title: "I'm a title",
101+
color: '#ffcbcb',
102+
start: new Date(Date.now() + DAY * 34).toISOString().split('T')[0],
103+
end: new Date(Date.now() + DAY * 36).toISOString().split('T')[0],
104+
},
105+
],
106+
},
107+
}

src/components/$DateSelect/DateSelect.tsx

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import styled from '@emotion/styled'
12
import React, { ElementType, useState } from 'react'
23
import { PP, PR } from '../../types/PolymorphicElementProps'
34
import { forwardRefWithGenerics } from '../../utils/ref'
@@ -27,8 +28,10 @@ export interface DateSelectAnnotation extends DateRange {
2728

2829
export type DateSelectProps = DateSelectValues & {
2930
annotations?: DateSelectAnnotation[]
31+
maxAnnotationsPerDay?: number
3032
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6
3133
locale?: string
34+
chunks?: number
3235
}
3336

3437
export type DateSelectMode = 'year' | 'month' | 'date'
@@ -41,35 +44,50 @@ export type DateSelectMode = 'year' | 'month' | 'date'
4144
// return new Date(date)
4245
// }
4346

47+
const DateSelectContainer = styled.div`
48+
user-select: none;
49+
display: flex;
50+
gap: 1em;
51+
`
52+
4453
export const DateSelect = forwardRefWithGenerics(
4554
<T extends ElementType>(props: PP<T, DateSelectProps>, ref?: PR<T>) => {
4655
const {
4756
type,
4857
value,
4958
onChange,
5059
annotations = [],
60+
maxAnnotationsPerDay = annotations.length ? 3 : 0,
5161
weekStartsOn = 0,
5262
locale,
63+
chunks = 1,
5364
...rest
5465
} = props
5566
// const theme = useTheme()
5667

57-
// const [currentMode, setCurrentMode] = useState<DateSelectMode>('date')
68+
const [currentMode, setCurrentMode] = useState<DateSelectMode>('date')
5869
const [selectedDate, setSelectedDate] = useState<Date>(new Date())
5970

6071
// const selectedYear = selectedDate.getFullYear()
6172
// const selectedMonth = selectedDate.getMonth()
6273

6374
return (
64-
<div {...rest} ref={ref}>
65-
<DateSelectMonthView
66-
{...props}
67-
selectedDate={selectedDate}
68-
setSelectedDate={setSelectedDate}
69-
firstMonth
70-
lastMonth
71-
/>
72-
</div>
75+
<DateSelectContainer {...rest} ref={ref}>
76+
{currentMode === 'date' &&
77+
new Array(chunks).fill(0).map((_, index) => (
78+
<DateSelectMonthView
79+
{...props}
80+
// eslint-disable-next-line react/no-array-index-key
81+
key={index}
82+
offset={index - Math.floor(chunks / 2)}
83+
selectedDate={selectedDate}
84+
setSelectedDate={setSelectedDate}
85+
setModeToMonth={() => setCurrentMode('month')}
86+
firstMonth={index === 0}
87+
lastMonth={index === chunks - 1}
88+
/>
89+
))}
90+
</DateSelectContainer>
7391
)
7492
}
7593
)

0 commit comments

Comments
 (0)