@dxos/react-ui-calendar 0.8.4-main.ef1bc66f44 → 0.8.4-main.fcc0d83b33
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/dist/lib/browser/index.mjs +42 -62
- 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 -62
- 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 +25 -20
- package/src/components/Calendar/Calendar.stories.tsx +15 -40
- package/src/components/Calendar/Calendar.tsx +138 -157
- 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.fcc0d83b33",
|
|
4
4
|
"description": "A calendar component.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -11,54 +11,59 @@
|
|
|
11
11
|
"license": "MIT",
|
|
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/
|
|
39
|
-
"@dxos/
|
|
40
|
-
"@dxos/
|
|
42
|
+
"@dxos/async": "0.8.4-main.fcc0d83b33",
|
|
43
|
+
"@dxos/debug": "0.8.4-main.fcc0d83b33",
|
|
44
|
+
"@dxos/log": "0.8.4-main.fcc0d83b33",
|
|
45
|
+
"@dxos/invariant": "0.8.4-main.fcc0d83b33",
|
|
46
|
+
"@dxos/util": "0.8.4-main.fcc0d83b33"
|
|
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/react-ui": "0.8.4-main.
|
|
52
|
-
"@dxos/
|
|
53
|
-
"@dxos/
|
|
54
|
-
"@dxos/ui-theme": "0.8.4-main.
|
|
55
|
+
"vite": "^8.0.10",
|
|
56
|
+
"@dxos/react-ui": "0.8.4-main.fcc0d83b33",
|
|
57
|
+
"@dxos/random": "0.8.4-main.fcc0d83b33",
|
|
58
|
+
"@dxos/storybook-utils": "0.8.4-main.fcc0d83b33",
|
|
59
|
+
"@dxos/ui-theme": "0.8.4-main.fcc0d83b33"
|
|
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.fcc0d83b33",
|
|
66
|
+
"@dxos/ui-theme": "0.8.4-main.fcc0d83b33"
|
|
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,145 @@ 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
|
-
? 'border-
|
|
240
|
-
:
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
/>
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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} role='none' style={style} className='grid'>
|
|
218
|
+
<div
|
|
219
|
+
role='none'
|
|
220
|
+
className='grid grid-cols-7 bg-input-surface'
|
|
221
|
+
style={{ gridTemplateColumns: `repeat(7, ${size}px)` }}
|
|
222
|
+
>
|
|
223
|
+
{Array.from({ length: 7 }).map((_, i) => {
|
|
224
|
+
const date = getDate(start, index, i, weekStartsOn);
|
|
225
|
+
const border = isSameDay(date, selected)
|
|
226
|
+
? 'border-primary-500'
|
|
227
|
+
: isSameDay(date, today)
|
|
228
|
+
? 'border-amber-500'
|
|
229
|
+
: hasDate(date)
|
|
230
|
+
? 'border-neutral-700 border-dashed'
|
|
231
|
+
: undefined;
|
|
232
|
+
|
|
233
|
+
return (
|
|
234
|
+
<div
|
|
235
|
+
key={i}
|
|
236
|
+
role='none'
|
|
237
|
+
className={mx('relative flex justify-center items-center cursor-pointer', getBgColor(date))}
|
|
238
|
+
onClick={() => handleDaySelect(date)}
|
|
239
|
+
>
|
|
240
|
+
<span className='text-description'>{date.getDate()}</span>
|
|
241
|
+
{!border && date.getDate() === 1 && (
|
|
242
|
+
<span className='absolute top-0 text-xs text-description'>{format(date, 'MMM')}</span>
|
|
243
|
+
)}
|
|
244
|
+
{border && <div role='none' className={mx('absolute inset-1 border-2 rounded-full', border)} />}
|
|
245
|
+
</div>
|
|
246
|
+
);
|
|
247
|
+
})}
|
|
248
|
+
</div>
|
|
269
249
|
</div>
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
[handleDaySelect, getNumAppointments, selected, weekStartsOn],
|
|
275
|
-
);
|
|
250
|
+
);
|
|
251
|
+
},
|
|
252
|
+
[handleDaySelect, hasDate, selected, weekStartsOn],
|
|
253
|
+
);
|
|
276
254
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
255
|
+
return (
|
|
256
|
+
<div
|
|
257
|
+
{...composableProps(props, {
|
|
258
|
+
role: 'none',
|
|
259
|
+
classNames: ['flex flex-col h-full w-full justify-center overflow-hidden', classNames],
|
|
260
|
+
})}
|
|
261
|
+
ref={forwardedRef}
|
|
262
|
+
>
|
|
263
|
+
{/* Day of week labels */}
|
|
264
|
+
<div role='none' className='grid w-full grid-cols-7' style={{ width: defaultWidth }}>
|
|
282
265
|
{days.map((date, i) => (
|
|
283
266
|
<div key={i} role='none' className='flex justify-center p-2 text-sm font-thin'>
|
|
284
267
|
{date}
|
|
285
268
|
</div>
|
|
286
269
|
))}
|
|
287
270
|
</div>
|
|
288
|
-
</div>
|
|
289
271
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
272
|
+
{/* Grid */}
|
|
273
|
+
<div role='none' className='flex flex-col h-full w-full justify-center overflow-hidden' ref={containerRef}>
|
|
274
|
+
<List
|
|
275
|
+
ref={listRef}
|
|
276
|
+
role='none'
|
|
277
|
+
className='scrollbar-none outline-hidden'
|
|
278
|
+
width={width}
|
|
279
|
+
height={maxHeight ?? height}
|
|
280
|
+
rowCount={maxRows}
|
|
281
|
+
rowHeight={size}
|
|
282
|
+
rowRenderer={rowRenderer}
|
|
283
|
+
scrollToAlignment='start'
|
|
284
|
+
onScroll={handleScroll}
|
|
285
|
+
onRowsRendered={() => setInitialized(true)}
|
|
286
|
+
/>
|
|
287
|
+
</div>
|
|
306
288
|
</div>
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
289
|
+
);
|
|
290
|
+
},
|
|
291
|
+
);
|
|
310
292
|
|
|
311
293
|
CalendarGrid.displayName = CALENDAR_GRID_NAME;
|
|
312
294
|
|
|
@@ -316,9 +298,8 @@ CalendarGrid.displayName = CALENDAR_GRID_NAME;
|
|
|
316
298
|
|
|
317
299
|
export const Calendar = {
|
|
318
300
|
Root: CalendarRoot,
|
|
319
|
-
Viewport: CalendarViewport,
|
|
320
301
|
Toolbar: CalendarToolbar,
|
|
321
302
|
Grid: CalendarGrid,
|
|
322
303
|
};
|
|
323
304
|
|
|
324
|
-
export type { CalendarController, CalendarRootProps,
|
|
305
|
+
export type { CalendarController, CalendarRootProps, CalendarToolbarProps, CalendarGridProps };
|