@almadar/ui 2.1.5 → 2.1.8
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.
|
@@ -14,8 +14,8 @@ import ReactMarkdown from 'react-markdown';
|
|
|
14
14
|
import remarkGfm from 'remark-gfm';
|
|
15
15
|
import remarkMath from 'remark-math';
|
|
16
16
|
import rehypeKatex from 'rehype-katex';
|
|
17
|
-
import
|
|
18
|
-
import
|
|
17
|
+
import SyntaxHighlighter from 'react-syntax-highlighter/dist/cjs/prism';
|
|
18
|
+
import dark from 'react-syntax-highlighter/dist/cjs/styles/prism/vsc-dark-plus';
|
|
19
19
|
|
|
20
20
|
var variantStyles = {
|
|
21
21
|
primary: [
|
|
@@ -808,6 +808,7 @@ var Box = React41__default.forwardRef(
|
|
|
808
808
|
const eventBus = useEventBus();
|
|
809
809
|
const handleClick = useCallback((e) => {
|
|
810
810
|
if (action) {
|
|
811
|
+
e.stopPropagation();
|
|
811
812
|
eventBus.emit(`UI:${action}`, actionPayload ?? {});
|
|
812
813
|
}
|
|
813
814
|
onClick?.(e);
|
|
@@ -4094,6 +4095,7 @@ var Menu2 = ({
|
|
|
4094
4095
|
className
|
|
4095
4096
|
}) => {
|
|
4096
4097
|
const eventBus = useEventBus();
|
|
4098
|
+
const { t } = useTranslate();
|
|
4097
4099
|
const [isOpen, setIsOpen] = useState(false);
|
|
4098
4100
|
const [activeSubMenu, setActiveSubMenu] = useState(null);
|
|
4099
4101
|
const [triggerRect, setTriggerRect] = useState(null);
|
|
@@ -4172,6 +4174,7 @@ var Menu2 = ({
|
|
|
4172
4174
|
onClick: () => handleItemClick({ ...item, id: itemId }),
|
|
4173
4175
|
disabled: item.disabled,
|
|
4174
4176
|
onMouseEnter: () => hasSubMenu && setActiveSubMenu(itemId),
|
|
4177
|
+
"data-testid": item.event ? `action-${item.event}` : void 0,
|
|
4175
4178
|
className: cn(
|
|
4176
4179
|
"w-full flex items-center justify-between gap-3 px-4 py-2 text-left",
|
|
4177
4180
|
"text-sm transition-colors",
|
|
@@ -5904,11 +5907,11 @@ var CodeBlock = React41__default.memo(
|
|
|
5904
5907
|
padding: "1rem"
|
|
5905
5908
|
},
|
|
5906
5909
|
children: /* @__PURE__ */ jsx(
|
|
5907
|
-
|
|
5910
|
+
SyntaxHighlighter,
|
|
5908
5911
|
{
|
|
5909
5912
|
PreTag: "div",
|
|
5910
5913
|
language,
|
|
5911
|
-
style:
|
|
5914
|
+
style: dark,
|
|
5912
5915
|
customStyle: {
|
|
5913
5916
|
backgroundColor: "transparent",
|
|
5914
5917
|
borderRadius: 0,
|
|
@@ -7000,6 +7003,7 @@ var StatCard = ({
|
|
|
7000
7003
|
variant: "ghost",
|
|
7001
7004
|
onClick: handleActionClick,
|
|
7002
7005
|
className: "mt-4 text-sm font-bold text-[var(--color-foreground)] hover:underline",
|
|
7006
|
+
"data-testid": action.event ? `action-${action.event}` : void 0,
|
|
7003
7007
|
children: [
|
|
7004
7008
|
action.label,
|
|
7005
7009
|
" \u2192"
|
|
@@ -7208,13 +7212,14 @@ var DetailPanel = ({
|
|
|
7208
7212
|
error
|
|
7209
7213
|
}) => {
|
|
7210
7214
|
const eventBus = useEventBus();
|
|
7215
|
+
const { t } = useTranslate();
|
|
7211
7216
|
const isFieldDefArray = (arr) => {
|
|
7212
7217
|
if (!arr || arr.length === 0) return false;
|
|
7213
7218
|
const first = arr[0];
|
|
7214
7219
|
return typeof first === "string" || typeof first === "object" && first !== null && "key" in first;
|
|
7215
7220
|
};
|
|
7216
7221
|
const effectiveFieldNames = isFieldDefArray(propFields) ? normalizeFieldDefs(propFields) : fieldNames;
|
|
7217
|
-
|
|
7222
|
+
useCallback(
|
|
7218
7223
|
(action, data2) => {
|
|
7219
7224
|
if (action.navigatesTo) {
|
|
7220
7225
|
const url = action.navigatesTo.replace(
|
|
@@ -7359,9 +7364,9 @@ var DetailPanel = ({
|
|
|
7359
7364
|
return /* @__PURE__ */ jsx(
|
|
7360
7365
|
ErrorState,
|
|
7361
7366
|
{
|
|
7362
|
-
title: "
|
|
7363
|
-
message: error.message || "
|
|
7364
|
-
|
|
7367
|
+
title: t("error.loadingData"),
|
|
7368
|
+
message: error.message || t("error.genericLoad"),
|
|
7369
|
+
retryEvent: "RETRY",
|
|
7365
7370
|
className
|
|
7366
7371
|
}
|
|
7367
7372
|
);
|
|
@@ -7424,8 +7429,10 @@ var DetailPanel = ({
|
|
|
7424
7429
|
Button,
|
|
7425
7430
|
{
|
|
7426
7431
|
variant: action.variant || "secondary",
|
|
7427
|
-
|
|
7432
|
+
action: action.event,
|
|
7433
|
+
actionPayload: { row: normalizedData },
|
|
7428
7434
|
icon: action.icon,
|
|
7435
|
+
"data-testid": action.event ? `action-${action.event}` : void 0,
|
|
7429
7436
|
children: action.label
|
|
7430
7437
|
},
|
|
7431
7438
|
idx
|
|
@@ -8062,6 +8069,7 @@ var CardGrid = ({
|
|
|
8062
8069
|
showTotal = true
|
|
8063
8070
|
}) => {
|
|
8064
8071
|
const eventBus = useEventBus();
|
|
8072
|
+
const { t } = useTranslate();
|
|
8065
8073
|
const effectiveFieldNames = normalizeFields(fields).length > 0 ? normalizeFields(fields) : fieldNames ?? normalizeFields(columns);
|
|
8066
8074
|
const gridTemplateColumns = `repeat(auto-fit, minmax(min(${minCardWidth}px, 100%), 1fr))`;
|
|
8067
8075
|
const normalizedData = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
@@ -8070,9 +8078,6 @@ var CardGrid = ({
|
|
|
8070
8078
|
const handlePageChange = (newPage) => {
|
|
8071
8079
|
eventBus.emit("UI:PAGINATE", { page: newPage, pageSize });
|
|
8072
8080
|
};
|
|
8073
|
-
const handleCardClick = (itemData) => {
|
|
8074
|
-
eventBus.emit("UI:VIEW", { row: itemData });
|
|
8075
|
-
};
|
|
8076
8081
|
const renderContent = () => {
|
|
8077
8082
|
if (children) {
|
|
8078
8083
|
return children;
|
|
@@ -8117,7 +8122,8 @@ var CardGrid = ({
|
|
|
8117
8122
|
"bg-[var(--color-card)] rounded-[var(--radius-lg)] border border-[var(--color-border)] p-4 shadow-[var(--shadow-sm)]",
|
|
8118
8123
|
"cursor-pointer hover:border-[var(--color-primary)] transition-colors"
|
|
8119
8124
|
),
|
|
8120
|
-
|
|
8125
|
+
action: "VIEW",
|
|
8126
|
+
actionPayload: { row: itemData },
|
|
8121
8127
|
children: [
|
|
8122
8128
|
cardFields.map((field) => {
|
|
8123
8129
|
const value = getNestedValue(itemData, field);
|
|
@@ -8135,6 +8141,7 @@ var CardGrid = ({
|
|
|
8135
8141
|
variant: buttonVariant,
|
|
8136
8142
|
size: "sm",
|
|
8137
8143
|
onClick: handleActionClick(action),
|
|
8144
|
+
"data-testid": action.event ? `action-${action.event}` : void 0,
|
|
8138
8145
|
children: action.label
|
|
8139
8146
|
},
|
|
8140
8147
|
actionIdx
|
|
@@ -9227,11 +9234,26 @@ function UISlotComponent({
|
|
|
9227
9234
|
slot,
|
|
9228
9235
|
portal = false,
|
|
9229
9236
|
position,
|
|
9230
|
-
className
|
|
9237
|
+
className,
|
|
9238
|
+
children,
|
|
9239
|
+
pattern,
|
|
9240
|
+
sourceTrait
|
|
9231
9241
|
}) {
|
|
9232
9242
|
const { slots, clear } = useUISlots();
|
|
9233
9243
|
const suspenseConfig = useContext(SuspenseConfigContext);
|
|
9234
9244
|
const content = slots[slot];
|
|
9245
|
+
if (children !== void 0) {
|
|
9246
|
+
return /* @__PURE__ */ jsx(
|
|
9247
|
+
Box,
|
|
9248
|
+
{
|
|
9249
|
+
id: `slot-${slot}`,
|
|
9250
|
+
className: cn("ui-slot", `ui-slot-${slot}`, className),
|
|
9251
|
+
"data-pattern": pattern,
|
|
9252
|
+
"data-source-trait": sourceTrait,
|
|
9253
|
+
children
|
|
9254
|
+
}
|
|
9255
|
+
);
|
|
9256
|
+
}
|
|
9235
9257
|
if (!content) {
|
|
9236
9258
|
if (!portal) {
|
|
9237
9259
|
return /* @__PURE__ */ jsx(
|
|
@@ -2809,10 +2809,16 @@ interface DetailPanelProps extends EntityDisplayProps {
|
|
|
2809
2809
|
position?: "left" | "right";
|
|
2810
2810
|
/** Panel width (CSS value, e.g., '400px', '50%') */
|
|
2811
2811
|
width?: string;
|
|
2812
|
+
/** Entity ID for fetching specific entity */
|
|
2813
|
+
entityId?: string;
|
|
2814
|
+
/** Display fields (alias for fields) */
|
|
2815
|
+
displayFields?: readonly string[];
|
|
2816
|
+
/** Show actions flag */
|
|
2817
|
+
showActions?: boolean;
|
|
2812
2818
|
}
|
|
2813
2819
|
declare const DetailPanel: React__default.FC<DetailPanelProps>;
|
|
2814
2820
|
|
|
2815
|
-
interface FormSectionProps {
|
|
2821
|
+
interface FormSectionProps extends EntityDisplayProps {
|
|
2816
2822
|
/** Section title */
|
|
2817
2823
|
title?: string;
|
|
2818
2824
|
/** Section description */
|
|
@@ -2827,47 +2833,28 @@ interface FormSectionProps {
|
|
|
2827
2833
|
card?: boolean;
|
|
2828
2834
|
/** Grid columns for fields */
|
|
2829
2835
|
columns?: 1 | 2 | 3;
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
isLoading?: boolean;
|
|
2833
|
-
/** Error state */
|
|
2834
|
-
error?: Error | null;
|
|
2835
|
-
/** Entity name */
|
|
2836
|
-
entity?: string;
|
|
2836
|
+
/** Entity ID for fetching specific entity */
|
|
2837
|
+
entityId?: string;
|
|
2837
2838
|
}
|
|
2838
2839
|
declare const FormSection$1: React__default.FC<FormSectionProps>;
|
|
2839
2840
|
/**
|
|
2840
2841
|
* Form layout with multiple sections
|
|
2841
2842
|
*/
|
|
2842
|
-
interface FormLayoutProps {
|
|
2843
|
+
interface FormLayoutProps extends EntityDisplayProps {
|
|
2843
2844
|
children: React__default.ReactNode;
|
|
2844
2845
|
/** Show section dividers */
|
|
2845
2846
|
dividers?: boolean;
|
|
2846
|
-
className?: string;
|
|
2847
|
-
/** Loading state */
|
|
2848
|
-
isLoading?: boolean;
|
|
2849
|
-
/** Error state */
|
|
2850
|
-
error?: Error | null;
|
|
2851
|
-
/** Entity name */
|
|
2852
|
-
entity?: string;
|
|
2853
2847
|
}
|
|
2854
2848
|
declare const FormLayout: React__default.FC<FormLayoutProps>;
|
|
2855
2849
|
/**
|
|
2856
2850
|
* Form actions bar (submit/cancel buttons)
|
|
2857
2851
|
*/
|
|
2858
|
-
interface FormActionsProps {
|
|
2852
|
+
interface FormActionsProps extends EntityDisplayProps {
|
|
2859
2853
|
children: React__default.ReactNode;
|
|
2860
2854
|
/** Sticky at bottom */
|
|
2861
2855
|
sticky?: boolean;
|
|
2862
2856
|
/** Alignment */
|
|
2863
2857
|
align?: "left" | "right" | "between" | "center";
|
|
2864
|
-
className?: string;
|
|
2865
|
-
/** Loading state */
|
|
2866
|
-
isLoading?: boolean;
|
|
2867
|
-
/** Error state */
|
|
2868
|
-
error?: Error | null;
|
|
2869
|
-
/** Entity name */
|
|
2870
|
-
entity?: string;
|
|
2871
2858
|
}
|
|
2872
2859
|
declare const FormActions: React__default.FC<FormActionsProps>;
|
|
2873
2860
|
|
|
@@ -7183,13 +7170,19 @@ interface UISlotComponentProps {
|
|
|
7183
7170
|
isLoading?: boolean;
|
|
7184
7171
|
error?: Error | null;
|
|
7185
7172
|
entity?: string;
|
|
7173
|
+
/** Compiled mode: render children directly instead of resolving from context */
|
|
7174
|
+
children?: React__default.ReactNode;
|
|
7175
|
+
/** Pattern type for data-pattern attribute (compiled mode) */
|
|
7176
|
+
pattern?: string;
|
|
7177
|
+
/** Source trait name for data-source-trait attribute (compiled mode) */
|
|
7178
|
+
sourceTrait?: string;
|
|
7186
7179
|
}
|
|
7187
7180
|
/**
|
|
7188
7181
|
* Individual slot renderer.
|
|
7189
7182
|
*
|
|
7190
7183
|
* Handles different slot types with appropriate wrappers.
|
|
7191
7184
|
*/
|
|
7192
|
-
declare function UISlotComponent({ slot, portal, position, className, }: UISlotComponentProps): React__default.ReactElement | null;
|
|
7185
|
+
declare function UISlotComponent({ slot, portal, position, className, children, pattern, sourceTrait, }: UISlotComponentProps): React__default.ReactElement | null;
|
|
7193
7186
|
interface SlotContentRendererProps {
|
|
7194
7187
|
content: SlotContent;
|
|
7195
7188
|
onDismiss: () => void;
|
package/dist/components/index.js
CHANGED
|
@@ -2,8 +2,8 @@ import { DEFAULT_CONFIG, renderStateMachineToDomData, parseContentSegments } fro
|
|
|
2
2
|
import { useAuthContext } from '../chunk-6OACETQB.js';
|
|
3
3
|
export { ENTITY_EVENTS, useAgentChat, useAuthContext, useCompile, useConnectGitHub, useCreateEntity, useDeepAgentGeneration, useDeleteEntity, useDisconnectGitHub, useEntities, useEntitiesByType, useEntity as useEntityById, useEntityMutations, useExtensions, useFileEditor, useFileSystem, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useInput, useOrbitalHistory, useOrbitalMutations, usePhysics, usePlayer, usePreview, useResolvedEntity, useSelectedEntity, useSendOrbitalEvent, useSingletonEntity, useUIEvents, useUpdateEntity, useValidation } from '../chunk-6OACETQB.js';
|
|
4
4
|
import '../chunk-3HJHHULT.js';
|
|
5
|
-
import { VStack, HStack, Typography, Button, Icon, Box, Card, Avatar, Badge, SearchInput, Checkbox, Menu as Menu$1, Pagination, LoadingState, EmptyState, Modal, ErrorState, QuizBlock, CodeBlock, ScaledDiagram, MarkdownContent, Divider, ProgressBar, Stack, Select, Drawer, Toast, Tabs, Input, ThemeToggle, HealthBar, ScoreDisplay, StateIndicator, Container
|
|
6
|
-
export { Accordion, Card2 as ActionCard, Alert, Avatar, Badge, Box, Breadcrumb, Button, ButtonGroup, Card, 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, Grid, HStack, Heading, HealthBar, Icon, Input, InputGroup, Label, LawReferenceTooltip, LoadingState, MarkdownContent, MasterDetail, Menu, Modal, Overlay, PageHeader, Pagination, Popover, ProgressBar, QuizBlock, Radio, RelationSelect, RepeatableFormSection, ScaledDiagram, ScoreDisplay, SearchInput, Select, SidePanel, SimpleGrid, Skeleton, SlotContentRenderer, Spacer, Spinner, Sprite, Stack, StatCard, StateIndicator, Switch, Tabs, Text, TextHighlight, Textarea, ThemeSelector, ThemeToggle, Toast, Tooltip, Typography, UISlotComponent, UISlotRenderer, VStack, ViolationAlert, WizardNavigation, WizardProgress, drawSprite } from '../chunk-
|
|
5
|
+
import { VStack, HStack, Typography, Button, Icon, Box, Card, Avatar, Badge, SearchInput, Checkbox, Menu as Menu$1, Pagination, LoadingState, EmptyState, Modal, ErrorState, QuizBlock, CodeBlock, ScaledDiagram, MarkdownContent, Divider, ProgressBar, Stack, Select, Drawer, Toast, Tabs, Input, ThemeToggle, EntityDisplayEvents, HealthBar, ScoreDisplay, StateIndicator, Container } from '../chunk-BS6DAANP.js';
|
|
6
|
+
export { Accordion, Card2 as ActionCard, Alert, Avatar, Badge, Box, Breadcrumb, Button, ButtonGroup, Card, 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, Grid, HStack, Heading, HealthBar, Icon, Input, InputGroup, Label, LawReferenceTooltip, LoadingState, MarkdownContent, MasterDetail, Menu, Modal, Overlay, PageHeader, Pagination, Popover, ProgressBar, QuizBlock, Radio, RelationSelect, RepeatableFormSection, ScaledDiagram, ScoreDisplay, SearchInput, Select, SidePanel, SimpleGrid, Skeleton, SlotContentRenderer, Spacer, Spinner, Sprite, Stack, StatCard, StateIndicator, Switch, Tabs, Text, TextHighlight, Textarea, ThemeSelector, ThemeToggle, Toast, Tooltip, Typography, UISlotComponent, UISlotRenderer, VStack, ViolationAlert, WizardNavigation, WizardProgress, drawSprite } from '../chunk-BS6DAANP.js';
|
|
7
7
|
import '../chunk-BTXQJGFB.js';
|
|
8
8
|
import { cn, getNestedValue } from '../chunk-KKCVDUK7.js';
|
|
9
9
|
export { cn } from '../chunk-KKCVDUK7.js';
|
|
@@ -14,8 +14,8 @@ export { useEmitEvent, useEventBus, useEventListener } from '../chunk-YXZM3WCF.j
|
|
|
14
14
|
export { DEFAULT_SLOTS, useUISlotManager } from '../chunk-7NEWMNNU.js';
|
|
15
15
|
export { clearEntities, getAllEntities, getByType, getEntity, getSingleton, removeEntity, spawnEntity, updateEntity, updateSingleton } from '../chunk-N7MVUW4R.js';
|
|
16
16
|
import { __publicField } from '../chunk-PKBMQBKP.js';
|
|
17
|
-
import * as
|
|
18
|
-
import
|
|
17
|
+
import * as React from 'react';
|
|
18
|
+
import React__default, { createContext, useState, useCallback, useMemo, useEffect, useRef, useContext } from 'react';
|
|
19
19
|
import { ChevronDown, X, Menu, ChevronRight, ChevronLeft, ArrowUp, ArrowDown, MoreVertical, Package, Check, AlertTriangle, Trash2, List as List$1, Printer, CheckCircle, XCircle, Play, RotateCcw, Send, Wrench, Bug, ArrowRight, Pause, SkipForward, Zap, Sword, Move, Heart, Shield, AlertCircle, Circle, Clock, CheckCircle2, Image as Image$1, Upload, ZoomIn, Eraser, FileText, ZoomOut, Download, Code, WrapText, Copy, Settings, Search, Bell, LogOut, Calendar, Pencil, Eye, MoreHorizontal, Minus, Plus } from 'lucide-react';
|
|
20
20
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
21
21
|
import { createPortal } from 'react-dom';
|
|
@@ -31,12 +31,20 @@ var FormSection = ({
|
|
|
31
31
|
columns = 1,
|
|
32
32
|
className
|
|
33
33
|
}) => {
|
|
34
|
-
const [collapsed, setCollapsed] =
|
|
34
|
+
const [collapsed, setCollapsed] = React__default.useState(defaultCollapsed);
|
|
35
|
+
const { t } = useTranslate();
|
|
36
|
+
const eventBus = useEventBus();
|
|
35
37
|
const gridClass = {
|
|
36
38
|
1: "grid-cols-1",
|
|
37
39
|
2: "grid-cols-1 md:grid-cols-2",
|
|
38
40
|
3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
|
|
39
41
|
}[columns];
|
|
42
|
+
React__default.useCallback(() => {
|
|
43
|
+
if (collapsible) {
|
|
44
|
+
setCollapsed((prev) => !prev);
|
|
45
|
+
eventBus.emit("UI:TOGGLE_COLLAPSE", { collapsed: !collapsed });
|
|
46
|
+
}
|
|
47
|
+
}, [collapsible, collapsed, eventBus]);
|
|
40
48
|
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
41
49
|
(title || description) && /* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "mb-4", children: [
|
|
42
50
|
title && /* @__PURE__ */ jsxs(
|
|
@@ -45,7 +53,7 @@ var FormSection = ({
|
|
|
45
53
|
justify: "between",
|
|
46
54
|
align: "center",
|
|
47
55
|
className: cn(collapsible && "cursor-pointer"),
|
|
48
|
-
|
|
56
|
+
action: collapsible ? "TOGGLE_COLLAPSE" : void 0,
|
|
49
57
|
children: [
|
|
50
58
|
/* @__PURE__ */ jsx(Typography, { variant: "h3", weight: "semibold", children: title }),
|
|
51
59
|
collapsible && /* @__PURE__ */ jsx(
|
|
@@ -53,7 +61,7 @@ var FormSection = ({
|
|
|
53
61
|
{
|
|
54
62
|
variant: "ghost",
|
|
55
63
|
size: "sm",
|
|
56
|
-
|
|
64
|
+
action: "TOGGLE_COLLAPSE",
|
|
57
65
|
children: /* @__PURE__ */ jsx(
|
|
58
66
|
Icon,
|
|
59
67
|
{
|
|
@@ -1028,7 +1036,7 @@ var List = ({
|
|
|
1028
1036
|
if (entity && typeof entity === "object" && "id" in entity) return [entity];
|
|
1029
1037
|
return [];
|
|
1030
1038
|
}, [entity]);
|
|
1031
|
-
const getItemActions =
|
|
1039
|
+
const getItemActions = React__default.useCallback(
|
|
1032
1040
|
(item) => {
|
|
1033
1041
|
if (!itemActions) return [];
|
|
1034
1042
|
if (typeof itemActions === "function") {
|
|
@@ -1037,6 +1045,7 @@ var List = ({
|
|
|
1037
1045
|
return itemActions.map((action, idx) => ({
|
|
1038
1046
|
id: `${item.id}-action-${idx}`,
|
|
1039
1047
|
label: action.label,
|
|
1048
|
+
event: action.event,
|
|
1040
1049
|
onClick: () => {
|
|
1041
1050
|
if (action.navigatesTo) {
|
|
1042
1051
|
const url = action.navigatesTo.replace(
|
|
@@ -1117,9 +1126,6 @@ var List = ({
|
|
|
1117
1126
|
eventBus.emit(`UI:${EntityDisplayEvents.DESELECT}`, { ids: newIds });
|
|
1118
1127
|
}
|
|
1119
1128
|
};
|
|
1120
|
-
const handleRowClick = (item) => {
|
|
1121
|
-
eventBus.emit("UI:VIEW", { row: item });
|
|
1122
|
-
};
|
|
1123
1129
|
const defaultRenderItem = (item, index, isLast) => {
|
|
1124
1130
|
const isSelected = selectedIds.map(String).includes(item.id);
|
|
1125
1131
|
const actions = normalizedItemActions ? normalizedItemActions(item) : [];
|
|
@@ -1130,8 +1136,9 @@ var List = ({
|
|
|
1130
1136
|
const editAction = actions.find(
|
|
1131
1137
|
(a) => a.label.toLowerCase().includes("edit")
|
|
1132
1138
|
);
|
|
1133
|
-
const hasExplicitClick = !!(
|
|
1134
|
-
const
|
|
1139
|
+
const hasExplicitClick = !!(viewAction?.event || item.onClick);
|
|
1140
|
+
const rowAction = viewAction?.event ?? "VIEW";
|
|
1141
|
+
const rowActionPayload = { row: item };
|
|
1135
1142
|
const primaryField = effectiveFieldNames?.[0];
|
|
1136
1143
|
const statusField = effectiveFieldNames?.find(
|
|
1137
1144
|
(f) => f.toLowerCase().includes("status")
|
|
@@ -1166,20 +1173,28 @@ var List = ({
|
|
|
1166
1173
|
isSelected && "bg-[var(--color-primary)]/10 shadow-inner",
|
|
1167
1174
|
item.disabled && "opacity-50 cursor-not-allowed grayscale"
|
|
1168
1175
|
),
|
|
1169
|
-
|
|
1176
|
+
action: rowAction,
|
|
1177
|
+
actionPayload: rowActionPayload,
|
|
1170
1178
|
children: [
|
|
1171
|
-
selectable && /* @__PURE__ */ jsx(
|
|
1172
|
-
|
|
1179
|
+
selectable && /* @__PURE__ */ jsx(
|
|
1180
|
+
Box,
|
|
1173
1181
|
{
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1182
|
+
className: "flex-shrink-0 pt-0.5",
|
|
1183
|
+
action: isSelected ? EntityDisplayEvents.DESELECT : EntityDisplayEvents.SELECT,
|
|
1184
|
+
actionPayload: { ids: isSelected ? selectedIds.filter((sid) => String(sid) !== item.id) : [...selectedIds.map(String), item.id] },
|
|
1185
|
+
children: /* @__PURE__ */ jsx(
|
|
1186
|
+
Checkbox,
|
|
1187
|
+
{
|
|
1188
|
+
checked: isSelected,
|
|
1189
|
+
onChange: (e) => handleSelect(item.id, e.target.checked),
|
|
1190
|
+
className: cn(
|
|
1191
|
+
"transition-transform active:scale-95",
|
|
1192
|
+
isSelected ? "border-[var(--color-primary)] bg-[var(--color-primary)]" : "border-[var(--color-border)]"
|
|
1193
|
+
)
|
|
1194
|
+
}
|
|
1180
1195
|
)
|
|
1181
1196
|
}
|
|
1182
|
-
)
|
|
1197
|
+
),
|
|
1183
1198
|
/* @__PURE__ */ jsxs(Box, { className: "flex-1 min-w-0 space-y-2.5", children: [
|
|
1184
1199
|
/* @__PURE__ */ jsxs(HStack, { className: "flex items-center gap-4", children: [
|
|
1185
1200
|
/* @__PURE__ */ jsx(
|
|
@@ -1262,10 +1277,7 @@ var List = ({
|
|
|
1262
1277
|
Button,
|
|
1263
1278
|
{
|
|
1264
1279
|
variant: "ghost",
|
|
1265
|
-
|
|
1266
|
-
e.stopPropagation();
|
|
1267
|
-
editAction.onClick?.();
|
|
1268
|
-
},
|
|
1280
|
+
action: editAction.event,
|
|
1269
1281
|
className: cn(
|
|
1270
1282
|
"p-2 rounded-[var(--radius-lg)] transition-all duration-200",
|
|
1271
1283
|
"hover:bg-[var(--color-primary)]/10 hover:text-[var(--color-primary)]",
|
|
@@ -1273,6 +1285,7 @@ var List = ({
|
|
|
1273
1285
|
"active:scale-95"
|
|
1274
1286
|
),
|
|
1275
1287
|
title: editAction.label,
|
|
1288
|
+
"data-testid": editAction.event ? `action-${editAction.event}` : void 0,
|
|
1276
1289
|
children: /* @__PURE__ */ jsx(Pencil, { className: "w-4 h-4" })
|
|
1277
1290
|
}
|
|
1278
1291
|
),
|
|
@@ -1280,10 +1293,7 @@ var List = ({
|
|
|
1280
1293
|
Button,
|
|
1281
1294
|
{
|
|
1282
1295
|
variant: "ghost",
|
|
1283
|
-
|
|
1284
|
-
e.stopPropagation();
|
|
1285
|
-
viewAction.onClick?.();
|
|
1286
|
-
},
|
|
1296
|
+
action: viewAction.event,
|
|
1287
1297
|
className: cn(
|
|
1288
1298
|
"p-2 rounded-[var(--radius-lg)] transition-all duration-200",
|
|
1289
1299
|
"hover:bg-[var(--color-muted)] hover:text-[var(--color-foreground)]",
|
|
@@ -1291,6 +1301,7 @@ var List = ({
|
|
|
1291
1301
|
"active:scale-95"
|
|
1292
1302
|
),
|
|
1293
1303
|
title: viewAction.label,
|
|
1304
|
+
"data-testid": viewAction.event ? `action-${viewAction.event}` : void 0,
|
|
1294
1305
|
children: /* @__PURE__ */ jsx(Eye, { className: "w-4 h-4" })
|
|
1295
1306
|
}
|
|
1296
1307
|
),
|
|
@@ -1530,7 +1541,7 @@ var WizardContainer = ({
|
|
|
1530
1541
|
const isCompleted = index < currentStep;
|
|
1531
1542
|
const stepKey = step.id ?? step.tabId ?? `step-${index}`;
|
|
1532
1543
|
const stepTitle = step.title ?? step.name ?? `Step ${index + 1}`;
|
|
1533
|
-
return /* @__PURE__ */ jsxs(
|
|
1544
|
+
return /* @__PURE__ */ jsxs(React__default.Fragment, { children: [
|
|
1534
1545
|
/* @__PURE__ */ jsx(
|
|
1535
1546
|
Button,
|
|
1536
1547
|
{
|
|
@@ -2754,7 +2765,7 @@ var StateMachineView = ({
|
|
|
2754
2765
|
style: { top: title ? 30 : 0 },
|
|
2755
2766
|
children: [
|
|
2756
2767
|
entity && /* @__PURE__ */ jsx(EntityBox, { entity, config }),
|
|
2757
|
-
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(
|
|
2768
|
+
states.map((state) => renderStateNode ? /* @__PURE__ */ jsx(React__default.Fragment, { children: renderStateNode(state, config) }, state.id) : /* @__PURE__ */ jsx(
|
|
2758
2769
|
StateNode,
|
|
2759
2770
|
{
|
|
2760
2771
|
state,
|
|
@@ -6769,7 +6780,7 @@ function GameMenu({
|
|
|
6769
6780
|
} catch {
|
|
6770
6781
|
}
|
|
6771
6782
|
const eventBus = eventBusProp || eventBusFromHook;
|
|
6772
|
-
const handleOptionClick =
|
|
6783
|
+
const handleOptionClick = React.useCallback(
|
|
6773
6784
|
(option) => {
|
|
6774
6785
|
if (option.event && eventBus) {
|
|
6775
6786
|
eventBus.emit(`UI:${option.event}`, { option });
|
|
@@ -6892,7 +6903,7 @@ function GameOverScreen({
|
|
|
6892
6903
|
} catch {
|
|
6893
6904
|
}
|
|
6894
6905
|
const eventBus = eventBusProp || eventBusFromHook;
|
|
6895
|
-
const handleActionClick =
|
|
6906
|
+
const handleActionClick = React.useCallback(
|
|
6896
6907
|
(action) => {
|
|
6897
6908
|
if (action.event && eventBus) {
|
|
6898
6909
|
eventBus.emit(`UI:${action.event}`, { action });
|
|
@@ -8159,7 +8170,7 @@ function LinearView({
|
|
|
8159
8170
|
/* @__PURE__ */ jsx(HStack, { className: "flex-wrap items-center", gap: "xs", children: trait.states.map((state, i) => {
|
|
8160
8171
|
const isDone = i < currentIdx;
|
|
8161
8172
|
const isCurrent = i === currentIdx;
|
|
8162
|
-
return /* @__PURE__ */ jsxs(
|
|
8173
|
+
return /* @__PURE__ */ jsxs(React__default.Fragment, { children: [
|
|
8163
8174
|
i > 0 && /* @__PURE__ */ jsx(
|
|
8164
8175
|
Typography,
|
|
8165
8176
|
{
|
|
@@ -8813,7 +8824,7 @@ function SequenceBar({
|
|
|
8813
8824
|
onSlotRemove(index);
|
|
8814
8825
|
}, [onSlotRemove, playing]);
|
|
8815
8826
|
const paddedSlots = Array.from({ length: maxSlots }, (_, i) => slots[i]);
|
|
8816
|
-
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(
|
|
8827
|
+
return /* @__PURE__ */ jsx(HStack, { className: cn("items-center", className), gap: "sm", children: paddedSlots.map((slot, i) => /* @__PURE__ */ jsxs(React__default.Fragment, { children: [
|
|
8817
8828
|
i > 0 && /* @__PURE__ */ jsx(
|
|
8818
8829
|
Typography,
|
|
8819
8830
|
{
|
|
@@ -11113,7 +11124,7 @@ function generateCombatMessage(event) {
|
|
|
11113
11124
|
return event.message;
|
|
11114
11125
|
}
|
|
11115
11126
|
function extractTitle(children) {
|
|
11116
|
-
if (!
|
|
11127
|
+
if (!React__default.isValidElement(children)) return void 0;
|
|
11117
11128
|
const props = children.props;
|
|
11118
11129
|
if (typeof props.title === "string") {
|
|
11119
11130
|
return props.title;
|
|
@@ -11148,7 +11159,7 @@ var ModalSlot = ({
|
|
|
11148
11159
|
};
|
|
11149
11160
|
ModalSlot.displayName = "ModalSlot";
|
|
11150
11161
|
function extractTitle2(children) {
|
|
11151
|
-
if (!
|
|
11162
|
+
if (!React__default.isValidElement(children)) return void 0;
|
|
11152
11163
|
const props = children.props;
|
|
11153
11164
|
if (typeof props.title === "string") {
|
|
11154
11165
|
return props.title;
|
|
@@ -11185,7 +11196,7 @@ var DrawerSlot = ({
|
|
|
11185
11196
|
};
|
|
11186
11197
|
DrawerSlot.displayName = "DrawerSlot";
|
|
11187
11198
|
function extractToastProps(children) {
|
|
11188
|
-
if (!
|
|
11199
|
+
if (!React__default.isValidElement(children)) {
|
|
11189
11200
|
if (typeof children === "string") {
|
|
11190
11201
|
return { message: children };
|
|
11191
11202
|
}
|
|
@@ -11216,7 +11227,7 @@ var ToastSlot = ({
|
|
|
11216
11227
|
eventBus.emit("UI:CLOSE");
|
|
11217
11228
|
};
|
|
11218
11229
|
if (!isVisible) return null;
|
|
11219
|
-
const isCustomContent =
|
|
11230
|
+
const isCustomContent = React__default.isValidElement(children) && !message;
|
|
11220
11231
|
return /* @__PURE__ */ jsx(Box, { className: "fixed bottom-4 right-4 z-50", children: isCustomContent ? children : /* @__PURE__ */ jsx(
|
|
11221
11232
|
Toast,
|
|
11222
11233
|
{
|
|
@@ -11721,7 +11732,7 @@ var Timeline = ({
|
|
|
11721
11732
|
}) => {
|
|
11722
11733
|
const { t } = useTranslate();
|
|
11723
11734
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
11724
|
-
const items =
|
|
11735
|
+
const items = React__default.useMemo(() => {
|
|
11725
11736
|
if (propItems) return propItems;
|
|
11726
11737
|
if (entityData.length === 0) return [];
|
|
11727
11738
|
return entityData.map((record, idx) => {
|
|
@@ -11862,7 +11873,7 @@ var MediaGallery = ({
|
|
|
11862
11873
|
[selectable, selectedItems, selectionEvent, eventBus]
|
|
11863
11874
|
);
|
|
11864
11875
|
const entityData = Array.isArray(entity) ? entity : [];
|
|
11865
|
-
const items =
|
|
11876
|
+
const items = React__default.useMemo(() => {
|
|
11866
11877
|
if (propItems) return propItems;
|
|
11867
11878
|
if (entityData.length === 0) return [];
|
|
11868
11879
|
return entityData.map((record, idx) => ({
|
package/dist/providers/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SuspenseConfigProvider } from '../chunk-
|
|
1
|
+
import { SuspenseConfigProvider } from '../chunk-BS6DAANP.js';
|
|
2
2
|
import { ThemeProvider } from '../chunk-BTXQJGFB.js';
|
|
3
3
|
import { recordTransition, registerCheck, bindEventBus, bindTraitStateGetter } from '../chunk-45CTDYBT.js';
|
|
4
4
|
import '../chunk-KKCVDUK7.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@almadar/ui",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.8",
|
|
4
4
|
"description": "React UI components, hooks, and providers for Almadar",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/components/index.js",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"remark-gfm": "^4.0.0",
|
|
81
81
|
"remark-math": "^6.0.0",
|
|
82
82
|
"rehype-katex": "^7.0.0",
|
|
83
|
-
"react-syntax-highlighter": "^
|
|
83
|
+
"react-syntax-highlighter": "^16.1.0"
|
|
84
84
|
},
|
|
85
85
|
"peerDependencies": {
|
|
86
86
|
"react": ">=18.0.0",
|
|
@@ -117,6 +117,7 @@
|
|
|
117
117
|
"vitest": "^1.4.0",
|
|
118
118
|
"@testing-library/react": "^14.2.0",
|
|
119
119
|
"@testing-library/jest-dom": "^6.4.0",
|
|
120
|
+
"@testing-library/user-event": "^14.5.0",
|
|
120
121
|
"@vitest/ui": "^1.4.0",
|
|
121
122
|
"jsdom": "^24.0.0",
|
|
122
123
|
"@storybook/addon-docs": "^10.2.6",
|