@almadar/ui 2.2.0 → 2.5.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/dist/{chunk-CC3UOKHI.js → chunk-FYYU3CHN.js} +2180 -383
- package/dist/chunk-K2D5D3WK.js +1033 -0
- package/dist/{chunk-DKQN5FVU.js → chunk-YLKXEXBP.js} +24 -24
- package/dist/components/index.d.ts +623 -48
- package/dist/components/index.js +300 -91
- package/dist/context/index.js +2 -2
- package/dist/providers/index.js +3 -3
- package/dist/renderer/index.d.ts +1 -1
- package/dist/renderer/index.js +1 -612
- package/package.json +36 -33
- package/dist/chunk-PL7MD6GF.js +0 -426
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { useTheme, useUISlots } from './chunk-
|
|
1
|
+
import { useTheme, useUISlots } from './chunk-YLKXEXBP.js';
|
|
2
2
|
import { useTranslate, useQuerySingleton } from './chunk-GOZKH7QW.js';
|
|
3
3
|
import { useEventBus } from './chunk-YXZM3WCF.js';
|
|
4
4
|
import { cn, debugGroup, debug, debugGroupEnd, getNestedValue, isDebugEnabled } from './chunk-KKCVDUK7.js';
|
|
5
|
+
import { isPortalSlot } from './chunk-K2D5D3WK.js';
|
|
5
6
|
import { __publicField } from './chunk-PKBMQBKP.js';
|
|
6
|
-
import * as React41 from 'react';
|
|
7
|
-
import React41__default, { useCallback, useRef, useState, useLayoutEffect, useEffect, createContext, useMemo, useContext, Suspense } from 'react';
|
|
8
7
|
import * as LucideIcons from 'lucide-react';
|
|
9
8
|
import { Loader2, ChevronDown, X, Check, Copy, AlertCircle, User, Sun, Moon, FileQuestion, Inbox, Search, Info, XCircle, CheckCircle, AlertTriangle, ChevronRight, Filter, Plus, ChevronLeft, HelpCircle, ChevronUp, MoreHorizontal, TrendingUp, TrendingDown, Minus, ArrowLeft, Calendar, Tag, Clock, CheckCircle2, DollarSign, FileText, Package } from 'lucide-react';
|
|
10
9
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
10
|
+
import * as React50 from 'react';
|
|
11
|
+
import React50__default, { useCallback, useRef, useState, useLayoutEffect, useEffect, lazy, createContext, useMemo, useId, useContext, Suspense } from 'react';
|
|
11
12
|
import { evaluate, createMinimalContext } from '@almadar/evaluator';
|
|
12
13
|
import { createPortal } from 'react-dom';
|
|
13
14
|
import ReactMarkdown from 'react-markdown';
|
|
@@ -16,7 +17,88 @@ import remarkMath from 'remark-math';
|
|
|
16
17
|
import rehypeKatex from 'rehype-katex';
|
|
17
18
|
import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism';
|
|
18
19
|
import dark from 'react-syntax-highlighter/dist/esm/styles/prism/vsc-dark-plus';
|
|
20
|
+
import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet';
|
|
21
|
+
import L from 'leaflet';
|
|
22
|
+
import 'leaflet/dist/leaflet.css';
|
|
19
23
|
|
|
24
|
+
var iconAliases = {
|
|
25
|
+
"close": LucideIcons.X,
|
|
26
|
+
"trash": LucideIcons.Trash2,
|
|
27
|
+
"loader": LucideIcons.Loader2,
|
|
28
|
+
"stop": LucideIcons.Square,
|
|
29
|
+
"volume": LucideIcons.Volume2,
|
|
30
|
+
"volume-off": LucideIcons.VolumeX,
|
|
31
|
+
"refresh": LucideIcons.RefreshCw,
|
|
32
|
+
"share": LucideIcons.Share2,
|
|
33
|
+
"sort-asc": LucideIcons.ArrowUpNarrowWide,
|
|
34
|
+
"sort-desc": LucideIcons.ArrowDownNarrowWide
|
|
35
|
+
};
|
|
36
|
+
function kebabToPascal(name) {
|
|
37
|
+
return name.split("-").map((part) => {
|
|
38
|
+
if (/^\d+$/.test(part)) return part;
|
|
39
|
+
return part.charAt(0).toUpperCase() + part.slice(1);
|
|
40
|
+
}).join("");
|
|
41
|
+
}
|
|
42
|
+
var resolvedCache = /* @__PURE__ */ new Map();
|
|
43
|
+
function resolveIcon(name) {
|
|
44
|
+
const cached = resolvedCache.get(name);
|
|
45
|
+
if (cached) return cached;
|
|
46
|
+
const resolved = doResolve(name);
|
|
47
|
+
resolvedCache.set(name, resolved);
|
|
48
|
+
return resolved;
|
|
49
|
+
}
|
|
50
|
+
function doResolve(name) {
|
|
51
|
+
if (iconAliases[name]) return iconAliases[name];
|
|
52
|
+
const pascalName = kebabToPascal(name);
|
|
53
|
+
const directLookup = LucideIcons[pascalName];
|
|
54
|
+
if (directLookup && typeof directLookup === "object") return directLookup;
|
|
55
|
+
const asIs = LucideIcons[name];
|
|
56
|
+
if (asIs && typeof asIs === "object") return asIs;
|
|
57
|
+
return LucideIcons.HelpCircle;
|
|
58
|
+
}
|
|
59
|
+
var sizeClasses = {
|
|
60
|
+
xs: "w-3 h-3",
|
|
61
|
+
sm: "w-4 h-4",
|
|
62
|
+
md: "w-5 h-5",
|
|
63
|
+
lg: "w-6 h-6",
|
|
64
|
+
xl: "w-8 h-8"
|
|
65
|
+
};
|
|
66
|
+
var animationClasses = {
|
|
67
|
+
none: "",
|
|
68
|
+
spin: "animate-spin",
|
|
69
|
+
pulse: "animate-pulse"
|
|
70
|
+
};
|
|
71
|
+
var Icon = ({
|
|
72
|
+
icon,
|
|
73
|
+
name,
|
|
74
|
+
size = "md",
|
|
75
|
+
color,
|
|
76
|
+
animation = "none",
|
|
77
|
+
className,
|
|
78
|
+
strokeWidth,
|
|
79
|
+
style
|
|
80
|
+
}) => {
|
|
81
|
+
const IconComponent = icon ?? (name ? resolveIcon(name) : LucideIcons.HelpCircle);
|
|
82
|
+
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
83
|
+
return /* @__PURE__ */ jsx(
|
|
84
|
+
IconComponent,
|
|
85
|
+
{
|
|
86
|
+
className: cn(
|
|
87
|
+
sizeClasses[size],
|
|
88
|
+
animationClasses[animation],
|
|
89
|
+
// Use theme's icon color or provided color
|
|
90
|
+
color ? color : "text-[var(--icon-color,currentColor)]",
|
|
91
|
+
className
|
|
92
|
+
),
|
|
93
|
+
strokeWidth: effectiveStrokeWidth,
|
|
94
|
+
style: {
|
|
95
|
+
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
96
|
+
...style
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
);
|
|
100
|
+
};
|
|
101
|
+
Icon.displayName = "Icon";
|
|
20
102
|
var variantStyles = {
|
|
21
103
|
primary: [
|
|
22
104
|
"bg-[var(--color-primary)] text-[var(--color-primary-foreground)]",
|
|
@@ -75,7 +157,7 @@ var iconSizeStyles = {
|
|
|
75
157
|
md: "h-4 w-4",
|
|
76
158
|
lg: "h-5 w-5"
|
|
77
159
|
};
|
|
78
|
-
var Button =
|
|
160
|
+
var Button = React50__default.forwardRef(
|
|
79
161
|
({
|
|
80
162
|
className,
|
|
81
163
|
variant = "primary",
|
|
@@ -84,8 +166,8 @@ var Button = React41__default.forwardRef(
|
|
|
84
166
|
disabled,
|
|
85
167
|
leftIcon,
|
|
86
168
|
rightIcon,
|
|
87
|
-
icon:
|
|
88
|
-
iconRight:
|
|
169
|
+
icon: iconProp,
|
|
170
|
+
iconRight: iconRightProp,
|
|
89
171
|
action,
|
|
90
172
|
actionPayload,
|
|
91
173
|
label,
|
|
@@ -94,6 +176,8 @@ var Button = React41__default.forwardRef(
|
|
|
94
176
|
...props
|
|
95
177
|
}, ref) => {
|
|
96
178
|
const eventBus = useEventBus();
|
|
179
|
+
const IconComponent = typeof iconProp === "string" ? resolveIcon(iconProp) : iconProp;
|
|
180
|
+
const IconRightComponent = typeof iconRightProp === "string" ? resolveIcon(iconRightProp) : iconRightProp;
|
|
97
181
|
const resolvedLeftIcon = leftIcon || IconComponent && /* @__PURE__ */ jsx(IconComponent, { className: iconSizeStyles[size] });
|
|
98
182
|
const resolvedRightIcon = rightIcon || IconRightComponent && /* @__PURE__ */ jsx(IconRightComponent, { className: iconSizeStyles[size] });
|
|
99
183
|
const handleClick = (e) => {
|
|
@@ -120,6 +204,7 @@ var Button = React41__default.forwardRef(
|
|
|
120
204
|
),
|
|
121
205
|
onClick: handleClick,
|
|
122
206
|
...props,
|
|
207
|
+
"data-testid": props["data-testid"] ?? (action ? `action-${action}` : void 0),
|
|
123
208
|
children: [
|
|
124
209
|
isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : resolvedLeftIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
|
|
125
210
|
children || label,
|
|
@@ -130,7 +215,7 @@ var Button = React41__default.forwardRef(
|
|
|
130
215
|
}
|
|
131
216
|
);
|
|
132
217
|
Button.displayName = "Button";
|
|
133
|
-
var Input =
|
|
218
|
+
var Input = React50__default.forwardRef(
|
|
134
219
|
({
|
|
135
220
|
className,
|
|
136
221
|
inputType,
|
|
@@ -242,7 +327,7 @@ var Input = React41__default.forwardRef(
|
|
|
242
327
|
}
|
|
243
328
|
);
|
|
244
329
|
Input.displayName = "Input";
|
|
245
|
-
var Label =
|
|
330
|
+
var Label = React50__default.forwardRef(
|
|
246
331
|
({ className, required, children, ...props }, ref) => {
|
|
247
332
|
return /* @__PURE__ */ jsxs(
|
|
248
333
|
"label",
|
|
@@ -262,7 +347,7 @@ var Label = React41__default.forwardRef(
|
|
|
262
347
|
}
|
|
263
348
|
);
|
|
264
349
|
Label.displayName = "Label";
|
|
265
|
-
var Textarea =
|
|
350
|
+
var Textarea = React50__default.forwardRef(
|
|
266
351
|
({ className, error, ...props }, ref) => {
|
|
267
352
|
return /* @__PURE__ */ jsx(
|
|
268
353
|
"textarea",
|
|
@@ -285,7 +370,7 @@ var Textarea = React41__default.forwardRef(
|
|
|
285
370
|
}
|
|
286
371
|
);
|
|
287
372
|
Textarea.displayName = "Textarea";
|
|
288
|
-
var Select =
|
|
373
|
+
var Select = React50__default.forwardRef(
|
|
289
374
|
({ className, options, placeholder, error, ...props }, ref) => {
|
|
290
375
|
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
291
376
|
/* @__PURE__ */ jsxs(
|
|
@@ -321,7 +406,7 @@ var Select = React41__default.forwardRef(
|
|
|
321
406
|
}
|
|
322
407
|
);
|
|
323
408
|
Select.displayName = "Select";
|
|
324
|
-
var Checkbox =
|
|
409
|
+
var Checkbox = React50__default.forwardRef(
|
|
325
410
|
({ className, label, id, ...props }, ref) => {
|
|
326
411
|
const inputId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
|
|
327
412
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
@@ -387,7 +472,7 @@ var shadowStyles = {
|
|
|
387
472
|
md: "shadow-[var(--shadow-main)]",
|
|
388
473
|
lg: "shadow-[var(--shadow-lg)]"
|
|
389
474
|
};
|
|
390
|
-
var Card =
|
|
475
|
+
var Card = React50__default.forwardRef(
|
|
391
476
|
({
|
|
392
477
|
className,
|
|
393
478
|
variant = "bordered",
|
|
@@ -423,9 +508,9 @@ var Card = React41__default.forwardRef(
|
|
|
423
508
|
}
|
|
424
509
|
);
|
|
425
510
|
Card.displayName = "Card";
|
|
426
|
-
var CardHeader =
|
|
511
|
+
var CardHeader = React50__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mb-4", className), ...props }));
|
|
427
512
|
CardHeader.displayName = "CardHeader";
|
|
428
|
-
var CardTitle =
|
|
513
|
+
var CardTitle = React50__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
429
514
|
"h3",
|
|
430
515
|
{
|
|
431
516
|
ref,
|
|
@@ -438,11 +523,11 @@ var CardTitle = React41__default.forwardRef(({ className, ...props }, ref) => /*
|
|
|
438
523
|
}
|
|
439
524
|
));
|
|
440
525
|
CardTitle.displayName = "CardTitle";
|
|
441
|
-
var CardContent =
|
|
526
|
+
var CardContent = React50__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("", className), ...props }));
|
|
442
527
|
CardContent.displayName = "CardContent";
|
|
443
528
|
var CardBody = CardContent;
|
|
444
529
|
CardBody.displayName = "CardBody";
|
|
445
|
-
var CardFooter =
|
|
530
|
+
var CardFooter = React50__default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
446
531
|
"div",
|
|
447
532
|
{
|
|
448
533
|
ref,
|
|
@@ -488,19 +573,28 @@ var sizeStyles2 = {
|
|
|
488
573
|
md: "px-2.5 py-1 text-sm",
|
|
489
574
|
lg: "px-3 py-1.5 text-base"
|
|
490
575
|
};
|
|
491
|
-
var Badge =
|
|
492
|
-
({ className, variant = "default", size = "sm", ...props }, ref) => {
|
|
493
|
-
|
|
576
|
+
var Badge = React50__default.forwardRef(
|
|
577
|
+
({ className, variant = "default", size = "sm", label, icon, children, ...props }, ref) => {
|
|
578
|
+
const iconSizes2 = { sm: "w-3 h-3", md: "w-3.5 h-3.5", lg: "w-4 h-4" };
|
|
579
|
+
const resolvedIcon = typeof icon === "string" ? (() => {
|
|
580
|
+
const I = resolveIcon(icon);
|
|
581
|
+
return I ? /* @__PURE__ */ jsx(I, { className: iconSizes2[size] }) : null;
|
|
582
|
+
})() : icon;
|
|
583
|
+
return /* @__PURE__ */ jsxs(
|
|
494
584
|
"span",
|
|
495
585
|
{
|
|
496
586
|
ref,
|
|
497
587
|
className: cn(
|
|
498
|
-
"inline-flex items-center font-bold rounded-[var(--radius-sm)]",
|
|
588
|
+
"inline-flex items-center gap-1 font-bold rounded-[var(--radius-sm)]",
|
|
499
589
|
variantStyles3[variant],
|
|
500
590
|
sizeStyles2[size],
|
|
501
591
|
className
|
|
502
592
|
),
|
|
503
|
-
...props
|
|
593
|
+
...props,
|
|
594
|
+
children: [
|
|
595
|
+
resolvedIcon,
|
|
596
|
+
children || label
|
|
597
|
+
]
|
|
504
598
|
}
|
|
505
599
|
);
|
|
506
600
|
}
|
|
@@ -512,7 +606,7 @@ var sizeStyles3 = {
|
|
|
512
606
|
md: "h-6 w-6",
|
|
513
607
|
lg: "h-8 w-8"
|
|
514
608
|
};
|
|
515
|
-
var Spinner =
|
|
609
|
+
var Spinner = React50__default.forwardRef(
|
|
516
610
|
({ className, size = "md", ...props }, ref) => {
|
|
517
611
|
return /* @__PURE__ */ jsx(
|
|
518
612
|
"div",
|
|
@@ -526,7 +620,7 @@ var Spinner = React41__default.forwardRef(
|
|
|
526
620
|
}
|
|
527
621
|
);
|
|
528
622
|
Spinner.displayName = "Spinner";
|
|
529
|
-
var
|
|
623
|
+
var sizeClasses2 = {
|
|
530
624
|
xs: "w-6 h-6 text-xs",
|
|
531
625
|
sm: "w-8 h-8 text-sm",
|
|
532
626
|
md: "w-10 h-10 text-base",
|
|
@@ -602,7 +696,7 @@ var Avatar = ({
|
|
|
602
696
|
"relative inline-flex items-center justify-center",
|
|
603
697
|
"bg-[var(--color-muted)] border-[length:var(--border-width)] border-[var(--color-border)]",
|
|
604
698
|
"overflow-hidden",
|
|
605
|
-
|
|
699
|
+
sizeClasses2[size],
|
|
606
700
|
isClickable && "cursor-pointer hover:bg-[var(--color-surface-hover)] transition-colors",
|
|
607
701
|
className
|
|
608
702
|
),
|
|
@@ -777,7 +871,7 @@ var positionStyles = {
|
|
|
777
871
|
fixed: "fixed",
|
|
778
872
|
sticky: "sticky"
|
|
779
873
|
};
|
|
780
|
-
var Box =
|
|
874
|
+
var Box = React50__default.forwardRef(
|
|
781
875
|
({
|
|
782
876
|
padding,
|
|
783
877
|
paddingX,
|
|
@@ -969,157 +1063,6 @@ var Divider = ({
|
|
|
969
1063
|
);
|
|
970
1064
|
};
|
|
971
1065
|
Divider.displayName = "Divider";
|
|
972
|
-
var iconMap = {
|
|
973
|
-
// Navigation & Actions
|
|
974
|
-
"chevron-right": LucideIcons.ChevronRight,
|
|
975
|
-
"chevron-left": LucideIcons.ChevronLeft,
|
|
976
|
-
"chevron-down": LucideIcons.ChevronDown,
|
|
977
|
-
"chevron-up": LucideIcons.ChevronUp,
|
|
978
|
-
"arrow-right": LucideIcons.ArrowRight,
|
|
979
|
-
"arrow-left": LucideIcons.ArrowLeft,
|
|
980
|
-
"arrow-up": LucideIcons.ArrowUp,
|
|
981
|
-
"arrow-down": LucideIcons.ArrowDown,
|
|
982
|
-
"x": LucideIcons.X,
|
|
983
|
-
"close": LucideIcons.X,
|
|
984
|
-
"menu": LucideIcons.Menu,
|
|
985
|
-
"more-vertical": LucideIcons.MoreVertical,
|
|
986
|
-
"more-horizontal": LucideIcons.MoreHorizontal,
|
|
987
|
-
// Status & Feedback
|
|
988
|
-
"check": LucideIcons.Check,
|
|
989
|
-
"check-circle": LucideIcons.CheckCircle,
|
|
990
|
-
"alert-circle": LucideIcons.AlertCircle,
|
|
991
|
-
"alert-triangle": LucideIcons.AlertTriangle,
|
|
992
|
-
"info": LucideIcons.Info,
|
|
993
|
-
"help-circle": LucideIcons.HelpCircle,
|
|
994
|
-
"loader": LucideIcons.Loader2,
|
|
995
|
-
// CRUD Operations
|
|
996
|
-
"plus": LucideIcons.Plus,
|
|
997
|
-
"minus": LucideIcons.Minus,
|
|
998
|
-
"edit": LucideIcons.Edit,
|
|
999
|
-
"pencil": LucideIcons.Pencil,
|
|
1000
|
-
"trash": LucideIcons.Trash2,
|
|
1001
|
-
"trash-2": LucideIcons.Trash2,
|
|
1002
|
-
"save": LucideIcons.Save,
|
|
1003
|
-
"copy": LucideIcons.Copy,
|
|
1004
|
-
"clipboard": LucideIcons.Clipboard,
|
|
1005
|
-
// Files & Documents
|
|
1006
|
-
"file": LucideIcons.File,
|
|
1007
|
-
"file-text": LucideIcons.FileText,
|
|
1008
|
-
"folder": LucideIcons.Folder,
|
|
1009
|
-
"folder-open": LucideIcons.FolderOpen,
|
|
1010
|
-
"download": LucideIcons.Download,
|
|
1011
|
-
"upload": LucideIcons.Upload,
|
|
1012
|
-
"image": LucideIcons.Image,
|
|
1013
|
-
// Communication
|
|
1014
|
-
"mail": LucideIcons.Mail,
|
|
1015
|
-
"message-circle": LucideIcons.MessageCircle,
|
|
1016
|
-
"send": LucideIcons.Send,
|
|
1017
|
-
"phone": LucideIcons.Phone,
|
|
1018
|
-
// User & Profile
|
|
1019
|
-
"user": LucideIcons.User,
|
|
1020
|
-
"users": LucideIcons.Users,
|
|
1021
|
-
"user-plus": LucideIcons.UserPlus,
|
|
1022
|
-
"settings": LucideIcons.Settings,
|
|
1023
|
-
"log-out": LucideIcons.LogOut,
|
|
1024
|
-
"log-in": LucideIcons.LogIn,
|
|
1025
|
-
// Search & Filter
|
|
1026
|
-
"search": LucideIcons.Search,
|
|
1027
|
-
"filter": LucideIcons.Filter,
|
|
1028
|
-
"sort-asc": LucideIcons.ArrowUpNarrowWide,
|
|
1029
|
-
"sort-desc": LucideIcons.ArrowDownNarrowWide,
|
|
1030
|
-
// Layout & View
|
|
1031
|
-
"grid": LucideIcons.Grid,
|
|
1032
|
-
"list": LucideIcons.List,
|
|
1033
|
-
"layout": LucideIcons.Layout,
|
|
1034
|
-
"maximize": LucideIcons.Maximize,
|
|
1035
|
-
"minimize": LucideIcons.Minimize,
|
|
1036
|
-
"eye": LucideIcons.Eye,
|
|
1037
|
-
"eye-off": LucideIcons.EyeOff,
|
|
1038
|
-
// Media & Playback
|
|
1039
|
-
"play": LucideIcons.Play,
|
|
1040
|
-
"pause": LucideIcons.Pause,
|
|
1041
|
-
"stop": LucideIcons.Square,
|
|
1042
|
-
"volume": LucideIcons.Volume2,
|
|
1043
|
-
"volume-off": LucideIcons.VolumeX,
|
|
1044
|
-
// Time & Calendar
|
|
1045
|
-
"calendar": LucideIcons.Calendar,
|
|
1046
|
-
"clock": LucideIcons.Clock,
|
|
1047
|
-
// Misc
|
|
1048
|
-
"star": LucideIcons.Star,
|
|
1049
|
-
"heart": LucideIcons.Heart,
|
|
1050
|
-
"home": LucideIcons.Home,
|
|
1051
|
-
"link": LucideIcons.Link,
|
|
1052
|
-
"external-link": LucideIcons.ExternalLink,
|
|
1053
|
-
"refresh": LucideIcons.RefreshCw,
|
|
1054
|
-
"refresh-cw": LucideIcons.RefreshCw,
|
|
1055
|
-
"zap": LucideIcons.Zap,
|
|
1056
|
-
"bell": LucideIcons.Bell,
|
|
1057
|
-
"bookmark": LucideIcons.Bookmark,
|
|
1058
|
-
"share": LucideIcons.Share2,
|
|
1059
|
-
"lock": LucideIcons.Lock,
|
|
1060
|
-
"unlock": LucideIcons.Unlock,
|
|
1061
|
-
"globe": LucideIcons.Globe,
|
|
1062
|
-
"database": LucideIcons.Database,
|
|
1063
|
-
"code": LucideIcons.Code,
|
|
1064
|
-
"terminal": LucideIcons.Terminal
|
|
1065
|
-
};
|
|
1066
|
-
function resolveIcon(name) {
|
|
1067
|
-
if (iconMap[name]) {
|
|
1068
|
-
return iconMap[name];
|
|
1069
|
-
}
|
|
1070
|
-
const lowerName = name.toLowerCase();
|
|
1071
|
-
if (iconMap[lowerName]) {
|
|
1072
|
-
return iconMap[lowerName];
|
|
1073
|
-
}
|
|
1074
|
-
const kebabName = name.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
1075
|
-
if (iconMap[kebabName]) {
|
|
1076
|
-
return iconMap[kebabName];
|
|
1077
|
-
}
|
|
1078
|
-
return LucideIcons.HelpCircle;
|
|
1079
|
-
}
|
|
1080
|
-
var sizeClasses2 = {
|
|
1081
|
-
xs: "w-3 h-3",
|
|
1082
|
-
sm: "w-4 h-4",
|
|
1083
|
-
md: "w-5 h-5",
|
|
1084
|
-
lg: "w-6 h-6",
|
|
1085
|
-
xl: "w-8 h-8"
|
|
1086
|
-
};
|
|
1087
|
-
var animationClasses = {
|
|
1088
|
-
none: "",
|
|
1089
|
-
spin: "animate-spin",
|
|
1090
|
-
pulse: "animate-pulse"
|
|
1091
|
-
};
|
|
1092
|
-
var Icon = ({
|
|
1093
|
-
icon,
|
|
1094
|
-
name,
|
|
1095
|
-
size = "md",
|
|
1096
|
-
color,
|
|
1097
|
-
animation = "none",
|
|
1098
|
-
className,
|
|
1099
|
-
strokeWidth,
|
|
1100
|
-
style
|
|
1101
|
-
}) => {
|
|
1102
|
-
const IconComponent = icon ?? (name ? resolveIcon(name) : LucideIcons.HelpCircle);
|
|
1103
|
-
const effectiveStrokeWidth = strokeWidth ?? void 0;
|
|
1104
|
-
return /* @__PURE__ */ jsx(
|
|
1105
|
-
IconComponent,
|
|
1106
|
-
{
|
|
1107
|
-
className: cn(
|
|
1108
|
-
sizeClasses2[size],
|
|
1109
|
-
animationClasses[animation],
|
|
1110
|
-
// Use theme's icon color or provided color
|
|
1111
|
-
color ? color : "text-[var(--icon-color,currentColor)]",
|
|
1112
|
-
className
|
|
1113
|
-
),
|
|
1114
|
-
strokeWidth: effectiveStrokeWidth,
|
|
1115
|
-
style: {
|
|
1116
|
-
...effectiveStrokeWidth === void 0 ? { strokeWidth: "var(--icon-stroke-width, 2)" } : {},
|
|
1117
|
-
...style
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
);
|
|
1121
|
-
};
|
|
1122
|
-
Icon.displayName = "Icon";
|
|
1123
1066
|
var colorClasses = {
|
|
1124
1067
|
default: "bg-[var(--color-primary)]",
|
|
1125
1068
|
primary: "bg-[var(--color-primary)]",
|
|
@@ -1273,7 +1216,7 @@ var ProgressBar = ({
|
|
|
1273
1216
|
return null;
|
|
1274
1217
|
};
|
|
1275
1218
|
ProgressBar.displayName = "ProgressBar";
|
|
1276
|
-
var Radio =
|
|
1219
|
+
var Radio = React50__default.forwardRef(
|
|
1277
1220
|
({
|
|
1278
1221
|
label,
|
|
1279
1222
|
helperText,
|
|
@@ -1377,7 +1320,7 @@ var Radio = React41__default.forwardRef(
|
|
|
1377
1320
|
}
|
|
1378
1321
|
);
|
|
1379
1322
|
Radio.displayName = "Radio";
|
|
1380
|
-
var Switch =
|
|
1323
|
+
var Switch = React50.forwardRef(
|
|
1381
1324
|
({
|
|
1382
1325
|
checked,
|
|
1383
1326
|
defaultChecked = false,
|
|
@@ -1388,10 +1331,10 @@ var Switch = React41.forwardRef(
|
|
|
1388
1331
|
name,
|
|
1389
1332
|
className
|
|
1390
1333
|
}, ref) => {
|
|
1391
|
-
const [isChecked, setIsChecked] =
|
|
1334
|
+
const [isChecked, setIsChecked] = React50.useState(
|
|
1392
1335
|
checked !== void 0 ? checked : defaultChecked
|
|
1393
1336
|
);
|
|
1394
|
-
|
|
1337
|
+
React50.useEffect(() => {
|
|
1395
1338
|
if (checked !== void 0) {
|
|
1396
1339
|
setIsChecked(checked);
|
|
1397
1340
|
}
|
|
@@ -1626,6 +1569,8 @@ var variantStyles5 = {
|
|
|
1626
1569
|
h4: "text-xl font-bold text-[var(--color-foreground)]",
|
|
1627
1570
|
h5: "text-lg font-bold text-[var(--color-foreground)]",
|
|
1628
1571
|
h6: "text-base font-bold text-[var(--color-foreground)]",
|
|
1572
|
+
heading: "text-2xl font-bold text-[var(--color-foreground)]",
|
|
1573
|
+
subheading: "text-lg font-semibold text-[var(--color-foreground)]",
|
|
1629
1574
|
body1: "text-base font-normal text-[var(--color-foreground)]",
|
|
1630
1575
|
body2: "text-sm font-normal text-[var(--color-foreground)]",
|
|
1631
1576
|
body: "text-base font-normal text-[var(--color-foreground)]",
|
|
@@ -1658,6 +1603,8 @@ var defaultElements = {
|
|
|
1658
1603
|
h4: "h4",
|
|
1659
1604
|
h5: "h5",
|
|
1660
1605
|
h6: "h6",
|
|
1606
|
+
heading: "h2",
|
|
1607
|
+
subheading: "h3",
|
|
1661
1608
|
body1: "p",
|
|
1662
1609
|
body2: "p",
|
|
1663
1610
|
body: "p",
|
|
@@ -1951,7 +1898,7 @@ var Overlay = ({
|
|
|
1951
1898
|
isVisible = true,
|
|
1952
1899
|
onClick,
|
|
1953
1900
|
className,
|
|
1954
|
-
blur =
|
|
1901
|
+
blur = false,
|
|
1955
1902
|
action
|
|
1956
1903
|
}) => {
|
|
1957
1904
|
const eventBus = useEventBus();
|
|
@@ -1966,7 +1913,7 @@ var Overlay = ({
|
|
|
1966
1913
|
"div",
|
|
1967
1914
|
{
|
|
1968
1915
|
className: cn(
|
|
1969
|
-
"fixed inset-0 z-40 bg-
|
|
1916
|
+
"fixed inset-0 z-40 bg-black/50",
|
|
1970
1917
|
blur && "backdrop-blur-sm",
|
|
1971
1918
|
className
|
|
1972
1919
|
),
|
|
@@ -1975,6 +1922,33 @@ var Overlay = ({
|
|
|
1975
1922
|
}
|
|
1976
1923
|
);
|
|
1977
1924
|
};
|
|
1925
|
+
var FlipContainer = ({
|
|
1926
|
+
flipped,
|
|
1927
|
+
className,
|
|
1928
|
+
children,
|
|
1929
|
+
onClick
|
|
1930
|
+
}) => {
|
|
1931
|
+
return /* @__PURE__ */ jsx(
|
|
1932
|
+
Box,
|
|
1933
|
+
{
|
|
1934
|
+
className: cn("relative w-full cursor-pointer", className),
|
|
1935
|
+
style: { perspective: "1000px" },
|
|
1936
|
+
onClick,
|
|
1937
|
+
children: /* @__PURE__ */ jsx(
|
|
1938
|
+
Box,
|
|
1939
|
+
{
|
|
1940
|
+
className: "relative w-full h-full transition-transform duration-500",
|
|
1941
|
+
style: {
|
|
1942
|
+
transformStyle: "preserve-3d",
|
|
1943
|
+
transform: flipped ? "rotateY(180deg)" : "rotateY(0deg)"
|
|
1944
|
+
},
|
|
1945
|
+
children
|
|
1946
|
+
}
|
|
1947
|
+
)
|
|
1948
|
+
}
|
|
1949
|
+
);
|
|
1950
|
+
};
|
|
1951
|
+
FlipContainer.displayName = "FlipContainer";
|
|
1978
1952
|
function toSharedContext(ctx) {
|
|
1979
1953
|
return createMinimalContext(
|
|
1980
1954
|
{
|
|
@@ -2031,8 +2005,8 @@ var LawReferenceTooltip = ({
|
|
|
2031
2005
|
position = "top",
|
|
2032
2006
|
className
|
|
2033
2007
|
}) => {
|
|
2034
|
-
const [isVisible, setIsVisible] =
|
|
2035
|
-
const timeoutRef =
|
|
2008
|
+
const [isVisible, setIsVisible] = React50__default.useState(false);
|
|
2009
|
+
const timeoutRef = React50__default.useRef(null);
|
|
2036
2010
|
const handleMouseEnter = () => {
|
|
2037
2011
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
2038
2012
|
timeoutRef.current = setTimeout(() => setIsVisible(true), 200);
|
|
@@ -2041,7 +2015,7 @@ var LawReferenceTooltip = ({
|
|
|
2041
2015
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
2042
2016
|
setIsVisible(false);
|
|
2043
2017
|
};
|
|
2044
|
-
|
|
2018
|
+
React50__default.useEffect(() => {
|
|
2045
2019
|
return () => {
|
|
2046
2020
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
2047
2021
|
};
|
|
@@ -2135,6 +2109,79 @@ var LawReferenceTooltip = ({
|
|
|
2135
2109
|
);
|
|
2136
2110
|
};
|
|
2137
2111
|
LawReferenceTooltip.displayName = "LawReferenceTooltip";
|
|
2112
|
+
var DAY_ABBREVIATIONS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2113
|
+
function DayCell({
|
|
2114
|
+
date,
|
|
2115
|
+
isToday = false,
|
|
2116
|
+
onClick,
|
|
2117
|
+
className
|
|
2118
|
+
}) {
|
|
2119
|
+
const handleClick = useCallback(() => {
|
|
2120
|
+
onClick?.(date);
|
|
2121
|
+
}, [onClick, date]);
|
|
2122
|
+
const dayAbbr = DAY_ABBREVIATIONS[date.getDay()];
|
|
2123
|
+
return /* @__PURE__ */ jsxs(
|
|
2124
|
+
Box,
|
|
2125
|
+
{
|
|
2126
|
+
className: cn(
|
|
2127
|
+
"p-2 text-center cursor-pointer hover:bg-[var(--color-muted)] transition-colors",
|
|
2128
|
+
isToday && "bg-blue-500/10",
|
|
2129
|
+
className
|
|
2130
|
+
),
|
|
2131
|
+
onClick: handleClick,
|
|
2132
|
+
children: [
|
|
2133
|
+
/* @__PURE__ */ jsx(
|
|
2134
|
+
Typography,
|
|
2135
|
+
{
|
|
2136
|
+
variant: "small",
|
|
2137
|
+
className: cn(
|
|
2138
|
+
"font-medium",
|
|
2139
|
+
isToday ? "text-blue-600" : "text-[var(--color-muted-foreground)]"
|
|
2140
|
+
),
|
|
2141
|
+
children: dayAbbr
|
|
2142
|
+
}
|
|
2143
|
+
),
|
|
2144
|
+
/* @__PURE__ */ jsx(
|
|
2145
|
+
Box,
|
|
2146
|
+
{
|
|
2147
|
+
display: "flex",
|
|
2148
|
+
rounded: "full",
|
|
2149
|
+
className: cn(
|
|
2150
|
+
"h-8 w-8 mx-auto items-center justify-center",
|
|
2151
|
+
isToday && "bg-blue-600 text-white"
|
|
2152
|
+
),
|
|
2153
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "font-semibold", children: date.getDate() })
|
|
2154
|
+
}
|
|
2155
|
+
)
|
|
2156
|
+
]
|
|
2157
|
+
}
|
|
2158
|
+
);
|
|
2159
|
+
}
|
|
2160
|
+
DayCell.displayName = "DayCell";
|
|
2161
|
+
function TimeSlotCell({
|
|
2162
|
+
time,
|
|
2163
|
+
onClick,
|
|
2164
|
+
className,
|
|
2165
|
+
children,
|
|
2166
|
+
isOccupied = false
|
|
2167
|
+
}) {
|
|
2168
|
+
const handleClick = useCallback(() => {
|
|
2169
|
+
onClick?.(time);
|
|
2170
|
+
}, [onClick, time]);
|
|
2171
|
+
return /* @__PURE__ */ jsx(
|
|
2172
|
+
Box,
|
|
2173
|
+
{
|
|
2174
|
+
className: cn(
|
|
2175
|
+
"p-1 min-h-[60px] cursor-pointer hover:bg-[var(--color-muted)] transition-colors",
|
|
2176
|
+
isOccupied && "bg-[var(--color-muted)]/30",
|
|
2177
|
+
className
|
|
2178
|
+
),
|
|
2179
|
+
onClick: handleClick,
|
|
2180
|
+
children
|
|
2181
|
+
}
|
|
2182
|
+
);
|
|
2183
|
+
}
|
|
2184
|
+
TimeSlotCell.displayName = "TimeSlotCell";
|
|
2138
2185
|
var heartIcon = (filled, size) => /* @__PURE__ */ jsx(
|
|
2139
2186
|
"svg",
|
|
2140
2187
|
{
|
|
@@ -2217,9 +2264,9 @@ function ScoreDisplay({
|
|
|
2217
2264
|
animated = true,
|
|
2218
2265
|
locale = "en-US"
|
|
2219
2266
|
}) {
|
|
2220
|
-
const [displayValue, setDisplayValue] =
|
|
2221
|
-
const [isAnimating, setIsAnimating] =
|
|
2222
|
-
|
|
2267
|
+
const [displayValue, setDisplayValue] = React50.useState(value);
|
|
2268
|
+
const [isAnimating, setIsAnimating] = React50.useState(false);
|
|
2269
|
+
React50.useEffect(() => {
|
|
2223
2270
|
if (!animated || displayValue === value) {
|
|
2224
2271
|
setDisplayValue(value);
|
|
2225
2272
|
return;
|
|
@@ -2292,9 +2339,9 @@ function ControlButton({
|
|
|
2292
2339
|
className
|
|
2293
2340
|
}) {
|
|
2294
2341
|
const eventBus = useEventBus();
|
|
2295
|
-
const [isPressed, setIsPressed] =
|
|
2342
|
+
const [isPressed, setIsPressed] = React50.useState(false);
|
|
2296
2343
|
const actualPressed = pressed ?? isPressed;
|
|
2297
|
-
const handlePointerDown =
|
|
2344
|
+
const handlePointerDown = React50.useCallback(
|
|
2298
2345
|
(e) => {
|
|
2299
2346
|
e.preventDefault();
|
|
2300
2347
|
if (disabled) return;
|
|
@@ -2304,7 +2351,7 @@ function ControlButton({
|
|
|
2304
2351
|
},
|
|
2305
2352
|
[disabled, pressEvent, eventBus, onPress]
|
|
2306
2353
|
);
|
|
2307
|
-
const handlePointerUp =
|
|
2354
|
+
const handlePointerUp = React50.useCallback(
|
|
2308
2355
|
(e) => {
|
|
2309
2356
|
e.preventDefault();
|
|
2310
2357
|
if (disabled) return;
|
|
@@ -2314,7 +2361,7 @@ function ControlButton({
|
|
|
2314
2361
|
},
|
|
2315
2362
|
[disabled, releaseEvent, eventBus, onRelease]
|
|
2316
2363
|
);
|
|
2317
|
-
const handlePointerLeave =
|
|
2364
|
+
const handlePointerLeave = React50.useCallback(
|
|
2318
2365
|
(e) => {
|
|
2319
2366
|
if (isPressed) {
|
|
2320
2367
|
setIsPressed(false);
|
|
@@ -2542,7 +2589,7 @@ var ErrorState = ({
|
|
|
2542
2589
|
);
|
|
2543
2590
|
};
|
|
2544
2591
|
ErrorState.displayName = "ErrorState";
|
|
2545
|
-
var ErrorBoundary = class extends
|
|
2592
|
+
var ErrorBoundary = class extends React50__default.Component {
|
|
2546
2593
|
constructor(props) {
|
|
2547
2594
|
super(props);
|
|
2548
2595
|
__publicField(this, "reset", () => {
|
|
@@ -2946,7 +2993,7 @@ var variantIconColors = {
|
|
|
2946
2993
|
warning: "text-[var(--color-warning)]",
|
|
2947
2994
|
error: "text-[var(--color-error)]"
|
|
2948
2995
|
};
|
|
2949
|
-
var
|
|
2996
|
+
var iconMap = {
|
|
2950
2997
|
info: Info,
|
|
2951
2998
|
success: CheckCircle,
|
|
2952
2999
|
warning: AlertTriangle,
|
|
@@ -2985,7 +3032,7 @@ var Alert = ({
|
|
|
2985
3032
|
/* @__PURE__ */ jsx("div", { className: "flex-shrink-0 mt-0.5", children: /* @__PURE__ */ jsx(
|
|
2986
3033
|
Icon,
|
|
2987
3034
|
{
|
|
2988
|
-
icon:
|
|
3035
|
+
icon: iconMap[variant],
|
|
2989
3036
|
size: "md",
|
|
2990
3037
|
className: variantIconColors[variant]
|
|
2991
3038
|
}
|
|
@@ -3997,7 +4044,7 @@ function getColsClass(cols) {
|
|
|
3997
4044
|
}
|
|
3998
4045
|
return classes.join(" ");
|
|
3999
4046
|
}
|
|
4000
|
-
var
|
|
4047
|
+
var Grid = ({
|
|
4001
4048
|
cols = 1,
|
|
4002
4049
|
rows,
|
|
4003
4050
|
gap = "md",
|
|
@@ -4034,7 +4081,7 @@ var Grid2 = ({
|
|
|
4034
4081
|
}
|
|
4035
4082
|
);
|
|
4036
4083
|
};
|
|
4037
|
-
|
|
4084
|
+
Grid.displayName = "Grid";
|
|
4038
4085
|
var InputGroup = ({
|
|
4039
4086
|
leftAddon,
|
|
4040
4087
|
rightAddon,
|
|
@@ -4089,7 +4136,7 @@ var InputGroup = ({
|
|
|
4089
4136
|
] });
|
|
4090
4137
|
};
|
|
4091
4138
|
InputGroup.displayName = "InputGroup";
|
|
4092
|
-
var
|
|
4139
|
+
var Menu = ({
|
|
4093
4140
|
trigger,
|
|
4094
4141
|
items,
|
|
4095
4142
|
position = "bottom-left",
|
|
@@ -4150,8 +4197,8 @@ var Menu2 = ({
|
|
|
4150
4197
|
"bottom-start": "top-full left-0 mt-2",
|
|
4151
4198
|
"bottom-end": "top-full right-0 mt-2"
|
|
4152
4199
|
};
|
|
4153
|
-
const triggerChild =
|
|
4154
|
-
const triggerElement =
|
|
4200
|
+
const triggerChild = React50__default.isValidElement(trigger) ? trigger : /* @__PURE__ */ jsx("span", { children: trigger });
|
|
4201
|
+
const triggerElement = React50__default.cloneElement(
|
|
4155
4202
|
triggerChild,
|
|
4156
4203
|
{
|
|
4157
4204
|
ref: triggerRef,
|
|
@@ -4247,7 +4294,7 @@ var Menu2 = ({
|
|
|
4247
4294
|
)
|
|
4248
4295
|
] });
|
|
4249
4296
|
};
|
|
4250
|
-
|
|
4297
|
+
Menu.displayName = "Menu";
|
|
4251
4298
|
var sizeClasses4 = {
|
|
4252
4299
|
sm: "max-w-md",
|
|
4253
4300
|
md: "max-w-lg",
|
|
@@ -4355,6 +4402,7 @@ var Modal = ({
|
|
|
4355
4402
|
{
|
|
4356
4403
|
type: "button",
|
|
4357
4404
|
onClick: handleClose,
|
|
4405
|
+
"data-event": "CLOSE",
|
|
4358
4406
|
className: cn(
|
|
4359
4407
|
"p-1 transition-colors rounded-[var(--radius-sm)]",
|
|
4360
4408
|
"hover:bg-[var(--color-muted)]"
|
|
@@ -4612,8 +4660,8 @@ var Popover = ({
|
|
|
4612
4660
|
onMouseEnter: handleOpen,
|
|
4613
4661
|
onMouseLeave: handleClose
|
|
4614
4662
|
};
|
|
4615
|
-
const childElement =
|
|
4616
|
-
const triggerElement =
|
|
4663
|
+
const childElement = React50__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
4664
|
+
const triggerElement = React50__default.cloneElement(
|
|
4617
4665
|
childElement,
|
|
4618
4666
|
{
|
|
4619
4667
|
ref: triggerRef,
|
|
@@ -5193,7 +5241,7 @@ var variantClasses = {
|
|
|
5193
5241
|
info: "bg-[var(--color-card)] border-[length:var(--border-width)] border-[var(--color-info)]",
|
|
5194
5242
|
warning: "bg-[var(--color-card)] border-[length:var(--border-width)] border-[var(--color-warning)]"
|
|
5195
5243
|
};
|
|
5196
|
-
var
|
|
5244
|
+
var iconMap2 = {
|
|
5197
5245
|
success: CheckCircle,
|
|
5198
5246
|
error: AlertCircle,
|
|
5199
5247
|
info: Info,
|
|
@@ -5251,7 +5299,7 @@ var Toast = ({
|
|
|
5251
5299
|
/* @__PURE__ */ jsx("div", { className: "flex-shrink-0 mt-0.5", children: /* @__PURE__ */ jsx(
|
|
5252
5300
|
Icon,
|
|
5253
5301
|
{
|
|
5254
|
-
icon:
|
|
5302
|
+
icon: iconMap2[variant],
|
|
5255
5303
|
size: "md",
|
|
5256
5304
|
className: iconColors[variant]
|
|
5257
5305
|
}
|
|
@@ -5343,8 +5391,8 @@ var Tooltip = ({
|
|
|
5343
5391
|
if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
|
|
5344
5392
|
};
|
|
5345
5393
|
}, []);
|
|
5346
|
-
const triggerElement =
|
|
5347
|
-
const trigger =
|
|
5394
|
+
const triggerElement = React50__default.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
|
|
5395
|
+
const trigger = React50__default.cloneElement(triggerElement, {
|
|
5348
5396
|
ref: triggerRef,
|
|
5349
5397
|
onMouseEnter: handleMouseEnter,
|
|
5350
5398
|
onMouseLeave: handleMouseLeave,
|
|
@@ -5593,7 +5641,7 @@ var WizardProgress = ({
|
|
|
5593
5641
|
children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: steps.map((step, index) => {
|
|
5594
5642
|
const isActive = index === currentStep;
|
|
5595
5643
|
const isCompleted = index < currentStep;
|
|
5596
|
-
return /* @__PURE__ */ jsxs(
|
|
5644
|
+
return /* @__PURE__ */ jsxs(React50__default.Fragment, { children: [
|
|
5597
5645
|
/* @__PURE__ */ jsx(
|
|
5598
5646
|
"button",
|
|
5599
5647
|
{
|
|
@@ -5723,7 +5771,7 @@ var WizardNavigation = ({
|
|
|
5723
5771
|
);
|
|
5724
5772
|
};
|
|
5725
5773
|
WizardNavigation.displayName = "WizardNavigation";
|
|
5726
|
-
var MarkdownContent =
|
|
5774
|
+
var MarkdownContent = React50__default.memo(
|
|
5727
5775
|
({ content, direction, className }) => {
|
|
5728
5776
|
const { t: _t } = useTranslate();
|
|
5729
5777
|
return /* @__PURE__ */ jsx(
|
|
@@ -5824,7 +5872,7 @@ var MarkdownContent = React41__default.memo(
|
|
|
5824
5872
|
(prev, next) => prev.content === next.content && prev.className === next.className && prev.direction === next.direction
|
|
5825
5873
|
);
|
|
5826
5874
|
MarkdownContent.displayName = "MarkdownContent";
|
|
5827
|
-
var CodeBlock =
|
|
5875
|
+
var CodeBlock = React50__default.memo(
|
|
5828
5876
|
({
|
|
5829
5877
|
code,
|
|
5830
5878
|
language = "text",
|
|
@@ -6049,6 +6097,156 @@ var ScaledDiagram = ({
|
|
|
6049
6097
|
);
|
|
6050
6098
|
};
|
|
6051
6099
|
ScaledDiagram.displayName = "ScaledDiagram";
|
|
6100
|
+
function getStartOfWeek(date) {
|
|
6101
|
+
const d = new Date(date);
|
|
6102
|
+
const day = d.getDay();
|
|
6103
|
+
const diff = d.getDate() - day + (day === 0 ? -6 : 1);
|
|
6104
|
+
d.setDate(diff);
|
|
6105
|
+
d.setHours(0, 0, 0, 0);
|
|
6106
|
+
return d;
|
|
6107
|
+
}
|
|
6108
|
+
function getWeekDays(start) {
|
|
6109
|
+
const days = [];
|
|
6110
|
+
for (let i = 0; i < 7; i++) {
|
|
6111
|
+
const day = new Date(start);
|
|
6112
|
+
day.setDate(start.getDate() + i);
|
|
6113
|
+
days.push(day);
|
|
6114
|
+
}
|
|
6115
|
+
return days;
|
|
6116
|
+
}
|
|
6117
|
+
function generateDefaultTimeSlots() {
|
|
6118
|
+
const slots = [];
|
|
6119
|
+
for (let hour = 9; hour <= 17; hour++) {
|
|
6120
|
+
slots.push(`${hour.toString().padStart(2, "0")}:00`);
|
|
6121
|
+
}
|
|
6122
|
+
return slots;
|
|
6123
|
+
}
|
|
6124
|
+
function eventInSlot(event, day, slotTime) {
|
|
6125
|
+
const eventStart = new Date(event.startTime);
|
|
6126
|
+
const [slotHour, slotMinute] = slotTime.split(":").map(Number);
|
|
6127
|
+
return eventStart.toDateString() === day.toDateString() && eventStart.getHours() === slotHour && eventStart.getMinutes() === slotMinute;
|
|
6128
|
+
}
|
|
6129
|
+
function CalendarGrid({
|
|
6130
|
+
weekStart,
|
|
6131
|
+
timeSlots,
|
|
6132
|
+
events = [],
|
|
6133
|
+
onSlotClick,
|
|
6134
|
+
onDayClick,
|
|
6135
|
+
onEventClick,
|
|
6136
|
+
className
|
|
6137
|
+
}) {
|
|
6138
|
+
const resolvedWeekStart = useMemo(
|
|
6139
|
+
() => weekStart ? getStartOfWeek(weekStart) : getStartOfWeek(/* @__PURE__ */ new Date()),
|
|
6140
|
+
[weekStart]
|
|
6141
|
+
);
|
|
6142
|
+
const weekDays = useMemo(
|
|
6143
|
+
() => getWeekDays(resolvedWeekStart),
|
|
6144
|
+
[resolvedWeekStart]
|
|
6145
|
+
);
|
|
6146
|
+
const resolvedTimeSlots = useMemo(
|
|
6147
|
+
() => timeSlots ?? generateDefaultTimeSlots(),
|
|
6148
|
+
[timeSlots]
|
|
6149
|
+
);
|
|
6150
|
+
const handleSlotClick = useCallback(
|
|
6151
|
+
(day, time) => {
|
|
6152
|
+
onSlotClick?.(day, time);
|
|
6153
|
+
},
|
|
6154
|
+
[onSlotClick]
|
|
6155
|
+
);
|
|
6156
|
+
const handleEventClick = useCallback(
|
|
6157
|
+
(event, e) => {
|
|
6158
|
+
e.stopPropagation();
|
|
6159
|
+
onEventClick?.(event);
|
|
6160
|
+
},
|
|
6161
|
+
[onEventClick]
|
|
6162
|
+
);
|
|
6163
|
+
const eventsForDayCount = useCallback(
|
|
6164
|
+
(day) => events.filter(
|
|
6165
|
+
(ev) => new Date(ev.startTime).toDateString() === day.toDateString()
|
|
6166
|
+
).length,
|
|
6167
|
+
[events]
|
|
6168
|
+
);
|
|
6169
|
+
const renderEvent = (event) => /* @__PURE__ */ jsx(
|
|
6170
|
+
Box,
|
|
6171
|
+
{
|
|
6172
|
+
rounded: "md",
|
|
6173
|
+
padding: "xs",
|
|
6174
|
+
border: true,
|
|
6175
|
+
className: cn(
|
|
6176
|
+
"cursor-pointer hover:shadow-sm transition-shadow text-xs truncate",
|
|
6177
|
+
event.color ? event.color : "bg-blue-500/15 border-blue-500/30 text-blue-600"
|
|
6178
|
+
),
|
|
6179
|
+
onClick: (e) => handleEventClick(event, e),
|
|
6180
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "small", className: "truncate font-medium", children: event.title })
|
|
6181
|
+
},
|
|
6182
|
+
event.id
|
|
6183
|
+
);
|
|
6184
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("overflow-x-auto", className), children: /* @__PURE__ */ jsxs(Box, { className: "min-w-[800px]", children: [
|
|
6185
|
+
/* @__PURE__ */ jsxs(Box, { className: "grid grid-cols-8 border-b border-[var(--color-border)]", children: [
|
|
6186
|
+
/* @__PURE__ */ jsx(Box, { className: "p-2" }),
|
|
6187
|
+
weekDays.map((day) => {
|
|
6188
|
+
const isToday = day.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
|
|
6189
|
+
const count = eventsForDayCount(day);
|
|
6190
|
+
return /* @__PURE__ */ jsxs(
|
|
6191
|
+
Box,
|
|
6192
|
+
{
|
|
6193
|
+
className: "border-l border-[var(--color-border)]",
|
|
6194
|
+
children: [
|
|
6195
|
+
/* @__PURE__ */ jsx(
|
|
6196
|
+
DayCell,
|
|
6197
|
+
{
|
|
6198
|
+
date: day,
|
|
6199
|
+
isToday,
|
|
6200
|
+
onClick: onDayClick
|
|
6201
|
+
}
|
|
6202
|
+
),
|
|
6203
|
+
count > 0 && /* @__PURE__ */ jsx(Box, { className: "text-center pb-1", children: /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: count }) })
|
|
6204
|
+
]
|
|
6205
|
+
},
|
|
6206
|
+
day.toISOString()
|
|
6207
|
+
);
|
|
6208
|
+
})
|
|
6209
|
+
] }),
|
|
6210
|
+
/* @__PURE__ */ jsx(Box, { className: "max-h-[500px] overflow-y-auto", children: resolvedTimeSlots.map((time) => /* @__PURE__ */ jsxs(
|
|
6211
|
+
Box,
|
|
6212
|
+
{
|
|
6213
|
+
className: "grid grid-cols-8 border-b border-[var(--color-border)]",
|
|
6214
|
+
children: [
|
|
6215
|
+
/* @__PURE__ */ jsx(Box, { className: "p-2 text-right pr-3", children: /* @__PURE__ */ jsx(
|
|
6216
|
+
Typography,
|
|
6217
|
+
{
|
|
6218
|
+
variant: "small",
|
|
6219
|
+
className: "text-[var(--color-muted-foreground)]",
|
|
6220
|
+
children: time
|
|
6221
|
+
}
|
|
6222
|
+
) }),
|
|
6223
|
+
weekDays.map((day) => {
|
|
6224
|
+
const slotEvents = events.filter(
|
|
6225
|
+
(ev) => eventInSlot(ev, day, time)
|
|
6226
|
+
);
|
|
6227
|
+
const isToday = day.toDateString() === (/* @__PURE__ */ new Date()).toDateString();
|
|
6228
|
+
return /* @__PURE__ */ jsx(
|
|
6229
|
+
TimeSlotCell,
|
|
6230
|
+
{
|
|
6231
|
+
time,
|
|
6232
|
+
isOccupied: slotEvents.length > 0,
|
|
6233
|
+
onClick: () => handleSlotClick(day, time),
|
|
6234
|
+
className: cn(
|
|
6235
|
+
"border-l border-[var(--color-border)]",
|
|
6236
|
+
isToday && "bg-blue-50/30"
|
|
6237
|
+
),
|
|
6238
|
+
children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: slotEvents.map(renderEvent) })
|
|
6239
|
+
},
|
|
6240
|
+
`${day.toISOString()}-${time}`
|
|
6241
|
+
);
|
|
6242
|
+
})
|
|
6243
|
+
]
|
|
6244
|
+
},
|
|
6245
|
+
time
|
|
6246
|
+
)) })
|
|
6247
|
+
] }) });
|
|
6248
|
+
}
|
|
6249
|
+
CalendarGrid.displayName = "CalendarGrid";
|
|
6052
6250
|
var RepeatableFormSection = ({
|
|
6053
6251
|
sectionType,
|
|
6054
6252
|
title,
|
|
@@ -6423,26 +6621,1356 @@ var FormSectionHeader = ({
|
|
|
6423
6621
|
);
|
|
6424
6622
|
};
|
|
6425
6623
|
FormSectionHeader.displayName = "FormSectionHeader";
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6624
|
+
var FlipCard = ({
|
|
6625
|
+
front,
|
|
6626
|
+
back,
|
|
6627
|
+
flipped = false,
|
|
6628
|
+
onFlip,
|
|
6629
|
+
className,
|
|
6630
|
+
height = "h-64"
|
|
6631
|
+
}) => {
|
|
6632
|
+
return /* @__PURE__ */ jsxs(
|
|
6633
|
+
FlipContainer,
|
|
6634
|
+
{
|
|
6635
|
+
flipped,
|
|
6636
|
+
className: cn(height, className),
|
|
6637
|
+
onClick: onFlip,
|
|
6638
|
+
children: [
|
|
6639
|
+
/* @__PURE__ */ jsx(
|
|
6640
|
+
Box,
|
|
6641
|
+
{
|
|
6642
|
+
className: "absolute inset-0 w-full h-full rounded-lg shadow-lg flex items-center justify-center p-6",
|
|
6643
|
+
style: { backfaceVisibility: "hidden", transform: "rotateY(0deg)" },
|
|
6644
|
+
children: front
|
|
6645
|
+
}
|
|
6646
|
+
),
|
|
6647
|
+
/* @__PURE__ */ jsx(
|
|
6648
|
+
Box,
|
|
6649
|
+
{
|
|
6650
|
+
className: "absolute inset-0 w-full h-full rounded-lg shadow-lg flex items-center justify-center p-6",
|
|
6651
|
+
style: { backfaceVisibility: "hidden", transform: "rotateY(180deg)" },
|
|
6652
|
+
children: back
|
|
6653
|
+
}
|
|
6654
|
+
)
|
|
6655
|
+
]
|
|
6656
|
+
}
|
|
6657
|
+
);
|
|
6658
|
+
};
|
|
6659
|
+
FlipCard.displayName = "FlipCard";
|
|
6660
|
+
var DEFAULT_OPTIONS = [
|
|
6661
|
+
{ label: "1W", value: "week" },
|
|
6662
|
+
{ label: "1M", value: "month" },
|
|
6663
|
+
{ label: "3M", value: "3months" },
|
|
6664
|
+
{ label: "1Y", value: "year" }
|
|
6665
|
+
];
|
|
6666
|
+
var DateRangeSelector = ({
|
|
6667
|
+
options = DEFAULT_OPTIONS,
|
|
6668
|
+
selected = "month",
|
|
6669
|
+
onSelect,
|
|
6670
|
+
className
|
|
6671
|
+
}) => {
|
|
6672
|
+
return /* @__PURE__ */ jsx(HStack, { gap: "xs", className: cn(className), children: options.map((option) => /* @__PURE__ */ jsx(
|
|
6673
|
+
Button,
|
|
6674
|
+
{
|
|
6675
|
+
variant: selected === option.value ? "primary" : "ghost",
|
|
6676
|
+
size: "sm",
|
|
6677
|
+
onClick: () => onSelect?.(option.value),
|
|
6678
|
+
children: option.label
|
|
6679
|
+
},
|
|
6680
|
+
option.value
|
|
6681
|
+
)) });
|
|
6682
|
+
};
|
|
6683
|
+
DateRangeSelector.displayName = "DateRangeSelector";
|
|
6684
|
+
var ChartLegend = ({
|
|
6685
|
+
items,
|
|
6686
|
+
className,
|
|
6687
|
+
direction = "horizontal"
|
|
6688
|
+
}) => {
|
|
6689
|
+
const Wrapper = direction === "horizontal" ? HStack : VStack;
|
|
6690
|
+
return /* @__PURE__ */ jsx(Wrapper, { gap: "md", className: cn("flex-wrap", className), children: items.map((item) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [
|
|
6691
|
+
/* @__PURE__ */ jsx(
|
|
6692
|
+
Box,
|
|
6693
|
+
{
|
|
6694
|
+
className: "rounded-full shrink-0",
|
|
6695
|
+
style: {
|
|
6696
|
+
width: 10,
|
|
6697
|
+
height: 10,
|
|
6698
|
+
backgroundColor: item.color
|
|
6699
|
+
}
|
|
6700
|
+
}
|
|
6701
|
+
),
|
|
6702
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-[var(--color-muted-foreground)]", children: item.label })
|
|
6703
|
+
] }, item.label)) });
|
|
6704
|
+
};
|
|
6705
|
+
ChartLegend.displayName = "ChartLegend";
|
|
6706
|
+
var LineChart = ({
|
|
6707
|
+
data,
|
|
6708
|
+
width = 400,
|
|
6709
|
+
height = 200,
|
|
6710
|
+
showGrid = true,
|
|
6711
|
+
showValues = false,
|
|
6712
|
+
showArea = true,
|
|
6713
|
+
lineColor = "var(--color-primary)",
|
|
6714
|
+
areaColor = "var(--color-primary)",
|
|
6715
|
+
className
|
|
6716
|
+
}) => {
|
|
6717
|
+
const gradientId = useId();
|
|
6718
|
+
const sortedData = useMemo(() => {
|
|
6719
|
+
return [...data].sort(
|
|
6720
|
+
(a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
|
|
6721
|
+
);
|
|
6722
|
+
}, [data]);
|
|
6723
|
+
const points = useMemo(() => {
|
|
6724
|
+
if (sortedData.length === 0) return [];
|
|
6725
|
+
const values = sortedData.map((d) => d.value);
|
|
6726
|
+
const minVal = Math.min(...values);
|
|
6727
|
+
const maxVal = Math.max(...values);
|
|
6728
|
+
const range = maxVal - minVal || 1;
|
|
6729
|
+
const padding = 20;
|
|
6730
|
+
const chartWidth = width - padding * 2;
|
|
6731
|
+
const chartHeight = height - padding * 2;
|
|
6732
|
+
return sortedData.map((point, index) => ({
|
|
6733
|
+
x: padding + index / (sortedData.length - 1 || 1) * chartWidth,
|
|
6734
|
+
y: padding + chartHeight - (point.value - minVal) / range * chartHeight,
|
|
6735
|
+
value: point.value,
|
|
6736
|
+
label: point.label
|
|
6737
|
+
}));
|
|
6738
|
+
}, [sortedData, width, height]);
|
|
6739
|
+
const linePath = useMemo(() => {
|
|
6740
|
+
if (points.length === 0) return "";
|
|
6741
|
+
return points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
|
|
6742
|
+
}, [points]);
|
|
6743
|
+
const areaPath = useMemo(() => {
|
|
6744
|
+
if (points.length === 0 || !showArea) return "";
|
|
6745
|
+
const bottom = height - 20;
|
|
6746
|
+
const first = points[0];
|
|
6747
|
+
const last = points[points.length - 1];
|
|
6748
|
+
return `${linePath} L ${last.x} ${bottom} L ${first.x} ${bottom} Z`;
|
|
6749
|
+
}, [linePath, points, height, showArea]);
|
|
6750
|
+
if (data.length === 0) {
|
|
6751
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center text-[var(--color-muted-foreground)]", className), style: { width, height }, children: "No data" });
|
|
6752
|
+
}
|
|
6753
|
+
return /* @__PURE__ */ jsx(Box, { className: cn(className), children: /* @__PURE__ */ jsxs(
|
|
6754
|
+
"svg",
|
|
6755
|
+
{
|
|
6756
|
+
viewBox: `0 0 ${width} ${height}`,
|
|
6757
|
+
width: "100%",
|
|
6758
|
+
height: "100%",
|
|
6759
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
6760
|
+
children: [
|
|
6761
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
6762
|
+
/* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: areaColor, stopOpacity: "0.3" }),
|
|
6763
|
+
/* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: areaColor, stopOpacity: "0" })
|
|
6764
|
+
] }) }),
|
|
6765
|
+
showGrid && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6766
|
+
/* @__PURE__ */ jsx("line", { x1: "20", y1: height * 0.25, x2: width - 20, y2: height * 0.25, stroke: "var(--color-border, #e5e7eb)", strokeWidth: "1" }),
|
|
6767
|
+
/* @__PURE__ */ jsx("line", { x1: "20", y1: height * 0.5, x2: width - 20, y2: height * 0.5, stroke: "var(--color-border, #e5e7eb)", strokeWidth: "1" }),
|
|
6768
|
+
/* @__PURE__ */ jsx("line", { x1: "20", y1: height * 0.75, x2: width - 20, y2: height * 0.75, stroke: "var(--color-border, #e5e7eb)", strokeWidth: "1" })
|
|
6769
|
+
] }),
|
|
6770
|
+
showArea && areaPath && /* @__PURE__ */ jsx("path", { d: areaPath, fill: `url(#${gradientId})` }),
|
|
6771
|
+
linePath && /* @__PURE__ */ jsx(
|
|
6772
|
+
"path",
|
|
6773
|
+
{
|
|
6774
|
+
d: linePath,
|
|
6775
|
+
fill: "none",
|
|
6776
|
+
stroke: lineColor,
|
|
6777
|
+
strokeWidth: "2",
|
|
6778
|
+
strokeLinejoin: "round",
|
|
6779
|
+
strokeLinecap: "round"
|
|
6780
|
+
}
|
|
6781
|
+
),
|
|
6782
|
+
points.map((point, index) => /* @__PURE__ */ jsx(
|
|
6783
|
+
"circle",
|
|
6784
|
+
{
|
|
6785
|
+
cx: point.x,
|
|
6786
|
+
cy: point.y,
|
|
6787
|
+
r: "4",
|
|
6788
|
+
fill: lineColor,
|
|
6789
|
+
stroke: "var(--color-background, white)",
|
|
6790
|
+
strokeWidth: "2"
|
|
6791
|
+
},
|
|
6792
|
+
index
|
|
6793
|
+
)),
|
|
6794
|
+
showValues && points.map((point, index) => /* @__PURE__ */ jsx(
|
|
6795
|
+
"text",
|
|
6796
|
+
{
|
|
6797
|
+
x: point.x,
|
|
6798
|
+
y: point.y - 10,
|
|
6799
|
+
textAnchor: "middle",
|
|
6800
|
+
fontSize: "11",
|
|
6801
|
+
fill: "var(--color-foreground, currentColor)",
|
|
6802
|
+
children: point.label ?? point.value
|
|
6803
|
+
},
|
|
6804
|
+
`label-${index}`
|
|
6805
|
+
))
|
|
6806
|
+
]
|
|
6807
|
+
}
|
|
6808
|
+
) });
|
|
6809
|
+
};
|
|
6810
|
+
LineChart.displayName = "LineChart";
|
|
6811
|
+
var sizeMap4 = {
|
|
6812
|
+
sm: { dot: 6, active: 8 },
|
|
6813
|
+
md: { dot: 8, active: 10 },
|
|
6814
|
+
lg: { dot: 10, active: 14 }
|
|
6815
|
+
};
|
|
6816
|
+
var stateColors = {
|
|
6817
|
+
active: "var(--color-primary)",
|
|
6818
|
+
complete: "var(--color-success, #22c55e)",
|
|
6819
|
+
pending: "var(--color-muted, #d4d4d8)"
|
|
6820
|
+
};
|
|
6821
|
+
var ProgressDots = ({
|
|
6822
|
+
count,
|
|
6823
|
+
currentIndex,
|
|
6824
|
+
getState,
|
|
6825
|
+
onDotClick,
|
|
6826
|
+
className,
|
|
6827
|
+
size = "md"
|
|
6828
|
+
}) => {
|
|
6829
|
+
const defaultGetState = useCallback(
|
|
6830
|
+
(index) => {
|
|
6831
|
+
if (index === currentIndex) return "active";
|
|
6832
|
+
return "pending";
|
|
6833
|
+
},
|
|
6834
|
+
[currentIndex]
|
|
6835
|
+
);
|
|
6836
|
+
const resolveState = getState ?? defaultGetState;
|
|
6837
|
+
const dims = sizeMap4[size];
|
|
6838
|
+
return /* @__PURE__ */ jsx(HStack, { gap: "xs", align: "center", className: cn(className), children: Array.from({ length: count }, (_, index) => {
|
|
6839
|
+
const state = resolveState(index);
|
|
6840
|
+
const isActive = state === "active";
|
|
6841
|
+
const dotSize = isActive ? dims.active : dims.dot;
|
|
6842
|
+
return /* @__PURE__ */ jsx(
|
|
6843
|
+
Box,
|
|
6844
|
+
{
|
|
6845
|
+
className: cn(
|
|
6846
|
+
"rounded-full transition-all duration-200",
|
|
6847
|
+
onDotClick && "cursor-pointer"
|
|
6848
|
+
),
|
|
6849
|
+
style: {
|
|
6850
|
+
width: dotSize,
|
|
6851
|
+
height: dotSize,
|
|
6852
|
+
backgroundColor: stateColors[state],
|
|
6853
|
+
transform: isActive ? "scale(1.2)" : "scale(1)"
|
|
6854
|
+
},
|
|
6855
|
+
onClick: onDotClick ? () => onDotClick(index) : void 0
|
|
6856
|
+
},
|
|
6857
|
+
index
|
|
6858
|
+
);
|
|
6859
|
+
}) });
|
|
6860
|
+
};
|
|
6861
|
+
ProgressDots.displayName = "ProgressDots";
|
|
6862
|
+
var sizeMap5 = {
|
|
6863
|
+
sm: { button: "sm", gap: "gap-0.5", container: "w-28" },
|
|
6864
|
+
md: { button: "md", gap: "gap-1", container: "w-40" },
|
|
6865
|
+
lg: { button: "lg", gap: "gap-1.5", container: "w-52" }
|
|
6866
|
+
};
|
|
6867
|
+
var arrowIcons = {
|
|
6868
|
+
up: "\u25B2",
|
|
6869
|
+
down: "\u25BC",
|
|
6870
|
+
left: "\u25C0",
|
|
6871
|
+
right: "\u25B6"
|
|
6872
|
+
};
|
|
6873
|
+
function DPad({
|
|
6874
|
+
onDirection,
|
|
6875
|
+
directionEvent,
|
|
6876
|
+
size = "md",
|
|
6877
|
+
includeDiagonals = false,
|
|
6878
|
+
className,
|
|
6879
|
+
disabled
|
|
6880
|
+
}) {
|
|
6881
|
+
const eventBus = useEventBus();
|
|
6882
|
+
const sizes = sizeMap5[size];
|
|
6883
|
+
const [activeDirections, setActiveDirections] = React50.useState(/* @__PURE__ */ new Set());
|
|
6884
|
+
const handlePress = React50.useCallback(
|
|
6885
|
+
(direction) => {
|
|
6886
|
+
setActiveDirections((prev) => new Set(prev).add(direction));
|
|
6887
|
+
if (directionEvent) eventBus.emit(`UI:${directionEvent}`, { direction, pressed: true });
|
|
6888
|
+
onDirection?.(direction, true);
|
|
6889
|
+
},
|
|
6890
|
+
[directionEvent, eventBus, onDirection]
|
|
6891
|
+
);
|
|
6892
|
+
const handleRelease = React50.useCallback(
|
|
6893
|
+
(direction) => {
|
|
6894
|
+
setActiveDirections((prev) => {
|
|
6895
|
+
const next = new Set(prev);
|
|
6896
|
+
next.delete(direction);
|
|
6897
|
+
return next;
|
|
6898
|
+
});
|
|
6899
|
+
if (directionEvent) eventBus.emit(`UI:${directionEvent}`, { direction, pressed: false });
|
|
6900
|
+
onDirection?.(direction, false);
|
|
6901
|
+
},
|
|
6902
|
+
[directionEvent, eventBus, onDirection]
|
|
6903
|
+
);
|
|
6904
|
+
const createButton = (direction) => /* @__PURE__ */ jsx(
|
|
6905
|
+
ControlButton,
|
|
6906
|
+
{
|
|
6907
|
+
icon: arrowIcons[direction],
|
|
6908
|
+
size: sizes.button,
|
|
6909
|
+
variant: "secondary",
|
|
6910
|
+
pressed: activeDirections.has(direction),
|
|
6911
|
+
onPress: () => handlePress(direction),
|
|
6912
|
+
onRelease: () => handleRelease(direction),
|
|
6913
|
+
disabled
|
|
6914
|
+
},
|
|
6915
|
+
direction
|
|
6916
|
+
);
|
|
6917
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("inline-grid grid-cols-3", sizes.gap, sizes.container, className), children: [
|
|
6918
|
+
/* @__PURE__ */ jsx("div", {}),
|
|
6919
|
+
createButton("up"),
|
|
6920
|
+
/* @__PURE__ */ jsx("div", {}),
|
|
6921
|
+
createButton("left"),
|
|
6922
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "w-6 h-6 rounded-full bg-gray-700 border-2 border-gray-600" }) }),
|
|
6923
|
+
createButton("right"),
|
|
6924
|
+
/* @__PURE__ */ jsx("div", {}),
|
|
6925
|
+
createButton("down"),
|
|
6926
|
+
/* @__PURE__ */ jsx("div", {})
|
|
6927
|
+
] });
|
|
6928
|
+
}
|
|
6929
|
+
DPad.displayName = "DPad";
|
|
6930
|
+
var sizeMap6 = {
|
|
6931
|
+
sm: "sm",
|
|
6932
|
+
md: "md",
|
|
6933
|
+
lg: "lg"
|
|
6934
|
+
};
|
|
6935
|
+
var layoutMap = {
|
|
6936
|
+
horizontal: "flex flex-row gap-2",
|
|
6937
|
+
vertical: "flex flex-col gap-2",
|
|
6938
|
+
diamond: "grid grid-cols-3 gap-1"
|
|
6939
|
+
};
|
|
6940
|
+
function ActionButtons({
|
|
6941
|
+
buttons,
|
|
6942
|
+
onAction,
|
|
6943
|
+
actionEvent,
|
|
6944
|
+
layout = "horizontal",
|
|
6945
|
+
size = "md",
|
|
6946
|
+
className,
|
|
6947
|
+
disabled
|
|
6948
|
+
}) {
|
|
6949
|
+
const eventBus = useEventBus();
|
|
6950
|
+
const [activeButtons, setActiveButtons] = React50.useState(/* @__PURE__ */ new Set());
|
|
6951
|
+
const handlePress = React50.useCallback(
|
|
6952
|
+
(id) => {
|
|
6953
|
+
setActiveButtons((prev) => new Set(prev).add(id));
|
|
6954
|
+
if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: true });
|
|
6955
|
+
onAction?.(id, true);
|
|
6956
|
+
},
|
|
6957
|
+
[actionEvent, eventBus, onAction]
|
|
6958
|
+
);
|
|
6959
|
+
const handleRelease = React50.useCallback(
|
|
6960
|
+
(id) => {
|
|
6961
|
+
setActiveButtons((prev) => {
|
|
6962
|
+
const next = new Set(prev);
|
|
6963
|
+
next.delete(id);
|
|
6964
|
+
return next;
|
|
6965
|
+
});
|
|
6966
|
+
if (actionEvent) eventBus.emit(`UI:${actionEvent}`, { id, pressed: false });
|
|
6967
|
+
onAction?.(id, false);
|
|
6968
|
+
},
|
|
6969
|
+
[actionEvent, eventBus, onAction]
|
|
6970
|
+
);
|
|
6971
|
+
if (layout === "diamond" && buttons.length === 4) {
|
|
6972
|
+
const [top, right, bottom, left] = buttons;
|
|
6973
|
+
return /* @__PURE__ */ jsxs("div", { className: cn(layoutMap[layout], className), children: [
|
|
6974
|
+
/* @__PURE__ */ jsx("div", {}),
|
|
6975
|
+
/* @__PURE__ */ jsx(
|
|
6976
|
+
ControlButton,
|
|
6977
|
+
{
|
|
6978
|
+
icon: top.icon,
|
|
6979
|
+
label: top.label,
|
|
6980
|
+
size: sizeMap6[size],
|
|
6981
|
+
variant: top.variant,
|
|
6982
|
+
pressed: activeButtons.has(top.id),
|
|
6983
|
+
onPress: () => handlePress(top.id),
|
|
6984
|
+
onRelease: () => handleRelease(top.id),
|
|
6985
|
+
disabled
|
|
6986
|
+
}
|
|
6987
|
+
),
|
|
6988
|
+
/* @__PURE__ */ jsx("div", {}),
|
|
6989
|
+
/* @__PURE__ */ jsx(
|
|
6990
|
+
ControlButton,
|
|
6991
|
+
{
|
|
6992
|
+
icon: left.icon,
|
|
6993
|
+
label: left.label,
|
|
6994
|
+
size: sizeMap6[size],
|
|
6995
|
+
variant: left.variant,
|
|
6996
|
+
pressed: activeButtons.has(left.id),
|
|
6997
|
+
onPress: () => handlePress(left.id),
|
|
6998
|
+
onRelease: () => handleRelease(left.id),
|
|
6999
|
+
disabled
|
|
7000
|
+
}
|
|
7001
|
+
),
|
|
7002
|
+
/* @__PURE__ */ jsx("div", {}),
|
|
7003
|
+
/* @__PURE__ */ jsx(
|
|
7004
|
+
ControlButton,
|
|
7005
|
+
{
|
|
7006
|
+
icon: right.icon,
|
|
7007
|
+
label: right.label,
|
|
7008
|
+
size: sizeMap6[size],
|
|
7009
|
+
variant: right.variant,
|
|
7010
|
+
pressed: activeButtons.has(right.id),
|
|
7011
|
+
onPress: () => handlePress(right.id),
|
|
7012
|
+
onRelease: () => handleRelease(right.id),
|
|
7013
|
+
disabled
|
|
7014
|
+
}
|
|
7015
|
+
),
|
|
7016
|
+
/* @__PURE__ */ jsx("div", {}),
|
|
7017
|
+
/* @__PURE__ */ jsx(
|
|
7018
|
+
ControlButton,
|
|
7019
|
+
{
|
|
7020
|
+
icon: bottom.icon,
|
|
7021
|
+
label: bottom.label,
|
|
7022
|
+
size: sizeMap6[size],
|
|
7023
|
+
variant: bottom.variant,
|
|
7024
|
+
pressed: activeButtons.has(bottom.id),
|
|
7025
|
+
onPress: () => handlePress(bottom.id),
|
|
7026
|
+
onRelease: () => handleRelease(bottom.id),
|
|
7027
|
+
disabled
|
|
7028
|
+
}
|
|
7029
|
+
),
|
|
7030
|
+
/* @__PURE__ */ jsx("div", {})
|
|
7031
|
+
] });
|
|
7032
|
+
}
|
|
7033
|
+
return /* @__PURE__ */ jsx("div", { className: cn(layoutMap[layout], className), children: buttons.map((button) => /* @__PURE__ */ jsx(
|
|
7034
|
+
ControlButton,
|
|
7035
|
+
{
|
|
7036
|
+
icon: button.icon,
|
|
7037
|
+
label: button.label,
|
|
7038
|
+
size: sizeMap6[size],
|
|
7039
|
+
variant: button.variant,
|
|
7040
|
+
pressed: activeButtons.has(button.id),
|
|
7041
|
+
onPress: () => handlePress(button.id),
|
|
7042
|
+
onRelease: () => handleRelease(button.id),
|
|
7043
|
+
disabled
|
|
7044
|
+
},
|
|
7045
|
+
button.id
|
|
7046
|
+
)) });
|
|
7047
|
+
}
|
|
7048
|
+
ActionButtons.displayName = "ActionButtons";
|
|
7049
|
+
var sizeMap7 = {
|
|
7050
|
+
sm: "text-xs px-2 py-1",
|
|
7051
|
+
md: "text-sm px-3 py-1.5",
|
|
7052
|
+
lg: "text-base px-4 py-2"
|
|
7053
|
+
};
|
|
7054
|
+
var variantMap2 = {
|
|
7055
|
+
default: "bg-gray-800/80 border-gray-700",
|
|
7056
|
+
primary: "bg-blue-900/80 border-blue-700",
|
|
7057
|
+
success: "bg-green-900/80 border-green-700",
|
|
7058
|
+
warning: "bg-yellow-900/80 border-yellow-700",
|
|
7059
|
+
danger: "bg-red-900/80 border-red-700"
|
|
7060
|
+
};
|
|
7061
|
+
function StatBadge({
|
|
7062
|
+
label,
|
|
7063
|
+
value = 0,
|
|
7064
|
+
max,
|
|
7065
|
+
format = "number",
|
|
7066
|
+
icon,
|
|
7067
|
+
size = "md",
|
|
7068
|
+
variant = "default",
|
|
7069
|
+
className,
|
|
7070
|
+
// Ignored config props (used for schema binding)
|
|
7071
|
+
source: _source,
|
|
7072
|
+
field: _field
|
|
7073
|
+
}) {
|
|
7074
|
+
const numValue = typeof value === "number" ? value : parseInt(String(value), 10) || 0;
|
|
7075
|
+
return /* @__PURE__ */ jsxs(
|
|
7076
|
+
"div",
|
|
7077
|
+
{
|
|
7078
|
+
className: cn(
|
|
7079
|
+
"inline-flex items-center gap-2 rounded-lg border backdrop-blur-sm",
|
|
7080
|
+
sizeMap7[size] ?? sizeMap7.md,
|
|
7081
|
+
variantMap2[variant] ?? variantMap2.default,
|
|
7082
|
+
className
|
|
7083
|
+
),
|
|
7084
|
+
children: [
|
|
7085
|
+
icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-lg", children: typeof icon === "string" ? (() => {
|
|
7086
|
+
const I = resolveIcon(icon);
|
|
7087
|
+
return I ? /* @__PURE__ */ jsx(I, { className: "w-4 h-4" }) : icon;
|
|
7088
|
+
})() : icon }),
|
|
7089
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-400 font-medium", children: label }),
|
|
7090
|
+
format === "hearts" && max && /* @__PURE__ */ jsx(
|
|
7091
|
+
HealthBar,
|
|
7092
|
+
{
|
|
7093
|
+
current: numValue,
|
|
7094
|
+
max,
|
|
7095
|
+
format: "hearts",
|
|
7096
|
+
size: size === "lg" ? "md" : "sm"
|
|
7097
|
+
}
|
|
7098
|
+
),
|
|
7099
|
+
format === "bar" && max && /* @__PURE__ */ jsx(
|
|
7100
|
+
HealthBar,
|
|
7101
|
+
{
|
|
7102
|
+
current: numValue,
|
|
7103
|
+
max,
|
|
7104
|
+
format: "bar",
|
|
7105
|
+
size: size === "lg" ? "md" : "sm"
|
|
7106
|
+
}
|
|
7107
|
+
),
|
|
7108
|
+
format === "number" && /* @__PURE__ */ jsx(
|
|
7109
|
+
ScoreDisplay,
|
|
7110
|
+
{
|
|
7111
|
+
value: numValue,
|
|
7112
|
+
size: size === "lg" ? "md" : "sm",
|
|
7113
|
+
animated: true
|
|
7114
|
+
}
|
|
7115
|
+
),
|
|
7116
|
+
format === "text" && /* @__PURE__ */ jsx("span", { className: "font-bold text-white", children: value })
|
|
7117
|
+
]
|
|
7118
|
+
}
|
|
7119
|
+
);
|
|
7120
|
+
}
|
|
7121
|
+
StatBadge.displayName = "StatBadge";
|
|
7122
|
+
var GROUP_COLORS = [
|
|
7123
|
+
"#3b82f6",
|
|
7124
|
+
// blue-500
|
|
7125
|
+
"#10b981",
|
|
7126
|
+
// emerald-500
|
|
7127
|
+
"#f59e0b",
|
|
7128
|
+
// amber-500
|
|
7129
|
+
"#ef4444",
|
|
7130
|
+
// red-500
|
|
7131
|
+
"#8b5cf6",
|
|
7132
|
+
// violet-500
|
|
7133
|
+
"#ec4899",
|
|
7134
|
+
// pink-500
|
|
7135
|
+
"#06b6d4",
|
|
7136
|
+
// cyan-500
|
|
7137
|
+
"#84cc16"
|
|
7138
|
+
// lime-500
|
|
7139
|
+
];
|
|
7140
|
+
var DEFAULT_NODE_COLOR = "#3b82f6";
|
|
7141
|
+
var DEFAULT_EDGE_COLOR = "#9ca3af";
|
|
7142
|
+
var DEFAULT_NODE_SIZE = 8;
|
|
7143
|
+
function resolveNodeColor(node, groups) {
|
|
7144
|
+
if (node.color) return node.color;
|
|
7145
|
+
if (node.group) {
|
|
7146
|
+
const idx = groups.indexOf(node.group);
|
|
7147
|
+
return GROUP_COLORS[idx % GROUP_COLORS.length];
|
|
7148
|
+
}
|
|
7149
|
+
return DEFAULT_NODE_COLOR;
|
|
7150
|
+
}
|
|
7151
|
+
var GraphView = ({
|
|
7152
|
+
nodes,
|
|
7153
|
+
edges,
|
|
7154
|
+
onNodeClick,
|
|
7155
|
+
onNodeHover,
|
|
7156
|
+
width: propWidth,
|
|
7157
|
+
height: propHeight,
|
|
7158
|
+
className,
|
|
7159
|
+
showLabels = true,
|
|
7160
|
+
zoomToFit = true
|
|
7161
|
+
}) => {
|
|
7162
|
+
const containerRef = useRef(null);
|
|
7163
|
+
const animRef = useRef(0);
|
|
7164
|
+
const [simNodes, setSimNodes] = useState([]);
|
|
7165
|
+
const [settled, setSettled] = useState(false);
|
|
7166
|
+
const [hoveredId, setHoveredId] = useState(null);
|
|
7167
|
+
const [dimensions, setDimensions] = useState({ width: propWidth ?? 600, height: propHeight ?? 400 });
|
|
7168
|
+
const w = propWidth ?? dimensions.width;
|
|
7169
|
+
const h = propHeight ?? dimensions.height;
|
|
7170
|
+
const groups = useMemo(
|
|
7171
|
+
() => [...new Set(nodes.map((n) => n.group).filter((g) => Boolean(g)))],
|
|
7172
|
+
[nodes]
|
|
7173
|
+
);
|
|
7174
|
+
const connectedIds = useMemo(() => {
|
|
7175
|
+
if (!hoveredId) return /* @__PURE__ */ new Set();
|
|
7176
|
+
const connected = /* @__PURE__ */ new Set([hoveredId]);
|
|
7177
|
+
for (const edge of edges) {
|
|
7178
|
+
if (edge.source === hoveredId) connected.add(edge.target);
|
|
7179
|
+
if (edge.target === hoveredId) connected.add(edge.source);
|
|
7180
|
+
}
|
|
7181
|
+
return connected;
|
|
7182
|
+
}, [hoveredId, edges]);
|
|
7183
|
+
useEffect(() => {
|
|
7184
|
+
if (propWidth && propHeight) return;
|
|
7185
|
+
const el = containerRef.current;
|
|
7186
|
+
if (!el) return;
|
|
7187
|
+
const update = () => {
|
|
7188
|
+
setDimensions({
|
|
7189
|
+
width: el.clientWidth || 600,
|
|
7190
|
+
height: el.clientHeight || 400
|
|
7191
|
+
});
|
|
7192
|
+
};
|
|
7193
|
+
update();
|
|
7194
|
+
window.addEventListener("resize", update);
|
|
7195
|
+
return () => window.removeEventListener("resize", update);
|
|
7196
|
+
}, [propWidth, propHeight]);
|
|
7197
|
+
useEffect(() => {
|
|
7198
|
+
if (nodes.length === 0) {
|
|
7199
|
+
setSimNodes([]);
|
|
7200
|
+
setSettled(true);
|
|
7201
|
+
return;
|
|
7202
|
+
}
|
|
7203
|
+
const initialNodes = nodes.map((n, idx) => {
|
|
7204
|
+
const angle = idx / nodes.length * 2 * Math.PI;
|
|
7205
|
+
const radius = Math.min(w, h) * 0.3;
|
|
7206
|
+
return {
|
|
7207
|
+
id: n.id,
|
|
7208
|
+
label: n.label,
|
|
7209
|
+
color: resolveNodeColor(n, groups),
|
|
7210
|
+
size: n.size ?? DEFAULT_NODE_SIZE,
|
|
7211
|
+
group: n.group,
|
|
7212
|
+
x: w / 2 + radius * Math.cos(angle) + (Math.random() - 0.5) * 20,
|
|
7213
|
+
y: h / 2 + radius * Math.sin(angle) + (Math.random() - 0.5) * 20,
|
|
7214
|
+
vx: 0,
|
|
7215
|
+
vy: 0,
|
|
7216
|
+
fx: 0,
|
|
7217
|
+
fy: 0
|
|
7218
|
+
};
|
|
7219
|
+
});
|
|
7220
|
+
let iterations = 0;
|
|
7221
|
+
const maxIterations = 120;
|
|
7222
|
+
let currentNodes = initialNodes;
|
|
7223
|
+
const tick = () => {
|
|
7224
|
+
const centerX = w / 2;
|
|
7225
|
+
const centerY = h / 2;
|
|
7226
|
+
for (const node of currentNodes) {
|
|
7227
|
+
node.fx = 0;
|
|
7228
|
+
node.fy = 0;
|
|
7229
|
+
}
|
|
7230
|
+
for (let i = 0; i < currentNodes.length; i++) {
|
|
7231
|
+
for (let j = i + 1; j < currentNodes.length; j++) {
|
|
7232
|
+
const a = currentNodes[i];
|
|
7233
|
+
const b = currentNodes[j];
|
|
7234
|
+
const dx = b.x - a.x;
|
|
7235
|
+
const dy = b.y - a.y;
|
|
7236
|
+
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
7237
|
+
const force = 800 / (dist * dist);
|
|
7238
|
+
const fx = dx / dist * force;
|
|
7239
|
+
const fy = dy / dist * force;
|
|
7240
|
+
a.fx -= fx;
|
|
7241
|
+
a.fy -= fy;
|
|
7242
|
+
b.fx += fx;
|
|
7243
|
+
b.fy += fy;
|
|
7244
|
+
}
|
|
7245
|
+
}
|
|
7246
|
+
for (const edge of edges) {
|
|
7247
|
+
const source = currentNodes.find((n) => n.id === edge.source);
|
|
7248
|
+
const target = currentNodes.find((n) => n.id === edge.target);
|
|
7249
|
+
if (!source || !target) continue;
|
|
7250
|
+
const dx = target.x - source.x;
|
|
7251
|
+
const dy = target.y - source.y;
|
|
7252
|
+
const dist = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
7253
|
+
const force = (dist - 100) * 0.05;
|
|
7254
|
+
const fx = dx / dist * force;
|
|
7255
|
+
const fy = dy / dist * force;
|
|
7256
|
+
source.fx += fx;
|
|
7257
|
+
source.fy += fy;
|
|
7258
|
+
target.fx -= fx;
|
|
7259
|
+
target.fy -= fy;
|
|
7260
|
+
}
|
|
7261
|
+
for (const node of currentNodes) {
|
|
7262
|
+
node.fx += (centerX - node.x) * 0.01;
|
|
7263
|
+
node.fy += (centerY - node.y) * 0.01;
|
|
7264
|
+
}
|
|
7265
|
+
const damping = 0.85;
|
|
7266
|
+
const margin = 40;
|
|
7267
|
+
for (const node of currentNodes) {
|
|
7268
|
+
node.vx = (node.vx + node.fx) * damping;
|
|
7269
|
+
node.vy = (node.vy + node.fy) * damping;
|
|
7270
|
+
node.x += node.vx;
|
|
7271
|
+
node.y += node.vy;
|
|
7272
|
+
node.x = Math.max(margin, Math.min(w - margin, node.x));
|
|
7273
|
+
node.y = Math.max(margin, Math.min(h - margin, node.y));
|
|
7274
|
+
}
|
|
7275
|
+
iterations++;
|
|
7276
|
+
setSimNodes([...currentNodes]);
|
|
7277
|
+
if (iterations < maxIterations) {
|
|
7278
|
+
animRef.current = requestAnimationFrame(tick);
|
|
7279
|
+
} else {
|
|
7280
|
+
setSettled(true);
|
|
7281
|
+
}
|
|
7282
|
+
};
|
|
7283
|
+
setSettled(false);
|
|
7284
|
+
animRef.current = requestAnimationFrame(tick);
|
|
7285
|
+
return () => {
|
|
7286
|
+
cancelAnimationFrame(animRef.current);
|
|
7287
|
+
};
|
|
7288
|
+
}, [nodes, edges, w, h, groups]);
|
|
7289
|
+
const viewBox = useMemo(() => {
|
|
7290
|
+
if (!zoomToFit || !settled || simNodes.length === 0) {
|
|
7291
|
+
return `0 0 ${w} ${h}`;
|
|
7292
|
+
}
|
|
7293
|
+
const pad = 60;
|
|
7294
|
+
let minX = Infinity;
|
|
7295
|
+
let minY = Infinity;
|
|
7296
|
+
let maxX = -Infinity;
|
|
7297
|
+
let maxY = -Infinity;
|
|
7298
|
+
for (const node of simNodes) {
|
|
7299
|
+
minX = Math.min(minX, node.x - node.size);
|
|
7300
|
+
minY = Math.min(minY, node.y - node.size);
|
|
7301
|
+
maxX = Math.max(maxX, node.x + node.size);
|
|
7302
|
+
maxY = Math.max(maxY, node.y + node.size);
|
|
7303
|
+
}
|
|
7304
|
+
const fitW = maxX - minX + pad * 2;
|
|
7305
|
+
const fitH = maxY - minY + pad * 2;
|
|
7306
|
+
return `${minX - pad} ${minY - pad} ${fitW} ${fitH}`;
|
|
7307
|
+
}, [zoomToFit, settled, simNodes, w, h]);
|
|
7308
|
+
const nodeMap = useMemo(() => {
|
|
7309
|
+
const map = /* @__PURE__ */ new Map();
|
|
7310
|
+
for (const n of simNodes) {
|
|
7311
|
+
map.set(n.id, n);
|
|
7312
|
+
}
|
|
7313
|
+
return map;
|
|
7314
|
+
}, [simNodes]);
|
|
7315
|
+
const handleNodeMouseEnter = useCallback(
|
|
7316
|
+
(node) => {
|
|
7317
|
+
setHoveredId(node.id);
|
|
7318
|
+
if (onNodeHover) {
|
|
7319
|
+
onNodeHover({ id: node.id, label: node.label, color: node.color, size: node.size, group: node.group });
|
|
7320
|
+
}
|
|
7321
|
+
},
|
|
7322
|
+
[onNodeHover]
|
|
7323
|
+
);
|
|
7324
|
+
const handleNodeMouseLeave = useCallback(() => {
|
|
7325
|
+
setHoveredId(null);
|
|
7326
|
+
if (onNodeHover) {
|
|
7327
|
+
onNodeHover(null);
|
|
7328
|
+
}
|
|
7329
|
+
}, [onNodeHover]);
|
|
7330
|
+
const handleNodeClickInternal = useCallback(
|
|
7331
|
+
(node) => {
|
|
7332
|
+
if (onNodeClick) {
|
|
7333
|
+
onNodeClick({ id: node.id, label: node.label, color: node.color, size: node.size, group: node.group });
|
|
7334
|
+
}
|
|
7335
|
+
},
|
|
7336
|
+
[onNodeClick]
|
|
7337
|
+
);
|
|
7338
|
+
if (nodes.length === 0) {
|
|
7339
|
+
return /* @__PURE__ */ jsx(Box, { className: cn("flex items-center justify-center", className), style: { width: w, height: h }, children: /* @__PURE__ */ jsx(Box, { className: "text-[var(--color-muted-foreground)] text-sm", children: "No graph data" }) });
|
|
7340
|
+
}
|
|
7341
|
+
return /* @__PURE__ */ jsx(
|
|
7342
|
+
Box,
|
|
7343
|
+
{
|
|
7344
|
+
ref: containerRef,
|
|
7345
|
+
className: cn("relative overflow-hidden rounded-lg border border-[var(--color-border)] bg-[var(--color-card)]", className),
|
|
7346
|
+
style: { width: propWidth ?? "100%", height: h },
|
|
7347
|
+
children: /* @__PURE__ */ jsxs(
|
|
7348
|
+
"svg",
|
|
7349
|
+
{
|
|
7350
|
+
width: "100%",
|
|
7351
|
+
height: "100%",
|
|
7352
|
+
viewBox,
|
|
7353
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
7354
|
+
children: [
|
|
7355
|
+
edges.map((edge, idx) => {
|
|
7356
|
+
const source = nodeMap.get(edge.source);
|
|
7357
|
+
const target = nodeMap.get(edge.target);
|
|
7358
|
+
if (!source || !target) return null;
|
|
7359
|
+
const isHighlighted = hoveredId ? connectedIds.has(edge.source) && connectedIds.has(edge.target) : true;
|
|
7360
|
+
return /* @__PURE__ */ jsxs("g", { children: [
|
|
7361
|
+
/* @__PURE__ */ jsx(
|
|
7362
|
+
"line",
|
|
7363
|
+
{
|
|
7364
|
+
x1: source.x,
|
|
7365
|
+
y1: source.y,
|
|
7366
|
+
x2: target.x,
|
|
7367
|
+
y2: target.y,
|
|
7368
|
+
stroke: edge.color ?? DEFAULT_EDGE_COLOR,
|
|
7369
|
+
strokeWidth: 1.5,
|
|
7370
|
+
opacity: isHighlighted ? 0.8 : 0.15
|
|
7371
|
+
}
|
|
7372
|
+
),
|
|
7373
|
+
showLabels && edge.label && /* @__PURE__ */ jsx(
|
|
7374
|
+
"text",
|
|
7375
|
+
{
|
|
7376
|
+
x: (source.x + target.x) / 2,
|
|
7377
|
+
y: (source.y + target.y) / 2 - 6,
|
|
7378
|
+
textAnchor: "middle",
|
|
7379
|
+
fill: "var(--color-muted-foreground)",
|
|
7380
|
+
fontSize: 9,
|
|
7381
|
+
opacity: isHighlighted ? 0.9 : 0.2,
|
|
7382
|
+
children: edge.label
|
|
7383
|
+
}
|
|
7384
|
+
)
|
|
7385
|
+
] }, `edge-${idx}`);
|
|
7386
|
+
}),
|
|
7387
|
+
simNodes.map((node) => {
|
|
7388
|
+
const isHighlighted = hoveredId ? connectedIds.has(node.id) : true;
|
|
7389
|
+
const isHovered = hoveredId === node.id;
|
|
7390
|
+
return /* @__PURE__ */ jsxs(
|
|
7391
|
+
"g",
|
|
7392
|
+
{
|
|
7393
|
+
style: { cursor: onNodeClick ? "pointer" : "default" },
|
|
7394
|
+
onMouseEnter: () => handleNodeMouseEnter(node),
|
|
7395
|
+
onMouseLeave: handleNodeMouseLeave,
|
|
7396
|
+
onClick: () => handleNodeClickInternal(node),
|
|
7397
|
+
children: [
|
|
7398
|
+
/* @__PURE__ */ jsx(
|
|
7399
|
+
"circle",
|
|
7400
|
+
{
|
|
7401
|
+
cx: node.x,
|
|
7402
|
+
cy: node.y,
|
|
7403
|
+
r: isHovered ? node.size * 1.4 : node.size,
|
|
7404
|
+
fill: node.color,
|
|
7405
|
+
opacity: isHighlighted ? 1 : 0.3,
|
|
7406
|
+
stroke: isHovered ? "#ffffff" : "none",
|
|
7407
|
+
strokeWidth: isHovered ? 2 : 0
|
|
7408
|
+
}
|
|
7409
|
+
),
|
|
7410
|
+
showLabels && /* @__PURE__ */ jsx(
|
|
7411
|
+
"text",
|
|
7412
|
+
{
|
|
7413
|
+
x: node.x,
|
|
7414
|
+
y: node.y + node.size + 12,
|
|
7415
|
+
textAnchor: "middle",
|
|
7416
|
+
fill: "var(--color-foreground)",
|
|
7417
|
+
fontSize: 11,
|
|
7418
|
+
fontWeight: isHovered ? "bold" : "normal",
|
|
7419
|
+
opacity: isHighlighted ? 0.9 : 0.2,
|
|
7420
|
+
children: node.label ?? node.id
|
|
7421
|
+
}
|
|
7422
|
+
)
|
|
7423
|
+
]
|
|
7424
|
+
},
|
|
7425
|
+
node.id
|
|
7426
|
+
);
|
|
7427
|
+
})
|
|
7428
|
+
]
|
|
7429
|
+
}
|
|
7430
|
+
)
|
|
7431
|
+
}
|
|
7432
|
+
);
|
|
7433
|
+
};
|
|
7434
|
+
GraphView.displayName = "GraphView";
|
|
7435
|
+
var defaultIcon = L.icon({
|
|
7436
|
+
iconUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png",
|
|
7437
|
+
iconRetinaUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png",
|
|
7438
|
+
shadowUrl: "https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png",
|
|
7439
|
+
iconSize: [25, 41],
|
|
7440
|
+
iconAnchor: [12, 41],
|
|
7441
|
+
popupAnchor: [1, -34],
|
|
7442
|
+
shadowSize: [41, 41]
|
|
7443
|
+
});
|
|
7444
|
+
L.Marker.prototype.options.icon = defaultIcon;
|
|
7445
|
+
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
7446
|
+
const map = useMap();
|
|
7447
|
+
const prevRef = useRef({ centerLat, centerLng, zoom });
|
|
7448
|
+
useEffect(() => {
|
|
7449
|
+
const prev = prevRef.current;
|
|
7450
|
+
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
7451
|
+
map.setView([centerLat, centerLng], zoom);
|
|
7452
|
+
prevRef.current = { centerLat, centerLng, zoom };
|
|
7453
|
+
}
|
|
7454
|
+
}, [map, centerLat, centerLng, zoom]);
|
|
7455
|
+
return null;
|
|
7456
|
+
}
|
|
7457
|
+
function MapClickHandler({ onMapClick }) {
|
|
7458
|
+
const map = useMap();
|
|
7459
|
+
useEffect(() => {
|
|
7460
|
+
if (!onMapClick) return;
|
|
7461
|
+
const handler = (e) => {
|
|
7462
|
+
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
7463
|
+
};
|
|
7464
|
+
map.on("click", handler);
|
|
7465
|
+
return () => {
|
|
7466
|
+
map.off("click", handler);
|
|
7467
|
+
};
|
|
7468
|
+
}, [map, onMapClick]);
|
|
7469
|
+
return null;
|
|
7470
|
+
}
|
|
7471
|
+
function MapView({
|
|
7472
|
+
markers = [],
|
|
7473
|
+
centerLat = 51.505,
|
|
7474
|
+
centerLng = -0.09,
|
|
7475
|
+
zoom = 13,
|
|
7476
|
+
height = "400px",
|
|
7477
|
+
onMarkerClick,
|
|
7478
|
+
onMapClick,
|
|
7479
|
+
mapClickEvent,
|
|
7480
|
+
markerClickEvent,
|
|
7481
|
+
showClickedPin = false,
|
|
7482
|
+
className,
|
|
7483
|
+
showAttribution = true
|
|
7484
|
+
}) {
|
|
7485
|
+
const eventBus = useEventBus();
|
|
7486
|
+
const [clickedPosition, setClickedPosition] = useState(null);
|
|
7487
|
+
const handleMapClick = useCallback((lat, lng) => {
|
|
7488
|
+
if (showClickedPin) {
|
|
7489
|
+
setClickedPosition({ lat, lng });
|
|
7490
|
+
}
|
|
7491
|
+
onMapClick?.(lat, lng);
|
|
7492
|
+
if (mapClickEvent) {
|
|
7493
|
+
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
7494
|
+
}
|
|
7495
|
+
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
7496
|
+
const handleMarkerClick = useCallback((marker) => {
|
|
7497
|
+
onMarkerClick?.(marker);
|
|
7498
|
+
if (markerClickEvent) {
|
|
7499
|
+
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
7500
|
+
}
|
|
7501
|
+
}, [onMarkerClick, markerClickEvent, eventBus]);
|
|
7502
|
+
return /* @__PURE__ */ jsx(
|
|
7503
|
+
Box,
|
|
7504
|
+
{
|
|
7505
|
+
className: cn("relative w-full overflow-hidden rounded-lg", className),
|
|
7506
|
+
style: { height },
|
|
7507
|
+
"data-testid": "map-view",
|
|
7508
|
+
children: /* @__PURE__ */ jsxs(
|
|
7509
|
+
MapContainer,
|
|
7510
|
+
{
|
|
7511
|
+
center: [centerLat, centerLng],
|
|
7512
|
+
zoom,
|
|
7513
|
+
style: { height: "100%", width: "100%" },
|
|
7514
|
+
attributionControl: showAttribution,
|
|
7515
|
+
children: [
|
|
7516
|
+
/* @__PURE__ */ jsx(
|
|
7517
|
+
TileLayer,
|
|
7518
|
+
{
|
|
7519
|
+
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
7520
|
+
attribution: showAttribution ? '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>' : void 0
|
|
7521
|
+
}
|
|
7522
|
+
),
|
|
7523
|
+
/* @__PURE__ */ jsx(MapUpdater, { centerLat, centerLng, zoom }),
|
|
7524
|
+
/* @__PURE__ */ jsx(MapClickHandler, { onMapClick: handleMapClick }),
|
|
7525
|
+
showClickedPin && clickedPosition && /* @__PURE__ */ jsx(Marker, { position: [clickedPosition.lat, clickedPosition.lng], children: /* @__PURE__ */ jsx(Popup, { children: /* @__PURE__ */ jsxs(Typography, { variant: "body2", children: [
|
|
7526
|
+
clickedPosition.lat.toFixed(5),
|
|
7527
|
+
", ",
|
|
7528
|
+
clickedPosition.lng.toFixed(5)
|
|
7529
|
+
] }) }) }),
|
|
7530
|
+
markers.map((marker) => /* @__PURE__ */ jsx(
|
|
7531
|
+
Marker,
|
|
7532
|
+
{
|
|
7533
|
+
position: [marker.lat, marker.lng],
|
|
7534
|
+
eventHandlers: onMarkerClick || markerClickEvent ? { click: () => handleMarkerClick(marker) } : void 0,
|
|
7535
|
+
children: marker.label ? /* @__PURE__ */ jsxs(Popup, { children: [
|
|
7536
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body2", children: marker.label }),
|
|
7537
|
+
marker.category ? /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "text-muted-foreground", children: marker.category }) : null
|
|
7538
|
+
] }) : null
|
|
7539
|
+
},
|
|
7540
|
+
marker.id
|
|
7541
|
+
))
|
|
7542
|
+
]
|
|
7543
|
+
}
|
|
7544
|
+
)
|
|
7545
|
+
}
|
|
7546
|
+
);
|
|
7547
|
+
}
|
|
7548
|
+
function fieldLabel(key) {
|
|
7549
|
+
return key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
7550
|
+
}
|
|
7551
|
+
function statusVariant(value) {
|
|
7552
|
+
const v = value.toLowerCase();
|
|
7553
|
+
if (["active", "completed", "done", "approved", "published", "resolved", "open", "online"].includes(v)) return "success";
|
|
7554
|
+
if (["pending", "in_progress", "in-progress", "review", "draft", "processing", "warning"].includes(v)) return "warning";
|
|
7555
|
+
if (["inactive", "deleted", "rejected", "failed", "error", "blocked", "closed", "offline"].includes(v)) return "error";
|
|
7556
|
+
if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
|
|
7557
|
+
return "default";
|
|
7558
|
+
}
|
|
7559
|
+
function formatDate(value) {
|
|
7560
|
+
if (!value) return "";
|
|
7561
|
+
const d = new Date(String(value));
|
|
7562
|
+
if (isNaN(d.getTime())) return String(value);
|
|
7563
|
+
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
7564
|
+
}
|
|
7565
|
+
function formatValue(value, format) {
|
|
7566
|
+
if (value === void 0 || value === null) return "";
|
|
7567
|
+
switch (format) {
|
|
7568
|
+
case "date":
|
|
7569
|
+
return formatDate(value);
|
|
7570
|
+
case "currency":
|
|
7571
|
+
return typeof value === "number" ? `$${value.toFixed(2)}` : String(value);
|
|
7572
|
+
case "number":
|
|
7573
|
+
return typeof value === "number" ? value.toLocaleString() : String(value);
|
|
7574
|
+
case "percent":
|
|
7575
|
+
return typeof value === "number" ? `${Math.round(value)}%` : String(value);
|
|
7576
|
+
case "boolean":
|
|
7577
|
+
return value ? "Yes" : "No";
|
|
7578
|
+
default:
|
|
7579
|
+
return String(value);
|
|
7580
|
+
}
|
|
7581
|
+
}
|
|
7582
|
+
var gapStyles5 = {
|
|
7583
|
+
none: "gap-0",
|
|
7584
|
+
sm: "gap-2",
|
|
7585
|
+
md: "gap-4",
|
|
7586
|
+
lg: "gap-6",
|
|
7587
|
+
xl: "gap-8"
|
|
7588
|
+
};
|
|
7589
|
+
var DataGrid = ({
|
|
7590
|
+
entity,
|
|
7591
|
+
fields: fieldsProp,
|
|
7592
|
+
columns: columnsProp,
|
|
7593
|
+
itemActions,
|
|
7594
|
+
cols,
|
|
7595
|
+
gap = "md",
|
|
7596
|
+
minCardWidth = 280,
|
|
7597
|
+
className,
|
|
7598
|
+
isLoading = false,
|
|
7599
|
+
error = null,
|
|
7600
|
+
imageField
|
|
7601
|
+
}) => {
|
|
7602
|
+
const eventBus = useEventBus();
|
|
7603
|
+
const { t } = useTranslate();
|
|
7604
|
+
const fields = fieldsProp ?? columnsProp ?? [];
|
|
7605
|
+
const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
7606
|
+
const titleField = fields.find((f) => f.variant === "h3" || f.variant === "h4") ?? fields[0];
|
|
7607
|
+
const badgeFields = fields.filter((f) => f.variant === "badge" && f !== titleField);
|
|
7608
|
+
const bodyFields = fields.filter((f) => f !== titleField && !badgeFields.includes(f));
|
|
7609
|
+
const primaryActions = itemActions?.filter((a) => a.variant !== "danger") ?? [];
|
|
7610
|
+
const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
|
|
7611
|
+
const handleActionClick = (action, itemData) => (e) => {
|
|
7612
|
+
e.stopPropagation();
|
|
7613
|
+
eventBus.emit(`UI:${action.event}`, { row: itemData });
|
|
7614
|
+
};
|
|
7615
|
+
const gridTemplateColumns = cols ? void 0 : `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
|
|
7616
|
+
const colsClass = cols ? {
|
|
7617
|
+
1: "grid-cols-1",
|
|
7618
|
+
2: "sm:grid-cols-2",
|
|
7619
|
+
3: "sm:grid-cols-2 lg:grid-cols-3",
|
|
7620
|
+
4: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",
|
|
7621
|
+
5: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5",
|
|
7622
|
+
6: "sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6"
|
|
7623
|
+
}[cols] : void 0;
|
|
7624
|
+
if (isLoading) {
|
|
7625
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
|
|
7626
|
+
}
|
|
7627
|
+
if (error) {
|
|
7628
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
7629
|
+
}
|
|
7630
|
+
if (data.length === 0) {
|
|
7631
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
|
|
7632
|
+
}
|
|
7633
|
+
return /* @__PURE__ */ jsx(
|
|
7634
|
+
Box,
|
|
7635
|
+
{
|
|
7636
|
+
className: cn("grid", gapStyles5[gap], colsClass, className),
|
|
7637
|
+
style: gridTemplateColumns ? { gridTemplateColumns } : void 0,
|
|
7638
|
+
children: data.map((item, index) => {
|
|
7639
|
+
const itemData = item;
|
|
7640
|
+
const id = itemData.id || String(index);
|
|
7641
|
+
const titleValue = getNestedValue(itemData, titleField?.name ?? "");
|
|
7642
|
+
return /* @__PURE__ */ jsxs(
|
|
7643
|
+
Box,
|
|
7644
|
+
{
|
|
7645
|
+
"data-entity-row": true,
|
|
7646
|
+
className: cn(
|
|
7647
|
+
"bg-[var(--color-card)] rounded-[var(--radius-lg)]",
|
|
7648
|
+
"border border-[var(--color-border)]",
|
|
7649
|
+
"shadow-[var(--shadow-sm)] hover:shadow-[var(--shadow-hover)]",
|
|
7650
|
+
"hover:border-[var(--color-primary)] transition-all",
|
|
7651
|
+
"flex flex-col"
|
|
7652
|
+
),
|
|
7653
|
+
children: [
|
|
7654
|
+
imageField && (() => {
|
|
7655
|
+
const imgUrl = getNestedValue(itemData, imageField);
|
|
7656
|
+
if (!imgUrl || typeof imgUrl !== "string") return null;
|
|
7657
|
+
return /* @__PURE__ */ jsx(Box, { className: "w-full aspect-video overflow-hidden rounded-t-[var(--radius-lg)]", children: /* @__PURE__ */ jsx(
|
|
7658
|
+
"img",
|
|
7659
|
+
{
|
|
7660
|
+
src: imgUrl,
|
|
7661
|
+
alt: titleValue !== void 0 ? String(titleValue) : "",
|
|
7662
|
+
className: "w-full h-full object-cover",
|
|
7663
|
+
loading: "lazy"
|
|
7664
|
+
}
|
|
7665
|
+
) });
|
|
7666
|
+
})(),
|
|
7667
|
+
/* @__PURE__ */ jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
|
|
7668
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
|
|
7669
|
+
titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
7670
|
+
titleField?.icon && /* @__PURE__ */ jsx(Icon, { name: titleField.icon, size: "sm", className: "text-[var(--color-primary)] flex-shrink-0" }),
|
|
7671
|
+
/* @__PURE__ */ jsx(
|
|
7672
|
+
Typography,
|
|
7673
|
+
{
|
|
7674
|
+
variant: titleField?.variant === "h3" ? "h3" : "h4",
|
|
7675
|
+
className: "font-semibold truncate",
|
|
7676
|
+
children: String(titleValue)
|
|
7677
|
+
}
|
|
7678
|
+
)
|
|
7679
|
+
] }),
|
|
7680
|
+
badgeFields.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-wrap", children: badgeFields.map((field) => {
|
|
7681
|
+
const val = getNestedValue(itemData, field.name);
|
|
7682
|
+
if (val === void 0 || val === null) return null;
|
|
7683
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
7684
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
|
|
7685
|
+
/* @__PURE__ */ jsx(Badge, { variant: statusVariant(String(val)), children: String(val) })
|
|
7686
|
+
] }, field.name);
|
|
7687
|
+
}) })
|
|
7688
|
+
] }),
|
|
7689
|
+
dangerActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
7690
|
+
Button,
|
|
7691
|
+
{
|
|
7692
|
+
variant: "ghost",
|
|
7693
|
+
size: "sm",
|
|
7694
|
+
onClick: handleActionClick(action, itemData),
|
|
7695
|
+
"data-testid": `action-${action.event}`,
|
|
7696
|
+
className: "text-[var(--color-error)] hover:bg-[var(--color-error)]/10 px-2",
|
|
7697
|
+
children: [
|
|
7698
|
+
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs" }),
|
|
7699
|
+
action.label
|
|
7700
|
+
]
|
|
7701
|
+
},
|
|
7702
|
+
idx
|
|
7703
|
+
)) })
|
|
7704
|
+
] }) }),
|
|
7705
|
+
bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
|
|
7706
|
+
const value = getNestedValue(itemData, field.name);
|
|
7707
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
7708
|
+
if (field.format === "boolean") {
|
|
7709
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
|
|
7710
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
7711
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-[var(--color-muted-foreground)]" }),
|
|
7712
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel(field.name) })
|
|
7713
|
+
] }),
|
|
7714
|
+
/* @__PURE__ */ jsx(Badge, { variant: value ? "success" : "neutral", children: value ? t("common.yes") || "Yes" : t("common.no") || "No" })
|
|
7715
|
+
] }, field.name);
|
|
7716
|
+
}
|
|
7717
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-center", children: [
|
|
7718
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
7719
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-[var(--color-muted-foreground)]" }),
|
|
7720
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel(field.name) })
|
|
7721
|
+
] }),
|
|
7722
|
+
/* @__PURE__ */ jsx(
|
|
7723
|
+
Typography,
|
|
7724
|
+
{
|
|
7725
|
+
variant: field.variant === "caption" ? "caption" : "small",
|
|
7726
|
+
className: "text-right truncate max-w-[60%]",
|
|
7727
|
+
children: formatValue(value, field.format)
|
|
7728
|
+
}
|
|
7729
|
+
)
|
|
7730
|
+
] }, field.name);
|
|
7731
|
+
}) }) }),
|
|
7732
|
+
primaryActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 mt-auto border-t border-[var(--color-border)]", children: /* @__PURE__ */ jsx(HStack, { gap: "sm", className: "justify-end", children: primaryActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
7733
|
+
Button,
|
|
7734
|
+
{
|
|
7735
|
+
variant: action.variant === "primary" ? "primary" : "ghost",
|
|
7736
|
+
size: "sm",
|
|
7737
|
+
onClick: handleActionClick(action, itemData),
|
|
7738
|
+
"data-testid": `action-${action.event}`,
|
|
7739
|
+
children: [
|
|
7740
|
+
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
7741
|
+
action.label
|
|
7742
|
+
]
|
|
7743
|
+
},
|
|
7744
|
+
idx
|
|
7745
|
+
)) }) })
|
|
7746
|
+
]
|
|
7747
|
+
},
|
|
7748
|
+
id
|
|
7749
|
+
);
|
|
7750
|
+
})
|
|
7751
|
+
}
|
|
7752
|
+
);
|
|
7753
|
+
};
|
|
7754
|
+
DataGrid.displayName = "DataGrid";
|
|
7755
|
+
function fieldLabel2(key) {
|
|
7756
|
+
return key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
7757
|
+
}
|
|
7758
|
+
function statusVariant2(value) {
|
|
7759
|
+
const v = value.toLowerCase();
|
|
7760
|
+
if (["active", "completed", "done", "approved", "published", "resolved", "open", "online"].includes(v)) return "success";
|
|
7761
|
+
if (["pending", "in_progress", "in-progress", "review", "draft", "processing", "warning"].includes(v)) return "warning";
|
|
7762
|
+
if (["inactive", "deleted", "rejected", "failed", "error", "blocked", "closed", "offline"].includes(v)) return "error";
|
|
7763
|
+
if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
|
|
7764
|
+
return "default";
|
|
7765
|
+
}
|
|
7766
|
+
function formatDate2(value) {
|
|
7767
|
+
if (!value) return "";
|
|
7768
|
+
const d = new Date(String(value));
|
|
7769
|
+
if (isNaN(d.getTime())) return String(value);
|
|
7770
|
+
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
7771
|
+
}
|
|
7772
|
+
function formatValue2(value, format) {
|
|
7773
|
+
if (value === void 0 || value === null) return "";
|
|
7774
|
+
switch (format) {
|
|
7775
|
+
case "date":
|
|
7776
|
+
return formatDate2(value);
|
|
7777
|
+
case "currency":
|
|
7778
|
+
return typeof value === "number" ? `$${value.toFixed(2)}` : String(value);
|
|
7779
|
+
case "number":
|
|
7780
|
+
return typeof value === "number" ? value.toLocaleString() : String(value);
|
|
7781
|
+
case "percent":
|
|
7782
|
+
return typeof value === "number" ? `${Math.round(value)}%` : String(value);
|
|
7783
|
+
case "boolean":
|
|
7784
|
+
return value ? "Yes" : "No";
|
|
7785
|
+
default:
|
|
7786
|
+
return String(value);
|
|
7787
|
+
}
|
|
7788
|
+
}
|
|
7789
|
+
var DataList = ({
|
|
7790
|
+
entity,
|
|
7791
|
+
fields: fieldsProp,
|
|
7792
|
+
columns: columnsProp,
|
|
7793
|
+
itemActions,
|
|
7794
|
+
gap = "none",
|
|
7795
|
+
variant = "default",
|
|
7796
|
+
className,
|
|
7797
|
+
isLoading = false,
|
|
7798
|
+
error = null
|
|
7799
|
+
}) => {
|
|
7800
|
+
const eventBus = useEventBus();
|
|
7801
|
+
const { t } = useTranslate();
|
|
7802
|
+
const fields = fieldsProp ?? columnsProp ?? [];
|
|
7803
|
+
const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
7804
|
+
const titleField = fields.find((f) => f.variant === "h3" || f.variant === "h4") ?? fields[0];
|
|
7805
|
+
const badgeFields = fields.filter((f) => f.variant === "badge" && f !== titleField);
|
|
7806
|
+
const progressFields = fields.filter((f) => f.variant === "progress");
|
|
7807
|
+
const bodyFields = fields.filter(
|
|
7808
|
+
(f) => f !== titleField && !badgeFields.includes(f) && !progressFields.includes(f)
|
|
7809
|
+
);
|
|
7810
|
+
const handleActionClick = (action, itemData) => (e) => {
|
|
7811
|
+
e.stopPropagation();
|
|
7812
|
+
eventBus.emit(`UI:${action.event}`, { row: itemData });
|
|
7813
|
+
};
|
|
7814
|
+
if (isLoading) {
|
|
7815
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading..." }) });
|
|
7816
|
+
}
|
|
7817
|
+
if (error) {
|
|
7818
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-8", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
|
|
7819
|
+
}
|
|
7820
|
+
if (data.length === 0) {
|
|
7821
|
+
return /* @__PURE__ */ jsx(Box, { className: "text-center py-12", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
|
|
7822
|
+
}
|
|
7823
|
+
const gapClass = {
|
|
7824
|
+
none: "",
|
|
7825
|
+
sm: "gap-1",
|
|
7826
|
+
md: "gap-2",
|
|
7827
|
+
lg: "gap-4"
|
|
7828
|
+
}[gap];
|
|
7829
|
+
const isCard = variant === "card";
|
|
7830
|
+
const isCompact = variant === "compact";
|
|
7831
|
+
return /* @__PURE__ */ jsx(
|
|
7832
|
+
Box,
|
|
7833
|
+
{
|
|
7834
|
+
className: cn(
|
|
7835
|
+
isCard && "bg-[var(--color-card)] rounded-[var(--radius-xl)] border border-[var(--color-border)] shadow-[var(--shadow-lg)] overflow-hidden",
|
|
7836
|
+
!isCard && gapClass,
|
|
7837
|
+
className
|
|
7838
|
+
),
|
|
7839
|
+
children: data.map((item, index) => {
|
|
7840
|
+
const itemData = item;
|
|
7841
|
+
const id = itemData.id || String(index);
|
|
7842
|
+
const titleValue = getNestedValue(itemData, titleField?.name ?? "");
|
|
7843
|
+
const isLast = index === data.length - 1;
|
|
7844
|
+
return /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, children: [
|
|
7845
|
+
/* @__PURE__ */ jsxs(
|
|
7846
|
+
Box,
|
|
7847
|
+
{
|
|
7848
|
+
className: cn(
|
|
7849
|
+
"group flex items-center gap-4 transition-all duration-200",
|
|
7850
|
+
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
7851
|
+
"hover:bg-[var(--color-muted)]/80",
|
|
7852
|
+
!isCard && !isCompact && "rounded-[var(--radius-lg)] border border-transparent hover:border-[var(--color-border)]"
|
|
7853
|
+
),
|
|
7854
|
+
children: [
|
|
7855
|
+
/* @__PURE__ */ jsxs(Box, { className: "flex-1 min-w-0", children: [
|
|
7856
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "items-center", children: [
|
|
7857
|
+
titleField?.icon && /* @__PURE__ */ jsx(
|
|
7858
|
+
Icon,
|
|
7859
|
+
{
|
|
7860
|
+
name: titleField.icon,
|
|
7861
|
+
size: isCompact ? "xs" : "sm",
|
|
7862
|
+
className: "text-[var(--color-primary)] flex-shrink-0"
|
|
7863
|
+
}
|
|
7864
|
+
),
|
|
7865
|
+
titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsx(
|
|
7866
|
+
Typography,
|
|
7867
|
+
{
|
|
7868
|
+
variant: titleField?.variant === "h3" ? "h3" : "h4",
|
|
7869
|
+
className: cn("font-semibold truncate flex-1", isCompact && "text-sm"),
|
|
7870
|
+
children: String(titleValue)
|
|
7871
|
+
}
|
|
7872
|
+
),
|
|
7873
|
+
badgeFields.map((field) => {
|
|
7874
|
+
const val = getNestedValue(itemData, field.name);
|
|
7875
|
+
if (val === void 0 || val === null) return null;
|
|
7876
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center flex-shrink-0", children: [
|
|
7877
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs" }),
|
|
7878
|
+
/* @__PURE__ */ jsx(Badge, { variant: statusVariant2(String(val)), children: String(val) })
|
|
7879
|
+
] }, field.name);
|
|
7880
|
+
})
|
|
7881
|
+
] }),
|
|
7882
|
+
bodyFields.length > 0 && !isCompact && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "mt-1.5 flex-wrap", children: bodyFields.map((field) => {
|
|
7883
|
+
const value = getNestedValue(itemData, field.name);
|
|
7884
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
7885
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
7886
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-[var(--color-muted-foreground)]" }),
|
|
7887
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "caption", color: "secondary", children: [
|
|
7888
|
+
field.label ?? fieldLabel2(field.name),
|
|
7889
|
+
":"
|
|
7890
|
+
] }),
|
|
7891
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", children: formatValue2(value, field.format) })
|
|
7892
|
+
] }, field.name);
|
|
7893
|
+
}) }),
|
|
7894
|
+
progressFields.map((field) => {
|
|
7895
|
+
const value = getNestedValue(itemData, field.name);
|
|
7896
|
+
if (typeof value !== "number") return null;
|
|
7897
|
+
return /* @__PURE__ */ jsxs(Box, { className: "mt-2 max-w-xs", children: [
|
|
7898
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center mb-1", children: [
|
|
7899
|
+
field.icon && /* @__PURE__ */ jsx(Icon, { name: field.icon, size: "xs", className: "text-[var(--color-muted-foreground)]" }),
|
|
7900
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: field.label ?? fieldLabel2(field.name) })
|
|
7901
|
+
] }),
|
|
7902
|
+
/* @__PURE__ */ jsx(ProgressBar, { value, max: 100 })
|
|
7903
|
+
] }, field.name);
|
|
7904
|
+
})
|
|
7905
|
+
] }),
|
|
7906
|
+
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(
|
|
7907
|
+
HStack,
|
|
7908
|
+
{
|
|
7909
|
+
gap: "xs",
|
|
7910
|
+
className: cn(
|
|
7911
|
+
"flex-shrink-0 transition-opacity duration-200",
|
|
7912
|
+
"opacity-0 group-hover:opacity-100"
|
|
7913
|
+
),
|
|
7914
|
+
children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
|
|
7915
|
+
Button,
|
|
7916
|
+
{
|
|
7917
|
+
variant: action.variant ?? "ghost",
|
|
7918
|
+
size: "sm",
|
|
7919
|
+
onClick: handleActionClick(action, itemData),
|
|
7920
|
+
"data-testid": `action-${action.event}`,
|
|
7921
|
+
className: cn(
|
|
7922
|
+
action.variant === "danger" && "text-[var(--color-error)] hover:bg-[var(--color-error)]/10"
|
|
7923
|
+
),
|
|
7924
|
+
children: [
|
|
7925
|
+
action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
7926
|
+
action.label
|
|
7927
|
+
]
|
|
7928
|
+
},
|
|
7929
|
+
idx
|
|
7930
|
+
))
|
|
7931
|
+
}
|
|
7932
|
+
)
|
|
7933
|
+
]
|
|
7934
|
+
}
|
|
7935
|
+
),
|
|
7936
|
+
isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-[var(--color-border)]/40" })
|
|
7937
|
+
] }, id);
|
|
7938
|
+
})
|
|
7939
|
+
}
|
|
7940
|
+
);
|
|
7941
|
+
};
|
|
7942
|
+
DataList.displayName = "DataList";
|
|
7943
|
+
|
|
7944
|
+
// components/organisms/types.ts
|
|
7945
|
+
var EntityDisplayEvents = {
|
|
7946
|
+
SORT: "SORT",
|
|
7947
|
+
PAGINATE: "PAGINATE",
|
|
7948
|
+
SEARCH: "SEARCH",
|
|
7949
|
+
FILTER: "FILTER",
|
|
7950
|
+
CLEAR_FILTERS: "CLEAR_FILTERS",
|
|
7951
|
+
SELECT: "SELECT",
|
|
6435
7952
|
DESELECT: "DESELECT"
|
|
6436
7953
|
};
|
|
7954
|
+
function humanizeFieldName(name) {
|
|
7955
|
+
return name.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).replace(/\b([A-Z])([A-Z]+)\b/g, (_, first, rest) => first + rest.toLowerCase()).trim();
|
|
7956
|
+
}
|
|
6437
7957
|
function normalizeColumns(columns) {
|
|
6438
7958
|
return columns.map((col) => {
|
|
6439
7959
|
if (typeof col === "string") {
|
|
6440
|
-
const
|
|
6441
|
-
return { key: col, header };
|
|
7960
|
+
const header2 = humanizeFieldName(col);
|
|
7961
|
+
return { key: col, header: header2 };
|
|
6442
7962
|
}
|
|
6443
|
-
|
|
7963
|
+
const key = col.key ?? col.name ?? "";
|
|
7964
|
+
const header = col.header ?? col.label ?? humanizeFieldName(String(key));
|
|
7965
|
+
return { ...col, key, header };
|
|
6444
7966
|
});
|
|
6445
7967
|
}
|
|
7968
|
+
function asBooleanValue(value) {
|
|
7969
|
+
if (typeof value === "boolean") return value;
|
|
7970
|
+
if (value === "true") return true;
|
|
7971
|
+
if (value === "false") return false;
|
|
7972
|
+
return null;
|
|
7973
|
+
}
|
|
6446
7974
|
function DataTable({
|
|
6447
7975
|
fields,
|
|
6448
7976
|
columns,
|
|
@@ -6739,7 +8267,13 @@ function DataTable({
|
|
|
6739
8267
|
{
|
|
6740
8268
|
"data-column": String(col.key),
|
|
6741
8269
|
className: "px-4 py-3 text-sm text-[var(--color-foreground)] whitespace-nowrap sm:whitespace-normal",
|
|
6742
|
-
children: col.render ? col.render(cellValue, row, rowIndex) :
|
|
8270
|
+
children: col.render ? col.render(cellValue, row, rowIndex) : (() => {
|
|
8271
|
+
const boolVal = asBooleanValue(cellValue);
|
|
8272
|
+
if (boolVal !== null) {
|
|
8273
|
+
return boolVal ? /* @__PURE__ */ jsx(Badge, { variant: "success", children: t("common.yes") }) : /* @__PURE__ */ jsx(Badge, { variant: "neutral", children: t("common.no") });
|
|
8274
|
+
}
|
|
8275
|
+
return String(cellValue ?? "");
|
|
8276
|
+
})()
|
|
6743
8277
|
},
|
|
6744
8278
|
String(col.key)
|
|
6745
8279
|
);
|
|
@@ -6825,7 +8359,7 @@ var StatCard = ({
|
|
|
6825
8359
|
trend: manualTrend,
|
|
6826
8360
|
trendDirection: manualDirection,
|
|
6827
8361
|
invertTrend = false,
|
|
6828
|
-
icon:
|
|
8362
|
+
icon: iconProp,
|
|
6829
8363
|
iconBg = "bg-[var(--color-muted)]",
|
|
6830
8364
|
iconColor = "text-[var(--color-foreground)]",
|
|
6831
8365
|
subtitle,
|
|
@@ -6837,10 +8371,11 @@ var StatCard = ({
|
|
|
6837
8371
|
isLoading: externalLoading,
|
|
6838
8372
|
error: externalError
|
|
6839
8373
|
}) => {
|
|
8374
|
+
const Icon2 = typeof iconProp === "string" ? resolveIcon(iconProp) ?? void 0 : iconProp;
|
|
6840
8375
|
const labelToUse = propLabel ?? propTitle;
|
|
6841
8376
|
const eventBus = useEventBus();
|
|
6842
8377
|
const { t } = useTranslate();
|
|
6843
|
-
const handleActionClick =
|
|
8378
|
+
const handleActionClick = React50__default.useCallback(() => {
|
|
6844
8379
|
if (action?.event) {
|
|
6845
8380
|
eventBus.emit(`UI:${action.event}`, {});
|
|
6846
8381
|
}
|
|
@@ -6851,7 +8386,7 @@ var StatCard = ({
|
|
|
6851
8386
|
const data = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
6852
8387
|
const isLoading = externalLoading ?? false;
|
|
6853
8388
|
const error = externalError;
|
|
6854
|
-
const computeMetricValue =
|
|
8389
|
+
const computeMetricValue = React50__default.useCallback(
|
|
6855
8390
|
(metric, items) => {
|
|
6856
8391
|
if (metric.value !== void 0) {
|
|
6857
8392
|
return metric.value;
|
|
@@ -6890,7 +8425,7 @@ var StatCard = ({
|
|
|
6890
8425
|
},
|
|
6891
8426
|
[]
|
|
6892
8427
|
);
|
|
6893
|
-
const schemaStats =
|
|
8428
|
+
const schemaStats = React50__default.useMemo(() => {
|
|
6894
8429
|
if (!metrics || metrics.length === 0) return null;
|
|
6895
8430
|
return metrics.map((metric) => ({
|
|
6896
8431
|
label: metric.label,
|
|
@@ -6898,7 +8433,7 @@ var StatCard = ({
|
|
|
6898
8433
|
format: metric.format
|
|
6899
8434
|
}));
|
|
6900
8435
|
}, [metrics, data, computeMetricValue]);
|
|
6901
|
-
const calculatedTrend =
|
|
8436
|
+
const calculatedTrend = React50__default.useMemo(() => {
|
|
6902
8437
|
if (manualTrend !== void 0) return manualTrend;
|
|
6903
8438
|
if (previousValue === void 0 || currentValue === void 0)
|
|
6904
8439
|
return void 0;
|
|
@@ -7034,7 +8569,7 @@ var PageHeader = ({
|
|
|
7034
8569
|
info: "bg-[var(--color-info)]/10 text-[var(--color-info)]"
|
|
7035
8570
|
};
|
|
7036
8571
|
return /* @__PURE__ */ jsxs(Box, { className: cn("mb-6", className), children: [
|
|
7037
|
-
breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(
|
|
8572
|
+
breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx(Box, { as: "nav", className: "mb-4", children: /* @__PURE__ */ jsx(Box, { as: "ol", className: "flex items-center gap-2 text-sm", children: breadcrumbs.map((crumb, idx) => /* @__PURE__ */ jsxs(React50__default.Fragment, { children: [
|
|
7038
8573
|
idx > 0 && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "muted", children: "/" }),
|
|
7039
8574
|
crumb.href ? /* @__PURE__ */ jsx(
|
|
7040
8575
|
"a",
|
|
@@ -7170,9 +8705,68 @@ function formatFieldValue(value, fieldName) {
|
|
|
7170
8705
|
}
|
|
7171
8706
|
return String(value);
|
|
7172
8707
|
}
|
|
8708
|
+
var ReactMarkdown2 = lazy(() => import('react-markdown'));
|
|
8709
|
+
function renderRichFieldValue(value, fieldName, fieldType) {
|
|
8710
|
+
if (value === void 0 || value === null) return "\u2014";
|
|
8711
|
+
const str = String(value);
|
|
8712
|
+
switch (fieldType) {
|
|
8713
|
+
case "image":
|
|
8714
|
+
case "url": {
|
|
8715
|
+
if (str.match(/\.(png|jpe?g|gif|svg|webp|avif)(\?|$)/i) || str.startsWith("data:image/")) {
|
|
8716
|
+
return /* @__PURE__ */ jsx(Box, { className: "mt-1 max-w-full", children: /* @__PURE__ */ jsx(
|
|
8717
|
+
"img",
|
|
8718
|
+
{
|
|
8719
|
+
src: str,
|
|
8720
|
+
alt: formatFieldLabel(fieldName),
|
|
8721
|
+
className: "max-w-full max-h-64 rounded-[var(--radius-md)] object-contain",
|
|
8722
|
+
loading: "lazy"
|
|
8723
|
+
}
|
|
8724
|
+
) });
|
|
8725
|
+
}
|
|
8726
|
+
return str;
|
|
8727
|
+
}
|
|
8728
|
+
case "markdown":
|
|
8729
|
+
case "richtext":
|
|
8730
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children: str }), children: /* @__PURE__ */ jsx(Box, { className: "prose prose-sm max-w-none dark:prose-invert", children: /* @__PURE__ */ jsx(ReactMarkdown2, { children: str }) }) });
|
|
8731
|
+
case "code":
|
|
8732
|
+
return /* @__PURE__ */ jsx(Box, { className: "mt-1 rounded-[var(--radius-md)] bg-[var(--color-muted)] p-3 overflow-x-auto", children: /* @__PURE__ */ jsx("pre", { className: "text-sm font-mono whitespace-pre-wrap break-words m-0", children: /* @__PURE__ */ jsx("code", { children: str }) }) });
|
|
8733
|
+
case "html":
|
|
8734
|
+
return /* @__PURE__ */ jsx(Box, { className: "mt-1 prose prose-sm max-w-none dark:prose-invert break-words", children: /* @__PURE__ */ jsx(Typography, { variant: "body", children: str }) });
|
|
8735
|
+
case "date":
|
|
8736
|
+
case "datetime": {
|
|
8737
|
+
const d = new Date(str);
|
|
8738
|
+
if (!isNaN(d.getTime())) {
|
|
8739
|
+
return d.toLocaleDateString(void 0, {
|
|
8740
|
+
year: "numeric",
|
|
8741
|
+
month: "long",
|
|
8742
|
+
day: "numeric",
|
|
8743
|
+
...fieldType === "datetime" ? { hour: "2-digit", minute: "2-digit" } : {}
|
|
8744
|
+
});
|
|
8745
|
+
}
|
|
8746
|
+
return str;
|
|
8747
|
+
}
|
|
8748
|
+
default:
|
|
8749
|
+
return formatFieldValue(value, fieldName);
|
|
8750
|
+
}
|
|
8751
|
+
}
|
|
7173
8752
|
function normalizeFieldDefs(fields) {
|
|
7174
8753
|
if (!fields) return [];
|
|
7175
|
-
return fields.map((f) =>
|
|
8754
|
+
return fields.map((f) => {
|
|
8755
|
+
if (typeof f === "string") return f;
|
|
8756
|
+
if ("key" in f) return f.key;
|
|
8757
|
+
if ("name" in f) return f.name;
|
|
8758
|
+
return String(f);
|
|
8759
|
+
});
|
|
8760
|
+
}
|
|
8761
|
+
function buildFieldTypeMap(fields) {
|
|
8762
|
+
const map = {};
|
|
8763
|
+
if (!fields) return map;
|
|
8764
|
+
for (const f of fields) {
|
|
8765
|
+
if (typeof f === "object" && "name" in f && "type" in f) {
|
|
8766
|
+
map[f.name] = f.type;
|
|
8767
|
+
}
|
|
8768
|
+
}
|
|
8769
|
+
return map;
|
|
7176
8770
|
}
|
|
7177
8771
|
var DetailPanel = ({
|
|
7178
8772
|
title: propTitle,
|
|
@@ -7196,9 +8790,10 @@ var DetailPanel = ({
|
|
|
7196
8790
|
const isFieldDefArray = (arr) => {
|
|
7197
8791
|
if (!arr || arr.length === 0) return false;
|
|
7198
8792
|
const first = arr[0];
|
|
7199
|
-
return typeof first === "string" || typeof first === "object" && first !== null && "key" in first;
|
|
8793
|
+
return typeof first === "string" || typeof first === "object" && first !== null && ("key" in first || "name" in first);
|
|
7200
8794
|
};
|
|
7201
8795
|
const effectiveFieldNames = isFieldDefArray(propFields) ? normalizeFieldDefs(propFields) : fieldNames;
|
|
8796
|
+
const fieldTypeMap = isFieldDefArray(propFields) ? buildFieldTypeMap(propFields) : {};
|
|
7202
8797
|
useCallback(
|
|
7203
8798
|
(action, data2) => {
|
|
7204
8799
|
if (action.navigatesTo) {
|
|
@@ -7273,7 +8868,7 @@ var DetailPanel = ({
|
|
|
7273
8868
|
if (value !== void 0 && value !== null) {
|
|
7274
8869
|
overviewFields.push({
|
|
7275
8870
|
label: formatFieldLabel(field),
|
|
7276
|
-
value:
|
|
8871
|
+
value: renderRichFieldValue(value, field, fieldTypeMap[field]),
|
|
7277
8872
|
icon: getFieldIcon(field)
|
|
7278
8873
|
});
|
|
7279
8874
|
}
|
|
@@ -7289,7 +8884,7 @@ var DetailPanel = ({
|
|
|
7289
8884
|
if (value !== void 0 && value !== null) {
|
|
7290
8885
|
metricsFields.push({
|
|
7291
8886
|
label: formatFieldLabel(field),
|
|
7292
|
-
value:
|
|
8887
|
+
value: renderRichFieldValue(value, field, fieldTypeMap[field]),
|
|
7293
8888
|
icon: getFieldIcon(field)
|
|
7294
8889
|
});
|
|
7295
8890
|
}
|
|
@@ -7305,7 +8900,7 @@ var DetailPanel = ({
|
|
|
7305
8900
|
if (value !== void 0 && value !== null) {
|
|
7306
8901
|
timelineFields.push({
|
|
7307
8902
|
label: formatFieldLabel(field),
|
|
7308
|
-
value:
|
|
8903
|
+
value: renderRichFieldValue(value, field, fieldTypeMap[field]),
|
|
7309
8904
|
icon: getFieldIcon(field)
|
|
7310
8905
|
});
|
|
7311
8906
|
}
|
|
@@ -7321,7 +8916,7 @@ var DetailPanel = ({
|
|
|
7321
8916
|
if (value !== void 0 && value !== null) {
|
|
7322
8917
|
descFields.push({
|
|
7323
8918
|
label: formatFieldLabel(field),
|
|
7324
|
-
value:
|
|
8919
|
+
value: renderRichFieldValue(value, field, fieldTypeMap[field]),
|
|
7325
8920
|
icon: getFieldIcon(field)
|
|
7326
8921
|
});
|
|
7327
8922
|
}
|
|
@@ -7361,96 +8956,123 @@ var DetailPanel = ({
|
|
|
7361
8956
|
}
|
|
7362
8957
|
);
|
|
7363
8958
|
}
|
|
7364
|
-
const
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
8959
|
+
const allFields = [];
|
|
8960
|
+
if (sections) {
|
|
8961
|
+
for (const section of sections) {
|
|
8962
|
+
for (const field of section.fields) {
|
|
8963
|
+
if (typeof field === "string") {
|
|
8964
|
+
const value = normalizedData ? getNestedValue(normalizedData, field) : void 0;
|
|
8965
|
+
allFields.push({
|
|
8966
|
+
label: formatFieldLabel(field),
|
|
8967
|
+
value: renderRichFieldValue(value, field, fieldTypeMap[field]),
|
|
8968
|
+
icon: getFieldIcon(field)
|
|
8969
|
+
});
|
|
8970
|
+
} else {
|
|
8971
|
+
allFields.push(field);
|
|
8972
|
+
}
|
|
8973
|
+
}
|
|
8974
|
+
}
|
|
8975
|
+
}
|
|
8976
|
+
const closeAction = actions?.find(
|
|
8977
|
+
(a) => a.event === "CLOSE" || a.event === "CANCEL" || a.label?.toLowerCase() === "close"
|
|
8978
|
+
);
|
|
8979
|
+
const otherActions = actions?.filter((a) => a !== closeAction) ?? [];
|
|
8980
|
+
const effectiveCloseAction = closeAction ?? { event: void 0};
|
|
8981
|
+
const content = /* @__PURE__ */ jsx(Card, { variant: "elevated", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", className: "p-6", children: [
|
|
8982
|
+
/* @__PURE__ */ jsxs(HStack, { justify: "end", align: "center", gap: "xs", children: [
|
|
8983
|
+
otherActions.map((action, idx) => /* @__PURE__ */ jsx(
|
|
8984
|
+
Button,
|
|
8985
|
+
{
|
|
8986
|
+
variant: action.variant || "secondary",
|
|
8987
|
+
size: "sm",
|
|
8988
|
+
action: action.event,
|
|
8989
|
+
actionPayload: { row: normalizedData },
|
|
8990
|
+
icon: action.icon,
|
|
8991
|
+
"data-testid": action.event ? `action-${action.event}` : void 0,
|
|
8992
|
+
children: action.label
|
|
8993
|
+
},
|
|
8994
|
+
idx
|
|
8995
|
+
)),
|
|
8996
|
+
/* @__PURE__ */ jsx(
|
|
8997
|
+
Button,
|
|
8998
|
+
{
|
|
8999
|
+
variant: "ghost",
|
|
9000
|
+
size: "sm",
|
|
9001
|
+
action: effectiveCloseAction.event,
|
|
9002
|
+
actionPayload: { row: normalizedData },
|
|
9003
|
+
onClick: effectiveCloseAction.event ? void 0 : handleClose,
|
|
9004
|
+
icon: X,
|
|
9005
|
+
"data-testid": effectiveCloseAction.event ? `action-${effectiveCloseAction.event}` : "action-close"
|
|
9006
|
+
}
|
|
9007
|
+
)
|
|
9008
|
+
] }),
|
|
9009
|
+
avatar,
|
|
9010
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" }),
|
|
9011
|
+
subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: subtitle }),
|
|
9012
|
+
/* @__PURE__ */ jsxs(HStack, { gap: "xs", wrap: true, children: [
|
|
7389
9013
|
normalizedData && effectiveFieldNames && effectiveFieldNames.filter(
|
|
7390
|
-
(f) => f.toLowerCase().includes("
|
|
9014
|
+
(f) => f.toLowerCase().includes("status") || f.toLowerCase().includes("priority")
|
|
7391
9015
|
).map((field) => {
|
|
7392
9016
|
const value = getNestedValue(normalizedData, field);
|
|
7393
|
-
if (value
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
/* @__PURE__ */ jsxs(HStack, { justify: "between", children: [
|
|
7397
|
-
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatFieldLabel(field) }),
|
|
7398
|
-
/* @__PURE__ */ jsxs(Typography, { variant: "small", weight: "medium", children: [
|
|
7399
|
-
value,
|
|
7400
|
-
"%"
|
|
7401
|
-
] })
|
|
7402
|
-
] }),
|
|
7403
|
-
/* @__PURE__ */ jsx(ProgressBar, { value })
|
|
7404
|
-
] }, field);
|
|
7405
|
-
}),
|
|
7406
|
-
actions && actions.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7407
|
-
/* @__PURE__ */ jsx(Divider, {}),
|
|
7408
|
-
/* @__PURE__ */ jsx(HStack, { gap: "sm", children: actions.map((action, idx) => /* @__PURE__ */ jsx(
|
|
7409
|
-
Button,
|
|
9017
|
+
if (!value) return null;
|
|
9018
|
+
return /* @__PURE__ */ jsx(
|
|
9019
|
+
Badge,
|
|
7410
9020
|
{
|
|
7411
|
-
variant:
|
|
7412
|
-
|
|
7413
|
-
actionPayload: { row: normalizedData },
|
|
7414
|
-
icon: action.icon,
|
|
7415
|
-
"data-testid": action.event ? `action-${action.event}` : void 0,
|
|
7416
|
-
children: action.label
|
|
9021
|
+
variant: getBadgeVariant(field, String(value)),
|
|
9022
|
+
children: String(value)
|
|
7417
9023
|
},
|
|
7418
|
-
|
|
7419
|
-
)
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
9024
|
+
field
|
|
9025
|
+
);
|
|
9026
|
+
}),
|
|
9027
|
+
status && /* @__PURE__ */ jsx(Badge, { variant: status.variant ?? "default", children: status.label })
|
|
9028
|
+
] }),
|
|
9029
|
+
normalizedData && effectiveFieldNames && effectiveFieldNames.filter(
|
|
9030
|
+
(f) => f.toLowerCase().includes("progress") || f.toLowerCase().includes("percent")
|
|
9031
|
+
).map((field) => {
|
|
9032
|
+
const value = getNestedValue(normalizedData, field);
|
|
9033
|
+
if (value === void 0 || value === null || typeof value !== "number")
|
|
9034
|
+
return null;
|
|
9035
|
+
return /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "w-full", children: [
|
|
9036
|
+
/* @__PURE__ */ jsxs(HStack, { justify: "between", children: [
|
|
9037
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatFieldLabel(field) }),
|
|
9038
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "small", weight: "medium", children: [
|
|
9039
|
+
value,
|
|
9040
|
+
"%"
|
|
9041
|
+
] })
|
|
9042
|
+
] }),
|
|
9043
|
+
/* @__PURE__ */ jsx(ProgressBar, { value })
|
|
9044
|
+
] }, field);
|
|
9045
|
+
}),
|
|
9046
|
+
allFields.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7424
9047
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
7425
|
-
/* @__PURE__ */ jsx(SimpleGrid, { minChildWidth: "250px", maxCols: 2, gap: "lg", children:
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
9048
|
+
/* @__PURE__ */ jsx(SimpleGrid, { minChildWidth: "250px", maxCols: 2, gap: "lg", children: allFields.map((field, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "sm", align: "start", children: [
|
|
9049
|
+
field.icon && /* @__PURE__ */ jsx(
|
|
9050
|
+
Icon,
|
|
9051
|
+
{
|
|
9052
|
+
icon: field.icon,
|
|
9053
|
+
size: "md",
|
|
9054
|
+
className: "text-[var(--color-muted-foreground)] mt-1"
|
|
9055
|
+
}
|
|
9056
|
+
),
|
|
9057
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "xs", flex: true, className: "min-w-0", children: [
|
|
9058
|
+
/* @__PURE__ */ jsx(
|
|
9059
|
+
Typography,
|
|
7431
9060
|
{
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
9061
|
+
variant: "small",
|
|
9062
|
+
color: "secondary",
|
|
9063
|
+
weight: "medium",
|
|
9064
|
+
children: field.label
|
|
7435
9065
|
}
|
|
7436
9066
|
),
|
|
7437
|
-
/* @__PURE__ */
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
),
|
|
7447
|
-
/* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children: resolved.value || "\u2014" })
|
|
7448
|
-
] })
|
|
7449
|
-
] }, fieldIdx);
|
|
7450
|
-
}) })
|
|
7451
|
-
] }) }, sectionIdx)),
|
|
7452
|
-
footer && /* @__PURE__ */ jsx(Card, { variant: "bordered", children: footer })
|
|
7453
|
-
] });
|
|
9067
|
+
/* @__PURE__ */ jsx(Typography, { variant: "body", className: "break-words", children: field.value || "\u2014" })
|
|
9068
|
+
] })
|
|
9069
|
+
] }, idx)) })
|
|
9070
|
+
] }),
|
|
9071
|
+
footer && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9072
|
+
/* @__PURE__ */ jsx(Divider, {}),
|
|
9073
|
+
footer
|
|
9074
|
+
] })
|
|
9075
|
+
] }) });
|
|
7454
9076
|
return /* @__PURE__ */ jsx(
|
|
7455
9077
|
Box,
|
|
7456
9078
|
{
|
|
@@ -7484,7 +9106,7 @@ var layoutStyles = {
|
|
|
7484
9106
|
horizontal: "flex flex-row flex-wrap items-end",
|
|
7485
9107
|
inline: "flex flex-row flex-wrap items-center"
|
|
7486
9108
|
};
|
|
7487
|
-
var
|
|
9109
|
+
var gapStyles6 = {
|
|
7488
9110
|
sm: "gap-2",
|
|
7489
9111
|
md: "gap-4",
|
|
7490
9112
|
lg: "gap-6"
|
|
@@ -7580,7 +9202,7 @@ var Form = ({
|
|
|
7580
9202
|
const normalizedInitialData = initialData ?? {};
|
|
7581
9203
|
const resolvedEntity = entity && typeof entity === "object" && !Array.isArray(entity) ? entity : void 0;
|
|
7582
9204
|
const entityName = typeof entity === "string" ? entity : resolvedEntity?.name;
|
|
7583
|
-
const entityDerivedFields =
|
|
9205
|
+
const entityDerivedFields = React50__default.useMemo(() => {
|
|
7584
9206
|
if (fields && fields.length > 0) return void 0;
|
|
7585
9207
|
if (!resolvedEntity) return void 0;
|
|
7586
9208
|
return resolvedEntity.fields.map(
|
|
@@ -7599,14 +9221,14 @@ var Form = ({
|
|
|
7599
9221
|
const conditionalFields = typeof conditionalFieldsRaw === "boolean" ? {} : conditionalFieldsRaw;
|
|
7600
9222
|
const hiddenCalculations = typeof hiddenCalculationsRaw === "boolean" ? [] : hiddenCalculationsRaw;
|
|
7601
9223
|
const violationTriggers = typeof violationTriggersRaw === "boolean" ? [] : violationTriggersRaw;
|
|
7602
|
-
const [formData, setFormData] =
|
|
9224
|
+
const [formData, setFormData] = React50__default.useState(
|
|
7603
9225
|
normalizedInitialData
|
|
7604
9226
|
);
|
|
7605
|
-
const [collapsedSections, setCollapsedSections] =
|
|
9227
|
+
const [collapsedSections, setCollapsedSections] = React50__default.useState(
|
|
7606
9228
|
/* @__PURE__ */ new Set()
|
|
7607
9229
|
);
|
|
7608
9230
|
const shouldShowCancel = showCancel ?? (fields && fields.length > 0);
|
|
7609
|
-
const evalContext =
|
|
9231
|
+
const evalContext = React50__default.useMemo(
|
|
7610
9232
|
() => ({
|
|
7611
9233
|
formValues: formData,
|
|
7612
9234
|
globalVariables: externalContext?.globalVariables ?? {},
|
|
@@ -7615,13 +9237,13 @@ var Form = ({
|
|
|
7615
9237
|
}),
|
|
7616
9238
|
[formData, externalContext]
|
|
7617
9239
|
);
|
|
7618
|
-
|
|
9240
|
+
React50__default.useEffect(() => {
|
|
7619
9241
|
const data = initialData;
|
|
7620
9242
|
if (data && Object.keys(data).length > 0) {
|
|
7621
9243
|
setFormData(data);
|
|
7622
9244
|
}
|
|
7623
9245
|
}, [initialData]);
|
|
7624
|
-
const processCalculations =
|
|
9246
|
+
const processCalculations = React50__default.useCallback(
|
|
7625
9247
|
(changedFieldId, newFormData) => {
|
|
7626
9248
|
if (!hiddenCalculations.length) return;
|
|
7627
9249
|
const context = {
|
|
@@ -7646,7 +9268,7 @@ var Form = ({
|
|
|
7646
9268
|
},
|
|
7647
9269
|
[hiddenCalculations, externalContext, eventBus]
|
|
7648
9270
|
);
|
|
7649
|
-
const checkViolations =
|
|
9271
|
+
const checkViolations = React50__default.useCallback(
|
|
7650
9272
|
(changedFieldId, newFormData) => {
|
|
7651
9273
|
if (!violationTriggers.length) return;
|
|
7652
9274
|
const context = {
|
|
@@ -7683,7 +9305,7 @@ var Form = ({
|
|
|
7683
9305
|
processCalculations(name, newFormData);
|
|
7684
9306
|
checkViolations(name, newFormData);
|
|
7685
9307
|
};
|
|
7686
|
-
const isFieldVisible =
|
|
9308
|
+
const isFieldVisible = React50__default.useCallback(
|
|
7687
9309
|
(fieldName) => {
|
|
7688
9310
|
const condition = conditionalFields[fieldName];
|
|
7689
9311
|
if (!condition) return true;
|
|
@@ -7691,7 +9313,7 @@ var Form = ({
|
|
|
7691
9313
|
},
|
|
7692
9314
|
[conditionalFields, evalContext]
|
|
7693
9315
|
);
|
|
7694
|
-
const isSectionVisible =
|
|
9316
|
+
const isSectionVisible = React50__default.useCallback(
|
|
7695
9317
|
(section) => {
|
|
7696
9318
|
if (!section.condition) return true;
|
|
7697
9319
|
return Boolean(evaluateFormExpression(section.condition, evalContext));
|
|
@@ -7723,7 +9345,7 @@ var Form = ({
|
|
|
7723
9345
|
eventBus.emit(`UI:${onCancel}`);
|
|
7724
9346
|
}
|
|
7725
9347
|
};
|
|
7726
|
-
const renderField =
|
|
9348
|
+
const renderField = React50__default.useCallback(
|
|
7727
9349
|
(field) => {
|
|
7728
9350
|
const fieldName = field.name || field.field;
|
|
7729
9351
|
if (!fieldName) return null;
|
|
@@ -7744,7 +9366,7 @@ var Form = ({
|
|
|
7744
9366
|
[formData, isFieldVisible, relationsData, relationsLoading, isLoading]
|
|
7745
9367
|
);
|
|
7746
9368
|
const effectiveFields = entityDerivedFields ?? fields;
|
|
7747
|
-
const normalizedFields =
|
|
9369
|
+
const normalizedFields = React50__default.useMemo(() => {
|
|
7748
9370
|
if (!effectiveFields || effectiveFields.length === 0) return [];
|
|
7749
9371
|
return effectiveFields.map((field) => {
|
|
7750
9372
|
if (typeof field === "string") {
|
|
@@ -7753,7 +9375,7 @@ var Form = ({
|
|
|
7753
9375
|
return field;
|
|
7754
9376
|
});
|
|
7755
9377
|
}, [effectiveFields]);
|
|
7756
|
-
const schemaFields =
|
|
9378
|
+
const schemaFields = React50__default.useMemo(() => {
|
|
7757
9379
|
if (normalizedFields.length === 0) return null;
|
|
7758
9380
|
if (isDebugEnabled()) {
|
|
7759
9381
|
debugGroup(`Form: ${entityName || "unknown"}`);
|
|
@@ -7763,7 +9385,7 @@ var Form = ({
|
|
|
7763
9385
|
}
|
|
7764
9386
|
return normalizedFields.map(renderField).filter(Boolean);
|
|
7765
9387
|
}, [normalizedFields, renderField, entityName, conditionalFields]);
|
|
7766
|
-
const sectionElements =
|
|
9388
|
+
const sectionElements = React50__default.useMemo(() => {
|
|
7767
9389
|
if (!sections || sections.length === 0) return null;
|
|
7768
9390
|
return sections.map((section) => {
|
|
7769
9391
|
if (!isSectionVisible(section)) {
|
|
@@ -7943,7 +9565,7 @@ var Form = ({
|
|
|
7943
9565
|
return /* @__PURE__ */ jsxs(
|
|
7944
9566
|
"form",
|
|
7945
9567
|
{
|
|
7946
|
-
className: cn(layoutStyles[layout],
|
|
9568
|
+
className: cn(layoutStyles[layout], gapStyles6[gap], className),
|
|
7947
9569
|
onSubmit: handleSubmit,
|
|
7948
9570
|
...props,
|
|
7949
9571
|
children: [
|
|
@@ -8011,9 +9633,37 @@ function formatDateTimeValue(value) {
|
|
|
8011
9633
|
Form.displayName = "Form";
|
|
8012
9634
|
function normalizeFields(fields) {
|
|
8013
9635
|
if (!fields) return [];
|
|
8014
|
-
return fields.map((f) => typeof f === "string" ? f : f.key);
|
|
9636
|
+
return fields.map((f) => typeof f === "string" ? f : f.key ?? f.name ?? "");
|
|
8015
9637
|
}
|
|
8016
|
-
|
|
9638
|
+
function fieldLabel3(key) {
|
|
9639
|
+
return key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
9640
|
+
}
|
|
9641
|
+
function asBooleanValue2(value) {
|
|
9642
|
+
if (typeof value === "boolean") return value;
|
|
9643
|
+
if (value === "true") return true;
|
|
9644
|
+
if (value === "false") return false;
|
|
9645
|
+
return null;
|
|
9646
|
+
}
|
|
9647
|
+
var STATUS_FIELDS = /* @__PURE__ */ new Set(["status", "state", "priority", "type", "category", "role", "level", "tier"]);
|
|
9648
|
+
function isDateField(key) {
|
|
9649
|
+
const lower = key.toLowerCase();
|
|
9650
|
+
return lower.includes("date") || lower.includes("time") || lower.endsWith("at") || lower.endsWith("_at");
|
|
9651
|
+
}
|
|
9652
|
+
function formatDate3(value) {
|
|
9653
|
+
if (!value) return "";
|
|
9654
|
+
const d = new Date(String(value));
|
|
9655
|
+
if (isNaN(d.getTime())) return String(value);
|
|
9656
|
+
return d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
9657
|
+
}
|
|
9658
|
+
function statusVariant3(value) {
|
|
9659
|
+
const v = value.toLowerCase();
|
|
9660
|
+
if (["active", "completed", "done", "approved", "published", "resolved", "open"].includes(v)) return "success";
|
|
9661
|
+
if (["pending", "in_progress", "in-progress", "review", "draft", "processing"].includes(v)) return "warning";
|
|
9662
|
+
if (["inactive", "deleted", "rejected", "failed", "error", "blocked", "closed"].includes(v)) return "error";
|
|
9663
|
+
if (["new", "created", "scheduled", "queued"].includes(v)) return "info";
|
|
9664
|
+
return "default";
|
|
9665
|
+
}
|
|
9666
|
+
var gapStyles7 = {
|
|
8017
9667
|
none: "gap-0",
|
|
8018
9668
|
sm: "gap-2",
|
|
8019
9669
|
md: "gap-4",
|
|
@@ -8045,7 +9695,8 @@ var CardGrid = ({
|
|
|
8045
9695
|
fieldNames,
|
|
8046
9696
|
columns,
|
|
8047
9697
|
itemActions,
|
|
8048
|
-
showTotal = true
|
|
9698
|
+
showTotal = true,
|
|
9699
|
+
imageField
|
|
8049
9700
|
}) => {
|
|
8050
9701
|
const eventBus = useEventBus();
|
|
8051
9702
|
const { t } = useTranslate();
|
|
@@ -8057,6 +9708,28 @@ var CardGrid = ({
|
|
|
8057
9708
|
const handlePageChange = (newPage) => {
|
|
8058
9709
|
eventBus.emit("UI:PAGINATE", { page: newPage, pageSize });
|
|
8059
9710
|
};
|
|
9711
|
+
const titleField = effectiveFieldNames?.[0];
|
|
9712
|
+
const statusField = effectiveFieldNames?.find((f) => STATUS_FIELDS.has(f.toLowerCase()));
|
|
9713
|
+
const bodyFields = effectiveFieldNames?.filter((f) => f !== titleField && f !== statusField) ?? [];
|
|
9714
|
+
const primaryActions = itemActions?.filter((a) => a.variant !== "danger") ?? [];
|
|
9715
|
+
const dangerActions = itemActions?.filter((a) => a.variant === "danger") ?? [];
|
|
9716
|
+
const handleActionClick = (action, itemData) => (e) => {
|
|
9717
|
+
e.stopPropagation();
|
|
9718
|
+
if (action.navigatesTo) {
|
|
9719
|
+
const url = action.navigatesTo.replace(/\{\{row\.(\w+(?:\.\w+)*)\}\}/g, (_, field) => {
|
|
9720
|
+
const value = getNestedValue(itemData, field);
|
|
9721
|
+
return value !== void 0 && value !== null ? String(value) : "";
|
|
9722
|
+
});
|
|
9723
|
+
eventBus.emit("UI:NAVIGATE", { url, row: itemData });
|
|
9724
|
+
return;
|
|
9725
|
+
}
|
|
9726
|
+
if (action.event) {
|
|
9727
|
+
eventBus.emit(`UI:${action.event}`, { row: itemData });
|
|
9728
|
+
}
|
|
9729
|
+
if (action.onClick) {
|
|
9730
|
+
action.onClick(itemData);
|
|
9731
|
+
}
|
|
9732
|
+
};
|
|
8060
9733
|
const renderContent = () => {
|
|
8061
9734
|
if (children) {
|
|
8062
9735
|
return children;
|
|
@@ -8071,62 +9744,85 @@ var CardGrid = ({
|
|
|
8071
9744
|
] }) });
|
|
8072
9745
|
}
|
|
8073
9746
|
if (normalizedData.length === 0) {
|
|
8074
|
-
return /* @__PURE__ */ jsx(Box, { className: "col-span-full text-center py-
|
|
9747
|
+
return /* @__PURE__ */ jsx(Box, { className: "col-span-full text-center py-12 text-[var(--color-muted-foreground)]", children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: t("empty.noItems") || "No items found" }) });
|
|
8075
9748
|
}
|
|
8076
9749
|
return normalizedData.map((item, index) => {
|
|
8077
9750
|
const itemData = item;
|
|
8078
9751
|
const id = itemData.id || String(index);
|
|
8079
|
-
const
|
|
8080
|
-
const
|
|
8081
|
-
e.stopPropagation();
|
|
8082
|
-
if (action.navigatesTo) {
|
|
8083
|
-
const url = action.navigatesTo.replace(/\{\{row\.(\w+(?:\.\w+)*)\}\}/g, (_, field) => {
|
|
8084
|
-
const value = getNestedValue(itemData, field);
|
|
8085
|
-
return value !== void 0 && value !== null ? String(value) : "";
|
|
8086
|
-
});
|
|
8087
|
-
eventBus.emit("UI:NAVIGATE", { url, row: itemData });
|
|
8088
|
-
return;
|
|
8089
|
-
}
|
|
8090
|
-
if (action.event) {
|
|
8091
|
-
eventBus.emit(`UI:${action.event}`, { row: itemData });
|
|
8092
|
-
}
|
|
8093
|
-
if (action.onClick) {
|
|
8094
|
-
action.onClick(itemData);
|
|
8095
|
-
}
|
|
8096
|
-
};
|
|
9752
|
+
const titleValue = titleField ? getNestedValue(itemData, titleField) : void 0;
|
|
9753
|
+
const statusValue = statusField ? getNestedValue(itemData, statusField) : void 0;
|
|
8097
9754
|
return /* @__PURE__ */ jsxs(
|
|
8098
9755
|
Box,
|
|
8099
9756
|
{
|
|
8100
9757
|
"data-entity-row": true,
|
|
8101
9758
|
className: cn(
|
|
8102
|
-
"bg-[var(--color-card)] rounded-[var(--radius-lg)] border border-[var(--color-border)]
|
|
8103
|
-
"
|
|
9759
|
+
"bg-[var(--color-card)] rounded-[var(--radius-lg)] border border-[var(--color-border)]",
|
|
9760
|
+
"shadow-[var(--shadow-sm)] hover:shadow-[var(--shadow-hover)]",
|
|
9761
|
+
"cursor-pointer hover:border-[var(--color-primary)] transition-all",
|
|
9762
|
+
"flex flex-col"
|
|
8104
9763
|
),
|
|
8105
9764
|
action: "VIEW",
|
|
8106
9765
|
actionPayload: { row: itemData },
|
|
8107
9766
|
children: [
|
|
8108
|
-
|
|
8109
|
-
const
|
|
8110
|
-
if (
|
|
8111
|
-
return /* @__PURE__ */
|
|
8112
|
-
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
9767
|
+
imageField && (() => {
|
|
9768
|
+
const imgUrl = getNestedValue(itemData, imageField);
|
|
9769
|
+
if (!imgUrl || typeof imgUrl !== "string") return null;
|
|
9770
|
+
return /* @__PURE__ */ jsx(Box, { className: "w-full aspect-video overflow-hidden rounded-t-[var(--radius-lg)]", children: /* @__PURE__ */ jsx(
|
|
9771
|
+
"img",
|
|
9772
|
+
{
|
|
9773
|
+
src: imgUrl,
|
|
9774
|
+
alt: titleValue !== void 0 ? String(titleValue) : "",
|
|
9775
|
+
className: "w-full h-full object-cover",
|
|
9776
|
+
loading: "lazy"
|
|
9777
|
+
}
|
|
9778
|
+
) });
|
|
9779
|
+
})(),
|
|
9780
|
+
/* @__PURE__ */ jsx(Box, { className: "p-4 pb-0", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between items-start", children: [
|
|
9781
|
+
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "flex-1 min-w-0", children: [
|
|
9782
|
+
titleValue !== void 0 && titleValue !== null && /* @__PURE__ */ jsx(Typography, { variant: "h4", className: "font-semibold truncate", children: String(titleValue) }),
|
|
9783
|
+
statusValue !== void 0 && statusValue !== null && /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Badge, { variant: statusVariant3(String(statusValue)), children: String(statusValue) }) })
|
|
9784
|
+
] }),
|
|
9785
|
+
dangerActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: dangerActions.map((action, actionIdx) => /* @__PURE__ */ jsx(
|
|
8119
9786
|
Button,
|
|
8120
9787
|
{
|
|
8121
|
-
variant:
|
|
9788
|
+
variant: "ghost",
|
|
8122
9789
|
size: "sm",
|
|
8123
|
-
onClick: handleActionClick(action),
|
|
9790
|
+
onClick: handleActionClick(action, itemData),
|
|
8124
9791
|
"data-testid": action.event ? `action-${action.event}` : void 0,
|
|
9792
|
+
className: "text-[var(--color-error)] hover:bg-[var(--color-error)]/10 px-2",
|
|
8125
9793
|
children: action.label
|
|
8126
9794
|
},
|
|
8127
9795
|
actionIdx
|
|
8128
|
-
)
|
|
8129
|
-
}) })
|
|
9796
|
+
)) })
|
|
9797
|
+
] }) }),
|
|
9798
|
+
bodyFields.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 flex-1", children: /* @__PURE__ */ jsx(VStack, { gap: "xs", children: bodyFields.map((field) => {
|
|
9799
|
+
const value = getNestedValue(itemData, field);
|
|
9800
|
+
if (value === void 0 || value === null || value === "") return null;
|
|
9801
|
+
const boolVal = asBooleanValue2(value);
|
|
9802
|
+
if (boolVal !== null) {
|
|
9803
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between", children: [
|
|
9804
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: fieldLabel3(field) }),
|
|
9805
|
+
boolVal ? /* @__PURE__ */ jsx(Badge, { variant: "success", children: t("common.yes") || "Yes" }) : /* @__PURE__ */ jsx(Badge, { variant: "neutral", children: t("common.no") || "No" })
|
|
9806
|
+
] }, field);
|
|
9807
|
+
}
|
|
9808
|
+
const displayValue = isDateField(field) ? formatDate3(value) : STATUS_FIELDS.has(field.toLowerCase()) ? void 0 : String(value);
|
|
9809
|
+
if (!displayValue) return null;
|
|
9810
|
+
return /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-between", children: [
|
|
9811
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: fieldLabel3(field) }),
|
|
9812
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-right truncate max-w-[60%]", children: displayValue })
|
|
9813
|
+
] }, field);
|
|
9814
|
+
}) }) }),
|
|
9815
|
+
primaryActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 mt-auto border-t border-[var(--color-border)]", children: /* @__PURE__ */ jsx(HStack, { gap: "sm", className: "justify-end", children: primaryActions.map((action, actionIdx) => /* @__PURE__ */ jsx(
|
|
9816
|
+
Button,
|
|
9817
|
+
{
|
|
9818
|
+
variant: action.variant === "primary" ? "primary" : "ghost",
|
|
9819
|
+
size: "sm",
|
|
9820
|
+
onClick: handleActionClick(action, itemData),
|
|
9821
|
+
"data-testid": action.event ? `action-${action.event}` : void 0,
|
|
9822
|
+
children: action.label
|
|
9823
|
+
},
|
|
9824
|
+
actionIdx
|
|
9825
|
+
)) }) })
|
|
8130
9826
|
]
|
|
8131
9827
|
},
|
|
8132
9828
|
id
|
|
@@ -8139,7 +9835,7 @@ var CardGrid = ({
|
|
|
8139
9835
|
{
|
|
8140
9836
|
className: cn(
|
|
8141
9837
|
"grid",
|
|
8142
|
-
|
|
9838
|
+
gapStyles7[gap],
|
|
8143
9839
|
alignStyles4[alignItems],
|
|
8144
9840
|
maxCols === 1 && "grid-cols-1",
|
|
8145
9841
|
maxCols === 2 && "sm:grid-cols-2",
|
|
@@ -8168,7 +9864,7 @@ var CardGrid = ({
|
|
|
8168
9864
|
CardGrid.displayName = "CardGrid";
|
|
8169
9865
|
function MasterDetail({
|
|
8170
9866
|
entity,
|
|
8171
|
-
masterFields
|
|
9867
|
+
masterFields,
|
|
8172
9868
|
detailFields: _detailFields,
|
|
8173
9869
|
// Captured but not used here - detail handled separately
|
|
8174
9870
|
loading: externalLoading,
|
|
@@ -8183,6 +9879,7 @@ function MasterDetail({
|
|
|
8183
9879
|
return /* @__PURE__ */ jsx(
|
|
8184
9880
|
DataTable,
|
|
8185
9881
|
{
|
|
9882
|
+
fields: masterFields,
|
|
8186
9883
|
columns: masterFields,
|
|
8187
9884
|
entity,
|
|
8188
9885
|
isLoading: loading || isLoading,
|
|
@@ -8254,7 +9951,7 @@ function GridPattern({
|
|
|
8254
9951
|
style,
|
|
8255
9952
|
children
|
|
8256
9953
|
}) {
|
|
8257
|
-
return /* @__PURE__ */ jsx(
|
|
9954
|
+
return /* @__PURE__ */ jsx(Grid, { cols, gap, rowGap, colGap, className, style, children });
|
|
8258
9955
|
}
|
|
8259
9956
|
GridPattern.displayName = "GridPattern";
|
|
8260
9957
|
function CenterPattern({
|
|
@@ -8271,14 +9968,14 @@ function SpacerPattern({ size = "flex" }) {
|
|
|
8271
9968
|
if (size === "flex") {
|
|
8272
9969
|
return /* @__PURE__ */ jsx(Spacer, {});
|
|
8273
9970
|
}
|
|
8274
|
-
const
|
|
9971
|
+
const sizeMap8 = {
|
|
8275
9972
|
xs: "0.25rem",
|
|
8276
9973
|
sm: "0.5rem",
|
|
8277
9974
|
md: "1rem",
|
|
8278
9975
|
lg: "1.5rem",
|
|
8279
9976
|
xl: "2rem"
|
|
8280
9977
|
};
|
|
8281
|
-
return /* @__PURE__ */ jsx(Box, { style: { width:
|
|
9978
|
+
return /* @__PURE__ */ jsx(Box, { style: { width: sizeMap8[size], height: sizeMap8[size], flexShrink: 0 } });
|
|
8282
9979
|
}
|
|
8283
9980
|
SpacerPattern.displayName = "SpacerPattern";
|
|
8284
9981
|
function DividerPattern({
|
|
@@ -8539,7 +10236,7 @@ function InputPattern({
|
|
|
8539
10236
|
className
|
|
8540
10237
|
}) {
|
|
8541
10238
|
const { emit } = useEventBus();
|
|
8542
|
-
const [localValue, setLocalValue] =
|
|
10239
|
+
const [localValue, setLocalValue] = React50__default.useState(value);
|
|
8543
10240
|
const handleChange = (e) => {
|
|
8544
10241
|
setLocalValue(e.target.value);
|
|
8545
10242
|
if (onChange) {
|
|
@@ -8576,7 +10273,7 @@ function TextareaPattern({
|
|
|
8576
10273
|
className
|
|
8577
10274
|
}) {
|
|
8578
10275
|
const { emit } = useEventBus();
|
|
8579
|
-
const [localValue, setLocalValue] =
|
|
10276
|
+
const [localValue, setLocalValue] = React50__default.useState(value);
|
|
8580
10277
|
const handleChange = (e) => {
|
|
8581
10278
|
setLocalValue(e.target.value);
|
|
8582
10279
|
if (onChange) {
|
|
@@ -8607,7 +10304,7 @@ function SelectPattern({
|
|
|
8607
10304
|
className
|
|
8608
10305
|
}) {
|
|
8609
10306
|
const { emit } = useEventBus();
|
|
8610
|
-
const [localValue, setLocalValue] =
|
|
10307
|
+
const [localValue, setLocalValue] = React50__default.useState(value);
|
|
8611
10308
|
const handleChange = (e) => {
|
|
8612
10309
|
setLocalValue(e.target.value);
|
|
8613
10310
|
if (onChange) {
|
|
@@ -8636,7 +10333,7 @@ function CheckboxPattern({
|
|
|
8636
10333
|
className
|
|
8637
10334
|
}) {
|
|
8638
10335
|
const { emit } = useEventBus();
|
|
8639
|
-
const [localChecked, setLocalChecked] =
|
|
10336
|
+
const [localChecked, setLocalChecked] = React50__default.useState(checked);
|
|
8640
10337
|
const handleChange = (e) => {
|
|
8641
10338
|
setLocalChecked(e.target.checked);
|
|
8642
10339
|
if (onChange) {
|
|
@@ -8750,7 +10447,7 @@ function MenuPattern({
|
|
|
8750
10447
|
...item,
|
|
8751
10448
|
onClick: () => emit(`UI:${item.event}`, {})
|
|
8752
10449
|
}));
|
|
8753
|
-
return /* @__PURE__ */ jsx(
|
|
10450
|
+
return /* @__PURE__ */ jsx(Menu, { items: menuItems, trigger, position, className });
|
|
8754
10451
|
}
|
|
8755
10452
|
MenuPattern.displayName = "MenuPattern";
|
|
8756
10453
|
function AccordionPattern({
|
|
@@ -8813,6 +10510,35 @@ function FloatButtonPattern({
|
|
|
8813
10510
|
);
|
|
8814
10511
|
}
|
|
8815
10512
|
FloatButtonPattern.displayName = "FloatButtonPattern";
|
|
10513
|
+
function MapViewPattern({
|
|
10514
|
+
markers,
|
|
10515
|
+
centerLat,
|
|
10516
|
+
centerLng,
|
|
10517
|
+
zoom,
|
|
10518
|
+
height,
|
|
10519
|
+
mapClickEvent,
|
|
10520
|
+
markerClickEvent,
|
|
10521
|
+
showClickedPin,
|
|
10522
|
+
className,
|
|
10523
|
+
showAttribution
|
|
10524
|
+
}) {
|
|
10525
|
+
return /* @__PURE__ */ jsx(
|
|
10526
|
+
MapView,
|
|
10527
|
+
{
|
|
10528
|
+
markers,
|
|
10529
|
+
centerLat,
|
|
10530
|
+
centerLng,
|
|
10531
|
+
zoom,
|
|
10532
|
+
height,
|
|
10533
|
+
mapClickEvent,
|
|
10534
|
+
markerClickEvent,
|
|
10535
|
+
showClickedPin,
|
|
10536
|
+
className,
|
|
10537
|
+
showAttribution
|
|
10538
|
+
}
|
|
10539
|
+
);
|
|
10540
|
+
}
|
|
10541
|
+
MapViewPattern.displayName = "MapViewPattern";
|
|
8816
10542
|
var ALLOWED_CUSTOM_COMPONENTS = [
|
|
8817
10543
|
"div",
|
|
8818
10544
|
"span",
|
|
@@ -9037,7 +10763,7 @@ function SuspenseConfigProvider({
|
|
|
9037
10763
|
config,
|
|
9038
10764
|
children
|
|
9039
10765
|
}) {
|
|
9040
|
-
return
|
|
10766
|
+
return React50__default.createElement(
|
|
9041
10767
|
SuspenseConfigContext.Provider,
|
|
9042
10768
|
{ value: config },
|
|
9043
10769
|
children
|
|
@@ -9113,6 +10839,8 @@ var COMPONENT_REGISTRY = {
|
|
|
9113
10839
|
ContainerPattern,
|
|
9114
10840
|
SimpleGridPattern,
|
|
9115
10841
|
FloatButtonPattern,
|
|
10842
|
+
// Map patterns
|
|
10843
|
+
MapViewPattern,
|
|
9116
10844
|
// Custom pattern
|
|
9117
10845
|
CustomPattern
|
|
9118
10846
|
};
|
|
@@ -9175,7 +10903,9 @@ var PATTERN_TO_COMPONENT = {
|
|
|
9175
10903
|
"simple-grid": "SimpleGridPattern",
|
|
9176
10904
|
"float-button": "FloatButtonPattern",
|
|
9177
10905
|
// Custom pattern
|
|
9178
|
-
custom: "CustomPattern"
|
|
10906
|
+
custom: "CustomPattern",
|
|
10907
|
+
// Map patterns
|
|
10908
|
+
"map-view": "MapViewPattern"
|
|
9179
10909
|
};
|
|
9180
10910
|
function getComponentForPattern(patternType) {
|
|
9181
10911
|
const componentName = PATTERN_TO_COMPONENT[patternType];
|
|
@@ -9214,6 +10944,9 @@ function UISlotComponent({
|
|
|
9214
10944
|
if (pattern === "clear") {
|
|
9215
10945
|
return null;
|
|
9216
10946
|
}
|
|
10947
|
+
if (isPortalSlot(slot)) {
|
|
10948
|
+
return /* @__PURE__ */ jsx(CompiledPortal, { slot, className, pattern, sourceTrait, children });
|
|
10949
|
+
}
|
|
9217
10950
|
return /* @__PURE__ */ jsx(
|
|
9218
10951
|
Box,
|
|
9219
10952
|
{
|
|
@@ -9264,6 +10997,70 @@ function UISlotComponent({
|
|
|
9264
10997
|
}
|
|
9265
10998
|
);
|
|
9266
10999
|
}
|
|
11000
|
+
function CompiledPortal({ slot, className, pattern, sourceTrait, children }) {
|
|
11001
|
+
const [portalRoot, setPortalRoot] = useState(null);
|
|
11002
|
+
const eventBus = useUISlots();
|
|
11003
|
+
useEffect(() => {
|
|
11004
|
+
let root = document.getElementById("ui-slot-portal-root");
|
|
11005
|
+
if (!root) {
|
|
11006
|
+
root = document.createElement("div");
|
|
11007
|
+
root.id = "ui-slot-portal-root";
|
|
11008
|
+
document.body.appendChild(root);
|
|
11009
|
+
}
|
|
11010
|
+
setPortalRoot(root);
|
|
11011
|
+
}, []);
|
|
11012
|
+
const handleDismiss = () => {
|
|
11013
|
+
eventBus.clear(slot);
|
|
11014
|
+
};
|
|
11015
|
+
if (!portalRoot) return null;
|
|
11016
|
+
let wrapper;
|
|
11017
|
+
switch (slot) {
|
|
11018
|
+
case "modal":
|
|
11019
|
+
wrapper = /* @__PURE__ */ jsx(Modal, { isOpen: true, onClose: handleDismiss, showCloseButton: true, children: /* @__PURE__ */ jsx(
|
|
11020
|
+
Box,
|
|
11021
|
+
{
|
|
11022
|
+
className: cn("ui-slot", `ui-slot-${slot}`, className),
|
|
11023
|
+
"data-pattern": pattern,
|
|
11024
|
+
"data-source-trait": sourceTrait,
|
|
11025
|
+
children
|
|
11026
|
+
}
|
|
11027
|
+
) });
|
|
11028
|
+
break;
|
|
11029
|
+
case "drawer":
|
|
11030
|
+
wrapper = /* @__PURE__ */ jsx(Drawer, { isOpen: true, onClose: handleDismiss, position: "right", children: /* @__PURE__ */ jsx(
|
|
11031
|
+
Box,
|
|
11032
|
+
{
|
|
11033
|
+
className: cn("ui-slot", `ui-slot-${slot}`, className),
|
|
11034
|
+
"data-pattern": pattern,
|
|
11035
|
+
"data-source-trait": sourceTrait,
|
|
11036
|
+
children
|
|
11037
|
+
}
|
|
11038
|
+
) });
|
|
11039
|
+
break;
|
|
11040
|
+
case "toast":
|
|
11041
|
+
wrapper = /* @__PURE__ */ jsx(Box, { className: "fixed top-4 right-4 z-50", children: /* @__PURE__ */ jsx(
|
|
11042
|
+
Box,
|
|
11043
|
+
{
|
|
11044
|
+
className: cn("ui-slot", `ui-slot-${slot}`, className),
|
|
11045
|
+
"data-pattern": pattern,
|
|
11046
|
+
"data-source-trait": sourceTrait,
|
|
11047
|
+
children
|
|
11048
|
+
}
|
|
11049
|
+
) });
|
|
11050
|
+
break;
|
|
11051
|
+
default:
|
|
11052
|
+
wrapper = /* @__PURE__ */ jsx(
|
|
11053
|
+
Box,
|
|
11054
|
+
{
|
|
11055
|
+
className: cn("ui-slot", `ui-slot-${slot}`, className),
|
|
11056
|
+
"data-pattern": pattern,
|
|
11057
|
+
"data-source-trait": sourceTrait,
|
|
11058
|
+
children
|
|
11059
|
+
}
|
|
11060
|
+
);
|
|
11061
|
+
}
|
|
11062
|
+
return createPortal(wrapper, portalRoot);
|
|
11063
|
+
}
|
|
9267
11064
|
function SlotPortal({
|
|
9268
11065
|
slot,
|
|
9269
11066
|
content,
|
|
@@ -9451,4 +11248,4 @@ function UISlotRenderer({
|
|
|
9451
11248
|
}
|
|
9452
11249
|
UISlotRenderer.displayName = "UISlotRenderer";
|
|
9453
11250
|
|
|
9454
|
-
export { Accordion, Alert, Avatar, Badge, Box, Breadcrumb, Button, ButtonGroup, Card, Card2, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Center, Checkbox, CodeBlock, ConditionalWrapper, Container, ControlButton, DataTable, DetailPanel, Divider, Drawer, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FilterGroup, Flex, FloatingActionButton, Form, FormField, FormSectionHeader,
|
|
11251
|
+
export { Accordion, ActionButtons, Alert, Avatar, Badge, Box, Breadcrumb, Button, ButtonGroup, CalendarGrid, Card, Card2, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Center, ChartLegend, Checkbox, CodeBlock, ConditionalWrapper, Container, ControlButton, DPad, DataGrid, DataList, DataTable, DateRangeSelector, DayCell, DetailPanel, Divider, Drawer, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FilterGroup, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormField, FormSectionHeader, GraphView, Grid, HStack, Heading, HealthBar, Icon, Input, InputGroup, Label, LawReferenceTooltip, LineChart, LoadingState, MapView, MarkdownContent, MasterDetail, Menu, Modal, Overlay, PageHeader, Pagination, Popover, ProgressBar, ProgressDots, QuizBlock, Radio, RelationSelect, RepeatableFormSection, ScaledDiagram, ScoreDisplay, SearchInput, Select, SidePanel, SimpleGrid, Skeleton, SlotContentRenderer, Spacer, Spinner, Sprite, Stack, StatBadge, StatCard, StateIndicator, SuspenseConfigProvider, Switch, Tabs, Text, TextHighlight, Textarea, ThemeSelector, ThemeToggle, TimeSlotCell, Toast, Tooltip, Typography, UISlotComponent, UISlotRenderer, VStack, ViolationAlert, WizardNavigation, WizardProgress, drawSprite };
|