@classytic/fluid 0.2.4 → 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 -387
  57. package/dist/dashboard.js +0 -1032
  58. package/dist/dashboard.js.map +0 -1
  59. package/dist/index.d.ts +0 -2140
  60. package/dist/index.js +0 -6422
  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
package/dist/index.mjs ADDED
@@ -0,0 +1,432 @@
1
+ import { t as cn } from "./utils-DQ5SCVoW.mjs";
2
+ import { a as getApiParams, i as clearSearchAndFilterParams, n as buildListingStatusParams, r as buildSearchParams, t as buildFilterParams } from "./filter-utils-DqMmy_v-.mjs";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ import { Skeleton } from "@/components/ui/skeleton";
5
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
6
+ import "react";
7
+ import { FileX2, InboxIcon, Loader2, SearchX } from "lucide-react";
8
+ import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty";
9
+
10
+ //#region src/layout/section.tsx
11
+ const backgrounds = {
12
+ default: "bg-background",
13
+ muted: "bg-muted",
14
+ primary: "bg-primary text-primary-foreground",
15
+ transparent: "bg-transparent"
16
+ };
17
+ const paddings = {
18
+ none: "",
19
+ sm: "py-8 md:py-12",
20
+ md: "py-12 md:py-16",
21
+ lg: "py-16 md:py-24",
22
+ xl: "py-24 md:py-32"
23
+ };
24
+ function Section({ id, children, className, background = "default", padding = "sm" }) {
25
+ return /* @__PURE__ */ jsx("section", {
26
+ id,
27
+ className: cn(backgrounds[background], paddings[padding], className),
28
+ children
29
+ });
30
+ }
31
+
32
+ //#endregion
33
+ //#region src/layout/container.tsx
34
+ const maxWidthClasses = {
35
+ sm: "max-w-screen-sm",
36
+ md: "max-w-screen-md",
37
+ lg: "max-w-screen-lg",
38
+ xl: "max-w-screen-xl",
39
+ "2xl": "max-w-screen-2xl",
40
+ "3xl": "max-w-3xl",
41
+ "4xl": "max-w-4xl",
42
+ "5xl": "max-w-5xl",
43
+ "6xl": "max-w-6xl",
44
+ "7xl": "max-w-7xl",
45
+ full: "max-w-full"
46
+ };
47
+ function Container({ children, className, maxWidth = "7xl" }) {
48
+ const isFullWidth = maxWidth === "full";
49
+ return /* @__PURE__ */ jsx("div", {
50
+ className: cn(isFullWidth ? "w-full px-4 sm:px-6 lg:px-10" : "mx-auto px-4 sm:px-6 lg:px-8", !isFullWidth && maxWidthClasses[maxWidth], className),
51
+ children
52
+ });
53
+ }
54
+
55
+ //#endregion
56
+ //#region src/components/display-heading.tsx
57
+ /**
58
+ * DisplayHeading - Reusable component for hero/display headings
59
+ * Provides consistent typography across the platform
60
+ */
61
+ function DisplayHeading({ children, size = "xl", align = "center", className, highlightText, highlightColor = "primary", as: Component = "h1", ...props }) {
62
+ const sizeClasses = {
63
+ lg: "text-3xl lg:text-5xl",
64
+ xl: "text-4xl lg:text-6xl",
65
+ "2xl": "text-5xl lg:text-7xl"
66
+ };
67
+ const alignClasses = {
68
+ left: "text-left",
69
+ center: "text-center",
70
+ right: "text-right"
71
+ };
72
+ const highlightClasses = {
73
+ primary: "text-primary",
74
+ secondary: "text-secondary",
75
+ accent: "text-accent",
76
+ gradient: "bg-gradient-to-r from-primary to-accent bg-clip-text text-transparent"
77
+ };
78
+ const renderContent = () => {
79
+ if (typeof children !== "string" || !highlightText) return children;
80
+ const parts = children.split(highlightText);
81
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
82
+ parts[0],
83
+ /* @__PURE__ */ jsx("span", {
84
+ className: highlightClasses[highlightColor],
85
+ children: highlightText
86
+ }),
87
+ parts[1]
88
+ ] });
89
+ };
90
+ return /* @__PURE__ */ jsx(Component, {
91
+ className: cn("font-bold tracking-tight text-balance leading-[1.1]", sizeClasses[size], alignClasses[align], className),
92
+ ...props,
93
+ children: renderContent()
94
+ });
95
+ }
96
+
97
+ //#endregion
98
+ //#region src/components/social-icons.tsx
99
+ const FacebookIcon = () => /* @__PURE__ */ jsx("svg", {
100
+ xmlns: "http://www.w3.org/2000/svg",
101
+ width: "18",
102
+ height: "18",
103
+ viewBox: "0 0 24 24",
104
+ fill: "none",
105
+ stroke: "currentColor",
106
+ strokeWidth: "2",
107
+ strokeLinecap: "round",
108
+ strokeLinejoin: "round",
109
+ children: /* @__PURE__ */ jsx("path", { d: "M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z" })
110
+ });
111
+ const GoogleIcon = () => /* @__PURE__ */ jsxs("svg", {
112
+ xmlns: "http://www.w3.org/2000/svg",
113
+ width: "18",
114
+ height: "18",
115
+ viewBox: "0 0 24 24",
116
+ fill: "currentColor",
117
+ children: [
118
+ /* @__PURE__ */ jsx("path", { d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" }),
119
+ /* @__PURE__ */ jsx("path", { d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" }),
120
+ /* @__PURE__ */ jsx("path", { d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" }),
121
+ /* @__PURE__ */ jsx("path", { d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" })
122
+ ]
123
+ });
124
+ const TwitterXIcon = () => /* @__PURE__ */ jsx("svg", {
125
+ xmlns: "http://www.w3.org/2000/svg",
126
+ viewBox: "0 0 1200 1227",
127
+ width: "18",
128
+ height: "18",
129
+ fill: "currentColor",
130
+ children: /* @__PURE__ */ jsx("path", { d: "M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z" })
131
+ });
132
+ const InstagramIcon = () => /* @__PURE__ */ jsxs("svg", {
133
+ xmlns: "http://www.w3.org/2000/svg",
134
+ width: "18",
135
+ height: "18",
136
+ viewBox: "0 0 24 24",
137
+ fill: "none",
138
+ stroke: "currentColor",
139
+ strokeWidth: "2",
140
+ strokeLinecap: "round",
141
+ strokeLinejoin: "round",
142
+ children: [
143
+ /* @__PURE__ */ jsx("rect", {
144
+ x: "2",
145
+ y: "2",
146
+ width: "20",
147
+ height: "20",
148
+ rx: "5",
149
+ ry: "5"
150
+ }),
151
+ /* @__PURE__ */ jsx("path", { d: "M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z" }),
152
+ /* @__PURE__ */ jsx("line", {
153
+ x1: "17.5",
154
+ y1: "6.5",
155
+ x2: "17.51",
156
+ y2: "6.5"
157
+ })
158
+ ]
159
+ });
160
+ const WhatsAppIcon = () => /* @__PURE__ */ jsx("svg", {
161
+ viewBox: "0 0 24 24",
162
+ fill: "currentColor",
163
+ width: "18",
164
+ height: "18",
165
+ children: /* @__PURE__ */ jsx("path", { d: "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z" })
166
+ });
167
+
168
+ //#endregion
169
+ //#region src/components/skeleton-wrappers.tsx
170
+ /**
171
+ * SkeletonTable - Loading skeleton for tables
172
+ * Matches DataTable structure for consistent loading states
173
+ *
174
+ * @example
175
+ * ```tsx
176
+ * <SkeletonTable rows={5} columns={4} />
177
+ * <SkeletonTable headers={["Name", "Email", "Status"]} rows={10} />
178
+ * ```
179
+ */
180
+ function SkeletonTable({ rows = 5, columns = 6, headers, className }) {
181
+ const columnCount = headers?.length || columns;
182
+ return /* @__PURE__ */ jsx("div", {
183
+ className: cn("rounded-md border", className),
184
+ children: /* @__PURE__ */ jsxs(Table, { children: [/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsx(TableRow, { children: headers ? headers.map((header, i) => /* @__PURE__ */ jsx(TableHead, { children: header }, i)) : Array.from({ length: columnCount }).map((_, i) => /* @__PURE__ */ jsx(TableHead, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-20" }) }, i)) }) }), /* @__PURE__ */ jsx(TableBody, { children: Array.from({ length: rows }).map((_, rowIndex) => /* @__PURE__ */ jsx(TableRow, { children: Array.from({ length: columnCount }).map((_, colIndex) => /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }) }, colIndex)) }, rowIndex)) })] })
185
+ });
186
+ }
187
+ /**
188
+ * SkeletonList - Compact skeleton for lists with avatars
189
+ *
190
+ * @example
191
+ * ```tsx
192
+ * <SkeletonList items={5} />
193
+ * <SkeletonList items={3} showAvatar={false} />
194
+ * ```
195
+ */
196
+ function SkeletonList({ items = 3, className, showAvatar = true, avatarShape = "circle" }) {
197
+ return /* @__PURE__ */ jsx("div", {
198
+ className: cn("space-y-3", className),
199
+ children: Array.from({ length: items }).map((_, i) => /* @__PURE__ */ jsxs("div", {
200
+ className: "flex items-center gap-3",
201
+ children: [showAvatar && /* @__PURE__ */ jsx(Skeleton, { className: cn("h-10 w-10 flex-shrink-0", avatarShape === "circle" ? "rounded-full" : "rounded-md") }), /* @__PURE__ */ jsxs("div", {
202
+ className: "flex-1 space-y-2",
203
+ children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-3/4" })]
204
+ })]
205
+ }, i))
206
+ });
207
+ }
208
+ /**
209
+ * SkeletonCard - Card skeleton for grid layouts
210
+ *
211
+ * @example
212
+ * ```tsx
213
+ * <SkeletonCard />
214
+ * <SkeletonCard showActions={false} lines={2} />
215
+ * ```
216
+ */
217
+ function SkeletonCard({ className, showActions = true, lines = 3 }) {
218
+ return /* @__PURE__ */ jsxs("div", {
219
+ className: cn("rounded-lg border p-4 space-y-3", className),
220
+ children: [
221
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-3/4" }),
222
+ Array.from({ length: lines - 1 }).map((_, i) => /* @__PURE__ */ jsx(Skeleton, { className: cn("h-4", i === lines - 2 ? "w-5/6" : "w-full") }, i)),
223
+ showActions && /* @__PURE__ */ jsxs("div", {
224
+ className: "flex gap-2 pt-2",
225
+ children: [/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-20" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-20" })]
226
+ })
227
+ ]
228
+ });
229
+ }
230
+ /**
231
+ * SkeletonGrid - Grid of skeleton cards
232
+ *
233
+ * @example
234
+ * ```tsx
235
+ * <SkeletonGrid cards={6} columns={3} />
236
+ * ```
237
+ */
238
+ function SkeletonGrid({ cards = 6, columns = 3, className, cardProps }) {
239
+ return /* @__PURE__ */ jsx("div", {
240
+ className: cn("grid gap-4", {
241
+ 1: "grid-cols-1",
242
+ 2: "grid-cols-1 sm:grid-cols-2",
243
+ 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
244
+ 4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
245
+ }[columns], className),
246
+ children: Array.from({ length: cards }).map((_, i) => /* @__PURE__ */ jsx(SkeletonCard, { ...cardProps }, i))
247
+ });
248
+ }
249
+
250
+ //#endregion
251
+ //#region src/components/loading-state.tsx
252
+ const SIZES = {
253
+ sm: "h-4 w-4",
254
+ md: "h-6 w-6",
255
+ lg: "h-10 w-10"
256
+ };
257
+ const TEXT_SIZES = {
258
+ sm: "text-xs",
259
+ md: "text-sm",
260
+ lg: "text-base"
261
+ };
262
+ /**
263
+ * LoadingState — Versatile loading indicator
264
+ *
265
+ * @example Default (centered, full area)
266
+ * ```tsx
267
+ * <LoadingState text="Loading projects..." />
268
+ * ```
269
+ *
270
+ * @example Inline (in a row)
271
+ * ```tsx
272
+ * <LoadingState variant="inline" text="Saving..." size="sm" />
273
+ * ```
274
+ *
275
+ * @example Minimal (just the spinner)
276
+ * ```tsx
277
+ * <LoadingState variant="minimal" />
278
+ * ```
279
+ */
280
+ function LoadingState({ text, variant = "default", size = "md", className }) {
281
+ const spinner = /* @__PURE__ */ jsx(Loader2, { className: cn(SIZES[size], "animate-spin text-muted-foreground") });
282
+ if (variant === "minimal") return /* @__PURE__ */ jsx("div", {
283
+ className: cn("flex items-center justify-center", className),
284
+ children: spinner
285
+ });
286
+ if (variant === "inline") return /* @__PURE__ */ jsxs("div", {
287
+ className: cn("flex items-center gap-2 text-muted-foreground", className),
288
+ children: [spinner, text && /* @__PURE__ */ jsx("span", {
289
+ className: TEXT_SIZES[size],
290
+ children: text
291
+ })]
292
+ });
293
+ return /* @__PURE__ */ jsxs("div", {
294
+ className: cn("flex flex-col items-center justify-center gap-3 py-12 px-6", className),
295
+ children: [spinner, text && /* @__PURE__ */ jsx("p", {
296
+ className: cn("text-muted-foreground", TEXT_SIZES[size]),
297
+ children: text
298
+ })]
299
+ });
300
+ }
301
+ /**
302
+ * LoadingOverlay — Renders children with an overlay spinner on top
303
+ *
304
+ * @example
305
+ * ```tsx
306
+ * <LoadingOverlay visible={isSaving} text="Saving changes...">
307
+ * <MyFormContent />
308
+ * </LoadingOverlay>
309
+ * ```
310
+ */
311
+ function LoadingOverlay({ text, visible = true, className, children }) {
312
+ return /* @__PURE__ */ jsxs("div", {
313
+ className: cn("relative", className),
314
+ children: [children, visible && /* @__PURE__ */ jsxs("div", {
315
+ className: "absolute inset-0 z-10 flex flex-col items-center justify-center gap-3 rounded-[inherit] bg-background/90 backdrop-blur-sm",
316
+ children: [/* @__PURE__ */ jsx(Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }), text && /* @__PURE__ */ jsx("p", {
317
+ className: "text-sm text-muted-foreground font-medium",
318
+ children: text
319
+ })]
320
+ })]
321
+ });
322
+ }
323
+
324
+ //#endregion
325
+ //#region src/components/empty-state.tsx
326
+ const PRESETS = {
327
+ noResults: {
328
+ icon: /* @__PURE__ */ jsx(SearchX, { className: "h-6 w-6" }),
329
+ title: "No results found",
330
+ description: "Try adjusting your search or filter criteria."
331
+ },
332
+ noData: {
333
+ icon: /* @__PURE__ */ jsx(InboxIcon, { className: "h-6 w-6" }),
334
+ title: "No data yet",
335
+ description: "Get started by creating your first item."
336
+ },
337
+ notFound: {
338
+ icon: /* @__PURE__ */ jsx(FileX2, { className: "h-6 w-6" }),
339
+ title: "Not found",
340
+ description: "The item you're looking for doesn't exist or has been removed."
341
+ }
342
+ };
343
+ /**
344
+ * EmptyState — Higher-level wrapper around the composable Empty primitives.
345
+ *
346
+ * Composes: Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent
347
+ *
348
+ * @example Default
349
+ * ```tsx
350
+ * <EmptyState
351
+ * title="No projects yet"
352
+ * description="Create your first project to get started."
353
+ * icon={<FolderPlus className="h-6 w-6" />}
354
+ * action={<Button>Create Project</Button>}
355
+ * />
356
+ * ```
357
+ *
358
+ * @example Compact (inline)
359
+ * ```tsx
360
+ * <EmptyState variant="compact" title="No items" />
361
+ * ```
362
+ *
363
+ * @example With preset
364
+ * ```tsx
365
+ * <EmptyStateNoResults action={<Button onClick={clearFilters}>Clear filters</Button>} />
366
+ * ```
367
+ */
368
+ function EmptyState({ title = "Nothing here", description, icon = /* @__PURE__ */ jsx(InboxIcon, { className: "h-6 w-6" }), action, secondaryAction, variant = "default", className, children }) {
369
+ if (variant === "compact") return /* @__PURE__ */ jsxs("div", {
370
+ "data-slot": "empty-state",
371
+ className: cn("flex items-center gap-3 py-6 px-4 text-muted-foreground", className),
372
+ children: [
373
+ icon && /* @__PURE__ */ jsx("div", {
374
+ className: "flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
375
+ children: icon
376
+ }),
377
+ /* @__PURE__ */ jsxs("div", {
378
+ className: "flex-1 min-w-0",
379
+ children: [/* @__PURE__ */ jsx("p", {
380
+ className: "text-sm font-medium",
381
+ children: title
382
+ }), description && /* @__PURE__ */ jsx("p", {
383
+ className: "text-xs text-muted-foreground/80 mt-0.5",
384
+ children: description
385
+ })]
386
+ }),
387
+ action
388
+ ]
389
+ });
390
+ return /* @__PURE__ */ jsxs(Empty, {
391
+ className: cn(variant === "card" && "border border-dashed", className),
392
+ children: [
393
+ /* @__PURE__ */ jsxs(EmptyHeader, { children: [
394
+ icon && /* @__PURE__ */ jsx(EmptyMedia, {
395
+ variant: "icon",
396
+ children: icon
397
+ }),
398
+ /* @__PURE__ */ jsx(EmptyTitle, { children: title }),
399
+ description && /* @__PURE__ */ jsx(EmptyDescription, { children: description })
400
+ ] }),
401
+ children && /* @__PURE__ */ jsx(EmptyContent, { children }),
402
+ (action || secondaryAction) && /* @__PURE__ */ jsx(EmptyContent, { children: /* @__PURE__ */ jsxs("div", {
403
+ className: "flex items-center gap-3",
404
+ children: [action, secondaryAction]
405
+ }) })
406
+ ]
407
+ });
408
+ }
409
+ /** No search results — with search icon */
410
+ function EmptyStateNoResults(props) {
411
+ return /* @__PURE__ */ jsx(EmptyState, {
412
+ ...PRESETS.noResults,
413
+ ...props
414
+ });
415
+ }
416
+ /** No data — with inbox icon */
417
+ function EmptyStateNoData(props) {
418
+ return /* @__PURE__ */ jsx(EmptyState, {
419
+ ...PRESETS.noData,
420
+ ...props
421
+ });
422
+ }
423
+ /** Not found — with file-x icon */
424
+ function EmptyStateNotFound(props) {
425
+ return /* @__PURE__ */ jsx(EmptyState, {
426
+ ...PRESETS.notFound,
427
+ ...props
428
+ });
429
+ }
430
+
431
+ //#endregion
432
+ export { Container, DisplayHeading, EmptyState, EmptyStateNoData, EmptyStateNoResults, EmptyStateNotFound, FacebookIcon, GoogleIcon, InstagramIcon, LoadingOverlay, LoadingState, Section, SkeletonCard, SkeletonGrid, SkeletonList, SkeletonTable, TwitterXIcon, WhatsAppIcon, buildFilterParams, buildListingStatusParams, buildSearchParams, clearSearchAndFilterParams, cn, getApiParams };
@@ -0,0 +1,215 @@
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import * as react from "react";
3
+ import { ReactNode } from "react";
4
+ import { LucideIcon } from "lucide-react";
5
+
6
+ //#region src/components/drawer-wrapper.d.ts
7
+ declare const DRAWER_SIZE_CLASSES: {
8
+ readonly horizontal: {
9
+ readonly sm: "data-[vaul-drawer-direction=right]:sm:max-w-xs data-[vaul-drawer-direction=left]:sm:max-w-xs";
10
+ readonly default: "data-[vaul-drawer-direction=right]:sm:max-w-sm data-[vaul-drawer-direction=left]:sm:max-w-sm";
11
+ readonly md: "data-[vaul-drawer-direction=right]:sm:max-w-md data-[vaul-drawer-direction=left]:sm:max-w-md";
12
+ readonly lg: "data-[vaul-drawer-direction=right]:w-full data-[vaul-drawer-direction=right]:sm:max-w-lg data-[vaul-drawer-direction=right]:md:max-w-2xl data-[vaul-drawer-direction=left]:w-full data-[vaul-drawer-direction=left]:sm:max-w-lg data-[vaul-drawer-direction=left]:md:max-w-2xl";
13
+ readonly xl: "data-[vaul-drawer-direction=right]:w-full data-[vaul-drawer-direction=right]:sm:max-w-2xl data-[vaul-drawer-direction=right]:md:max-w-4xl data-[vaul-drawer-direction=left]:w-full data-[vaul-drawer-direction=left]:sm:max-w-2xl data-[vaul-drawer-direction=left]:md:max-w-4xl";
14
+ readonly full: "data-[vaul-drawer-direction=right]:w-full data-[vaul-drawer-direction=right]:max-w-full data-[vaul-drawer-direction=right]:sm:max-w-full data-[vaul-drawer-direction=left]:w-full data-[vaul-drawer-direction=left]:max-w-full data-[vaul-drawer-direction=left]:sm:max-w-full";
15
+ };
16
+ readonly vertical: {
17
+ readonly sm: "max-h-[40vh]";
18
+ readonly default: "max-h-[80vh]";
19
+ readonly md: "max-h-[60vh]";
20
+ readonly lg: "max-h-[80vh]";
21
+ readonly xl: "max-h-[90vh]";
22
+ readonly full: "max-h-screen h-screen";
23
+ };
24
+ };
25
+ type DrawerSizeVariant = keyof (typeof DRAWER_SIZE_CLASSES)["vertical"];
26
+ interface DrawerWrapperProps {
27
+ open: boolean;
28
+ onOpenChange: (open: boolean) => void;
29
+ title?: string;
30
+ description?: string;
31
+ children?: ReactNode;
32
+ footer?: ReactNode;
33
+ trigger?: ReactNode;
34
+ direction?: "top" | "bottom" | "left" | "right";
35
+ /** Named size preset. For left/right: controls width. For top/bottom: controls height. */
36
+ size?: DrawerSizeVariant;
37
+ className?: string;
38
+ headerClassName?: string;
39
+ contentClassName?: string;
40
+ footerClassName?: string;
41
+ hideHeader?: boolean;
42
+ hideTitle?: boolean;
43
+ hideDescription?: boolean;
44
+ /** Show an X close button (useful for full-size or side drawers) */
45
+ showCloseButton?: boolean;
46
+ /** Whether to show the drag handle indicator (bottom drawers only) */
47
+ showHandle?: boolean;
48
+ /** Snap points for drawer positioning */
49
+ snapPoints?: (number | string)[];
50
+ /** Whether drawer should scale background */
51
+ shouldScaleBackground?: boolean;
52
+ }
53
+ declare const DrawerWrapper: react.NamedExoticComponent<DrawerWrapperProps>;
54
+ interface FormDrawerProps extends Omit<DrawerWrapperProps, "footer"> {
55
+ onSubmit?: () => void;
56
+ onCancel?: () => void;
57
+ submitLabel?: string;
58
+ cancelLabel?: string;
59
+ submitDisabled?: boolean;
60
+ submitLoading?: boolean;
61
+ }
62
+ declare const FormDrawer: react.NamedExoticComponent<FormDrawerProps>;
63
+ interface ConfirmDrawerProps extends Omit<DrawerWrapperProps, "footer"> {
64
+ onConfirm?: () => void;
65
+ onCancel?: () => void;
66
+ confirmLabel?: string;
67
+ cancelLabel?: string;
68
+ confirmVariant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link";
69
+ confirmDisabled?: boolean;
70
+ confirmLoading?: boolean;
71
+ }
72
+ declare const ConfirmDrawer: react.NamedExoticComponent<ConfirmDrawerProps>;
73
+ //#endregion
74
+ //#region src/components/navigation-bar.d.ts
75
+ interface NavBarLink {
76
+ title: string;
77
+ href: string;
78
+ description?: string;
79
+ icon?: LucideIcon;
80
+ isActive?: boolean;
81
+ external?: boolean;
82
+ }
83
+ interface NavBarDropdown {
84
+ title: string;
85
+ icon?: LucideIcon;
86
+ items: NavBarLink[];
87
+ /** Grid columns for the dropdown (1-3) */
88
+ columns?: 1 | 2 | 3;
89
+ /** Featured item shown separately */
90
+ featured?: {
91
+ title: string;
92
+ description: string;
93
+ href: string;
94
+ icon?: react.ReactNode;
95
+ };
96
+ }
97
+ type NavBarItem = NavBarLink | NavBarDropdown;
98
+ interface NavBarBrand {
99
+ title: string;
100
+ icon?: react.ReactNode;
101
+ href?: string;
102
+ }
103
+ interface NavigationBarProps {
104
+ /** Brand / logo section */
105
+ brand: NavBarBrand;
106
+ /** Navigation items */
107
+ items: NavBarItem[];
108
+ /** Right-side content (e.g., auth buttons, avatar) */
109
+ actions?: react.ReactNode;
110
+ /** Sticky positioning */
111
+ sticky?: boolean;
112
+ /** Show border at bottom */
113
+ bordered?: boolean;
114
+ /** Additional className */
115
+ className?: string;
116
+ /** Mobile breakpoint for showing hamburger */
117
+ mobileBreakpoint?: "sm" | "md" | "lg";
118
+ }
119
+ declare function NavigationBar({
120
+ brand,
121
+ items,
122
+ actions,
123
+ sticky,
124
+ bordered,
125
+ className,
126
+ mobileBreakpoint
127
+ }: NavigationBarProps): react_jsx_runtime0.JSX.Element;
128
+ //#endregion
129
+ //#region src/components/context-menu-wrapper.d.ts
130
+ interface ContextMenuAction {
131
+ type?: "item" | "separator" | "label" | "checkbox" | "radio-group" | "submenu";
132
+ key?: string;
133
+ label?: string;
134
+ icon?: LucideIcon;
135
+ onClick?: () => void;
136
+ disabled?: boolean;
137
+ hidden?: boolean;
138
+ variant?: "default" | "destructive";
139
+ shortcut?: string;
140
+ /** For checkbox items */
141
+ checked?: boolean;
142
+ onCheckedChange?: (checked: boolean) => void;
143
+ /** For radio groups */
144
+ radioValue?: string;
145
+ onRadioChange?: (value: string) => void;
146
+ radioOptions?: {
147
+ value: string;
148
+ label: string;
149
+ }[];
150
+ /** For submenus */
151
+ items?: ContextMenuAction[];
152
+ }
153
+ interface ContextMenuWrapperProps {
154
+ children: react.ReactNode;
155
+ items: ContextMenuAction[];
156
+ className?: string;
157
+ contentClassName?: string;
158
+ disabled?: boolean;
159
+ }
160
+ declare function ContextMenuWrapper({
161
+ children,
162
+ items,
163
+ className,
164
+ contentClassName,
165
+ disabled
166
+ }: ContextMenuWrapperProps): react_jsx_runtime0.JSX.Element;
167
+ //#endregion
168
+ //#region src/components/hover-card-wrapper.d.ts
169
+ interface HoverCardWrapperProps {
170
+ trigger: react.ReactNode;
171
+ children: react.ReactNode;
172
+ side?: "top" | "bottom" | "left" | "right";
173
+ align?: "start" | "center" | "end";
174
+ sideOffset?: number;
175
+ className?: string;
176
+ contentClassName?: string;
177
+ /** Delay before opening (ms) */
178
+ openDelay?: number;
179
+ /** Delay before closing (ms) */
180
+ closeDelay?: number;
181
+ }
182
+ declare function HoverCardWrapper({
183
+ trigger,
184
+ children,
185
+ side,
186
+ align,
187
+ sideOffset,
188
+ className,
189
+ contentClassName,
190
+ openDelay,
191
+ closeDelay
192
+ }: HoverCardWrapperProps): react_jsx_runtime0.JSX.Element;
193
+ interface UserHoverCardProps {
194
+ trigger: react.ReactNode;
195
+ user: {
196
+ name: string;
197
+ username?: string;
198
+ avatar?: string;
199
+ bio?: string;
200
+ initials?: string;
201
+ };
202
+ /** Extra content below bio */
203
+ footer?: react.ReactNode;
204
+ side?: "top" | "bottom" | "left" | "right";
205
+ className?: string;
206
+ }
207
+ declare function UserHoverCard({
208
+ trigger,
209
+ user,
210
+ footer,
211
+ side,
212
+ className
213
+ }: UserHoverCardProps): react_jsx_runtime0.JSX.Element;
214
+ //#endregion
215
+ export { ConfirmDrawer, type ConfirmDrawerProps, type ContextMenuAction, ContextMenuWrapper, type ContextMenuWrapperProps, DrawerWrapper, type DrawerWrapperProps, FormDrawer, type FormDrawerProps, HoverCardWrapper, type HoverCardWrapperProps, type NavBarBrand, type NavBarDropdown, type NavBarItem, type NavBarLink, NavigationBar, type NavigationBarProps, UserHoverCard, type UserHoverCardProps };