@almadar/ui 2.1.3 → 2.1.4

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.
@@ -1,21 +1,21 @@
1
1
  import { DEFAULT_CONFIG, renderStateMachineToDomData, parseContentSegments } from '../chunk-N6DJVKZ6.js';
2
- import { useAuthContext } from '../chunk-BKC4XU44.js';
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-BKC4XU44.js';
2
+ import { useAuthContext } from '../chunk-E3EXHX2Z.js';
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-E3EXHX2Z.js';
4
4
  import '../chunk-XSEDIUM6.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, EntityDisplayEvents } from '../chunk-LX4G4SVJ.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-LX4G4SVJ.js';
7
- import '../chunk-QU4JHKVC.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, EntityDisplayEvents } from '../chunk-Y7AFNUT2.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-Y7AFNUT2.js';
7
+ import '../chunk-BTXQJGFB.js';
8
8
  import { cn, getNestedValue } from '../chunk-KKCVDUK7.js';
9
9
  export { cn } from '../chunk-KKCVDUK7.js';
10
- import { useTranslate } from '../chunk-PE2H3NAW.js';
11
- export { EntityDataProvider, I18nProvider, createTranslate, entityDataKeys, parseQueryBinding, useEntity, useEntityDataAdapter, useEntityDetail, useEntityList, useEntityListSuspense, useEntitySuspense, useQuerySingleton, useTranslate } from '../chunk-PE2H3NAW.js';
10
+ import { useTranslate } from '../chunk-JLEMVREZ.js';
11
+ export { EntityDataProvider, I18nProvider, createTranslate, entityDataKeys, parseQueryBinding, useEntity, useEntityDataAdapter, useEntityDetail, useEntityList, useEntityListSuspense, useEntitySuspense, useQuerySingleton, useTranslate } from '../chunk-JLEMVREZ.js';
12
12
  import { useEventBus, useEventListener } from '../chunk-YXZM3WCF.js';
13
13
  export { useEmitEvent, useEventBus, useEventListener } from '../chunk-YXZM3WCF.js';
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
17
  import * as React42 from 'react';
18
- import React42__default, { createContext, useState, useMemo, useCallback, useEffect, useRef, useContext } from 'react';
18
+ import React42__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';
@@ -417,13 +417,13 @@ var SidebarNavItem = ({ item, collapsed }) => {
417
417
  "w-full flex items-center gap-3 px-3 py-2.5 transition-all duration-[var(--transition-fast)] group relative",
418
418
  "rounded-[var(--radius-sm)] border-[length:var(--border-width-thin)] border-transparent",
419
419
  isActive ? [
420
- "bg-[var(--color-foreground)] text-[var(--color-background)]",
420
+ "bg-[var(--color-primary)] text-[var(--color-primary-foreground)]",
421
421
  "font-medium shadow-[var(--shadow-sm)]",
422
- "border-[var(--color-border)] translate-x-1 -translate-y-0.5"
422
+ "border-[var(--color-primary)] translate-x-1 -translate-y-0.5"
423
423
  ].join(" ") : [
424
424
  "text-[var(--color-foreground)]",
425
425
  "hover:bg-[var(--color-muted)] hover:border-[var(--color-border)]",
426
- "active:bg-[var(--color-foreground)] active:text-[var(--color-background)]"
426
+ "active:bg-[var(--color-primary)] active:text-[var(--color-primary-foreground)]"
427
427
  ].join(" ")
428
428
  ),
429
429
  title: collapsed ? item.label : void 0,
@@ -434,7 +434,7 @@ var SidebarNavItem = ({ item, collapsed }) => {
434
434
  size: 20,
435
435
  className: cn(
436
436
  "min-w-[20px] flex-shrink-0",
437
- isActive && "text-[var(--color-background)]"
437
+ isActive && "text-[var(--color-primary-foreground)]"
438
438
  )
439
439
  }
440
440
  ),
@@ -460,22 +460,36 @@ var Sidebar = ({
460
460
  footerContent,
461
461
  collapsed: controlledCollapsed,
462
462
  defaultCollapsed = false,
463
- onCollapseChange,
463
+ collapseChangeEvent,
464
464
  hideCollapseButton = false,
465
465
  showCloseButton = false,
466
- onClose,
467
- onLogoClick,
466
+ closeEvent,
467
+ logoClickEvent,
468
468
  className
469
469
  }) => {
470
+ const { emit } = useEventBus();
471
+ const { t } = useTranslate();
470
472
  const [internalCollapsed, setInternalCollapsed] = useState(defaultCollapsed);
471
473
  const collapsed = controlledCollapsed !== void 0 ? controlledCollapsed : internalCollapsed;
472
- const handleToggle = () => {
474
+ const handleToggle = useCallback(() => {
473
475
  const newCollapsed = !collapsed;
474
476
  if (controlledCollapsed === void 0) {
475
477
  setInternalCollapsed(newCollapsed);
476
478
  }
477
- onCollapseChange?.(newCollapsed);
478
- };
479
+ if (collapseChangeEvent) {
480
+ emit(collapseChangeEvent, { collapsed: newCollapsed });
481
+ }
482
+ }, [collapsed, controlledCollapsed, collapseChangeEvent, emit]);
483
+ const handleClose = useCallback(() => {
484
+ if (closeEvent) {
485
+ emit(closeEvent, {});
486
+ }
487
+ }, [closeEvent, emit]);
488
+ const handleLogoClick = useCallback(() => {
489
+ if (logoClickEvent) {
490
+ emit(logoClickEvent, {});
491
+ }
492
+ }, [logoClickEvent, emit]);
479
493
  return /* @__PURE__ */ jsxs(
480
494
  Box,
481
495
  {
@@ -496,7 +510,7 @@ var Sidebar = ({
496
510
  "flex items-center gap-3 cursor-pointer",
497
511
  collapsed && "justify-center w-full"
498
512
  ),
499
- onClick: onLogoClick,
513
+ onClick: handleLogoClick,
500
514
  children: [
501
515
  logo ? typeof logo === "string" ? (
502
516
  // eslint-disable-next-line almadar/no-raw-dom-elements -- semantic img with src/alt
@@ -519,7 +533,7 @@ var Sidebar = ({
519
533
  "rounded-[var(--radius-sm)]",
520
534
  collapsed && "mx-auto"
521
535
  ),
522
- title: collapsed ? "Expand Sidebar" : "Collapse Sidebar",
536
+ title: collapsed ? t("sidebar.expand") : t("sidebar.collapse"),
523
537
  children: collapsed ? /* @__PURE__ */ jsx(ChevronRight, { size: 18 }) : /* @__PURE__ */ jsx(ChevronLeft, { size: 18 })
524
538
  }
525
539
  ),
@@ -527,9 +541,9 @@ var Sidebar = ({
527
541
  Button,
528
542
  {
529
543
  variant: "ghost",
530
- onClick: onClose,
544
+ onClick: handleClose,
531
545
  className: "p-1.5 hover:bg-[var(--color-muted)] text-[var(--color-foreground)] lg:hidden rounded-[var(--radius-sm)]",
532
- "aria-label": "Close sidebar",
546
+ "aria-label": t("sidebar.close"),
533
547
  children: /* @__PURE__ */ jsx(X, { size: 18 })
534
548
  }
535
549
  )
@@ -635,7 +649,6 @@ var Table = ({
635
649
  columns,
636
650
  // EntityDisplayProps
637
651
  entity,
638
- data,
639
652
  className,
640
653
  isLoading,
641
654
  error,
@@ -664,7 +677,7 @@ var Table = ({
664
677
  const eventBus = useEventBus();
665
678
  const resolvedEmptyMessage = emptyMessage ?? t("empty.noData");
666
679
  const resolvedSearchPlaceholder = searchPlaceholder ?? t("common.search");
667
- const resolvedData = Array.isArray(data) ? data : Array.isArray(entity) ? entity : [];
680
+ const resolvedData = Array.isArray(entity) ? entity : [];
668
681
  const resolvedSortColumn = sortColumnProp ?? sortBy;
669
682
  const resolvedSortDirection = sortDirectionProp ?? entitySortDirection ?? void 0;
670
683
  const resolvedCurrentPage = currentPageProp ?? page ?? 1;
@@ -994,7 +1007,6 @@ var ProgressIndicator = ({ value }) => {
994
1007
  };
995
1008
  var List = ({
996
1009
  entity,
997
- data,
998
1010
  isLoading = false,
999
1011
  error,
1000
1012
  selectable = false,
@@ -1010,14 +1022,12 @@ var List = ({
1010
1022
  const eventBus = useEventBus();
1011
1023
  const { t } = useTranslate();
1012
1024
  const resolvedEmptyMessage = emptyMessage ?? t("empty.noData");
1013
- const entityName = typeof entity === "string" ? entity : void 0;
1014
1025
  const effectiveFieldNames = normalizeFields(fields).length > 0 ? normalizeFields(fields) : fieldNames;
1015
1026
  const rawItems = useMemo(() => {
1016
- const d = data ?? [];
1017
- if (Array.isArray(d)) return d;
1018
- if (d && typeof d === "object" && "id" in d) return [d];
1027
+ if (Array.isArray(entity)) return entity;
1028
+ if (entity && typeof entity === "object" && "id" in entity) return [entity];
1019
1029
  return [];
1020
- }, [data]);
1030
+ }, [entity]);
1021
1031
  const getItemActions = React42__default.useCallback(
1022
1032
  (item) => {
1023
1033
  if (!itemActions) return [];
@@ -1033,26 +1043,25 @@ var List = ({
1033
1043
  /\{\{(\w+)\}\}/g,
1034
1044
  (_, key) => String(item[key] || item.id || "")
1035
1045
  );
1036
- eventBus.emit("UI:NAVIGATE", { url, row: item, entity: entityName });
1046
+ eventBus.emit("UI:NAVIGATE", { url, row: item });
1037
1047
  return;
1038
1048
  }
1039
1049
  if (action.event) {
1040
1050
  eventBus.emit(`UI:${action.event}`, {
1041
- row: item,
1042
- entity: entityName
1051
+ row: item
1043
1052
  });
1044
1053
  }
1045
1054
  }
1046
1055
  }));
1047
1056
  },
1048
- [itemActions, eventBus, entityName]
1057
+ [itemActions, eventBus]
1049
1058
  );
1050
1059
  const normalizedItemActions = itemActions ? getItemActions : void 0;
1051
1060
  if (isLoading) {
1052
1061
  return /* @__PURE__ */ jsx(
1053
1062
  LoadingState,
1054
1063
  {
1055
- message: `Loading ${entityType || "items"}...`,
1064
+ message: "Loading items...",
1056
1065
  className
1057
1066
  }
1058
1067
  );
@@ -1062,7 +1071,7 @@ var List = ({
1062
1071
  EmptyState,
1063
1072
  {
1064
1073
  icon: Package,
1065
- title: `Error loading ${entityType || "items"}`,
1074
+ title: "Error loading items",
1066
1075
  description: error.message,
1067
1076
  className
1068
1077
  }
@@ -1109,7 +1118,7 @@ var List = ({
1109
1118
  }
1110
1119
  };
1111
1120
  const handleRowClick = (item) => {
1112
- eventBus.emit("UI:VIEW", { row: item, entity: entityName });
1121
+ eventBus.emit("UI:VIEW", { row: item });
1113
1122
  };
1114
1123
  const defaultRenderItem = (item, index, isLast) => {
1115
1124
  const isSelected = selectedIds.map(String).includes(item.id);
@@ -1325,7 +1334,7 @@ var List = ({
1325
1334
  EmptyState,
1326
1335
  {
1327
1336
  icon: Package,
1328
- title: `No ${entityType || "items"} found`,
1337
+ title: "No items found",
1329
1338
  description: resolvedEmptyMessage,
1330
1339
  className
1331
1340
  }
@@ -3376,7 +3385,7 @@ var PRINT_STYLES = `
3376
3385
  }
3377
3386
  `;
3378
3387
  var BookViewer = ({
3379
- data,
3388
+ entity,
3380
3389
  initialPage = 0,
3381
3390
  fieldMap,
3382
3391
  className
@@ -3386,10 +3395,11 @@ var BookViewer = ({
3386
3395
  const [currentPage, setCurrentPage] = useState(initialPage);
3387
3396
  const resolvedFieldMap = useMemo(() => resolveFieldMap(fieldMap), [fieldMap]);
3388
3397
  const book = useMemo(() => {
3389
- const raw = data?.[0];
3398
+ const entityArray = Array.isArray(entity) ? entity : entity ? [entity] : [];
3399
+ const raw = entityArray[0];
3390
3400
  if (!raw) return null;
3391
3401
  return mapBookData(raw, resolvedFieldMap);
3392
- }, [data, resolvedFieldMap]);
3402
+ }, [entity, resolvedFieldMap]);
3393
3403
  const direction = book?.direction ?? "ltr";
3394
3404
  const chapters = useMemo(() => book ? flattenChapters(book) : [], [book]);
3395
3405
  const totalPages = 2 + chapters.length;
@@ -10104,11 +10114,15 @@ function ClassifierBoard({
10104
10114
  ] }) }),
10105
10115
  unassignedItems.length > 0 && /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
10106
10116
  /* @__PURE__ */ jsx(Typography, { variant: "small", weight: "bold", className: "uppercase tracking-wider text-[var(--color-muted-foreground)]", children: t("classifier.itemsToSort") }),
10107
- /* @__PURE__ */ jsx(HStack, { gap: "sm", className: "flex-wrap", children: unassignedItems.map((item) => /* @__PURE__ */ jsx(Badge, { size: "md", className: "cursor-pointer", children: item.label }, item.id)) })
10117
+ /* @__PURE__ */ jsx(HStack, { gap: "sm", className: "flex-wrap", children: unassignedItems.map((item) => /* @__PURE__ */ jsxs(Badge, { size: "md", className: "cursor-pointer", children: [
10118
+ item.iconUrl && /* @__PURE__ */ jsx("img", { src: item.iconUrl, alt: "", className: "w-4 h-4 object-contain inline-block" }),
10119
+ item.label
10120
+ ] }, item.id)) })
10108
10121
  ] }) }),
10109
10122
  /* @__PURE__ */ jsx(VStack, { gap: "md", children: entity.categories.map((cat) => {
10110
10123
  const catItems = entity.items.filter((item) => assignments[item.id] === cat.id);
10111
10124
  return /* @__PURE__ */ jsx(Card, { className: "p-4", children: /* @__PURE__ */ jsxs(VStack, { gap: "sm", children: [
10125
+ cat.imageUrl && /* @__PURE__ */ jsx(Box, { className: "w-full h-16 overflow-hidden rounded-md", children: /* @__PURE__ */ jsx("img", { src: cat.imageUrl, alt: "", className: "w-full h-full object-cover" }) }),
10112
10126
  /* @__PURE__ */ jsxs(HStack, { justify: "between", align: "center", children: [
10113
10127
  /* @__PURE__ */ jsx(Typography, { variant: "body", weight: "bold", children: cat.label }),
10114
10128
  /* @__PURE__ */ jsx(Badge, { size: "sm", children: catItems.length })
@@ -10122,6 +10136,7 @@ function ClassifierBoard({
10122
10136
  className: `cursor-pointer ${result ? result.correct ? "border-green-500 bg-green-50 dark:bg-green-950" : "border-red-500 bg-red-50 dark:bg-red-950" : ""}`,
10123
10137
  onClick: () => handleUnassign(item.id),
10124
10138
  children: [
10139
+ item.iconUrl && /* @__PURE__ */ jsx("img", { src: item.iconUrl, alt: "", className: "w-3 h-3 object-contain inline-block" }),
10125
10140
  item.label,
10126
10141
  result && /* @__PURE__ */ jsx(Icon, { icon: result.correct ? CheckCircle : XCircle, size: "xs", className: result.correct ? "text-green-600" : "text-red-600" })
10127
10142
  ]
@@ -11406,10 +11421,10 @@ var Chart = ({
11406
11421
  const handleAction = useCallback(
11407
11422
  (action) => {
11408
11423
  if (action.event) {
11409
- eventBus.emit(`UI:${action.event}`, { entity });
11424
+ eventBus.emit(`UI:${action.event}`, {});
11410
11425
  }
11411
11426
  },
11412
- [eventBus, entity]
11427
+ [eventBus]
11413
11428
  );
11414
11429
  const normalizedData = useMemo(() => {
11415
11430
  if (simpleData) return simpleData;
@@ -11509,10 +11524,10 @@ var Meter = ({
11509
11524
  const handleAction = useCallback(
11510
11525
  (action) => {
11511
11526
  if (action.event) {
11512
- eventBus.emit(`UI:${action.event}`, { entity, value });
11527
+ eventBus.emit(`UI:${action.event}`, { value });
11513
11528
  }
11514
11529
  },
11515
- [eventBus, entity, value]
11530
+ [eventBus, value]
11516
11531
  );
11517
11532
  const percentage = useMemo(() => {
11518
11533
  const range = max - min;
@@ -11697,7 +11712,6 @@ var STATUS_STYLES3 = {
11697
11712
  var Timeline = ({
11698
11713
  title,
11699
11714
  items: propItems,
11700
- data,
11701
11715
  fields,
11702
11716
  itemActions,
11703
11717
  entity,
@@ -11705,19 +11719,12 @@ var Timeline = ({
11705
11719
  error,
11706
11720
  className
11707
11721
  }) => {
11708
- const eventBus = useEventBus();
11709
- const handleAction = useCallback(
11710
- (action, item) => {
11711
- if (action.event) {
11712
- eventBus.emit(`UI:${action.event}`, { entity, row: item });
11713
- }
11714
- },
11715
- [eventBus, entity]
11716
- );
11722
+ const { t } = useTranslate();
11723
+ const entityData = Array.isArray(entity) ? entity : [];
11717
11724
  const items = React42__default.useMemo(() => {
11718
11725
  if (propItems) return propItems;
11719
- if (!data) return [];
11720
- return data.map((record, idx) => {
11726
+ if (entityData.length === 0) return [];
11727
+ return entityData.map((record, idx) => {
11721
11728
  const titleField = fields?.[0] || "title";
11722
11729
  const descField = fields?.[1] || "description";
11723
11730
  const dateField = fields?.find(
@@ -11734,7 +11741,7 @@ var Timeline = ({
11734
11741
  status: record[statusField] || "pending"
11735
11742
  };
11736
11743
  });
11737
- }, [propItems, data, fields]);
11744
+ }, [propItems, entityData, fields]);
11738
11745
  if (isLoading) {
11739
11746
  return /* @__PURE__ */ jsx(LoadingState, { message: "Loading timeline...", className });
11740
11747
  }
@@ -11794,12 +11801,12 @@ var Timeline = ({
11794
11801
  item.description && /* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: item.description }),
11795
11802
  item.tags && item.tags.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", wrap: true, children: item.tags.map((tag, tagIdx) => /* @__PURE__ */ jsx(Badge, { variant: "default", children: tag }, tagIdx)) }),
11796
11803
  itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "mt-1", children: itemActions.map((action, actionIdx) => /* @__PURE__ */ jsx(
11797
- Badge,
11804
+ Box,
11798
11805
  {
11799
- variant: "default",
11806
+ action: action.event,
11807
+ actionPayload: { row: item },
11800
11808
  className: "cursor-pointer hover:opacity-80 transition-opacity",
11801
- onClick: () => handleAction(action, item),
11802
- children: action.label
11809
+ children: /* @__PURE__ */ jsx(Badge, { variant: "default", children: action.label })
11803
11810
  },
11804
11811
  actionIdx
11805
11812
  )) })
@@ -11824,11 +11831,10 @@ var ASPECT_CLASSES = {
11824
11831
  var MediaGallery = ({
11825
11832
  title,
11826
11833
  items: propItems,
11827
- data,
11828
11834
  columns = 3,
11829
11835
  selectable = false,
11830
11836
  selectedItems = [],
11831
- onSelectionChange,
11837
+ selectionEvent = "SELECTION_CHANGE",
11832
11838
  showUpload = false,
11833
11839
  actions,
11834
11840
  aspectRatio = "square",
@@ -11838,42 +11844,35 @@ var MediaGallery = ({
11838
11844
  className
11839
11845
  }) => {
11840
11846
  const eventBus = useEventBus();
11847
+ const { t } = useTranslate();
11841
11848
  const [lightboxItem, setLightboxItem] = useState(null);
11842
- const handleAction = useCallback(
11843
- (action) => {
11844
- if (action.event) {
11845
- eventBus.emit(`UI:${action.event}`, { entity });
11846
- }
11847
- },
11848
- [eventBus, entity]
11849
- );
11849
+ const closeLightbox = useCallback(() => setLightboxItem(null), []);
11850
+ useEventListener("UI:LIGHTBOX_CLOSE", closeLightbox);
11850
11851
  const handleItemClick = useCallback(
11851
11852
  (item) => {
11852
11853
  if (selectable) {
11853
11854
  const isSelected = selectedItems.includes(item.id);
11854
11855
  const newSelection = isSelected ? selectedItems.filter((id) => id !== item.id) : [...selectedItems, item.id];
11855
- onSelectionChange?.(newSelection);
11856
+ eventBus.emit(`UI:${selectionEvent}`, { selection: newSelection });
11856
11857
  } else {
11857
11858
  setLightboxItem(item);
11858
11859
  }
11859
- eventBus.emit("UI:MEDIA_SELECT", { entity, row: item });
11860
+ eventBus.emit("UI:MEDIA_SELECT", { row: item });
11860
11861
  },
11861
- [selectable, selectedItems, onSelectionChange, eventBus, entity]
11862
+ [selectable, selectedItems, selectionEvent, eventBus]
11862
11863
  );
11863
- const handleUpload = useCallback(() => {
11864
- eventBus.emit("UI:MEDIA_UPLOAD", { entity });
11865
- }, [eventBus, entity]);
11864
+ const entityData = Array.isArray(entity) ? entity : [];
11866
11865
  const items = React42__default.useMemo(() => {
11867
11866
  if (propItems) return propItems;
11868
- if (!data) return [];
11869
- return data.map((record, idx) => ({
11867
+ if (entityData.length === 0) return [];
11868
+ return entityData.map((record, idx) => ({
11870
11869
  id: String(record.id ?? idx),
11871
11870
  src: String(record.src ?? record.url ?? record.image ?? ""),
11872
11871
  alt: record.alt ? String(record.alt) : void 0,
11873
11872
  thumbnail: record.thumbnail ? String(record.thumbnail) : void 0,
11874
11873
  caption: record.caption ? String(record.caption) : record.title ? String(record.title) : void 0
11875
11874
  }));
11876
- }, [propItems, data]);
11875
+ }, [propItems, entityData]);
11877
11876
  if (isLoading) {
11878
11877
  return /* @__PURE__ */ jsx(LoadingState, { message: "Loading media...", className });
11879
11878
  }
@@ -11909,17 +11908,16 @@ var MediaGallery = ({
11909
11908
  variant: "secondary",
11910
11909
  size: "sm",
11911
11910
  icon: Upload,
11912
- onClick: handleUpload,
11911
+ action: "MEDIA_UPLOAD",
11913
11912
  children: "Upload"
11914
11913
  }
11915
11914
  ),
11916
11915
  actions?.map((action, idx) => /* @__PURE__ */ jsx(
11917
- Badge,
11916
+ Box,
11918
11917
  {
11919
- variant: "default",
11918
+ action: action.event,
11920
11919
  className: "cursor-pointer hover:opacity-80 transition-opacity",
11921
- onClick: () => handleAction(action),
11922
- children: action.label
11920
+ children: /* @__PURE__ */ jsx(Badge, { variant: "default", children: action.label })
11923
11921
  },
11924
11922
  idx
11925
11923
  ))
@@ -11989,7 +11987,7 @@ var MediaGallery = ({
11989
11987
  Box,
11990
11988
  {
11991
11989
  className: "fixed inset-0 z-50 bg-[var(--color-background)]/80 backdrop-blur-sm flex items-center justify-center",
11992
- onClick: () => setLightboxItem(null),
11990
+ action: "LIGHTBOX_CLOSE",
11993
11991
  children: /* @__PURE__ */ jsxs(
11994
11992
  VStack,
11995
11993
  {
@@ -12004,7 +12002,7 @@ var MediaGallery = ({
12004
12002
  variant: "ghost",
12005
12003
  size: "sm",
12006
12004
  icon: X,
12007
- onClick: () => setLightboxItem(null),
12005
+ action: "LIGHTBOX_CLOSE",
12008
12006
  className: "text-white hover:bg-white/20"
12009
12007
  }
12010
12008
  ) }),
@@ -12121,15 +12119,15 @@ var SignaturePad = ({
12121
12119
  setHasSignature(false);
12122
12120
  onChange?.(null);
12123
12121
  if (clearEvent) {
12124
- eventBus.emit(`UI:${clearEvent}`, { entity });
12122
+ eventBus.emit(`UI:${clearEvent}`, {});
12125
12123
  }
12126
- }, [onChange, clearEvent, eventBus, entity]);
12124
+ }, [onChange, clearEvent, eventBus]);
12127
12125
  const confirmSignature = useCallback(() => {
12128
12126
  const dataUrl = canvasRef.current?.toDataURL("image/png") ?? null;
12129
12127
  if (signEvent) {
12130
- eventBus.emit(`UI:${signEvent}`, { entity, signature: dataUrl });
12128
+ eventBus.emit(`UI:${signEvent}`, { signature: dataUrl });
12131
12129
  }
12132
- }, [signEvent, eventBus, entity]);
12130
+ }, [signEvent, eventBus]);
12133
12131
  if (isLoading) {
12134
12132
  return /* @__PURE__ */ jsx(LoadingState, { message: "Loading signature pad...", className });
12135
12133
  }
@@ -12226,34 +12224,34 @@ var DocumentViewer = ({
12226
12224
  const handleAction = useCallback(
12227
12225
  (action) => {
12228
12226
  if (action.event) {
12229
- eventBus.emit(`UI:${action.event}`, { entity, page: currentPage });
12227
+ eventBus.emit(`UI:${action.event}`, { page: currentPage });
12230
12228
  }
12231
12229
  },
12232
- [eventBus, entity, currentPage]
12230
+ [eventBus, currentPage]
12233
12231
  );
12234
12232
  const handleDownload = useCallback(() => {
12235
12233
  const downloadSrc = documents?.[activeDocIndex]?.src ?? src;
12236
12234
  if (downloadSrc) {
12237
- eventBus.emit("UI:DOCUMENT_DOWNLOAD", { entity, src: downloadSrc });
12235
+ eventBus.emit("UI:DOCUMENT_DOWNLOAD", { src: downloadSrc });
12238
12236
  window.open(downloadSrc, "_blank");
12239
12237
  }
12240
- }, [documents, activeDocIndex, src, eventBus, entity]);
12238
+ }, [documents, activeDocIndex, src, eventBus]);
12241
12239
  const handlePrint = useCallback(() => {
12242
- eventBus.emit("UI:DOCUMENT_PRINT", { entity });
12240
+ eventBus.emit("UI:DOCUMENT_PRINT", {});
12243
12241
  window.print();
12244
- }, [eventBus, entity]);
12242
+ }, [eventBus]);
12245
12243
  const handleZoomIn = useCallback(() => setZoom((z) => Math.min(z + 25, 200)), []);
12246
12244
  const handleZoomOut = useCallback(() => setZoom((z) => Math.max(z - 25, 50)), []);
12247
12245
  const handlePagePrev = useCallback(() => {
12248
12246
  setCurrentPage((p2) => Math.max(p2 - 1, 1));
12249
- eventBus.emit("UI:DOCUMENT_PAGE_CHANGE", { entity, page: currentPage - 1 });
12250
- }, [eventBus, entity, currentPage]);
12247
+ eventBus.emit("UI:DOCUMENT_PAGE_CHANGE", { page: currentPage - 1 });
12248
+ }, [eventBus, currentPage]);
12251
12249
  const handlePageNext = useCallback(() => {
12252
12250
  if (totalPages) {
12253
12251
  setCurrentPage((p2) => Math.min(p2 + 1, totalPages));
12254
- eventBus.emit("UI:DOCUMENT_PAGE_CHANGE", { entity, page: currentPage + 1 });
12252
+ eventBus.emit("UI:DOCUMENT_PAGE_CHANGE", { page: currentPage + 1 });
12255
12253
  }
12256
- }, [totalPages, eventBus, entity, currentPage]);
12254
+ }, [totalPages, eventBus, currentPage]);
12257
12255
  if (isLoading) {
12258
12256
  return /* @__PURE__ */ jsx(LoadingState, { message: "Loading document...", className });
12259
12257
  }
@@ -12427,19 +12425,19 @@ var GraphCanvas = ({
12427
12425
  const handleAction = useCallback(
12428
12426
  (action) => {
12429
12427
  if (action.event) {
12430
- eventBus.emit(`UI:${action.event}`, { entity });
12428
+ eventBus.emit(`UI:${action.event}`, {});
12431
12429
  }
12432
12430
  },
12433
- [eventBus, entity]
12431
+ [eventBus]
12434
12432
  );
12435
12433
  const handleNodeClick = useCallback(
12436
12434
  (node) => {
12437
12435
  if (nodeClickEvent) {
12438
- eventBus.emit(`UI:${nodeClickEvent}`, { entity, row: node });
12436
+ eventBus.emit(`UI:${nodeClickEvent}`, { row: node });
12439
12437
  }
12440
12438
  onNodeClick?.(node);
12441
12439
  },
12442
- [nodeClickEvent, eventBus, entity, onNodeClick]
12440
+ [nodeClickEvent, eventBus, onNodeClick]
12443
12441
  );
12444
12442
  const groups = useMemo(
12445
12443
  () => [...new Set(propNodes.map((n) => n.group).filter(Boolean))],
@@ -12751,10 +12749,10 @@ var CodeViewer = ({
12751
12749
  const handleAction = useCallback(
12752
12750
  (action) => {
12753
12751
  if (action.event) {
12754
- eventBus.emit(`UI:${action.event}`, { entity });
12752
+ eventBus.emit(`UI:${action.event}`, {});
12755
12753
  }
12756
12754
  },
12757
- [eventBus, entity]
12755
+ [eventBus]
12758
12756
  );
12759
12757
  const activeFile = files?.[activeFileIndex];
12760
12758
  const activeCode = activeFile?.code ?? code ?? "";
@@ -12771,11 +12769,11 @@ var CodeViewer = ({
12771
12769
  try {
12772
12770
  await navigator.clipboard.writeText(activeCode);
12773
12771
  setCopied(true);
12774
- eventBus.emit("UI:CODE_COPY", { entity, language: activeLanguage });
12772
+ eventBus.emit("UI:CODE_COPY", { language: activeLanguage });
12775
12773
  setTimeout(() => setCopied(false), 2e3);
12776
12774
  } catch {
12777
12775
  }
12778
- }, [activeCode, eventBus, entity, activeLanguage]);
12776
+ }, [activeCode, eventBus, activeLanguage]);
12779
12777
  const tabItems = files?.map((file, idx) => ({
12780
12778
  id: `file-${idx}`,
12781
12779
  label: file.label,
@@ -1,5 +1,5 @@
1
- import { ThemeProvider, useTheme } from '../chunk-QU4JHKVC.js';
2
- export { BUILT_IN_THEMES, ThemeContext_default as ThemeContext, ThemeProvider, UISlotContext, UISlotProvider, useSlotContent, useSlotHasContent, useTheme, useUISlots } from '../chunk-QU4JHKVC.js';
1
+ import { ThemeProvider, useTheme } from '../chunk-BTXQJGFB.js';
2
+ export { BUILT_IN_THEMES, ThemeContext_default as ThemeContext, ThemeProvider, UISlotContext, UISlotProvider, useSlotContent, useSlotHasContent, useTheme, useUISlots } from '../chunk-BTXQJGFB.js';
3
3
  import '../chunk-7NEWMNNU.js';
4
4
  import '../chunk-PKBMQBKP.js';
5
5
  import { createContext, useCallback, useMemo, useContext } from 'react';
@@ -1,6 +1,6 @@
1
- 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-BKC4XU44.js';
1
+ 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-E3EXHX2Z.js';
2
2
  import '../chunk-XSEDIUM6.js';
3
- export { EntityDataProvider, I18nProvider, createTranslate, entityDataKeys, parseQueryBinding, useEntity, useEntityDataAdapter, useEntityDetail, useEntityList, useEntityListSuspense, useEntitySuspense, useQuerySingleton, useTranslate } from '../chunk-PE2H3NAW.js';
3
+ export { EntityDataProvider, I18nProvider, createTranslate, entityDataKeys, parseQueryBinding, useEntity, useEntityDataAdapter, useEntityDetail, useEntityList, useEntityListSuspense, useEntitySuspense, useQuerySingleton, useTranslate } from '../chunk-JLEMVREZ.js';
4
4
  export { useEmitEvent, useEventBus, useEventListener } from '../chunk-YXZM3WCF.js';
5
5
  export { DEFAULT_SLOTS, useUISlotManager } from '../chunk-7NEWMNNU.js';
6
6
  export { clearEntities, getAllEntities, getByType, getEntity, getSingleton, removeEntity, spawnEntity, updateEntity, updateSingleton } from '../chunk-N7MVUW4R.js';
@@ -1,9 +1,9 @@
1
- import { SuspenseConfigProvider } from '../chunk-LX4G4SVJ.js';
2
- import { ThemeProvider } from '../chunk-QU4JHKVC.js';
1
+ import { SuspenseConfigProvider } from '../chunk-Y7AFNUT2.js';
2
+ import { ThemeProvider } from '../chunk-BTXQJGFB.js';
3
3
  import { recordTransition, registerCheck, bindEventBus, bindTraitStateGetter } from '../chunk-45CTDYBT.js';
4
4
  import '../chunk-KKCVDUK7.js';
5
- import { SelectionProvider, EntityDataProvider } from '../chunk-PE2H3NAW.js';
6
- export { SelectionContext, SelectionProvider, useSelection, useSelectionOptional } from '../chunk-PE2H3NAW.js';
5
+ import { SelectionProvider, EntityDataProvider } from '../chunk-JLEMVREZ.js';
6
+ export { SelectionContext, SelectionProvider, useSelection, useSelectionOptional } from '../chunk-JLEMVREZ.js';
7
7
  import { useEventBus, EventBusProvider } from '../chunk-YXZM3WCF.js';
8
8
  export { EventBusContext, EventBusProvider } from '../chunk-YXZM3WCF.js';
9
9
  import '../chunk-7NEWMNNU.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "main": "./dist/components/index.js",