@fluid-app/portal-sdk 0.1.211 → 0.1.212

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.
Files changed (34) hide show
  1. package/dist/CalendarWidget-CmVC7I4i.cjs +627 -0
  2. package/dist/CalendarWidget-CmVC7I4i.cjs.map +1 -0
  3. package/dist/CalendarWidget-RdPgsQLG.mjs +610 -0
  4. package/dist/CalendarWidget-RdPgsQLG.mjs.map +1 -0
  5. package/dist/{FluidProvider-CfBG1eFt.cjs → FluidProvider-Bt4SKs7T.cjs} +3 -3
  6. package/dist/{FluidProvider-CfBG1eFt.cjs.map → FluidProvider-Bt4SKs7T.cjs.map} +1 -1
  7. package/dist/{FluidProvider-DJfKbTQm.mjs → FluidProvider-jP1UPIfR.mjs} +3 -3
  8. package/dist/{FluidProvider-DJfKbTQm.mjs.map → FluidProvider-jP1UPIfR.mjs.map} +1 -1
  9. package/dist/{MessagingScreen-BUSGkkQM.mjs → MessagingScreen-B0ENhnsm.mjs} +2 -2
  10. package/dist/{MessagingScreen-BUSGkkQM.mjs.map → MessagingScreen-B0ENhnsm.mjs.map} +1 -1
  11. package/dist/{MessagingScreen-4QQbsIUy.cjs → MessagingScreen-CcIu18cI.cjs} +3 -3
  12. package/dist/{MessagingScreen-C6rXYwlm.cjs → MessagingScreen-DcGDKg37.cjs} +2 -2
  13. package/dist/{MessagingScreen-C6rXYwlm.cjs.map → MessagingScreen-DcGDKg37.cjs.map} +1 -1
  14. package/dist/{ProfileScreen-DaDRVK5B.cjs → ProfileScreen-BvPCl8Aw.cjs} +2 -2
  15. package/dist/{ProfileScreen-DaDRVK5B.cjs.map → ProfileScreen-BvPCl8Aw.cjs.map} +1 -1
  16. package/dist/{ProfileScreen-gHoo8LGb.cjs → ProfileScreen-CAUOIsa5.cjs} +3 -3
  17. package/dist/{ProfileScreen-aUcLKi7B.mjs → ProfileScreen-QiVaR0cu.mjs} +2 -2
  18. package/dist/{ProfileScreen-aUcLKi7B.mjs.map → ProfileScreen-QiVaR0cu.mjs.map} +1 -1
  19. package/dist/{ShopScreen-Bdkbl6gq.cjs → ShopScreen-C-jvejyb.cjs} +3 -3
  20. package/dist/{ShopScreen-vC7Yk8vC.cjs → ShopScreen-Dn_XPw2v.cjs} +2 -2
  21. package/dist/{ShopScreen-vC7Yk8vC.cjs.map → ShopScreen-Dn_XPw2v.cjs.map} +1 -1
  22. package/dist/{ShopScreen-jdit46tQ.mjs → ShopScreen-DvlABqGn.mjs} +2 -2
  23. package/dist/{ShopScreen-jdit46tQ.mjs.map → ShopScreen-DvlABqGn.mjs.map} +1 -1
  24. package/dist/index.cjs +11 -11
  25. package/dist/index.d.cts +8 -4
  26. package/dist/index.d.cts.map +1 -1
  27. package/dist/index.d.mts +8 -4
  28. package/dist/index.d.mts.map +1 -1
  29. package/dist/index.mjs +11 -11
  30. package/package.json +15 -15
  31. package/dist/CalendarWidget-BcZNsVQo.cjs +0 -445
  32. package/dist/CalendarWidget-BcZNsVQo.cjs.map +0 -1
  33. package/dist/CalendarWidget-DTqgk0qe.mjs +0 -428
  34. package/dist/CalendarWidget-DTqgk0qe.mjs.map +0 -1
@@ -0,0 +1,627 @@
1
+ const require_chunk = require("./chunk-9hOWP6kD.cjs");
2
+ const require_registry_context = require("./registry-context-RWj2xJlC.cjs");
3
+ const require_error_state = require("./error-state-C-AalLnz.cjs");
4
+ const require_registries = require("./registries-CpUM406S.cjs");
5
+ let react = require("react");
6
+ let _tanstack_react_query = require("@tanstack/react-query");
7
+ let react_jsx_runtime = require("react/jsx-runtime");
8
+ let lucide_react = require("lucide-react");
9
+ //#region ../widgets/src/hooks/use-calendar-events.preview.ts
10
+ const today = /* @__PURE__ */ new Date();
11
+ const inTwoDays = new Date(today);
12
+ inTwoDays.setDate(inTwoDays.getDate() + 2);
13
+ function toISO(date, hours, minutes = 0) {
14
+ const d = new Date(date);
15
+ d.setHours(hours, minutes, 0, 0);
16
+ return d.toISOString();
17
+ }
18
+ function toDateString(date) {
19
+ return date.toISOString().split("T")[0];
20
+ }
21
+ const PREVIEW_DATA = [
22
+ {
23
+ id: 1,
24
+ title: "Team Strategy Call",
25
+ start: toISO(today, 9, 0),
26
+ end: toISO(today, 10, 0),
27
+ status: "active",
28
+ color: "#4f46e5"
29
+ },
30
+ {
31
+ id: 2,
32
+ title: "Product Launch Webinar",
33
+ start: toISO(today, 14, 0),
34
+ end: toISO(today, 15, 30),
35
+ status: "active",
36
+ color: "#0891b2",
37
+ venue: "Zoom"
38
+ },
39
+ {
40
+ id: 3,
41
+ title: "Annual Leadership Summit",
42
+ start: `${toDateString(inTwoDays)}T00:00:00.000Z`,
43
+ end: `${toDateString(inTwoDays)}T23:59:59.000Z`,
44
+ status: "active",
45
+ color: "#059669",
46
+ isAllDay: true,
47
+ venue: "Convention Center"
48
+ }
49
+ ];
50
+ //#endregion
51
+ //#region ../widgets/src/hooks/use-calendar-events.ts
52
+ function useCalendarEvents() {
53
+ const widgetsApi = require_error_state.useWidgetsApi();
54
+ const { isPreview } = require_error_state.useWidgetPreviewContext();
55
+ const { baseUrl } = require_registry_context.useDataSourceRegistryConfig();
56
+ return (0, _tanstack_react_query.useQuery)({
57
+ queryKey: [
58
+ "portal-widget-use",
59
+ "calendar-events",
60
+ isPreview ? "preview" : baseUrl
61
+ ],
62
+ queryFn: ({ signal }) => widgetsApi.fetchCalendarEvents(signal),
63
+ enabled: !isPreview,
64
+ ...isPreview && { placeholderData: PREVIEW_DATA }
65
+ });
66
+ }
67
+ //#endregion
68
+ //#region ../widgets/src/widgets/CalendarWidget.tsx
69
+ var CalendarWidget_exports = /* @__PURE__ */ require_chunk.__exportAll({
70
+ CalendarWidget: () => CalendarWidget,
71
+ calendarWidgetPropertySchema: () => calendarWidgetPropertySchema
72
+ });
73
+ const DAY_NAMES = [
74
+ "Sun",
75
+ "Mon",
76
+ "Tue",
77
+ "Wed",
78
+ "Thu",
79
+ "Fri",
80
+ "Sat"
81
+ ];
82
+ const getDaysInMonth = (year, month) => new Date(year, month + 1, 0).getDate();
83
+ const getFirstDayOfMonth = (year, month) => new Date(year, month, 1).getDay();
84
+ const isSameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
85
+ const startOfDay = (d) => {
86
+ const x = new Date(d);
87
+ x.setHours(0, 0, 0, 0);
88
+ return x;
89
+ };
90
+ const addDays = (d, n) => {
91
+ const x = new Date(d);
92
+ x.setDate(x.getDate() + n);
93
+ return x;
94
+ };
95
+ const diffDays = (a, b) => {
96
+ const ms = startOfDay(a).getTime() - startOfDay(b).getTime();
97
+ return Math.round(ms / 864e5);
98
+ };
99
+ const generateMonthGrid = (year, month) => {
100
+ const daysInMonth = getDaysInMonth(year, month);
101
+ const firstDay = getFirstDayOfMonth(year, month);
102
+ const today = /* @__PURE__ */ new Date();
103
+ const cells = [];
104
+ for (let i = 0; i < firstDay; i++) cells.push({
105
+ date: null,
106
+ isToday: false,
107
+ isCurrentMonth: false
108
+ });
109
+ for (let day = 1; day <= daysInMonth; day++) {
110
+ const date = new Date(year, month, day);
111
+ cells.push({
112
+ date,
113
+ isToday: isSameDay(date, today),
114
+ isCurrentMonth: true
115
+ });
116
+ }
117
+ return cells;
118
+ };
119
+ const generateWeekGrid = () => {
120
+ const today = /* @__PURE__ */ new Date();
121
+ const weekday = today.getDay();
122
+ return Array.from({ length: 7 }, (_, i) => {
123
+ const date = addDays(today, -weekday + i);
124
+ return {
125
+ date,
126
+ isToday: isSameDay(date, today)
127
+ };
128
+ });
129
+ };
130
+ const formatTime = (iso) => new Date(iso).toLocaleTimeString("en-US", {
131
+ hour: "numeric",
132
+ minute: "2-digit"
133
+ });
134
+ const formatContextualDate = (date) => {
135
+ const d = diffDays(date, /* @__PURE__ */ new Date());
136
+ const weekday = date.toLocaleDateString("en-US", { weekday: "short" });
137
+ const monthDay = date.toLocaleDateString("en-US", {
138
+ month: "short",
139
+ day: "numeric"
140
+ });
141
+ if (d === 0) return {
142
+ lead: "Today",
143
+ detail: `${weekday}, ${monthDay}`
144
+ };
145
+ if (d === 1) return {
146
+ lead: "Tomorrow",
147
+ detail: `${weekday}, ${monthDay}`
148
+ };
149
+ if (d === -1) return {
150
+ lead: "Yesterday",
151
+ detail: `${weekday}, ${monthDay}`
152
+ };
153
+ return {
154
+ lead: null,
155
+ detail: `${weekday}, ${monthDay}`
156
+ };
157
+ };
158
+ function DayCellButton({ date, isToday, isSelected, eventCount, accentColor, textColor, showEventDensity, onClick }) {
159
+ const dotCount = showEventDensity ? Math.min(eventCount, 3) : eventCount > 0 ? 1 : 0;
160
+ const baseClasses = "group relative flex aspect-square w-full flex-col items-center justify-center rounded-lg text-sm tabular-nums transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-0";
161
+ const stateClasses = isSelected ? `bg-${accentColor} text-${accentColor}-foreground focus-visible:ring-${accentColor}/40` : isToday ? `bg-${accentColor}/10 text-${accentColor} font-semibold hover:bg-${accentColor}/20 focus-visible:ring-${accentColor}/40` : `text-${textColor} hover:bg-${accentColor}/10 focus-visible:ring-${accentColor}/40`;
162
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
163
+ type: "button",
164
+ onClick,
165
+ "aria-label": date.toLocaleDateString("en-US", {
166
+ weekday: "long",
167
+ month: "long",
168
+ day: "numeric"
169
+ }),
170
+ "aria-current": isToday ? "date" : void 0,
171
+ "aria-pressed": isSelected,
172
+ className: `${baseClasses} ${stateClasses}`,
173
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
174
+ className: "leading-none",
175
+ children: date.getDate()
176
+ }), dotCount > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
177
+ "aria-hidden": "true",
178
+ className: "absolute bottom-1.5 flex items-center gap-[2px]",
179
+ children: Array.from({ length: dotCount }).map((_, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: `size-1 rounded-full ${isSelected ? `bg-${accentColor}-foreground/70` : `bg-${accentColor}`}` }, i))
180
+ })]
181
+ });
182
+ }
183
+ function EventCard({ event, accentColor, textColor }) {
184
+ const accentVar = `var(--color-${accentColor})`;
185
+ const barColor = event.color || accentVar;
186
+ const timeText = event.isAllDay ? "All day" : `${formatTime(event.start)} – ${formatTime(event.end)}`;
187
+ const content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
188
+ "aria-hidden": "true",
189
+ className: "w-[2px] shrink-0 self-stretch rounded-full",
190
+ style: { backgroundColor: barColor }
191
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
192
+ className: "min-w-0 flex-1",
193
+ children: [
194
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
195
+ className: `truncate text-sm font-semibold text-${textColor} leading-tight`,
196
+ children: event.title
197
+ }),
198
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
199
+ className: `mt-1 text-[11px] tabular-nums text-${textColor}/60 font-medium`,
200
+ children: timeText
201
+ }),
202
+ event.venue && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
203
+ className: `mt-1.5 flex items-center gap-1 text-[11px] text-${textColor}/55`,
204
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.MapPin, { className: "size-2.5 shrink-0" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
205
+ className: "truncate",
206
+ children: event.venue
207
+ })]
208
+ })
209
+ ]
210
+ })] });
211
+ const wrapperClasses = `group flex gap-x-2 rounded-md px-2 py-2 transition-colors -mx-2`;
212
+ const interactiveClasses = `hover:bg-${accentColor}/5`;
213
+ if (event.url) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
214
+ href: event.url,
215
+ target: "_blank",
216
+ rel: "noopener noreferrer",
217
+ className: `${wrapperClasses} ${interactiveClasses}`,
218
+ children: content
219
+ });
220
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
221
+ className: wrapperClasses,
222
+ children: content
223
+ });
224
+ }
225
+ function NavButton({ icon: Icon, label, variant, accentColor, textColor, onClick }) {
226
+ const classes = variant === "accent" ? `bg-${accentColor} text-${accentColor}-foreground hover:bg-${accentColor}/90 focus-visible:ring-${accentColor}/40` : `bg-${textColor}/5 text-${textColor} hover:bg-${textColor}/10 focus-visible:ring-${textColor}/20`;
227
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
228
+ type: "button",
229
+ onClick,
230
+ "aria-label": label,
231
+ className: `flex size-8 items-center justify-center rounded-full text-[12px] transition-colors focus:outline-none focus-visible:ring-2 ${classes}`,
232
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { className: "size-4" })
233
+ });
234
+ }
235
+ function CalendarWidget({ titleEnabled = true, titleText = "Calendar", titleFontSize = "xl", titleColor = "foreground", background = {
236
+ type: "solid",
237
+ color: "background"
238
+ }, textColor = "foreground", accentColor = "primary", padding = 4, borderRadius = "md", showEventDensity = true, showTodayButton = true, weekendDim = true, showYearEyebrow = true, className, ...props }) {
239
+ const backgroundColor = background.color || "background";
240
+ const backgroundImage = (background.resource?.image_url || background.resource?.imageUrl) && background.type === "image" ? `url(${background.resource.image_url || background.resource.imageUrl})` : "none";
241
+ const [view, setView] = (0, react.useState)(() => {
242
+ const now = /* @__PURE__ */ new Date();
243
+ return {
244
+ month: now.getMonth(),
245
+ year: now.getFullYear()
246
+ };
247
+ });
248
+ const currentMonth = view.month;
249
+ const currentYear = view.year;
250
+ const [isCollapsed, setIsCollapsed] = (0, react.useState)(false);
251
+ const [selectedDate, setSelectedDate] = (0, react.useState)(() => /* @__PURE__ */ new Date());
252
+ const [gridTransitioning, setGridTransitioning] = (0, react.useState)(false);
253
+ const { data: events = [], isLoading, isError } = useCalendarEvents();
254
+ const monthGrid = (0, react.useMemo)(() => generateMonthGrid(currentYear, currentMonth), [currentYear, currentMonth]);
255
+ const weekGrid = generateWeekGrid();
256
+ const eventsByDate = (0, react.useMemo)(() => {
257
+ const map = /* @__PURE__ */ new Map();
258
+ for (const event of events) {
259
+ const start = startOfDay(new Date(event.start));
260
+ const end = startOfDay(new Date(event.end));
261
+ for (let cur = start; cur <= end; cur = addDays(cur, 1)) {
262
+ const key = `${cur.getFullYear()}-${cur.getMonth()}-${cur.getDate()}`;
263
+ const list = map.get(key);
264
+ if (list) list.push(event);
265
+ else map.set(key, [event]);
266
+ }
267
+ }
268
+ return map;
269
+ }, [events]);
270
+ const lookupEventsForDate = (0, react.useCallback)((date) => {
271
+ const key = `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;
272
+ return eventsByDate.get(key) ?? [];
273
+ }, [eventsByDate]);
274
+ const selectedDateEvents = (0, react.useMemo)(() => {
275
+ if (!selectedDate) return [];
276
+ return lookupEventsForDate(selectedDate);
277
+ }, [selectedDate, lookupEventsForDate]);
278
+ const transitionTimeoutRef = (0, react.useRef)(null);
279
+ (0, react.useEffect)(() => () => {
280
+ if (transitionTimeoutRef.current !== null) window.clearTimeout(transitionTimeoutRef.current);
281
+ }, []);
282
+ const navigate = (0, react.useCallback)((direction) => {
283
+ if (transitionTimeoutRef.current !== null) window.clearTimeout(transitionTimeoutRef.current);
284
+ setGridTransitioning(true);
285
+ transitionTimeoutRef.current = window.setTimeout(() => {
286
+ setView((prev) => {
287
+ const next = prev.month + direction;
288
+ if (next < 0) return {
289
+ month: 11,
290
+ year: prev.year - 1
291
+ };
292
+ if (next > 11) return {
293
+ month: 0,
294
+ year: prev.year + 1
295
+ };
296
+ return {
297
+ month: next,
298
+ year: prev.year
299
+ };
300
+ });
301
+ setGridTransitioning(false);
302
+ transitionTimeoutRef.current = null;
303
+ }, 120);
304
+ }, []);
305
+ const goToToday = (0, react.useCallback)(() => {
306
+ if (transitionTimeoutRef.current !== null) window.clearTimeout(transitionTimeoutRef.current);
307
+ const now = /* @__PURE__ */ new Date();
308
+ setGridTransitioning(true);
309
+ transitionTimeoutRef.current = window.setTimeout(() => {
310
+ setView({
311
+ month: now.getMonth(),
312
+ year: now.getFullYear()
313
+ });
314
+ setSelectedDate(now);
315
+ setGridTransitioning(false);
316
+ transitionTimeoutRef.current = null;
317
+ }, 80);
318
+ }, []);
319
+ const now = /* @__PURE__ */ new Date();
320
+ const viewingCurrentMonth = currentMonth === now.getMonth() && currentYear === now.getFullYear();
321
+ const monthLabel = new Date(currentYear, currentMonth).toLocaleString("en-US", { month: "long" });
322
+ const yearLabel = String(currentYear);
323
+ const contextualDate = selectedDate ? formatContextualDate(selectedDate) : null;
324
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
325
+ className: `@container overflow-hidden rounded-${borderRadius} bg-${backgroundColor} text-${textColor} ${className ?? ""}`,
326
+ style: { backgroundImage },
327
+ ...props,
328
+ children: [titleEnabled && titleText && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
329
+ className: `p-${padding} pb-0`,
330
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
331
+ className: `text-${titleFontSize} text-${titleColor} font-bold tracking-[-0.012em]`,
332
+ children: titleText
333
+ })
334
+ }), isLoading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
335
+ className: `flex min-h-[300px] items-center justify-center p-${padding}`,
336
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
337
+ className: `text-${accentColor}`,
338
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "size-8 animate-spin rounded-full border-2 border-current border-t-transparent" })
339
+ })
340
+ }) : isError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_error_state.ErrorState, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
341
+ className: `p-${padding}`,
342
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
343
+ className: "@md:flex @md:gap-6",
344
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
345
+ className: "@md:flex-none",
346
+ children: [
347
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
348
+ className: "mb-4 flex items-start justify-between gap-3",
349
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
350
+ className: "flex min-w-0 flex-col",
351
+ children: [showYearEyebrow && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
352
+ className: `text-[10px] font-bold tracking-[0.16em] uppercase text-${textColor}/55`,
353
+ children: yearLabel
354
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
355
+ className: `text-xl leading-tight font-bold tracking-[-0.015em] text-${textColor}`,
356
+ children: monthLabel
357
+ })]
358
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
359
+ className: "flex shrink-0 items-center gap-1.5",
360
+ children: [
361
+ showTodayButton && !viewingCurrentMonth && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
362
+ type: "button",
363
+ onClick: goToToday,
364
+ className: `flex items-center gap-1 rounded-full bg-${accentColor}/10 px-2.5 py-1 text-[11px] font-semibold text-${accentColor} transition-colors hover:bg-${accentColor}/20 focus:outline-none focus-visible:ring-2 focus-visible:ring-${accentColor}/40`,
365
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CalendarCheck, { className: "size-3" }), "Today"]
366
+ }),
367
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavButton, {
368
+ icon: lucide_react.ChevronLeft,
369
+ label: "Previous month",
370
+ variant: "ghost",
371
+ accentColor,
372
+ textColor,
373
+ onClick: () => navigate(-1)
374
+ }),
375
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NavButton, {
376
+ icon: lucide_react.ChevronRight,
377
+ label: "Next month",
378
+ variant: "accent",
379
+ accentColor,
380
+ textColor,
381
+ onClick: () => navigate(1)
382
+ })
383
+ ]
384
+ })]
385
+ }),
386
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
387
+ className: "mb-2 grid grid-cols-7 gap-1 text-center",
388
+ children: DAY_NAMES.map((day, idx) => {
389
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
390
+ className: `text-[10px] font-semibold tracking-[0.12em] uppercase text-${textColor}/${weekendDim && (idx === 0 || idx === 6) ? "40" : "55"}`,
391
+ children: day
392
+ }, day);
393
+ })
394
+ }),
395
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
396
+ className: "transition-opacity duration-150 ease-out",
397
+ style: { opacity: gridTransitioning ? .3 : 1 },
398
+ children: [isCollapsed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
399
+ className: "grid grid-cols-7 gap-1 @md:hidden",
400
+ children: weekGrid.map(({ date, isToday }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DayCellButton, {
401
+ date,
402
+ isToday,
403
+ isSelected: !!selectedDate && isSameDay(selectedDate, date),
404
+ eventCount: lookupEventsForDate(date).length,
405
+ accentColor,
406
+ textColor,
407
+ showEventDensity,
408
+ onClick: () => setSelectedDate(date)
409
+ }, date.toISOString()))
410
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
411
+ className: `grid grid-cols-7 gap-1 ${isCollapsed ? "hidden @md:grid" : "grid"}`,
412
+ children: monthGrid.map((cell, idx) => {
413
+ if (!cell.date) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "aspect-square" }, `empty-${idx}`);
414
+ const eventCount = lookupEventsForDate(cell.date).length;
415
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DayCellButton, {
416
+ date: cell.date,
417
+ isToday: cell.isToday,
418
+ isSelected: !!selectedDate && isSameDay(selectedDate, cell.date),
419
+ eventCount,
420
+ accentColor,
421
+ textColor,
422
+ showEventDensity,
423
+ onClick: () => setSelectedDate(cell.date)
424
+ }, cell.date.toISOString());
425
+ })
426
+ })]
427
+ }),
428
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
429
+ type: "button",
430
+ onClick: () => setIsCollapsed(!isCollapsed),
431
+ className: `mt-2 flex w-full items-center justify-center gap-3 rounded-full p-1 text-${textColor}/40 transition-colors hover:text-${textColor}/60 @md:hidden`,
432
+ "aria-label": isCollapsed ? "Expand calendar" : "Collapse calendar",
433
+ children: [
434
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: `h-px w-1/2 bg-${textColor}/20` }),
435
+ isCollapsed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronsDown, { className: "size-3" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronsUp, { className: "size-3" }),
436
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: `h-px w-1/2 bg-${textColor}/20` })
437
+ ]
438
+ })
439
+ ]
440
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
441
+ className: `mt-4 border-${textColor}/10 @md:mt-0 @md:w-56 @md:border-l @md:pl-6`,
442
+ children: [contextualDate && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
443
+ className: "mb-3",
444
+ children: [contextualDate.lead && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
445
+ className: `text-[10px] font-bold tracking-[0.16em] uppercase text-${accentColor}`,
446
+ children: contextualDate.lead
447
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
448
+ className: `text-sm font-semibold text-${textColor} tabular-nums`,
449
+ children: contextualDate.detail
450
+ })]
451
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
452
+ className: "animate-in fade-in slide-in-from-bottom-2 flex flex-col duration-200 ease-out",
453
+ children: selectedDateEvents.length > 0 ? selectedDateEvents.map((event, idx) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EventCard, {
454
+ event,
455
+ accentColor,
456
+ textColor
457
+ }, `${event.id}-${idx}`)) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
458
+ className: `flex flex-col items-start gap-1 rounded-md border border-dashed border-${textColor}/15 px-3 py-3`,
459
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
460
+ className: "flex items-center gap-1.5",
461
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CalendarCheck, { className: `size-3 text-${textColor}/40` }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
462
+ className: `text-[11px] font-semibold text-${textColor}/60`,
463
+ children: "Nothing scheduled"
464
+ })]
465
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
466
+ className: `text-[11px] text-${textColor}/45`,
467
+ children: "Enjoy the breather."
468
+ })]
469
+ })
470
+ }, selectedDate?.toISOString() ?? "none")]
471
+ })]
472
+ })
473
+ })]
474
+ });
475
+ }
476
+ const calendarWidgetPropertySchema = {
477
+ widgetType: "CalendarWidget",
478
+ displayName: "Calendar Widget",
479
+ tabsConfig: [{
480
+ id: "styling",
481
+ label: "Styling"
482
+ }],
483
+ fields: [
484
+ {
485
+ key: "titleEnabled",
486
+ label: "Widget Title",
487
+ type: "boolean",
488
+ description: "Enable the title displayed above the calendar",
489
+ defaultValue: true,
490
+ tab: "styling",
491
+ group: "Title"
492
+ },
493
+ {
494
+ key: "titleText",
495
+ label: "Title",
496
+ type: "text",
497
+ description: "Title text displayed above the calendar",
498
+ defaultValue: "Calendar",
499
+ tab: "styling",
500
+ group: "Title",
501
+ requiresKeyToBeTrue: "titleEnabled"
502
+ },
503
+ require_registries.getFontSizeField({
504
+ key: "titleFontSize",
505
+ label: "Title Font Size",
506
+ description: "Font size for the widget title",
507
+ defaultValue: "xl",
508
+ tab: "styling",
509
+ group: "Title",
510
+ requiresKeyToBeTrue: "titleEnabled"
511
+ }),
512
+ require_registries.getColorField({
513
+ key: "titleColor",
514
+ label: "Title Color",
515
+ description: "Color for the widget title",
516
+ defaultValue: "foreground",
517
+ tab: "styling",
518
+ group: "Title",
519
+ requiresKeyToBeTrue: "titleEnabled"
520
+ }),
521
+ {
522
+ type: "background",
523
+ key: "background",
524
+ label: "Background",
525
+ description: "Background for the calendar container",
526
+ defaultValue: "background",
527
+ tab: "styling",
528
+ group: "Design"
529
+ },
530
+ require_registries.getColorField({
531
+ key: "textColor",
532
+ label: "Text Color",
533
+ description: "Default text color for calendar content",
534
+ defaultValue: "foreground",
535
+ tab: "styling",
536
+ group: "Design"
537
+ }),
538
+ require_registries.getColorField({
539
+ key: "accentColor",
540
+ label: "Accent Color",
541
+ description: "Drives today highlight, event dots, Today pill, and selected day",
542
+ defaultValue: "primary",
543
+ tab: "styling",
544
+ group: "Design"
545
+ }),
546
+ {
547
+ key: "separator",
548
+ type: "separator",
549
+ label: "Separator",
550
+ tab: "styling",
551
+ group: "Design"
552
+ },
553
+ require_registries.getPaddingField({
554
+ key: "padding",
555
+ label: "Padding",
556
+ description: "Padding around the calendar container",
557
+ defaultValue: 4,
558
+ tab: "styling",
559
+ group: "Design"
560
+ }),
561
+ require_registries.getBorderRadiusField({
562
+ key: "borderRadius",
563
+ label: "Border Radius",
564
+ description: "Border radius for the calendar container",
565
+ defaultValue: "md",
566
+ tab: "styling",
567
+ group: "Design"
568
+ }),
569
+ {
570
+ key: "showYearEyebrow",
571
+ label: "Year Eyebrow",
572
+ type: "boolean",
573
+ description: "Small uppercase year label above the month (e.g. '2026 / November').",
574
+ defaultValue: true,
575
+ tab: "styling",
576
+ group: "Polish"
577
+ },
578
+ {
579
+ key: "showTodayButton",
580
+ label: "Today Button",
581
+ type: "boolean",
582
+ description: "Show a 'Today' pill when viewing a different month.",
583
+ defaultValue: true,
584
+ tab: "styling",
585
+ group: "Polish"
586
+ },
587
+ {
588
+ key: "showEventDensity",
589
+ label: "Event Density Dots",
590
+ type: "boolean",
591
+ description: "Show 1–3 dots per day based on event count (off = single dot).",
592
+ defaultValue: true,
593
+ tab: "styling",
594
+ group: "Polish"
595
+ },
596
+ {
597
+ key: "weekendDim",
598
+ label: "Dim Weekends",
599
+ type: "boolean",
600
+ description: "Subtly dim the Sun/Sat day-of-week headers for visual rhythm.",
601
+ defaultValue: true,
602
+ tab: "styling",
603
+ group: "Polish"
604
+ }
605
+ ]
606
+ };
607
+ //#endregion
608
+ Object.defineProperty(exports, "CalendarWidget", {
609
+ enumerable: true,
610
+ get: function() {
611
+ return CalendarWidget;
612
+ }
613
+ });
614
+ Object.defineProperty(exports, "CalendarWidget_exports", {
615
+ enumerable: true,
616
+ get: function() {
617
+ return CalendarWidget_exports;
618
+ }
619
+ });
620
+ Object.defineProperty(exports, "calendarWidgetPropertySchema", {
621
+ enumerable: true,
622
+ get: function() {
623
+ return calendarWidgetPropertySchema;
624
+ }
625
+ });
626
+
627
+ //# sourceMappingURL=CalendarWidget-CmVC7I4i.cjs.map