@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.
@@ -1,24 +1,13 @@
1
1
  // src/components/Calendar/Calendar.tsx
2
2
  import { createContext } from "@radix-ui/react-context";
3
- import { addDays, differenceInWeeks, format, startOfWeek } from "date-fns";
3
+ import { addDays, differenceInWeeks, format, startOfDay, startOfWeek } from "date-fns";
4
4
  import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
5
5
  import { useResizeDetector } from "react-resize-detector";
6
6
  import { List } from "react-virtualized";
7
7
  import { Event } from "@dxos/async";
8
- import { Icon, IconButton, useTranslation } from "@dxos/react-ui";
9
- import { mx } from "@dxos/ui-theme";
10
-
11
- // src/translations.ts
12
- var translationKey = "@dxos/react-ui-calendar";
13
- var translations = [
14
- {
15
- "en-US": {
16
- [translationKey]: {
17
- "today button": "Today"
18
- }
19
- }
20
- }
21
- ];
8
+ import { IconButton, useTranslation } from "@dxos/react-ui";
9
+ import { composable, composableProps, mx } from "@dxos/ui-theme";
10
+ import { translationKey } from "#translations";
22
11
 
23
12
  // src/components/Calendar/util.ts
24
13
  var getDate = (start2, weekNumber, dayOfWeek, weekStartsOn) => {
@@ -61,16 +50,8 @@ var CalendarRoot = /* @__PURE__ */ forwardRef(({ children, weekStartsOn = 1 }, f
61
50
  setSelected
62
51
  }, children);
63
52
  });
64
- var CALENDAR_VIEWPORT_NAME = "CalendarContent";
65
- var CalendarViewport = ({ children, classNames }) => {
66
- return /* @__PURE__ */ React.createElement("div", {
67
- role: "none",
68
- className: mx("flex flex-col items-center overflow-hidden bg-inputSurface", classNames)
69
- }, children);
70
- };
71
- CalendarViewport.displayName = CALENDAR_VIEWPORT_NAME;
72
53
  var CALENDAR_TOOLBAR_NAME = "CalendarHeader";
73
- var CalendarToolbar = ({ classNames }) => {
54
+ var CalendarToolbar = composable(({ classNames, ...props }, forwardedRef) => {
74
55
  const { t } = useTranslation(translationKey);
75
56
  const { weekStartsOn, event, index, selected } = useCalendarContext(CALENDAR_TOOLBAR_NAME);
76
57
  const top = useMemo(() => getDate(start, index ?? 0, 6, weekStartsOn), [
@@ -89,8 +70,14 @@ var CalendarToolbar = ({ classNames }) => {
89
70
  today
90
71
  ]);
91
72
  return /* @__PURE__ */ React.createElement("div", {
92
- role: "none",
93
- className: mx("shink-0 is-full grid grid-cols-3 items-center bg-barSurface", classNames),
73
+ ...composableProps(props, {
74
+ role: "none",
75
+ classNames: [
76
+ "shrink-0 grid! grid-cols-3 items-center bg-toolbar-surface",
77
+ classNames
78
+ ]
79
+ }),
80
+ ref: forwardedRef,
94
81
  style: {
95
82
  width: defaultWidth
96
83
  }
@@ -98,26 +85,31 @@ var CalendarToolbar = ({ classNames }) => {
98
85
  className: "flex justify-start"
99
86
  }, /* @__PURE__ */ React.createElement(IconButton, {
100
87
  variant: "ghost",
101
- size: 5,
102
88
  icon: "ph--calendar--regular",
103
89
  iconOnly: true,
104
90
  classNames: "aspect-square",
105
- label: t("today button"),
91
+ label: t("today.button"),
106
92
  onClick: handleToday
107
93
  })), /* @__PURE__ */ React.createElement("div", {
108
94
  className: "flex justify-center p-2 text-description"
109
95
  }, format(selected ?? top, "MMMM")), /* @__PURE__ */ React.createElement("div", {
110
96
  className: "flex justify-end p-2 text-description"
111
97
  }, (selected ?? top).getFullYear()));
112
- };
98
+ });
113
99
  CalendarToolbar.displayName = CALENDAR_TOOLBAR_NAME;
114
100
  var CALENDAR_GRID_NAME = "CalendarGrid";
115
- var CalendarGrid = ({ classNames, rows, onSelect }) => {
101
+ var CalendarGrid = composable(({ classNames, rows, dates = [], onSelect, ...props }, forwardedRef) => {
116
102
  const { weekStartsOn, event, setIndex, selected, setSelected } = useCalendarContext(CALENDAR_GRID_NAME);
117
103
  const { ref: containerRef, width = 0, height = 0 } = useResizeDetector();
118
104
  const maxHeight = rows ? rows * size : void 0;
119
105
  const listRef = useRef(null);
120
106
  const today = useMemo(() => /* @__PURE__ */ new Date(), []);
107
+ const dateSet = useMemo(() => new Set(dates.map((date) => startOfDay(date).toISOString())), [
108
+ dates
109
+ ]);
110
+ const hasDate = useCallback((date) => dateSet.has(startOfDay(date).toISOString()), [
111
+ dateSet
112
+ ]);
121
113
  const [initialized, setInitialized] = useState(false);
122
114
  useEffect(() => {
123
115
  const index = differenceInWeeks(today, start);
@@ -151,9 +143,6 @@ var CalendarGrid = ({ classNames, rows, onSelect }) => {
151
143
  return format(day, "EEE");
152
144
  });
153
145
  }, []);
154
- const getNumAppointments = useCallback((_date) => {
155
- return 0;
156
- }, []);
157
146
  const handleDaySelect = useCallback((date) => {
158
147
  setSelected((current) => isSameDay(date, current) ? void 0 : date);
159
148
  onSelect?.({
@@ -166,18 +155,15 @@ var CalendarGrid = ({ classNames, rows, onSelect }) => {
166
155
  setIndex(Math.round(info.scrollTop / size));
167
156
  }, []);
168
157
  const rowRenderer = useCallback(({ key, index, style }) => {
169
- const getBgColor = (date) => date.getMonth() % 2 === 0 && "bg-modalSurface";
158
+ const getBgColor = (date) => date.getMonth() % 2 === 0 && "bg-modal-surface";
170
159
  return /* @__PURE__ */ React.createElement("div", {
171
160
  key,
172
161
  role: "none",
173
162
  style,
174
- className: "is-full grid grid-cols-[1fr_max-content_1fr] snap-center"
163
+ className: "grid"
175
164
  }, /* @__PURE__ */ React.createElement("div", {
176
165
  role: "none",
177
- className: mx(getBgColor(getDate(start, index, 0, weekStartsOn)))
178
- }), /* @__PURE__ */ React.createElement("div", {
179
- role: "none",
180
- className: "grid grid-cols-7",
166
+ className: "grid grid-cols-7 bg-input-surface",
181
167
  style: {
182
168
  gridTemplateColumns: `repeat(7, ${size}px)`
183
169
  }
@@ -185,8 +171,7 @@ var CalendarGrid = ({ classNames, rows, onSelect }) => {
185
171
  length: 7
186
172
  }).map((_, i) => {
187
173
  const date = getDate(start, index, i, weekStartsOn);
188
- const num = getNumAppointments(date);
189
- const border = isSameDay(date, selected) ? "border-primary-500" : isSameDay(date, today) ? "border-amber-500" : void 0;
174
+ const border = isSameDay(date, selected) ? "border-primary-500" : isSameDay(date, today) ? "border-amber-500" : hasDate(date) ? "border-neutral-700 border-dashed" : void 0;
190
175
  return /* @__PURE__ */ React.createElement("div", {
191
176
  key: i,
192
177
  role: "none",
@@ -198,30 +183,27 @@ var CalendarGrid = ({ classNames, rows, onSelect }) => {
198
183
  className: "absolute top-0 text-xs text-description"
199
184
  }, format(date, "MMM")), border && /* @__PURE__ */ React.createElement("div", {
200
185
  role: "none",
201
- className: mx("absolute top-0 left-0 is-full bs-full border-2 rounded-full", border)
202
- }), num > 0 && /* @__PURE__ */ React.createElement(Icon, {
203
- classNames: "absolute bottom-0",
204
- icon: num > 3 ? "ph--dots-three--regular" : "ph--dot--regular",
205
- size: 5
186
+ className: mx("absolute inset-1 border-2 rounded-full", border)
206
187
  }));
207
- })), /* @__PURE__ */ React.createElement("div", {
208
- className: mx(getBgColor(getDate(start, index, 6, weekStartsOn)))
209
- }));
188
+ })));
210
189
  }, [
211
190
  handleDaySelect,
212
- getNumAppointments,
191
+ hasDate,
213
192
  selected,
214
193
  weekStartsOn
215
194
  ]);
216
195
  return /* @__PURE__ */ React.createElement("div", {
217
- role: "none",
218
- className: mx("flex flex-col bs-full is-full justify-center overflow-hidden", classNames)
219
- }, /* @__PURE__ */ React.createElement("div", {
220
- role: "none",
221
- className: "flex justify-center bg-groupSurface"
196
+ ...composableProps(props, {
197
+ role: "none",
198
+ classNames: [
199
+ "flex flex-col h-full w-full justify-center overflow-hidden",
200
+ classNames
201
+ ]
202
+ }),
203
+ ref: forwardedRef
222
204
  }, /* @__PURE__ */ React.createElement("div", {
223
205
  role: "none",
224
- className: "flex is-full grid grid-cols-7",
206
+ className: "grid w-full grid-cols-7",
225
207
  style: {
226
208
  width: defaultWidth
227
209
  }
@@ -229,15 +211,14 @@ var CalendarGrid = ({ classNames, rows, onSelect }) => {
229
211
  key: i,
230
212
  role: "none",
231
213
  className: "flex justify-center p-2 text-sm font-thin"
232
- }, date)))), /* @__PURE__ */ React.createElement("div", {
214
+ }, date))), /* @__PURE__ */ React.createElement("div", {
233
215
  role: "none",
234
- className: "flex flex-col bs-full is-full justify-center overflow-hidden",
216
+ className: "flex flex-col h-full w-full justify-center overflow-hidden",
235
217
  ref: containerRef
236
218
  }, /* @__PURE__ */ React.createElement(List, {
237
219
  ref: listRef,
238
220
  role: "none",
239
- // TODO(burdon): Snap isn't working.
240
- className: "[&>div]:snap-y scrollbar-none outline-none",
221
+ className: "scrollbar-none outline-hidden",
241
222
  width,
242
223
  height: maxHeight ?? height,
243
224
  rowCount: maxRows,
@@ -247,11 +228,10 @@ var CalendarGrid = ({ classNames, rows, onSelect }) => {
247
228
  onScroll: handleScroll,
248
229
  onRowsRendered: () => setInitialized(true)
249
230
  })));
250
- };
231
+ });
251
232
  CalendarGrid.displayName = CALENDAR_GRID_NAME;
252
233
  var Calendar = {
253
234
  Root: CalendarRoot,
254
- Viewport: CalendarViewport,
255
235
  Toolbar: CalendarToolbar,
256
236
  Grid: CalendarGrid
257
237
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../src/components/Calendar/Calendar.tsx", "../../../src/translations.ts", "../../../src/components/Calendar/util.ts"],
4
- "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { createContext } from '@radix-ui/react-context';\nimport { type Day, addDays, differenceInWeeks, format, startOfWeek } from 'date-fns';\nimport React, {\n type Dispatch,\n type PropsWithChildren,\n type SetStateAction,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useResizeDetector } from 'react-resize-detector';\nimport { List, type ListProps, type ListRowRenderer } from 'react-virtualized';\n\nimport { Event } from '@dxos/async';\nimport { Icon, IconButton, type ThemedClassName, useTranslation } from '@dxos/react-ui';\nimport { mx } from '@dxos/ui-theme';\n\nimport { translationKey } from '../../translations';\n\nimport { getDate, isSameDay } from './util';\n\nconst maxRows = 50 * 100;\nconst start = new Date('1970-01-01');\nconst size = 48;\nconst defaultWidth = 7 * size;\n\n//\n// Context\n//\n\ntype CalendarEvent = {\n type: 'scroll';\n date: Date;\n};\n\ntype CalendarContextValue = {\n weekStartsOn: Day;\n event: Event<CalendarEvent>;\n index: number | undefined;\n setIndex: Dispatch<SetStateAction<number | undefined>>;\n selected: Date | undefined;\n setSelected: Dispatch<SetStateAction<Date | undefined>>;\n};\n\nconst [CalendarContextProvider, useCalendarContext] = createContext<CalendarContextValue>('Calendar');\n\n//\n// Controller\n//\n\ntype CalendarController = {\n scrollTo: (date: Date) => void;\n};\n\n//\n// Root\n//\n\ntype CalendarRootProps = PropsWithChildren<Partial<Pick<CalendarContextValue, 'weekStartsOn'>>>;\n\nconst CalendarRoot = forwardRef<CalendarController, CalendarRootProps>(\n ({ children, weekStartsOn = 1 }, forwardedRef) => {\n const event = useMemo(() => new Event<CalendarEvent>(), []);\n const [selected, setSelected] = useState<Date | undefined>();\n const [index, setIndex] = useState<number | undefined>();\n\n useImperativeHandle(\n forwardedRef,\n () => ({\n scrollTo: (date: Date) => {\n event.emit({ type: 'scroll', date });\n },\n }),\n [event],\n );\n\n return (\n <CalendarContextProvider\n weekStartsOn={weekStartsOn}\n event={event}\n index={index}\n setIndex={setIndex}\n selected={selected}\n setSelected={setSelected}\n >\n {children}\n </CalendarContextProvider>\n );\n },\n);\n\n//\n// Viewport\n//\n\nconst CALENDAR_VIEWPORT_NAME = 'CalendarContent';\n\ntype CalendarViewportProps = PropsWithChildren<ThemedClassName>;\n\nconst CalendarViewport = ({ children, classNames }: CalendarViewportProps) => {\n return (\n <div role='none' className={mx('flex flex-col items-center overflow-hidden bg-inputSurface', classNames)}>\n {children}\n </div>\n );\n};\n\nCalendarViewport.displayName = CALENDAR_VIEWPORT_NAME;\n\n//\n// Header\n//\n\nconst CALENDAR_TOOLBAR_NAME = 'CalendarHeader';\n\ntype CalendarToolbarProps = ThemedClassName;\n\nconst CalendarToolbar = ({ classNames }: CalendarToolbarProps) => {\n const { t } = useTranslation(translationKey);\n const { weekStartsOn, event, index, selected } = useCalendarContext(CALENDAR_TOOLBAR_NAME);\n const top = useMemo(() => getDate(start, index ?? 0, 6, weekStartsOn), [index, weekStartsOn]);\n const today = useMemo(() => new Date(), []);\n\n const handleToday = useCallback(() => {\n event.emit({ type: 'scroll', date: today });\n }, [event, start, today]);\n\n return (\n <div\n role='none'\n className={mx('shink-0 is-full grid grid-cols-3 items-center bg-barSurface', classNames)}\n style={{ width: defaultWidth }}\n >\n <div className='flex justify-start'>\n <IconButton\n variant='ghost'\n size={5}\n icon='ph--calendar--regular'\n iconOnly\n classNames='aspect-square'\n label={t('today button')}\n onClick={handleToday}\n />\n </div>\n <div className='flex justify-center p-2 text-description'>{format(selected ?? top, 'MMMM')}</div>\n <div className='flex justify-end p-2 text-description'>{(selected ?? top).getFullYear()}</div>\n </div>\n );\n};\n\nCalendarToolbar.displayName = CALENDAR_TOOLBAR_NAME;\n\n//\n// Grid\n// TODO(burdon): Key nav.\n// TODO(burdon): Drag range.\n//\n\nconst CALENDAR_GRID_NAME = 'CalendarGrid';\n\ntype CalendarGridProps = ThemedClassName<{\n rows?: number;\n onSelect?: (event: { date: Date }) => void;\n}>;\n\nconst CalendarGrid = ({ classNames, rows, onSelect }: CalendarGridProps) => {\n const { weekStartsOn, event, setIndex, selected, setSelected } = useCalendarContext(CALENDAR_GRID_NAME);\n const { ref: containerRef, width = 0, height = 0 } = useResizeDetector();\n const maxHeight = rows ? rows * size : undefined;\n const listRef = useRef<List>(null);\n const today = useMemo(() => new Date(), []);\n\n const [initialized, setInitialized] = useState(false);\n useEffect(() => {\n const index = differenceInWeeks(today, start);\n listRef.current?.scrollToRow(index);\n }, [initialized, start, today]);\n\n useEffect(() => {\n return event.on((event) => {\n switch (event.type) {\n case 'scroll': {\n const index = differenceInWeeks(event.date, start);\n listRef.current?.scrollToRow(index);\n break;\n }\n }\n });\n }, [event]);\n\n const days = useMemo(() => {\n const weekStart = startOfWeek(new Date(), { weekStartsOn });\n return Array.from({ length: 7 }, (_, i) => {\n const day = addDays(weekStart, i);\n return format(day, 'EEE'); // Short day name (Mon, Tue, etc.)\n });\n }, []);\n\n // TODO(burdon): Get info by range.\n // TODO(burdon): Border marker for \"all day events?\"\n const getNumAppointments = useCallback((_date: Date) => {\n // return Math.floor(Math.random() * 10);\n return 0;\n }, []);\n\n const handleDaySelect = useCallback(\n (date: Date) => {\n setSelected((current) => (isSameDay(date, current) ? undefined : date));\n onSelect?.({ date });\n },\n [onSelect],\n );\n\n const handleScroll = useCallback<NonNullable<ListProps['onScroll']>>((info) => {\n setIndex(Math.round(info.scrollTop / size));\n }, []);\n\n const rowRenderer = useCallback<ListRowRenderer>(\n ({ key, index, style }) => {\n const getBgColor = (date: Date) => date.getMonth() % 2 === 0 && 'bg-modalSurface';\n return (\n <div key={key} role='none' style={style} className='is-full grid grid-cols-[1fr_max-content_1fr] snap-center'>\n <div role='none' className={mx(getBgColor(getDate(start, index, 0, weekStartsOn)))} />\n <div role='none' className='grid grid-cols-7' style={{ gridTemplateColumns: `repeat(7, ${size}px)` }}>\n {Array.from({ length: 7 }).map((_, i) => {\n const date = getDate(start, index, i, weekStartsOn);\n const num = getNumAppointments(date);\n const border = isSameDay(date, selected)\n ? 'border-primary-500'\n : isSameDay(date, today)\n ? 'border-amber-500'\n : undefined;\n\n return (\n <div\n key={i}\n role='none'\n className={mx('relative flex justify-center items-center cursor-pointer', getBgColor(date))}\n onClick={() => handleDaySelect(date)}\n >\n <span className='text-description'>{date.getDate()}</span>\n {!border && date.getDate() === 1 && (\n <span className='absolute top-0 text-xs text-description'>{format(date, 'MMM')}</span>\n )}\n {border && (\n <div\n role='none'\n className={mx('absolute top-0 left-0 is-full bs-full border-2 rounded-full', border)}\n />\n )}\n {num > 0 && (\n <Icon\n classNames='absolute bottom-0'\n icon={num > 3 ? 'ph--dots-three--regular' : 'ph--dot--regular'}\n size={5}\n />\n )}\n </div>\n );\n })}\n </div>\n <div className={mx(getBgColor(getDate(start, index, 6, weekStartsOn)))} />\n </div>\n );\n },\n [handleDaySelect, getNumAppointments, selected, weekStartsOn],\n );\n\n return (\n <div role='none' className={mx('flex flex-col bs-full is-full justify-center overflow-hidden', classNames)}>\n {/* Day labels */}\n <div role='none' className='flex justify-center bg-groupSurface'>\n <div role='none' className='flex is-full grid grid-cols-7' style={{ width: defaultWidth }}>\n {days.map((date, i) => (\n <div key={i} role='none' className='flex justify-center p-2 text-sm font-thin'>\n {date}\n </div>\n ))}\n </div>\n </div>\n\n {/* Grid */}\n <div role='none' className='flex flex-col bs-full is-full justify-center overflow-hidden' ref={containerRef}>\n <List\n ref={listRef}\n role='none'\n // TODO(burdon): Snap isn't working.\n className='[&>div]:snap-y scrollbar-none outline-none'\n width={width}\n height={maxHeight ?? height}\n rowCount={maxRows}\n rowHeight={size}\n rowRenderer={rowRenderer}\n scrollToAlignment='start'\n onScroll={handleScroll}\n onRowsRendered={() => setInitialized(true)}\n />\n </div>\n </div>\n );\n};\n\nCalendarGrid.displayName = CALENDAR_GRID_NAME;\n\n//\n// Calendar\n//\n\nexport const Calendar = {\n Root: CalendarRoot,\n Viewport: CalendarViewport,\n Toolbar: CalendarToolbar,\n Grid: CalendarGrid,\n};\n\nexport type { CalendarController, CalendarRootProps, CalendarViewportProps, CalendarToolbarProps, CalendarGridProps };\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Resource } from '@dxos/react-ui';\n\nexport const translationKey = '@dxos/react-ui-calendar';\n\nexport const translations = [\n {\n 'en-US': {\n [translationKey]: {\n 'today button': 'Today',\n },\n },\n },\n] as const satisfies Resource[];\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Day } from 'date-fns';\n\nexport const getDate = (start: Date, weekNumber: number, dayOfWeek: number, weekStartsOn: Day): Date => {\n const result = new Date(start);\n const startDayOfWeek = start.getDay(); // 0 = Sunday, 1 = Monday, etc.\n const adjustedStartDay = (startDayOfWeek === 0 ? 7 : startDayOfWeek) - weekStartsOn; // Adjust for weekStartsOn.\n result.setDate(start.getDate() - adjustedStartDay + weekNumber * 7 + dayOfWeek);\n return result;\n};\n\nexport const isSameDay = (date1: Date, date2: Date | undefined): boolean => {\n return (\n !!date2 &&\n date1.getFullYear() === date2.getFullYear() &&\n date1.getMonth() === date2.getMonth() &&\n date1.getDate() === date2.getDate()\n );\n};\n"],
5
- "mappings": "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",
6
- "names": ["createContext", "addDays", "differenceInWeeks", "format", "startOfWeek", "React", "forwardRef", "useCallback", "useEffect", "useImperativeHandle", "useMemo", "useRef", "useState", "useResizeDetector", "List", "Event", "Icon", "IconButton", "useTranslation", "mx", "translationKey", "translations", "getDate", "start", "weekNumber", "dayOfWeek", "weekStartsOn", "result", "Date", "startDayOfWeek", "getDay", "adjustedStartDay", "setDate", "isSameDay", "date1", "date2", "getFullYear", "getMonth", "maxRows", "start", "Date", "size", "defaultWidth", "CalendarContextProvider", "useCalendarContext", "createContext", "CalendarRoot", "forwardRef", "children", "weekStartsOn", "forwardedRef", "event", "useMemo", "Event", "selected", "setSelected", "useState", "index", "setIndex", "useImperativeHandle", "scrollTo", "date", "emit", "type", "CALENDAR_VIEWPORT_NAME", "CalendarViewport", "classNames", "div", "role", "className", "mx", "displayName", "CALENDAR_TOOLBAR_NAME", "CalendarToolbar", "t", "useTranslation", "translationKey", "top", "getDate", "today", "handleToday", "useCallback", "style", "width", "IconButton", "variant", "icon", "iconOnly", "label", "onClick", "format", "getFullYear", "CALENDAR_GRID_NAME", "CalendarGrid", "rows", "onSelect", "ref", "containerRef", "height", "useResizeDetector", "maxHeight", "undefined", "listRef", "useRef", "initialized", "setInitialized", "useEffect", "differenceInWeeks", "current", "scrollToRow", "on", "days", "weekStart", "startOfWeek", "Array", "from", "length", "_", "i", "day", "addDays", "getNumAppointments", "_date", "handleDaySelect", "isSameDay", "handleScroll", "info", "Math", "round", "scrollTop", "rowRenderer", "key", "getBgColor", "getMonth", "gridTemplateColumns", "map", "num", "border", "span", "Icon", "List", "rowCount", "rowHeight", "scrollToAlignment", "onScroll", "onRowsRendered", "Calendar", "Root", "Viewport", "Toolbar", "Grid"]
3
+ "sources": ["../../../src/components/Calendar/Calendar.tsx", "../../../src/components/Calendar/util.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { createContext } from '@radix-ui/react-context';\nimport { type Day, addDays, differenceInWeeks, format, startOfDay, startOfWeek } from 'date-fns';\nimport React, {\n type Dispatch,\n type PropsWithChildren,\n type SetStateAction,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useResizeDetector } from 'react-resize-detector';\nimport { List, type ListProps, type ListRowRenderer } from 'react-virtualized';\n\nimport { Event } from '@dxos/async';\nimport { IconButton, useTranslation } from '@dxos/react-ui';\nimport { composable, composableProps, mx } from '@dxos/ui-theme';\n\nimport { translationKey } from '#translations';\n\nimport { getDate, isSameDay } from './util';\n\nconst maxRows = 50 * 100;\nconst start = new Date('1970-01-01');\nconst size = 48;\nconst defaultWidth = 7 * size;\n\n//\n// Context\n//\n\ntype CalendarEvent = {\n type: 'scroll';\n date: Date;\n};\n\ntype CalendarContextValue = {\n weekStartsOn: Day;\n event: Event<CalendarEvent>;\n index: number | undefined;\n setIndex: Dispatch<SetStateAction<number | undefined>>;\n selected: Date | undefined;\n setSelected: Dispatch<SetStateAction<Date | undefined>>;\n};\n\nconst [CalendarContextProvider, useCalendarContext] = createContext<CalendarContextValue>('Calendar');\n\n//\n// Controller\n//\n\ntype CalendarController = {\n scrollTo: (date: Date) => void;\n};\n\n//\n// Root\n//\n\ntype CalendarRootProps = PropsWithChildren<Partial<Pick<CalendarContextValue, 'weekStartsOn'>>>;\n\nconst CalendarRoot = forwardRef<CalendarController, CalendarRootProps>(\n ({ children, weekStartsOn = 1 }, forwardedRef) => {\n const event = useMemo(() => new Event<CalendarEvent>(), []);\n const [selected, setSelected] = useState<Date | undefined>();\n const [index, setIndex] = useState<number | undefined>();\n\n useImperativeHandle(\n forwardedRef,\n () => ({\n scrollTo: (date: Date) => {\n event.emit({ type: 'scroll', date });\n },\n }),\n [event],\n );\n\n return (\n <CalendarContextProvider\n weekStartsOn={weekStartsOn}\n event={event}\n index={index}\n setIndex={setIndex}\n selected={selected}\n setSelected={setSelected}\n >\n {children}\n </CalendarContextProvider>\n );\n },\n);\n\n//\n// Header\n//\n\nconst CALENDAR_TOOLBAR_NAME = 'CalendarHeader';\n\ntype CalendarToolbarProps = {};\n\nconst CalendarToolbar = composable<HTMLDivElement, CalendarToolbarProps>(({ classNames, ...props }, forwardedRef) => {\n const { t } = useTranslation(translationKey);\n const { weekStartsOn, event, index, selected } = useCalendarContext(CALENDAR_TOOLBAR_NAME);\n const top = useMemo(() => getDate(start, index ?? 0, 6, weekStartsOn), [index, weekStartsOn]);\n const today = useMemo(() => new Date(), []);\n\n const handleToday = useCallback(() => {\n event.emit({ type: 'scroll', date: today });\n }, [event, start, today]);\n\n return (\n <div\n {...composableProps(props, {\n role: 'none',\n classNames: ['shrink-0 grid! grid-cols-3 items-center bg-toolbar-surface', classNames],\n })}\n ref={forwardedRef}\n style={{ width: defaultWidth }}\n >\n <div className='flex justify-start'>\n <IconButton\n variant='ghost'\n icon='ph--calendar--regular'\n iconOnly\n classNames='aspect-square'\n label={t('today.button')}\n onClick={handleToday}\n />\n </div>\n <div className='flex justify-center p-2 text-description'>{format(selected ?? top, 'MMMM')}</div>\n <div className='flex justify-end p-2 text-description'>{(selected ?? top).getFullYear()}</div>\n </div>\n );\n});\n\nCalendarToolbar.displayName = CALENDAR_TOOLBAR_NAME;\n\n//\n// Grid\n// TODO(burdon): Key nav.\n// TODO(burdon): Drag range.\n//\n\nconst CALENDAR_GRID_NAME = 'CalendarGrid';\n\ntype CalendarGridProps = {\n rows?: number;\n /** Dates to highlight on the grid. Each date that appears in this array receives a border indicator. */\n dates?: Date[];\n onSelect?: (event: { date: Date }) => void;\n};\n\nconst CalendarGrid = composable<HTMLDivElement, CalendarGridProps>(\n ({ classNames, rows, dates = [], onSelect, ...props }, forwardedRef) => {\n const { weekStartsOn, event, setIndex, selected, setSelected } = useCalendarContext(CALENDAR_GRID_NAME);\n const { ref: containerRef, width = 0, height = 0 } = useResizeDetector();\n const maxHeight = rows ? rows * size : undefined;\n const listRef = useRef<List>(null);\n const today = useMemo(() => new Date(), []);\n\n // Build a set of ISO date strings (YYYY-MM-DD) for O(1) per-cell lookup.\n const dateSet = useMemo(() => new Set(dates.map((date) => startOfDay(date).toISOString())), [dates]);\n\n const hasDate = useCallback((date: Date) => dateSet.has(startOfDay(date).toISOString()), [dateSet]);\n\n const [initialized, setInitialized] = useState(false);\n useEffect(() => {\n const index = differenceInWeeks(today, start);\n listRef.current?.scrollToRow(index);\n }, [initialized, start, today]);\n\n useEffect(() => {\n return event.on((event) => {\n switch (event.type) {\n case 'scroll': {\n const index = differenceInWeeks(event.date, start);\n listRef.current?.scrollToRow(index);\n break;\n }\n }\n });\n }, [event]);\n\n const days = useMemo(() => {\n const weekStart = startOfWeek(new Date(), { weekStartsOn });\n return Array.from({ length: 7 }, (_, i) => {\n const day = addDays(weekStart, i);\n return format(day, 'EEE'); // Short day name (Mon, Tue, etc.)\n });\n }, []);\n\n // TODO(burdon): Get info by range.\n\n const handleDaySelect = useCallback(\n (date: Date) => {\n setSelected((current) => (isSameDay(date, current) ? undefined : date));\n onSelect?.({ date });\n },\n [onSelect],\n );\n\n const handleScroll = useCallback<NonNullable<ListProps['onScroll']>>((info) => {\n setIndex(Math.round(info.scrollTop / size));\n }, []);\n\n const rowRenderer = useCallback<ListRowRenderer>(\n ({ key, index, style }) => {\n const getBgColor = (date: Date) => date.getMonth() % 2 === 0 && 'bg-modal-surface';\n return (\n <div key={key} role='none' style={style} className='grid'>\n <div\n role='none'\n className='grid grid-cols-7 bg-input-surface'\n style={{ gridTemplateColumns: `repeat(7, ${size}px)` }}\n >\n {Array.from({ length: 7 }).map((_, i) => {\n const date = getDate(start, index, i, weekStartsOn);\n const border = isSameDay(date, selected)\n ? 'border-primary-500'\n : isSameDay(date, today)\n ? 'border-amber-500'\n : hasDate(date)\n ? 'border-neutral-700 border-dashed'\n : undefined;\n\n return (\n <div\n key={i}\n role='none'\n className={mx('relative flex justify-center items-center cursor-pointer', getBgColor(date))}\n onClick={() => handleDaySelect(date)}\n >\n <span className='text-description'>{date.getDate()}</span>\n {!border && date.getDate() === 1 && (\n <span className='absolute top-0 text-xs text-description'>{format(date, 'MMM')}</span>\n )}\n {border && <div role='none' className={mx('absolute inset-1 border-2 rounded-full', border)} />}\n </div>\n );\n })}\n </div>\n </div>\n );\n },\n [handleDaySelect, hasDate, selected, weekStartsOn],\n );\n\n return (\n <div\n {...composableProps(props, {\n role: 'none',\n classNames: ['flex flex-col h-full w-full justify-center overflow-hidden', classNames],\n })}\n ref={forwardedRef}\n >\n {/* Day of week labels */}\n <div role='none' className='grid w-full grid-cols-7' style={{ width: defaultWidth }}>\n {days.map((date, i) => (\n <div key={i} role='none' className='flex justify-center p-2 text-sm font-thin'>\n {date}\n </div>\n ))}\n </div>\n\n {/* Grid */}\n <div role='none' className='flex flex-col h-full w-full justify-center overflow-hidden' ref={containerRef}>\n <List\n ref={listRef}\n role='none'\n className='scrollbar-none outline-hidden'\n width={width}\n height={maxHeight ?? height}\n rowCount={maxRows}\n rowHeight={size}\n rowRenderer={rowRenderer}\n scrollToAlignment='start'\n onScroll={handleScroll}\n onRowsRendered={() => setInitialized(true)}\n />\n </div>\n </div>\n );\n },\n);\n\nCalendarGrid.displayName = CALENDAR_GRID_NAME;\n\n//\n// Calendar\n//\n\nexport const Calendar = {\n Root: CalendarRoot,\n Toolbar: CalendarToolbar,\n Grid: CalendarGrid,\n};\n\nexport type { CalendarController, CalendarRootProps, CalendarToolbarProps, CalendarGridProps };\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Day } from 'date-fns';\n\nexport const getDate = (start: Date, weekNumber: number, dayOfWeek: number, weekStartsOn: Day): Date => {\n const result = new Date(start);\n const startDayOfWeek = start.getDay(); // 0 = Sunday, 1 = Monday, etc.\n const adjustedStartDay = (startDayOfWeek === 0 ? 7 : startDayOfWeek) - weekStartsOn; // Adjust for weekStartsOn.\n result.setDate(start.getDate() - adjustedStartDay + weekNumber * 7 + dayOfWeek);\n return result;\n};\n\nexport const isSameDay = (date1: Date, date2: Date | undefined): boolean => {\n return (\n !!date2 &&\n date1.getFullYear() === date2.getFullYear() &&\n date1.getMonth() === date2.getMonth() &&\n date1.getDate() === date2.getDate()\n );\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["createContext", "addDays", "differenceInWeeks", "format", "startOfDay", "startOfWeek", "React", "forwardRef", "useCallback", "useEffect", "useImperativeHandle", "useMemo", "useRef", "useState", "useResizeDetector", "List", "Event", "IconButton", "useTranslation", "composable", "composableProps", "mx", "translationKey", "getDate", "start", "weekNumber", "dayOfWeek", "weekStartsOn", "result", "Date", "startDayOfWeek", "getDay", "adjustedStartDay", "setDate", "isSameDay", "date1", "date2", "getFullYear", "getMonth", "maxRows", "start", "Date", "size", "defaultWidth", "CalendarContextProvider", "useCalendarContext", "createContext", "CalendarRoot", "forwardRef", "children", "weekStartsOn", "forwardedRef", "event", "useMemo", "Event", "selected", "setSelected", "useState", "index", "setIndex", "useImperativeHandle", "scrollTo", "date", "emit", "type", "CALENDAR_TOOLBAR_NAME", "CalendarToolbar", "composable", "classNames", "props", "t", "useTranslation", "translationKey", "top", "getDate", "today", "handleToday", "useCallback", "div", "composableProps", "role", "ref", "style", "width", "className", "IconButton", "variant", "icon", "iconOnly", "label", "onClick", "format", "getFullYear", "displayName", "CALENDAR_GRID_NAME", "CalendarGrid", "rows", "dates", "onSelect", "containerRef", "height", "useResizeDetector", "maxHeight", "undefined", "listRef", "useRef", "dateSet", "Set", "map", "startOfDay", "toISOString", "hasDate", "has", "initialized", "setInitialized", "useEffect", "differenceInWeeks", "current", "scrollToRow", "on", "days", "weekStart", "startOfWeek", "Array", "from", "length", "_", "i", "day", "addDays", "handleDaySelect", "isSameDay", "handleScroll", "info", "Math", "round", "scrollTop", "rowRenderer", "key", "getBgColor", "getMonth", "gridTemplateColumns", "border", "mx", "span", "List", "rowCount", "rowHeight", "scrollToAlignment", "onScroll", "onRowsRendered", "Calendar", "Root", "Toolbar", "Grid"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"src/translations.ts":{"bytes":1196,"imports":[],"format":"esm"},"src/components/Calendar/util.ts":{"bytes":2802,"imports":[],"format":"esm"},"src/components/Calendar/Calendar.tsx":{"bytes":31567,"imports":[{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"date-fns","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react-resize-detector","kind":"import-statement","external":true},{"path":"react-virtualized","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"src/translations.ts","kind":"import-statement","original":"../../translations"},{"path":"src/components/Calendar/util.ts","kind":"import-statement","original":"./util"}],"format":"esm"},"src/components/Calendar/index.ts":{"bytes":476,"imports":[{"path":"src/components/Calendar/Calendar.tsx","kind":"import-statement","original":"./Calendar"}],"format":"esm"},"src/components/index.ts":{"bytes":467,"imports":[{"path":"src/components/Calendar/index.ts","kind":"import-statement","original":"./Calendar"}],"format":"esm"},"src/index.ts":{"bytes":462,"imports":[{"path":"src/components/index.ts","kind":"import-statement","original":"./components"}],"format":"esm"}},"outputs":{"dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":18836},"dist/lib/browser/index.mjs":{"imports":[{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"date-fns","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react-resize-detector","kind":"import-statement","external":true},{"path":"react-virtualized","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true}],"exports":["Calendar"],"entryPoint":"src/index.ts","inputs":{"src/components/Calendar/Calendar.tsx":{"bytesInOutput":8042},"src/translations.ts":{"bytesInOutput":167},"src/components/Calendar/util.ts":{"bytesInOutput":517},"src/components/Calendar/index.ts":{"bytesInOutput":0},"src/components/index.ts":{"bytesInOutput":0},"src/index.ts":{"bytesInOutput":0}},"bytes":8925}}}
1
+ {"inputs":{"src/components/Calendar/util.ts":{"bytes":2699,"imports":[],"format":"esm"},"src/components/Calendar/Calendar.tsx":{"bytes":29849,"imports":[{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"date-fns","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react-resize-detector","kind":"import-statement","external":true},{"path":"react-virtualized","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"#translations","kind":"import-statement","external":true},{"path":"src/components/Calendar/util.ts","kind":"import-statement","original":"./util"}],"format":"esm"},"src/components/Calendar/index.ts":{"bytes":376,"imports":[{"path":"src/components/Calendar/Calendar.tsx","kind":"import-statement","original":"./Calendar"}],"format":"esm"},"src/components/index.ts":{"bytes":376,"imports":[{"path":"src/components/Calendar/index.ts","kind":"import-statement","original":"./Calendar"}],"format":"esm"},"src/index.ts":{"bytes":382,"imports":[{"path":"src/components/index.ts","kind":"import-statement","original":"./components"}],"format":"esm"},"src/translations.ts":{"bytes":1105,"imports":[],"format":"esm"}},"outputs":{"dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":17699},"dist/lib/browser/index.mjs":{"imports":[{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"date-fns","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react-resize-detector","kind":"import-statement","external":true},{"path":"react-virtualized","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/ui-theme","kind":"import-statement","external":true},{"path":"#translations","kind":"import-statement","external":true}],"exports":["Calendar"],"entryPoint":"src/index.ts","inputs":{"src/components/Calendar/Calendar.tsx":{"bytesInOutput":7434},"src/components/Calendar/util.ts":{"bytesInOutput":517},"src/components/Calendar/index.ts":{"bytesInOutput":0},"src/components/index.ts":{"bytesInOutput":0},"src/index.ts":{"bytesInOutput":0}},"bytes":8126},"dist/lib/browser/translations.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":582},"dist/lib/browser/translations.mjs":{"imports":[],"exports":["translationKey","translations"],"entryPoint":"src/translations.ts","inputs":{"src/translations.ts":{"bytesInOutput":167}},"bytes":277}}}
@@ -0,0 +1,16 @@
1
+ // src/translations.ts
2
+ var translationKey = "@dxos/react-ui-calendar";
3
+ var translations = [
4
+ {
5
+ "en-US": {
6
+ [translationKey]: {
7
+ "today.button": "Today"
8
+ }
9
+ }
10
+ }
11
+ ];
12
+ export {
13
+ translationKey,
14
+ translations
15
+ };
16
+ //# sourceMappingURL=translations.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/translations.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Resource } from '@dxos/react-ui';\n\nexport const translationKey = '@dxos/react-ui-calendar';\n\nexport const translations = [\n {\n 'en-US': {\n [translationKey]: {\n 'today.button': 'Today',\n },\n },\n },\n] as const satisfies Resource[];\n"],
5
+ "mappings": ";AAMO,IAAMA,iBAAiB;AAEvB,IAAMC,eAAe;EAC1B;IACE,SAAS;MACP,CAACD,cAAAA,GAAiB;QAChB,gBAAgB;MAClB;IACF;EACF;;",
6
+ "names": ["translationKey", "translations"]
7
+ }
@@ -2,25 +2,14 @@ import { createRequire } from 'node:module';const require = createRequire(import
2
2
 
3
3
  // src/components/Calendar/Calendar.tsx
4
4
  import { createContext } from "@radix-ui/react-context";
5
- import { addDays, differenceInWeeks, format, startOfWeek } from "date-fns";
5
+ import { addDays, differenceInWeeks, format, startOfDay, startOfWeek } from "date-fns";
6
6
  import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
7
7
  import { useResizeDetector } from "react-resize-detector";
8
8
  import { List } from "react-virtualized";
9
9
  import { Event } from "@dxos/async";
10
- import { Icon, IconButton, useTranslation } from "@dxos/react-ui";
11
- import { mx } from "@dxos/ui-theme";
12
-
13
- // src/translations.ts
14
- var translationKey = "@dxos/react-ui-calendar";
15
- var translations = [
16
- {
17
- "en-US": {
18
- [translationKey]: {
19
- "today button": "Today"
20
- }
21
- }
22
- }
23
- ];
10
+ import { IconButton, useTranslation } from "@dxos/react-ui";
11
+ import { composable, composableProps, mx } from "@dxos/ui-theme";
12
+ import { translationKey } from "#translations";
24
13
 
25
14
  // src/components/Calendar/util.ts
26
15
  var getDate = (start2, weekNumber, dayOfWeek, weekStartsOn) => {
@@ -63,16 +52,8 @@ var CalendarRoot = /* @__PURE__ */ forwardRef(({ children, weekStartsOn = 1 }, f
63
52
  setSelected
64
53
  }, children);
65
54
  });
66
- var CALENDAR_VIEWPORT_NAME = "CalendarContent";
67
- var CalendarViewport = ({ children, classNames }) => {
68
- return /* @__PURE__ */ React.createElement("div", {
69
- role: "none",
70
- className: mx("flex flex-col items-center overflow-hidden bg-inputSurface", classNames)
71
- }, children);
72
- };
73
- CalendarViewport.displayName = CALENDAR_VIEWPORT_NAME;
74
55
  var CALENDAR_TOOLBAR_NAME = "CalendarHeader";
75
- var CalendarToolbar = ({ classNames }) => {
56
+ var CalendarToolbar = composable(({ classNames, ...props }, forwardedRef) => {
76
57
  const { t } = useTranslation(translationKey);
77
58
  const { weekStartsOn, event, index, selected } = useCalendarContext(CALENDAR_TOOLBAR_NAME);
78
59
  const top = useMemo(() => getDate(start, index ?? 0, 6, weekStartsOn), [
@@ -91,8 +72,14 @@ var CalendarToolbar = ({ classNames }) => {
91
72
  today
92
73
  ]);
93
74
  return /* @__PURE__ */ React.createElement("div", {
94
- role: "none",
95
- className: mx("shink-0 is-full grid grid-cols-3 items-center bg-barSurface", classNames),
75
+ ...composableProps(props, {
76
+ role: "none",
77
+ classNames: [
78
+ "shrink-0 grid! grid-cols-3 items-center bg-toolbar-surface",
79
+ classNames
80
+ ]
81
+ }),
82
+ ref: forwardedRef,
96
83
  style: {
97
84
  width: defaultWidth
98
85
  }
@@ -100,26 +87,31 @@ var CalendarToolbar = ({ classNames }) => {
100
87
  className: "flex justify-start"
101
88
  }, /* @__PURE__ */ React.createElement(IconButton, {
102
89
  variant: "ghost",
103
- size: 5,
104
90
  icon: "ph--calendar--regular",
105
91
  iconOnly: true,
106
92
  classNames: "aspect-square",
107
- label: t("today button"),
93
+ label: t("today.button"),
108
94
  onClick: handleToday
109
95
  })), /* @__PURE__ */ React.createElement("div", {
110
96
  className: "flex justify-center p-2 text-description"
111
97
  }, format(selected ?? top, "MMMM")), /* @__PURE__ */ React.createElement("div", {
112
98
  className: "flex justify-end p-2 text-description"
113
99
  }, (selected ?? top).getFullYear()));
114
- };
100
+ });
115
101
  CalendarToolbar.displayName = CALENDAR_TOOLBAR_NAME;
116
102
  var CALENDAR_GRID_NAME = "CalendarGrid";
117
- var CalendarGrid = ({ classNames, rows, onSelect }) => {
103
+ var CalendarGrid = composable(({ classNames, rows, dates = [], onSelect, ...props }, forwardedRef) => {
118
104
  const { weekStartsOn, event, setIndex, selected, setSelected } = useCalendarContext(CALENDAR_GRID_NAME);
119
105
  const { ref: containerRef, width = 0, height = 0 } = useResizeDetector();
120
106
  const maxHeight = rows ? rows * size : void 0;
121
107
  const listRef = useRef(null);
122
108
  const today = useMemo(() => /* @__PURE__ */ new Date(), []);
109
+ const dateSet = useMemo(() => new Set(dates.map((date) => startOfDay(date).toISOString())), [
110
+ dates
111
+ ]);
112
+ const hasDate = useCallback((date) => dateSet.has(startOfDay(date).toISOString()), [
113
+ dateSet
114
+ ]);
123
115
  const [initialized, setInitialized] = useState(false);
124
116
  useEffect(() => {
125
117
  const index = differenceInWeeks(today, start);
@@ -153,9 +145,6 @@ var CalendarGrid = ({ classNames, rows, onSelect }) => {
153
145
  return format(day, "EEE");
154
146
  });
155
147
  }, []);
156
- const getNumAppointments = useCallback((_date) => {
157
- return 0;
158
- }, []);
159
148
  const handleDaySelect = useCallback((date) => {
160
149
  setSelected((current) => isSameDay(date, current) ? void 0 : date);
161
150
  onSelect?.({
@@ -168,18 +157,15 @@ var CalendarGrid = ({ classNames, rows, onSelect }) => {
168
157
  setIndex(Math.round(info.scrollTop / size));
169
158
  }, []);
170
159
  const rowRenderer = useCallback(({ key, index, style }) => {
171
- const getBgColor = (date) => date.getMonth() % 2 === 0 && "bg-modalSurface";
160
+ const getBgColor = (date) => date.getMonth() % 2 === 0 && "bg-modal-surface";
172
161
  return /* @__PURE__ */ React.createElement("div", {
173
162
  key,
174
163
  role: "none",
175
164
  style,
176
- className: "is-full grid grid-cols-[1fr_max-content_1fr] snap-center"
165
+ className: "grid"
177
166
  }, /* @__PURE__ */ React.createElement("div", {
178
167
  role: "none",
179
- className: mx(getBgColor(getDate(start, index, 0, weekStartsOn)))
180
- }), /* @__PURE__ */ React.createElement("div", {
181
- role: "none",
182
- className: "grid grid-cols-7",
168
+ className: "grid grid-cols-7 bg-input-surface",
183
169
  style: {
184
170
  gridTemplateColumns: `repeat(7, ${size}px)`
185
171
  }
@@ -187,8 +173,7 @@ var CalendarGrid = ({ classNames, rows, onSelect }) => {
187
173
  length: 7
188
174
  }).map((_, i) => {
189
175
  const date = getDate(start, index, i, weekStartsOn);
190
- const num = getNumAppointments(date);
191
- const border = isSameDay(date, selected) ? "border-primary-500" : isSameDay(date, today) ? "border-amber-500" : void 0;
176
+ const border = isSameDay(date, selected) ? "border-primary-500" : isSameDay(date, today) ? "border-amber-500" : hasDate(date) ? "border-neutral-700 border-dashed" : void 0;
192
177
  return /* @__PURE__ */ React.createElement("div", {
193
178
  key: i,
194
179
  role: "none",
@@ -200,30 +185,27 @@ var CalendarGrid = ({ classNames, rows, onSelect }) => {
200
185
  className: "absolute top-0 text-xs text-description"
201
186
  }, format(date, "MMM")), border && /* @__PURE__ */ React.createElement("div", {
202
187
  role: "none",
203
- className: mx("absolute top-0 left-0 is-full bs-full border-2 rounded-full", border)
204
- }), num > 0 && /* @__PURE__ */ React.createElement(Icon, {
205
- classNames: "absolute bottom-0",
206
- icon: num > 3 ? "ph--dots-three--regular" : "ph--dot--regular",
207
- size: 5
188
+ className: mx("absolute inset-1 border-2 rounded-full", border)
208
189
  }));
209
- })), /* @__PURE__ */ React.createElement("div", {
210
- className: mx(getBgColor(getDate(start, index, 6, weekStartsOn)))
211
- }));
190
+ })));
212
191
  }, [
213
192
  handleDaySelect,
214
- getNumAppointments,
193
+ hasDate,
215
194
  selected,
216
195
  weekStartsOn
217
196
  ]);
218
197
  return /* @__PURE__ */ React.createElement("div", {
219
- role: "none",
220
- className: mx("flex flex-col bs-full is-full justify-center overflow-hidden", classNames)
221
- }, /* @__PURE__ */ React.createElement("div", {
222
- role: "none",
223
- className: "flex justify-center bg-groupSurface"
198
+ ...composableProps(props, {
199
+ role: "none",
200
+ classNames: [
201
+ "flex flex-col h-full w-full justify-center overflow-hidden",
202
+ classNames
203
+ ]
204
+ }),
205
+ ref: forwardedRef
224
206
  }, /* @__PURE__ */ React.createElement("div", {
225
207
  role: "none",
226
- className: "flex is-full grid grid-cols-7",
208
+ className: "grid w-full grid-cols-7",
227
209
  style: {
228
210
  width: defaultWidth
229
211
  }
@@ -231,15 +213,14 @@ var CalendarGrid = ({ classNames, rows, onSelect }) => {
231
213
  key: i,
232
214
  role: "none",
233
215
  className: "flex justify-center p-2 text-sm font-thin"
234
- }, date)))), /* @__PURE__ */ React.createElement("div", {
216
+ }, date))), /* @__PURE__ */ React.createElement("div", {
235
217
  role: "none",
236
- className: "flex flex-col bs-full is-full justify-center overflow-hidden",
218
+ className: "flex flex-col h-full w-full justify-center overflow-hidden",
237
219
  ref: containerRef
238
220
  }, /* @__PURE__ */ React.createElement(List, {
239
221
  ref: listRef,
240
222
  role: "none",
241
- // TODO(burdon): Snap isn't working.
242
- className: "[&>div]:snap-y scrollbar-none outline-none",
223
+ className: "scrollbar-none outline-hidden",
243
224
  width,
244
225
  height: maxHeight ?? height,
245
226
  rowCount: maxRows,
@@ -249,11 +230,10 @@ var CalendarGrid = ({ classNames, rows, onSelect }) => {
249
230
  onScroll: handleScroll,
250
231
  onRowsRendered: () => setInitialized(true)
251
232
  })));
252
- };
233
+ });
253
234
  CalendarGrid.displayName = CALENDAR_GRID_NAME;
254
235
  var Calendar = {
255
236
  Root: CalendarRoot,
256
- Viewport: CalendarViewport,
257
237
  Toolbar: CalendarToolbar,
258
238
  Grid: CalendarGrid
259
239
  };