@classytic/fluid 0.2.1 → 0.3.2

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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +149 -62
  3. package/dist/api-pagination-CJ0vR_w6.d.mts +34 -0
  4. package/dist/api-pagination-DBTE0yk4.mjs +190 -0
  5. package/dist/chunk-DQk6qfdC.mjs +18 -0
  6. package/dist/client/calendar.d.mts +105 -0
  7. package/dist/client/calendar.mjs +202 -0
  8. package/dist/client/core.d.mts +1614 -0
  9. package/dist/client/core.mjs +2779 -0
  10. package/dist/client/error.d.mts +125 -0
  11. package/dist/client/error.mjs +166 -0
  12. package/dist/client/hooks.d.mts +162 -0
  13. package/dist/client/hooks.mjs +447 -0
  14. package/dist/client/table.d.mts +84 -0
  15. package/dist/client/table.mjs +373 -0
  16. package/dist/client/theme.d.mts +6 -0
  17. package/dist/client/theme.mjs +65 -0
  18. package/dist/command.d.mts +134 -0
  19. package/dist/command.mjs +132 -0
  20. package/dist/compact.d.mts +359 -0
  21. package/dist/compact.mjs +892 -0
  22. package/dist/dashboard.d.mts +778 -0
  23. package/dist/dashboard.mjs +1617 -0
  24. package/dist/filter-utils-DqMmy_v-.mjs +72 -0
  25. package/dist/filter-utils-IZ0GtuPo.d.mts +40 -0
  26. package/dist/forms.d.mts +1549 -0
  27. package/dist/forms.mjs +3740 -0
  28. package/dist/index.d.mts +296 -0
  29. package/dist/index.mjs +432 -0
  30. package/dist/layouts.d.mts +215 -0
  31. package/dist/layouts.mjs +460 -0
  32. package/dist/search-context-DR7DBs7S.mjs +19 -0
  33. package/dist/search.d.mts +254 -0
  34. package/dist/search.mjs +523 -0
  35. package/dist/sheet-wrapper-CWNCvYMD.mjs +211 -0
  36. package/dist/use-base-search-BGgWnWaF.d.mts +35 -0
  37. package/dist/use-debounce-xmZucz5e.mjs +53 -0
  38. package/dist/use-keyboard-shortcut-Bl6YM5Q7.mjs +82 -0
  39. package/dist/use-keyboard-shortcut-_mRCh3QO.d.mts +24 -0
  40. package/dist/use-media-query-BnVNIKT4.mjs +17 -0
  41. package/dist/use-mobile-BX3SQVo2.mjs +20 -0
  42. package/dist/use-scroll-detection-CsgsQYvy.mjs +43 -0
  43. package/dist/utils-CDue7cEt.d.mts +6 -0
  44. package/dist/utils-DQ5SCVoW.mjs +10 -0
  45. package/package.json +85 -45
  46. package/styles.css +2 -2
  47. package/dist/chunk-GUHK2DTW.js +0 -15
  48. package/dist/chunk-GUHK2DTW.js.map +0 -1
  49. package/dist/chunk-H3NFL3GJ.js +0 -57
  50. package/dist/chunk-H3NFL3GJ.js.map +0 -1
  51. package/dist/chunk-J2YRTQE4.js +0 -293
  52. package/dist/chunk-J2YRTQE4.js.map +0 -1
  53. package/dist/compact.d.ts +0 -217
  54. package/dist/compact.js +0 -986
  55. package/dist/compact.js.map +0 -1
  56. package/dist/dashboard.d.ts +0 -386
  57. package/dist/dashboard.js +0 -1032
  58. package/dist/dashboard.js.map +0 -1
  59. package/dist/index.d.ts +0 -2141
  60. package/dist/index.js +0 -6460
  61. package/dist/index.js.map +0 -1
  62. package/dist/layout.d.ts +0 -25
  63. package/dist/layout.js +0 -4
  64. package/dist/layout.js.map +0 -1
  65. package/dist/search.d.ts +0 -172
  66. package/dist/search.js +0 -341
  67. package/dist/search.js.map +0 -1
  68. package/dist/use-base-search-AS5Z3SAy.d.ts +0 -64
  69. package/dist/utils-Cbsgs0XP.d.ts +0 -5
@@ -0,0 +1,202 @@
1
+ "use client";
2
+
3
+ import { t as cn } from "../utils-DQ5SCVoW.mjs";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import { useCallback, useMemo, useState } from "react";
6
+ import { ChevronLeft, ChevronRight } from "lucide-react";
7
+ import { Button } from "@/components/ui/button";
8
+ import { addMonths, eachDayOfInterval, endOfMonth, format, getDay, isSameDay, isSameMonth, startOfMonth, subMonths } from "date-fns";
9
+
10
+ //#region src/components/event-calendar.tsx
11
+ const WEEKDAYS = [
12
+ "Sun",
13
+ "Mon",
14
+ "Tue",
15
+ "Wed",
16
+ "Thu",
17
+ "Fri",
18
+ "Sat"
19
+ ];
20
+ /**
21
+ * EventCalendar - A reusable calendar component for displaying events
22
+ *
23
+ * Can be used for attendance tracking, scheduling, etc.
24
+ */
25
+ function EventCalendar({ events = [], selectedDate: controlledSelectedDate, onDateSelect, onMonthChange, initialMonth = /* @__PURE__ */ new Date(), renderDayContent, renderEventIndicators, getEventsForDate, className, headerLeft, headerRight, minCellHeight = "5rem", showWeekNumbers = false, isLoading = false }) {
26
+ const [currentMonth, setCurrentMonth] = useState(initialMonth);
27
+ const [internalSelectedDate, setInternalSelectedDate] = useState(null);
28
+ const selectedDate = controlledSelectedDate ?? internalSelectedDate;
29
+ const { days, paddingDaysBefore, paddingDaysAfter } = useMemo(() => {
30
+ const monthStart = startOfMonth(currentMonth);
31
+ const daysInMonth = eachDayOfInterval({
32
+ start: monthStart,
33
+ end: endOfMonth(currentMonth)
34
+ });
35
+ const startDayOfWeek = getDay(monthStart);
36
+ return {
37
+ days: daysInMonth,
38
+ paddingDaysBefore: startDayOfWeek,
39
+ paddingDaysAfter: 42 - (startDayOfWeek + daysInMonth.length)
40
+ };
41
+ }, [currentMonth]);
42
+ const defaultGetEventsForDate = useCallback((date, allEvents) => {
43
+ return allEvents.filter((event) => {
44
+ return isSameDay(typeof event.date === "string" ? new Date(event.date) : event.date, date);
45
+ });
46
+ }, []);
47
+ const getEvents = getEventsForDate || defaultGetEventsForDate;
48
+ const handlePrevMonth = useCallback(() => {
49
+ const newMonth = subMonths(currentMonth, 1);
50
+ setCurrentMonth(newMonth);
51
+ onMonthChange?.(newMonth);
52
+ }, [currentMonth, onMonthChange]);
53
+ const handleNextMonth = useCallback(() => {
54
+ const newMonth = addMonths(currentMonth, 1);
55
+ setCurrentMonth(newMonth);
56
+ onMonthChange?.(newMonth);
57
+ }, [currentMonth, onMonthChange]);
58
+ const handleDateClick = useCallback((date) => {
59
+ const dayEvents = getEvents(date, events);
60
+ setInternalSelectedDate(date);
61
+ onDateSelect?.(date, dayEvents);
62
+ }, [
63
+ events,
64
+ getEvents,
65
+ onDateSelect
66
+ ]);
67
+ const defaultRenderEventIndicators = useCallback((dayEvents) => {
68
+ if (dayEvents.length === 0) return null;
69
+ return /* @__PURE__ */ jsxs("div", {
70
+ className: "flex gap-0.5 mt-1",
71
+ children: [dayEvents.slice(0, 3).map((_, idx) => /* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 rounded-full bg-primary" }, idx)), dayEvents.length > 3 && /* @__PURE__ */ jsxs("span", {
72
+ className: "text-[10px] text-muted-foreground ml-0.5",
73
+ children: ["+", dayEvents.length - 3]
74
+ })]
75
+ });
76
+ }, []);
77
+ const renderIndicators = renderEventIndicators || defaultRenderEventIndicators;
78
+ return /* @__PURE__ */ jsxs("div", {
79
+ className: cn("space-y-4", className),
80
+ children: [/* @__PURE__ */ jsxs("div", {
81
+ className: "flex items-center justify-between",
82
+ children: [/* @__PURE__ */ jsxs("div", {
83
+ className: "flex items-center gap-4",
84
+ children: [headerLeft, /* @__PURE__ */ jsx("h2", {
85
+ className: "text-lg font-semibold",
86
+ children: format(currentMonth, "MMMM yyyy")
87
+ })]
88
+ }), /* @__PURE__ */ jsxs("div", {
89
+ className: "flex items-center gap-2",
90
+ children: [headerRight, /* @__PURE__ */ jsxs("div", {
91
+ className: "flex gap-1",
92
+ children: [/* @__PURE__ */ jsx(Button, {
93
+ variant: "outline",
94
+ size: "icon",
95
+ onClick: handlePrevMonth,
96
+ disabled: isLoading,
97
+ children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
98
+ }), /* @__PURE__ */ jsx(Button, {
99
+ variant: "outline",
100
+ size: "icon",
101
+ onClick: handleNextMonth,
102
+ disabled: isLoading,
103
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
104
+ })]
105
+ })]
106
+ })]
107
+ }), /* @__PURE__ */ jsxs("div", {
108
+ className: "rounded-lg border overflow-hidden",
109
+ children: [/* @__PURE__ */ jsxs("div", {
110
+ className: cn("grid bg-muted/50", showWeekNumbers ? "grid-cols-8" : "grid-cols-7"),
111
+ children: [showWeekNumbers && /* @__PURE__ */ jsx("div", {
112
+ className: "px-2 py-3 text-center text-xs font-medium text-muted-foreground border-r",
113
+ children: "Wk"
114
+ }), WEEKDAYS.map((day) => /* @__PURE__ */ jsx("div", {
115
+ className: "px-2 py-3 text-center text-xs font-medium text-muted-foreground",
116
+ children: day
117
+ }, day))]
118
+ }), /* @__PURE__ */ jsxs("div", {
119
+ className: cn("grid gap-px bg-border", showWeekNumbers ? "grid-cols-8" : "grid-cols-7"),
120
+ children: [
121
+ Array.from({ length: paddingDaysBefore }).map((_, index) => /* @__PURE__ */ jsx("div", {
122
+ className: "bg-card",
123
+ style: { minHeight: minCellHeight }
124
+ }, `padding-start-${index}`)),
125
+ days.map((day) => {
126
+ const dayEvents = getEvents(day, events);
127
+ const isToday = isSameDay(day, /* @__PURE__ */ new Date());
128
+ const isSelected = selectedDate ? isSameDay(day, selectedDate) : false;
129
+ const isCurrentMonth = isSameMonth(day, currentMonth);
130
+ return /* @__PURE__ */ jsx("div", {
131
+ className: cn("bg-card p-2 cursor-pointer transition-colors hover:bg-muted/50", isSelected && "ring-2 ring-primary ring-inset bg-primary/5", !isCurrentMonth && "opacity-50", isLoading && "pointer-events-none opacity-50"),
132
+ style: { minHeight: minCellHeight },
133
+ onClick: () => handleDateClick(day),
134
+ children: renderDayContent ? renderDayContent(day, dayEvents, isSelected) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
135
+ className: cn("flex h-7 w-7 items-center justify-center rounded-full text-sm", isToday && "bg-primary text-primary-foreground font-semibold"),
136
+ children: format(day, "d")
137
+ }), renderIndicators(dayEvents)] })
138
+ }, day.toISOString());
139
+ }),
140
+ Array.from({ length: paddingDaysAfter }).map((_, index) => /* @__PURE__ */ jsx("div", {
141
+ className: "bg-card",
142
+ style: { minHeight: minCellHeight }
143
+ }, `padding-end-${index}`))
144
+ ]
145
+ })]
146
+ })]
147
+ });
148
+ }
149
+ function CalendarDayDetail({ date, title, emptyMessage = "Click on a day to see details", children, className }) {
150
+ return /* @__PURE__ */ jsxs("div", {
151
+ className: cn("rounded-lg border bg-card", className),
152
+ children: [/* @__PURE__ */ jsx("div", {
153
+ className: "p-4 border-b",
154
+ children: /* @__PURE__ */ jsx("h3", {
155
+ className: "font-semibold",
156
+ children: date ? format(date, "EEEE, MMMM d") : title || "Select a day"
157
+ })
158
+ }), /* @__PURE__ */ jsx("div", {
159
+ className: "p-4",
160
+ children: !date ? /* @__PURE__ */ jsx("p", {
161
+ className: "text-sm text-muted-foreground",
162
+ children: emptyMessage
163
+ }) : children
164
+ })]
165
+ });
166
+ }
167
+ function CalendarWithDetail({ renderDetail, detailTitle, detailEmptyMessage, layout = "horizontal", detailPosition = "right", onDateSelect, ...calendarProps }) {
168
+ const [selectedDate, setSelectedDate] = useState(null);
169
+ const [selectedEvents, setSelectedEvents] = useState([]);
170
+ const handleDateSelect = useCallback((date, events) => {
171
+ setSelectedDate(date);
172
+ setSelectedEvents(events);
173
+ onDateSelect?.(date, events);
174
+ }, [onDateSelect]);
175
+ const isHorizontal = layout === "horizontal";
176
+ const detailFirst = detailPosition === "left" || detailPosition === "top";
177
+ const calendarElement = /* @__PURE__ */ jsx(EventCalendar, {
178
+ ...calendarProps,
179
+ selectedDate,
180
+ onDateSelect: handleDateSelect
181
+ });
182
+ const detailElement = /* @__PURE__ */ jsx(CalendarDayDetail, {
183
+ date: selectedDate,
184
+ title: detailTitle,
185
+ emptyMessage: detailEmptyMessage,
186
+ className: isHorizontal ? "min-w-[300px]" : "",
187
+ children: selectedDate && renderDetail?.(selectedDate, selectedEvents)
188
+ });
189
+ return /* @__PURE__ */ jsx("div", {
190
+ className: cn("gap-4", isHorizontal ? "flex" : "flex flex-col", isHorizontal && "items-start"),
191
+ children: detailFirst ? /* @__PURE__ */ jsxs(Fragment, { children: [detailElement, /* @__PURE__ */ jsx("div", {
192
+ className: "flex-1",
193
+ children: calendarElement
194
+ })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
195
+ className: isHorizontal ? "flex-1" : "",
196
+ children: calendarElement
197
+ }), detailElement] })
198
+ });
199
+ }
200
+
201
+ //#endregion
202
+ export { CalendarDayDetail, CalendarWithDetail, EventCalendar };