@almadar/ui 1.0.19 → 1.0.21
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/components/index.d.ts +95 -9
- package/dist/components/index.js +312 -99
- package/package.json +6 -2
package/dist/components/index.js
CHANGED
|
@@ -11,7 +11,7 @@ export { DEFAULT_SLOTS, useUISlotManager } from '../chunk-7NEWMNNU.js';
|
|
|
11
11
|
export { clearEntities, getAllEntities, getByType, getEntity, getSingleton, removeEntity, spawnEntity, updateEntity, updateSingleton } from '../chunk-N7MVUW4R.js';
|
|
12
12
|
import '../chunk-PKBMQBKP.js';
|
|
13
13
|
import * as React37 from 'react';
|
|
14
|
-
import React37__default, { useMemo, useState, useEffect,
|
|
14
|
+
import React37__default, { useCallback, useMemo, useState, useEffect, useRef } from 'react';
|
|
15
15
|
import * as LucideIcons from 'lucide-react';
|
|
16
16
|
import { Loader2, ChevronDown, X, User, Sun, Moon, FileQuestion, Inbox, Search, Info, AlertCircle, XCircle, CheckCircle, AlertTriangle, ChevronRight, Filter, Plus, ChevronLeft, Check, ChevronUp, MoreHorizontal, TrendingUp, TrendingDown, Minus, ArrowLeft, Menu, ArrowUp, ArrowDown, MoreVertical, Package, Trash2, Circle, Clock, CheckCircle2, Image as Image$1, Upload, ZoomIn, Eraser, FileText, ZoomOut, Download, Printer, RotateCcw, Code, WrapText, Copy, Settings, Bell, LogOut, Pause, Play, RefreshCw, Eye, Edit, Calendar, Pencil, Undo2, Save, Tag, DollarSign, Send, ListTodo } from 'lucide-react';
|
|
17
17
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -88,11 +88,22 @@ var Button = React37__default.forwardRef(
|
|
|
88
88
|
rightIcon,
|
|
89
89
|
icon: IconComponent,
|
|
90
90
|
iconRight: IconRightComponent,
|
|
91
|
+
action,
|
|
92
|
+
actionPayload,
|
|
93
|
+
label,
|
|
91
94
|
children,
|
|
95
|
+
onClick,
|
|
92
96
|
...props
|
|
93
97
|
}, ref) => {
|
|
98
|
+
const eventBus = useEventBus();
|
|
94
99
|
const resolvedLeftIcon = leftIcon || IconComponent && /* @__PURE__ */ jsx(IconComponent, { className: iconSizeStyles[size] });
|
|
95
100
|
const resolvedRightIcon = rightIcon || IconRightComponent && /* @__PURE__ */ jsx(IconRightComponent, { className: iconSizeStyles[size] });
|
|
101
|
+
const handleClick = (e) => {
|
|
102
|
+
if (action) {
|
|
103
|
+
eventBus.emit(`UI:${action}`, actionPayload ?? {});
|
|
104
|
+
}
|
|
105
|
+
onClick?.(e);
|
|
106
|
+
};
|
|
96
107
|
return /* @__PURE__ */ jsxs(
|
|
97
108
|
"button",
|
|
98
109
|
{
|
|
@@ -109,10 +120,11 @@ var Button = React37__default.forwardRef(
|
|
|
109
120
|
sizeStyles[size],
|
|
110
121
|
className
|
|
111
122
|
),
|
|
123
|
+
onClick: handleClick,
|
|
112
124
|
...props,
|
|
113
125
|
children: [
|
|
114
126
|
isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : resolvedLeftIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
|
|
115
|
-
children,
|
|
127
|
+
children || label,
|
|
116
128
|
resolvedRightIcon && !isLoading && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: resolvedRightIcon })
|
|
117
129
|
]
|
|
118
130
|
}
|
|
@@ -567,13 +579,23 @@ var Avatar = ({
|
|
|
567
579
|
status,
|
|
568
580
|
badge,
|
|
569
581
|
className,
|
|
570
|
-
onClick
|
|
582
|
+
onClick,
|
|
583
|
+
action,
|
|
584
|
+
actionPayload
|
|
571
585
|
}) => {
|
|
586
|
+
const eventBus = useEventBus();
|
|
572
587
|
const initials = providedInitials ?? (name ? generateInitials(name) : void 0);
|
|
573
588
|
const hasImage = !!src;
|
|
574
589
|
const hasInitials = !!initials;
|
|
575
590
|
const hasIcon = !!Icon2;
|
|
576
591
|
const getInitialsBackground = () => "bg-[var(--color-primary)] text-[var(--color-primary-foreground)]";
|
|
592
|
+
const isClickable = action || onClick;
|
|
593
|
+
const handleClick = () => {
|
|
594
|
+
if (action) {
|
|
595
|
+
eventBus.emit(`UI:${action}`, actionPayload ?? {});
|
|
596
|
+
}
|
|
597
|
+
onClick?.();
|
|
598
|
+
};
|
|
577
599
|
return /* @__PURE__ */ jsxs("div", { className: "relative inline-block", children: [
|
|
578
600
|
/* @__PURE__ */ jsx(
|
|
579
601
|
"div",
|
|
@@ -583,12 +605,12 @@ var Avatar = ({
|
|
|
583
605
|
"bg-[var(--color-muted)] border-[length:var(--border-width)] border-[var(--color-border)]",
|
|
584
606
|
"overflow-hidden",
|
|
585
607
|
sizeClasses[size],
|
|
586
|
-
|
|
608
|
+
isClickable && "cursor-pointer hover:bg-[var(--color-surface-hover)] transition-colors",
|
|
587
609
|
className
|
|
588
610
|
),
|
|
589
|
-
onClick,
|
|
590
|
-
role:
|
|
591
|
-
tabIndex:
|
|
611
|
+
onClick: isClickable ? handleClick : void 0,
|
|
612
|
+
role: isClickable ? "button" : void 0,
|
|
613
|
+
tabIndex: isClickable ? 0 : void 0,
|
|
592
614
|
children: hasImage ? /* @__PURE__ */ jsx(
|
|
593
615
|
"img",
|
|
594
616
|
{
|
|
@@ -777,9 +799,34 @@ var Box = React37__default.forwardRef(
|
|
|
777
799
|
className,
|
|
778
800
|
children,
|
|
779
801
|
as: Component = "div",
|
|
802
|
+
action,
|
|
803
|
+
actionPayload,
|
|
804
|
+
hoverEvent,
|
|
780
805
|
onClick,
|
|
806
|
+
onMouseEnter,
|
|
807
|
+
onMouseLeave,
|
|
781
808
|
...rest
|
|
782
809
|
}, ref) => {
|
|
810
|
+
const eventBus = useEventBus();
|
|
811
|
+
const handleClick = useCallback((e) => {
|
|
812
|
+
if (action) {
|
|
813
|
+
eventBus.emit(`UI:${action}`, actionPayload ?? {});
|
|
814
|
+
}
|
|
815
|
+
onClick?.(e);
|
|
816
|
+
}, [action, actionPayload, eventBus, onClick]);
|
|
817
|
+
const handleMouseEnter = useCallback((e) => {
|
|
818
|
+
if (hoverEvent) {
|
|
819
|
+
eventBus.emit(`UI:${hoverEvent}`, { hovered: true });
|
|
820
|
+
}
|
|
821
|
+
onMouseEnter?.(e);
|
|
822
|
+
}, [hoverEvent, eventBus, onMouseEnter]);
|
|
823
|
+
const handleMouseLeave = useCallback((e) => {
|
|
824
|
+
if (hoverEvent) {
|
|
825
|
+
eventBus.emit(`UI:${hoverEvent}`, { hovered: false });
|
|
826
|
+
}
|
|
827
|
+
onMouseLeave?.(e);
|
|
828
|
+
}, [hoverEvent, eventBus, onMouseLeave]);
|
|
829
|
+
const isClickable = action || onClick;
|
|
783
830
|
return /* @__PURE__ */ jsx(
|
|
784
831
|
Component,
|
|
785
832
|
{
|
|
@@ -811,10 +858,12 @@ var Box = React37__default.forwardRef(
|
|
|
811
858
|
// Position
|
|
812
859
|
position && positionStyles[position],
|
|
813
860
|
// Cursor for clickable
|
|
814
|
-
|
|
861
|
+
isClickable && "cursor-pointer",
|
|
815
862
|
className
|
|
816
863
|
),
|
|
817
|
-
onClick,
|
|
864
|
+
onClick: isClickable ? handleClick : void 0,
|
|
865
|
+
onMouseEnter: hoverEvent || onMouseEnter ? handleMouseEnter : void 0,
|
|
866
|
+
onMouseLeave: hoverEvent || onMouseLeave ? handleMouseLeave : void 0,
|
|
818
867
|
...rest,
|
|
819
868
|
children
|
|
820
869
|
}
|
|
@@ -1474,8 +1523,17 @@ var Stack = ({
|
|
|
1474
1523
|
onClick,
|
|
1475
1524
|
onKeyDown,
|
|
1476
1525
|
role,
|
|
1477
|
-
tabIndex
|
|
1526
|
+
tabIndex,
|
|
1527
|
+
action,
|
|
1528
|
+
actionPayload
|
|
1478
1529
|
}) => {
|
|
1530
|
+
const eventBus = useEventBus();
|
|
1531
|
+
const handleClick = (e) => {
|
|
1532
|
+
if (action) {
|
|
1533
|
+
eventBus.emit(`UI:${action}`, actionPayload ?? {});
|
|
1534
|
+
}
|
|
1535
|
+
onClick?.(e);
|
|
1536
|
+
};
|
|
1479
1537
|
const directionClass = direction === "horizontal" ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
|
|
1480
1538
|
return /* @__PURE__ */ jsx(
|
|
1481
1539
|
Component,
|
|
@@ -1491,7 +1549,7 @@ var Stack = ({
|
|
|
1491
1549
|
className
|
|
1492
1550
|
),
|
|
1493
1551
|
style,
|
|
1494
|
-
onClick,
|
|
1552
|
+
onClick: action || onClick ? handleClick : void 0,
|
|
1495
1553
|
onKeyDown,
|
|
1496
1554
|
role,
|
|
1497
1555
|
tabIndex,
|
|
@@ -1509,8 +1567,11 @@ var TextHighlight = ({
|
|
|
1509
1567
|
onMouseLeave,
|
|
1510
1568
|
annotationId,
|
|
1511
1569
|
className,
|
|
1512
|
-
children
|
|
1570
|
+
children,
|
|
1571
|
+
action,
|
|
1572
|
+
hoverEvent
|
|
1513
1573
|
}) => {
|
|
1574
|
+
const eventBus = useEventBus();
|
|
1514
1575
|
const baseStyles = "cursor-pointer transition-all duration-150";
|
|
1515
1576
|
const typeStyles = {
|
|
1516
1577
|
question: cn(
|
|
@@ -1533,14 +1594,24 @@ var TextHighlight = ({
|
|
|
1533
1594
|
"data-highlight-type": highlightType,
|
|
1534
1595
|
"data-annotation-id": annotationId,
|
|
1535
1596
|
className: cn(baseStyles, typeStyles[highlightType], className),
|
|
1536
|
-
onClick
|
|
1537
|
-
|
|
1538
|
-
|
|
1597
|
+
onClick: () => {
|
|
1598
|
+
if (action) eventBus.emit(`UI:${action}`, { annotationId });
|
|
1599
|
+
onClick?.();
|
|
1600
|
+
},
|
|
1601
|
+
onMouseEnter: () => {
|
|
1602
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: true, annotationId });
|
|
1603
|
+
onMouseEnter?.();
|
|
1604
|
+
},
|
|
1605
|
+
onMouseLeave: () => {
|
|
1606
|
+
if (hoverEvent) eventBus.emit(`UI:${hoverEvent}`, { hovered: false, annotationId });
|
|
1607
|
+
onMouseLeave?.();
|
|
1608
|
+
},
|
|
1539
1609
|
role: "button",
|
|
1540
1610
|
tabIndex: 0,
|
|
1541
1611
|
onKeyDown: (e) => {
|
|
1542
1612
|
if (e.key === "Enter" || e.key === " ") {
|
|
1543
1613
|
e.preventDefault();
|
|
1614
|
+
if (action) eventBus.emit(`UI:${action}`, { annotationId });
|
|
1544
1615
|
onClick?.();
|
|
1545
1616
|
}
|
|
1546
1617
|
},
|
|
@@ -1837,9 +1908,17 @@ var Overlay = ({
|
|
|
1837
1908
|
isVisible = true,
|
|
1838
1909
|
onClick,
|
|
1839
1910
|
className,
|
|
1840
|
-
blur = true
|
|
1911
|
+
blur = true,
|
|
1912
|
+
action
|
|
1841
1913
|
}) => {
|
|
1914
|
+
const eventBus = useEventBus();
|
|
1842
1915
|
if (!isVisible) return null;
|
|
1916
|
+
const handleClick = (e) => {
|
|
1917
|
+
if (action) {
|
|
1918
|
+
eventBus.emit(`UI:${action}`, {});
|
|
1919
|
+
}
|
|
1920
|
+
onClick?.(e);
|
|
1921
|
+
};
|
|
1843
1922
|
return /* @__PURE__ */ jsx(
|
|
1844
1923
|
"div",
|
|
1845
1924
|
{
|
|
@@ -1848,7 +1927,7 @@ var Overlay = ({
|
|
|
1848
1927
|
blur && "backdrop-blur-sm",
|
|
1849
1928
|
className
|
|
1850
1929
|
),
|
|
1851
|
-
onClick,
|
|
1930
|
+
onClick: action || onClick ? handleClick : void 0,
|
|
1852
1931
|
"aria-hidden": "true"
|
|
1853
1932
|
}
|
|
1854
1933
|
);
|
|
@@ -2163,10 +2242,13 @@ function ControlButton({
|
|
|
2163
2242
|
variant = "secondary",
|
|
2164
2243
|
onPress,
|
|
2165
2244
|
onRelease,
|
|
2245
|
+
pressEvent,
|
|
2246
|
+
releaseEvent,
|
|
2166
2247
|
pressed,
|
|
2167
2248
|
disabled,
|
|
2168
2249
|
className
|
|
2169
2250
|
}) {
|
|
2251
|
+
const eventBus = useEventBus();
|
|
2170
2252
|
const [isPressed, setIsPressed] = React37.useState(false);
|
|
2171
2253
|
const actualPressed = pressed ?? isPressed;
|
|
2172
2254
|
const handlePointerDown = React37.useCallback(
|
|
@@ -2174,27 +2256,30 @@ function ControlButton({
|
|
|
2174
2256
|
e.preventDefault();
|
|
2175
2257
|
if (disabled) return;
|
|
2176
2258
|
setIsPressed(true);
|
|
2259
|
+
if (pressEvent) eventBus.emit(`UI:${pressEvent}`, {});
|
|
2177
2260
|
onPress?.();
|
|
2178
2261
|
},
|
|
2179
|
-
[disabled, onPress]
|
|
2262
|
+
[disabled, pressEvent, eventBus, onPress]
|
|
2180
2263
|
);
|
|
2181
2264
|
const handlePointerUp = React37.useCallback(
|
|
2182
2265
|
(e) => {
|
|
2183
2266
|
e.preventDefault();
|
|
2184
2267
|
if (disabled) return;
|
|
2185
2268
|
setIsPressed(false);
|
|
2269
|
+
if (releaseEvent) eventBus.emit(`UI:${releaseEvent}`, {});
|
|
2186
2270
|
onRelease?.();
|
|
2187
2271
|
},
|
|
2188
|
-
[disabled, onRelease]
|
|
2272
|
+
[disabled, releaseEvent, eventBus, onRelease]
|
|
2189
2273
|
);
|
|
2190
2274
|
const handlePointerLeave = React37.useCallback(
|
|
2191
2275
|
(e) => {
|
|
2192
2276
|
if (isPressed) {
|
|
2193
2277
|
setIsPressed(false);
|
|
2278
|
+
if (releaseEvent) eventBus.emit(`UI:${releaseEvent}`, {});
|
|
2194
2279
|
onRelease?.();
|
|
2195
2280
|
}
|
|
2196
2281
|
},
|
|
2197
|
-
[isPressed, onRelease]
|
|
2282
|
+
[isPressed, releaseEvent, eventBus, onRelease]
|
|
2198
2283
|
);
|
|
2199
2284
|
return /* @__PURE__ */ jsxs(
|
|
2200
2285
|
"button",
|
|
@@ -2240,8 +2325,10 @@ function Sprite({
|
|
|
2240
2325
|
zIndex = 0,
|
|
2241
2326
|
columns = 16,
|
|
2242
2327
|
className,
|
|
2243
|
-
onClick
|
|
2328
|
+
onClick,
|
|
2329
|
+
action
|
|
2244
2330
|
}) {
|
|
2331
|
+
const eventBus = useEventBus();
|
|
2245
2332
|
const sourcePosition = useMemo(() => {
|
|
2246
2333
|
const frameX = frame % columns;
|
|
2247
2334
|
const frameY = Math.floor(frame / columns);
|
|
@@ -2266,11 +2353,15 @@ function Sprite({
|
|
|
2266
2353
|
return transforms.join(" ");
|
|
2267
2354
|
}, [x, y, scale, flipX, flipY, rotation]);
|
|
2268
2355
|
const backgroundPosition = `-${sourcePosition.x}px -${sourcePosition.y}px`;
|
|
2356
|
+
const handleClick = () => {
|
|
2357
|
+
if (action) eventBus.emit(`UI:${action}`, {});
|
|
2358
|
+
onClick?.();
|
|
2359
|
+
};
|
|
2269
2360
|
return /* @__PURE__ */ jsx(
|
|
2270
2361
|
"div",
|
|
2271
2362
|
{
|
|
2272
2363
|
className,
|
|
2273
|
-
onClick,
|
|
2364
|
+
onClick: action || onClick ? handleClick : void 0,
|
|
2274
2365
|
style: {
|
|
2275
2366
|
position: "absolute",
|
|
2276
2367
|
width: frameWidth,
|
|
@@ -2283,7 +2374,7 @@ function Sprite({
|
|
|
2283
2374
|
transformOrigin: "center center",
|
|
2284
2375
|
opacity,
|
|
2285
2376
|
zIndex,
|
|
2286
|
-
pointerEvents: onClick ? "auto" : "none"
|
|
2377
|
+
pointerEvents: action || onClick ? "auto" : "none"
|
|
2287
2378
|
}
|
|
2288
2379
|
}
|
|
2289
2380
|
);
|
|
@@ -2361,8 +2452,14 @@ var EmptyState = ({
|
|
|
2361
2452
|
onAction,
|
|
2362
2453
|
className,
|
|
2363
2454
|
destructive,
|
|
2364
|
-
variant
|
|
2455
|
+
variant,
|
|
2456
|
+
actionEvent
|
|
2365
2457
|
}) => {
|
|
2458
|
+
const eventBus = useEventBus();
|
|
2459
|
+
const handleAction = () => {
|
|
2460
|
+
if (actionEvent) eventBus.emit(`UI:${actionEvent}`, {});
|
|
2461
|
+
onAction?.();
|
|
2462
|
+
};
|
|
2366
2463
|
const Icon2 = typeof icon === "string" ? ICON_MAP[icon] : icon;
|
|
2367
2464
|
const isDestructive = destructive || variant === "error";
|
|
2368
2465
|
const isSuccess = variant === "success";
|
|
@@ -2404,12 +2501,12 @@ var EmptyState = ({
|
|
|
2404
2501
|
}
|
|
2405
2502
|
),
|
|
2406
2503
|
description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-[var(--color-muted-foreground)] max-w-sm", children: description }),
|
|
2407
|
-
actionLabel && onAction && /* @__PURE__ */ jsx(
|
|
2504
|
+
actionLabel && (onAction || actionEvent) && /* @__PURE__ */ jsx(
|
|
2408
2505
|
Button,
|
|
2409
2506
|
{
|
|
2410
2507
|
className: "mt-4",
|
|
2411
2508
|
variant: isDestructive ? "danger" : "primary",
|
|
2412
|
-
onClick:
|
|
2509
|
+
onClick: handleAction,
|
|
2413
2510
|
children: actionLabel
|
|
2414
2511
|
}
|
|
2415
2512
|
)
|
|
@@ -2451,8 +2548,14 @@ var ErrorState = ({
|
|
|
2451
2548
|
message,
|
|
2452
2549
|
description,
|
|
2453
2550
|
onRetry,
|
|
2454
|
-
className
|
|
2551
|
+
className,
|
|
2552
|
+
retryEvent
|
|
2455
2553
|
}) => {
|
|
2554
|
+
const eventBus = useEventBus();
|
|
2555
|
+
const handleRetry = () => {
|
|
2556
|
+
if (retryEvent) eventBus.emit(`UI:${retryEvent}`, {});
|
|
2557
|
+
onRetry?.();
|
|
2558
|
+
};
|
|
2456
2559
|
const resolvedMessage = message ?? description ?? "An error occurred";
|
|
2457
2560
|
return /* @__PURE__ */ jsxs(
|
|
2458
2561
|
"div",
|
|
@@ -2465,7 +2568,7 @@ var ErrorState = ({
|
|
|
2465
2568
|
/* @__PURE__ */ jsx("div", { className: "mb-4 rounded-[var(--radius-full)] bg-[var(--color-error)]/10 p-3", children: /* @__PURE__ */ jsx(AlertCircle, { className: "h-8 w-8 text-[var(--color-error)]" }) }),
|
|
2466
2569
|
/* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-[var(--color-foreground)]", children: title }),
|
|
2467
2570
|
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-[var(--color-muted-foreground)] max-w-sm", children: resolvedMessage }),
|
|
2468
|
-
onRetry && /* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick:
|
|
2571
|
+
(onRetry || retryEvent) && /* @__PURE__ */ jsx(Button, { variant: "secondary", className: "mt-4", onClick: handleRetry, children: "Try again" })
|
|
2469
2572
|
]
|
|
2470
2573
|
}
|
|
2471
2574
|
);
|
|
@@ -2492,8 +2595,10 @@ var Accordion = ({
|
|
|
2492
2595
|
defaultOpen,
|
|
2493
2596
|
openItems: controlledOpenItems,
|
|
2494
2597
|
onItemToggle,
|
|
2495
|
-
className
|
|
2598
|
+
className,
|
|
2599
|
+
toggleEvent
|
|
2496
2600
|
}) => {
|
|
2601
|
+
const eventBus = useEventBus();
|
|
2497
2602
|
const normalizedItems = items.map(
|
|
2498
2603
|
(item, index) => normalizeItem(item, index)
|
|
2499
2604
|
);
|
|
@@ -2523,6 +2628,7 @@ var Accordion = ({
|
|
|
2523
2628
|
setInternalOpenItems(newOpenItems);
|
|
2524
2629
|
}
|
|
2525
2630
|
onItemToggle?.(itemId, !isOpen);
|
|
2631
|
+
if (toggleEvent) eventBus.emit(`UI:${toggleEvent}`, { itemId, isOpen: !isOpen });
|
|
2526
2632
|
};
|
|
2527
2633
|
return /* @__PURE__ */ jsx("div", { className: cn("w-full", className), children: normalizedItems.map((item, index) => {
|
|
2528
2634
|
const isOpen = openItemsSet.has(item.id);
|
|
@@ -2600,9 +2706,15 @@ var Alert = ({
|
|
|
2600
2706
|
onDismiss,
|
|
2601
2707
|
onClose,
|
|
2602
2708
|
actions,
|
|
2603
|
-
className
|
|
2709
|
+
className,
|
|
2710
|
+
dismissEvent
|
|
2604
2711
|
}) => {
|
|
2605
|
-
const
|
|
2712
|
+
const eventBus = useEventBus();
|
|
2713
|
+
const handleDismissCallback = onDismiss || onClose;
|
|
2714
|
+
const handleDismiss = () => {
|
|
2715
|
+
if (dismissEvent) eventBus.emit(`UI:${dismissEvent}`, {});
|
|
2716
|
+
handleDismissCallback?.();
|
|
2717
|
+
};
|
|
2606
2718
|
const content = children ?? message;
|
|
2607
2719
|
return /* @__PURE__ */ jsx(
|
|
2608
2720
|
Box,
|
|
@@ -2628,7 +2740,7 @@ var Alert = ({
|
|
|
2628
2740
|
/* @__PURE__ */ jsx(Typography, { variant: "body2", children: content }),
|
|
2629
2741
|
actions && /* @__PURE__ */ jsx("div", { className: "mt-3 flex gap-2", children: actions })
|
|
2630
2742
|
] }),
|
|
2631
|
-
(dismissible ||
|
|
2743
|
+
(dismissible || dismissEvent || handleDismissCallback) && /* @__PURE__ */ jsx(
|
|
2632
2744
|
"button",
|
|
2633
2745
|
{
|
|
2634
2746
|
type: "button",
|
|
@@ -2652,6 +2764,7 @@ var Breadcrumb = ({
|
|
|
2652
2764
|
maxItems,
|
|
2653
2765
|
className
|
|
2654
2766
|
}) => {
|
|
2767
|
+
const eventBus = useEventBus();
|
|
2655
2768
|
const displayItems = maxItems && items.length > maxItems ? [
|
|
2656
2769
|
...items.slice(0, 1),
|
|
2657
2770
|
{ label: "...", isCurrent: false },
|
|
@@ -2691,7 +2804,10 @@ var Breadcrumb = ({
|
|
|
2691
2804
|
"button",
|
|
2692
2805
|
{
|
|
2693
2806
|
type: "button",
|
|
2694
|
-
onClick:
|
|
2807
|
+
onClick: () => {
|
|
2808
|
+
if (item.event) eventBus.emit(`UI:${item.event}`, { label: item.label });
|
|
2809
|
+
item.onClick?.();
|
|
2810
|
+
},
|
|
2695
2811
|
className: cn(
|
|
2696
2812
|
"flex items-center gap-1.5 transition-colors",
|
|
2697
2813
|
"focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)] focus:ring-offset-2",
|
|
@@ -3223,9 +3339,15 @@ function Card2({
|
|
|
3223
3339
|
actions,
|
|
3224
3340
|
children,
|
|
3225
3341
|
onClick,
|
|
3226
|
-
className = ""
|
|
3342
|
+
className = "",
|
|
3343
|
+
action
|
|
3227
3344
|
}) {
|
|
3228
|
-
const
|
|
3345
|
+
const eventBus = useEventBus();
|
|
3346
|
+
const isClickable = !!onClick || !!action;
|
|
3347
|
+
const handleClick = () => {
|
|
3348
|
+
if (action) eventBus.emit(`UI:${action}`, {});
|
|
3349
|
+
onClick?.();
|
|
3350
|
+
};
|
|
3229
3351
|
return /* @__PURE__ */ jsxs(
|
|
3230
3352
|
"div",
|
|
3231
3353
|
{
|
|
@@ -3236,10 +3358,10 @@ function Card2({
|
|
|
3236
3358
|
${isClickable ? "cursor-pointer hover:shadow-[var(--shadow-hover)] transition-shadow" : ""}
|
|
3237
3359
|
${className}
|
|
3238
3360
|
`,
|
|
3239
|
-
onClick,
|
|
3361
|
+
onClick: isClickable ? handleClick : void 0,
|
|
3240
3362
|
role: isClickable ? "button" : void 0,
|
|
3241
3363
|
tabIndex: isClickable ? 0 : void 0,
|
|
3242
|
-
onKeyDown: isClickable ? (e) => e.key === "Enter" &&
|
|
3364
|
+
onKeyDown: isClickable ? (e) => e.key === "Enter" && handleClick() : void 0,
|
|
3243
3365
|
children: [
|
|
3244
3366
|
image && /* @__PURE__ */ jsx("div", { className: "aspect-video w-full overflow-hidden rounded-t-lg", children: /* @__PURE__ */ jsx(
|
|
3245
3367
|
"img",
|
|
@@ -3255,21 +3377,22 @@ function Card2({
|
|
|
3255
3377
|
subtitle && /* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--color-muted-foreground)] mt-1", children: subtitle })
|
|
3256
3378
|
] }),
|
|
3257
3379
|
children && /* @__PURE__ */ jsx("div", { className: "text-[var(--color-card-foreground)]", children }),
|
|
3258
|
-
actions && actions.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 mt-4 pt-4 border-t border-[var(--color-border)]", children: actions.map((
|
|
3380
|
+
actions && actions.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 mt-4 pt-4 border-t border-[var(--color-border)]", children: actions.map((action2, index) => /* @__PURE__ */ jsx(
|
|
3259
3381
|
"button",
|
|
3260
3382
|
{
|
|
3261
3383
|
onClick: (e) => {
|
|
3262
3384
|
e.stopPropagation();
|
|
3263
|
-
|
|
3385
|
+
if (action2.event) eventBus.emit(`UI:${action2.event}`, { label: action2.label });
|
|
3386
|
+
action2.onClick?.();
|
|
3264
3387
|
},
|
|
3265
|
-
disabled:
|
|
3388
|
+
disabled: action2.disabled,
|
|
3266
3389
|
className: `
|
|
3267
3390
|
px-3 py-1.5 text-sm font-medium rounded-[var(--radius-sm)]
|
|
3268
3391
|
transition-colors
|
|
3269
|
-
${
|
|
3392
|
+
${action2.variant === "primary" ? "bg-[var(--color-primary)] text-[var(--color-primary-foreground)] hover:bg-[var(--color-primary-hover)] disabled:opacity-50" : action2.variant === "danger" ? "bg-[var(--color-error)] text-[var(--color-error-foreground)] hover:opacity-90 disabled:opacity-50" : "bg-[var(--color-muted)] text-[var(--color-foreground)] hover:bg-[var(--color-surface-hover)]"}
|
|
3270
3393
|
disabled:cursor-not-allowed
|
|
3271
3394
|
`,
|
|
3272
|
-
children:
|
|
3395
|
+
children: action2.label
|
|
3273
3396
|
},
|
|
3274
3397
|
index
|
|
3275
3398
|
)) })
|
|
@@ -3418,6 +3541,7 @@ var FloatingActionButton = ({
|
|
|
3418
3541
|
position = "bottom-right",
|
|
3419
3542
|
className
|
|
3420
3543
|
}) => {
|
|
3544
|
+
const eventBus = useEventBus();
|
|
3421
3545
|
const resolvedAction = action ?? (icon ? {
|
|
3422
3546
|
icon: resolveIcon2(icon),
|
|
3423
3547
|
onClick: onClick ?? (() => {
|
|
@@ -3461,7 +3585,8 @@ var FloatingActionButton = ({
|
|
|
3461
3585
|
if (actions && actions.length > 0) {
|
|
3462
3586
|
const handleMainClick = () => {
|
|
3463
3587
|
if (actions.length === 1) {
|
|
3464
|
-
actions[0].
|
|
3588
|
+
if (actions[0].event) eventBus.emit(`UI:${actions[0].event}`, { actionId: actions[0].id });
|
|
3589
|
+
actions[0].onClick?.();
|
|
3465
3590
|
} else {
|
|
3466
3591
|
setIsExpanded(!isExpanded);
|
|
3467
3592
|
}
|
|
@@ -3503,7 +3628,8 @@ var FloatingActionButton = ({
|
|
|
3503
3628
|
icon: actionItem.icon,
|
|
3504
3629
|
onClick: () => {
|
|
3505
3630
|
setIsExpanded(false);
|
|
3506
|
-
actionItem.
|
|
3631
|
+
if (actionItem.event) eventBus.emit(`UI:${actionItem.event}`, { actionId: actionItem.id });
|
|
3632
|
+
actionItem.onClick?.();
|
|
3507
3633
|
},
|
|
3508
3634
|
className: "rounded-[var(--radius-full)] shadow-[var(--shadow-lg)]",
|
|
3509
3635
|
"aria-label": actionItem.label,
|
|
@@ -3717,6 +3843,7 @@ var Menu2 = ({
|
|
|
3717
3843
|
position = "bottom-left",
|
|
3718
3844
|
className
|
|
3719
3845
|
}) => {
|
|
3846
|
+
const eventBus = useEventBus();
|
|
3720
3847
|
const [isOpen, setIsOpen] = useState(false);
|
|
3721
3848
|
const [activeSubMenu, setActiveSubMenu] = useState(null);
|
|
3722
3849
|
const [triggerRect, setTriggerRect] = useState(null);
|
|
@@ -3739,6 +3866,7 @@ var Menu2 = ({
|
|
|
3739
3866
|
if (item.subMenu && item.subMenu.length > 0) {
|
|
3740
3867
|
setActiveSubMenu(item.id ?? null);
|
|
3741
3868
|
} else {
|
|
3869
|
+
if (item.event) eventBus.emit(`UI:${item.event}`, { itemId: item.id, label: item.label });
|
|
3742
3870
|
item.onClick?.();
|
|
3743
3871
|
setIsOpen(false);
|
|
3744
3872
|
}
|
|
@@ -3884,8 +4012,10 @@ var Modal = ({
|
|
|
3884
4012
|
showCloseButton = true,
|
|
3885
4013
|
closeOnOverlayClick = true,
|
|
3886
4014
|
closeOnEscape = true,
|
|
3887
|
-
className
|
|
4015
|
+
className,
|
|
4016
|
+
closeEvent
|
|
3888
4017
|
}) => {
|
|
4018
|
+
const eventBus = useEventBus();
|
|
3889
4019
|
const modalRef = useRef(null);
|
|
3890
4020
|
const previousActiveElement = useRef(null);
|
|
3891
4021
|
useEffect(() => {
|
|
@@ -3903,11 +4033,14 @@ var Modal = ({
|
|
|
3903
4033
|
useEffect(() => {
|
|
3904
4034
|
if (!isOpen || !closeOnEscape) return;
|
|
3905
4035
|
const handleEscape = (e) => {
|
|
3906
|
-
if (e.key === "Escape")
|
|
4036
|
+
if (e.key === "Escape") {
|
|
4037
|
+
if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
|
|
4038
|
+
onClose();
|
|
4039
|
+
}
|
|
3907
4040
|
};
|
|
3908
4041
|
document.addEventListener("keydown", handleEscape);
|
|
3909
4042
|
return () => document.removeEventListener("keydown", handleEscape);
|
|
3910
|
-
}, [isOpen, closeOnEscape, onClose]);
|
|
4043
|
+
}, [isOpen, closeOnEscape, onClose, closeEvent, eventBus]);
|
|
3911
4044
|
useEffect(() => {
|
|
3912
4045
|
if (isOpen) {
|
|
3913
4046
|
document.body.style.overflow = "hidden";
|
|
@@ -3919,9 +4052,13 @@ var Modal = ({
|
|
|
3919
4052
|
};
|
|
3920
4053
|
}, [isOpen]);
|
|
3921
4054
|
if (!isOpen) return null;
|
|
4055
|
+
const handleClose = () => {
|
|
4056
|
+
if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
|
|
4057
|
+
onClose();
|
|
4058
|
+
};
|
|
3922
4059
|
const handleOverlayClick = (e) => {
|
|
3923
4060
|
if (closeOnOverlayClick && e.target === e.currentTarget) {
|
|
3924
|
-
|
|
4061
|
+
handleClose();
|
|
3925
4062
|
}
|
|
3926
4063
|
};
|
|
3927
4064
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -3963,7 +4100,7 @@ var Modal = ({
|
|
|
3963
4100
|
"button",
|
|
3964
4101
|
{
|
|
3965
4102
|
type: "button",
|
|
3966
|
-
onClick:
|
|
4103
|
+
onClick: handleClose,
|
|
3967
4104
|
className: cn(
|
|
3968
4105
|
"p-1 transition-colors rounded-[var(--radius-sm)]",
|
|
3969
4106
|
"hover:bg-[var(--color-muted)]"
|
|
@@ -4005,13 +4142,24 @@ var Pagination = ({
|
|
|
4005
4142
|
showTotal = false,
|
|
4006
4143
|
totalItems,
|
|
4007
4144
|
maxVisiblePages = 7,
|
|
4008
|
-
className
|
|
4145
|
+
className,
|
|
4146
|
+
pageChangeEvent,
|
|
4147
|
+
pageSizeChangeEvent
|
|
4009
4148
|
}) => {
|
|
4149
|
+
const eventBus = useEventBus();
|
|
4010
4150
|
const [jumpToPage, setJumpToPage] = useState("");
|
|
4151
|
+
const handlePageChange = (page) => {
|
|
4152
|
+
if (pageChangeEvent) eventBus.emit(`UI:${pageChangeEvent}`, { page });
|
|
4153
|
+
onPageChange(page);
|
|
4154
|
+
};
|
|
4155
|
+
const handlePageSizeChange = (size) => {
|
|
4156
|
+
if (pageSizeChangeEvent) eventBus.emit(`UI:${pageSizeChangeEvent}`, { pageSize: size });
|
|
4157
|
+
onPageSizeChange?.(size);
|
|
4158
|
+
};
|
|
4011
4159
|
const handleJumpToPage = () => {
|
|
4012
4160
|
const page = parseInt(jumpToPage, 10);
|
|
4013
4161
|
if (page >= 1 && page <= totalPages) {
|
|
4014
|
-
|
|
4162
|
+
handlePageChange(page);
|
|
4015
4163
|
setJumpToPage("");
|
|
4016
4164
|
}
|
|
4017
4165
|
};
|
|
@@ -4060,7 +4208,7 @@ var Pagination = ({
|
|
|
4060
4208
|
"select",
|
|
4061
4209
|
{
|
|
4062
4210
|
value: pageSize,
|
|
4063
|
-
onChange: (e) =>
|
|
4211
|
+
onChange: (e) => handlePageSizeChange(Number(e.target.value)),
|
|
4064
4212
|
className: "px-2 py-1 text-sm border-[length:var(--border-width)] border-[var(--color-border)] bg-[var(--color-card)] text-[var(--color-foreground)] font-medium focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)]",
|
|
4065
4213
|
children: pageSizeOptions.map((size) => /* @__PURE__ */ jsx("option", { value: size, children: size }, size))
|
|
4066
4214
|
}
|
|
@@ -4073,7 +4221,7 @@ var Pagination = ({
|
|
|
4073
4221
|
{
|
|
4074
4222
|
variant: "secondary",
|
|
4075
4223
|
size: "sm",
|
|
4076
|
-
onClick: () =>
|
|
4224
|
+
onClick: () => handlePageChange(currentPage - 1),
|
|
4077
4225
|
disabled: currentPage === 1,
|
|
4078
4226
|
icon: ChevronLeft,
|
|
4079
4227
|
children: "Previous"
|
|
@@ -4098,7 +4246,7 @@ var Pagination = ({
|
|
|
4098
4246
|
{
|
|
4099
4247
|
variant: isActive ? "primary" : "ghost",
|
|
4100
4248
|
size: "sm",
|
|
4101
|
-
onClick: () =>
|
|
4249
|
+
onClick: () => handlePageChange(page),
|
|
4102
4250
|
className: "min-w-[2.5rem]",
|
|
4103
4251
|
children: page
|
|
4104
4252
|
},
|
|
@@ -4110,7 +4258,7 @@ var Pagination = ({
|
|
|
4110
4258
|
{
|
|
4111
4259
|
variant: "secondary",
|
|
4112
4260
|
size: "sm",
|
|
4113
|
-
onClick: () =>
|
|
4261
|
+
onClick: () => handlePageChange(currentPage + 1),
|
|
4114
4262
|
disabled: currentPage === totalPages,
|
|
4115
4263
|
iconRight: ChevronRight,
|
|
4116
4264
|
children: "Next"
|
|
@@ -4551,15 +4699,21 @@ var SidePanel = ({
|
|
|
4551
4699
|
width = "w-96",
|
|
4552
4700
|
position = "right",
|
|
4553
4701
|
showOverlay = true,
|
|
4554
|
-
className
|
|
4702
|
+
className,
|
|
4703
|
+
closeEvent
|
|
4555
4704
|
}) => {
|
|
4705
|
+
const eventBus = useEventBus();
|
|
4706
|
+
const handleClose = () => {
|
|
4707
|
+
if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
|
|
4708
|
+
onClose();
|
|
4709
|
+
};
|
|
4556
4710
|
if (!isOpen) return null;
|
|
4557
4711
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4558
4712
|
showOverlay && /* @__PURE__ */ jsx(
|
|
4559
4713
|
"div",
|
|
4560
4714
|
{
|
|
4561
4715
|
className: "fixed inset-0 bg-white/80 backdrop-blur-sm z-40 lg:hidden",
|
|
4562
|
-
onClick:
|
|
4716
|
+
onClick: handleClose
|
|
4563
4717
|
}
|
|
4564
4718
|
),
|
|
4565
4719
|
/* @__PURE__ */ jsxs(
|
|
@@ -4585,7 +4739,7 @@ var SidePanel = ({
|
|
|
4585
4739
|
variant: "ghost",
|
|
4586
4740
|
size: "sm",
|
|
4587
4741
|
icon: X,
|
|
4588
|
-
onClick:
|
|
4742
|
+
onClick: handleClose,
|
|
4589
4743
|
"aria-label": "Close panel",
|
|
4590
4744
|
children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
|
|
4591
4745
|
}
|
|
@@ -4794,17 +4948,28 @@ var Toast = ({
|
|
|
4794
4948
|
actionLabel,
|
|
4795
4949
|
onAction,
|
|
4796
4950
|
badge,
|
|
4797
|
-
className
|
|
4951
|
+
className,
|
|
4952
|
+
dismissEvent,
|
|
4953
|
+
actionEvent
|
|
4798
4954
|
}) => {
|
|
4955
|
+
const eventBus = useEventBus();
|
|
4956
|
+
const handleDismiss = () => {
|
|
4957
|
+
if (dismissEvent) eventBus.emit(`UI:${dismissEvent}`, {});
|
|
4958
|
+
onDismiss?.();
|
|
4959
|
+
};
|
|
4960
|
+
const handleAction = () => {
|
|
4961
|
+
if (actionEvent) eventBus.emit(`UI:${actionEvent}`, {});
|
|
4962
|
+
onAction?.();
|
|
4963
|
+
};
|
|
4799
4964
|
useEffect(() => {
|
|
4800
|
-
if (duration <= 0 || !onDismiss) {
|
|
4965
|
+
if (duration <= 0 || !onDismiss && !dismissEvent) {
|
|
4801
4966
|
return;
|
|
4802
4967
|
}
|
|
4803
4968
|
const timer = setTimeout(() => {
|
|
4804
|
-
|
|
4969
|
+
handleDismiss();
|
|
4805
4970
|
}, duration);
|
|
4806
4971
|
return () => clearTimeout(timer);
|
|
4807
|
-
}, [duration, onDismiss]);
|
|
4972
|
+
}, [duration, onDismiss, dismissEvent]);
|
|
4808
4973
|
return /* @__PURE__ */ jsx(
|
|
4809
4974
|
"div",
|
|
4810
4975
|
{
|
|
@@ -4827,7 +4992,7 @@ var Toast = ({
|
|
|
4827
4992
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
4828
4993
|
title && /* @__PURE__ */ jsx(Typography, { variant: "h6", className: "mb-1", children: title }),
|
|
4829
4994
|
/* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-sm", children: message }),
|
|
4830
|
-
actionLabel && onAction && /* @__PURE__ */ jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick:
|
|
4995
|
+
actionLabel && (onAction || actionEvent) && /* @__PURE__ */ jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: handleAction, children: actionLabel }) })
|
|
4831
4996
|
] }),
|
|
4832
4997
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 flex-shrink-0", children: [
|
|
4833
4998
|
badge !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", size: "sm", children: badge }),
|
|
@@ -4835,7 +5000,7 @@ var Toast = ({
|
|
|
4835
5000
|
"button",
|
|
4836
5001
|
{
|
|
4837
5002
|
type: "button",
|
|
4838
|
-
onClick:
|
|
5003
|
+
onClick: handleDismiss,
|
|
4839
5004
|
className: cn(
|
|
4840
5005
|
"flex-shrink-0 p-1 transition-colors rounded-[var(--radius-sm)]",
|
|
4841
5006
|
"hover:bg-[var(--color-muted)]",
|
|
@@ -4982,8 +5147,10 @@ var Drawer = ({
|
|
|
4982
5147
|
showCloseButton = true,
|
|
4983
5148
|
closeOnOverlayClick = true,
|
|
4984
5149
|
closeOnEscape = true,
|
|
4985
|
-
className
|
|
5150
|
+
className,
|
|
5151
|
+
closeEvent
|
|
4986
5152
|
}) => {
|
|
5153
|
+
const eventBus = useEventBus();
|
|
4987
5154
|
const drawerRef = useRef(null);
|
|
4988
5155
|
const previousActiveElement = useRef(null);
|
|
4989
5156
|
useEffect(() => {
|
|
@@ -5002,12 +5169,13 @@ var Drawer = ({
|
|
|
5002
5169
|
if (!isOpen || !closeOnEscape) return;
|
|
5003
5170
|
const handleEscape = (e) => {
|
|
5004
5171
|
if (e.key === "Escape") {
|
|
5172
|
+
if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
|
|
5005
5173
|
onClose();
|
|
5006
5174
|
}
|
|
5007
5175
|
};
|
|
5008
5176
|
document.addEventListener("keydown", handleEscape);
|
|
5009
5177
|
return () => document.removeEventListener("keydown", handleEscape);
|
|
5010
|
-
}, [isOpen, closeOnEscape, onClose]);
|
|
5178
|
+
}, [isOpen, closeOnEscape, onClose, closeEvent, eventBus]);
|
|
5011
5179
|
useEffect(() => {
|
|
5012
5180
|
if (isOpen) {
|
|
5013
5181
|
document.body.style.overflow = "hidden";
|
|
@@ -5019,9 +5187,13 @@ var Drawer = ({
|
|
|
5019
5187
|
};
|
|
5020
5188
|
}, [isOpen]);
|
|
5021
5189
|
if (!isOpen) return null;
|
|
5190
|
+
const handleClose = () => {
|
|
5191
|
+
if (closeEvent) eventBus.emit(`UI:${closeEvent}`, {});
|
|
5192
|
+
onClose();
|
|
5193
|
+
};
|
|
5022
5194
|
const handleOverlayClick = (e) => {
|
|
5023
5195
|
if (closeOnOverlayClick && e.target === e.currentTarget) {
|
|
5024
|
-
|
|
5196
|
+
handleClose();
|
|
5025
5197
|
}
|
|
5026
5198
|
};
|
|
5027
5199
|
const widthClass = width in sizeWidths ? sizeWidths[width] : "";
|
|
@@ -5070,7 +5242,7 @@ var Drawer = ({
|
|
|
5070
5242
|
"button",
|
|
5071
5243
|
{
|
|
5072
5244
|
type: "button",
|
|
5073
|
-
onClick:
|
|
5245
|
+
onClick: handleClose,
|
|
5074
5246
|
className: cn(
|
|
5075
5247
|
"p-1 transition-colors rounded-[var(--radius-sm)]",
|
|
5076
5248
|
"hover:bg-[var(--color-muted)]",
|
|
@@ -5130,13 +5302,16 @@ var WizardProgress = ({
|
|
|
5130
5302
|
onStepClick,
|
|
5131
5303
|
allowNavigation = true,
|
|
5132
5304
|
compact = false,
|
|
5133
|
-
className
|
|
5305
|
+
className,
|
|
5306
|
+
stepClickEvent
|
|
5134
5307
|
}) => {
|
|
5308
|
+
const eventBus = useEventBus();
|
|
5135
5309
|
const totalSteps = steps.length;
|
|
5136
5310
|
const handleStepClick = (index) => {
|
|
5137
5311
|
const isCompleted = index < currentStep;
|
|
5138
|
-
if (isCompleted && allowNavigation
|
|
5139
|
-
|
|
5312
|
+
if (isCompleted && allowNavigation) {
|
|
5313
|
+
if (stepClickEvent) eventBus.emit(`UI:${stepClickEvent}`, { stepIndex: index });
|
|
5314
|
+
onStepClick?.(index);
|
|
5140
5315
|
}
|
|
5141
5316
|
};
|
|
5142
5317
|
return /* @__PURE__ */ jsx(
|
|
@@ -10035,6 +10210,11 @@ function IsometricCanvas({
|
|
|
10035
10210
|
onUnitClick,
|
|
10036
10211
|
onTileHover,
|
|
10037
10212
|
onTileLeave,
|
|
10213
|
+
// Declarative event props
|
|
10214
|
+
tileClickEvent,
|
|
10215
|
+
unitClickEvent,
|
|
10216
|
+
tileHoverEvent,
|
|
10217
|
+
tileLeaveEvent,
|
|
10038
10218
|
// Rendering options
|
|
10039
10219
|
scale = 0.4,
|
|
10040
10220
|
debug: debug2 = false,
|
|
@@ -10054,6 +10234,7 @@ function IsometricCanvas({
|
|
|
10054
10234
|
assetBaseUrl,
|
|
10055
10235
|
assetManifest
|
|
10056
10236
|
}) {
|
|
10237
|
+
const eventBus = useEventBus();
|
|
10057
10238
|
const canvasRef = useRef(null);
|
|
10058
10239
|
const containerRef = useRef(null);
|
|
10059
10240
|
const minimapRef = useRef(null);
|
|
@@ -10590,20 +10771,22 @@ function IsometricCanvas({
|
|
|
10590
10771
|
const wasPanning = handleMouseMove(e, () => draw(animTimeRef.current));
|
|
10591
10772
|
if (wasPanning) return;
|
|
10592
10773
|
}
|
|
10593
|
-
if (!onTileHover || !canvasRef.current) return;
|
|
10774
|
+
if (!onTileHover && !tileHoverEvent || !canvasRef.current) return;
|
|
10594
10775
|
const world = screenToWorld(e.clientX, e.clientY, canvasRef.current, viewportSize);
|
|
10595
10776
|
const adjustedX = world.x - scaledTileWidth / 2;
|
|
10596
10777
|
const adjustedY = world.y - (scaledTileHeight - scaledFloorHeight) - scaledFloorHeight / 2;
|
|
10597
10778
|
const isoPos = screenToIso(adjustedX, adjustedY, scale, baseOffsetX);
|
|
10598
10779
|
const tileExists = tilesProp.some((t) => t.x === isoPos.x && t.y === isoPos.y);
|
|
10599
10780
|
if (tileExists) {
|
|
10600
|
-
|
|
10781
|
+
if (tileHoverEvent) eventBus.emit(`UI:${tileHoverEvent}`, { x: isoPos.x, y: isoPos.y });
|
|
10782
|
+
onTileHover?.(isoPos.x, isoPos.y);
|
|
10601
10783
|
}
|
|
10602
|
-
}, [enableCamera, handleMouseMove, draw, onTileHover, screenToWorld, viewportSize, scaledTileWidth, scaledTileHeight, scaledFloorHeight, scale, baseOffsetX, tilesProp]);
|
|
10784
|
+
}, [enableCamera, handleMouseMove, draw, onTileHover, screenToWorld, viewportSize, scaledTileWidth, scaledTileHeight, scaledFloorHeight, scale, baseOffsetX, tilesProp, tileHoverEvent, eventBus]);
|
|
10603
10785
|
const handleMouseLeaveWithCamera = useCallback(() => {
|
|
10604
10786
|
handleMouseLeave();
|
|
10787
|
+
if (tileLeaveEvent) eventBus.emit(`UI:${tileLeaveEvent}`, {});
|
|
10605
10788
|
onTileLeave?.();
|
|
10606
|
-
}, [handleMouseLeave, onTileLeave]);
|
|
10789
|
+
}, [handleMouseLeave, onTileLeave, tileLeaveEvent, eventBus]);
|
|
10607
10790
|
const handleWheelWithCamera = useCallback((e) => {
|
|
10608
10791
|
if (enableCamera) {
|
|
10609
10792
|
handleWheel(e, () => draw(animTimeRef.current));
|
|
@@ -10617,15 +10800,17 @@ function IsometricCanvas({
|
|
|
10617
10800
|
const adjustedY = world.y - (scaledTileHeight - scaledFloorHeight) - scaledFloorHeight / 2;
|
|
10618
10801
|
const isoPos = screenToIso(adjustedX, adjustedY, scale, baseOffsetX);
|
|
10619
10802
|
const clickedUnit = units.find((u) => u.position.x === isoPos.x && u.position.y === isoPos.y);
|
|
10620
|
-
if (clickedUnit && onUnitClick) {
|
|
10621
|
-
|
|
10622
|
-
|
|
10803
|
+
if (clickedUnit && (onUnitClick || unitClickEvent)) {
|
|
10804
|
+
if (unitClickEvent) eventBus.emit(`UI:${unitClickEvent}`, { unitId: clickedUnit.id });
|
|
10805
|
+
onUnitClick?.(clickedUnit.id);
|
|
10806
|
+
} else if (onTileClick || tileClickEvent) {
|
|
10623
10807
|
const tileExists = tilesProp.some((t) => t.x === isoPos.x && t.y === isoPos.y);
|
|
10624
10808
|
if (tileExists) {
|
|
10625
|
-
|
|
10809
|
+
if (tileClickEvent) eventBus.emit(`UI:${tileClickEvent}`, { x: isoPos.x, y: isoPos.y });
|
|
10810
|
+
onTileClick?.(isoPos.x, isoPos.y);
|
|
10626
10811
|
}
|
|
10627
10812
|
}
|
|
10628
|
-
}, [dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledTileHeight, scaledFloorHeight, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick]);
|
|
10813
|
+
}, [dragDistance, screenToWorld, viewportSize, scaledTileWidth, scaledTileHeight, scaledFloorHeight, scale, baseOffsetX, units, tilesProp, onUnitClick, onTileClick, unitClickEvent, tileClickEvent, eventBus]);
|
|
10629
10814
|
if (error) {
|
|
10630
10815
|
return /* @__PURE__ */ jsx(ErrorState, { title: "Canvas Error", message: error.message, className });
|
|
10631
10816
|
}
|
|
@@ -11897,10 +12082,17 @@ function EmojiEffect({
|
|
|
11897
12082
|
);
|
|
11898
12083
|
}
|
|
11899
12084
|
function CanvasEffect(props) {
|
|
12085
|
+
const eventBus = useEventBus();
|
|
12086
|
+
const { completeEvent, onComplete, ...rest } = props;
|
|
12087
|
+
const handleComplete = useCallback(() => {
|
|
12088
|
+
if (completeEvent) eventBus.emit(`UI:${completeEvent}`, {});
|
|
12089
|
+
onComplete?.();
|
|
12090
|
+
}, [completeEvent, eventBus, onComplete]);
|
|
12091
|
+
const enhancedProps = { ...rest, onComplete: handleComplete };
|
|
11900
12092
|
if (props.assetManifest) {
|
|
11901
|
-
return /* @__PURE__ */ jsx(CanvasEffectEngine, { ...
|
|
12093
|
+
return /* @__PURE__ */ jsx(CanvasEffectEngine, { ...enhancedProps, assetManifest: props.assetManifest });
|
|
11902
12094
|
}
|
|
11903
|
-
return /* @__PURE__ */ jsx(EmojiEffect, { ...
|
|
12095
|
+
return /* @__PURE__ */ jsx(EmojiEffect, { ...enhancedProps });
|
|
11904
12096
|
}
|
|
11905
12097
|
CanvasEffect.displayName = "CanvasEffect";
|
|
11906
12098
|
|
|
@@ -12465,10 +12657,14 @@ function InventoryPanel({
|
|
|
12465
12657
|
onSelectSlot,
|
|
12466
12658
|
onUseItem,
|
|
12467
12659
|
onDropItem,
|
|
12660
|
+
selectSlotEvent,
|
|
12661
|
+
useItemEvent,
|
|
12662
|
+
dropItemEvent,
|
|
12468
12663
|
showTooltips = true,
|
|
12469
12664
|
className,
|
|
12470
12665
|
slotSize = 48
|
|
12471
12666
|
}) {
|
|
12667
|
+
const eventBus = useEventBus();
|
|
12472
12668
|
const [hoveredSlot, setHoveredSlot] = useState(null);
|
|
12473
12669
|
const [tooltipPosition, setTooltipPosition] = useState({ x: 0, y: 0 });
|
|
12474
12670
|
const slotArray = Array.from({ length: slots }, (_, index) => {
|
|
@@ -12476,49 +12672,53 @@ function InventoryPanel({
|
|
|
12476
12672
|
});
|
|
12477
12673
|
const rows = Math.ceil(slots / columns);
|
|
12478
12674
|
const handleSlotClick = useCallback((index) => {
|
|
12479
|
-
|
|
12480
|
-
|
|
12675
|
+
if (selectSlotEvent) eventBus.emit(`UI:${selectSlotEvent}`, { index });
|
|
12676
|
+
onSelectSlot?.(index);
|
|
12677
|
+
}, [onSelectSlot, selectSlotEvent, eventBus]);
|
|
12481
12678
|
const handleSlotDoubleClick = useCallback((index) => {
|
|
12482
12679
|
const item = slotArray[index];
|
|
12483
|
-
if (item
|
|
12484
|
-
|
|
12680
|
+
if (item) {
|
|
12681
|
+
if (useItemEvent) eventBus.emit(`UI:${useItemEvent}`, { item });
|
|
12682
|
+
onUseItem?.(item);
|
|
12485
12683
|
}
|
|
12486
|
-
}, [slotArray, onUseItem]);
|
|
12684
|
+
}, [slotArray, onUseItem, useItemEvent, eventBus]);
|
|
12487
12685
|
const handleKeyDown = useCallback((e, index) => {
|
|
12488
12686
|
const item = slotArray[index];
|
|
12489
12687
|
switch (e.key) {
|
|
12490
12688
|
case "Enter":
|
|
12491
12689
|
case " ":
|
|
12492
|
-
if (item
|
|
12690
|
+
if (item) {
|
|
12493
12691
|
e.preventDefault();
|
|
12494
|
-
|
|
12692
|
+
if (useItemEvent) eventBus.emit(`UI:${useItemEvent}`, { item });
|
|
12693
|
+
onUseItem?.(item);
|
|
12495
12694
|
}
|
|
12496
12695
|
break;
|
|
12497
12696
|
case "Delete":
|
|
12498
12697
|
case "Backspace":
|
|
12499
|
-
if (item
|
|
12698
|
+
if (item) {
|
|
12500
12699
|
e.preventDefault();
|
|
12501
|
-
|
|
12700
|
+
if (dropItemEvent) eventBus.emit(`UI:${dropItemEvent}`, { item });
|
|
12701
|
+
onDropItem?.(item);
|
|
12502
12702
|
}
|
|
12503
12703
|
break;
|
|
12504
12704
|
case "ArrowRight":
|
|
12505
12705
|
e.preventDefault();
|
|
12506
|
-
onSelectSlot(Math.min(index + 1, slots - 1));
|
|
12706
|
+
onSelectSlot?.(Math.min(index + 1, slots - 1));
|
|
12507
12707
|
break;
|
|
12508
12708
|
case "ArrowLeft":
|
|
12509
12709
|
e.preventDefault();
|
|
12510
|
-
onSelectSlot(Math.max(index - 1, 0));
|
|
12710
|
+
onSelectSlot?.(Math.max(index - 1, 0));
|
|
12511
12711
|
break;
|
|
12512
12712
|
case "ArrowDown":
|
|
12513
12713
|
e.preventDefault();
|
|
12514
|
-
onSelectSlot(Math.min(index + columns, slots - 1));
|
|
12714
|
+
onSelectSlot?.(Math.min(index + columns, slots - 1));
|
|
12515
12715
|
break;
|
|
12516
12716
|
case "ArrowUp":
|
|
12517
12717
|
e.preventDefault();
|
|
12518
|
-
onSelectSlot(Math.max(index - columns, 0));
|
|
12718
|
+
onSelectSlot?.(Math.max(index - columns, 0));
|
|
12519
12719
|
break;
|
|
12520
12720
|
}
|
|
12521
|
-
}, [slotArray, onUseItem, onDropItem, onSelectSlot, columns, slots]);
|
|
12721
|
+
}, [slotArray, onUseItem, onDropItem, onSelectSlot, columns, slots, useItemEvent, dropItemEvent, eventBus]);
|
|
12522
12722
|
const handleMouseEnter = useCallback((e, index) => {
|
|
12523
12723
|
if (showTooltips && slotArray[index]) {
|
|
12524
12724
|
setHoveredSlot(index);
|
|
@@ -12604,8 +12804,12 @@ function DialogueBox({
|
|
|
12604
12804
|
onComplete,
|
|
12605
12805
|
onChoice,
|
|
12606
12806
|
onAdvance,
|
|
12807
|
+
completeEvent,
|
|
12808
|
+
choiceEvent,
|
|
12809
|
+
advanceEvent,
|
|
12607
12810
|
className
|
|
12608
12811
|
}) {
|
|
12812
|
+
const eventBus = useEventBus();
|
|
12609
12813
|
const [displayedText, setDisplayedText] = useState("");
|
|
12610
12814
|
const [isTyping, setIsTyping] = useState(false);
|
|
12611
12815
|
const [selectedChoice, setSelectedChoice] = useState(0);
|
|
@@ -12620,6 +12824,7 @@ function DialogueBox({
|
|
|
12620
12824
|
if (typewriterSpeed === 0) {
|
|
12621
12825
|
setDisplayedText(dialogue.text);
|
|
12622
12826
|
setIsTyping(false);
|
|
12827
|
+
if (completeEvent) eventBus.emit(`UI:${completeEvent}`, {});
|
|
12623
12828
|
onComplete?.();
|
|
12624
12829
|
} else {
|
|
12625
12830
|
setIsTyping(true);
|
|
@@ -12639,9 +12844,11 @@ function DialogueBox({
|
|
|
12639
12844
|
} else {
|
|
12640
12845
|
setIsTyping(false);
|
|
12641
12846
|
clearInterval(interval);
|
|
12847
|
+
if (completeEvent) eventBus.emit(`UI:${completeEvent}`, {});
|
|
12642
12848
|
onComplete?.();
|
|
12643
12849
|
if (dialogue.autoAdvance && !dialogue.choices?.length) {
|
|
12644
12850
|
autoAdvanceTimerRef.current = setTimeout(() => {
|
|
12851
|
+
if (advanceEvent) eventBus.emit(`UI:${advanceEvent}`, {});
|
|
12645
12852
|
onAdvance?.();
|
|
12646
12853
|
}, dialogue.autoAdvance);
|
|
12647
12854
|
}
|
|
@@ -12654,16 +12861,18 @@ function DialogueBox({
|
|
|
12654
12861
|
charIndexRef.current = textRef.current.length;
|
|
12655
12862
|
setDisplayedText(textRef.current);
|
|
12656
12863
|
setIsTyping(false);
|
|
12864
|
+
if (completeEvent) eventBus.emit(`UI:${completeEvent}`, {});
|
|
12657
12865
|
onComplete?.();
|
|
12658
12866
|
}
|
|
12659
|
-
}, [isTyping, onComplete]);
|
|
12867
|
+
}, [isTyping, onComplete, completeEvent, eventBus]);
|
|
12660
12868
|
const handleClick = useCallback(() => {
|
|
12661
12869
|
if (isTyping) {
|
|
12662
12870
|
skipTypewriter();
|
|
12663
12871
|
} else if (!dialogue.choices?.length) {
|
|
12872
|
+
if (advanceEvent) eventBus.emit(`UI:${advanceEvent}`, {});
|
|
12664
12873
|
onAdvance?.();
|
|
12665
12874
|
}
|
|
12666
|
-
}, [isTyping, skipTypewriter, dialogue.choices, onAdvance]);
|
|
12875
|
+
}, [isTyping, skipTypewriter, dialogue.choices, onAdvance, advanceEvent, eventBus]);
|
|
12667
12876
|
const handleKeyDown = useCallback((e) => {
|
|
12668
12877
|
if (isTyping) {
|
|
12669
12878
|
if (e.key === " " || e.key === "Enter") {
|
|
@@ -12688,6 +12897,7 @@ function DialogueBox({
|
|
|
12688
12897
|
e.preventDefault();
|
|
12689
12898
|
const choice = enabledChoices2[selectedChoice];
|
|
12690
12899
|
if (choice) {
|
|
12900
|
+
if (choiceEvent) eventBus.emit(`UI:${choiceEvent}`, { choice });
|
|
12691
12901
|
onChoice?.(choice);
|
|
12692
12902
|
}
|
|
12693
12903
|
break;
|
|
@@ -12698,6 +12908,7 @@ function DialogueBox({
|
|
|
12698
12908
|
const choiceIndex = parseInt(e.key) - 1;
|
|
12699
12909
|
if (choiceIndex < enabledChoices2.length) {
|
|
12700
12910
|
e.preventDefault();
|
|
12911
|
+
if (choiceEvent) eventBus.emit(`UI:${choiceEvent}`, { choice: enabledChoices2[choiceIndex] });
|
|
12701
12912
|
onChoice?.(enabledChoices2[choiceIndex]);
|
|
12702
12913
|
}
|
|
12703
12914
|
break;
|
|
@@ -12705,10 +12916,11 @@ function DialogueBox({
|
|
|
12705
12916
|
} else {
|
|
12706
12917
|
if (e.key === " " || e.key === "Enter") {
|
|
12707
12918
|
e.preventDefault();
|
|
12919
|
+
if (advanceEvent) eventBus.emit(`UI:${advanceEvent}`, {});
|
|
12708
12920
|
onAdvance?.();
|
|
12709
12921
|
}
|
|
12710
12922
|
}
|
|
12711
|
-
}, [isTyping, skipTypewriter, dialogue.choices, selectedChoice, onChoice, onAdvance]);
|
|
12923
|
+
}, [isTyping, skipTypewriter, dialogue.choices, selectedChoice, onChoice, onAdvance, choiceEvent, advanceEvent, eventBus]);
|
|
12712
12924
|
const enabledChoices = dialogue.choices?.filter((c) => !c.disabled) ?? [];
|
|
12713
12925
|
return /* @__PURE__ */ jsx(
|
|
12714
12926
|
"div",
|
|
@@ -12750,6 +12962,7 @@ function DialogueBox({
|
|
|
12750
12962
|
),
|
|
12751
12963
|
onClick: (e) => {
|
|
12752
12964
|
e.stopPropagation();
|
|
12965
|
+
if (choiceEvent) eventBus.emit(`UI:${choiceEvent}`, { choice });
|
|
12753
12966
|
onChoice?.(choice);
|
|
12754
12967
|
},
|
|
12755
12968
|
children: [
|