@dxos/react-ui-calendar 0.8.4-main.ef1bc66f44 → 0.8.4-main.f466a3d56e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +102 -5
- package/dist/lib/browser/index.mjs +42 -69
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/translations.mjs +16 -0
- package/dist/lib/browser/translations.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +42 -69
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/translations.mjs +18 -0
- package/dist/lib/node-esm/translations.mjs.map +7 -0
- package/dist/types/src/components/Calendar/Calendar.d.ts +12 -18
- package/dist/types/src/components/Calendar/Calendar.d.ts.map +1 -1
- package/dist/types/src/components/Calendar/Calendar.stories.d.ts +4 -9
- package/dist/types/src/components/Calendar/Calendar.stories.d.ts.map +1 -1
- package/dist/types/src/components/Calendar/util.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +1 -1
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +26 -21
- package/src/components/Calendar/Calendar.stories.tsx +15 -40
- package/src/components/Calendar/Calendar.tsx +134 -158
- package/src/translations.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-calendar",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.f466a3d56e",
|
|
4
4
|
"description": "A calendar component.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -8,57 +8,62 @@
|
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "https://github.com/dxos/dxos"
|
|
10
10
|
},
|
|
11
|
-
"license": "
|
|
11
|
+
"license": "FSL-1.1-Apache-2.0",
|
|
12
12
|
"author": "DXOS.org",
|
|
13
13
|
"type": "module",
|
|
14
|
+
"imports": {
|
|
15
|
+
"#translations": "./src/translations.ts"
|
|
16
|
+
},
|
|
14
17
|
"exports": {
|
|
15
18
|
".": {
|
|
16
19
|
"source": "./src/index.ts",
|
|
17
20
|
"types": "./dist/types/src/index.d.ts",
|
|
18
21
|
"browser": "./dist/lib/browser/index.mjs",
|
|
19
22
|
"node": "./dist/lib/node-esm/index.mjs"
|
|
23
|
+
},
|
|
24
|
+
"./translations": {
|
|
25
|
+
"source": "./src/translations.ts",
|
|
26
|
+
"types": "./dist/types/src/translations.d.ts",
|
|
27
|
+
"browser": "./dist/lib/browser/translations.mjs",
|
|
28
|
+
"node": "./dist/lib/node-esm/translations.mjs"
|
|
20
29
|
}
|
|
21
30
|
},
|
|
22
31
|
"types": "dist/types/src/index.d.ts",
|
|
23
|
-
"typesVersions": {
|
|
24
|
-
"*": {}
|
|
25
|
-
},
|
|
26
32
|
"files": [
|
|
27
33
|
"dist",
|
|
28
34
|
"src"
|
|
29
35
|
],
|
|
30
36
|
"dependencies": {
|
|
31
37
|
"@radix-ui/react-context": "1.1.1",
|
|
32
|
-
"date-fns": "^3.
|
|
38
|
+
"date-fns": "^3.6.0",
|
|
33
39
|
"react-resize-detector": "^11.0.1",
|
|
34
40
|
"react-virtualized": "^9.22.6",
|
|
35
41
|
"react-window": "^2.2.3",
|
|
36
|
-
"@dxos/
|
|
37
|
-
"@dxos/
|
|
38
|
-
"@dxos/invariant": "0.8.4-main.
|
|
39
|
-
"@dxos/
|
|
40
|
-
"@dxos/
|
|
42
|
+
"@dxos/async": "0.8.4-main.f466a3d56e",
|
|
43
|
+
"@dxos/debug": "0.8.4-main.f466a3d56e",
|
|
44
|
+
"@dxos/invariant": "0.8.4-main.f466a3d56e",
|
|
45
|
+
"@dxos/log": "0.8.4-main.f466a3d56e",
|
|
46
|
+
"@dxos/util": "0.8.4-main.f466a3d56e"
|
|
41
47
|
},
|
|
42
48
|
"devDependencies": {
|
|
43
49
|
"@types/react": "~19.2.7",
|
|
44
50
|
"@types/react-dom": "~19.2.3",
|
|
45
51
|
"@types/react-virtualized": "^9.22.3",
|
|
46
|
-
"
|
|
47
|
-
"effect": "3.19.16",
|
|
52
|
+
"effect": "3.20.0",
|
|
48
53
|
"react": "~19.2.3",
|
|
49
54
|
"react-dom": "~19.2.3",
|
|
50
|
-
"vite": "
|
|
51
|
-
"@dxos/
|
|
52
|
-
"@dxos/
|
|
53
|
-
"@dxos/
|
|
54
|
-
"@dxos/ui-theme": "0.8.4-main.
|
|
55
|
+
"vite": "^8.0.13",
|
|
56
|
+
"@dxos/random": "0.8.4-main.f466a3d56e",
|
|
57
|
+
"@dxos/react-ui": "0.8.4-main.f466a3d56e",
|
|
58
|
+
"@dxos/storybook-utils": "0.8.4-main.f466a3d56e",
|
|
59
|
+
"@dxos/ui-theme": "0.8.4-main.f466a3d56e"
|
|
55
60
|
},
|
|
56
61
|
"peerDependencies": {
|
|
57
|
-
"effect": "3.
|
|
62
|
+
"effect": "3.20.0",
|
|
58
63
|
"react": "~19.2.3",
|
|
59
64
|
"react-dom": "~19.2.3",
|
|
60
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
61
|
-
"@dxos/ui-theme": "0.8.4-main.
|
|
65
|
+
"@dxos/react-ui": "0.8.4-main.f466a3d56e",
|
|
66
|
+
"@dxos/ui-theme": "0.8.4-main.f466a3d56e"
|
|
62
67
|
},
|
|
63
68
|
"publishConfig": {
|
|
64
69
|
"access": "public"
|
|
@@ -5,18 +5,17 @@
|
|
|
5
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { Panel } from '@dxos/react-ui';
|
|
9
|
+
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
9
10
|
|
|
10
|
-
import { translations } from '
|
|
11
|
+
import { translations } from '#translations';
|
|
11
12
|
|
|
12
13
|
import { Calendar } from './Calendar';
|
|
13
14
|
|
|
14
15
|
const meta = {
|
|
15
16
|
title: 'ui/react-ui-calendar/Calendar',
|
|
16
17
|
component: Calendar.Grid,
|
|
17
|
-
decorators: [withTheme()],
|
|
18
18
|
parameters: {
|
|
19
|
-
layout: 'centered',
|
|
20
19
|
translations,
|
|
21
20
|
},
|
|
22
21
|
} satisfies Meta<typeof Calendar.Grid>;
|
|
@@ -26,51 +25,27 @@ export default meta;
|
|
|
26
25
|
type Story = StoryObj<typeof meta>;
|
|
27
26
|
|
|
28
27
|
export const Default: Story = {
|
|
28
|
+
decorators: [withTheme(), withLayout({ layout: 'centered' })],
|
|
29
29
|
render: () => (
|
|
30
30
|
<Calendar.Root>
|
|
31
|
-
<Calendar.
|
|
32
|
-
|
|
33
|
-
<Calendar.Grid rows={6} />
|
|
34
|
-
</Calendar.Viewport>
|
|
35
|
-
</Calendar.Root>
|
|
36
|
-
),
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export const Border: Story = {
|
|
40
|
-
render: () => (
|
|
41
|
-
<Calendar.Root>
|
|
42
|
-
<Calendar.Viewport classNames='bg-modalSurface border border-separator rounded'>
|
|
43
|
-
<Calendar.Toolbar />
|
|
44
|
-
<Calendar.Grid rows={6} />
|
|
45
|
-
</Calendar.Viewport>
|
|
31
|
+
<Calendar.Toolbar />
|
|
32
|
+
<Calendar.Grid rows={6} />
|
|
46
33
|
</Calendar.Root>
|
|
47
34
|
),
|
|
48
35
|
};
|
|
49
36
|
|
|
50
37
|
export const Column: Story = {
|
|
38
|
+
decorators: [withTheme(), withLayout({ layout: 'column', classNames: 'w-auto' })],
|
|
51
39
|
render: () => (
|
|
52
|
-
<
|
|
53
|
-
<
|
|
54
|
-
<
|
|
40
|
+
<Calendar.Root>
|
|
41
|
+
<Panel.Root>
|
|
42
|
+
<Panel.Toolbar asChild>
|
|
55
43
|
<Calendar.Toolbar />
|
|
44
|
+
</Panel.Toolbar>
|
|
45
|
+
<Panel.Content asChild>
|
|
56
46
|
<Calendar.Grid />
|
|
57
|
-
</
|
|
58
|
-
</
|
|
59
|
-
</
|
|
60
|
-
),
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export const Mobile: Story = {
|
|
64
|
-
render: () => (
|
|
65
|
-
<div className='absolute inset-0 flex bs-full justify-center'>
|
|
66
|
-
<div className='flex bs-full is-[400px] justify-center'>
|
|
67
|
-
<Calendar.Root>
|
|
68
|
-
<Calendar.Viewport classNames='is-full'>
|
|
69
|
-
<Calendar.Toolbar />
|
|
70
|
-
<Calendar.Grid />
|
|
71
|
-
</Calendar.Viewport>
|
|
72
|
-
</Calendar.Root>
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
47
|
+
</Panel.Content>
|
|
48
|
+
</Panel.Root>
|
|
49
|
+
</Calendar.Root>
|
|
75
50
|
),
|
|
76
51
|
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { createContext } from '@radix-ui/react-context';
|
|
6
|
-
import { type Day, addDays, differenceInWeeks, format, startOfWeek } from 'date-fns';
|
|
6
|
+
import { type Day, addDays, differenceInWeeks, format, startOfDay, startOfWeek } from 'date-fns';
|
|
7
7
|
import React, {
|
|
8
8
|
type Dispatch,
|
|
9
9
|
type PropsWithChildren,
|
|
@@ -20,10 +20,10 @@ import { useResizeDetector } from 'react-resize-detector';
|
|
|
20
20
|
import { List, type ListProps, type ListRowRenderer } from 'react-virtualized';
|
|
21
21
|
|
|
22
22
|
import { Event } from '@dxos/async';
|
|
23
|
-
import {
|
|
24
|
-
import { mx } from '@dxos/ui-theme';
|
|
23
|
+
import { IconButton, useTranslation } from '@dxos/react-ui';
|
|
24
|
+
import { composable, composableProps, mx } from '@dxos/ui-theme';
|
|
25
25
|
|
|
26
|
-
import { translationKey } from '
|
|
26
|
+
import { translationKey } from '#translations';
|
|
27
27
|
|
|
28
28
|
import { getDate, isSameDay } from './util';
|
|
29
29
|
|
|
@@ -97,33 +97,15 @@ const CalendarRoot = forwardRef<CalendarController, CalendarRootProps>(
|
|
|
97
97
|
},
|
|
98
98
|
);
|
|
99
99
|
|
|
100
|
-
//
|
|
101
|
-
// Viewport
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
const CALENDAR_VIEWPORT_NAME = 'CalendarContent';
|
|
105
|
-
|
|
106
|
-
type CalendarViewportProps = PropsWithChildren<ThemedClassName>;
|
|
107
|
-
|
|
108
|
-
const CalendarViewport = ({ children, classNames }: CalendarViewportProps) => {
|
|
109
|
-
return (
|
|
110
|
-
<div role='none' className={mx('flex flex-col items-center overflow-hidden bg-inputSurface', classNames)}>
|
|
111
|
-
{children}
|
|
112
|
-
</div>
|
|
113
|
-
);
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
CalendarViewport.displayName = CALENDAR_VIEWPORT_NAME;
|
|
117
|
-
|
|
118
100
|
//
|
|
119
101
|
// Header
|
|
120
102
|
//
|
|
121
103
|
|
|
122
104
|
const CALENDAR_TOOLBAR_NAME = 'CalendarHeader';
|
|
123
105
|
|
|
124
|
-
type CalendarToolbarProps =
|
|
106
|
+
type CalendarToolbarProps = {};
|
|
125
107
|
|
|
126
|
-
const CalendarToolbar = ({ classNames }
|
|
108
|
+
const CalendarToolbar = composable<HTMLDivElement, CalendarToolbarProps>(({ classNames, ...props }, forwardedRef) => {
|
|
127
109
|
const { t } = useTranslation(translationKey);
|
|
128
110
|
const { weekStartsOn, event, index, selected } = useCalendarContext(CALENDAR_TOOLBAR_NAME);
|
|
129
111
|
const top = useMemo(() => getDate(start, index ?? 0, 6, weekStartsOn), [index, weekStartsOn]);
|
|
@@ -135,18 +117,20 @@ const CalendarToolbar = ({ classNames }: CalendarToolbarProps) => {
|
|
|
135
117
|
|
|
136
118
|
return (
|
|
137
119
|
<div
|
|
138
|
-
|
|
139
|
-
|
|
120
|
+
{...composableProps(props, {
|
|
121
|
+
role: 'none',
|
|
122
|
+
classNames: ['shrink-0 grid! grid-cols-3 items-center bg-toolbar-surface', classNames],
|
|
123
|
+
})}
|
|
124
|
+
ref={forwardedRef}
|
|
140
125
|
style={{ width: defaultWidth }}
|
|
141
126
|
>
|
|
142
127
|
<div className='flex justify-start'>
|
|
143
128
|
<IconButton
|
|
144
129
|
variant='ghost'
|
|
145
|
-
size={5}
|
|
146
130
|
icon='ph--calendar--regular'
|
|
147
131
|
iconOnly
|
|
148
132
|
classNames='aspect-square'
|
|
149
|
-
label={t('today
|
|
133
|
+
label={t('today.button')}
|
|
150
134
|
onClick={handleToday}
|
|
151
135
|
/>
|
|
152
136
|
</div>
|
|
@@ -154,7 +138,7 @@ const CalendarToolbar = ({ classNames }: CalendarToolbarProps) => {
|
|
|
154
138
|
<div className='flex justify-end p-2 text-description'>{(selected ?? top).getFullYear()}</div>
|
|
155
139
|
</div>
|
|
156
140
|
);
|
|
157
|
-
};
|
|
141
|
+
});
|
|
158
142
|
|
|
159
143
|
CalendarToolbar.displayName = CALENDAR_TOOLBAR_NAME;
|
|
160
144
|
|
|
@@ -166,147 +150,140 @@ CalendarToolbar.displayName = CALENDAR_TOOLBAR_NAME;
|
|
|
166
150
|
|
|
167
151
|
const CALENDAR_GRID_NAME = 'CalendarGrid';
|
|
168
152
|
|
|
169
|
-
type CalendarGridProps =
|
|
153
|
+
type CalendarGridProps = {
|
|
170
154
|
rows?: number;
|
|
155
|
+
/** Dates to highlight on the grid. Each date that appears in this array receives a border indicator. */
|
|
156
|
+
dates?: Date[];
|
|
171
157
|
onSelect?: (event: { date: Date }) => void;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const CalendarGrid = ({ classNames, rows, onSelect }: CalendarGridProps) => {
|
|
175
|
-
const { weekStartsOn, event, setIndex, selected, setSelected } = useCalendarContext(CALENDAR_GRID_NAME);
|
|
176
|
-
const { ref: containerRef, width = 0, height = 0 } = useResizeDetector();
|
|
177
|
-
const maxHeight = rows ? rows * size : undefined;
|
|
178
|
-
const listRef = useRef<List>(null);
|
|
179
|
-
const today = useMemo(() => new Date(), []);
|
|
158
|
+
};
|
|
180
159
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
160
|
+
const CalendarGrid = composable<HTMLDivElement, CalendarGridProps>(
|
|
161
|
+
({ classNames, rows, dates = [], onSelect, ...props }, forwardedRef) => {
|
|
162
|
+
const { weekStartsOn, event, setIndex, selected, setSelected } = useCalendarContext(CALENDAR_GRID_NAME);
|
|
163
|
+
const { ref: containerRef, width = 0, height = 0 } = useResizeDetector();
|
|
164
|
+
const maxHeight = rows ? rows * size : undefined;
|
|
165
|
+
const listRef = useRef<List>(null);
|
|
166
|
+
const today = useMemo(() => new Date(), []);
|
|
167
|
+
|
|
168
|
+
// Build a set of ISO date strings (YYYY-MM-DD) for O(1) per-cell lookup.
|
|
169
|
+
const dateSet = useMemo(() => new Set(dates.map((date) => startOfDay(date).toISOString())), [dates]);
|
|
170
|
+
|
|
171
|
+
const hasDate = useCallback((date: Date) => dateSet.has(startOfDay(date).toISOString()), [dateSet]);
|
|
172
|
+
|
|
173
|
+
const [initialized, setInitialized] = useState(false);
|
|
174
|
+
useEffect(() => {
|
|
175
|
+
const index = differenceInWeeks(today, start);
|
|
176
|
+
listRef.current?.scrollToRow(index);
|
|
177
|
+
}, [initialized, start, today]);
|
|
178
|
+
|
|
179
|
+
useEffect(() => {
|
|
180
|
+
return event.on((event) => {
|
|
181
|
+
switch (event.type) {
|
|
182
|
+
case 'scroll': {
|
|
183
|
+
const index = differenceInWeeks(event.date, start);
|
|
184
|
+
listRef.current?.scrollToRow(index);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
194
187
|
}
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
(date: Date) => {
|
|
216
|
-
setSelected((current) => (isSameDay(date, current) ? undefined : date));
|
|
217
|
-
onSelect?.({ date });
|
|
218
|
-
},
|
|
219
|
-
[onSelect],
|
|
220
|
-
);
|
|
188
|
+
});
|
|
189
|
+
}, [event]);
|
|
190
|
+
|
|
191
|
+
const days = useMemo(() => {
|
|
192
|
+
const weekStart = startOfWeek(new Date(), { weekStartsOn });
|
|
193
|
+
return Array.from({ length: 7 }, (_, i) => {
|
|
194
|
+
const day = addDays(weekStart, i);
|
|
195
|
+
return format(day, 'EEE'); // Short day name (Mon, Tue, etc.)
|
|
196
|
+
});
|
|
197
|
+
}, []);
|
|
198
|
+
|
|
199
|
+
// TODO(burdon): Get info by range.
|
|
200
|
+
|
|
201
|
+
const handleDaySelect = useCallback(
|
|
202
|
+
(date: Date) => {
|
|
203
|
+
setSelected((current) => (isSameDay(date, current) ? undefined : date));
|
|
204
|
+
onSelect?.({ date });
|
|
205
|
+
},
|
|
206
|
+
[onSelect],
|
|
207
|
+
);
|
|
221
208
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
/>
|
|
258
|
-
)}
|
|
259
|
-
{num > 0 && (
|
|
260
|
-
<Icon
|
|
261
|
-
classNames='absolute bottom-0'
|
|
262
|
-
icon={num > 3 ? 'ph--dots-three--regular' : 'ph--dot--regular'}
|
|
263
|
-
size={5}
|
|
264
|
-
/>
|
|
265
|
-
)}
|
|
266
|
-
</div>
|
|
267
|
-
);
|
|
268
|
-
})}
|
|
209
|
+
const handleScroll = useCallback<NonNullable<ListProps['onScroll']>>((info) => {
|
|
210
|
+
setIndex(Math.round(info.scrollTop / size));
|
|
211
|
+
}, []);
|
|
212
|
+
|
|
213
|
+
const rowRenderer = useCallback<ListRowRenderer>(
|
|
214
|
+
({ key, index, style }) => {
|
|
215
|
+
const getBgColor = (date: Date) => date.getMonth() % 2 === 0 && 'bg-modal-surface';
|
|
216
|
+
return (
|
|
217
|
+
<div key={key} style={style} className='grid'>
|
|
218
|
+
<div className='grid grid-cols-7 bg-input-surface' style={{ gridTemplateColumns: `repeat(7, ${size}px)` }}>
|
|
219
|
+
{Array.from({ length: 7 }).map((_, i) => {
|
|
220
|
+
const date = getDate(start, index, i, weekStartsOn);
|
|
221
|
+
const border = isSameDay(date, selected)
|
|
222
|
+
? 'border-primary-500'
|
|
223
|
+
: isSameDay(date, today)
|
|
224
|
+
? 'border-amber-500'
|
|
225
|
+
: hasDate(date)
|
|
226
|
+
? 'border-neutral-700 border-dashed'
|
|
227
|
+
: undefined;
|
|
228
|
+
|
|
229
|
+
return (
|
|
230
|
+
<div
|
|
231
|
+
key={i}
|
|
232
|
+
className={mx('relative flex justify-center items-center cursor-pointer', getBgColor(date))}
|
|
233
|
+
onClick={() => handleDaySelect(date)}
|
|
234
|
+
>
|
|
235
|
+
<span className='text-description'>{date.getDate()}</span>
|
|
236
|
+
{!border && date.getDate() === 1 && (
|
|
237
|
+
<span className='absolute top-0 text-xs text-description'>{format(date, 'MMM')}</span>
|
|
238
|
+
)}
|
|
239
|
+
{border && <div className={mx('absolute inset-1 border-2 rounded-full', border)} />}
|
|
240
|
+
</div>
|
|
241
|
+
);
|
|
242
|
+
})}
|
|
243
|
+
</div>
|
|
269
244
|
</div>
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
[handleDaySelect, getNumAppointments, selected, weekStartsOn],
|
|
275
|
-
);
|
|
245
|
+
);
|
|
246
|
+
},
|
|
247
|
+
[handleDaySelect, hasDate, selected, weekStartsOn],
|
|
248
|
+
);
|
|
276
249
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
250
|
+
return (
|
|
251
|
+
<div
|
|
252
|
+
{...composableProps(props, {
|
|
253
|
+
role: 'none',
|
|
254
|
+
classNames: ['flex flex-col h-full w-full justify-center overflow-hidden', classNames],
|
|
255
|
+
})}
|
|
256
|
+
ref={forwardedRef}
|
|
257
|
+
>
|
|
258
|
+
{/* Day of week labels */}
|
|
259
|
+
<div className='grid w-full grid-cols-7' style={{ width: defaultWidth }}>
|
|
282
260
|
{days.map((date, i) => (
|
|
283
|
-
<div key={i}
|
|
261
|
+
<div key={i} className='flex justify-center p-2 text-sm font-thin'>
|
|
284
262
|
{date}
|
|
285
263
|
</div>
|
|
286
264
|
))}
|
|
287
265
|
</div>
|
|
288
|
-
</div>
|
|
289
266
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
267
|
+
{/* Grid */}
|
|
268
|
+
<div className='flex flex-col h-full w-full justify-center overflow-hidden' ref={containerRef}>
|
|
269
|
+
<List
|
|
270
|
+
ref={listRef}
|
|
271
|
+
role='none'
|
|
272
|
+
className='scrollbar-none outline-hidden'
|
|
273
|
+
width={width}
|
|
274
|
+
height={maxHeight ?? height}
|
|
275
|
+
rowCount={maxRows}
|
|
276
|
+
rowHeight={size}
|
|
277
|
+
rowRenderer={rowRenderer}
|
|
278
|
+
scrollToAlignment='start'
|
|
279
|
+
onScroll={handleScroll}
|
|
280
|
+
onRowsRendered={() => setInitialized(true)}
|
|
281
|
+
/>
|
|
282
|
+
</div>
|
|
306
283
|
</div>
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
284
|
+
);
|
|
285
|
+
},
|
|
286
|
+
);
|
|
310
287
|
|
|
311
288
|
CalendarGrid.displayName = CALENDAR_GRID_NAME;
|
|
312
289
|
|
|
@@ -316,9 +293,8 @@ CalendarGrid.displayName = CALENDAR_GRID_NAME;
|
|
|
316
293
|
|
|
317
294
|
export const Calendar = {
|
|
318
295
|
Root: CalendarRoot,
|
|
319
|
-
Viewport: CalendarViewport,
|
|
320
296
|
Toolbar: CalendarToolbar,
|
|
321
297
|
Grid: CalendarGrid,
|
|
322
298
|
};
|
|
323
299
|
|
|
324
|
-
export type { CalendarController, CalendarRootProps,
|
|
300
|
+
export type { CalendarController, CalendarRootProps, CalendarToolbarProps, CalendarGridProps };
|