@timbal-ai/timbal-react 1.5.0 → 1.6.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.
- package/CHANGELOG.md +17 -1
- package/README.md +25 -0
- package/dist/app.cjs +855 -640
- package/dist/app.d.cts +4 -4
- package/dist/app.d.ts +4 -4
- package/dist/app.esm.js +6 -6
- package/dist/{chart-artifact-2OTDTRwM.d.ts → chart-artifact-C2pZQsaP.d.ts} +81 -29
- package/dist/{chart-artifact-CS3qyGIY.d.cts → chart-artifact-VAqgH-My.d.cts} +81 -29
- package/dist/{chat-ClmzWzCX.d.cts → chat-DDsp-Vzz.d.cts} +1 -1
- package/dist/{chat-ClmzWzCX.d.ts → chat-DDsp-Vzz.d.ts} +1 -1
- package/dist/chat.cjs +26 -26
- package/dist/chat.d.cts +3 -3
- package/dist/chat.d.ts +3 -3
- package/dist/chat.esm.js +3 -3
- package/dist/{chunk-TZI3ID3C.esm.js → chunk-24B4I4XC.esm.js} +3 -3
- package/dist/{chunk-SZDYIRMB.esm.js → chunk-6SQMTBPL.esm.js} +618 -530
- package/dist/{chunk-QIABF4KB.esm.js → chunk-ELEY66OH.esm.js} +2 -2
- package/dist/{chunk-WMKPT5BV.esm.js → chunk-HSL36SJ4.esm.js} +6 -6
- package/dist/chunk-JJOO4PR5.esm.js +391 -0
- package/dist/{chunk-AZL2WANO.esm.js → chunk-MBS7XHV2.esm.js} +28 -28
- package/dist/{chunk-5ECRZ5O7.esm.js → chunk-NO5AWNWT.esm.js} +224 -57
- package/dist/{chunk-ZNYAETFD.esm.js → chunk-R4RQT2XQ.esm.js} +2 -2
- package/dist/{chunk-JYDJRGDE.esm.js → chunk-TMP7RIA7.esm.js} +2 -2
- package/dist/{chunk-IGHBLJV3.esm.js → chunk-WQIQW7EM.esm.js} +3 -2
- package/dist/{chunk-B4XAC4G7.esm.js → chunk-YYEI6XME.esm.js} +361 -527
- package/dist/{circular-progress-CDsJwIPF.d.cts → circular-progress-B9nnwzCu.d.cts} +1 -1
- package/dist/{circular-progress-CDsJwIPF.d.ts → circular-progress-B9nnwzCu.d.ts} +1 -1
- package/dist/index.cjs +1327 -852
- package/dist/index.d.cts +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/index.esm.js +40 -20
- package/dist/{kanban-U5xNe9py.d.cts → kanban-FFBeaZPS.d.cts} +4 -4
- package/dist/{kanban-U5xNe9py.d.ts → kanban-FFBeaZPS.d.ts} +4 -4
- package/dist/{layout-B8r6Jbat.d.ts → layout-CuKeSY74.d.ts} +1 -1
- package/dist/{layout-Cu7Ijn04.d.cts → layout-PzVwkJyL.d.cts} +1 -1
- package/dist/site.cjs +71 -0
- package/dist/site.d.cts +15 -1
- package/dist/site.d.ts +15 -1
- package/dist/site.esm.js +12 -311
- package/dist/studio.cjs +31 -31
- package/dist/studio.d.cts +2 -2
- package/dist/studio.d.ts +2 -2
- package/dist/studio.esm.js +7 -7
- package/dist/{timbal-v2-button-B7vPs7gg.d.ts → timbal-v2-button-DCAZNyUx.d.cts} +1 -1
- package/dist/{timbal-v2-button-B7vPs7gg.d.cts → timbal-v2-button-DCAZNyUx.d.ts} +1 -1
- package/dist/ui.cjs +77 -77
- package/dist/ui.d.cts +3 -3
- package/dist/ui.d.ts +3 -3
- package/dist/ui.esm.js +15 -15
- package/dist/{welcome-NXZlcihe.d.cts → welcome-B00oH5Io.d.cts} +1 -1
- package/dist/{welcome-DduQAC4K.d.ts → welcome-DU-4NTjZ.d.ts} +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -38,7 +38,7 @@ __export(index_exports, {
|
|
|
38
38
|
AccordionContent: () => AccordionContent,
|
|
39
39
|
AccordionItem: () => AccordionItem,
|
|
40
40
|
AccordionTrigger: () => AccordionTrigger,
|
|
41
|
-
ActionBarPrimitive: () =>
|
|
41
|
+
ActionBarPrimitive: () => import_react84.ActionBarPrimitive,
|
|
42
42
|
Alert: () => Alert,
|
|
43
43
|
AlertDescription: () => AlertDescription,
|
|
44
44
|
AlertDialog: () => AlertDialog,
|
|
@@ -63,8 +63,8 @@ __export(index_exports, {
|
|
|
63
63
|
ArtifactRegistryProvider: () => ArtifactRegistryProvider,
|
|
64
64
|
ArtifactView: () => ArtifactView,
|
|
65
65
|
AspectRatio: () => AspectRatio,
|
|
66
|
-
AssistantRuntimeProvider: () =>
|
|
67
|
-
AuiIf: () =>
|
|
66
|
+
AssistantRuntimeProvider: () => import_react84.AssistantRuntimeProvider,
|
|
67
|
+
AuiIf: () => import_react84.AuiIf,
|
|
68
68
|
AuthGuard: () => AuthGuard,
|
|
69
69
|
Avatar: () => Avatar,
|
|
70
70
|
AvatarFallback: () => AvatarFallback,
|
|
@@ -121,7 +121,7 @@ __export(index_exports, {
|
|
|
121
121
|
CommandSeparator: () => CommandSeparator,
|
|
122
122
|
CommandShortcut: () => CommandShortcut,
|
|
123
123
|
Composer: () => Composer,
|
|
124
|
-
ComposerPrimitive: () =>
|
|
124
|
+
ComposerPrimitive: () => import_react84.ComposerPrimitive,
|
|
125
125
|
ConnectionRow: () => ConnectionRow,
|
|
126
126
|
ConnectionRowList: () => ConnectionRowList,
|
|
127
127
|
ContextMenu: () => ContextMenu,
|
|
@@ -140,6 +140,7 @@ __export(index_exports, {
|
|
|
140
140
|
ContextMenuTrigger: () => ContextMenuTrigger,
|
|
141
141
|
CopyButton: () => CopyButton,
|
|
142
142
|
DEFAULT_UPLOAD_ACCEPT: () => DEFAULT_UPLOAD_ACCEPT,
|
|
143
|
+
DURATION: () => DURATION,
|
|
143
144
|
DangerZone: () => DangerZone,
|
|
144
145
|
DangerZoneAction: () => DangerZoneAction,
|
|
145
146
|
DataTable: () => DataTable,
|
|
@@ -173,6 +174,7 @@ __export(index_exports, {
|
|
|
173
174
|
DropdownMenuSubContent: () => DropdownMenuSubContent,
|
|
174
175
|
DropdownMenuSubTrigger: () => DropdownMenuSubTrigger,
|
|
175
176
|
DropdownMenuTrigger: () => DropdownMenuTrigger,
|
|
177
|
+
EASE: () => EASE,
|
|
176
178
|
EmptyState: () => EmptyState,
|
|
177
179
|
ExpandableSection: () => ExpandableSection,
|
|
178
180
|
Field: () => Field,
|
|
@@ -218,7 +220,9 @@ __export(index_exports, {
|
|
|
218
220
|
KbdGroup: () => KbdGroup,
|
|
219
221
|
Label: () => Label3,
|
|
220
222
|
LineAreaChart: () => LineAreaChart,
|
|
223
|
+
Magnetic: () => Magnetic,
|
|
221
224
|
MarkdownText: () => MarkdownText,
|
|
225
|
+
Marquee: () => Marquee,
|
|
222
226
|
MemoPillSegmentedTabs: () => MemoPillSegmentedTabs,
|
|
223
227
|
Menubar: () => Menubar,
|
|
224
228
|
MenubarCheckboxItem: () => MenubarCheckboxItem,
|
|
@@ -234,7 +238,7 @@ __export(index_exports, {
|
|
|
234
238
|
MenubarSubContent: () => MenubarSubContent,
|
|
235
239
|
MenubarSubTrigger: () => MenubarSubTrigger,
|
|
236
240
|
MenubarTrigger: () => MenubarTrigger,
|
|
237
|
-
MessagePrimitive: () =>
|
|
241
|
+
MessagePrimitive: () => import_react84.MessagePrimitive,
|
|
238
242
|
MetricChartCard: () => MetricChartCard,
|
|
239
243
|
MetricRow: () => MetricRow,
|
|
240
244
|
MetricTile: () => MetricTile,
|
|
@@ -257,6 +261,7 @@ __export(index_exports, {
|
|
|
257
261
|
PaginationLink: () => PaginationLink,
|
|
258
262
|
PaginationNext: () => PaginationNext,
|
|
259
263
|
PaginationPrevious: () => PaginationPrevious,
|
|
264
|
+
Parallax: () => Parallax,
|
|
260
265
|
PieChart: () => PieChart,
|
|
261
266
|
PillSegmentedTabs: () => PillSegmentedTabs,
|
|
262
267
|
PlanBadge: () => PlanBadge,
|
|
@@ -273,8 +278,11 @@ __export(index_exports, {
|
|
|
273
278
|
RadioGroupItem: () => RadioGroupItem,
|
|
274
279
|
Rating: () => Rating,
|
|
275
280
|
ResourceCard: () => ResourceCard,
|
|
281
|
+
Reveal: () => Reveal,
|
|
276
282
|
SEMANTIC_COLOR_TOKENS: () => SEMANTIC_COLOR_TOKENS,
|
|
283
|
+
SITE_AGENT_INSTRUCTIONS: () => SITE_AGENT_INSTRUCTIONS,
|
|
277
284
|
SLOP_BUDGETS: () => SLOP_BUDGETS,
|
|
285
|
+
SPRING: () => SPRING,
|
|
278
286
|
STUDIO_NAV_MODE: () => STUDIO_NAV_MODE,
|
|
279
287
|
ScrollArea: () => ScrollArea,
|
|
280
288
|
ScrollBar: () => ScrollBar,
|
|
@@ -334,9 +342,10 @@ __export(index_exports, {
|
|
|
334
342
|
TableHeader: () => TableHeader,
|
|
335
343
|
TableRow: () => TableRow,
|
|
336
344
|
TagInput: () => TagInput,
|
|
345
|
+
TextReveal: () => TextReveal,
|
|
337
346
|
Textarea: () => Textarea,
|
|
338
347
|
Thread: () => Thread,
|
|
339
|
-
ThreadPrimitive: () =>
|
|
348
|
+
ThreadPrimitive: () => import_react84.ThreadPrimitive,
|
|
340
349
|
TimbalChat: () => TimbalChat,
|
|
341
350
|
TimbalChatShell: () => TimbalChatShell,
|
|
342
351
|
TimbalMark: () => TimbalMark,
|
|
@@ -435,15 +444,15 @@ __export(index_exports, {
|
|
|
435
444
|
useAppShellChat: () => useAppShellChat,
|
|
436
445
|
useAppShellNav: () => useAppShellNav,
|
|
437
446
|
useArtifactRegistry: () => useArtifactRegistry,
|
|
438
|
-
useComposerRuntime: () =>
|
|
447
|
+
useComposerRuntime: () => import_react84.useComposerRuntime,
|
|
439
448
|
useInterval: () => useInterval,
|
|
440
449
|
useLiveQuery: () => useLiveQuery,
|
|
441
|
-
useMessageRuntime: () =>
|
|
450
|
+
useMessageRuntime: () => import_react84.useMessageRuntime,
|
|
442
451
|
useOptionalSession: () => useOptionalSession,
|
|
443
452
|
useResolvedSuggestions: () => useResolvedSuggestions,
|
|
444
453
|
useSession: () => useSession,
|
|
445
|
-
useThread: () =>
|
|
446
|
-
useThreadRuntime: () =>
|
|
454
|
+
useThread: () => import_react84.useThread,
|
|
455
|
+
useThreadRuntime: () => import_react84.useThreadRuntime,
|
|
447
456
|
useTimbalRuntime: () => useTimbalRuntime,
|
|
448
457
|
useTimbalStream: () => useTimbalStream,
|
|
449
458
|
useToast: () => useToast,
|
|
@@ -1413,22 +1422,22 @@ var TIMBAL_V2_MODAL_SURFACE = cn(
|
|
|
1413
1422
|
);
|
|
1414
1423
|
var TIMBAL_V2_PRIMARY_GRADIENT = "bg-gradient-to-b from-primary-fill-from to-primary-fill-to";
|
|
1415
1424
|
var TIMBAL_V2_SIZE_HEIGHT = {
|
|
1416
|
-
xs: "min-h-
|
|
1417
|
-
sm: "min-h-
|
|
1418
|
-
md: "min-h-
|
|
1419
|
-
lg: "min-h-
|
|
1425
|
+
xs: "min-h-7 h-7",
|
|
1426
|
+
sm: "min-h-8 h-8",
|
|
1427
|
+
md: "min-h-9 h-9",
|
|
1428
|
+
lg: "min-h-10 h-10"
|
|
1420
1429
|
};
|
|
1421
1430
|
var TIMBAL_V2_SIZE_ICON = {
|
|
1422
|
-
xs: "min-h-
|
|
1431
|
+
xs: "min-h-7 min-w-7 size-7",
|
|
1423
1432
|
sm: "min-h-8 min-w-8 size-8",
|
|
1424
|
-
md: "min-h-
|
|
1425
|
-
lg: "min-h-
|
|
1433
|
+
md: "min-h-9 min-w-9 size-9",
|
|
1434
|
+
lg: "min-h-10 min-w-10 size-10"
|
|
1426
1435
|
};
|
|
1427
1436
|
var TIMBAL_V2_SIZE_LABEL_PX = {
|
|
1428
|
-
xs: "px-
|
|
1429
|
-
sm: "px-
|
|
1430
|
-
md: "px-5",
|
|
1431
|
-
lg: "px-
|
|
1437
|
+
xs: "px-2.5",
|
|
1438
|
+
sm: "px-3",
|
|
1439
|
+
md: "px-3.5",
|
|
1440
|
+
lg: "px-4.5"
|
|
1432
1441
|
};
|
|
1433
1442
|
var TIMBAL_V2_FILL = {
|
|
1434
1443
|
primary: [
|
|
@@ -1595,7 +1604,7 @@ function DialogContent({
|
|
|
1595
1604
|
"data-slot": "dialog-content",
|
|
1596
1605
|
className: cn(
|
|
1597
1606
|
TIMBAL_V2_MODAL_SURFACE,
|
|
1598
|
-
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-[70] grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-xl p-
|
|
1607
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-[70] grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-xl p-5 duration-200 outline-none sm:max-w-lg",
|
|
1599
1608
|
className
|
|
1600
1609
|
),
|
|
1601
1610
|
...props,
|
|
@@ -1692,9 +1701,9 @@ function avatarChartVariantClass(_seed) {
|
|
|
1692
1701
|
return AVATAR_PRIMARY_FALLBACK_CLASS;
|
|
1693
1702
|
}
|
|
1694
1703
|
var AVATAR_SIZE_CLASS = {
|
|
1695
|
-
default: "size-
|
|
1696
|
-
sm: "size-
|
|
1697
|
-
lg: "size-
|
|
1704
|
+
default: "size-7",
|
|
1705
|
+
sm: "size-5",
|
|
1706
|
+
lg: "size-9"
|
|
1698
1707
|
};
|
|
1699
1708
|
function Avatar({
|
|
1700
1709
|
className,
|
|
@@ -3875,16 +3884,16 @@ var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
|
3875
3884
|
)
|
|
3876
3885
|
},
|
|
3877
3886
|
size: {
|
|
3878
|
-
xs: "h-
|
|
3879
|
-
sm: "h-
|
|
3880
|
-
md: "h-
|
|
3881
|
-
lg: "h-
|
|
3882
|
-
xl: "h-
|
|
3883
|
-
default: "h-
|
|
3884
|
-
icon: "h-
|
|
3885
|
-
"icon-xs": "h-
|
|
3886
|
-
"icon-sm": "h-
|
|
3887
|
-
"icon-lg": "h-
|
|
3887
|
+
xs: "h-7 gap-1 rounded-md px-2 text-xs",
|
|
3888
|
+
sm: "h-8 gap-1 rounded-md px-2.5 text-xs",
|
|
3889
|
+
md: "h-9 gap-1.5 rounded-lg px-3 text-sm",
|
|
3890
|
+
lg: "h-10 gap-1.5 rounded-lg px-3.5 text-sm",
|
|
3891
|
+
xl: "h-11 gap-2 rounded-lg px-4 text-base",
|
|
3892
|
+
default: "h-9 gap-1.5 rounded-lg px-3 text-sm",
|
|
3893
|
+
icon: "h-9 w-9 rounded-lg",
|
|
3894
|
+
"icon-xs": "h-7 w-7 rounded-md",
|
|
3895
|
+
"icon-sm": "h-8 w-8 rounded-md",
|
|
3896
|
+
"icon-lg": "h-10 w-10 rounded-lg"
|
|
3888
3897
|
},
|
|
3889
3898
|
shape: {
|
|
3890
3899
|
pill: "rounded-full!",
|
|
@@ -4141,7 +4150,7 @@ var BadgeNode = ({ node }) => {
|
|
|
4141
4150
|
"span",
|
|
4142
4151
|
{
|
|
4143
4152
|
className: cn(
|
|
4144
|
-
"aui-ui-badge inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium",
|
|
4153
|
+
"aui-ui-badge inline-flex w-fit shrink-0 items-center rounded-full px-2 py-0.5 text-xs font-medium",
|
|
4145
4154
|
BADGE_TONE[node.tone ?? "default"],
|
|
4146
4155
|
node.className
|
|
4147
4156
|
),
|
|
@@ -5790,8 +5799,8 @@ var import_lucide_react9 = require("lucide-react");
|
|
|
5790
5799
|
|
|
5791
5800
|
// src/design/control-surface.ts
|
|
5792
5801
|
var CONTROL_SIZE = {
|
|
5793
|
-
sm: "h-
|
|
5794
|
-
default: "h-
|
|
5802
|
+
sm: "h-8 px-2.5",
|
|
5803
|
+
default: "h-9 px-3"
|
|
5795
5804
|
};
|
|
5796
5805
|
var CONTROL_SHAPE = {
|
|
5797
5806
|
field: "rounded-lg",
|
|
@@ -5819,7 +5828,7 @@ var overlayListPanelClass = cn(
|
|
|
5819
5828
|
overlaySurfaceClass,
|
|
5820
5829
|
"overflow-hidden rounded-lg p-0 outline-hidden"
|
|
5821
5830
|
);
|
|
5822
|
-
var overlayItemClass = "relative flex cursor-default items-center gap-2 rounded-md px-2 py-1
|
|
5831
|
+
var overlayItemClass = "relative flex cursor-default items-center gap-2 rounded-md px-2 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground";
|
|
5823
5832
|
|
|
5824
5833
|
// src/chat/workforce-selector.tsx
|
|
5825
5834
|
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
@@ -5944,8 +5953,8 @@ var SIDEBAR_MOBILE_PX = 272;
|
|
|
5944
5953
|
var SIDEBAR_GAP_PX = 12;
|
|
5945
5954
|
var SIDEBAR_CONTENT_GAP_PX = 8;
|
|
5946
5955
|
var TOPBAR_GAP_PX = 8;
|
|
5947
|
-
var TOPBAR_HEIGHT_PX =
|
|
5948
|
-
var PILL_HEIGHT_PX =
|
|
5956
|
+
var TOPBAR_HEIGHT_PX = 44;
|
|
5957
|
+
var PILL_HEIGHT_PX = 36;
|
|
5949
5958
|
var SIDEBAR_INSET_PX_EXPANDED = SIDEBAR_GAP_PX + SIDEBAR_WIDTH_PX + SIDEBAR_CONTENT_GAP_PX;
|
|
5950
5959
|
var SIDEBAR_INSET_PX_COLLAPSED = SIDEBAR_GAP_PX + SIDEBAR_WIDTH_COLLAPSED_PX + SIDEBAR_CONTENT_GAP_PX;
|
|
5951
5960
|
var px = (n) => `${n / 16}rem`;
|
|
@@ -6526,7 +6535,7 @@ function DropdownMenuCheckboxItem({
|
|
|
6526
6535
|
import_radix_ui6.DropdownMenu.CheckboxItem,
|
|
6527
6536
|
{
|
|
6528
6537
|
"data-slot": "dropdown-menu-checkbox-item",
|
|
6529
|
-
className: cn(overlayItemClass, "py-1
|
|
6538
|
+
className: cn(overlayItemClass, "py-1 pr-2 pl-8", className),
|
|
6530
6539
|
checked,
|
|
6531
6540
|
...props,
|
|
6532
6541
|
children: [
|
|
@@ -6556,7 +6565,7 @@ function DropdownMenuRadioItem({
|
|
|
6556
6565
|
import_radix_ui6.DropdownMenu.RadioItem,
|
|
6557
6566
|
{
|
|
6558
6567
|
"data-slot": "dropdown-menu-radio-item",
|
|
6559
|
-
className: cn(overlayItemClass, "py-1
|
|
6568
|
+
className: cn(overlayItemClass, "py-1 pr-2 pl-8", className),
|
|
6560
6569
|
...props,
|
|
6561
6570
|
children: [
|
|
6562
6571
|
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_radix_ui6.DropdownMenu.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react10.CircleIcon, { className: "size-2 fill-current" }) }) }),
|
|
@@ -7810,10 +7819,10 @@ var pillSegmentedTrackFlushClass = cn(
|
|
|
7810
7819
|
"h-[var(--studio-chrome-pill-height)] items-center gap-0.5 overflow-visible p-0.5"
|
|
7811
7820
|
);
|
|
7812
7821
|
var pillSegmentedSegmentClass = cn(
|
|
7813
|
-
"relative flex items-center gap-1.5 rounded-full px-
|
|
7822
|
+
"relative flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-normal transition-colors"
|
|
7814
7823
|
);
|
|
7815
7824
|
var pillSegmentedFlushSegmentClass = cn(
|
|
7816
|
-
"relative box-border inline-flex h-
|
|
7825
|
+
"relative box-border inline-flex h-8 min-h-8 items-center justify-center gap-1.5 rounded-full px-3 py-0",
|
|
7817
7826
|
"text-sm font-normal leading-tight transition-colors"
|
|
7818
7827
|
);
|
|
7819
7828
|
var pillSegmentedActiveIndicatorClass = cn(
|
|
@@ -8224,7 +8233,7 @@ Presentational groups \u2014 import from the package root, not from these paths:
|
|
|
8224
8233
|
|
|
8225
8234
|
| Folder | Components |
|
|
8226
8235
|
|--------|------------|
|
|
8227
|
-
| \`data/\` | \`MetricRow\`, \`MetricChartCard\`, \`MetricTile\`, \`DataTable\`, \`FilterBar\`, \`FilterField\`, \`ChartPanel\` |
|
|
8236
|
+
| \`data/\` | \`MetricRow\`, \`MetricChartCard\`, \`MetricTile\`, \`DataTable\`, \`FilterBar\`, \`FilterField\`, \`FilterDropdown\`, \`ChartPanel\` |
|
|
8228
8237
|
| \`integrations/\` | \`IntegrationCard\`, \`ConnectionRow\`, \`ConnectionRowList\`, \`IntegrationsEmptyState\`, \`PlanBadge\` |
|
|
8229
8238
|
| \`settings/\` | \`SettingsSection\`, \`FieldRow\`, \`DangerZone\`, \`FloatingUnsavedChangesBar\` |
|
|
8230
8239
|
| \`surfaces/\` | \`StatTile\`, \`InfoCard\`, \`AlertCard\`, \`CatalogCard\`, \`ResourceCard\`, \`DescriptionList\`, \`ExpandableSection\`, \`StatusDot\`, \`StatusBadge\`, \`EmptyState\` |
|
|
@@ -8293,6 +8302,7 @@ The cause of slop is dropping **below** the curated block layer into raw primiti
|
|
|
8293
8302
|
| \`StatusBadge\` | Status pill: \`tone\` (\`default\`\\|\`primary\`\\|\`success\`\\|\`warn\`\\|\`danger\`\\|\`muted\`), children. Use \`danger\` for critical/error severity. |
|
|
8294
8303
|
| \`FilterBar\` | Horizontal filter row \u2014 bottom-aligns controls. Mix \`SearchInput\` with labeled \`FilterField\` + \`Select\` (or \`Field\` + \`Select\`); labels sit above, control baselines match. |
|
|
8295
8304
|
| \`FilterField\` | Optional label wrapper for a filter control inside \`FilterBar\` (severity, status, \u2026). Omit \`label\` for search-only fields. |
|
|
8305
|
+
| \`FilterDropdown\` | Single-button **multi-facet** filter popover for dense list/table views \u2014 **data-driven**: pass \`fields\` describing your **actual columns** (each \`{ id, label, type }\` where \`type\` is \`multiselect\` \\| \`text\` \\| \`daterange\` \\| \`numeric\`; \`multiselect\` takes \`options: [{ value, label, hint?, icon? }]\`). State is keyed by field \`id\` \u2014 controlled (\`value\` + \`onChange\`) or uncontrolled (\`defaultValue\`). Renders **removable active-filter pills** next to the trigger by default (\`showActiveChips\`); wire \`onChange\` to actually filter your rows. **Always derive \`fields\` from the table's columns/data; never ship the default example facets.** Use when one \`FilterBar\` row isn't enough. |
|
|
8296
8306
|
| \`SearchInput\` | Filter field with consistent app styling. |
|
|
8297
8307
|
| \`DataTable\` | Sortable table: \`columns\`, \`rows\`, \`getRowKey\`, optional \`sort\` / \`onSortChange\`, \`emptyTitle\`, \`showRowCount\`, \`caption\`, \`truncate: true\` on columns with long text. **Scales:** \`pageSize\` (built-in client pager), \`selectable\` + \`onSelectionChange\` (checkbox column for bulk actions), \`loading\` (skeleton rows). \`onRowClick\` for row \u2192 detail (open a \`Sheet\`). |
|
|
8298
8308
|
| \`Avatar\` / \`AvatarFallback\` | User initials: \`variant="secondary"\` (or \`primary\` / \`chart\` alias) on **both** \`Avatar\` and \`AvatarFallback\` \u2014 same chrome as catalog **Action** buttons (\`Button variant="secondary"\`: elevated gradient, \`border-border\`, \`shadow-card\`, \`text-foreground\`). Never dark primary CTA fill or raw \`bg-blue-600\`. |
|
|
@@ -8351,6 +8361,21 @@ Charts run on **recharts** with shadcn \`ChartContainer\` / \`ChartTooltipConten
|
|
|
8351
8361
|
| \`Banner\` | Page-level announcement bar: \`tone\` (\`default\`\\|\`primary\`\\|\`success\`\\|\`warn\`\\|\`danger\`), \`icon\`, \`title\`, body as children, right-aligned \`actions\`, \`onDismiss\` (renders the dismiss X). For in-form/field messages use \`InfoCard\` or \`Alert\` instead. |
|
|
8352
8362
|
| \`Timeline\` | Vertical event log: \`items: [{ id, title, description?, meta?, tone?, icon? }]\`. Presentational \u2014 pass already-formatted timestamps in \`meta\`. |
|
|
8353
8363
|
|
|
8364
|
+
#### More \`/ui\` primitives (import from \`/ui\` or the package root)
|
|
8365
|
+
|
|
8366
|
+
These ship in the same design system but aren't re-exported from \`/app\`. Reach for them before hand-rolling \u2014 they're all dependency-free and on the shared tokens / control surface.
|
|
8367
|
+
|
|
8368
|
+
| Component | Use for |
|
|
8369
|
+
|-----------|---------|
|
|
8370
|
+
| \`Stepper\` | Ordered step indicator for wizards / onboarding (horizontal or vertical; complete / active / upcoming states). |
|
|
8371
|
+
| \`Rating\` | Star rating \u2014 interactive (keyboard + hover preview) or \`readOnly\`; controlled or uncontrolled. |
|
|
8372
|
+
| \`NumberField\` | Numeric input with \u2212/+ steppers on the control surface; clamps to \`min\`/\`max\`, steps by \`step\`. |
|
|
8373
|
+
| \`TagInput\` | Chips / token input; commits on Enter/comma, removes on Backspace, optional \`dedupe\`/\`max\`. |
|
|
8374
|
+
| \`AvatarGroup\` | Overlapping avatar stack with an optional \`+N\` overflow chip (\`max\`, \`spacing\`). |
|
|
8375
|
+
| \`CircularProgress\` | Lightweight SVG progress ring \u2014 determinate (optional center label) or indeterminate. |
|
|
8376
|
+
| \`CopyButton\` | Click-to-copy with a transient check confirmation; icon-only or with a label. |
|
|
8377
|
+
| \`Snippet\` | Single-line code / command on the elevated surface with a built-in copy button. |
|
|
8378
|
+
|
|
8354
8379
|
Studio chrome (\`StudioSidebar\`, \`ModeToggle\`, \u2026) lives in \`@timbal-ai/timbal-react/studio\` \u2014 optional, not required for every dashboard.
|
|
8355
8380
|
|
|
8356
8381
|
### Block recipes \u2014 compose these (don't clone wholesale)
|
|
@@ -8417,6 +8442,7 @@ import {
|
|
|
8417
8442
|
DataTable,
|
|
8418
8443
|
FilterBar,
|
|
8419
8444
|
FilterField,
|
|
8445
|
+
FilterDropdown,
|
|
8420
8446
|
AlertCard,
|
|
8421
8447
|
CatalogCard,
|
|
8422
8448
|
} from "@timbal-ai/timbal-react/app";
|
|
@@ -9612,30 +9638,36 @@ var Sparkline = ({
|
|
|
9612
9638
|
height = 28,
|
|
9613
9639
|
strokeWidth = 1.5,
|
|
9614
9640
|
className,
|
|
9615
|
-
ariaLabel = "Trend"
|
|
9641
|
+
ariaLabel = "Trend",
|
|
9642
|
+
interactive = false,
|
|
9643
|
+
labels,
|
|
9644
|
+
formatValue
|
|
9616
9645
|
}) => {
|
|
9617
9646
|
const uid = (0, import_react57.useId)();
|
|
9647
|
+
const containerRef = (0, import_react57.useRef)(null);
|
|
9648
|
+
const [activeIndex, setActiveIndex] = (0, import_react57.useState)(null);
|
|
9618
9649
|
const values = data.map((d) => typeof d === "number" ? d : toNum(d[dataKey]));
|
|
9619
9650
|
if (values.length === 0) {
|
|
9620
9651
|
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: cn("inline-block", className), style: { width, height } });
|
|
9621
9652
|
}
|
|
9622
|
-
const
|
|
9653
|
+
const padX = 0;
|
|
9654
|
+
const padY = strokeWidth + 1;
|
|
9623
9655
|
const min = Math.min(...values);
|
|
9624
9656
|
const max = Math.max(...values);
|
|
9625
9657
|
const range = max - min || 1;
|
|
9626
|
-
const innerW = width -
|
|
9627
|
-
const innerH = height -
|
|
9658
|
+
const innerW = width - padX * 2;
|
|
9659
|
+
const innerH = height - padY * 2;
|
|
9628
9660
|
const points = values.map((v, i) => ({
|
|
9629
|
-
x:
|
|
9630
|
-
y:
|
|
9661
|
+
x: padX + (values.length > 1 ? i / (values.length - 1) * innerW : innerW / 2),
|
|
9662
|
+
y: padY + innerH - (v - min) / range * innerH
|
|
9631
9663
|
}));
|
|
9632
|
-
|
|
9664
|
+
const svg = /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
9633
9665
|
"svg",
|
|
9634
9666
|
{
|
|
9635
9667
|
width,
|
|
9636
9668
|
height,
|
|
9637
9669
|
viewBox: `0 0 ${width} ${height}`,
|
|
9638
|
-
className: cn("block", className),
|
|
9670
|
+
className: cn("block", interactive ? "h-full w-full" : className),
|
|
9639
9671
|
role: "img",
|
|
9640
9672
|
"aria-label": ariaLabel,
|
|
9641
9673
|
preserveAspectRatio: "none",
|
|
@@ -9645,7 +9677,7 @@ var Sparkline = ({
|
|
|
9645
9677
|
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("stop", { offset: "0%", style: { stopColor: color, stopOpacity: 0.25 } }),
|
|
9646
9678
|
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("stop", { offset: "100%", style: { stopColor: color, stopOpacity: 0 } })
|
|
9647
9679
|
] }) }),
|
|
9648
|
-
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("path", { d: monotoneAreaPath(points, height -
|
|
9680
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("path", { d: monotoneAreaPath(points, height - padY), fill: `url(#${uid}-spark)` })
|
|
9649
9681
|
] }),
|
|
9650
9682
|
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9651
9683
|
"path",
|
|
@@ -9657,7 +9689,81 @@ var Sparkline = ({
|
|
|
9657
9689
|
strokeLinecap: "round",
|
|
9658
9690
|
strokeLinejoin: "round"
|
|
9659
9691
|
}
|
|
9660
|
-
)
|
|
9692
|
+
),
|
|
9693
|
+
interactive && activeIndex != null && points[activeIndex] ? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
|
|
9694
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9695
|
+
"line",
|
|
9696
|
+
{
|
|
9697
|
+
x1: points[activeIndex].x,
|
|
9698
|
+
x2: points[activeIndex].x,
|
|
9699
|
+
y1: 0,
|
|
9700
|
+
y2: height,
|
|
9701
|
+
stroke: color,
|
|
9702
|
+
strokeWidth: 1,
|
|
9703
|
+
strokeOpacity: 0.3,
|
|
9704
|
+
vectorEffect: "non-scaling-stroke"
|
|
9705
|
+
}
|
|
9706
|
+
),
|
|
9707
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9708
|
+
"circle",
|
|
9709
|
+
{
|
|
9710
|
+
cx: points[activeIndex].x,
|
|
9711
|
+
cy: points[activeIndex].y,
|
|
9712
|
+
r: 2.75,
|
|
9713
|
+
fill: color,
|
|
9714
|
+
stroke: "var(--background, #fff)",
|
|
9715
|
+
strokeWidth: 1.5,
|
|
9716
|
+
vectorEffect: "non-scaling-stroke"
|
|
9717
|
+
}
|
|
9718
|
+
)
|
|
9719
|
+
] }) : null
|
|
9720
|
+
]
|
|
9721
|
+
}
|
|
9722
|
+
);
|
|
9723
|
+
if (!interactive) return svg;
|
|
9724
|
+
const onMove = (e) => {
|
|
9725
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
9726
|
+
if (rect.width === 0) return;
|
|
9727
|
+
const fraction = (e.clientX - rect.left) / rect.width;
|
|
9728
|
+
const index = Math.max(
|
|
9729
|
+
0,
|
|
9730
|
+
Math.min(values.length - 1, Math.round(fraction * (values.length - 1)))
|
|
9731
|
+
);
|
|
9732
|
+
setActiveIndex(index);
|
|
9733
|
+
};
|
|
9734
|
+
const active = activeIndex != null ? points[activeIndex] : null;
|
|
9735
|
+
const formattedValue = activeIndex != null ? formatValue ? formatValue(values[activeIndex], activeIndex) : formatCompact(values[activeIndex]) : null;
|
|
9736
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
9737
|
+
"span",
|
|
9738
|
+
{
|
|
9739
|
+
ref: containerRef,
|
|
9740
|
+
className: cn("relative block touch-none", className),
|
|
9741
|
+
style: { width: "100%", height: "100%" },
|
|
9742
|
+
onPointerMove: onMove,
|
|
9743
|
+
onPointerLeave: () => setActiveIndex(null),
|
|
9744
|
+
children: [
|
|
9745
|
+
svg,
|
|
9746
|
+
active ? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
9747
|
+
"span",
|
|
9748
|
+
{
|
|
9749
|
+
"aria-hidden": true,
|
|
9750
|
+
className: cn(
|
|
9751
|
+
"pointer-events-none absolute z-30 -translate-x-1/2 -translate-y-full whitespace-nowrap",
|
|
9752
|
+
"rounded-xl border px-3 py-2 text-[11px] font-medium leading-none tabular-nums shadow-[0_12px_40px_-10px_rgba(0,0,0,0.55)]",
|
|
9753
|
+
"border-white/10 bg-gradient-to-b from-neutral-800 to-neutral-950 text-white",
|
|
9754
|
+
"dark:border-black/10 dark:from-white dark:to-neutral-100 dark:text-neutral-900"
|
|
9755
|
+
),
|
|
9756
|
+
style: {
|
|
9757
|
+
left: `${active.x / width * 100}%`,
|
|
9758
|
+
top: `${active.y / height * 100}%`,
|
|
9759
|
+
marginTop: -8
|
|
9760
|
+
},
|
|
9761
|
+
children: [
|
|
9762
|
+
labels?.[activeIndex] != null ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "mr-1.5 text-neutral-300 dark:text-neutral-500", children: labels[activeIndex] }) : null,
|
|
9763
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { children: formattedValue })
|
|
9764
|
+
]
|
|
9765
|
+
}
|
|
9766
|
+
) : null
|
|
9661
9767
|
]
|
|
9662
9768
|
}
|
|
9663
9769
|
);
|
|
@@ -9675,6 +9781,15 @@ var inlineTrendToneClass = {
|
|
|
9675
9781
|
down: "text-rose-500/90 dark:text-rose-400/95 font-medium",
|
|
9676
9782
|
neutral: "text-muted-foreground/80"
|
|
9677
9783
|
};
|
|
9784
|
+
var sparklineToneColor = {
|
|
9785
|
+
up: "var(--primary, #3b82f6)",
|
|
9786
|
+
down: "var(--destructive, #f43f5e)",
|
|
9787
|
+
neutral: "var(--muted-foreground, #64748b)"
|
|
9788
|
+
};
|
|
9789
|
+
var sparklineBandBleed = {
|
|
9790
|
+
default: "-mx-4 -mb-3 h-10",
|
|
9791
|
+
compact: "-mx-3 -mb-2 h-8"
|
|
9792
|
+
};
|
|
9678
9793
|
var activeToneClass = {
|
|
9679
9794
|
default: "bg-foreground dark:bg-white",
|
|
9680
9795
|
primary: "bg-primary",
|
|
@@ -9704,8 +9819,10 @@ var MetricTile = ({
|
|
|
9704
9819
|
ariaLabel,
|
|
9705
9820
|
className
|
|
9706
9821
|
}) => {
|
|
9822
|
+
const density = useAppDensity();
|
|
9707
9823
|
const metricTileBaseClass = useAppDensityClass("metricTile");
|
|
9708
9824
|
const hasSparkline = Boolean(sparkline || sparklineData);
|
|
9825
|
+
const bandBleed = sparklineBandBleed[density === "compact" ? "compact" : "default"];
|
|
9709
9826
|
const content = /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_jsx_runtime61.Fragment, { children: [
|
|
9710
9827
|
active ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
9711
9828
|
"span",
|
|
@@ -9717,17 +9834,6 @@ var MetricTile = ({
|
|
|
9717
9834
|
)
|
|
9718
9835
|
}
|
|
9719
9836
|
) : null,
|
|
9720
|
-
hasSparkline ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "absolute inset-x-0 bottom-0.5 h-9 w-full overflow-hidden pointer-events-none z-0 opacity-45 dark:opacity-35 select-none", children: sparkline ?? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
9721
|
-
Sparkline,
|
|
9722
|
-
{
|
|
9723
|
-
data: sparklineData,
|
|
9724
|
-
width: 160,
|
|
9725
|
-
height: 36,
|
|
9726
|
-
className: "w-full h-full",
|
|
9727
|
-
color: trendTone === "up" ? "var(--primary, #3b82f6)" : trendTone === "down" ? "var(--destructive, #f43f5e)" : "var(--muted-foreground, #64748b)",
|
|
9728
|
-
...sparklineConfig
|
|
9729
|
-
}
|
|
9730
|
-
) }) : null,
|
|
9731
9837
|
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "relative z-10 flex flex-col gap-1 w-full text-left", children: [
|
|
9732
9838
|
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-xs font-semibold text-muted-foreground/80 tracking-tight", children: label }),
|
|
9733
9839
|
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("span", { className: "flex items-center gap-2", children: [
|
|
@@ -9746,7 +9852,28 @@ var MetricTile = ({
|
|
|
9746
9852
|
}
|
|
9747
9853
|
) : null
|
|
9748
9854
|
] })
|
|
9749
|
-
] })
|
|
9855
|
+
] }),
|
|
9856
|
+
hasSparkline ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
9857
|
+
"div",
|
|
9858
|
+
{
|
|
9859
|
+
className: cn(
|
|
9860
|
+
"relative z-10 mt-2",
|
|
9861
|
+
bandBleed
|
|
9862
|
+
),
|
|
9863
|
+
children: sparkline ?? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
9864
|
+
Sparkline,
|
|
9865
|
+
{
|
|
9866
|
+
data: sparklineData,
|
|
9867
|
+
width: 160,
|
|
9868
|
+
height: 40,
|
|
9869
|
+
interactive: true,
|
|
9870
|
+
className: "h-full w-full opacity-90",
|
|
9871
|
+
color: sparklineToneColor[trendTone],
|
|
9872
|
+
...sparklineConfig
|
|
9873
|
+
}
|
|
9874
|
+
)
|
|
9875
|
+
}
|
|
9876
|
+
) : null
|
|
9750
9877
|
] });
|
|
9751
9878
|
const divider = showDivider ? metricCellDividerClass : void 0;
|
|
9752
9879
|
if (onSelect) {
|
|
@@ -10447,7 +10574,7 @@ var StatusBadge = ({
|
|
|
10447
10574
|
"span",
|
|
10448
10575
|
{
|
|
10449
10576
|
className: cn(
|
|
10450
|
-
"aui-app-status-badge inline-flex items-center gap-1.5 rounded-full px-2 py-0.5",
|
|
10577
|
+
"aui-app-status-badge inline-flex w-fit shrink-0 items-center gap-1.5 rounded-full px-2 py-0.5",
|
|
10451
10578
|
"text-xs font-medium leading-none ring-1 ring-inset",
|
|
10452
10579
|
statusBadgeToneClass[tone],
|
|
10453
10580
|
className
|
|
@@ -10861,7 +10988,7 @@ function CopyButton({
|
|
|
10861
10988
|
"inline-flex items-center justify-center gap-1.5 rounded-md text-sm font-medium text-muted-foreground transition-colors",
|
|
10862
10989
|
"hover:bg-accent hover:text-foreground data-[copied=true]:text-emerald-600 dark:data-[copied=true]:text-emerald-400",
|
|
10863
10990
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/15",
|
|
10864
|
-
children ? "h-
|
|
10991
|
+
children ? "h-7 px-1.5" : "size-7",
|
|
10865
10992
|
className
|
|
10866
10993
|
),
|
|
10867
10994
|
...props,
|
|
@@ -11592,7 +11719,7 @@ var FilterField = ({
|
|
|
11592
11719
|
|
|
11593
11720
|
// src/app/data/FilterDropdown.tsx
|
|
11594
11721
|
var import_react73 = require("react");
|
|
11595
|
-
var
|
|
11722
|
+
var import_lucide_react25 = require("lucide-react");
|
|
11596
11723
|
|
|
11597
11724
|
// src/ui/checkbox.tsx
|
|
11598
11725
|
var import_radix_ui7 = require("radix-ui");
|
|
@@ -11625,23 +11752,178 @@ function Checkbox({
|
|
|
11625
11752
|
);
|
|
11626
11753
|
}
|
|
11627
11754
|
|
|
11628
|
-
// src/ui/
|
|
11755
|
+
// src/ui/select.tsx
|
|
11629
11756
|
var import_radix_ui8 = require("radix-ui");
|
|
11757
|
+
var import_lucide_react24 = require("lucide-react");
|
|
11630
11758
|
var import_jsx_runtime105 = require("react/jsx-runtime");
|
|
11759
|
+
function Select({
|
|
11760
|
+
...props
|
|
11761
|
+
}) {
|
|
11762
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(import_radix_ui8.Select.Root, { "data-slot": "select", ...props });
|
|
11763
|
+
}
|
|
11764
|
+
function SelectGroup({
|
|
11765
|
+
...props
|
|
11766
|
+
}) {
|
|
11767
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(import_radix_ui8.Select.Group, { "data-slot": "select-group", ...props });
|
|
11768
|
+
}
|
|
11769
|
+
function SelectValue({
|
|
11770
|
+
...props
|
|
11771
|
+
}) {
|
|
11772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(import_radix_ui8.Select.Value, { "data-slot": "select-value", ...props });
|
|
11773
|
+
}
|
|
11774
|
+
function SelectTrigger({
|
|
11775
|
+
className,
|
|
11776
|
+
size = "default",
|
|
11777
|
+
children,
|
|
11778
|
+
...props
|
|
11779
|
+
}) {
|
|
11780
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsxs)(
|
|
11781
|
+
import_radix_ui8.Select.Trigger,
|
|
11782
|
+
{
|
|
11783
|
+
"data-slot": "select-trigger",
|
|
11784
|
+
"data-size": size,
|
|
11785
|
+
className: cn(
|
|
11786
|
+
controlClass({ size }),
|
|
11787
|
+
"flex w-fit items-center justify-between gap-2 whitespace-nowrap *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",
|
|
11788
|
+
className
|
|
11789
|
+
),
|
|
11790
|
+
...props,
|
|
11791
|
+
children: [
|
|
11792
|
+
children,
|
|
11793
|
+
/* @__PURE__ */ (0, import_jsx_runtime105.jsx)(import_radix_ui8.Select.Icon, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(import_lucide_react24.ChevronDownIcon, { className: "size-4 opacity-50" }) })
|
|
11794
|
+
]
|
|
11795
|
+
}
|
|
11796
|
+
);
|
|
11797
|
+
}
|
|
11798
|
+
function SelectContent({
|
|
11799
|
+
className,
|
|
11800
|
+
children,
|
|
11801
|
+
position = "popper",
|
|
11802
|
+
...props
|
|
11803
|
+
}) {
|
|
11804
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(import_radix_ui8.Select.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime105.jsxs)(
|
|
11805
|
+
import_radix_ui8.Select.Content,
|
|
11806
|
+
{
|
|
11807
|
+
"data-slot": "select-content",
|
|
11808
|
+
className: cn(
|
|
11809
|
+
overlayListPanelClass,
|
|
11810
|
+
"relative max-h-[var(--radix-select-content-available-height)] min-w-[8rem] origin-[var(--radix-select-content-transform-origin)] overflow-x-hidden overflow-y-auto",
|
|
11811
|
+
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
11812
|
+
className
|
|
11813
|
+
),
|
|
11814
|
+
position,
|
|
11815
|
+
...props,
|
|
11816
|
+
children: [
|
|
11817
|
+
/* @__PURE__ */ (0, import_jsx_runtime105.jsx)(SelectScrollUpButton, {}),
|
|
11818
|
+
/* @__PURE__ */ (0, import_jsx_runtime105.jsx)(
|
|
11819
|
+
import_radix_ui8.Select.Viewport,
|
|
11820
|
+
{
|
|
11821
|
+
className: cn(
|
|
11822
|
+
"p-1",
|
|
11823
|
+
position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
|
|
11824
|
+
),
|
|
11825
|
+
children
|
|
11826
|
+
}
|
|
11827
|
+
),
|
|
11828
|
+
/* @__PURE__ */ (0, import_jsx_runtime105.jsx)(SelectScrollDownButton, {})
|
|
11829
|
+
]
|
|
11830
|
+
}
|
|
11831
|
+
) });
|
|
11832
|
+
}
|
|
11833
|
+
function SelectLabel({
|
|
11834
|
+
className,
|
|
11835
|
+
...props
|
|
11836
|
+
}) {
|
|
11837
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(
|
|
11838
|
+
import_radix_ui8.Select.Label,
|
|
11839
|
+
{
|
|
11840
|
+
"data-slot": "select-label",
|
|
11841
|
+
className: cn("px-2 py-1.5 text-xs font-medium text-muted-foreground", className),
|
|
11842
|
+
...props
|
|
11843
|
+
}
|
|
11844
|
+
);
|
|
11845
|
+
}
|
|
11846
|
+
function SelectItem({
|
|
11847
|
+
className,
|
|
11848
|
+
children,
|
|
11849
|
+
...props
|
|
11850
|
+
}) {
|
|
11851
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsxs)(
|
|
11852
|
+
import_radix_ui8.Select.Item,
|
|
11853
|
+
{
|
|
11854
|
+
"data-slot": "select-item",
|
|
11855
|
+
className: cn(
|
|
11856
|
+
overlayItemClass,
|
|
11857
|
+
"w-full py-1 pr-8 pl-2 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
11858
|
+
className
|
|
11859
|
+
),
|
|
11860
|
+
...props,
|
|
11861
|
+
children: [
|
|
11862
|
+
/* @__PURE__ */ (0, import_jsx_runtime105.jsx)("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(import_radix_ui8.Select.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(import_lucide_react24.CheckIcon, { className: "size-4" }) }) }),
|
|
11863
|
+
/* @__PURE__ */ (0, import_jsx_runtime105.jsx)(import_radix_ui8.Select.ItemText, { children })
|
|
11864
|
+
]
|
|
11865
|
+
}
|
|
11866
|
+
);
|
|
11867
|
+
}
|
|
11868
|
+
function SelectSeparator({
|
|
11869
|
+
className,
|
|
11870
|
+
...props
|
|
11871
|
+
}) {
|
|
11872
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(
|
|
11873
|
+
import_radix_ui8.Select.Separator,
|
|
11874
|
+
{
|
|
11875
|
+
"data-slot": "select-separator",
|
|
11876
|
+
className: cn("-mx-1 my-1 h-px bg-border", className),
|
|
11877
|
+
...props
|
|
11878
|
+
}
|
|
11879
|
+
);
|
|
11880
|
+
}
|
|
11881
|
+
function SelectScrollUpButton({
|
|
11882
|
+
className,
|
|
11883
|
+
...props
|
|
11884
|
+
}) {
|
|
11885
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(
|
|
11886
|
+
import_radix_ui8.Select.ScrollUpButton,
|
|
11887
|
+
{
|
|
11888
|
+
"data-slot": "select-scroll-up-button",
|
|
11889
|
+
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
11890
|
+
...props,
|
|
11891
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(import_lucide_react24.ChevronUpIcon, { className: "size-4" })
|
|
11892
|
+
}
|
|
11893
|
+
);
|
|
11894
|
+
}
|
|
11895
|
+
function SelectScrollDownButton({
|
|
11896
|
+
className,
|
|
11897
|
+
...props
|
|
11898
|
+
}) {
|
|
11899
|
+
return /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(
|
|
11900
|
+
import_radix_ui8.Select.ScrollDownButton,
|
|
11901
|
+
{
|
|
11902
|
+
"data-slot": "select-scroll-down-button",
|
|
11903
|
+
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
11904
|
+
...props,
|
|
11905
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime105.jsx)(import_lucide_react24.ChevronDownIcon, { className: "size-4" })
|
|
11906
|
+
}
|
|
11907
|
+
);
|
|
11908
|
+
}
|
|
11909
|
+
|
|
11910
|
+
// src/ui/popover.tsx
|
|
11911
|
+
var import_radix_ui9 = require("radix-ui");
|
|
11912
|
+
var import_jsx_runtime106 = require("react/jsx-runtime");
|
|
11631
11913
|
function Popover({
|
|
11632
11914
|
...props
|
|
11633
11915
|
}) {
|
|
11634
|
-
return /* @__PURE__ */ (0,
|
|
11916
|
+
return /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(import_radix_ui9.Popover.Root, { "data-slot": "popover", ...props });
|
|
11635
11917
|
}
|
|
11636
11918
|
function PopoverTrigger({
|
|
11637
11919
|
...props
|
|
11638
11920
|
}) {
|
|
11639
|
-
return /* @__PURE__ */ (0,
|
|
11921
|
+
return /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(import_radix_ui9.Popover.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
11640
11922
|
}
|
|
11641
11923
|
function PopoverAnchor({
|
|
11642
11924
|
...props
|
|
11643
11925
|
}) {
|
|
11644
|
-
return /* @__PURE__ */ (0,
|
|
11926
|
+
return /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(import_radix_ui9.Popover.Anchor, { "data-slot": "popover-anchor", ...props });
|
|
11645
11927
|
}
|
|
11646
11928
|
function PopoverContent({
|
|
11647
11929
|
className,
|
|
@@ -11650,8 +11932,8 @@ function PopoverContent({
|
|
|
11650
11932
|
variant = "default",
|
|
11651
11933
|
...props
|
|
11652
11934
|
}) {
|
|
11653
|
-
return /* @__PURE__ */ (0,
|
|
11654
|
-
|
|
11935
|
+
return /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(import_radix_ui9.Popover.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
11936
|
+
import_radix_ui9.Popover.Content,
|
|
11655
11937
|
{
|
|
11656
11938
|
"data-slot": "popover-content",
|
|
11657
11939
|
"data-variant": variant,
|
|
@@ -11663,7 +11945,7 @@ function PopoverContent({
|
|
|
11663
11945
|
"min-w-[8rem] origin-[var(--radix-popover-content-transform-origin)]"
|
|
11664
11946
|
) : cn(
|
|
11665
11947
|
overlaySurfaceClass,
|
|
11666
|
-
"w-72 origin-[var(--radix-popover-content-transform-origin)] rounded-xl p-
|
|
11948
|
+
"w-72 origin-[var(--radix-popover-content-transform-origin)] rounded-xl p-3 outline-hidden"
|
|
11667
11949
|
),
|
|
11668
11950
|
className
|
|
11669
11951
|
),
|
|
@@ -11673,499 +11955,471 @@ function PopoverContent({
|
|
|
11673
11955
|
}
|
|
11674
11956
|
|
|
11675
11957
|
// src/app/data/FilterDropdown.tsx
|
|
11676
|
-
var
|
|
11677
|
-
var
|
|
11678
|
-
{ id: "
|
|
11679
|
-
{ id: "
|
|
11680
|
-
{ id: "
|
|
11958
|
+
var import_jsx_runtime107 = require("react/jsx-runtime");
|
|
11959
|
+
var DEFAULT_PRESETS = [
|
|
11960
|
+
{ id: "last_7_days", label: "Last 7 days" },
|
|
11961
|
+
{ id: "last_30_days", label: "Last 30 days" },
|
|
11962
|
+
{ id: "last_90_days", label: "Last 90 days" },
|
|
11963
|
+
{ id: "this_month", label: "This month" },
|
|
11964
|
+
{ id: "this_year", label: "This year" },
|
|
11965
|
+
{ id: "custom", label: "Custom range" }
|
|
11681
11966
|
];
|
|
11682
|
-
var
|
|
11683
|
-
{ id: "
|
|
11684
|
-
{ id: "
|
|
11685
|
-
{ id: "
|
|
11967
|
+
var DEFAULT_OPERATORS = [
|
|
11968
|
+
{ id: "gt", label: "Greater than" },
|
|
11969
|
+
{ id: "lt", label: "Less than" },
|
|
11970
|
+
{ id: "eq", label: "Equals" }
|
|
11686
11971
|
];
|
|
11972
|
+
function asArray(v) {
|
|
11973
|
+
return Array.isArray(v) ? v : [];
|
|
11974
|
+
}
|
|
11975
|
+
function asText(v) {
|
|
11976
|
+
return typeof v === "string" ? v : "";
|
|
11977
|
+
}
|
|
11978
|
+
function asDate(v) {
|
|
11979
|
+
return v && !Array.isArray(v) && typeof v === "object" && "preset" in v ? v : { preset: null };
|
|
11980
|
+
}
|
|
11981
|
+
function asNumeric(v) {
|
|
11982
|
+
return v && !Array.isArray(v) && typeof v === "object" && "operator" in v ? v : { operator: "gt", value: "" };
|
|
11983
|
+
}
|
|
11984
|
+
var OPERATOR_SYMBOL = {
|
|
11985
|
+
gt: ">",
|
|
11986
|
+
lt: "<",
|
|
11987
|
+
eq: "="
|
|
11988
|
+
};
|
|
11687
11989
|
function FilterDropdown({
|
|
11688
|
-
|
|
11689
|
-
|
|
11690
|
-
|
|
11691
|
-
|
|
11990
|
+
fields,
|
|
11991
|
+
value,
|
|
11992
|
+
defaultValue,
|
|
11993
|
+
onChange,
|
|
11994
|
+
label = "Filter",
|
|
11995
|
+
align = "start",
|
|
11996
|
+
showActiveChips = true,
|
|
11692
11997
|
className
|
|
11693
11998
|
}) {
|
|
11694
11999
|
const [isOpen, setIsOpen] = (0, import_react73.useState)(false);
|
|
11695
|
-
const [
|
|
12000
|
+
const [activeId, setActiveId] = (0, import_react73.useState)(fields[0]?.id ?? null);
|
|
11696
12001
|
const [isMobile, setIsMobile] = (0, import_react73.useState)(false);
|
|
12002
|
+
const isControlled = value !== void 0;
|
|
12003
|
+
const [internal, setInternal] = (0, import_react73.useState)(defaultValue ?? {});
|
|
12004
|
+
const values = isControlled ? value : internal;
|
|
11697
12005
|
(0, import_react73.useEffect)(() => {
|
|
11698
12006
|
const checkMobile = () => setIsMobile(window.innerWidth < 768);
|
|
11699
12007
|
checkMobile();
|
|
11700
12008
|
window.addEventListener("resize", checkMobile);
|
|
11701
12009
|
return () => window.removeEventListener("resize", checkMobile);
|
|
11702
12010
|
}, []);
|
|
11703
|
-
const [selectedContacts, setSelectedContacts] = (0, import_react73.useState)(
|
|
11704
|
-
filters?.contacts ?? initialFilters?.contacts ?? []
|
|
11705
|
-
);
|
|
11706
|
-
const [walletInput, setWalletInput] = (0, import_react73.useState)(filters?.walletAddress ?? initialFilters?.walletAddress ?? "");
|
|
11707
|
-
const [appliedWallet, setAppliedWallet] = (0, import_react73.useState)(filters?.walletAddress ?? initialFilters?.walletAddress ?? "");
|
|
11708
|
-
const [selectedDatePreset, setSelectedDatePreset] = (0, import_react73.useState)(
|
|
11709
|
-
filters?.lastInvoiceDate ?? initialFilters?.lastInvoiceDate ?? null
|
|
11710
|
-
);
|
|
11711
|
-
const [customDateFrom, setCustomDateFrom] = (0, import_react73.useState)(
|
|
11712
|
-
filters?.customDateRange?.from ?? initialFilters?.customDateRange?.from ?? ""
|
|
11713
|
-
);
|
|
11714
|
-
const [customDateTo, setCustomDateTo] = (0, import_react73.useState)(
|
|
11715
|
-
filters?.customDateRange?.to ?? initialFilters?.customDateRange?.to ?? ""
|
|
11716
|
-
);
|
|
11717
|
-
const [ltvOperator, setLtvOperator] = (0, import_react73.useState)(
|
|
11718
|
-
filters?.lifetimeValue?.operator ?? initialFilters?.lifetimeValue?.operator ?? "greater_than"
|
|
11719
|
-
);
|
|
11720
|
-
const [ltvValue, setLtvValue] = (0, import_react73.useState)(filters?.lifetimeValue?.value ?? initialFilters?.lifetimeValue?.value ?? "");
|
|
11721
|
-
const [isLtvOperatorOpen, setLtvOperatorOpen] = (0, import_react73.useState)(false);
|
|
11722
|
-
const [outstandingOperator, setOutstandingOperator] = (0, import_react73.useState)(
|
|
11723
|
-
filters?.outstanding?.operator ?? initialFilters?.outstanding?.operator ?? "greater_than"
|
|
11724
|
-
);
|
|
11725
|
-
const [outstandingValue, setOutstandingValue] = (0, import_react73.useState)(filters?.outstanding?.value ?? initialFilters?.outstanding?.value ?? "");
|
|
11726
|
-
const [isOutstandingOperatorOpen, setOutstandingOperatorOpen] = (0, import_react73.useState)(false);
|
|
11727
12011
|
(0, import_react73.useEffect)(() => {
|
|
11728
|
-
if (
|
|
11729
|
-
|
|
11730
|
-
|
|
11731
|
-
|
|
11732
|
-
|
|
11733
|
-
|
|
11734
|
-
|
|
11735
|
-
|
|
11736
|
-
setLtvValue(filters.lifetimeValue?.value ?? "");
|
|
11737
|
-
setOutstandingOperator(filters.outstanding?.operator ?? "greater_than");
|
|
11738
|
-
setOutstandingValue(filters.outstanding?.value ?? "");
|
|
11739
|
-
}
|
|
11740
|
-
}, [filters]);
|
|
11741
|
-
const [contactSearch, setContactSearch] = (0, import_react73.useState)("");
|
|
11742
|
-
const [walletSearch, setWalletSearch] = (0, import_react73.useState)("");
|
|
11743
|
-
const refDate = (0, import_react73.useMemo)(() => new Date(2026, 5, 26), []);
|
|
11744
|
-
const presets = (0, import_react73.useMemo)(() => {
|
|
11745
|
-
const year = refDate.getFullYear();
|
|
11746
|
-
const month = refDate.getMonth();
|
|
11747
|
-
const lastMonthDate = new Date(year, month - 1, 1);
|
|
11748
|
-
const lastMonthLabel = lastMonthDate.toLocaleDateString("en-US", { month: "short", year: "numeric" });
|
|
11749
|
-
const thisMonthLabel = refDate.toLocaleDateString("en-US", { month: "short", year: "numeric" });
|
|
11750
|
-
const thisQuarter = Math.floor(month / 3) + 1;
|
|
11751
|
-
const thisQuarterLabel = `Q${thisQuarter} ${year}`;
|
|
11752
|
-
const lastQuarter = thisQuarter === 1 ? 4 : thisQuarter - 1;
|
|
11753
|
-
const lastQuarterYear = thisQuarter === 1 ? year - 1 : year;
|
|
11754
|
-
const lastQuarterLabel = `Q${lastQuarter} ${lastQuarterYear}`;
|
|
11755
|
-
const thisYearLabel = `${year}`;
|
|
11756
|
-
const last30 = new Date(refDate);
|
|
11757
|
-
last30.setDate(refDate.getDate() - 30);
|
|
11758
|
-
const formatDate = (d) => d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
|
|
11759
|
-
const last30Label = `${formatDate(last30)} - ${formatDate(refDate)}`;
|
|
11760
|
-
const last90 = new Date(refDate);
|
|
11761
|
-
last90.setDate(refDate.getDate() - 90);
|
|
11762
|
-
const last90Label = `${formatDate(last90)} - ${formatDate(refDate)}`;
|
|
11763
|
-
return [
|
|
11764
|
-
{ id: "last_month", label: "Last month", date: lastMonthLabel },
|
|
11765
|
-
{ id: "this_month", label: "This month", date: thisMonthLabel },
|
|
11766
|
-
{ id: "this_quarter", label: "This quarter", date: thisQuarterLabel },
|
|
11767
|
-
{ id: "last_quarter", label: "Last quarter", date: lastQuarterLabel },
|
|
11768
|
-
{ id: "this_year", label: "This year", date: thisYearLabel },
|
|
11769
|
-
{ id: "last_30_days", label: "Last 30 days", date: last30Label },
|
|
11770
|
-
{ id: "last_90_days", label: "Last 90 days", date: last90Label },
|
|
11771
|
-
{ id: "custom", label: "Custom range", date: "" }
|
|
11772
|
-
];
|
|
11773
|
-
}, [refDate]);
|
|
11774
|
-
const filteredContacts = (0, import_react73.useMemo)(() => {
|
|
11775
|
-
if (!contactSearch) return contacts;
|
|
11776
|
-
const query = contactSearch.toLowerCase();
|
|
11777
|
-
return contacts.filter(
|
|
11778
|
-
(c) => c.name.toLowerCase().includes(query) || c.email.toLowerCase().includes(query)
|
|
11779
|
-
);
|
|
11780
|
-
}, [contacts, contactSearch]);
|
|
11781
|
-
const handleContactToggle = (contactName) => {
|
|
11782
|
-
const next = selectedContacts.includes(contactName) ? selectedContacts.filter((name) => name !== contactName) : [...selectedContacts, contactName];
|
|
11783
|
-
setSelectedContacts(next);
|
|
11784
|
-
notifyChanges({ contacts: next });
|
|
11785
|
-
setIsOpen(false);
|
|
12012
|
+
if (!fields.some((f) => f.id === activeId)) {
|
|
12013
|
+
setActiveId(fields[0]?.id ?? null);
|
|
12014
|
+
}
|
|
12015
|
+
}, [fields, activeId]);
|
|
12016
|
+
const commit = (id, next) => {
|
|
12017
|
+
const merged = { ...values, [id]: next };
|
|
12018
|
+
if (!isControlled) setInternal(merged);
|
|
12019
|
+
onChange?.(merged);
|
|
11786
12020
|
};
|
|
11787
|
-
const
|
|
11788
|
-
|
|
11789
|
-
|
|
11790
|
-
setIsOpen(false);
|
|
12021
|
+
const clearAll = () => {
|
|
12022
|
+
if (!isControlled) setInternal({});
|
|
12023
|
+
onChange?.({});
|
|
11791
12024
|
};
|
|
11792
|
-
const
|
|
11793
|
-
|
|
11794
|
-
|
|
11795
|
-
|
|
11796
|
-
|
|
11797
|
-
|
|
11798
|
-
|
|
11799
|
-
|
|
11800
|
-
|
|
11801
|
-
|
|
11802
|
-
|
|
12025
|
+
const activeIdx = fields.findIndex((f) => f.id === activeId);
|
|
12026
|
+
const activeField = activeIdx >= 0 ? fields[activeIdx] : void 0;
|
|
12027
|
+
const chips = [];
|
|
12028
|
+
for (const field of fields) {
|
|
12029
|
+
const v = values[field.id];
|
|
12030
|
+
if (field.type === "multiselect") {
|
|
12031
|
+
const selected = asArray(v);
|
|
12032
|
+
for (const optionValue of selected) {
|
|
12033
|
+
const opt = field.options?.find((o) => o.value === optionValue);
|
|
12034
|
+
chips.push({
|
|
12035
|
+
id: `${field.id}:${optionValue}`,
|
|
12036
|
+
label: `${field.label}: ${opt?.label ?? optionValue}`,
|
|
12037
|
+
remove: () => commit(field.id, selected.filter((x) => x !== optionValue))
|
|
12038
|
+
});
|
|
12039
|
+
}
|
|
12040
|
+
} else if (field.type === "text") {
|
|
12041
|
+
const text = asText(v);
|
|
12042
|
+
if (text) {
|
|
12043
|
+
chips.push({
|
|
12044
|
+
id: field.id,
|
|
12045
|
+
label: `${field.label}: ${text}`,
|
|
12046
|
+
remove: () => commit(field.id, "")
|
|
12047
|
+
});
|
|
12048
|
+
}
|
|
12049
|
+
} else if (field.type === "numeric") {
|
|
12050
|
+
const n = asNumeric(v);
|
|
12051
|
+
if (n.value) {
|
|
12052
|
+
chips.push({
|
|
12053
|
+
id: field.id,
|
|
12054
|
+
label: `${field.label} ${OPERATOR_SYMBOL[n.operator]} ${n.value}`,
|
|
12055
|
+
remove: () => commit(field.id, null)
|
|
12056
|
+
});
|
|
12057
|
+
}
|
|
12058
|
+
} else if (field.type === "daterange") {
|
|
12059
|
+
const d = asDate(v);
|
|
12060
|
+
if (d.preset) {
|
|
12061
|
+
const presetLabel = d.preset === "custom" ? `${d.from || "\u2026"} \u2013 ${d.to || "\u2026"}` : (field.presets ?? DEFAULT_PRESETS).find((p) => p.id === d.preset)?.label ?? d.preset;
|
|
12062
|
+
chips.push({
|
|
12063
|
+
id: field.id,
|
|
12064
|
+
label: `${field.label}: ${presetLabel}`,
|
|
12065
|
+
remove: () => commit(field.id, { preset: null })
|
|
12066
|
+
});
|
|
12067
|
+
}
|
|
11803
12068
|
}
|
|
11804
|
-
}
|
|
11805
|
-
|
|
11806
|
-
|
|
11807
|
-
|
|
11808
|
-
|
|
11809
|
-
|
|
11810
|
-
|
|
11811
|
-
|
|
11812
|
-
|
|
11813
|
-
|
|
11814
|
-
|
|
11815
|
-
|
|
11816
|
-
|
|
11817
|
-
|
|
11818
|
-
|
|
11819
|
-
|
|
11820
|
-
|
|
11821
|
-
|
|
11822
|
-
|
|
11823
|
-
|
|
11824
|
-
|
|
11825
|
-
|
|
11826
|
-
|
|
11827
|
-
|
|
11828
|
-
|
|
11829
|
-
|
|
11830
|
-
|
|
11831
|
-
|
|
11832
|
-
|
|
11833
|
-
|
|
11834
|
-
|
|
11835
|
-
|
|
11836
|
-
|
|
11837
|
-
|
|
11838
|
-
|
|
11839
|
-
|
|
11840
|
-
|
|
11841
|
-
|
|
11842
|
-
|
|
11843
|
-
|
|
11844
|
-
|
|
11845
|
-
|
|
11846
|
-
|
|
11847
|
-
|
|
11848
|
-
|
|
11849
|
-
|
|
11850
|
-
|
|
11851
|
-
|
|
11852
|
-
|
|
11853
|
-
|
|
11854
|
-
|
|
11855
|
-
|
|
11856
|
-
|
|
12069
|
+
}
|
|
12070
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: cn("flex flex-wrap items-center gap-2", className), children: [
|
|
12071
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
|
|
12072
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12073
|
+
Button,
|
|
12074
|
+
{
|
|
12075
|
+
variant: "outline",
|
|
12076
|
+
size: "sm",
|
|
12077
|
+
className: "border-dashed font-medium text-muted-foreground hover:text-foreground",
|
|
12078
|
+
iconLeading: /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(import_lucide_react25.ListFilterIcon, { className: "size-4" }),
|
|
12079
|
+
children: label
|
|
12080
|
+
}
|
|
12081
|
+
) }),
|
|
12082
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12083
|
+
PopoverContent,
|
|
12084
|
+
{
|
|
12085
|
+
variant: "list",
|
|
12086
|
+
align,
|
|
12087
|
+
className: "overflow-visible border-none bg-transparent p-0 shadow-none max-w-[calc(100vw-32px)] md:max-w-none",
|
|
12088
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "relative flex flex-col md:flex-row items-stretch md:items-start w-[calc(100vw-32px)] max-w-[340px] md:w-auto md:max-w-none", children: [
|
|
12089
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "w-full md:w-56 rounded-xl border border-border bg-popover p-1.5 shadow-lg", children: fields.map((field) => {
|
|
12090
|
+
const isActive = activeId === field.id;
|
|
12091
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)(
|
|
12092
|
+
"button",
|
|
12093
|
+
{
|
|
12094
|
+
type: "button",
|
|
12095
|
+
className: cn(
|
|
12096
|
+
"flex w-full items-center justify-between rounded-lg px-3 py-2 text-sm text-left transition-colors outline-none",
|
|
12097
|
+
isActive ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted/50 hover:text-foreground"
|
|
12098
|
+
),
|
|
12099
|
+
onMouseEnter: () => !isMobile && setActiveId(field.id),
|
|
12100
|
+
onClick: () => setActiveId(field.id),
|
|
12101
|
+
children: [
|
|
12102
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("span", { className: "flex items-center gap-2", children: [
|
|
12103
|
+
field.icon,
|
|
12104
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { children: field.label })
|
|
12105
|
+
] }),
|
|
12106
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(import_lucide_react25.ChevronRightIcon, { className: "size-4 text-muted-foreground/50" })
|
|
12107
|
+
]
|
|
12108
|
+
},
|
|
12109
|
+
field.id
|
|
12110
|
+
);
|
|
12111
|
+
}) }),
|
|
12112
|
+
activeField && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12113
|
+
"div",
|
|
12114
|
+
{
|
|
12115
|
+
className: "relative left-0 mt-2 w-full md:absolute md:left-[calc(100%+6px)] md:w-80 rounded-xl border border-border bg-popover p-3 shadow-lg transition-all duration-150 md:mt-0",
|
|
12116
|
+
style: isMobile ? {} : { top: `${activeIdx * 36 + 6}px` },
|
|
12117
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12118
|
+
FilterFieldControl,
|
|
12119
|
+
{
|
|
12120
|
+
field: activeField,
|
|
12121
|
+
value: values[activeField.id],
|
|
12122
|
+
onChange: (next) => commit(activeField.id, next),
|
|
12123
|
+
onClose: () => setIsOpen(false)
|
|
12124
|
+
}
|
|
12125
|
+
)
|
|
12126
|
+
}
|
|
12127
|
+
)
|
|
12128
|
+
] })
|
|
12129
|
+
}
|
|
12130
|
+
)
|
|
12131
|
+
] }),
|
|
12132
|
+
showActiveChips && chips.map((chip) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(FilterChip, { label: chip.label, onRemove: chip.remove }, chip.id)),
|
|
12133
|
+
showActiveChips && chips.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12134
|
+
"button",
|
|
11857
12135
|
{
|
|
11858
|
-
|
|
11859
|
-
|
|
11860
|
-
|
|
11861
|
-
|
|
11862
|
-
iconLeading: /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(import_lucide_react24.ListFilterIcon, { className: "size-4" }),
|
|
11863
|
-
children: "Filter"
|
|
12136
|
+
type: "button",
|
|
12137
|
+
onClick: clearAll,
|
|
12138
|
+
className: "rounded-full px-3 py-1 text-sm font-medium text-muted-foreground outline-none transition-colors hover:text-foreground",
|
|
12139
|
+
children: "Clear all"
|
|
11864
12140
|
}
|
|
11865
|
-
)
|
|
11866
|
-
|
|
11867
|
-
|
|
11868
|
-
|
|
11869
|
-
|
|
11870
|
-
|
|
11871
|
-
|
|
11872
|
-
|
|
11873
|
-
|
|
11874
|
-
|
|
11875
|
-
|
|
11876
|
-
|
|
11877
|
-
|
|
11878
|
-
|
|
11879
|
-
|
|
11880
|
-
|
|
11881
|
-
|
|
11882
|
-
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11886
|
-
|
|
11887
|
-
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
|
|
11893
|
-
|
|
11894
|
-
|
|
11895
|
-
|
|
11896
|
-
|
|
11897
|
-
|
|
12141
|
+
)
|
|
12142
|
+
] });
|
|
12143
|
+
}
|
|
12144
|
+
function FilterChip({ label, onRemove }) {
|
|
12145
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("span", { className: "inline-flex h-9 items-center gap-1.5 rounded-full border border-border bg-muted/40 pl-3 pr-1.5 text-sm font-medium text-foreground", children: [
|
|
12146
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { className: "truncate", children: label }),
|
|
12147
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12148
|
+
"button",
|
|
12149
|
+
{
|
|
12150
|
+
type: "button",
|
|
12151
|
+
onClick: onRemove,
|
|
12152
|
+
"aria-label": `Remove ${label}`,
|
|
12153
|
+
className: "flex size-5 items-center justify-center rounded-full text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground",
|
|
12154
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(import_lucide_react25.XIcon, { className: "size-3.5" })
|
|
12155
|
+
}
|
|
12156
|
+
)
|
|
12157
|
+
] });
|
|
12158
|
+
}
|
|
12159
|
+
function FilterFieldControl({
|
|
12160
|
+
field,
|
|
12161
|
+
value,
|
|
12162
|
+
onChange,
|
|
12163
|
+
onClose
|
|
12164
|
+
}) {
|
|
12165
|
+
switch (field.type) {
|
|
12166
|
+
case "multiselect":
|
|
12167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(MultiSelectControl, { field, value: asArray(value), onChange });
|
|
12168
|
+
case "text":
|
|
12169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(TextControl, { field, value: asText(value), onChange, onClose });
|
|
12170
|
+
case "daterange":
|
|
12171
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(DateRangeControl, { field, value: asDate(value), onChange, onClose });
|
|
12172
|
+
case "numeric":
|
|
12173
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(NumericControl, { field, value: asNumeric(value), onChange, onClose });
|
|
12174
|
+
default:
|
|
12175
|
+
return null;
|
|
12176
|
+
}
|
|
12177
|
+
}
|
|
12178
|
+
function MultiSelectControl({
|
|
12179
|
+
field,
|
|
12180
|
+
value,
|
|
12181
|
+
onChange
|
|
12182
|
+
}) {
|
|
12183
|
+
const options = field.options ?? [];
|
|
12184
|
+
const [search, setSearch] = (0, import_react73.useState)("");
|
|
12185
|
+
const searchable = field.searchable ?? options.length > 8;
|
|
12186
|
+
const filtered = (0, import_react73.useMemo)(() => {
|
|
12187
|
+
if (!search) return options;
|
|
12188
|
+
const q = search.toLowerCase();
|
|
12189
|
+
return options.filter(
|
|
12190
|
+
(o) => o.label.toLowerCase().includes(q) || o.hint?.toLowerCase().includes(q)
|
|
12191
|
+
);
|
|
12192
|
+
}, [options, search]);
|
|
12193
|
+
const toggle = (optionValue) => {
|
|
12194
|
+
onChange(
|
|
12195
|
+
value.includes(optionValue) ? value.filter((v) => v !== optionValue) : [...value, optionValue]
|
|
12196
|
+
);
|
|
12197
|
+
};
|
|
12198
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex flex-col gap-2.5", children: [
|
|
12199
|
+
searchable && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12200
|
+
SearchInput,
|
|
12201
|
+
{
|
|
12202
|
+
placeholder: field.searchPlaceholder ?? "Search\u2026",
|
|
12203
|
+
value: search,
|
|
12204
|
+
onChange: (e) => setSearch(e.target.value),
|
|
12205
|
+
className: "w-full min-w-0"
|
|
12206
|
+
}
|
|
12207
|
+
),
|
|
12208
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "flex max-h-48 flex-col gap-1 overflow-y-auto pr-1", children: filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("p", { className: "py-4 text-center text-xs text-muted-foreground", children: "No options found" }) : filtered.map((option) => /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)(
|
|
12209
|
+
"label",
|
|
12210
|
+
{
|
|
12211
|
+
className: "flex cursor-pointer items-center gap-2.5 rounded-lg px-2 py-1.5 transition-colors hover:bg-muted/50",
|
|
12212
|
+
children: [
|
|
12213
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12214
|
+
Checkbox,
|
|
11898
12215
|
{
|
|
11899
|
-
|
|
11900
|
-
|
|
11901
|
-
children: [
|
|
11902
|
-
activeMenu === "contact" && /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex flex-col gap-2.5", children: [
|
|
11903
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "relative flex items-center", children: [
|
|
11904
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(import_lucide_react24.SearchIcon, { className: "absolute left-2.5 size-4 text-muted-foreground/60" }),
|
|
11905
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
11906
|
-
"input",
|
|
11907
|
-
{
|
|
11908
|
-
type: "text",
|
|
11909
|
-
placeholder: "Search by name or email...",
|
|
11910
|
-
value: contactSearch,
|
|
11911
|
-
onChange: (e) => setContactSearch(e.target.value),
|
|
11912
|
-
className: "w-full rounded-lg border border-border bg-background py-1.5 pl-8 pr-3 text-sm outline-none placeholder:text-muted-foreground/60 focus:border-border"
|
|
11913
|
-
}
|
|
11914
|
-
)
|
|
11915
|
-
] }),
|
|
11916
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("div", { className: "max-h-48 overflow-y-auto flex flex-col gap-1 pr-1", children: filteredContacts.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime106.jsx)("p", { className: "py-4 text-center text-xs text-muted-foreground", children: "No contacts found" }) : filteredContacts.map((contact) => {
|
|
11917
|
-
const isChecked = selectedContacts.includes(contact.name);
|
|
11918
|
-
return /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)(
|
|
11919
|
-
"label",
|
|
11920
|
-
{
|
|
11921
|
-
className: "flex cursor-pointer items-center gap-2.5 rounded-lg px-2 py-1.5 hover:bg-muted/50 transition-colors",
|
|
11922
|
-
children: [
|
|
11923
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
11924
|
-
Checkbox,
|
|
11925
|
-
{
|
|
11926
|
-
checked: isChecked,
|
|
11927
|
-
onCheckedChange: () => handleContactToggle(contact.name)
|
|
11928
|
-
}
|
|
11929
|
-
),
|
|
11930
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(Avatar, { variant: "secondary", children: /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(AvatarFallback, { children: contact.initials }) }),
|
|
11931
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("span", { className: "text-sm font-medium text-foreground", children: contact.name })
|
|
11932
|
-
]
|
|
11933
|
-
},
|
|
11934
|
-
contact.id
|
|
11935
|
-
);
|
|
11936
|
-
}) })
|
|
11937
|
-
] }),
|
|
11938
|
-
activeMenu === "wallet" && /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex flex-col gap-2.5", children: [
|
|
11939
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("div", { className: "relative flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
11940
|
-
"input",
|
|
11941
|
-
{
|
|
11942
|
-
type: "text",
|
|
11943
|
-
placeholder: "Search by wallet...",
|
|
11944
|
-
value: walletInput,
|
|
11945
|
-
onChange: (e) => setWalletInput(e.target.value),
|
|
11946
|
-
className: "w-full rounded-lg border border-border bg-background px-3 py-1.5 text-sm outline-none placeholder:text-muted-foreground/60"
|
|
11947
|
-
}
|
|
11948
|
-
) }),
|
|
11949
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex items-center justify-end gap-2 pt-1 border-t border-border/40", children: [
|
|
11950
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
11951
|
-
Button,
|
|
11952
|
-
{
|
|
11953
|
-
variant: "ghost",
|
|
11954
|
-
size: "sm",
|
|
11955
|
-
onClick: handleWalletClear,
|
|
11956
|
-
className: "text-muted-foreground hover:text-foreground h-8 px-3",
|
|
11957
|
-
children: "Clear"
|
|
11958
|
-
}
|
|
11959
|
-
),
|
|
11960
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
11961
|
-
Button,
|
|
11962
|
-
{
|
|
11963
|
-
color: "primary",
|
|
11964
|
-
size: "sm",
|
|
11965
|
-
onClick: handleWalletApply,
|
|
11966
|
-
className: "h-8 px-3",
|
|
11967
|
-
children: "Apply"
|
|
11968
|
-
}
|
|
11969
|
-
)
|
|
11970
|
-
] })
|
|
11971
|
-
] }),
|
|
11972
|
-
activeMenu === "date" && /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
11973
|
-
presets.map((preset) => {
|
|
11974
|
-
const isSelected = selectedDatePreset === preset.id;
|
|
11975
|
-
return /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)(
|
|
11976
|
-
"button",
|
|
11977
|
-
{
|
|
11978
|
-
type: "button",
|
|
11979
|
-
onClick: () => handleDatePresetSelect(preset.id),
|
|
11980
|
-
className: cn(
|
|
11981
|
-
"flex w-full items-center justify-between rounded-lg px-2.5 py-1.5 text-sm text-left transition-colors outline-none",
|
|
11982
|
-
isSelected ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted/50 hover:text-foreground"
|
|
11983
|
-
),
|
|
11984
|
-
children: [
|
|
11985
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("span", { children: preset.label }),
|
|
11986
|
-
preset.date && /* @__PURE__ */ (0, import_jsx_runtime106.jsx)("span", { className: "text-xs text-muted-foreground/70", children: preset.date })
|
|
11987
|
-
]
|
|
11988
|
-
},
|
|
11989
|
-
preset.id
|
|
11990
|
-
);
|
|
11991
|
-
}),
|
|
11992
|
-
selectedDatePreset === "custom" && /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex flex-col gap-2 mt-2 pt-2 border-t border-border/40", children: [
|
|
11993
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
11994
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
11995
|
-
"input",
|
|
11996
|
-
{
|
|
11997
|
-
type: "date",
|
|
11998
|
-
value: customDateFrom,
|
|
11999
|
-
onChange: (e) => setCustomDateFrom(e.target.value),
|
|
12000
|
-
className: "w-full rounded-lg border border-border bg-background px-2 py-1 text-xs outline-none"
|
|
12001
|
-
}
|
|
12002
|
-
),
|
|
12003
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("span", { className: "text-xs text-muted-foreground", children: "to" }),
|
|
12004
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
12005
|
-
"input",
|
|
12006
|
-
{
|
|
12007
|
-
type: "date",
|
|
12008
|
-
value: customDateTo,
|
|
12009
|
-
onChange: (e) => setCustomDateTo(e.target.value),
|
|
12010
|
-
className: "w-full rounded-lg border border-border bg-background px-2 py-1 text-xs outline-none"
|
|
12011
|
-
}
|
|
12012
|
-
)
|
|
12013
|
-
] }),
|
|
12014
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("div", { className: "flex justify-end gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
12015
|
-
Button,
|
|
12016
|
-
{
|
|
12017
|
-
color: "primary",
|
|
12018
|
-
size: "sm",
|
|
12019
|
-
onClick: handleCustomDateApply,
|
|
12020
|
-
className: "h-7 text-xs px-2.5",
|
|
12021
|
-
children: "Apply"
|
|
12022
|
-
}
|
|
12023
|
-
) })
|
|
12024
|
-
] })
|
|
12025
|
-
] }),
|
|
12026
|
-
activeMenu === "ltv" && /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex flex-col gap-2.5", children: [
|
|
12027
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
12028
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "relative shrink-0", children: [
|
|
12029
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)(
|
|
12030
|
-
"button",
|
|
12031
|
-
{
|
|
12032
|
-
type: "button",
|
|
12033
|
-
onClick: () => setLtvOperatorOpen(!isLtvOperatorOpen),
|
|
12034
|
-
className: "flex h-9 items-center gap-1 rounded-lg border border-border bg-background px-2.5 text-xs font-normal text-muted-foreground hover:bg-muted/50 hover:text-foreground outline-none whitespace-nowrap",
|
|
12035
|
-
children: [
|
|
12036
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("span", { children: OPERATORS.find((op) => op.id === ltvOperator)?.label.replace("...", "") }),
|
|
12037
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(import_lucide_react24.ChevronDownIcon, { className: "size-3" })
|
|
12038
|
-
]
|
|
12039
|
-
}
|
|
12040
|
-
),
|
|
12041
|
-
isLtvOperatorOpen && /* @__PURE__ */ (0, import_jsx_runtime106.jsx)("div", { className: "absolute left-0 top-full z-50 mt-1 w-32 rounded-lg border border-border bg-popover p-1 shadow-md", children: OPERATORS.map((op) => /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
12042
|
-
"button",
|
|
12043
|
-
{
|
|
12044
|
-
type: "button",
|
|
12045
|
-
onClick: () => {
|
|
12046
|
-
setLtvOperator(op.id);
|
|
12047
|
-
setLtvOperatorOpen(false);
|
|
12048
|
-
},
|
|
12049
|
-
className: "w-full rounded-md px-2 py-1 text-left text-xs text-foreground hover:bg-muted outline-none",
|
|
12050
|
-
children: op.label
|
|
12051
|
-
},
|
|
12052
|
-
op.id
|
|
12053
|
-
)) })
|
|
12054
|
-
] }),
|
|
12055
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
12056
|
-
"input",
|
|
12057
|
-
{
|
|
12058
|
-
type: "text",
|
|
12059
|
-
placeholder: "0.00",
|
|
12060
|
-
value: ltvValue,
|
|
12061
|
-
onChange: (e) => setLtvValue(e.target.value),
|
|
12062
|
-
className: "h-9 flex-1 min-w-0 rounded-lg border border-border bg-background px-3 py-1 text-sm outline-none placeholder:text-muted-foreground/60"
|
|
12063
|
-
}
|
|
12064
|
-
)
|
|
12065
|
-
] }),
|
|
12066
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex items-center justify-end gap-2 pt-1 border-t border-border/40", children: [
|
|
12067
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
12068
|
-
Button,
|
|
12069
|
-
{
|
|
12070
|
-
variant: "ghost",
|
|
12071
|
-
size: "sm",
|
|
12072
|
-
onClick: handleLtvClear,
|
|
12073
|
-
className: "text-muted-foreground hover:text-foreground h-8 px-3",
|
|
12074
|
-
children: "Clear"
|
|
12075
|
-
}
|
|
12076
|
-
),
|
|
12077
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
12078
|
-
Button,
|
|
12079
|
-
{
|
|
12080
|
-
color: "primary",
|
|
12081
|
-
size: "sm",
|
|
12082
|
-
onClick: handleLtvApply,
|
|
12083
|
-
className: "h-8 px-3",
|
|
12084
|
-
children: "Apply"
|
|
12085
|
-
}
|
|
12086
|
-
)
|
|
12087
|
-
] })
|
|
12088
|
-
] }),
|
|
12089
|
-
activeMenu === "outstanding" && /* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex flex-col gap-2.5", children: [
|
|
12090
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
12091
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "relative shrink-0", children: [
|
|
12092
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)(
|
|
12093
|
-
"button",
|
|
12094
|
-
{
|
|
12095
|
-
type: "button",
|
|
12096
|
-
onClick: () => setOutstandingOperatorOpen(!isOutstandingOperatorOpen),
|
|
12097
|
-
className: "flex h-9 items-center gap-1 rounded-lg border border-border bg-background px-2.5 text-xs font-normal text-muted-foreground hover:bg-muted/50 hover:text-foreground outline-none whitespace-nowrap",
|
|
12098
|
-
children: [
|
|
12099
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)("span", { children: OPERATORS.find((op) => op.id === outstandingOperator)?.label.replace("...", "") }),
|
|
12100
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(import_lucide_react24.ChevronDownIcon, { className: "size-3" })
|
|
12101
|
-
]
|
|
12102
|
-
}
|
|
12103
|
-
),
|
|
12104
|
-
isOutstandingOperatorOpen && /* @__PURE__ */ (0, import_jsx_runtime106.jsx)("div", { className: "absolute left-0 top-full z-50 mt-1 w-32 rounded-lg border border-border bg-popover p-1 shadow-md", children: OPERATORS.map((op) => /* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
12105
|
-
"button",
|
|
12106
|
-
{
|
|
12107
|
-
type: "button",
|
|
12108
|
-
onClick: () => {
|
|
12109
|
-
setOutstandingOperator(op.id);
|
|
12110
|
-
setOutstandingOperatorOpen(false);
|
|
12111
|
-
},
|
|
12112
|
-
className: "w-full rounded-md px-2 py-1 text-left text-xs text-foreground hover:bg-muted outline-none",
|
|
12113
|
-
children: op.label
|
|
12114
|
-
},
|
|
12115
|
-
op.id
|
|
12116
|
-
)) })
|
|
12117
|
-
] }),
|
|
12118
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
12119
|
-
"input",
|
|
12120
|
-
{
|
|
12121
|
-
type: "text",
|
|
12122
|
-
placeholder: "0.00",
|
|
12123
|
-
value: outstandingValue,
|
|
12124
|
-
onChange: (e) => setOutstandingValue(e.target.value),
|
|
12125
|
-
className: "h-9 flex-1 min-w-0 rounded-lg border border-border bg-background px-3 py-1 text-sm outline-none placeholder:text-muted-foreground/60"
|
|
12126
|
-
}
|
|
12127
|
-
)
|
|
12128
|
-
] }),
|
|
12129
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsxs)("div", { className: "flex items-center justify-end gap-2 pt-1 border-t border-border/40", children: [
|
|
12130
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
12131
|
-
Button,
|
|
12132
|
-
{
|
|
12133
|
-
variant: "ghost",
|
|
12134
|
-
size: "sm",
|
|
12135
|
-
onClick: handleOutstandingClear,
|
|
12136
|
-
className: "text-muted-foreground hover:text-foreground h-8 px-3",
|
|
12137
|
-
children: "Clear"
|
|
12138
|
-
}
|
|
12139
|
-
),
|
|
12140
|
-
/* @__PURE__ */ (0, import_jsx_runtime106.jsx)(
|
|
12141
|
-
Button,
|
|
12142
|
-
{
|
|
12143
|
-
color: "primary",
|
|
12144
|
-
size: "sm",
|
|
12145
|
-
onClick: handleOutstandingApply,
|
|
12146
|
-
className: "h-8 px-3",
|
|
12147
|
-
children: "Apply"
|
|
12148
|
-
}
|
|
12149
|
-
)
|
|
12150
|
-
] })
|
|
12151
|
-
] })
|
|
12152
|
-
]
|
|
12216
|
+
checked: value.includes(option.value),
|
|
12217
|
+
onCheckedChange: () => toggle(option.value)
|
|
12153
12218
|
}
|
|
12154
|
-
)
|
|
12155
|
-
|
|
12219
|
+
),
|
|
12220
|
+
option.icon,
|
|
12221
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("span", { className: "flex min-w-0 flex-col", children: [
|
|
12222
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { className: "truncate text-sm font-medium text-foreground", children: option.label }),
|
|
12223
|
+
option.hint && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { className: "truncate text-xs text-muted-foreground", children: option.hint })
|
|
12224
|
+
] })
|
|
12225
|
+
]
|
|
12226
|
+
},
|
|
12227
|
+
option.value
|
|
12228
|
+
)) })
|
|
12229
|
+
] });
|
|
12230
|
+
}
|
|
12231
|
+
function TextControl({
|
|
12232
|
+
field,
|
|
12233
|
+
value,
|
|
12234
|
+
onChange,
|
|
12235
|
+
onClose
|
|
12236
|
+
}) {
|
|
12237
|
+
const [draft, setDraft] = (0, import_react73.useState)(value);
|
|
12238
|
+
(0, import_react73.useEffect)(() => setDraft(value), [value]);
|
|
12239
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex flex-col gap-2.5", children: [
|
|
12240
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12241
|
+
"input",
|
|
12242
|
+
{
|
|
12243
|
+
type: "text",
|
|
12244
|
+
placeholder: field.placeholder ?? "Type a value\u2026",
|
|
12245
|
+
value: draft,
|
|
12246
|
+
onChange: (e) => setDraft(e.target.value),
|
|
12247
|
+
onKeyDown: (e) => {
|
|
12248
|
+
if (e.key === "Enter") {
|
|
12249
|
+
onChange(draft);
|
|
12250
|
+
onClose();
|
|
12251
|
+
}
|
|
12252
|
+
},
|
|
12253
|
+
className: controlClass({ size: "sm" }, "w-full")
|
|
12254
|
+
}
|
|
12255
|
+
),
|
|
12256
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12257
|
+
ApplyClear,
|
|
12258
|
+
{
|
|
12259
|
+
onClear: () => {
|
|
12260
|
+
setDraft("");
|
|
12261
|
+
onChange("");
|
|
12262
|
+
onClose();
|
|
12263
|
+
},
|
|
12264
|
+
onApply: () => {
|
|
12265
|
+
onChange(draft);
|
|
12266
|
+
onClose();
|
|
12267
|
+
}
|
|
12156
12268
|
}
|
|
12157
12269
|
)
|
|
12158
|
-
] })
|
|
12270
|
+
] });
|
|
12271
|
+
}
|
|
12272
|
+
function DateRangeControl({
|
|
12273
|
+
field,
|
|
12274
|
+
value,
|
|
12275
|
+
onChange,
|
|
12276
|
+
onClose
|
|
12277
|
+
}) {
|
|
12278
|
+
const presets = field.presets ?? DEFAULT_PRESETS;
|
|
12279
|
+
const [from, setFrom] = (0, import_react73.useState)(value.from ?? "");
|
|
12280
|
+
const [to, setTo] = (0, import_react73.useState)(value.to ?? "");
|
|
12281
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
12282
|
+
presets.map((preset) => {
|
|
12283
|
+
const isSelected = value.preset === preset.id;
|
|
12284
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)(
|
|
12285
|
+
"button",
|
|
12286
|
+
{
|
|
12287
|
+
type: "button",
|
|
12288
|
+
onClick: () => {
|
|
12289
|
+
if (preset.id === "custom") {
|
|
12290
|
+
onChange({ preset: "custom", from, to });
|
|
12291
|
+
} else {
|
|
12292
|
+
onChange({ preset: preset.id });
|
|
12293
|
+
onClose();
|
|
12294
|
+
}
|
|
12295
|
+
},
|
|
12296
|
+
className: cn(
|
|
12297
|
+
"flex w-full items-center justify-between rounded-lg px-2.5 py-1.5 text-left text-sm transition-colors outline-none",
|
|
12298
|
+
isSelected ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted/50 hover:text-foreground"
|
|
12299
|
+
),
|
|
12300
|
+
children: [
|
|
12301
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { children: preset.label }),
|
|
12302
|
+
preset.hint && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { className: "text-xs text-muted-foreground/70", children: preset.hint })
|
|
12303
|
+
]
|
|
12304
|
+
},
|
|
12305
|
+
preset.id
|
|
12306
|
+
);
|
|
12307
|
+
}),
|
|
12308
|
+
value.preset === "custom" && /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "mt-2 flex flex-col gap-2 border-t border-border/40 pt-2", children: [
|
|
12309
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
12310
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12311
|
+
"input",
|
|
12312
|
+
{
|
|
12313
|
+
type: "date",
|
|
12314
|
+
value: from,
|
|
12315
|
+
onChange: (e) => setFrom(e.target.value),
|
|
12316
|
+
className: controlClass({ size: "sm" }, "w-full text-xs")
|
|
12317
|
+
}
|
|
12318
|
+
),
|
|
12319
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("span", { className: "text-xs text-muted-foreground", children: "to" }),
|
|
12320
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12321
|
+
"input",
|
|
12322
|
+
{
|
|
12323
|
+
type: "date",
|
|
12324
|
+
value: to,
|
|
12325
|
+
onChange: (e) => setTo(e.target.value),
|
|
12326
|
+
className: controlClass({ size: "sm" }, "w-full text-xs")
|
|
12327
|
+
}
|
|
12328
|
+
)
|
|
12329
|
+
] }),
|
|
12330
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("div", { className: "flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12331
|
+
Button,
|
|
12332
|
+
{
|
|
12333
|
+
color: "primary",
|
|
12334
|
+
size: "sm",
|
|
12335
|
+
className: "h-8 px-3",
|
|
12336
|
+
onClick: () => {
|
|
12337
|
+
onChange({ preset: "custom", from, to });
|
|
12338
|
+
onClose();
|
|
12339
|
+
},
|
|
12340
|
+
children: "Apply"
|
|
12341
|
+
}
|
|
12342
|
+
) })
|
|
12343
|
+
] })
|
|
12344
|
+
] });
|
|
12345
|
+
}
|
|
12346
|
+
function NumericControl({
|
|
12347
|
+
field,
|
|
12348
|
+
value,
|
|
12349
|
+
onChange,
|
|
12350
|
+
onClose
|
|
12351
|
+
}) {
|
|
12352
|
+
const operators = field.operators ?? DEFAULT_OPERATORS;
|
|
12353
|
+
const [operator, setOperator] = (0, import_react73.useState)(value.operator);
|
|
12354
|
+
const [draft, setDraft] = (0, import_react73.useState)(value.value);
|
|
12355
|
+
(0, import_react73.useEffect)(() => {
|
|
12356
|
+
setOperator(value.operator);
|
|
12357
|
+
setDraft(value.value);
|
|
12358
|
+
}, [value.operator, value.value]);
|
|
12359
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex flex-col gap-2.5", children: [
|
|
12360
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
12361
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsxs)(Select, { value: operator, onValueChange: (v) => setOperator(v), children: [
|
|
12362
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(SelectTrigger, { size: "sm", className: "shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(SelectValue, {}) }),
|
|
12363
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(SelectContent, { children: operators.map((op) => /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(SelectItem, { value: op.id, children: op.label }, op.id)) })
|
|
12364
|
+
] }),
|
|
12365
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12366
|
+
"input",
|
|
12367
|
+
{
|
|
12368
|
+
type: "text",
|
|
12369
|
+
inputMode: "decimal",
|
|
12370
|
+
placeholder: field.placeholder ?? "0.00",
|
|
12371
|
+
value: draft,
|
|
12372
|
+
onChange: (e) => setDraft(e.target.value),
|
|
12373
|
+
onKeyDown: (e) => {
|
|
12374
|
+
if (e.key === "Enter") {
|
|
12375
|
+
onChange(draft ? { operator, value: draft } : null);
|
|
12376
|
+
onClose();
|
|
12377
|
+
}
|
|
12378
|
+
},
|
|
12379
|
+
className: controlClass({ size: "sm" }, "min-w-0 flex-1")
|
|
12380
|
+
}
|
|
12381
|
+
)
|
|
12382
|
+
] }),
|
|
12383
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12384
|
+
ApplyClear,
|
|
12385
|
+
{
|
|
12386
|
+
onClear: () => {
|
|
12387
|
+
setDraft("");
|
|
12388
|
+
onChange(null);
|
|
12389
|
+
onClose();
|
|
12390
|
+
},
|
|
12391
|
+
onApply: () => {
|
|
12392
|
+
onChange(draft ? { operator, value: draft } : null);
|
|
12393
|
+
onClose();
|
|
12394
|
+
}
|
|
12395
|
+
}
|
|
12396
|
+
)
|
|
12397
|
+
] });
|
|
12398
|
+
}
|
|
12399
|
+
function ApplyClear({ onClear, onApply }) {
|
|
12400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("div", { className: "flex items-center justify-end gap-2 border-t border-border/40 pt-1", children: [
|
|
12401
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
12402
|
+
Button,
|
|
12403
|
+
{
|
|
12404
|
+
variant: "ghost",
|
|
12405
|
+
size: "sm",
|
|
12406
|
+
onClick: onClear,
|
|
12407
|
+
className: "h-8 px-3 text-muted-foreground hover:text-foreground",
|
|
12408
|
+
children: "Clear"
|
|
12409
|
+
}
|
|
12410
|
+
),
|
|
12411
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(Button, { color: "primary", size: "sm", onClick: onApply, className: "h-8 px-3", children: "Apply" })
|
|
12412
|
+
] });
|
|
12159
12413
|
}
|
|
12160
12414
|
|
|
12161
12415
|
// src/app/data/DataTable.tsx
|
|
12162
12416
|
var import_react74 = require("react");
|
|
12163
|
-
var
|
|
12417
|
+
var import_lucide_react26 = require("lucide-react");
|
|
12164
12418
|
|
|
12165
12419
|
// src/ui/skeleton.tsx
|
|
12166
|
-
var
|
|
12420
|
+
var import_jsx_runtime108 = require("react/jsx-runtime");
|
|
12167
12421
|
function Skeleton({ className, ...props }) {
|
|
12168
|
-
return /* @__PURE__ */ (0,
|
|
12422
|
+
return /* @__PURE__ */ (0, import_jsx_runtime108.jsx)(
|
|
12169
12423
|
"div",
|
|
12170
12424
|
{
|
|
12171
12425
|
"data-slot": "skeleton",
|
|
@@ -12176,7 +12430,7 @@ function Skeleton({ className, ...props }) {
|
|
|
12176
12430
|
}
|
|
12177
12431
|
|
|
12178
12432
|
// src/app/data/DataTable.tsx
|
|
12179
|
-
var
|
|
12433
|
+
var import_jsx_runtime109 = require("react/jsx-runtime");
|
|
12180
12434
|
var shellClass2 = "w-full";
|
|
12181
12435
|
var tableClass = "w-full border-separate border-spacing-0 bg-transparent text-sm";
|
|
12182
12436
|
var headRowClass = "";
|
|
@@ -12219,12 +12473,12 @@ function SortIndicator({
|
|
|
12219
12473
|
}) {
|
|
12220
12474
|
const iconClass = "size-3.5 shrink-0 opacity-60 group-hover:opacity-100";
|
|
12221
12475
|
if (!active) {
|
|
12222
|
-
return /* @__PURE__ */ (0,
|
|
12476
|
+
return /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(import_lucide_react26.ArrowUpDownIcon, { className: iconClass, "aria-hidden": true });
|
|
12223
12477
|
}
|
|
12224
12478
|
if (direction === "desc") {
|
|
12225
|
-
return /* @__PURE__ */ (0,
|
|
12479
|
+
return /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(import_lucide_react26.ArrowDownIcon, { className: iconClass, "aria-hidden": true });
|
|
12226
12480
|
}
|
|
12227
|
-
return /* @__PURE__ */ (0,
|
|
12481
|
+
return /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(import_lucide_react26.ArrowUpIcon, { className: iconClass, "aria-hidden": true });
|
|
12228
12482
|
}
|
|
12229
12483
|
function DataTable({
|
|
12230
12484
|
columns,
|
|
@@ -12322,7 +12576,7 @@ function DataTable({
|
|
|
12322
12576
|
const headPad = dense ? "px-3 py-2" : void 0;
|
|
12323
12577
|
const colSpan = columns.length + (selectable ? 1 : 0);
|
|
12324
12578
|
if (!loading && rows.length === 0 && emptyMode === "replace") {
|
|
12325
|
-
return /* @__PURE__ */ (0,
|
|
12579
|
+
return /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(EmptyState, { title: emptyTitle, description: emptyDescription, className });
|
|
12326
12580
|
}
|
|
12327
12581
|
const allKeys = sortedRows.map(getRowKey);
|
|
12328
12582
|
const allSelected = allKeys.length > 0 && allKeys.every((k) => selectedSet.has(k));
|
|
@@ -12347,10 +12601,10 @@ function DataTable({
|
|
|
12347
12601
|
const hasPager = paginated && !loading && sortedRows.length > 0;
|
|
12348
12602
|
const hasFoot = (showRowCount || footer || hasPager) && (loading || sortedRows.length > 0);
|
|
12349
12603
|
const skeletonCount = loadingRows ?? pageSize ?? 5;
|
|
12350
|
-
return /* @__PURE__ */ (0,
|
|
12351
|
-
caption ? /* @__PURE__ */ (0,
|
|
12352
|
-
/* @__PURE__ */ (0,
|
|
12353
|
-
selectable ? /* @__PURE__ */ (0,
|
|
12604
|
+
return /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("div", { className: cn("aui-app-data-table", shellClass2, className), children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("table", { className: tableClass, children: [
|
|
12605
|
+
caption ? /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("caption", { className: "sr-only", children: caption }) : null,
|
|
12606
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)("thead", { className: cn(headRowClass, stickyHeader && stickyHeadClass), children: /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("tr", { children: [
|
|
12607
|
+
selectable ? /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("th", { scope: "col", className: cn(selectCellClass, headPad), children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
12354
12608
|
Checkbox,
|
|
12355
12609
|
{
|
|
12356
12610
|
checked: headerCheckedState,
|
|
@@ -12362,19 +12616,19 @@ function DataTable({
|
|
|
12362
12616
|
columns.map((col) => {
|
|
12363
12617
|
const isSorted = sort?.columnId === col.id;
|
|
12364
12618
|
const ariaSort = col.sortable ? isSorted ? sort.direction === "asc" ? "ascending" : "descending" : "none" : void 0;
|
|
12365
|
-
const headerContent = col.sortable ? /* @__PURE__ */ (0,
|
|
12619
|
+
const headerContent = col.sortable ? /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)(
|
|
12366
12620
|
"button",
|
|
12367
12621
|
{
|
|
12368
12622
|
type: "button",
|
|
12369
12623
|
className: sortButtonClass,
|
|
12370
12624
|
onClick: () => setSort(nextSort(sort, col.id)),
|
|
12371
12625
|
children: [
|
|
12372
|
-
/* @__PURE__ */ (0,
|
|
12373
|
-
/* @__PURE__ */ (0,
|
|
12626
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)("span", { className: "truncate", children: col.header }),
|
|
12627
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)(SortIndicator, { active: Boolean(isSorted), direction: sort?.direction })
|
|
12374
12628
|
]
|
|
12375
12629
|
}
|
|
12376
12630
|
) : col.header;
|
|
12377
|
-
return /* @__PURE__ */ (0,
|
|
12631
|
+
return /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
12378
12632
|
"th",
|
|
12379
12633
|
{
|
|
12380
12634
|
scope: "col",
|
|
@@ -12391,9 +12645,9 @@ function DataTable({
|
|
|
12391
12645
|
);
|
|
12392
12646
|
})
|
|
12393
12647
|
] }) }),
|
|
12394
|
-
/* @__PURE__ */ (0,
|
|
12395
|
-
selectable ? /* @__PURE__ */ (0,
|
|
12396
|
-
columns.map((col) => /* @__PURE__ */ (0,
|
|
12648
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)("tbody", { className: cn(!hasFoot && "[&_tr:last-child_td]:border-b-0"), children: loading ? Array.from({ length: skeletonCount }).map((_, rowIdx) => /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("tr", { className: rowClass, "aria-hidden": true, children: [
|
|
12649
|
+
selectable ? /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("td", { className: cn(selectCellClass, cellPad), children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(Skeleton, { className: "size-4 rounded-[4px]" }) }) : null,
|
|
12650
|
+
columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
12397
12651
|
"td",
|
|
12398
12652
|
{
|
|
12399
12653
|
className: cn(
|
|
@@ -12402,17 +12656,17 @@ function DataTable({
|
|
|
12402
12656
|
col.align && alignClass[col.align],
|
|
12403
12657
|
col.className
|
|
12404
12658
|
),
|
|
12405
|
-
children: /* @__PURE__ */ (0,
|
|
12659
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(Skeleton, { className: "h-4 w-[60%]" })
|
|
12406
12660
|
},
|
|
12407
12661
|
col.id
|
|
12408
12662
|
))
|
|
12409
|
-
] }, `skeleton-${rowIdx}`)) : visibleRows.length === 0 ? /* @__PURE__ */ (0,
|
|
12410
|
-
/* @__PURE__ */ (0,
|
|
12411
|
-
emptyDescription ? /* @__PURE__ */ (0,
|
|
12663
|
+
] }, `skeleton-${rowIdx}`)) : visibleRows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("td", { colSpan, className: emptyCellClass, children: /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
|
|
12664
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)("p", { className: "font-medium text-foreground", children: emptyTitle }),
|
|
12665
|
+
emptyDescription ? /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("p", { className: "max-w-sm text-muted-foreground", children: emptyDescription }) : null
|
|
12412
12666
|
] }) }) }) : visibleRows.map((row) => {
|
|
12413
12667
|
const key = getRowKey(row);
|
|
12414
12668
|
const isSelected = selectedSet.has(key);
|
|
12415
|
-
return /* @__PURE__ */ (0,
|
|
12669
|
+
return /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)(
|
|
12416
12670
|
"tr",
|
|
12417
12671
|
{
|
|
12418
12672
|
className: rowClass,
|
|
@@ -12428,12 +12682,12 @@ function DataTable({
|
|
|
12428
12682
|
tabIndex: onRowClick ? 0 : void 0,
|
|
12429
12683
|
role: onRowClick ? "button" : void 0,
|
|
12430
12684
|
children: [
|
|
12431
|
-
selectable ? /* @__PURE__ */ (0,
|
|
12685
|
+
selectable ? /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
12432
12686
|
"td",
|
|
12433
12687
|
{
|
|
12434
12688
|
className: cn(selectCellClass, cellPad),
|
|
12435
12689
|
onClick: (event) => event.stopPropagation(),
|
|
12436
|
-
children: /* @__PURE__ */ (0,
|
|
12690
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
12437
12691
|
Checkbox,
|
|
12438
12692
|
{
|
|
12439
12693
|
checked: isSelected,
|
|
@@ -12443,7 +12697,7 @@ function DataTable({
|
|
|
12443
12697
|
)
|
|
12444
12698
|
}
|
|
12445
12699
|
) : null,
|
|
12446
|
-
columns.map((col) => /* @__PURE__ */ (0,
|
|
12700
|
+
columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
12447
12701
|
"td",
|
|
12448
12702
|
{
|
|
12449
12703
|
className: cn(
|
|
@@ -12453,7 +12707,7 @@ function DataTable({
|
|
|
12453
12707
|
col.align && alignClass[col.align],
|
|
12454
12708
|
col.className
|
|
12455
12709
|
),
|
|
12456
|
-
children: col.truncate ? /* @__PURE__ */ (0,
|
|
12710
|
+
children: col.truncate ? /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("div", { className: "truncate", children: col.cell(row) }) : col.cell(row)
|
|
12457
12711
|
},
|
|
12458
12712
|
col.id
|
|
12459
12713
|
))
|
|
@@ -12462,7 +12716,7 @@ function DataTable({
|
|
|
12462
12716
|
key
|
|
12463
12717
|
);
|
|
12464
12718
|
}) }),
|
|
12465
|
-
hasFoot ? /* @__PURE__ */ (0,
|
|
12719
|
+
hasFoot ? /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("tfoot", { children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)("td", { colSpan, className: footCellClass, children: /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)(
|
|
12466
12720
|
"div",
|
|
12467
12721
|
{
|
|
12468
12722
|
className: cn(
|
|
@@ -12470,18 +12724,18 @@ function DataTable({
|
|
|
12470
12724
|
(showRowCount || footer || hasPager) && "justify-between"
|
|
12471
12725
|
),
|
|
12472
12726
|
children: [
|
|
12473
|
-
/* @__PURE__ */ (0,
|
|
12474
|
-
showRowCount ? /* @__PURE__ */ (0,
|
|
12727
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { className: footInnerClass, children: [
|
|
12728
|
+
showRowCount ? /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("span", { children: [
|
|
12475
12729
|
rowCountText,
|
|
12476
12730
|
selectable && selectedSet.size > 0 ? ` \xB7 ${selectedSet.size} selected` : null
|
|
12477
|
-
] }) : selectable && selectedSet.size > 0 ? /* @__PURE__ */ (0,
|
|
12731
|
+
] }) : selectable && selectedSet.size > 0 ? /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("span", { children: [
|
|
12478
12732
|
selectedSet.size,
|
|
12479
12733
|
" selected"
|
|
12480
12734
|
] }) : null,
|
|
12481
12735
|
footer
|
|
12482
12736
|
] }),
|
|
12483
|
-
hasPager ? /* @__PURE__ */ (0,
|
|
12484
|
-
/* @__PURE__ */ (0,
|
|
12737
|
+
hasPager ? /* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
12738
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("span", { className: "tabular-nums", children: [
|
|
12485
12739
|
pageIndex * pageSize + 1,
|
|
12486
12740
|
"\u2013",
|
|
12487
12741
|
Math.min(
|
|
@@ -12492,8 +12746,8 @@ function DataTable({
|
|
|
12492
12746
|
"of ",
|
|
12493
12747
|
sortedRows.length
|
|
12494
12748
|
] }),
|
|
12495
|
-
/* @__PURE__ */ (0,
|
|
12496
|
-
/* @__PURE__ */ (0,
|
|
12749
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
12750
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
12497
12751
|
"button",
|
|
12498
12752
|
{
|
|
12499
12753
|
type: "button",
|
|
@@ -12501,10 +12755,10 @@ function DataTable({
|
|
|
12501
12755
|
onClick: () => setPage(pageIndex - 1),
|
|
12502
12756
|
disabled: pageIndex <= 0,
|
|
12503
12757
|
"aria-label": "Previous page",
|
|
12504
|
-
children: /* @__PURE__ */ (0,
|
|
12758
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(import_lucide_react26.ChevronLeftIcon, { className: "size-4", "aria-hidden": true })
|
|
12505
12759
|
}
|
|
12506
12760
|
),
|
|
12507
|
-
/* @__PURE__ */ (0,
|
|
12761
|
+
/* @__PURE__ */ (0, import_jsx_runtime109.jsx)(
|
|
12508
12762
|
"button",
|
|
12509
12763
|
{
|
|
12510
12764
|
type: "button",
|
|
@@ -12512,7 +12766,7 @@ function DataTable({
|
|
|
12512
12766
|
onClick: () => setPage(pageIndex + 1),
|
|
12513
12767
|
disabled: pageIndex >= pageCount - 1,
|
|
12514
12768
|
"aria-label": "Next page",
|
|
12515
|
-
children: /* @__PURE__ */ (0,
|
|
12769
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime109.jsx)(import_lucide_react26.ChevronRightIcon, { className: "size-4", "aria-hidden": true })
|
|
12516
12770
|
}
|
|
12517
12771
|
)
|
|
12518
12772
|
] })
|
|
@@ -12525,7 +12779,7 @@ function DataTable({
|
|
|
12525
12779
|
|
|
12526
12780
|
// src/app/data/ChartPanel.tsx
|
|
12527
12781
|
var import_react75 = require("react");
|
|
12528
|
-
var
|
|
12782
|
+
var import_jsx_runtime110 = require("react/jsx-runtime");
|
|
12529
12783
|
var ChartPanel = ({
|
|
12530
12784
|
title,
|
|
12531
12785
|
description,
|
|
@@ -12543,14 +12797,14 @@ var ChartPanel = ({
|
|
|
12543
12797
|
const titleId = (0, import_react75.useId)();
|
|
12544
12798
|
const resolvedTitle = title ?? artifact?.title;
|
|
12545
12799
|
const hasHeader = Boolean(resolvedTitle || description || actions);
|
|
12546
|
-
const body = loading ? /* @__PURE__ */ (0,
|
|
12547
|
-
return /* @__PURE__ */ (0,
|
|
12800
|
+
const body = loading ? /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(Skeleton, { className: "w-full rounded-lg", style: { height }, "aria-hidden": true }) : children ?? (artifact ? /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(ChartArtifactView, { artifact, embedded: true, height }) : null);
|
|
12801
|
+
return /* @__PURE__ */ (0, import_jsx_runtime110.jsxs)(
|
|
12548
12802
|
"section",
|
|
12549
12803
|
{
|
|
12550
12804
|
className: cn(metricCardShellClass, "aui-app-chart-panel", className),
|
|
12551
12805
|
"aria-labelledby": resolvedTitle ? titleId : void 0,
|
|
12552
12806
|
children: [
|
|
12553
|
-
/* @__PURE__ */ (0,
|
|
12807
|
+
/* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
12554
12808
|
MetricCardHeader,
|
|
12555
12809
|
{
|
|
12556
12810
|
title: resolvedTitle,
|
|
@@ -12559,14 +12813,14 @@ var ChartPanel = ({
|
|
|
12559
12813
|
actions
|
|
12560
12814
|
}
|
|
12561
12815
|
),
|
|
12562
|
-
/* @__PURE__ */ (0,
|
|
12816
|
+
/* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
12563
12817
|
"div",
|
|
12564
12818
|
{
|
|
12565
12819
|
className: cn(
|
|
12566
12820
|
"relative min-h-0 w-full",
|
|
12567
12821
|
hasHeader ? metricChartPlotRegionClass : chartPanelBodyClass
|
|
12568
12822
|
),
|
|
12569
|
-
children: body ?? /* @__PURE__ */ (0,
|
|
12823
|
+
children: body ?? /* @__PURE__ */ (0, import_jsx_runtime110.jsx)(
|
|
12570
12824
|
"div",
|
|
12571
12825
|
{
|
|
12572
12826
|
className: "flex items-center justify-center text-sm font-normal text-muted-foreground",
|
|
@@ -12584,7 +12838,7 @@ var ChartPanel = ({
|
|
|
12584
12838
|
|
|
12585
12839
|
// src/app/data/MetricRow.tsx
|
|
12586
12840
|
var import_react76 = require("react");
|
|
12587
|
-
var
|
|
12841
|
+
var import_jsx_runtime111 = require("react/jsx-runtime");
|
|
12588
12842
|
var MetricRow = ({
|
|
12589
12843
|
title,
|
|
12590
12844
|
titleTag,
|
|
@@ -12610,13 +12864,13 @@ var MetricRow = ({
|
|
|
12610
12864
|
onMetricChange?.(id);
|
|
12611
12865
|
};
|
|
12612
12866
|
const hasHeader = Boolean(title || titleTag || description || actions);
|
|
12613
|
-
return /* @__PURE__ */ (0,
|
|
12867
|
+
return /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
|
|
12614
12868
|
"section",
|
|
12615
12869
|
{
|
|
12616
12870
|
className: cn(metricCardShellClass, className),
|
|
12617
12871
|
"aria-labelledby": title ? titleId : void 0,
|
|
12618
12872
|
children: [
|
|
12619
|
-
/* @__PURE__ */ (0,
|
|
12873
|
+
/* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
|
|
12620
12874
|
MetricCardHeader,
|
|
12621
12875
|
{
|
|
12622
12876
|
title,
|
|
@@ -12626,7 +12880,7 @@ var MetricRow = ({
|
|
|
12626
12880
|
actions
|
|
12627
12881
|
}
|
|
12628
12882
|
),
|
|
12629
|
-
/* @__PURE__ */ (0,
|
|
12883
|
+
/* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
|
|
12630
12884
|
"div",
|
|
12631
12885
|
{
|
|
12632
12886
|
role: selectable ? "group" : void 0,
|
|
@@ -12637,18 +12891,18 @@ var MetricRow = ({
|
|
|
12637
12891
|
metricTilesGridColsClass(loading ? metrics.length || 4 : metrics.length),
|
|
12638
12892
|
hasHeader && "mt-3.5 border-t border-border/40"
|
|
12639
12893
|
),
|
|
12640
|
-
children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */ (0,
|
|
12894
|
+
children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)(
|
|
12641
12895
|
"div",
|
|
12642
12896
|
{
|
|
12643
12897
|
className: cn("flex min-w-0 flex-1 flex-col gap-2", metricTileClass),
|
|
12644
12898
|
"aria-hidden": true,
|
|
12645
12899
|
children: [
|
|
12646
|
-
/* @__PURE__ */ (0,
|
|
12647
|
-
/* @__PURE__ */ (0,
|
|
12900
|
+
/* @__PURE__ */ (0, import_jsx_runtime111.jsx)(Skeleton, { className: "h-3 w-20" }),
|
|
12901
|
+
/* @__PURE__ */ (0, import_jsx_runtime111.jsx)(Skeleton, { className: "h-7 w-24" })
|
|
12648
12902
|
]
|
|
12649
12903
|
},
|
|
12650
12904
|
`skeleton-${index}`
|
|
12651
|
-
)) : metrics.map((m, index) => /* @__PURE__ */ (0,
|
|
12905
|
+
)) : metrics.map((m, index) => /* @__PURE__ */ (0, import_jsx_runtime111.jsx)(
|
|
12652
12906
|
MetricTile,
|
|
12653
12907
|
{
|
|
12654
12908
|
label: m.label,
|
|
@@ -12676,7 +12930,7 @@ var MetricRow = ({
|
|
|
12676
12930
|
|
|
12677
12931
|
// src/app/data/MetricChartCard.tsx
|
|
12678
12932
|
var import_react77 = require("react");
|
|
12679
|
-
var
|
|
12933
|
+
var import_jsx_runtime112 = require("react/jsx-runtime");
|
|
12680
12934
|
var MetricChartCard = ({
|
|
12681
12935
|
title,
|
|
12682
12936
|
titleTag,
|
|
@@ -12712,13 +12966,13 @@ var MetricChartCard = ({
|
|
|
12712
12966
|
};
|
|
12713
12967
|
const hasHeader = Boolean(title || titleTag || description || actions);
|
|
12714
12968
|
const chartAriaLabel = typeof active?.label === "string" ? `${active.label} over time` : "Metric chart";
|
|
12715
|
-
return /* @__PURE__ */ (0,
|
|
12969
|
+
return /* @__PURE__ */ (0, import_jsx_runtime112.jsxs)(
|
|
12716
12970
|
"section",
|
|
12717
12971
|
{
|
|
12718
12972
|
className: cn(metricCardShellClass, className),
|
|
12719
12973
|
"aria-labelledby": title ? titleId : void 0,
|
|
12720
12974
|
children: [
|
|
12721
|
-
/* @__PURE__ */ (0,
|
|
12975
|
+
/* @__PURE__ */ (0, import_jsx_runtime112.jsx)(
|
|
12722
12976
|
MetricCardHeader,
|
|
12723
12977
|
{
|
|
12724
12978
|
title,
|
|
@@ -12728,7 +12982,7 @@ var MetricChartCard = ({
|
|
|
12728
12982
|
titleId
|
|
12729
12983
|
}
|
|
12730
12984
|
),
|
|
12731
|
-
/* @__PURE__ */ (0,
|
|
12985
|
+
/* @__PURE__ */ (0, import_jsx_runtime112.jsx)(
|
|
12732
12986
|
"div",
|
|
12733
12987
|
{
|
|
12734
12988
|
role: "group",
|
|
@@ -12739,18 +12993,18 @@ var MetricChartCard = ({
|
|
|
12739
12993
|
metricTilesGridColsClass(loading ? metrics.length || 4 : metrics.length),
|
|
12740
12994
|
hasHeader && "mt-3.5 border-t border-border/40"
|
|
12741
12995
|
),
|
|
12742
|
-
children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */ (0,
|
|
12996
|
+
children: loading ? Array.from({ length: metrics.length || 4 }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime112.jsxs)(
|
|
12743
12997
|
"div",
|
|
12744
12998
|
{
|
|
12745
12999
|
className: cn("flex min-w-0 flex-1 flex-col gap-2", metricTileClass),
|
|
12746
13000
|
"aria-hidden": true,
|
|
12747
13001
|
children: [
|
|
12748
|
-
/* @__PURE__ */ (0,
|
|
12749
|
-
/* @__PURE__ */ (0,
|
|
13002
|
+
/* @__PURE__ */ (0, import_jsx_runtime112.jsx)(Skeleton, { className: "h-3 w-20" }),
|
|
13003
|
+
/* @__PURE__ */ (0, import_jsx_runtime112.jsx)(Skeleton, { className: "h-7 w-24" })
|
|
12750
13004
|
]
|
|
12751
13005
|
},
|
|
12752
13006
|
`skeleton-${index}`
|
|
12753
|
-
)) : metrics.map((m, index) => /* @__PURE__ */ (0,
|
|
13007
|
+
)) : metrics.map((m, index) => /* @__PURE__ */ (0, import_jsx_runtime112.jsx)(
|
|
12754
13008
|
MetricTile,
|
|
12755
13009
|
{
|
|
12756
13010
|
label: m.label,
|
|
@@ -12771,14 +13025,14 @@ var MetricChartCard = ({
|
|
|
12771
13025
|
))
|
|
12772
13026
|
}
|
|
12773
13027
|
),
|
|
12774
|
-
/* @__PURE__ */ (0,
|
|
13028
|
+
/* @__PURE__ */ (0, import_jsx_runtime112.jsx)("div", { className: metricChartRegionClass, "aria-live": "polite", "aria-atomic": "true", children: loading ? /* @__PURE__ */ (0, import_jsx_runtime112.jsx)(
|
|
12775
13029
|
Skeleton,
|
|
12776
13030
|
{
|
|
12777
13031
|
className: "w-full rounded-lg",
|
|
12778
13032
|
style: { height },
|
|
12779
13033
|
"aria-hidden": true
|
|
12780
13034
|
}
|
|
12781
|
-
) : active?.data && active.data.length > 0 ? /* @__PURE__ */ (0,
|
|
13035
|
+
) : active?.data && active.data.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime112.jsx)(
|
|
12782
13036
|
LineAreaChart,
|
|
12783
13037
|
{
|
|
12784
13038
|
data: active.data,
|
|
@@ -12798,7 +13052,7 @@ var MetricChartCard = ({
|
|
|
12798
13052
|
ariaLabel: chartAriaLabel
|
|
12799
13053
|
},
|
|
12800
13054
|
active.id
|
|
12801
|
-
) : /* @__PURE__ */ (0,
|
|
13055
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime112.jsx)(
|
|
12802
13056
|
"div",
|
|
12803
13057
|
{
|
|
12804
13058
|
className: "flex w-full items-center justify-center text-sm font-normal text-muted-foreground",
|
|
@@ -12904,8 +13158,8 @@ function useLiveQuery(fetcher, options = {}) {
|
|
|
12904
13158
|
|
|
12905
13159
|
// src/ui/untitled-button.tsx
|
|
12906
13160
|
var import_class_variance_authority2 = require("class-variance-authority");
|
|
12907
|
-
var
|
|
12908
|
-
var
|
|
13161
|
+
var import_radix_ui10 = require("radix-ui");
|
|
13162
|
+
var import_jsx_runtime113 = require("react/jsx-runtime");
|
|
12909
13163
|
var SOLID_SKEUOMORPHIC_SHADOW2 = "shadow-skeuomorphic-solid";
|
|
12910
13164
|
var BORDERED_SKEUOMORPHIC_SHADOW2 = "shadow-skeuomorphic-bordered";
|
|
12911
13165
|
var untitledButtonVariants = (0, import_class_variance_authority2.cva)(
|
|
@@ -12988,10 +13242,10 @@ var untitledButtonVariants = (0, import_class_variance_authority2.cva)(
|
|
|
12988
13242
|
)
|
|
12989
13243
|
},
|
|
12990
13244
|
size: {
|
|
12991
|
-
sm: "h-
|
|
12992
|
-
md: "h-
|
|
12993
|
-
lg: "h-
|
|
12994
|
-
xl: "h-
|
|
13245
|
+
sm: "h-8 gap-1 rounded-md px-2.5 text-xs",
|
|
13246
|
+
md: "h-9 gap-1.5 rounded-lg px-3 text-sm",
|
|
13247
|
+
lg: "h-10 gap-1.5 rounded-lg px-3.5 text-sm",
|
|
13248
|
+
xl: "h-11 gap-2 rounded-lg px-4 text-base"
|
|
12995
13249
|
}
|
|
12996
13250
|
},
|
|
12997
13251
|
defaultVariants: {
|
|
@@ -13016,8 +13270,8 @@ function UntitledButton({
|
|
|
13016
13270
|
const isDisabled = disabled || isLoading;
|
|
13017
13271
|
const classes = cn(untitledButtonVariants({ color, size }), className);
|
|
13018
13272
|
if (asChild) {
|
|
13019
|
-
return /* @__PURE__ */ (0,
|
|
13020
|
-
|
|
13273
|
+
return /* @__PURE__ */ (0, import_jsx_runtime113.jsx)(
|
|
13274
|
+
import_radix_ui10.Slot.Root,
|
|
13021
13275
|
{
|
|
13022
13276
|
className: classes,
|
|
13023
13277
|
"aria-disabled": isDisabled ? true : void 0,
|
|
@@ -13027,7 +13281,7 @@ function UntitledButton({
|
|
|
13027
13281
|
}
|
|
13028
13282
|
);
|
|
13029
13283
|
}
|
|
13030
|
-
return /* @__PURE__ */ (0,
|
|
13284
|
+
return /* @__PURE__ */ (0, import_jsx_runtime113.jsxs)(
|
|
13031
13285
|
"button",
|
|
13032
13286
|
{
|
|
13033
13287
|
type,
|
|
@@ -13036,7 +13290,7 @@ function UntitledButton({
|
|
|
13036
13290
|
className: classes,
|
|
13037
13291
|
...props,
|
|
13038
13292
|
children: [
|
|
13039
|
-
isLoading ? /* @__PURE__ */ (0,
|
|
13293
|
+
isLoading ? /* @__PURE__ */ (0, import_jsx_runtime113.jsx)(
|
|
13040
13294
|
"span",
|
|
13041
13295
|
{
|
|
13042
13296
|
"aria-hidden": true,
|
|
@@ -13051,8 +13305,8 @@ function UntitledButton({
|
|
|
13051
13305
|
}
|
|
13052
13306
|
|
|
13053
13307
|
// src/ui/banner.tsx
|
|
13054
|
-
var
|
|
13055
|
-
var
|
|
13308
|
+
var import_lucide_react27 = require("lucide-react");
|
|
13309
|
+
var import_jsx_runtime114 = require("react/jsx-runtime");
|
|
13056
13310
|
var bannerSoftClass = {
|
|
13057
13311
|
default: "border-border/50 bg-muted/30 text-foreground/90 dark:bg-muted/15",
|
|
13058
13312
|
primary: "border-primary/15 bg-primary/5 text-primary-800 dark:text-primary-200 [&_[data-banner-icon]]:text-primary",
|
|
@@ -13097,7 +13351,7 @@ function Banner({
|
|
|
13097
13351
|
}) {
|
|
13098
13352
|
const isSolid = variant === "solid";
|
|
13099
13353
|
const isSingleLine = !title;
|
|
13100
|
-
return /* @__PURE__ */ (0,
|
|
13354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime114.jsxs)(
|
|
13101
13355
|
"div",
|
|
13102
13356
|
{
|
|
13103
13357
|
"data-slot": "banner",
|
|
@@ -13112,7 +13366,7 @@ function Banner({
|
|
|
13112
13366
|
),
|
|
13113
13367
|
...props,
|
|
13114
13368
|
children: [
|
|
13115
|
-
icon ? /* @__PURE__ */ (0,
|
|
13369
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
13116
13370
|
"span",
|
|
13117
13371
|
{
|
|
13118
13372
|
"data-banner-icon": true,
|
|
@@ -13123,9 +13377,9 @@ function Banner({
|
|
|
13123
13377
|
children: icon
|
|
13124
13378
|
}
|
|
13125
13379
|
) : null,
|
|
13126
|
-
/* @__PURE__ */ (0,
|
|
13127
|
-
title ? /* @__PURE__ */ (0,
|
|
13128
|
-
children ? /* @__PURE__ */ (0,
|
|
13380
|
+
/* @__PURE__ */ (0, import_jsx_runtime114.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
13381
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime114.jsx)("p", { className: "font-medium tracking-tight", children: title }) : null,
|
|
13382
|
+
children ? /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
13129
13383
|
"div",
|
|
13130
13384
|
{
|
|
13131
13385
|
className: cn(
|
|
@@ -13136,8 +13390,8 @@ function Banner({
|
|
|
13136
13390
|
}
|
|
13137
13391
|
) : null
|
|
13138
13392
|
] }),
|
|
13139
|
-
actions ? /* @__PURE__ */ (0,
|
|
13140
|
-
onDismiss ? /* @__PURE__ */ (0,
|
|
13393
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime114.jsx)("div", { className: "flex shrink-0 items-center gap-2", children: actions }) : null,
|
|
13394
|
+
onDismiss ? /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(
|
|
13141
13395
|
"button",
|
|
13142
13396
|
{
|
|
13143
13397
|
type: "button",
|
|
@@ -13148,7 +13402,7 @@ function Banner({
|
|
|
13148
13402
|
isSingleLine ? "self-center" : "-mt-0.5",
|
|
13149
13403
|
isSolid ? "opacity-80 hover:bg-background/15 hover:opacity-100" : "text-muted-foreground hover:bg-foreground/10 hover:text-foreground"
|
|
13150
13404
|
),
|
|
13151
|
-
children: /* @__PURE__ */ (0,
|
|
13405
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(import_lucide_react27.XIcon, { className: "size-4", "aria-hidden": true })
|
|
13152
13406
|
}
|
|
13153
13407
|
) : null
|
|
13154
13408
|
]
|
|
@@ -13157,7 +13411,7 @@ function Banner({
|
|
|
13157
13411
|
}
|
|
13158
13412
|
|
|
13159
13413
|
// src/ui/timeline.tsx
|
|
13160
|
-
var
|
|
13414
|
+
var import_jsx_runtime115 = require("react/jsx-runtime");
|
|
13161
13415
|
var timelineRowGap = {
|
|
13162
13416
|
sm: "pb-4",
|
|
13163
13417
|
default: "pb-6"
|
|
@@ -13190,16 +13444,16 @@ var toneStyles = {
|
|
|
13190
13444
|
}
|
|
13191
13445
|
};
|
|
13192
13446
|
function Timeline({ items, size = "default", className, ...props }) {
|
|
13193
|
-
return /* @__PURE__ */ (0,
|
|
13447
|
+
return /* @__PURE__ */ (0, import_jsx_runtime115.jsx)("ol", { "data-slot": "timeline", className: cn("flex flex-col", className), ...props, children: items.map((item, index) => {
|
|
13194
13448
|
const last = index === items.length - 1;
|
|
13195
13449
|
const tone = item.tone ?? "default";
|
|
13196
13450
|
const styles = toneStyles[tone];
|
|
13197
|
-
return /* @__PURE__ */ (0,
|
|
13451
|
+
return /* @__PURE__ */ (0, import_jsx_runtime115.jsxs)(
|
|
13198
13452
|
"li",
|
|
13199
13453
|
{
|
|
13200
13454
|
className: cn("relative flex gap-3.5 last:pb-0", timelineRowGap[size]),
|
|
13201
13455
|
children: [
|
|
13202
|
-
!last ? /* @__PURE__ */ (0,
|
|
13456
|
+
!last ? /* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
|
|
13203
13457
|
"span",
|
|
13204
13458
|
{
|
|
13205
13459
|
"aria-hidden": true,
|
|
@@ -13209,7 +13463,7 @@ function Timeline({ items, size = "default", className, ...props }) {
|
|
|
13209
13463
|
)
|
|
13210
13464
|
}
|
|
13211
13465
|
) : null,
|
|
13212
|
-
/* @__PURE__ */ (0,
|
|
13466
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsx)("div", { className: "relative flex w-5 shrink-0 justify-center pt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
|
|
13213
13467
|
"span",
|
|
13214
13468
|
{
|
|
13215
13469
|
className: cn(
|
|
@@ -13217,7 +13471,7 @@ function Timeline({ items, size = "default", className, ...props }) {
|
|
|
13217
13471
|
styles.border,
|
|
13218
13472
|
item.icon ? "size-6" : "size-4"
|
|
13219
13473
|
),
|
|
13220
|
-
children: item.icon ? /* @__PURE__ */ (0,
|
|
13474
|
+
children: item.icon ? /* @__PURE__ */ (0, import_jsx_runtime115.jsx)("div", { className: cn("text-xs", styles.icon), children: item.icon }) : /* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
|
|
13221
13475
|
"span",
|
|
13222
13476
|
{
|
|
13223
13477
|
className: cn(
|
|
@@ -13228,12 +13482,12 @@ function Timeline({ items, size = "default", className, ...props }) {
|
|
|
13228
13482
|
)
|
|
13229
13483
|
}
|
|
13230
13484
|
) }),
|
|
13231
|
-
/* @__PURE__ */ (0,
|
|
13232
|
-
/* @__PURE__ */ (0,
|
|
13233
|
-
/* @__PURE__ */ (0,
|
|
13234
|
-
item.meta ? /* @__PURE__ */ (0,
|
|
13485
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsxs)("div", { className: "min-w-0 flex-1 pb-0.5", children: [
|
|
13486
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
|
|
13487
|
+
/* @__PURE__ */ (0, import_jsx_runtime115.jsx)("p", { className: "text-sm font-normal text-foreground", children: item.title }),
|
|
13488
|
+
item.meta ? /* @__PURE__ */ (0, import_jsx_runtime115.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground tabular-nums", children: item.meta }) : null
|
|
13235
13489
|
] }),
|
|
13236
|
-
item.description ? /* @__PURE__ */ (0,
|
|
13490
|
+
item.description ? /* @__PURE__ */ (0, import_jsx_runtime115.jsx)("p", { className: "mt-0.5 text-[13px] leading-relaxed text-muted-foreground", children: item.description }) : null
|
|
13237
13491
|
] })
|
|
13238
13492
|
]
|
|
13239
13493
|
},
|
|
@@ -13247,8 +13501,8 @@ var React6 = __toESM(require("react"), 1);
|
|
|
13247
13501
|
var import_core2 = require("@dnd-kit/core");
|
|
13248
13502
|
var import_sortable = require("@dnd-kit/sortable");
|
|
13249
13503
|
var import_utilities = require("@dnd-kit/utilities");
|
|
13250
|
-
var
|
|
13251
|
-
var
|
|
13504
|
+
var import_lucide_react28 = require("lucide-react");
|
|
13505
|
+
var import_jsx_runtime116 = require("react/jsx-runtime");
|
|
13252
13506
|
var columnTitleToneClass = {
|
|
13253
13507
|
default: "text-foreground",
|
|
13254
13508
|
primary: "text-blue-600 dark:text-blue-400",
|
|
@@ -13310,7 +13564,7 @@ function SortableCard({
|
|
|
13310
13564
|
transition
|
|
13311
13565
|
};
|
|
13312
13566
|
const dragHandleProps = disabled ? void 0 : { ...attributes, ...listeners2 };
|
|
13313
|
-
return /* @__PURE__ */ (0,
|
|
13567
|
+
return /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)(
|
|
13314
13568
|
"div",
|
|
13315
13569
|
{
|
|
13316
13570
|
ref: setNodeRef,
|
|
@@ -13325,7 +13579,7 @@ function SortableCard({
|
|
|
13325
13579
|
className
|
|
13326
13580
|
),
|
|
13327
13581
|
children: [
|
|
13328
|
-
!disabled && dragHandle === "auto" ? /* @__PURE__ */ (0,
|
|
13582
|
+
!disabled && dragHandle === "auto" ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
13329
13583
|
"button",
|
|
13330
13584
|
{
|
|
13331
13585
|
type: "button",
|
|
@@ -13333,7 +13587,7 @@ function SortableCard({
|
|
|
13333
13587
|
className: "absolute right-1.5 top-1.5 z-10 grid size-6 cursor-grab touch-none place-items-center rounded-md text-muted-foreground/40 opacity-0 transition hover:bg-foreground/5 hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/15 group-hover/kanban-card:opacity-100 active:cursor-grabbing",
|
|
13334
13588
|
...attributes,
|
|
13335
13589
|
...listeners2,
|
|
13336
|
-
children: /* @__PURE__ */ (0,
|
|
13590
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(import_lucide_react28.GripVerticalIcon, { className: "size-4", "aria-hidden": true })
|
|
13337
13591
|
}
|
|
13338
13592
|
) : null,
|
|
13339
13593
|
renderCard(card, { column, isDragging, isOverlay: false, dragHandleProps })
|
|
@@ -13357,7 +13611,7 @@ function KanbanColumnView({
|
|
|
13357
13611
|
}) {
|
|
13358
13612
|
const tone = column.tone ?? "default";
|
|
13359
13613
|
const { setNodeRef, isOver } = (0, import_core2.useDroppable)({ id: column.id, disabled });
|
|
13360
|
-
return /* @__PURE__ */ (0,
|
|
13614
|
+
return /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)(
|
|
13361
13615
|
"div",
|
|
13362
13616
|
{
|
|
13363
13617
|
"data-slot": "kanban-column",
|
|
@@ -13367,9 +13621,9 @@ function KanbanColumnView({
|
|
|
13367
13621
|
className
|
|
13368
13622
|
),
|
|
13369
13623
|
children: [
|
|
13370
|
-
renderColumnHeader ? renderColumnHeader(column) : /* @__PURE__ */ (0,
|
|
13371
|
-
/* @__PURE__ */ (0,
|
|
13372
|
-
/* @__PURE__ */ (0,
|
|
13624
|
+
renderColumnHeader ? renderColumnHeader(column) : /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("div", { className: "flex flex-col gap-0.5 px-1 pb-0.5", children: [
|
|
13625
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
13626
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
13373
13627
|
"h3",
|
|
13374
13628
|
{
|
|
13375
13629
|
className: cn(
|
|
@@ -13379,12 +13633,12 @@ function KanbanColumnView({
|
|
|
13379
13633
|
children: column.title
|
|
13380
13634
|
}
|
|
13381
13635
|
),
|
|
13382
|
-
/* @__PURE__ */ (0,
|
|
13383
|
-
column.action ? /* @__PURE__ */ (0,
|
|
13636
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)("span", { className: "shrink-0 text-xs font-normal tabular-nums text-muted-foreground/60", children: column.cards.length }),
|
|
13637
|
+
column.action ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)("div", { className: "shrink-0", children: column.action }) : null
|
|
13384
13638
|
] }),
|
|
13385
|
-
column.description ? /* @__PURE__ */ (0,
|
|
13639
|
+
column.description ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)("p", { className: "truncate text-xs text-muted-foreground", children: column.description }) : null
|
|
13386
13640
|
] }),
|
|
13387
|
-
/* @__PURE__ */ (0,
|
|
13641
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)(import_sortable.SortableContext, { items: cardIds, strategy: import_sortable.verticalListSortingStrategy, children: /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
13388
13642
|
"div",
|
|
13389
13643
|
{
|
|
13390
13644
|
ref: setNodeRef,
|
|
@@ -13394,9 +13648,9 @@ function KanbanColumnView({
|
|
|
13394
13648
|
densityListClass[density],
|
|
13395
13649
|
isOver && "bg-muted/50"
|
|
13396
13650
|
),
|
|
13397
|
-
children: column.cards.length === 0 ? /* @__PURE__ */ (0,
|
|
13651
|
+
children: column.cards.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)("div", { className: "flex flex-1 items-center justify-center rounded-xl border border-dashed border-border/60 px-2 py-8 text-center text-xs text-muted-foreground/70", children: emptyColumnLabel ?? "Drop here" }) : column.cards.map((card) => {
|
|
13398
13652
|
const id = getCardId(card);
|
|
13399
|
-
return /* @__PURE__ */ (0,
|
|
13653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
13400
13654
|
SortableCard,
|
|
13401
13655
|
{
|
|
13402
13656
|
card,
|
|
@@ -13414,7 +13668,7 @@ function KanbanColumnView({
|
|
|
13414
13668
|
})
|
|
13415
13669
|
}
|
|
13416
13670
|
) }),
|
|
13417
|
-
column.footer ? /* @__PURE__ */ (0,
|
|
13671
|
+
column.footer ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)("div", { className: "px-0.5 pt-0.5", children: column.footer }) : null
|
|
13418
13672
|
]
|
|
13419
13673
|
}
|
|
13420
13674
|
);
|
|
@@ -13553,7 +13807,7 @@ function Kanban({
|
|
|
13553
13807
|
onColumnsChange?.(next);
|
|
13554
13808
|
}
|
|
13555
13809
|
};
|
|
13556
|
-
return /* @__PURE__ */ (0,
|
|
13810
|
+
return /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)(
|
|
13557
13811
|
import_core2.DndContext,
|
|
13558
13812
|
{
|
|
13559
13813
|
sensors,
|
|
@@ -13567,7 +13821,7 @@ function Kanban({
|
|
|
13567
13821
|
if (isControlled) setInternal(cloneColumns(columnsProp));
|
|
13568
13822
|
},
|
|
13569
13823
|
children: [
|
|
13570
|
-
/* @__PURE__ */ (0,
|
|
13824
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
13571
13825
|
"div",
|
|
13572
13826
|
{
|
|
13573
13827
|
"data-slot": "kanban",
|
|
@@ -13578,7 +13832,7 @@ function Kanban({
|
|
|
13578
13832
|
density === "compact" ? "gap-3" : "gap-4",
|
|
13579
13833
|
className
|
|
13580
13834
|
),
|
|
13581
|
-
children: columns.map((column) => /* @__PURE__ */ (0,
|
|
13835
|
+
children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
13582
13836
|
KanbanColumnView,
|
|
13583
13837
|
{
|
|
13584
13838
|
column,
|
|
@@ -13598,7 +13852,7 @@ function Kanban({
|
|
|
13598
13852
|
))
|
|
13599
13853
|
}
|
|
13600
13854
|
),
|
|
13601
|
-
/* @__PURE__ */ (0,
|
|
13855
|
+
/* @__PURE__ */ (0, import_jsx_runtime116.jsx)(import_core2.DragOverlay, { children: activeCard ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
|
|
13602
13856
|
"div",
|
|
13603
13857
|
{
|
|
13604
13858
|
"data-slot": "kanban-card-overlay",
|
|
@@ -13747,8 +14001,8 @@ When you call a tool that returns an artifact (\`make_chart\`, \`ask_question\`,
|
|
|
13747
14001
|
`.trim();
|
|
13748
14002
|
|
|
13749
14003
|
// src/auth/guard.tsx
|
|
13750
|
-
var
|
|
13751
|
-
var
|
|
14004
|
+
var import_lucide_react29 = require("lucide-react");
|
|
14005
|
+
var import_jsx_runtime117 = require("react/jsx-runtime");
|
|
13752
14006
|
var AuthGuard = ({
|
|
13753
14007
|
children,
|
|
13754
14008
|
requireAuth = false,
|
|
@@ -13759,7 +14013,7 @@ var AuthGuard = ({
|
|
|
13759
14013
|
return children;
|
|
13760
14014
|
}
|
|
13761
14015
|
if (loading) {
|
|
13762
|
-
return /* @__PURE__ */ (0,
|
|
14016
|
+
return /* @__PURE__ */ (0, import_jsx_runtime117.jsx)("div", { className: "flex items-center justify-center h-screen", children: /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_lucide_react29.Loader2, { className: "w-8 h-8 animate-spin" }) });
|
|
13763
14017
|
}
|
|
13764
14018
|
if (requireAuth && !isAuthenticated && !isEmbedded) {
|
|
13765
14019
|
const returnTo = encodeURIComponent(
|
|
@@ -13772,162 +14026,7 @@ var AuthGuard = ({
|
|
|
13772
14026
|
};
|
|
13773
14027
|
|
|
13774
14028
|
// src/index.ts
|
|
13775
|
-
var
|
|
13776
|
-
|
|
13777
|
-
// src/ui/select.tsx
|
|
13778
|
-
var import_radix_ui10 = require("radix-ui");
|
|
13779
|
-
var import_lucide_react29 = require("lucide-react");
|
|
13780
|
-
var import_jsx_runtime117 = require("react/jsx-runtime");
|
|
13781
|
-
function Select({
|
|
13782
|
-
...props
|
|
13783
|
-
}) {
|
|
13784
|
-
return /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_radix_ui10.Select.Root, { "data-slot": "select", ...props });
|
|
13785
|
-
}
|
|
13786
|
-
function SelectGroup({
|
|
13787
|
-
...props
|
|
13788
|
-
}) {
|
|
13789
|
-
return /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_radix_ui10.Select.Group, { "data-slot": "select-group", ...props });
|
|
13790
|
-
}
|
|
13791
|
-
function SelectValue({
|
|
13792
|
-
...props
|
|
13793
|
-
}) {
|
|
13794
|
-
return /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_radix_ui10.Select.Value, { "data-slot": "select-value", ...props });
|
|
13795
|
-
}
|
|
13796
|
-
function SelectTrigger({
|
|
13797
|
-
className,
|
|
13798
|
-
size = "default",
|
|
13799
|
-
children,
|
|
13800
|
-
...props
|
|
13801
|
-
}) {
|
|
13802
|
-
return /* @__PURE__ */ (0, import_jsx_runtime117.jsxs)(
|
|
13803
|
-
import_radix_ui10.Select.Trigger,
|
|
13804
|
-
{
|
|
13805
|
-
"data-slot": "select-trigger",
|
|
13806
|
-
"data-size": size,
|
|
13807
|
-
className: cn(
|
|
13808
|
-
controlClass({ size }),
|
|
13809
|
-
"flex w-fit items-center justify-between gap-2 whitespace-nowrap *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",
|
|
13810
|
-
className
|
|
13811
|
-
),
|
|
13812
|
-
...props,
|
|
13813
|
-
children: [
|
|
13814
|
-
children,
|
|
13815
|
-
/* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_radix_ui10.Select.Icon, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_lucide_react29.ChevronDownIcon, { className: "size-4 opacity-50" }) })
|
|
13816
|
-
]
|
|
13817
|
-
}
|
|
13818
|
-
);
|
|
13819
|
-
}
|
|
13820
|
-
function SelectContent({
|
|
13821
|
-
className,
|
|
13822
|
-
children,
|
|
13823
|
-
position = "popper",
|
|
13824
|
-
...props
|
|
13825
|
-
}) {
|
|
13826
|
-
return /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_radix_ui10.Select.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime117.jsxs)(
|
|
13827
|
-
import_radix_ui10.Select.Content,
|
|
13828
|
-
{
|
|
13829
|
-
"data-slot": "select-content",
|
|
13830
|
-
className: cn(
|
|
13831
|
-
overlayListPanelClass,
|
|
13832
|
-
"relative max-h-[var(--radix-select-content-available-height)] min-w-[8rem] origin-[var(--radix-select-content-transform-origin)] overflow-x-hidden overflow-y-auto",
|
|
13833
|
-
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
13834
|
-
className
|
|
13835
|
-
),
|
|
13836
|
-
position,
|
|
13837
|
-
...props,
|
|
13838
|
-
children: [
|
|
13839
|
-
/* @__PURE__ */ (0, import_jsx_runtime117.jsx)(SelectScrollUpButton, {}),
|
|
13840
|
-
/* @__PURE__ */ (0, import_jsx_runtime117.jsx)(
|
|
13841
|
-
import_radix_ui10.Select.Viewport,
|
|
13842
|
-
{
|
|
13843
|
-
className: cn(
|
|
13844
|
-
"p-1",
|
|
13845
|
-
position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
|
|
13846
|
-
),
|
|
13847
|
-
children
|
|
13848
|
-
}
|
|
13849
|
-
),
|
|
13850
|
-
/* @__PURE__ */ (0, import_jsx_runtime117.jsx)(SelectScrollDownButton, {})
|
|
13851
|
-
]
|
|
13852
|
-
}
|
|
13853
|
-
) });
|
|
13854
|
-
}
|
|
13855
|
-
function SelectLabel({
|
|
13856
|
-
className,
|
|
13857
|
-
...props
|
|
13858
|
-
}) {
|
|
13859
|
-
return /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(
|
|
13860
|
-
import_radix_ui10.Select.Label,
|
|
13861
|
-
{
|
|
13862
|
-
"data-slot": "select-label",
|
|
13863
|
-
className: cn("px-2 py-1.5 text-xs font-medium text-muted-foreground", className),
|
|
13864
|
-
...props
|
|
13865
|
-
}
|
|
13866
|
-
);
|
|
13867
|
-
}
|
|
13868
|
-
function SelectItem({
|
|
13869
|
-
className,
|
|
13870
|
-
children,
|
|
13871
|
-
...props
|
|
13872
|
-
}) {
|
|
13873
|
-
return /* @__PURE__ */ (0, import_jsx_runtime117.jsxs)(
|
|
13874
|
-
import_radix_ui10.Select.Item,
|
|
13875
|
-
{
|
|
13876
|
-
"data-slot": "select-item",
|
|
13877
|
-
className: cn(
|
|
13878
|
-
overlayItemClass,
|
|
13879
|
-
"w-full py-1.5 pr-8 pl-2 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
13880
|
-
className
|
|
13881
|
-
),
|
|
13882
|
-
...props,
|
|
13883
|
-
children: [
|
|
13884
|
-
/* @__PURE__ */ (0, import_jsx_runtime117.jsx)("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_radix_ui10.Select.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_lucide_react29.CheckIcon, { className: "size-4" }) }) }),
|
|
13885
|
-
/* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_radix_ui10.Select.ItemText, { children })
|
|
13886
|
-
]
|
|
13887
|
-
}
|
|
13888
|
-
);
|
|
13889
|
-
}
|
|
13890
|
-
function SelectSeparator({
|
|
13891
|
-
className,
|
|
13892
|
-
...props
|
|
13893
|
-
}) {
|
|
13894
|
-
return /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(
|
|
13895
|
-
import_radix_ui10.Select.Separator,
|
|
13896
|
-
{
|
|
13897
|
-
"data-slot": "select-separator",
|
|
13898
|
-
className: cn("-mx-1 my-1 h-px bg-border", className),
|
|
13899
|
-
...props
|
|
13900
|
-
}
|
|
13901
|
-
);
|
|
13902
|
-
}
|
|
13903
|
-
function SelectScrollUpButton({
|
|
13904
|
-
className,
|
|
13905
|
-
...props
|
|
13906
|
-
}) {
|
|
13907
|
-
return /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(
|
|
13908
|
-
import_radix_ui10.Select.ScrollUpButton,
|
|
13909
|
-
{
|
|
13910
|
-
"data-slot": "select-scroll-up-button",
|
|
13911
|
-
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
13912
|
-
...props,
|
|
13913
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_lucide_react29.ChevronUpIcon, { className: "size-4" })
|
|
13914
|
-
}
|
|
13915
|
-
);
|
|
13916
|
-
}
|
|
13917
|
-
function SelectScrollDownButton({
|
|
13918
|
-
className,
|
|
13919
|
-
...props
|
|
13920
|
-
}) {
|
|
13921
|
-
return /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(
|
|
13922
|
-
import_radix_ui10.Select.ScrollDownButton,
|
|
13923
|
-
{
|
|
13924
|
-
"data-slot": "select-scroll-down-button",
|
|
13925
|
-
className: cn("flex cursor-default items-center justify-center py-1", className),
|
|
13926
|
-
...props,
|
|
13927
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(import_lucide_react29.ChevronDownIcon, { className: "size-4" })
|
|
13928
|
-
}
|
|
13929
|
-
);
|
|
13930
|
-
}
|
|
14029
|
+
var import_react84 = require("@assistant-ui/react");
|
|
13931
14030
|
|
|
13932
14031
|
// src/ui/input.tsx
|
|
13933
14032
|
var import_jsx_runtime118 = require("react/jsx-runtime");
|
|
@@ -13961,7 +14060,7 @@ function Textarea({ className, ...props }) {
|
|
|
13961
14060
|
"data-slot": "textarea",
|
|
13962
14061
|
className: cn(
|
|
13963
14062
|
controlSurfaceClass,
|
|
13964
|
-
"min-h-16 w-full resize-y rounded-lg px-
|
|
14063
|
+
"min-h-16 w-full resize-y rounded-lg px-2.5 py-1.5 leading-relaxed",
|
|
13965
14064
|
className
|
|
13966
14065
|
),
|
|
13967
14066
|
...props
|
|
@@ -14220,7 +14319,7 @@ function BreadcrumbEllipsis({
|
|
|
14220
14319
|
"data-slot": "breadcrumb-ellipsis",
|
|
14221
14320
|
role: "presentation",
|
|
14222
14321
|
"aria-hidden": "true",
|
|
14223
|
-
className: cn("flex size-
|
|
14322
|
+
className: cn("flex size-8 items-center justify-center", className),
|
|
14224
14323
|
...props,
|
|
14225
14324
|
children: [
|
|
14226
14325
|
/* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_lucide_react31.MoreHorizontalIcon, { className: "size-4" }),
|
|
@@ -14356,7 +14455,7 @@ function ToolbarButton({
|
|
|
14356
14455
|
{
|
|
14357
14456
|
"data-slot": "toolbar-button",
|
|
14358
14457
|
className: cn(
|
|
14359
|
-
"inline-flex h-
|
|
14458
|
+
"inline-flex h-7 min-w-7 items-center justify-center rounded-md px-1.5 text-sm font-medium text-foreground outline-none transition-colors",
|
|
14360
14459
|
"hover:bg-muted focus-visible:ring-2 focus-visible:ring-foreground/10 disabled:pointer-events-none disabled:opacity-50",
|
|
14361
14460
|
className
|
|
14362
14461
|
),
|
|
@@ -14399,7 +14498,7 @@ function ToolbarToggleItem({
|
|
|
14399
14498
|
{
|
|
14400
14499
|
"data-slot": "toolbar-toggle-item",
|
|
14401
14500
|
className: cn(
|
|
14402
|
-
"inline-flex h-
|
|
14501
|
+
"inline-flex h-7 min-w-7 items-center justify-center rounded-md px-1.5 text-sm outline-none transition-colors",
|
|
14403
14502
|
"hover:bg-muted focus-visible:ring-2 focus-visible:ring-foreground/10",
|
|
14404
14503
|
"data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
|
|
14405
14504
|
className
|
|
@@ -14417,7 +14516,7 @@ function ToolbarLink({
|
|
|
14417
14516
|
{
|
|
14418
14517
|
"data-slot": "toolbar-link",
|
|
14419
14518
|
className: cn(
|
|
14420
|
-
"inline-flex h-
|
|
14519
|
+
"inline-flex h-7 items-center rounded-md px-1.5 text-sm text-foreground outline-none transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-foreground/10",
|
|
14421
14520
|
className
|
|
14422
14521
|
),
|
|
14423
14522
|
...props
|
|
@@ -14438,7 +14537,7 @@ function Menubar({
|
|
|
14438
14537
|
{
|
|
14439
14538
|
"data-slot": "menubar",
|
|
14440
14539
|
className: cn(
|
|
14441
|
-
"flex h-
|
|
14540
|
+
"flex h-8 items-center gap-1 rounded-lg border border-border bg-gradient-to-b from-elevated-from to-elevated-to p-1 shadow-card",
|
|
14442
14541
|
className
|
|
14443
14542
|
),
|
|
14444
14543
|
...props
|
|
@@ -14459,7 +14558,7 @@ function MenubarTrigger({
|
|
|
14459
14558
|
{
|
|
14460
14559
|
"data-slot": "menubar-trigger",
|
|
14461
14560
|
className: cn(
|
|
14462
|
-
"flex cursor-default items-center rounded-md px-2 py-
|
|
14561
|
+
"flex cursor-default items-center rounded-md px-2 py-0.5 text-sm font-medium outline-none select-none",
|
|
14463
14562
|
"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
|
14464
14563
|
className
|
|
14465
14564
|
),
|
|
@@ -14521,7 +14620,7 @@ function MenubarCheckboxItem({
|
|
|
14521
14620
|
import_radix_ui18.Menubar.CheckboxItem,
|
|
14522
14621
|
{
|
|
14523
14622
|
"data-slot": "menubar-checkbox-item",
|
|
14524
|
-
className: cn(overlayItemClass, "py-1
|
|
14623
|
+
className: cn(overlayItemClass, "py-1 pr-2 pl-8", className),
|
|
14525
14624
|
checked,
|
|
14526
14625
|
...props,
|
|
14527
14626
|
children: [
|
|
@@ -14545,7 +14644,7 @@ function MenubarRadioItem({
|
|
|
14545
14644
|
import_radix_ui18.Menubar.RadioItem,
|
|
14546
14645
|
{
|
|
14547
14646
|
"data-slot": "menubar-radio-item",
|
|
14548
|
-
className: cn(overlayItemClass, "py-1
|
|
14647
|
+
className: cn(overlayItemClass, "py-1 pr-2 pl-8", className),
|
|
14549
14648
|
...props,
|
|
14550
14649
|
children: [
|
|
14551
14650
|
/* @__PURE__ */ (0, import_jsx_runtime128.jsx)("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime128.jsx)(import_radix_ui18.Menubar.ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime128.jsx)(import_lucide_react33.CircleIcon, { className: "size-2 fill-current" }) }) }),
|
|
@@ -14831,7 +14930,7 @@ function CommandDialog({
|
|
|
14831
14930
|
{
|
|
14832
14931
|
className: cn("overflow-hidden p-0", className),
|
|
14833
14932
|
showCloseButton,
|
|
14834
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime130.jsx)(Command, { className: "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1
|
|
14933
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime130.jsx)(Command, { className: "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:size-4 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-1.5 [&_[cmdk-item]_svg]:size-4", children })
|
|
14835
14934
|
}
|
|
14836
14935
|
)
|
|
14837
14936
|
] });
|
|
@@ -14844,7 +14943,7 @@ function CommandInput({
|
|
|
14844
14943
|
"div",
|
|
14845
14944
|
{
|
|
14846
14945
|
"data-slot": "command-input-wrapper",
|
|
14847
|
-
className: "flex h-
|
|
14946
|
+
className: "flex h-9 items-center gap-2 border-b border-border px-2.5",
|
|
14848
14947
|
children: [
|
|
14849
14948
|
/* @__PURE__ */ (0, import_jsx_runtime130.jsx)(import_lucide_react35.SearchIcon, { className: "size-4 shrink-0 text-muted-foreground" }),
|
|
14850
14949
|
/* @__PURE__ */ (0, import_jsx_runtime130.jsx)(
|
|
@@ -14852,7 +14951,7 @@ function CommandInput({
|
|
|
14852
14951
|
{
|
|
14853
14952
|
"data-slot": "command-input",
|
|
14854
14953
|
className: cn(
|
|
14855
|
-
"flex h-
|
|
14954
|
+
"flex h-9 w-full rounded-md bg-transparent py-2 text-sm outline-none placeholder:text-muted-foreground/70 disabled:cursor-not-allowed disabled:opacity-50",
|
|
14856
14955
|
className
|
|
14857
14956
|
),
|
|
14858
14957
|
...props
|
|
@@ -14882,7 +14981,7 @@ function CommandEmpty({
|
|
|
14882
14981
|
import_cmdk.Command.Empty,
|
|
14883
14982
|
{
|
|
14884
14983
|
"data-slot": "command-empty",
|
|
14885
|
-
className: "py-
|
|
14984
|
+
className: "py-4 text-center text-sm text-muted-foreground",
|
|
14886
14985
|
...props
|
|
14887
14986
|
}
|
|
14888
14987
|
);
|
|
@@ -14896,7 +14995,7 @@ function CommandGroup({
|
|
|
14896
14995
|
{
|
|
14897
14996
|
"data-slot": "command-group",
|
|
14898
14997
|
className: cn(
|
|
14899
|
-
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1
|
|
14998
|
+
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
|
|
14900
14999
|
className
|
|
14901
15000
|
),
|
|
14902
15001
|
...props
|
|
@@ -14978,12 +15077,12 @@ function Calendar({
|
|
|
14978
15077
|
button_previous: cn(navButtonClass, defaults.button_previous),
|
|
14979
15078
|
button_next: cn(navButtonClass, defaults.button_next),
|
|
14980
15079
|
month_caption: cn(
|
|
14981
|
-
"flex h-
|
|
15080
|
+
"flex h-9 items-center justify-center",
|
|
14982
15081
|
defaults.month_caption
|
|
14983
15082
|
),
|
|
14984
15083
|
caption_label: cn("text-sm font-semibold", defaults.caption_label),
|
|
14985
15084
|
dropdowns: cn(
|
|
14986
|
-
"flex h-
|
|
15085
|
+
"flex h-9 items-center justify-center gap-1.5 text-sm font-semibold",
|
|
14987
15086
|
defaults.dropdowns
|
|
14988
15087
|
),
|
|
14989
15088
|
dropdown_root: cn(
|
|
@@ -14994,17 +15093,17 @@ function Calendar({
|
|
|
14994
15093
|
month_grid: cn("border-separate border-spacing-y-1", defaults.month_grid),
|
|
14995
15094
|
weekdays: cn(defaults.weekdays),
|
|
14996
15095
|
weekday: cn(
|
|
14997
|
-
"size-
|
|
15096
|
+
"size-9 pb-2 text-xs font-medium text-muted-foreground",
|
|
14998
15097
|
defaults.weekday
|
|
14999
15098
|
),
|
|
15000
15099
|
week: cn(defaults.week),
|
|
15001
|
-
week_number_header: cn("size-
|
|
15100
|
+
week_number_header: cn("size-9", defaults.week_number_header),
|
|
15002
15101
|
week_number: cn(
|
|
15003
15102
|
"text-xs text-muted-foreground",
|
|
15004
15103
|
defaults.week_number
|
|
15005
15104
|
),
|
|
15006
15105
|
day: cn(
|
|
15007
|
-
"relative size-
|
|
15106
|
+
"relative size-9 p-0 text-center text-sm focus-within:relative focus-within:z-10",
|
|
15008
15107
|
defaults.day
|
|
15009
15108
|
),
|
|
15010
15109
|
range_start: cn("rounded-l-md", defaults.range_start),
|
|
@@ -15302,7 +15401,7 @@ function InputOTPSlot({
|
|
|
15302
15401
|
"data-slot": "input-otp-slot",
|
|
15303
15402
|
className: cn(
|
|
15304
15403
|
controlSurfaceClass,
|
|
15305
|
-
"relative size-
|
|
15404
|
+
"relative size-8 rounded-none text-center text-sm tabular-nums",
|
|
15306
15405
|
"-ms-px first:ms-0 first:rounded-s-lg last:rounded-e-lg",
|
|
15307
15406
|
"focus-visible:z-10",
|
|
15308
15407
|
className
|
|
@@ -15503,7 +15602,7 @@ function AccordionTrigger({
|
|
|
15503
15602
|
{
|
|
15504
15603
|
"data-slot": "accordion-trigger",
|
|
15505
15604
|
className: cn(
|
|
15506
|
-
"flex flex-1 items-center justify-between gap-4 rounded-md py-
|
|
15605
|
+
"flex flex-1 items-center justify-between gap-4 rounded-md py-3 text-left text-sm font-medium outline-none transition-all",
|
|
15507
15606
|
"focus-visible:ring-2 focus-visible:ring-foreground/10 disabled:pointer-events-none disabled:opacity-50",
|
|
15508
15607
|
"hover:underline [&[data-state=open]>svg]:rotate-180",
|
|
15509
15608
|
className
|
|
@@ -15527,7 +15626,7 @@ function AccordionContent({
|
|
|
15527
15626
|
"data-slot": "accordion-content",
|
|
15528
15627
|
className: "overflow-hidden text-sm text-muted-foreground data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
|
|
15529
15628
|
...props,
|
|
15530
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime138.jsx)("div", { className: cn("pt-0 pb-
|
|
15629
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime138.jsx)("div", { className: cn("pt-0 pb-3", className), children })
|
|
15531
15630
|
}
|
|
15532
15631
|
);
|
|
15533
15632
|
}
|
|
@@ -15728,10 +15827,10 @@ var sheetContentVariants = (0, import_class_variance_authority5.cva)(
|
|
|
15728
15827
|
{
|
|
15729
15828
|
variants: {
|
|
15730
15829
|
side: {
|
|
15731
|
-
top: "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top fixed top-4 inset-x-4 mx-auto w-[calc(100vw-2rem)] sm:max-w-lg rounded-2xl p-
|
|
15732
|
-
bottom: "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom fixed bottom-4 inset-x-4 mx-auto w-[calc(100vw-2rem)] sm:max-w-lg rounded-2xl p-
|
|
15733
|
-
left: "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left fixed top-4 bottom-4 left-4 w-[calc(100vw-2rem)] rounded-2xl p-
|
|
15734
|
-
right: "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right fixed top-4 bottom-4 right-4 w-[calc(100vw-2rem)] rounded-2xl p-
|
|
15830
|
+
top: "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top fixed top-4 inset-x-4 mx-auto w-[calc(100vw-2rem)] sm:max-w-lg rounded-2xl p-5",
|
|
15831
|
+
bottom: "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom fixed bottom-4 inset-x-4 mx-auto w-[calc(100vw-2rem)] sm:max-w-lg rounded-2xl p-5",
|
|
15832
|
+
left: "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left fixed top-4 bottom-4 left-4 w-[calc(100vw-2rem)] rounded-2xl p-5",
|
|
15833
|
+
right: "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right fixed top-4 bottom-4 right-4 w-[calc(100vw-2rem)] rounded-2xl p-5"
|
|
15735
15834
|
},
|
|
15736
15835
|
size: {
|
|
15737
15836
|
default: "",
|
|
@@ -16375,7 +16474,7 @@ function ContextMenuSubContent({
|
|
|
16375
16474
|
var import_class_variance_authority7 = require("class-variance-authority");
|
|
16376
16475
|
var import_jsx_runtime151 = require("react/jsx-runtime");
|
|
16377
16476
|
var alertVariants = (0, import_class_variance_authority7.cva)(
|
|
16378
|
-
"relative grid w-full gap-1 rounded-xl border px-
|
|
16477
|
+
"relative grid w-full gap-1 rounded-xl border px-3.5 py-2.5 text-sm [&>svg]:absolute [&>svg]:top-3 [&>svg]:left-3.5 [&>svg]:size-4 [&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-10",
|
|
16379
16478
|
{
|
|
16380
16479
|
variants: {
|
|
16381
16480
|
variant: {
|
|
@@ -16433,7 +16532,7 @@ function Card({ className, ...props }) {
|
|
|
16433
16532
|
"data-slot": "card",
|
|
16434
16533
|
className: cn(
|
|
16435
16534
|
TIMBAL_V2_ELEVATED_SURFACE,
|
|
16436
|
-
"flex flex-col gap-
|
|
16535
|
+
"flex flex-col gap-3 rounded-xl py-3 text-card-foreground",
|
|
16437
16536
|
className
|
|
16438
16537
|
),
|
|
16439
16538
|
...props
|
|
@@ -16445,7 +16544,7 @@ function CardHeader({ className, ...props }) {
|
|
|
16445
16544
|
"div",
|
|
16446
16545
|
{
|
|
16447
16546
|
"data-slot": "card-header",
|
|
16448
|
-
className: cn("flex flex-col gap-1.5 px-
|
|
16547
|
+
className: cn("flex flex-col gap-1.5 px-3.5", className),
|
|
16449
16548
|
...props
|
|
16450
16549
|
}
|
|
16451
16550
|
);
|
|
@@ -16471,14 +16570,14 @@ function CardDescription({ className, ...props }) {
|
|
|
16471
16570
|
);
|
|
16472
16571
|
}
|
|
16473
16572
|
function CardContent({ className, ...props }) {
|
|
16474
|
-
return /* @__PURE__ */ (0, import_jsx_runtime152.jsx)("div", { "data-slot": "card-content", className: cn("px-
|
|
16573
|
+
return /* @__PURE__ */ (0, import_jsx_runtime152.jsx)("div", { "data-slot": "card-content", className: cn("px-3.5", className), ...props });
|
|
16475
16574
|
}
|
|
16476
16575
|
function CardFooter({ className, ...props }) {
|
|
16477
16576
|
return /* @__PURE__ */ (0, import_jsx_runtime152.jsx)(
|
|
16478
16577
|
"div",
|
|
16479
16578
|
{
|
|
16480
16579
|
"data-slot": "card-footer",
|
|
16481
|
-
className: cn("flex items-center px-
|
|
16580
|
+
className: cn("flex items-center px-3.5", className),
|
|
16482
16581
|
...props
|
|
16483
16582
|
}
|
|
16484
16583
|
);
|
|
@@ -16548,7 +16647,7 @@ function TableHead({ className, ...props }) {
|
|
|
16548
16647
|
{
|
|
16549
16648
|
"data-slot": "table-head",
|
|
16550
16649
|
className: cn(
|
|
16551
|
-
"h-
|
|
16650
|
+
"h-8 px-2.5 text-left align-middle text-xs font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
|
|
16552
16651
|
className
|
|
16553
16652
|
),
|
|
16554
16653
|
...props
|
|
@@ -16561,7 +16660,7 @@ function TableCell({ className, ...props }) {
|
|
|
16561
16660
|
{
|
|
16562
16661
|
"data-slot": "table-cell",
|
|
16563
16662
|
className: cn(
|
|
16564
|
-
"
|
|
16663
|
+
"py-2 px-2.5 align-middle text-sm [&:has([role=checkbox])]:pr-0",
|
|
16565
16664
|
className
|
|
16566
16665
|
),
|
|
16567
16666
|
...props
|
|
@@ -16615,7 +16714,7 @@ function Toast({
|
|
|
16615
16714
|
"data-slot": "toast",
|
|
16616
16715
|
className: cn(
|
|
16617
16716
|
TIMBAL_V2_ELEVATED_SURFACE,
|
|
16618
|
-
"group pointer-events-auto relative flex w-full items-center justify-between gap-3 overflow-hidden rounded-xl p-
|
|
16717
|
+
"group pointer-events-auto relative flex w-full items-center justify-between gap-3 overflow-hidden rounded-xl p-3 pr-7 shadow-card-elevated transition-all",
|
|
16619
16718
|
"data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-80 data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full data-[state=closed]:slide-out-to-right-full",
|
|
16620
16719
|
variant === "destructive" && "border-destructive/45 bg-destructive/10 text-destructive",
|
|
16621
16720
|
className
|
|
@@ -16936,7 +17035,7 @@ function Rating({
|
|
|
16936
17035
|
const value = isControlled ? valueProp : uncontrolled;
|
|
16937
17036
|
const [hover, setHover] = React11.useState(null);
|
|
16938
17037
|
const interactive = !readOnly && !disabled;
|
|
16939
|
-
const
|
|
17038
|
+
const shown2 = hover ?? value;
|
|
16940
17039
|
const set = (next) => {
|
|
16941
17040
|
if (!interactive) return;
|
|
16942
17041
|
if (!isControlled) setUncontrolled(next);
|
|
@@ -16974,7 +17073,7 @@ function Rating({
|
|
|
16974
17073
|
onMouseLeave: () => setHover(null),
|
|
16975
17074
|
children: Array.from({ length: max }, (_, i) => {
|
|
16976
17075
|
const unit = i + 1;
|
|
16977
|
-
const filled = unit <=
|
|
17076
|
+
const filled = unit <= shown2;
|
|
16978
17077
|
return /* @__PURE__ */ (0, import_jsx_runtime158.jsx)(
|
|
16979
17078
|
"button",
|
|
16980
17079
|
{
|
|
@@ -17107,8 +17206,8 @@ var React13 = __toESM(require("react"), 1);
|
|
|
17107
17206
|
var import_lucide_react47 = require("lucide-react");
|
|
17108
17207
|
var import_jsx_runtime160 = require("react/jsx-runtime");
|
|
17109
17208
|
var tagInputSizeClass = {
|
|
17110
|
-
sm: "min-h-
|
|
17111
|
-
default: "min-h-
|
|
17209
|
+
sm: "min-h-8 gap-1 px-1.5 py-0.5",
|
|
17210
|
+
default: "min-h-9 gap-1 px-2 py-1"
|
|
17112
17211
|
};
|
|
17113
17212
|
function TagInput({
|
|
17114
17213
|
value: valueProp,
|
|
@@ -17216,8 +17315,8 @@ var snippetVariantClass = {
|
|
|
17216
17315
|
ghost: "border-transparent bg-foreground/[0.04]"
|
|
17217
17316
|
};
|
|
17218
17317
|
var snippetSizeClass = {
|
|
17219
|
-
sm: "gap-1.5 py-
|
|
17220
|
-
default: "gap-2 py-1
|
|
17318
|
+
sm: "gap-1.5 py-0.5 pl-2 pr-0.5 text-xs",
|
|
17319
|
+
default: "gap-2 py-1 pl-2.5 pr-1 text-sm"
|
|
17221
17320
|
};
|
|
17222
17321
|
function Snippet({
|
|
17223
17322
|
children,
|
|
@@ -17333,6 +17432,373 @@ function CircularProgress({
|
|
|
17333
17432
|
}
|
|
17334
17433
|
);
|
|
17335
17434
|
}
|
|
17435
|
+
|
|
17436
|
+
// src/site/Reveal.tsx
|
|
17437
|
+
var React14 = __toESM(require("react"), 1);
|
|
17438
|
+
var import_react79 = require("motion/react");
|
|
17439
|
+
|
|
17440
|
+
// src/site/easing.ts
|
|
17441
|
+
var EASE = {
|
|
17442
|
+
/** Strong slow-out — the workhorse for entrances and reveals. */
|
|
17443
|
+
out: [0.16, 1, 0.3, 1],
|
|
17444
|
+
/** Symmetric in-out for loops and continuous motion. */
|
|
17445
|
+
inOut: [0.65, 0, 0.35, 1],
|
|
17446
|
+
/** Gentle in-out, good for parallax / large translations. */
|
|
17447
|
+
soft: [0.4, 0, 0.2, 1]
|
|
17448
|
+
};
|
|
17449
|
+
var DURATION = {
|
|
17450
|
+
fast: 0.4,
|
|
17451
|
+
base: 0.7,
|
|
17452
|
+
slow: 1.1
|
|
17453
|
+
};
|
|
17454
|
+
var SPRING = {
|
|
17455
|
+
/** Tight, responsive follow. */
|
|
17456
|
+
snappy: { stiffness: 350, damping: 30, mass: 0.4 },
|
|
17457
|
+
/** Looser, more elastic follow. */
|
|
17458
|
+
smooth: { stiffness: 150, damping: 20, mass: 0.6 }
|
|
17459
|
+
};
|
|
17460
|
+
|
|
17461
|
+
// src/site/Reveal.tsx
|
|
17462
|
+
var import_jsx_runtime163 = require("react/jsx-runtime");
|
|
17463
|
+
function hidden(variant, distance) {
|
|
17464
|
+
switch (variant) {
|
|
17465
|
+
case "fade":
|
|
17466
|
+
return { opacity: 0 };
|
|
17467
|
+
case "fade-up":
|
|
17468
|
+
return { opacity: 0, y: distance };
|
|
17469
|
+
case "fade-down":
|
|
17470
|
+
return { opacity: 0, y: -distance };
|
|
17471
|
+
case "fade-left":
|
|
17472
|
+
return { opacity: 0, x: distance };
|
|
17473
|
+
case "fade-right":
|
|
17474
|
+
return { opacity: 0, x: -distance };
|
|
17475
|
+
case "blur":
|
|
17476
|
+
return { opacity: 0, filter: "blur(12px)" };
|
|
17477
|
+
case "scale":
|
|
17478
|
+
return { opacity: 0, scale: 0.94 };
|
|
17479
|
+
case "mask-up":
|
|
17480
|
+
return { y: "110%" };
|
|
17481
|
+
}
|
|
17482
|
+
}
|
|
17483
|
+
function shown(variant) {
|
|
17484
|
+
if (variant === "mask-up") return { y: "0%" };
|
|
17485
|
+
if (variant === "blur") return { opacity: 1, filter: "blur(0px)" };
|
|
17486
|
+
if (variant === "scale") return { opacity: 1, scale: 1 };
|
|
17487
|
+
return { opacity: 1, x: 0, y: 0 };
|
|
17488
|
+
}
|
|
17489
|
+
var Reveal = React14.forwardRef(function Reveal2({
|
|
17490
|
+
variant = "fade-up",
|
|
17491
|
+
delay = 0,
|
|
17492
|
+
duration = DURATION.base,
|
|
17493
|
+
distance = 28,
|
|
17494
|
+
amount = 0.3,
|
|
17495
|
+
repeat = false,
|
|
17496
|
+
as = "div",
|
|
17497
|
+
className,
|
|
17498
|
+
children,
|
|
17499
|
+
...rest
|
|
17500
|
+
}, ref) {
|
|
17501
|
+
const reduce = (0, import_react79.useReducedMotion)();
|
|
17502
|
+
const isMask = variant === "mask-up";
|
|
17503
|
+
if (reduce) {
|
|
17504
|
+
const Tag = as;
|
|
17505
|
+
return /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(Tag, { ref, className: cn(isMask && "overflow-hidden", className), ...rest, children });
|
|
17506
|
+
}
|
|
17507
|
+
const variants = {
|
|
17508
|
+
hidden: hidden(variant, distance),
|
|
17509
|
+
shown: shown(variant)
|
|
17510
|
+
};
|
|
17511
|
+
const MotionTag = import_react79.motion[as] ?? import_react79.motion.div;
|
|
17512
|
+
const inner = /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(
|
|
17513
|
+
MotionTag,
|
|
17514
|
+
{
|
|
17515
|
+
ref,
|
|
17516
|
+
className,
|
|
17517
|
+
variants,
|
|
17518
|
+
initial: "hidden",
|
|
17519
|
+
whileInView: "shown",
|
|
17520
|
+
viewport: { once: !repeat, amount },
|
|
17521
|
+
transition: { duration, delay, ease: EASE.out },
|
|
17522
|
+
...rest,
|
|
17523
|
+
children
|
|
17524
|
+
}
|
|
17525
|
+
);
|
|
17526
|
+
if (isMask) {
|
|
17527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("span", { className: "block overflow-hidden", children: inner });
|
|
17528
|
+
}
|
|
17529
|
+
return inner;
|
|
17530
|
+
});
|
|
17531
|
+
|
|
17532
|
+
// src/site/TextReveal.tsx
|
|
17533
|
+
var React15 = __toESM(require("react"), 1);
|
|
17534
|
+
var import_react80 = require("motion/react");
|
|
17535
|
+
var import_jsx_runtime164 = require("react/jsx-runtime");
|
|
17536
|
+
var tokenVariants = {
|
|
17537
|
+
hidden: { y: "115%" },
|
|
17538
|
+
shown: { y: "0%" }
|
|
17539
|
+
};
|
|
17540
|
+
function TextReveal({
|
|
17541
|
+
children,
|
|
17542
|
+
splitBy = "words",
|
|
17543
|
+
stagger = 0.06,
|
|
17544
|
+
delay = 0,
|
|
17545
|
+
duration = DURATION.base,
|
|
17546
|
+
repeat = false,
|
|
17547
|
+
amount = 0.4,
|
|
17548
|
+
as = "span",
|
|
17549
|
+
className,
|
|
17550
|
+
...rest
|
|
17551
|
+
}) {
|
|
17552
|
+
const reduce = (0, import_react80.useReducedMotion)();
|
|
17553
|
+
const Tag = as;
|
|
17554
|
+
const tokens = React15.useMemo(() => {
|
|
17555
|
+
if (splitBy === "lines") return children.split("\n");
|
|
17556
|
+
return children.split(/(\s+)/).filter((t) => t.length > 0);
|
|
17557
|
+
}, [children, splitBy]);
|
|
17558
|
+
if (reduce) {
|
|
17559
|
+
return /* @__PURE__ */ (0, import_jsx_runtime164.jsx)(Tag, { className, ...rest, children });
|
|
17560
|
+
}
|
|
17561
|
+
const containerVariants = {
|
|
17562
|
+
hidden: {},
|
|
17563
|
+
shown: { transition: { staggerChildren: stagger, delayChildren: delay } }
|
|
17564
|
+
};
|
|
17565
|
+
return /* @__PURE__ */ (0, import_jsx_runtime164.jsx)(
|
|
17566
|
+
import_react80.motion.span,
|
|
17567
|
+
{
|
|
17568
|
+
variants: containerVariants,
|
|
17569
|
+
initial: "hidden",
|
|
17570
|
+
whileInView: "shown",
|
|
17571
|
+
viewport: { once: !repeat, amount },
|
|
17572
|
+
className: cn(as === "span" ? "inline" : "block", className),
|
|
17573
|
+
...rest,
|
|
17574
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime164.jsx)(Tag, { className: as === "span" ? "inline" : "block", children: tokens.map(
|
|
17575
|
+
(token, i) => /^\s+$/.test(token) && splitBy === "words" ? /* @__PURE__ */ (0, import_jsx_runtime164.jsx)("span", { children: " " }, i) : /* @__PURE__ */ (0, import_jsx_runtime164.jsx)(
|
|
17576
|
+
"span",
|
|
17577
|
+
{
|
|
17578
|
+
className: cn(
|
|
17579
|
+
"overflow-hidden",
|
|
17580
|
+
splitBy === "lines" ? "block" : "inline-block align-bottom"
|
|
17581
|
+
),
|
|
17582
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime164.jsx)(
|
|
17583
|
+
import_react80.motion.span,
|
|
17584
|
+
{
|
|
17585
|
+
className: "inline-block",
|
|
17586
|
+
variants: tokenVariants,
|
|
17587
|
+
transition: { duration, ease: EASE.out },
|
|
17588
|
+
children: token
|
|
17589
|
+
}
|
|
17590
|
+
)
|
|
17591
|
+
},
|
|
17592
|
+
i
|
|
17593
|
+
)
|
|
17594
|
+
) })
|
|
17595
|
+
}
|
|
17596
|
+
);
|
|
17597
|
+
}
|
|
17598
|
+
|
|
17599
|
+
// src/site/Parallax.tsx
|
|
17600
|
+
var React16 = __toESM(require("react"), 1);
|
|
17601
|
+
var import_react81 = require("motion/react");
|
|
17602
|
+
var import_jsx_runtime165 = require("react/jsx-runtime");
|
|
17603
|
+
var Parallax = React16.forwardRef(function Parallax2({ speed = 0.2, axis = "y", smooth = true, className, children, style, ...rest }, forwardedRef) {
|
|
17604
|
+
const reduce = (0, import_react81.useReducedMotion)();
|
|
17605
|
+
const innerRef = React16.useRef(null);
|
|
17606
|
+
React16.useImperativeHandle(forwardedRef, () => innerRef.current);
|
|
17607
|
+
const { scrollYProgress } = (0, import_react81.useScroll)({
|
|
17608
|
+
target: innerRef,
|
|
17609
|
+
offset: ["start end", "end start"]
|
|
17610
|
+
});
|
|
17611
|
+
const range = 100 * speed;
|
|
17612
|
+
const raw = (0, import_react81.useTransform)(scrollYProgress, [0, 1], [range, -range]);
|
|
17613
|
+
const smoothed = (0, import_react81.useSpring)(raw, { stiffness: 120, damping: 30, mass: 0.4 });
|
|
17614
|
+
const value = smooth ? smoothed : raw;
|
|
17615
|
+
if (reduce) {
|
|
17616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime165.jsx)("div", { ref: innerRef, className, style, ...rest, children });
|
|
17617
|
+
}
|
|
17618
|
+
return /* @__PURE__ */ (0, import_jsx_runtime165.jsx)(
|
|
17619
|
+
import_react81.motion.div,
|
|
17620
|
+
{
|
|
17621
|
+
ref: innerRef,
|
|
17622
|
+
className: cn("will-change-transform", className),
|
|
17623
|
+
style: { ...style, [axis]: value },
|
|
17624
|
+
...rest,
|
|
17625
|
+
children
|
|
17626
|
+
}
|
|
17627
|
+
);
|
|
17628
|
+
});
|
|
17629
|
+
|
|
17630
|
+
// src/site/Marquee.tsx
|
|
17631
|
+
var React17 = __toESM(require("react"), 1);
|
|
17632
|
+
var import_react82 = require("motion/react");
|
|
17633
|
+
var import_jsx_runtime166 = require("react/jsx-runtime");
|
|
17634
|
+
var Marquee = React17.forwardRef(function Marquee2({ speed = 60, direction = "left", pauseOnHover = true, gap = "3rem", className, children, ...rest }, ref) {
|
|
17635
|
+
const reduce = (0, import_react82.useReducedMotion)();
|
|
17636
|
+
const x = (0, import_react82.useMotionValue)(0);
|
|
17637
|
+
const setWidthRef = React17.useRef(0);
|
|
17638
|
+
const groupRef = React17.useRef(null);
|
|
17639
|
+
const [paused, setPaused] = React17.useState(false);
|
|
17640
|
+
React17.useEffect(() => {
|
|
17641
|
+
const el = groupRef.current;
|
|
17642
|
+
if (!el) return;
|
|
17643
|
+
const measure = () => {
|
|
17644
|
+
const gapPx = parseFloat(getComputedStyle(el.parentElement).columnGap || "0") || 0;
|
|
17645
|
+
setWidthRef.current = el.offsetWidth + gapPx;
|
|
17646
|
+
};
|
|
17647
|
+
measure();
|
|
17648
|
+
const ro = new ResizeObserver(measure);
|
|
17649
|
+
ro.observe(el);
|
|
17650
|
+
return () => ro.disconnect();
|
|
17651
|
+
}, []);
|
|
17652
|
+
(0, import_react82.useAnimationFrame)((_, delta) => {
|
|
17653
|
+
if (reduce || paused || setWidthRef.current === 0) return;
|
|
17654
|
+
const dir = direction === "left" ? -1 : 1;
|
|
17655
|
+
const moveBy = speed * delta / 1e3;
|
|
17656
|
+
let next = x.get() + dir * moveBy;
|
|
17657
|
+
const w = setWidthRef.current;
|
|
17658
|
+
if (next <= -w) next += w;
|
|
17659
|
+
else if (next >= w) next -= w;
|
|
17660
|
+
x.set(next);
|
|
17661
|
+
});
|
|
17662
|
+
if (reduce) {
|
|
17663
|
+
return /* @__PURE__ */ (0, import_jsx_runtime166.jsx)(
|
|
17664
|
+
"div",
|
|
17665
|
+
{
|
|
17666
|
+
ref,
|
|
17667
|
+
className: cn("flex w-full items-center overflow-x-auto", className),
|
|
17668
|
+
style: { columnGap: gap },
|
|
17669
|
+
...rest,
|
|
17670
|
+
children
|
|
17671
|
+
}
|
|
17672
|
+
);
|
|
17673
|
+
}
|
|
17674
|
+
return /* @__PURE__ */ (0, import_jsx_runtime166.jsx)(
|
|
17675
|
+
"div",
|
|
17676
|
+
{
|
|
17677
|
+
ref,
|
|
17678
|
+
className: cn("w-full overflow-hidden", className),
|
|
17679
|
+
onMouseEnter: pauseOnHover ? () => setPaused(true) : void 0,
|
|
17680
|
+
onMouseLeave: pauseOnHover ? () => setPaused(false) : void 0,
|
|
17681
|
+
...rest,
|
|
17682
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime166.jsxs)(import_react82.motion.div, { className: "flex w-max flex-nowrap items-center", style: { x, columnGap: gap }, children: [
|
|
17683
|
+
/* @__PURE__ */ (0, import_jsx_runtime166.jsx)("div", { ref: groupRef, className: "flex flex-nowrap items-center", style: { columnGap: gap }, children }),
|
|
17684
|
+
/* @__PURE__ */ (0, import_jsx_runtime166.jsx)("div", { className: "flex flex-nowrap items-center", style: { columnGap: gap }, "aria-hidden": true, children })
|
|
17685
|
+
] })
|
|
17686
|
+
}
|
|
17687
|
+
);
|
|
17688
|
+
});
|
|
17689
|
+
|
|
17690
|
+
// src/site/Magnetic.tsx
|
|
17691
|
+
var React18 = __toESM(require("react"), 1);
|
|
17692
|
+
var import_react83 = require("motion/react");
|
|
17693
|
+
var import_jsx_runtime167 = require("react/jsx-runtime");
|
|
17694
|
+
var Magnetic = React18.forwardRef(function Magnetic2({ strength = 0.35, max = 24, spring = "snappy", className, children, ...rest }, forwardedRef) {
|
|
17695
|
+
const reduce = (0, import_react83.useReducedMotion)();
|
|
17696
|
+
const innerRef = React18.useRef(null);
|
|
17697
|
+
React18.useImperativeHandle(forwardedRef, () => innerRef.current);
|
|
17698
|
+
const mvx = (0, import_react83.useMotionValue)(0);
|
|
17699
|
+
const mvy = (0, import_react83.useMotionValue)(0);
|
|
17700
|
+
const x = (0, import_react83.useSpring)(mvx, SPRING[spring]);
|
|
17701
|
+
const y = (0, import_react83.useSpring)(mvy, SPRING[spring]);
|
|
17702
|
+
const clamp3 = (v) => Math.max(-max, Math.min(max, v));
|
|
17703
|
+
function handleMove(e) {
|
|
17704
|
+
if (reduce) return;
|
|
17705
|
+
const el = innerRef.current;
|
|
17706
|
+
if (!el) return;
|
|
17707
|
+
const rect = el.getBoundingClientRect();
|
|
17708
|
+
const cx = rect.left + rect.width / 2;
|
|
17709
|
+
const cy = rect.top + rect.height / 2;
|
|
17710
|
+
mvx.set(clamp3((e.clientX - cx) * strength));
|
|
17711
|
+
mvy.set(clamp3((e.clientY - cy) * strength));
|
|
17712
|
+
}
|
|
17713
|
+
function reset() {
|
|
17714
|
+
mvx.set(0);
|
|
17715
|
+
mvy.set(0);
|
|
17716
|
+
}
|
|
17717
|
+
if (reduce) {
|
|
17718
|
+
return /* @__PURE__ */ (0, import_jsx_runtime167.jsx)("div", { ref: innerRef, className: cn("inline-block", className), ...rest, children });
|
|
17719
|
+
}
|
|
17720
|
+
return /* @__PURE__ */ (0, import_jsx_runtime167.jsx)(
|
|
17721
|
+
import_react83.motion.div,
|
|
17722
|
+
{
|
|
17723
|
+
ref: innerRef,
|
|
17724
|
+
className: cn("inline-block", className),
|
|
17725
|
+
style: { x, y },
|
|
17726
|
+
onMouseMove: handleMove,
|
|
17727
|
+
onMouseLeave: reset,
|
|
17728
|
+
...rest,
|
|
17729
|
+
children
|
|
17730
|
+
}
|
|
17731
|
+
);
|
|
17732
|
+
});
|
|
17733
|
+
|
|
17734
|
+
// src/site/agent-instructions.ts
|
|
17735
|
+
var SITE_AGENT_INSTRUCTIONS = `
|
|
17736
|
+
## Site kit (@timbal-ai/timbal-react/site)
|
|
17737
|
+
|
|
17738
|
+
Expressive **motion & interaction primitives** for marketing, brand, landing, and editorial pages \u2014 the counterpart to \`/app\` (which is for dashboards and operations UIs). Import from \`@timbal-ai/timbal-react/site\` (or the package root).
|
|
17739
|
+
|
|
17740
|
+
These are **mechanics, not art direction**: they animate whatever you put inside them. Compose them under a chosen aesthetic; they do not impose colors, type, or layout.
|
|
17741
|
+
|
|
17742
|
+
### When to use \`/site\` (and when not to)
|
|
17743
|
+
|
|
17744
|
+
- **Do** use \`/site\` for landing pages, hero sections, feature walkthroughs, logo walls, pricing pages, and editorial/brand storytelling.
|
|
17745
|
+
- **Do not** use \`/site\` inside dashboards, settings, tables, or in-thread chat artifacts \u2014 those stay on \`/app\` and \`/artifacts\`. Animated dashboard chrome reads as slop.
|
|
17746
|
+
- Every primitive is **reduced-motion-aware** (collapses to static, no-transform output under \`prefers-reduced-motion\`) and **SSR-safe** (no layout shift \u2014 elements occupy their space from first paint). You never need to guard them yourself.
|
|
17747
|
+
- Built on the \`motion\` engine the package already bundles \u2014 **no extra dependencies**.
|
|
17748
|
+
|
|
17749
|
+
### Dosing (anti-overuse \u2014 read this)
|
|
17750
|
+
|
|
17751
|
+
The failure mode is animating *everything*. Restraint is the brand signal.
|
|
17752
|
+
|
|
17753
|
+
- Pick **one** signature motion per section (e.g. a \`TextReveal\` headline **or** a \`Parallax\` hero image, not both stacked).
|
|
17754
|
+
- Stagger entrances down the page; do not fire ten reveals at once on first paint.
|
|
17755
|
+
- Reserve \`Magnetic\` for **primary** CTAs / nav, not every button.
|
|
17756
|
+
- Keep \`Parallax\` \`speed\` subtle (\`0.15\`\u2013\`0.35\`); large values look gimmicky.
|
|
17757
|
+
- Default durations are intentionally slow and weighted (\`DURATION.base\` = 0.7s) \u2014 that confident pacing is the point. Don't speed everything up to app-kit's 150ms.
|
|
17758
|
+
|
|
17759
|
+
### Component menu
|
|
17760
|
+
|
|
17761
|
+
| Component | Use for | Key props |
|
|
17762
|
+
|-----------|---------|-----------|
|
|
17763
|
+
| \`Reveal\` | Fade/slide a block in as it scrolls into view (headings, cards, images, list items). | \`variant\` (\`fade\` \\| \`fade-up\` \\| \`fade-down\` \\| \`fade-left\` \\| \`fade-right\` \\| \`blur\` \\| \`scale\` \\| \`mask-up\`, default \`fade-up\`), \`delay\`, \`duration\`, \`distance\` (px, default 28), \`amount\` (visibility fraction 0\u20131 / \`"some"\` / \`"all"\`, default 0.3), \`repeat\` (replay on re-enter), \`as\` (render element, e.g. \`"section"\`/\`"li"\`). |
|
|
17764
|
+
| \`TextReveal\` | Signature editorial headline entrance \u2014 text rides up token-by-token from a clip on a stagger. | \`children\` (**plain string only**), \`splitBy\` (\`words\` default \\| \`lines\`), \`stagger\` (default 0.06), \`delay\`, \`duration\`, \`amount\` (default 0.4), \`repeat\`, \`as\` (\`span\` default \\| \`h1\`\u2013\`h4\` \\| \`p\`). |
|
|
17765
|
+
| \`Parallax\` | Depth \u2014 translate a layer relative to scroll (hero images, background art). | \`speed\` (-0.6\u20260.6, positive = lags behind scroll, default 0.2), \`axis\` (\`y\` default \\| \`x\`), \`smooth\` (spring-damped, default true). |
|
|
17766
|
+
| \`Marquee\` | Seamless infinite scrolling row (logo walls, testimonials, ticker). Duplicates children internally \u2014 no visible seam. | \`speed\` (px/s, default 60), \`direction\` (\`left\` default \\| \`right\`), \`pauseOnHover\` (default true), \`gap\` (CSS length, default \`"3rem"\`). |
|
|
17767
|
+
| \`Magnetic\` | Pointer-following "magnetic" affordance for a **single** interactive child (primary CTA, nav link). | \`strength\` (fraction of cursor offset, default 0.35), \`max\` (px clamp, default 24), \`spring\` (\`"snappy"\` default \\| \`"smooth"\`). Wrap one button/link. |
|
|
17768
|
+
|
|
17769
|
+
### Motion tokens
|
|
17770
|
+
|
|
17771
|
+
\`EASE\` (cubic-bezier tuples: \`out\` / \`inOut\` / \`soft\`), \`DURATION\` (\`fast\` 0.4s / \`base\` 0.7s / \`slow\` 1.1s), and \`SPRING\` (\`snappy\` / \`smooth\`) are exported for custom \`motion\` work that should match the kit's feel. Prefer the component defaults; reach for tokens only when hand-rolling a bespoke animation.
|
|
17772
|
+
|
|
17773
|
+
### Example imports
|
|
17774
|
+
|
|
17775
|
+
\`\`\`tsx
|
|
17776
|
+
import { Reveal, TextReveal, Parallax, Marquee, Magnetic } from "@timbal-ai/timbal-react/site";
|
|
17777
|
+
\`\`\`
|
|
17778
|
+
|
|
17779
|
+
\`\`\`tsx
|
|
17780
|
+
<Reveal variant="fade-up" delay={0.1}>
|
|
17781
|
+
<TextReveal as="h1" className="text-6xl font-semibold">
|
|
17782
|
+
Built for the long run
|
|
17783
|
+
</TextReveal>
|
|
17784
|
+
</Reveal>
|
|
17785
|
+
|
|
17786
|
+
<Parallax speed={0.3}>
|
|
17787
|
+
<img src={hero} alt="" className="h-full w-full object-cover" />
|
|
17788
|
+
</Parallax>
|
|
17789
|
+
|
|
17790
|
+
<Magnetic strength={0.4}>
|
|
17791
|
+
<Button>Get started</Button>
|
|
17792
|
+
</Magnetic>
|
|
17793
|
+
\`\`\`
|
|
17794
|
+
|
|
17795
|
+
### Rules
|
|
17796
|
+
|
|
17797
|
+
- \`/site\` is for the **marketing/brand surface**, not the product app shell (\`/app\`) or in-chat widgets (\`/artifacts\`).
|
|
17798
|
+
- \`TextReveal\` takes a **string** child only \u2014 it splits internally; do not pass JSX.
|
|
17799
|
+
- \`Magnetic\` wraps a **single** interactive child; don't wrap whole layouts.
|
|
17800
|
+
- Trust the reduced-motion / SSR handling \u2014 never add your own \`prefers-reduced-motion\` guards around these.
|
|
17801
|
+
`.trim();
|
|
17336
17802
|
// Annotate the CommonJS export names for ESM import in node:
|
|
17337
17803
|
0 && (module.exports = {
|
|
17338
17804
|
APP_KIT_AGENT_INSTRUCTIONS,
|
|
@@ -17445,6 +17911,7 @@ function CircularProgress({
|
|
|
17445
17911
|
ContextMenuTrigger,
|
|
17446
17912
|
CopyButton,
|
|
17447
17913
|
DEFAULT_UPLOAD_ACCEPT,
|
|
17914
|
+
DURATION,
|
|
17448
17915
|
DangerZone,
|
|
17449
17916
|
DangerZoneAction,
|
|
17450
17917
|
DataTable,
|
|
@@ -17478,6 +17945,7 @@ function CircularProgress({
|
|
|
17478
17945
|
DropdownMenuSubContent,
|
|
17479
17946
|
DropdownMenuSubTrigger,
|
|
17480
17947
|
DropdownMenuTrigger,
|
|
17948
|
+
EASE,
|
|
17481
17949
|
EmptyState,
|
|
17482
17950
|
ExpandableSection,
|
|
17483
17951
|
Field,
|
|
@@ -17523,7 +17991,9 @@ function CircularProgress({
|
|
|
17523
17991
|
KbdGroup,
|
|
17524
17992
|
Label,
|
|
17525
17993
|
LineAreaChart,
|
|
17994
|
+
Magnetic,
|
|
17526
17995
|
MarkdownText,
|
|
17996
|
+
Marquee,
|
|
17527
17997
|
MemoPillSegmentedTabs,
|
|
17528
17998
|
Menubar,
|
|
17529
17999
|
MenubarCheckboxItem,
|
|
@@ -17562,6 +18032,7 @@ function CircularProgress({
|
|
|
17562
18032
|
PaginationLink,
|
|
17563
18033
|
PaginationNext,
|
|
17564
18034
|
PaginationPrevious,
|
|
18035
|
+
Parallax,
|
|
17565
18036
|
PieChart,
|
|
17566
18037
|
PillSegmentedTabs,
|
|
17567
18038
|
PlanBadge,
|
|
@@ -17578,8 +18049,11 @@ function CircularProgress({
|
|
|
17578
18049
|
RadioGroupItem,
|
|
17579
18050
|
Rating,
|
|
17580
18051
|
ResourceCard,
|
|
18052
|
+
Reveal,
|
|
17581
18053
|
SEMANTIC_COLOR_TOKENS,
|
|
18054
|
+
SITE_AGENT_INSTRUCTIONS,
|
|
17582
18055
|
SLOP_BUDGETS,
|
|
18056
|
+
SPRING,
|
|
17583
18057
|
STUDIO_NAV_MODE,
|
|
17584
18058
|
ScrollArea,
|
|
17585
18059
|
ScrollBar,
|
|
@@ -17639,6 +18113,7 @@ function CircularProgress({
|
|
|
17639
18113
|
TableHeader,
|
|
17640
18114
|
TableRow,
|
|
17641
18115
|
TagInput,
|
|
18116
|
+
TextReveal,
|
|
17642
18117
|
Textarea,
|
|
17643
18118
|
Thread,
|
|
17644
18119
|
ThreadPrimitive,
|