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