@nestjs-dash/design-system 0.2.0

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 (186) hide show
  1. package/dist/components/admin-shell.d.ts +48 -0
  2. package/dist/components/admin-shell.d.ts.map +1 -0
  3. package/dist/components/admin-shell.js +49 -0
  4. package/dist/components/admin-shell.js.map +1 -0
  5. package/dist/components/chart.d.ts +12 -0
  6. package/dist/components/chart.d.ts.map +1 -0
  7. package/dist/components/chart.js +68 -0
  8. package/dist/components/chart.js.map +1 -0
  9. package/dist/components/confirm-dialog.d.ts +17 -0
  10. package/dist/components/confirm-dialog.d.ts.map +1 -0
  11. package/dist/components/confirm-dialog.js +8 -0
  12. package/dist/components/confirm-dialog.js.map +1 -0
  13. package/dist/components/data-pagination.d.ts +13 -0
  14. package/dist/components/data-pagination.d.ts.map +1 -0
  15. package/dist/components/data-pagination.js +61 -0
  16. package/dist/components/data-pagination.js.map +1 -0
  17. package/dist/components/data-table.d.ts +27 -0
  18. package/dist/components/data-table.d.ts.map +1 -0
  19. package/dist/components/data-table.js +82 -0
  20. package/dist/components/data-table.js.map +1 -0
  21. package/dist/components/empty-state.d.ts +5 -0
  22. package/dist/components/empty-state.d.ts.map +1 -0
  23. package/dist/components/empty-state.js +5 -0
  24. package/dist/components/empty-state.js.map +1 -0
  25. package/dist/components/file-upload-field.d.ts +28 -0
  26. package/dist/components/file-upload-field.d.ts.map +1 -0
  27. package/dist/components/file-upload-field.js +104 -0
  28. package/dist/components/file-upload-field.js.map +1 -0
  29. package/dist/components/icon.d.ts +8 -0
  30. package/dist/components/icon.d.ts.map +1 -0
  31. package/dist/components/icon.js +21 -0
  32. package/dist/components/icon.js.map +1 -0
  33. package/dist/components/image-placeholder.d.ts +7 -0
  34. package/dist/components/image-placeholder.d.ts.map +1 -0
  35. package/dist/components/image-placeholder.js +11 -0
  36. package/dist/components/image-placeholder.js.map +1 -0
  37. package/dist/components/image-upload-field.d.ts +29 -0
  38. package/dist/components/image-upload-field.d.ts.map +1 -0
  39. package/dist/components/image-upload-field.js +103 -0
  40. package/dist/components/image-upload-field.js.map +1 -0
  41. package/dist/components/repeater-field.d.ts +18 -0
  42. package/dist/components/repeater-field.d.ts.map +1 -0
  43. package/dist/components/repeater-field.js +104 -0
  44. package/dist/components/repeater-field.js.map +1 -0
  45. package/dist/components/rich-box-field.d.ts +29 -0
  46. package/dist/components/rich-box-field.d.ts.map +1 -0
  47. package/dist/components/rich-box-field.js +69 -0
  48. package/dist/components/rich-box-field.js.map +1 -0
  49. package/dist/components/rich-editor-field.d.ts +15 -0
  50. package/dist/components/rich-editor-field.d.ts.map +1 -0
  51. package/dist/components/rich-editor-field.js +52 -0
  52. package/dist/components/rich-editor-field.js.map +1 -0
  53. package/dist/components/schema-form.d.ts +42 -0
  54. package/dist/components/schema-form.d.ts.map +1 -0
  55. package/dist/components/schema-form.js +180 -0
  56. package/dist/components/schema-form.js.map +1 -0
  57. package/dist/components/tags-input-field.d.ts +14 -0
  58. package/dist/components/tags-input-field.d.ts.map +1 -0
  59. package/dist/components/tags-input-field.js +59 -0
  60. package/dist/components/tags-input-field.js.map +1 -0
  61. package/dist/components/theme-toggle.d.ts +12 -0
  62. package/dist/components/theme-toggle.d.ts.map +1 -0
  63. package/dist/components/theme-toggle.js +19 -0
  64. package/dist/components/theme-toggle.js.map +1 -0
  65. package/dist/components/ui/alert.d.ts +10 -0
  66. package/dist/components/ui/alert.d.ts.map +1 -0
  67. package/dist/components/ui/alert.js +26 -0
  68. package/dist/components/ui/alert.js.map +1 -0
  69. package/dist/components/ui/avatar.d.ts +12 -0
  70. package/dist/components/ui/avatar.d.ts.map +1 -0
  71. package/dist/components/ui/avatar.js +25 -0
  72. package/dist/components/ui/avatar.js.map +1 -0
  73. package/dist/components/ui/badge.d.ts +10 -0
  74. package/dist/components/ui/badge.d.ts.map +1 -0
  75. package/dist/components/ui/badge.js +26 -0
  76. package/dist/components/ui/badge.js.map +1 -0
  77. package/dist/components/ui/breadcrumb.d.ts +12 -0
  78. package/dist/components/ui/breadcrumb.d.ts.map +1 -0
  79. package/dist/components/ui/breadcrumb.js +29 -0
  80. package/dist/components/ui/breadcrumb.js.map +1 -0
  81. package/dist/components/ui/button.d.ts +11 -0
  82. package/dist/components/ui/button.d.ts.map +1 -0
  83. package/dist/components/ui/button.js +39 -0
  84. package/dist/components/ui/button.js.map +1 -0
  85. package/dist/components/ui/card.d.ts +10 -0
  86. package/dist/components/ui/card.d.ts.map +1 -0
  87. package/dist/components/ui/card.js +26 -0
  88. package/dist/components/ui/card.js.map +1 -0
  89. package/dist/components/ui/checkbox.d.ts +5 -0
  90. package/dist/components/ui/checkbox.d.ts.map +1 -0
  91. package/dist/components/ui/checkbox.js +10 -0
  92. package/dist/components/ui/checkbox.js.map +1 -0
  93. package/dist/components/ui/collapsible.d.ts +6 -0
  94. package/dist/components/ui/collapsible.d.ts.map +1 -0
  95. package/dist/components/ui/collapsible.js +13 -0
  96. package/dist/components/ui/collapsible.js.map +1 -0
  97. package/dist/components/ui/dialog.d.ts +18 -0
  98. package/dist/components/ui/dialog.d.ts.map +1 -0
  99. package/dist/components/ui/dialog.js +39 -0
  100. package/dist/components/ui/dialog.js.map +1 -0
  101. package/dist/components/ui/dropdown-menu.d.ts +26 -0
  102. package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
  103. package/dist/components/ui/dropdown-menu.js +53 -0
  104. package/dist/components/ui/dropdown-menu.js.map +1 -0
  105. package/dist/components/ui/input.d.ts +4 -0
  106. package/dist/components/ui/input.d.ts.map +1 -0
  107. package/dist/components/ui/input.js +8 -0
  108. package/dist/components/ui/input.js.map +1 -0
  109. package/dist/components/ui/label.d.ts +5 -0
  110. package/dist/components/ui/label.d.ts.map +1 -0
  111. package/dist/components/ui/label.js +9 -0
  112. package/dist/components/ui/label.js.map +1 -0
  113. package/dist/components/ui/pagination.d.ts +14 -0
  114. package/dist/components/ui/pagination.d.ts.map +1 -0
  115. package/dist/components/ui/pagination.js +31 -0
  116. package/dist/components/ui/pagination.js.map +1 -0
  117. package/dist/components/ui/scroll-area.d.ts +6 -0
  118. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  119. package/dist/components/ui/scroll-area.js +13 -0
  120. package/dist/components/ui/scroll-area.js.map +1 -0
  121. package/dist/components/ui/select.d.ts +16 -0
  122. package/dist/components/ui/select.d.ts.map +1 -0
  123. package/dist/components/ui/select.js +40 -0
  124. package/dist/components/ui/select.js.map +1 -0
  125. package/dist/components/ui/separator.d.ts +5 -0
  126. package/dist/components/ui/separator.d.ts.map +1 -0
  127. package/dist/components/ui/separator.js +10 -0
  128. package/dist/components/ui/separator.js.map +1 -0
  129. package/dist/components/ui/sheet.d.ts +15 -0
  130. package/dist/components/ui/sheet.d.ts.map +1 -0
  131. package/dist/components/ui/sheet.js +41 -0
  132. package/dist/components/ui/sheet.js.map +1 -0
  133. package/dist/components/ui/sidebar.d.ts +70 -0
  134. package/dist/components/ui/sidebar.d.ts.map +1 -0
  135. package/dist/components/ui/sidebar.js +203 -0
  136. package/dist/components/ui/sidebar.js.map +1 -0
  137. package/dist/components/ui/skeleton.d.ts +3 -0
  138. package/dist/components/ui/skeleton.d.ts.map +1 -0
  139. package/dist/components/ui/skeleton.js +7 -0
  140. package/dist/components/ui/skeleton.js.map +1 -0
  141. package/dist/components/ui/table.d.ts +11 -0
  142. package/dist/components/ui/table.d.ts.map +1 -0
  143. package/dist/components/ui/table.js +30 -0
  144. package/dist/components/ui/table.js.map +1 -0
  145. package/dist/components/ui/tabs.d.ts +12 -0
  146. package/dist/components/ui/tabs.d.ts.map +1 -0
  147. package/dist/components/ui/tabs.js +34 -0
  148. package/dist/components/ui/tabs.js.map +1 -0
  149. package/dist/components/ui/textarea.d.ts +4 -0
  150. package/dist/components/ui/textarea.d.ts.map +1 -0
  151. package/dist/components/ui/textarea.js +8 -0
  152. package/dist/components/ui/textarea.js.map +1 -0
  153. package/dist/components/ui/tooltip.d.ts +8 -0
  154. package/dist/components/ui/tooltip.d.ts.map +1 -0
  155. package/dist/components/ui/tooltip.js +18 -0
  156. package/dist/components/ui/tooltip.js.map +1 -0
  157. package/dist/hooks/use-mobile.d.ts +2 -0
  158. package/dist/hooks/use-mobile.d.ts.map +1 -0
  159. package/dist/hooks/use-mobile.js +18 -0
  160. package/dist/hooks/use-mobile.js.map +1 -0
  161. package/dist/index.d.ts +45 -0
  162. package/dist/index.d.ts.map +1 -0
  163. package/dist/index.js +44 -0
  164. package/dist/index.js.map +1 -0
  165. package/dist/lib/badge-colors.d.ts +4 -0
  166. package/dist/lib/badge-colors.d.ts.map +1 -0
  167. package/dist/lib/badge-colors.js +22 -0
  168. package/dist/lib/badge-colors.js.map +1 -0
  169. package/dist/lib/format-date.d.ts +7 -0
  170. package/dist/lib/format-date.d.ts.map +1 -0
  171. package/dist/lib/format-date.js +35 -0
  172. package/dist/lib/format-date.js.map +1 -0
  173. package/dist/lib/utils.d.ts +2 -0
  174. package/dist/lib/utils.d.ts.map +1 -0
  175. package/dist/lib/utils.js +2 -0
  176. package/dist/lib/utils.js.map +1 -0
  177. package/dist/nestjs-dash.css +2 -0
  178. package/dist/pagination.d.ts +10 -0
  179. package/dist/pagination.d.ts.map +1 -0
  180. package/dist/pagination.js +42 -0
  181. package/dist/pagination.js.map +1 -0
  182. package/dist/ui.d.ts +99 -0
  183. package/dist/ui.d.ts.map +1 -0
  184. package/dist/ui.js +104 -0
  185. package/dist/ui.js.map +1 -0
  186. package/package.json +81 -0
@@ -0,0 +1,48 @@
1
+ import type { SchemaNode } from '@nestjs-dash/support';
2
+ import type { ReactNode } from 'react';
3
+ import type { PaginationMeta } from './data-pagination.js';
4
+ export interface NavigationItem {
5
+ label: string;
6
+ slug: string;
7
+ href: string;
8
+ icon?: string;
9
+ type?: string;
10
+ openInNewTab?: boolean;
11
+ }
12
+ export interface NavigationGroup {
13
+ label: string;
14
+ collapsible?: boolean;
15
+ collapsed?: boolean;
16
+ items: NavigationItem[];
17
+ }
18
+ export interface BreadcrumbItemModel {
19
+ label: string;
20
+ href?: string;
21
+ }
22
+ export interface PanelViewModel {
23
+ brandName: string;
24
+ path: string;
25
+ navigation: NavigationItem[];
26
+ navigationGroups?: NavigationGroup[];
27
+ breadcrumbs?: BreadcrumbItemModel[];
28
+ currentSlug?: string | null;
29
+ resource?: {
30
+ slug: string;
31
+ label: string;
32
+ table?: {
33
+ columns: SchemaNode[];
34
+ actions: SchemaNode[];
35
+ } | null;
36
+ form?: SchemaNode | null;
37
+ };
38
+ records?: Array<Record<string, unknown>>;
39
+ meta?: PaginationMeta;
40
+ }
41
+ export declare function AdminShell(props: {
42
+ model: PanelViewModel;
43
+ children?: ReactNode;
44
+ header?: ReactNode;
45
+ /** Called when a viewer expands/collapses a named nav group (accordion state). */
46
+ onGroupToggle?: (label: string, expanded: boolean) => void;
47
+ }): import("react").JSX.Element;
48
+ //# sourceMappingURL=admin-shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-shell.d.ts","sourceRoot":"","sources":["../../src/components/admin-shell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAgC3D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,WAAW,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE;YACN,OAAO,EAAE,UAAU,EAAE,CAAC;YACtB,OAAO,EAAE,UAAU,EAAE,CAAC;SACvB,GAAG,IAAI,CAAC;QACT,IAAI,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;KAC1B,CAAC;IACF,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACzC,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB;AAQD,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,KAAK,EAAE,cAAc,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,kFAAkF;IAClF,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5D,+BA4LA"}
@@ -0,0 +1,49 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { DataTable } from './data-table.js';
3
+ import { EmptyState } from './empty-state.js';
4
+ import { Icon } from './icon.js';
5
+ import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, } from './ui/breadcrumb.js';
6
+ import { Card, CardContent, CardHeader, CardTitle } from './ui/card.js';
7
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from './ui/collapsible.js';
8
+ import { Separator } from './ui/separator.js';
9
+ import { Sidebar, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarRail, SidebarTrigger, } from './ui/sidebar.js';
10
+ import { TooltipProvider } from './ui/tooltip.js';
11
+ function isCurrent(item, currentSlug) {
12
+ return (item.slug === currentSlug || (item.type === 'page' && currentSlug === `pages:${item.slug}`));
13
+ }
14
+ export function AdminShell(props) {
15
+ const listHrefBuilder = props.model.resource && props.model.path
16
+ ? (page, limit) => {
17
+ const params = new URLSearchParams();
18
+ params.set('page', String(page));
19
+ params.set('limit', String(limit));
20
+ return `${props.model.path}/${props.model.resource.slug}?${params.toString()}`;
21
+ }
22
+ : undefined;
23
+ const body = props.children ??
24
+ (props.model.resource ? (_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsx(CardTitle, { children: props.model.resource.label }) }), _jsx(CardContent, { children: props.model.resource.table ? (_jsx(DataTable, { columns: props.model.resource.table.columns, rows: props.model.records ?? [], meta: props.model.meta, buildHref: listHrefBuilder })) : null })] })) : (_jsx(EmptyState, { title: "Select a resource", description: "Choose an item from the sidebar." })));
25
+ const groups = props.model.navigationGroups;
26
+ const flatItems = props.model.navigation;
27
+ return (_jsx(TooltipProvider, { children: _jsxs(SidebarProvider, { defaultOpen: true, children: [_jsxs(Sidebar, { collapsible: "icon", variant: "sidebar", children: [_jsx(SidebarHeader, { className: "px-4 py-4 text-lg font-bold", children: _jsx("a", { href: props.model.path, className: "text-inherit no-underline", children: props.model.brandName }) }), _jsx(Separator, {}), _jsxs(SidebarContent, { children: [_jsx(SidebarGroup, { children: _jsx(SidebarGroupContent, { children: _jsx(SidebarMenu, { children: _jsx(SidebarMenuItem, { children: _jsx(SidebarMenuButton, { asChild: true, isActive: props.model.currentSlug == null, tooltip: "Dashboard", children: _jsx("a", { href: props.model.path, "aria-current": props.model.currentSlug == null ? 'page' : undefined, children: _jsx("span", { children: "Dashboard" }) }) }) }) }) }) }), groups?.length ? (groups.map((group) => {
28
+ const items = (_jsx(SidebarMenu, { children: group.items.map((item) => {
29
+ const current = isCurrent(item, props.model.currentSlug);
30
+ return (_jsx(SidebarMenuItem, { children: _jsx(SidebarMenuButton, { asChild: true, isActive: current, tooltip: item.label, children: _jsxs("a", { href: item.href, target: item.openInNewTab ? '_blank' : undefined, rel: item.openInNewTab ? 'noreferrer' : undefined, "aria-current": current ? 'page' : undefined, children: [item.icon ? _jsx(Icon, { name: item.icon }) : null, _jsx("span", { children: item.label })] }) }) }, item.slug));
31
+ }) }));
32
+ if (group.label === 'Main' || !group.collapsible) {
33
+ return (_jsxs(SidebarGroup, { children: [group.label !== 'Main' ? (_jsx(SidebarGroupLabel, { children: group.label })) : null, _jsx(SidebarGroupContent, { children: items })] }, group.label));
34
+ }
35
+ return (_jsx(Collapsible, { defaultOpen: !group.collapsed, onOpenChange: (open) => props.onGroupToggle?.(group.label, open), className: "group/nav-group", children: _jsxs(SidebarGroup, { children: [_jsx(CollapsibleTrigger, { asChild: true, children: _jsxs(SidebarGroupLabel, { className: "flex w-full cursor-pointer items-center justify-between", children: [group.label, _jsx(Icon, { name: "chevron-right", className: "transition-transform group-data-[state=open]/nav-group:rotate-90" })] }) }), _jsx(CollapsibleContent, { children: _jsx(SidebarGroupContent, { children: items }) })] }) }, group.label));
36
+ })) : (_jsx(SidebarGroup, { children: _jsx(SidebarGroupContent, { children: _jsx(SidebarMenu, { children: flatItems.map((item) => {
37
+ const current = isCurrent(item, props.model.currentSlug);
38
+ return (_jsx(SidebarMenuItem, { children: _jsx(SidebarMenuButton, { asChild: true, isActive: current, tooltip: item.label, children: _jsxs("a", { href: item.href, "aria-current": current ? 'page' : undefined, children: [item.icon ? _jsx(Icon, { name: item.icon }) : null, _jsx("span", { children: item.label })] }) }) }, item.slug));
39
+ }) }) }) }))] }), _jsx(SidebarRail, {})] }), _jsxs(SidebarInset, { children: [_jsxs("header", { className: "flex h-12 items-center gap-2 border-b border-border px-4", children: [_jsx(SidebarTrigger, {}), props.model.breadcrumbs?.length ? (_jsxs(_Fragment, { children: [_jsx(Separator, { orientation: "vertical", className: "mr-2 h-4" }), _jsx(Breadcrumb, { "data-afi-breadcrumbs": true, children: _jsx(BreadcrumbList, { children: props.model.breadcrumbs.flatMap((item, index) => {
40
+ const isLast = index === props.model.breadcrumbs.length - 1;
41
+ const nodes = [];
42
+ if (index > 0) {
43
+ nodes.push(_jsx(BreadcrumbSeparator, {}, `sep-${index}`));
44
+ }
45
+ nodes.push(_jsx(BreadcrumbItem, { children: isLast || !item.href ? (_jsx(BreadcrumbPage, { children: item.label })) : (_jsx(BreadcrumbLink, { href: item.href, children: item.label })) }, `${item.label}-${index}`));
46
+ return nodes;
47
+ }) }) })] })) : null, props.header ? _jsx("div", { className: "ml-auto flex items-center gap-2", children: props.header }) : null] }), _jsx("main", { className: "flex-1 p-6 space-y-4", children: body })] })] }) }));
48
+ }
49
+ //# sourceMappingURL=admin-shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-shell.js","sourceRoot":"","sources":["../../src/components/admin-shell.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ChartSpec } from '@nestjs-dash/support';
2
+ import * as React from 'react';
3
+ /**
4
+ * Renders a `ChartSpec` (produced by `@nestjs-dash/core`'s `BarChart`/
5
+ * `LineChart`/`PieChart` builders) as a real, hydrated, interactive Recharts
6
+ * component — colored via the design system's existing `--chart-1..5`
7
+ * theme tokens.
8
+ */
9
+ export declare function ChartWidget({ spec }: {
10
+ spec: ChartSpec;
11
+ }): React.JSX.Element;
12
+ //# sourceMappingURL=chart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart.d.ts","sourceRoot":"","sources":["../../src/components/chart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6B,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAgK/B;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,qBA6CxD"}
@@ -0,0 +1,68 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from 'react';
3
+ import { Bar, CartesianGrid, Legend, Line, Pie, BarChart as RBarChart, LineChart as RLineChart, PieChart as RPieChart, ResponsiveContainer, Tooltip, XAxis, YAxis, } from 'recharts';
4
+ import { EmptyState } from './empty-state.js';
5
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from './ui/card.js';
6
+ import { Skeleton } from './ui/skeleton.js';
7
+ /** `--chart-1..5` — the design system's existing shadcn-style chart color tokens. */
8
+ function chartColorVar(n) {
9
+ return `var(--chart-${n})`;
10
+ }
11
+ function seriesColor(series, index) {
12
+ return chartColorVar(series.color ?? ((index % 5) + 1));
13
+ }
14
+ const subscribeNever = () => () => { };
15
+ /** True once running on the client, false during SSR — the recommended
16
+ * React idiom for a server/client-only value (avoids the extra
17
+ * render-then-setState pass a `useState`+`useEffect` mount flag causes). */
18
+ function useHasMounted() {
19
+ return React.useSyncExternalStore(subscribeNever, () => true, () => false);
20
+ }
21
+ /**
22
+ * Recharts' `ResponsiveContainer` measures real DOM layout and produces no
23
+ * meaningful output during server-side `renderToString` — so this renders a
24
+ * fixed-height `Skeleton` until the client takes over, then swaps to the
25
+ * real chart. Server render and the client's initial (pre-hydration-settle)
26
+ * render both produce the same skeleton markup — no hydration mismatch.
27
+ */
28
+ function ChartContainer(props) {
29
+ const mounted = useHasMounted();
30
+ if (!mounted) {
31
+ return _jsx(Skeleton, { className: "w-full rounded-md", style: { height: props.height } });
32
+ }
33
+ return (_jsx(ResponsiveContainer, { width: "100%", height: props.height, children: props.children }));
34
+ }
35
+ function ChartTooltipContent({ active, payload, label, }) {
36
+ if (!active || !payload?.length) {
37
+ return null;
38
+ }
39
+ return (_jsxs("div", { className: "rounded-md border border-border bg-card p-2 text-sm shadow-md", children: [label != null ? _jsx("div", { className: "mb-1 font-medium", children: label }) : null, payload.map((entry, index) => (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "inline-block size-2 rounded-full", style: { backgroundColor: entry.color } }), _jsxs("span", { className: "text-muted-foreground", children: [entry.name, ":"] }), _jsx("span", { className: "font-medium", children: entry.value })] }, index)))] }));
40
+ }
41
+ const legendStyle = { fontSize: 12, color: 'var(--muted-foreground)' };
42
+ function RechartsBar(props) {
43
+ return (_jsxs(RBarChart, { data: props.data, children: [_jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: "var(--border)" }), _jsx(XAxis, { dataKey: props.categoryKey, stroke: "var(--muted-foreground)", fontSize: 12 }), _jsx(YAxis, { stroke: "var(--muted-foreground)", fontSize: 12, allowDecimals: false }), _jsx(Tooltip, { content: _jsx(ChartTooltipContent, {}) }), props.legend ? _jsx(Legend, { wrapperStyle: legendStyle }) : null, props.series.map((series, index) => (_jsx(Bar, { dataKey: series.key, name: series.label ?? series.key, fill: seriesColor(series, index), radius: [4, 4, 0, 0] }, series.key)))] }));
44
+ }
45
+ function RechartsLine(props) {
46
+ return (_jsxs(RLineChart, { data: props.data, children: [_jsx(CartesianGrid, { strokeDasharray: "3 3", stroke: "var(--border)" }), _jsx(XAxis, { dataKey: props.categoryKey, stroke: "var(--muted-foreground)", fontSize: 12 }), _jsx(YAxis, { stroke: "var(--muted-foreground)", fontSize: 12, allowDecimals: false }), _jsx(Tooltip, { content: _jsx(ChartTooltipContent, {}) }), props.legend ? _jsx(Legend, { wrapperStyle: legendStyle }) : null, props.series.map((series, index) => (_jsx(Line, { type: "monotone", dataKey: series.key, name: series.label ?? series.key, stroke: seriesColor(series, index), strokeWidth: 2, dot: false }, series.key)))] }));
47
+ }
48
+ function RechartsPie(props) {
49
+ const valueKey = props.series[0]?.key ?? 'value';
50
+ // `Cell` is deprecated in recharts 3.x — a per-slice `fill` set directly
51
+ // on each datum is the documented replacement for coloring a `Pie`.
52
+ const coloredData = props.data.map((row, index) => ({
53
+ ...row,
54
+ fill: chartColorVar(((index % 5) + 1)),
55
+ }));
56
+ return (_jsxs(RPieChart, { children: [_jsx(Tooltip, { content: _jsx(ChartTooltipContent, {}) }), props.legend ? _jsx(Legend, { wrapperStyle: legendStyle }) : null, _jsx(Pie, { data: coloredData, dataKey: valueKey, nameKey: props.categoryKey, label: true })] }));
57
+ }
58
+ /**
59
+ * Renders a `ChartSpec` (produced by `@nestjs-dash/core`'s `BarChart`/
60
+ * `LineChart`/`PieChart` builders) as a real, hydrated, interactive Recharts
61
+ * component — colored via the design system's existing `--chart-1..5`
62
+ * theme tokens.
63
+ */
64
+ export function ChartWidget({ spec }) {
65
+ const legend = spec.legend ?? spec.kind === 'pie';
66
+ return (_jsxs(Card, { children: [spec.title || spec.description ? (_jsxs(CardHeader, { children: [spec.title ? _jsx(CardTitle, { children: spec.title }) : null, spec.description ? _jsx(CardDescription, { children: spec.description }) : null] })) : null, _jsx(CardContent, { children: spec.data.length === 0 ? (_jsx(EmptyState, { title: spec.emptyLabel ?? 'No data yet', description: spec.emptyLabel ? undefined : 'Nothing to chart yet.' })) : (_jsx(ChartContainer, { height: spec.height ?? 240, children: spec.kind === 'bar' ? (_jsx(RechartsBar, { data: spec.data, categoryKey: spec.categoryKey, series: spec.series, legend: legend })) : spec.kind === 'line' ? (_jsx(RechartsLine, { data: spec.data, categoryKey: spec.categoryKey, series: spec.series, legend: legend })) : (_jsx(RechartsPie, { data: spec.data, categoryKey: spec.categoryKey, series: spec.series, legend: legend })) })) })] }));
67
+ }
68
+ //# sourceMappingURL=chart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart.js","sourceRoot":"","sources":["../../src/components/chart.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { VariantProps } from 'class-variance-authority';
2
+ import type { ReactNode } from 'react';
3
+ import { buttonVariants } from './ui/button.js';
4
+ export declare function ConfirmDialog(props: {
5
+ trigger: ReactNode;
6
+ title: string;
7
+ description?: string;
8
+ confirmLabel?: string;
9
+ cancelLabel?: string;
10
+ /** Confirm button style. Defaults to 'destructive' (the common delete-confirmation case). */
11
+ confirmVariant?: VariantProps<typeof buttonVariants>['variant'];
12
+ formAction?: string;
13
+ method?: 'post' | 'get';
14
+ children?: ReactNode;
15
+ onConfirm?: () => void;
16
+ }): import("react").JSX.Element;
17
+ //# sourceMappingURL=confirm-dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm-dialog.d.ts","sourceRoot":"","sources":["../../src/components/confirm-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAU,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAYxD,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,OAAO,EAAE,SAAS,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,cAAc,CAAC,EAAE,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB,+BA0CA"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Button, buttonVariants } from './ui/button.js';
3
+ import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from './ui/dialog.js';
4
+ export function ConfirmDialog(props) {
5
+ const confirmVariant = props.confirmVariant ?? 'destructive';
6
+ return (_jsxs(Dialog, { children: [_jsx(DialogTrigger, { asChild: true, children: props.trigger }), _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: props.title }), props.description ? _jsx(DialogDescription, { children: props.description }) : null] }), props.formAction ? (_jsxs("form", { method: props.method ?? 'post', action: props.formAction, className: "space-y-4", children: [props.children, _jsxs(DialogFooter, { children: [_jsx(DialogClose, { asChild: true, children: _jsx(Button, { type: "button", variant: "secondary", children: props.cancelLabel ?? 'Cancel' }) }), _jsx(Button, { type: "submit", variant: confirmVariant, children: props.confirmLabel ?? 'Confirm' })] })] })) : (_jsxs(_Fragment, { children: [props.children, _jsxs(DialogFooter, { children: [_jsx(DialogClose, { asChild: true, children: _jsx(Button, { type: "button", variant: "secondary", children: props.cancelLabel ?? 'Cancel' }) }), _jsx(Button, { type: "button", variant: confirmVariant, onClick: props.onConfirm, children: props.confirmLabel ?? 'Confirm' })] })] }))] })] }));
7
+ }
8
+ //# sourceMappingURL=confirm-dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm-dialog.js","sourceRoot":"","sources":["../../src/components/confirm-dialog.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EACL,MAAM,EACN,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,gBAAgB,CAAC;AAExB,MAAM,UAAU,aAAa,CAAC,KAY7B;IACC,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,IAAI,aAAa,CAAC;IAC7D,OAAO,CACL,MAAC,MAAM,eACL,KAAC,aAAa,IAAC,OAAO,kBAAE,KAAK,CAAC,OAAO,GAAiB,EACtD,MAAC,aAAa,eACZ,MAAC,YAAY,eACX,KAAC,WAAW,cAAE,KAAK,CAAC,KAAK,GAAe,EACvC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,KAAC,iBAAiB,cAAE,KAAK,CAAC,WAAW,GAAqB,CAAC,CAAC,CAAC,IAAI,IACzE,EACd,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAClB,gBAAM,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,SAAS,EAAC,WAAW,aAClF,KAAK,CAAC,QAAQ,EACf,MAAC,YAAY,eACX,KAAC,WAAW,IAAC,OAAO,kBAClB,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAC,WAAW,YACtC,KAAK,CAAC,WAAW,IAAI,QAAQ,GACvB,GACG,EACd,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,cAAc,YAC1C,KAAK,CAAC,YAAY,IAAI,SAAS,GACzB,IACI,IACV,CACR,CAAC,CAAC,CAAC,CACF,8BACG,KAAK,CAAC,QAAQ,EACf,MAAC,YAAY,eACX,KAAC,WAAW,IAAC,OAAO,kBAClB,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAC,WAAW,YACtC,KAAK,CAAC,WAAW,IAAI,QAAQ,GACvB,GACG,EACd,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,CAAC,SAAS,YACpE,KAAK,CAAC,YAAY,IAAI,SAAS,GACzB,IACI,IACd,CACJ,IACa,IACT,CACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface PaginationMeta {
2
+ totalItems: number;
3
+ currentPage: number;
4
+ totalPages: number;
5
+ itemsPerPage?: number;
6
+ }
7
+ export declare function DataPagination(props: {
8
+ meta: PaginationMeta;
9
+ buildHref?: (page: number, limit: number) => string;
10
+ onPageChange?: (page: number) => void;
11
+ onLimitChange?: (limit: number) => void;
12
+ }): import("react").JSX.Element;
13
+ //# sourceMappingURL=data-pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-pagination.d.ts","sourceRoot":"","sources":["../../src/components/data-pagination.tsx"],"names":[],"mappings":"AAaA,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACpD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC,+BAuIA"}
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { buildPageWindow, pageSizeOptionsFor } from '../pagination.js';
3
+ import { Button } from './ui/button.js';
4
+ import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, } from './ui/pagination.js';
5
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select.js';
6
+ export function DataPagination(props) {
7
+ const currentPage = Math.max(props.meta.currentPage || 1, 1);
8
+ const totalPages = Math.max(props.meta.totalPages || 1, 1);
9
+ const itemsPerPage = props.meta.itemsPerPage != null && props.meta.itemsPerPage > 0
10
+ ? Math.trunc(props.meta.itemsPerPage)
11
+ : 20;
12
+ const totalItems = props.meta.totalItems ?? 0;
13
+ const prevDisabled = currentPage <= 1;
14
+ const nextDisabled = currentPage >= totalPages;
15
+ const goToPage = (page) => {
16
+ if (props.onPageChange) {
17
+ props.onPageChange(page);
18
+ return;
19
+ }
20
+ if (props.buildHref && typeof window !== 'undefined') {
21
+ window.location.assign(props.buildHref(page, itemsPerPage));
22
+ }
23
+ };
24
+ const changeLimit = (limit) => {
25
+ if (props.onLimitChange) {
26
+ props.onLimitChange(limit);
27
+ return;
28
+ }
29
+ if (props.buildHref && typeof window !== 'undefined') {
30
+ window.location.assign(props.buildHref(1, limit));
31
+ }
32
+ };
33
+ const pageHref = (page) => props.buildHref && !props.onPageChange ? props.buildHref(page, itemsPerPage) : '#';
34
+ return (_jsxs("div", { className: "mt-4 flex flex-wrap items-center justify-between gap-3 border-t border-border pt-3", "data-afi-pagination": true, children: [_jsx("p", { className: "m-0 text-sm text-muted-foreground", children: `Page ${currentPage} of ${totalPages} · ${totalItems} items` }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [_jsx("span", { children: "Show" }), _jsxs(Select, { value: String(itemsPerPage), onValueChange: (value) => changeLimit(Number(value)), children: [_jsx(SelectTrigger, { size: "sm", className: "min-w-16", "aria-label": "Page size", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: pageSizeOptionsFor(itemsPerPage).map((size) => (_jsx(SelectItem, { value: String(size), children: size }, size))) })] })] }), _jsx(Pagination, { className: "mx-0 w-auto justify-start", children: _jsxs(PaginationContent, { children: [_jsx(PaginationItem, { children: prevDisabled ? (_jsx(Button, { variant: "ghost", size: "default", disabled: true, children: "Previous" })) : (_jsx(PaginationPrevious, { href: pageHref(currentPage - 1), onClick: (event) => {
35
+ if (props.onPageChange || !props.buildHref) {
36
+ event.preventDefault();
37
+ goToPage(currentPage - 1);
38
+ }
39
+ } })) }), buildPageWindow(currentPage, totalPages).map((item, index) => {
40
+ if (item === 'ellipsis') {
41
+ return (_jsx(PaginationItem, { children: _jsx(PaginationEllipsis, {}) }, `ellipsis-${index}`));
42
+ }
43
+ const isCurrent = item === currentPage;
44
+ return (_jsx(PaginationItem, { children: _jsx(PaginationLink, { href: pageHref(item), isActive: isCurrent, onClick: (event) => {
45
+ if (isCurrent) {
46
+ event.preventDefault();
47
+ return;
48
+ }
49
+ if (props.onPageChange || !props.buildHref) {
50
+ event.preventDefault();
51
+ goToPage(item);
52
+ }
53
+ }, children: item }) }, item));
54
+ }), _jsx(PaginationItem, { children: nextDisabled ? (_jsx(Button, { variant: "ghost", size: "default", disabled: true, children: "Next" })) : (_jsx(PaginationNext, { href: pageHref(currentPage + 1), onClick: (event) => {
55
+ if (props.onPageChange || !props.buildHref) {
56
+ event.preventDefault();
57
+ goToPage(currentPage + 1);
58
+ }
59
+ } })) })] }) })] })] }));
60
+ }
61
+ //# sourceMappingURL=data-pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-pagination.js","sourceRoot":"","sources":["../../src/components/data-pagination.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { SchemaNode } from '@nestjs-dash/support';
2
+ import type { ReactNode } from 'react';
3
+ import type { PaginationMeta } from './data-pagination.js';
4
+ export type SortDirection = 'ASC' | 'DESC';
5
+ export type SortBy = Array<[column: string, direction: SortDirection]>;
6
+ export declare function DataTable(props: {
7
+ columns: SchemaNode[];
8
+ rows: Array<Record<string, unknown>>;
9
+ meta?: PaginationMeta;
10
+ buildHref?: (page: number, limit: number) => string;
11
+ onPageChange?: (page: number) => void;
12
+ onLimitChange?: (limit: number) => void;
13
+ /** Override cell content per column; falls back to the built-in icon/text rendering. */
14
+ renderCell?: (column: SchemaNode, row: Record<string, unknown>) => ReactNode;
15
+ /** When provided, adds a trailing actions column rendered per row. */
16
+ renderRowActions?: (row: Record<string, unknown>) => ReactNode;
17
+ actionsLabel?: string;
18
+ emptyTitle?: string;
19
+ emptyDescription?: string;
20
+ /** Currently active sort, e.g. `[['name', 'ASC']]`. Only affects columns built with `.sortable()`. */
21
+ sortBy?: SortBy;
22
+ /** Build the URL to navigate to when a sortable column header is clicked. */
23
+ buildSortHref?: (column: string, direction: SortDirection) => string;
24
+ /** Handle sort clicks without a page navigation (client-only tables). */
25
+ onSortChange?: (column: string, direction: SortDirection) => void;
26
+ }): import("react").JSX.Element;
27
+ //# sourceMappingURL=data-table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../src/components/data-table.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAsC3D,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAC3C,MAAM,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;AAOvE,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAC/B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACpD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,wFAAwF;IACxF,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,SAAS,CAAC;IAC7E,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,SAAS,CAAC;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sGAAsG;IACtG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,KAAK,MAAM,CAAC;IACrE,yEAAyE;IACzE,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,KAAK,IAAI,CAAC;CACnE,+BA6GA"}
@@ -0,0 +1,82 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { BADGE_COLOR_CLASSES } from '../lib/badge-colors.js';
3
+ import { formatDate, formatRelativeTime, parseDateValue } from '../lib/format-date.js';
4
+ import { DataPagination } from './data-pagination.js';
5
+ import { EmptyState } from './empty-state.js';
6
+ import { Icon } from './icon.js';
7
+ import { Badge } from './ui/badge.js';
8
+ import { Button } from './ui/button.js';
9
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './ui/table.js';
10
+ function defaultCell(column, raw) {
11
+ switch (column.kind) {
12
+ case 'icon-column':
13
+ return raw ? _jsx(Icon, { name: String(raw) }) : null;
14
+ case 'badge-column': {
15
+ if (raw == null || raw === '')
16
+ return null;
17
+ const colors = (column.props.colors ?? {});
18
+ const color = colors[String(raw)];
19
+ return (_jsx(Badge, { variant: "outline", className: color ? BADGE_COLOR_CLASSES[color] : undefined, children: String(raw) }));
20
+ }
21
+ case 'boolean-column':
22
+ return raw ? (_jsx(Icon, { name: "circle-check", className: "text-green-600 dark:text-green-400" })) : (_jsx(Icon, { name: "circle-x", className: "text-red-600 dark:text-red-400" }));
23
+ case 'date-column': {
24
+ const date = parseDateValue(raw);
25
+ if (!date)
26
+ return null;
27
+ return column.props.since ? formatRelativeTime(date) : formatDate(date);
28
+ }
29
+ default:
30
+ return String(raw ?? '');
31
+ }
32
+ }
33
+ function sortDirectionFor(name, sortBy) {
34
+ const entry = sortBy?.find(([column]) => column === name);
35
+ return entry ? entry[1] : null;
36
+ }
37
+ export function DataTable(props) {
38
+ const sortInteractive = Boolean(props.buildSortHref || props.onSortChange);
39
+ function handleSortClick(column, direction) {
40
+ if (props.onSortChange) {
41
+ props.onSortChange(column, direction);
42
+ return;
43
+ }
44
+ if (props.buildSortHref && typeof window !== 'undefined') {
45
+ window.location.assign(props.buildSortHref(column, direction));
46
+ }
47
+ }
48
+ const table = props.rows.length === 0 ? (_jsx(EmptyState, { title: props.emptyTitle ?? 'No records', description: props.emptyDescription ?? 'Create a record to get started.' })) : (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [props.columns.map((column) => {
49
+ const name = String(column.name ?? '');
50
+ const label = String(column.props.label ?? column.name ?? '');
51
+ if (!sortInteractive || column.props.sortable !== true) {
52
+ return _jsx(TableHead, { children: label }, name);
53
+ }
54
+ const current = sortDirectionFor(name, props.sortBy);
55
+ const next = current === 'ASC' ? 'DESC' : 'ASC';
56
+ const href = props.buildSortHref?.(name, next);
57
+ return (_jsx(TableHead, { "aria-sort": current === 'ASC' ? 'ascending' : current === 'DESC' ? 'descending' : 'none', children: _jsx(Button, { asChild: true, variant: "ghost", size: "sm", className: "-ml-3 h-8 has-[>svg]:px-2", children: _jsxs("a", { href: href ?? '#', "data-afi-sort": name, "data-afi-sort-active": current != null, onClick: (event) => {
58
+ // Real href present (SSR link mode): let it navigate natively
59
+ // so sorting still works without JS. Only intercept for the
60
+ // client-callback mode.
61
+ if (props.onSortChange) {
62
+ event.preventDefault();
63
+ handleSortClick(name, next);
64
+ }
65
+ }, children: [label, _jsx(Icon, { name: current === 'ASC'
66
+ ? 'arrow-up'
67
+ : current === 'DESC'
68
+ ? 'arrow-down'
69
+ : 'chevrons-up-down', className: current ? 'text-foreground' : 'text-muted-foreground/60' })] }) }) }, name));
70
+ }), props.renderRowActions ? (_jsx(TableHead, { children: props.actionsLabel ?? 'Actions' })) : null] }) }), _jsx(TableBody, { children: props.rows.map((row, index) => (_jsxs(TableRow, { children: [props.columns.map((column) => {
71
+ if (props.renderCell) {
72
+ return (_jsx(TableCell, { children: props.renderCell(column, row) }, String(column.name)));
73
+ }
74
+ const raw = row[String(column.name)];
75
+ return _jsx(TableCell, { children: defaultCell(column, raw) }, String(column.name));
76
+ }), props.renderRowActions ? _jsx(TableCell, { children: props.renderRowActions(row) }) : null] }, String(row.id ?? index)))) })] }));
77
+ if (!props.meta) {
78
+ return table;
79
+ }
80
+ return (_jsxs("div", { children: [table, _jsx(DataPagination, { meta: props.meta, buildHref: props.buildHref, onPageChange: props.onPageChange, onLimitChange: props.onLimitChange })] }));
81
+ }
82
+ //# sourceMappingURL=data-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-table.js","sourceRoot":"","sources":["../../src/components/data-table.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function EmptyState(props: {
2
+ title: string;
3
+ description?: string;
4
+ }): import("react").JSX.Element;
5
+ //# sourceMappingURL=empty-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"empty-state.d.ts","sourceRoot":"","sources":["../../src/components/empty-state.tsx"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,+BASxE"}
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export function EmptyState(props) {
3
+ return (_jsxs("div", { className: "p-8 text-center text-muted-foreground", "data-slot": "empty-state", children: [_jsx("h3", { className: "text-base font-semibold text-foreground", children: props.title }), props.description ? (_jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: props.description })) : null] }));
4
+ }
5
+ //# sourceMappingURL=empty-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"empty-state.js","sourceRoot":"","sources":["../../src/components/empty-state.tsx"],"names":[],"mappings":";AAAA,MAAM,UAAU,UAAU,CAAC,KAA8C;IACvE,OAAO,CACL,eAAK,SAAS,EAAC,uCAAuC,eAAW,aAAa,aAC5E,aAAI,SAAS,EAAC,yCAAyC,YAAE,KAAK,CAAC,KAAK,GAAM,EACzE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CACnB,YAAG,SAAS,EAAC,oCAAoC,YAAE,KAAK,CAAC,WAAW,GAAK,CAC1E,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ export type FileUploadItem = {
2
+ path?: string;
3
+ url?: string;
4
+ disk?: string;
5
+ fileName?: string;
6
+ mimeType?: string;
7
+ size?: number;
8
+ };
9
+ /**
10
+ * Interactive generic file field: file list, native picker, and a hidden JSON
11
+ * payload input so the surrounding `<form>` POST carries the uploaded items —
12
+ * same pattern as `ImageUploadField`, without the image preview/crop UI.
13
+ */
14
+ export declare function FileUploadField(props: {
15
+ name: string;
16
+ label: string;
17
+ multiple?: boolean;
18
+ maxFiles?: number;
19
+ maxSizeKb?: number;
20
+ accept?: string;
21
+ disk?: string;
22
+ directory?: string;
23
+ visibility?: string;
24
+ required?: boolean;
25
+ defaultValue?: unknown;
26
+ uploadUrl: string;
27
+ }): import("react").JSX.Element;
28
+ //# sourceMappingURL=file-upload-field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-upload-field.d.ts","sourceRoot":"","sources":["../../src/components/file-upload-field.tsx"],"names":[],"mappings":"AAMA,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AA0BF;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB,+BA+GA"}