@almadar/ui 5.9.10 → 5.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -59,6 +59,8 @@ export interface TableViewProps<T extends EntityRow = EntityRow> extends DataDnd
59
59
  fields?: readonly TableViewColumn[];
60
60
  /** Per-row action buttons (trailing column). */
61
61
  itemActions?: readonly TableViewItemAction[];
62
+ /** Max inline action buttons before the rest collapse into a "⋯" overflow menu. Omit = all inline. */
63
+ maxInlineActions?: number;
62
64
  /** Render a leading checkbox column. Selection changes emit `selectEvent`. */
63
65
  selectable?: boolean;
64
66
  /** Event emitted on selection change: UI:{selectEvent} with { ids, rows }. */
@@ -101,7 +103,7 @@ export interface TableViewProps<T extends EntityRow = EntityRow> extends DataDnd
101
103
  */
102
104
  look?: 'dense' | 'spacious' | 'striped' | 'borderless' | 'bordered';
103
105
  }
104
- export declare function TableView<T extends EntityRow = EntityRow>({ entity, columns, fields, itemActions, selectable, selectEvent, selectedIds, sortEvent, sortColumn, sortDirection, className, emptyMessage, isLoading, error, groupBy, pageSize, children, renderItem: _schemaRenderItem, look, dragGroup, accepts, sortable, dropEvent, reorderEvent, positionEvent, dndItemIdField, dndRoot, }: TableViewProps<T>): import("react/jsx-runtime").JSX.Element;
106
+ export declare function TableView<T extends EntityRow = EntityRow>({ entity, columns, fields, itemActions, maxInlineActions, selectable, selectEvent, selectedIds, sortEvent, sortColumn, sortDirection, className, emptyMessage, isLoading, error, groupBy, pageSize, children, renderItem: _schemaRenderItem, look, dragGroup, accepts, sortable, dropEvent, reorderEvent, positionEvent, dndItemIdField, dndRoot, }: TableViewProps<T>): import("react/jsx-runtime").JSX.Element;
105
107
  export declare namespace TableView {
106
108
  var displayName: string;
107
109
  }
@@ -23448,6 +23448,8 @@ function DataGrid({
23448
23448
  fields,
23449
23449
  columns,
23450
23450
  itemActions,
23451
+ maxInlineActions,
23452
+ scrollX = false,
23451
23453
  cols,
23452
23454
  gap = "md",
23453
23455
  minCardWidth = 280,
@@ -23587,8 +23589,8 @@ function DataGrid({
23587
23589
  /* @__PURE__ */ jsxRuntime.jsx(
23588
23590
  Box,
23589
23591
  {
23590
- className: cn("grid", gapStyles6[gap], colsClass, lookStyles5[look], className),
23591
- style: gridTemplateColumns ? { gridTemplateColumns } : void 0,
23592
+ className: cn("grid", gapStyles6[gap], scrollX ? "grid-flow-col overflow-x-auto" : colsClass, lookStyles5[look], className),
23593
+ style: scrollX ? { gridAutoFlow: "column", gridAutoColumns: `minmax(${minCardWidth}px, 1fr)` } : gridTemplateColumns ? { gridTemplateColumns } : void 0,
23592
23594
  children: data.map((item, index) => {
23593
23595
  const itemData = item;
23594
23596
  const id = itemData.id || String(index);
@@ -23715,21 +23717,39 @@ function DataGrid({
23715
23717
  )
23716
23718
  ] }, field.name);
23717
23719
  }) }) }),
23718
- primaryActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 py-3 mt-auto border-t border-border", children: /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "sm", className: "justify-end", children: primaryActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
23719
- Button,
23720
- {
23721
- variant: action.variant === "primary" ? "primary" : "ghost",
23722
- size: "sm",
23723
- onClick: handleActionClick(action, itemData),
23724
- "data-testid": `action-${action.event}`,
23725
- "data-row-id": String(itemData.id),
23726
- children: [
23727
- action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
23728
- action.label
23729
- ]
23730
- },
23731
- idx
23732
- )) }) })
23720
+ primaryActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "px-4 py-3 mt-auto border-t border-border", children: /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", className: "justify-end", children: [
23721
+ (maxInlineActions != null ? primaryActions.slice(0, maxInlineActions) : primaryActions).map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
23722
+ Button,
23723
+ {
23724
+ variant: action.variant === "primary" ? "primary" : "ghost",
23725
+ size: "sm",
23726
+ onClick: handleActionClick(action, itemData),
23727
+ "data-testid": `action-${action.event}`,
23728
+ "data-row-id": String(itemData.id),
23729
+ children: [
23730
+ action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
23731
+ action.label
23732
+ ]
23733
+ },
23734
+ idx
23735
+ )),
23736
+ maxInlineActions != null && primaryActions.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
23737
+ Menu,
23738
+ {
23739
+ position: "bottom-end",
23740
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": "More actions", "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
23741
+ items: primaryActions.slice(maxInlineActions).map((action) => ({
23742
+ label: action.label,
23743
+ icon: action.icon,
23744
+ event: action.event,
23745
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
23746
+ id: itemData.id,
23747
+ row: itemData
23748
+ })
23749
+ }))
23750
+ }
23751
+ )
23752
+ ] }) })
23733
23753
  ]
23734
23754
  },
23735
23755
  id
@@ -23779,6 +23799,7 @@ var init_DataGrid = __esm({
23779
23799
  init_Button();
23780
23800
  init_Icon();
23781
23801
  init_InfiniteScrollSentinel();
23802
+ init_Menu();
23782
23803
  init_useDataDnd();
23783
23804
  dataGridLog = logger.createLogger("almadar:ui:data-grid");
23784
23805
  BADGE_VARIANTS = /* @__PURE__ */ new Set([
@@ -23858,6 +23879,7 @@ function DataList({
23858
23879
  fields,
23859
23880
  columns,
23860
23881
  itemActions,
23882
+ maxInlineActions,
23861
23883
  itemClickEvent,
23862
23884
  gap = "none",
23863
23885
  variant = "default",
@@ -23948,6 +23970,46 @@ function DataList({
23948
23970
  };
23949
23971
  eventBus.emit(`UI:${action.event}`, payload);
23950
23972
  };
23973
+ const renderItemActions = (itemData) => {
23974
+ if (!itemActions || itemActions.length === 0) return null;
23975
+ const inline = maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions;
23976
+ const overflow = maxInlineActions != null ? itemActions.slice(maxInlineActions) : [];
23977
+ return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "flex-shrink-0", children: [
23978
+ inline.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
23979
+ Button,
23980
+ {
23981
+ variant: action.variant ?? "ghost",
23982
+ size: "sm",
23983
+ onClick: handleActionClick(action, itemData),
23984
+ "data-testid": `action-${action.event}`,
23985
+ "data-row-id": String(itemData.id),
23986
+ className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
23987
+ children: [
23988
+ action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
23989
+ action.label
23990
+ ]
23991
+ },
23992
+ idx
23993
+ )),
23994
+ overflow.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
23995
+ Menu,
23996
+ {
23997
+ position: "bottom-end",
23998
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": "More actions", "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
23999
+ items: overflow.map((action) => ({
24000
+ label: action.label,
24001
+ icon: action.icon,
24002
+ event: action.event,
24003
+ variant: action.variant === "danger" ? "danger" : "default",
24004
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
24005
+ id: itemData.id,
24006
+ row: itemData
24007
+ })
24008
+ }))
24009
+ }
24010
+ )
24011
+ ] });
24012
+ };
23951
24013
  const handleRowClick = (itemData) => () => {
23952
24014
  if (!itemClickEvent) return;
23953
24015
  const payload = {
@@ -24037,31 +24099,7 @@ function DataList({
24037
24099
  /* @__PURE__ */ jsxRuntime.jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, onClick: itemClickEvent ? handleRowClick(itemData) : void 0, className: cn(itemClickEvent && "cursor-pointer"), children: [
24038
24100
  /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "group flex items-stretch gap-2", children: [
24039
24101
  /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
24040
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
24041
- HStack,
24042
- {
24043
- gap: "xs",
24044
- className: "flex-shrink-0",
24045
- children: itemActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
24046
- Button,
24047
- {
24048
- variant: action.variant ?? "ghost",
24049
- size: "sm",
24050
- onClick: handleActionClick(action, itemData),
24051
- "data-testid": `action-${action.event}`,
24052
- "data-row-id": String(itemData.id),
24053
- className: cn(
24054
- action.variant === "danger" && "text-error hover:bg-error/10"
24055
- ),
24056
- children: [
24057
- action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
24058
- action.label
24059
- ]
24060
- },
24061
- idx
24062
- ))
24063
- }
24064
- )
24102
+ renderItemActions(itemData)
24065
24103
  ] }),
24066
24104
  isCard && !isLast && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "mx-6 border-b border-border/40" })
24067
24105
  ] }, id2)
@@ -24132,24 +24170,7 @@ function DataList({
24132
24170
  ] }, field.name);
24133
24171
  })
24134
24172
  ] }),
24135
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: itemActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
24136
- Button,
24137
- {
24138
- variant: action.variant ?? "ghost",
24139
- size: "sm",
24140
- onClick: handleActionClick(action, itemData),
24141
- "data-testid": `action-${action.event}`,
24142
- "data-row-id": String(itemData.id),
24143
- className: cn(
24144
- action.variant === "danger" && "text-error hover:bg-error/10"
24145
- ),
24146
- children: [
24147
- action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
24148
- action.label
24149
- ]
24150
- },
24151
- idx
24152
- )) })
24173
+ renderItemActions(itemData)
24153
24174
  ]
24154
24175
  }
24155
24176
  ),
@@ -24219,6 +24240,7 @@ var init_DataList = __esm({
24219
24240
  init_ProgressBar();
24220
24241
  init_Divider();
24221
24242
  init_InfiniteScrollSentinel();
24243
+ init_Menu();
24222
24244
  init_useDataDnd();
24223
24245
  dataListLog = logger.createLogger("almadar:ui:data-list");
24224
24246
  listLookStyles = {
@@ -29328,6 +29350,7 @@ function TableView({
29328
29350
  columns,
29329
29351
  fields,
29330
29352
  itemActions,
29353
+ maxInlineActions,
29331
29354
  selectable = false,
29332
29355
  selectEvent,
29333
29356
  selectedIds,
@@ -29510,22 +29533,41 @@ function TableView({
29510
29533
  }
29511
29534
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
29512
29535
  }),
29513
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: itemActions.map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
29514
- Button,
29515
- {
29516
- variant: action.variant ?? "ghost",
29517
- size: "sm",
29518
- onClick: handleActionClick(action, row),
29519
- "data-testid": `action-${action.event}`,
29520
- "data-row-id": String(row.id),
29521
- className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
29522
- children: [
29523
- action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
29524
- action.label
29525
- ]
29526
- },
29527
- i
29528
- )) })
29536
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
29537
+ (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
29538
+ Button,
29539
+ {
29540
+ variant: action.variant ?? "ghost",
29541
+ size: "sm",
29542
+ onClick: handleActionClick(action, row),
29543
+ "data-testid": `action-${action.event}`,
29544
+ "data-row-id": String(row.id),
29545
+ className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
29546
+ children: [
29547
+ action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
29548
+ action.label
29549
+ ]
29550
+ },
29551
+ i
29552
+ )),
29553
+ maxInlineActions != null && itemActions.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
29554
+ Menu,
29555
+ {
29556
+ position: "bottom-end",
29557
+ trigger: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", "aria-label": "More actions", "data-testid": "action-overflow", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
29558
+ items: itemActions.slice(maxInlineActions).map((action) => ({
29559
+ label: action.label,
29560
+ icon: action.icon,
29561
+ event: action.event,
29562
+ variant: action.variant === "danger" ? "danger" : "default",
29563
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
29564
+ id: row.id,
29565
+ row
29566
+ })
29567
+ }))
29568
+ }
29569
+ )
29570
+ ] })
29529
29571
  ]
29530
29572
  }
29531
29573
  );
@@ -29573,6 +29615,7 @@ var init_TableView = __esm({
29573
29615
  init_Icon();
29574
29616
  init_Checkbox();
29575
29617
  init_Divider();
29618
+ init_Menu();
29576
29619
  init_useDataDnd();
29577
29620
  logger.createLogger("almadar:ui:table-view");
29578
29621
  alignClass = {
@@ -29586,11 +29629,11 @@ var init_TableView = __esm({
29586
29629
  semibold: "font-semibold"
29587
29630
  };
29588
29631
  LOOKS = {
29589
- dense: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: true },
29590
- spacious: { rowPad: "px-5 py-4", headPad: "px-5 py-3", striped: false, divider: true },
29591
- striped: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: true, divider: false },
29592
- borderless: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: false },
29593
- bordered: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: true }
29632
+ dense: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: true },
29633
+ spacious: { rowPad: "px-card-lg py-card-md", headPad: "px-card-lg py-card-sm", striped: false, divider: true },
29634
+ striped: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: true, divider: false },
29635
+ borderless: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: false },
29636
+ bordered: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: true }
29594
29637
  };
29595
29638
  TableView.displayName = "TableView";
29596
29639
  }
@@ -23399,6 +23399,8 @@ function DataGrid({
23399
23399
  fields,
23400
23400
  columns,
23401
23401
  itemActions,
23402
+ maxInlineActions,
23403
+ scrollX = false,
23402
23404
  cols,
23403
23405
  gap = "md",
23404
23406
  minCardWidth = 280,
@@ -23538,8 +23540,8 @@ function DataGrid({
23538
23540
  /* @__PURE__ */ jsx(
23539
23541
  Box,
23540
23542
  {
23541
- className: cn("grid", gapStyles6[gap], colsClass, lookStyles5[look], className),
23542
- style: gridTemplateColumns ? { gridTemplateColumns } : void 0,
23543
+ className: cn("grid", gapStyles6[gap], scrollX ? "grid-flow-col overflow-x-auto" : colsClass, lookStyles5[look], className),
23544
+ style: scrollX ? { gridAutoFlow: "column", gridAutoColumns: `minmax(${minCardWidth}px, 1fr)` } : gridTemplateColumns ? { gridTemplateColumns } : void 0,
23543
23545
  children: data.map((item, index) => {
23544
23546
  const itemData = item;
23545
23547
  const id = itemData.id || String(index);
@@ -23666,21 +23668,39 @@ function DataGrid({
23666
23668
  )
23667
23669
  ] }, field.name);
23668
23670
  }) }) }),
23669
- primaryActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 mt-auto border-t border-border", children: /* @__PURE__ */ jsx(HStack, { gap: "sm", className: "justify-end", children: primaryActions.map((action, idx) => /* @__PURE__ */ jsxs(
23670
- Button,
23671
- {
23672
- variant: action.variant === "primary" ? "primary" : "ghost",
23673
- size: "sm",
23674
- onClick: handleActionClick(action, itemData),
23675
- "data-testid": `action-${action.event}`,
23676
- "data-row-id": String(itemData.id),
23677
- children: [
23678
- action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
23679
- action.label
23680
- ]
23681
- },
23682
- idx
23683
- )) }) })
23671
+ primaryActions.length > 0 && /* @__PURE__ */ jsx(Box, { className: "px-4 py-3 mt-auto border-t border-border", children: /* @__PURE__ */ jsxs(HStack, { gap: "sm", className: "justify-end", children: [
23672
+ (maxInlineActions != null ? primaryActions.slice(0, maxInlineActions) : primaryActions).map((action, idx) => /* @__PURE__ */ jsxs(
23673
+ Button,
23674
+ {
23675
+ variant: action.variant === "primary" ? "primary" : "ghost",
23676
+ size: "sm",
23677
+ onClick: handleActionClick(action, itemData),
23678
+ "data-testid": `action-${action.event}`,
23679
+ "data-row-id": String(itemData.id),
23680
+ children: [
23681
+ action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
23682
+ action.label
23683
+ ]
23684
+ },
23685
+ idx
23686
+ )),
23687
+ maxInlineActions != null && primaryActions.length > maxInlineActions && /* @__PURE__ */ jsx(
23688
+ Menu,
23689
+ {
23690
+ position: "bottom-end",
23691
+ trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": "More actions", "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
23692
+ items: primaryActions.slice(maxInlineActions).map((action) => ({
23693
+ label: action.label,
23694
+ icon: action.icon,
23695
+ event: action.event,
23696
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
23697
+ id: itemData.id,
23698
+ row: itemData
23699
+ })
23700
+ }))
23701
+ }
23702
+ )
23703
+ ] }) })
23684
23704
  ]
23685
23705
  },
23686
23706
  id
@@ -23730,6 +23750,7 @@ var init_DataGrid = __esm({
23730
23750
  init_Button();
23731
23751
  init_Icon();
23732
23752
  init_InfiniteScrollSentinel();
23753
+ init_Menu();
23733
23754
  init_useDataDnd();
23734
23755
  dataGridLog = createLogger("almadar:ui:data-grid");
23735
23756
  BADGE_VARIANTS = /* @__PURE__ */ new Set([
@@ -23809,6 +23830,7 @@ function DataList({
23809
23830
  fields,
23810
23831
  columns,
23811
23832
  itemActions,
23833
+ maxInlineActions,
23812
23834
  itemClickEvent,
23813
23835
  gap = "none",
23814
23836
  variant = "default",
@@ -23899,6 +23921,46 @@ function DataList({
23899
23921
  };
23900
23922
  eventBus.emit(`UI:${action.event}`, payload);
23901
23923
  };
23924
+ const renderItemActions = (itemData) => {
23925
+ if (!itemActions || itemActions.length === 0) return null;
23926
+ const inline = maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions;
23927
+ const overflow = maxInlineActions != null ? itemActions.slice(maxInlineActions) : [];
23928
+ return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "flex-shrink-0", children: [
23929
+ inline.map((action, idx) => /* @__PURE__ */ jsxs(
23930
+ Button,
23931
+ {
23932
+ variant: action.variant ?? "ghost",
23933
+ size: "sm",
23934
+ onClick: handleActionClick(action, itemData),
23935
+ "data-testid": `action-${action.event}`,
23936
+ "data-row-id": String(itemData.id),
23937
+ className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
23938
+ children: [
23939
+ action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
23940
+ action.label
23941
+ ]
23942
+ },
23943
+ idx
23944
+ )),
23945
+ overflow.length > 0 && /* @__PURE__ */ jsx(
23946
+ Menu,
23947
+ {
23948
+ position: "bottom-end",
23949
+ trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": "More actions", "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
23950
+ items: overflow.map((action) => ({
23951
+ label: action.label,
23952
+ icon: action.icon,
23953
+ event: action.event,
23954
+ variant: action.variant === "danger" ? "danger" : "default",
23955
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
23956
+ id: itemData.id,
23957
+ row: itemData
23958
+ })
23959
+ }))
23960
+ }
23961
+ )
23962
+ ] });
23963
+ };
23902
23964
  const handleRowClick = (itemData) => () => {
23903
23965
  if (!itemClickEvent) return;
23904
23966
  const payload = {
@@ -23988,31 +24050,7 @@ function DataList({
23988
24050
  /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, onClick: itemClickEvent ? handleRowClick(itemData) : void 0, className: cn(itemClickEvent && "cursor-pointer"), children: [
23989
24051
  /* @__PURE__ */ jsxs(Box, { className: "group flex items-stretch gap-2", children: [
23990
24052
  /* @__PURE__ */ jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
23991
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(
23992
- HStack,
23993
- {
23994
- gap: "xs",
23995
- className: "flex-shrink-0",
23996
- children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
23997
- Button,
23998
- {
23999
- variant: action.variant ?? "ghost",
24000
- size: "sm",
24001
- onClick: handleActionClick(action, itemData),
24002
- "data-testid": `action-${action.event}`,
24003
- "data-row-id": String(itemData.id),
24004
- className: cn(
24005
- action.variant === "danger" && "text-error hover:bg-error/10"
24006
- ),
24007
- children: [
24008
- action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
24009
- action.label
24010
- ]
24011
- },
24012
- idx
24013
- ))
24014
- }
24015
- )
24053
+ renderItemActions(itemData)
24016
24054
  ] }),
24017
24055
  isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "mx-6 border-b border-border/40" })
24018
24056
  ] }, id2)
@@ -24083,24 +24121,7 @@ function DataList({
24083
24121
  ] }, field.name);
24084
24122
  })
24085
24123
  ] }),
24086
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: itemActions.map((action, idx) => /* @__PURE__ */ jsxs(
24087
- Button,
24088
- {
24089
- variant: action.variant ?? "ghost",
24090
- size: "sm",
24091
- onClick: handleActionClick(action, itemData),
24092
- "data-testid": `action-${action.event}`,
24093
- "data-row-id": String(itemData.id),
24094
- className: cn(
24095
- action.variant === "danger" && "text-error hover:bg-error/10"
24096
- ),
24097
- children: [
24098
- action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
24099
- action.label
24100
- ]
24101
- },
24102
- idx
24103
- )) })
24124
+ renderItemActions(itemData)
24104
24125
  ]
24105
24126
  }
24106
24127
  ),
@@ -24170,6 +24191,7 @@ var init_DataList = __esm({
24170
24191
  init_ProgressBar();
24171
24192
  init_Divider();
24172
24193
  init_InfiniteScrollSentinel();
24194
+ init_Menu();
24173
24195
  init_useDataDnd();
24174
24196
  dataListLog = createLogger("almadar:ui:data-list");
24175
24197
  listLookStyles = {
@@ -29279,6 +29301,7 @@ function TableView({
29279
29301
  columns,
29280
29302
  fields,
29281
29303
  itemActions,
29304
+ maxInlineActions,
29282
29305
  selectable = false,
29283
29306
  selectEvent,
29284
29307
  selectedIds,
@@ -29461,22 +29484,41 @@ function TableView({
29461
29484
  }
29462
29485
  return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
29463
29486
  }),
29464
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsx(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: itemActions.map((action, i) => /* @__PURE__ */ jsxs(
29465
- Button,
29466
- {
29467
- variant: action.variant ?? "ghost",
29468
- size: "sm",
29469
- onClick: handleActionClick(action, row),
29470
- "data-testid": `action-${action.event}`,
29471
- "data-row-id": String(row.id),
29472
- className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
29473
- children: [
29474
- action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
29475
- action.label
29476
- ]
29477
- },
29478
- i
29479
- )) })
29487
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
29488
+ (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxs(
29489
+ Button,
29490
+ {
29491
+ variant: action.variant ?? "ghost",
29492
+ size: "sm",
29493
+ onClick: handleActionClick(action, row),
29494
+ "data-testid": `action-${action.event}`,
29495
+ "data-row-id": String(row.id),
29496
+ className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
29497
+ children: [
29498
+ action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
29499
+ action.label
29500
+ ]
29501
+ },
29502
+ i
29503
+ )),
29504
+ maxInlineActions != null && itemActions.length > maxInlineActions && /* @__PURE__ */ jsx(
29505
+ Menu,
29506
+ {
29507
+ position: "bottom-end",
29508
+ trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": "More actions", "data-testid": "action-overflow", children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
29509
+ items: itemActions.slice(maxInlineActions).map((action) => ({
29510
+ label: action.label,
29511
+ icon: action.icon,
29512
+ event: action.event,
29513
+ variant: action.variant === "danger" ? "danger" : "default",
29514
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
29515
+ id: row.id,
29516
+ row
29517
+ })
29518
+ }))
29519
+ }
29520
+ )
29521
+ ] })
29480
29522
  ]
29481
29523
  }
29482
29524
  );
@@ -29524,6 +29566,7 @@ var init_TableView = __esm({
29524
29566
  init_Icon();
29525
29567
  init_Checkbox();
29526
29568
  init_Divider();
29569
+ init_Menu();
29527
29570
  init_useDataDnd();
29528
29571
  createLogger("almadar:ui:table-view");
29529
29572
  alignClass = {
@@ -29537,11 +29580,11 @@ var init_TableView = __esm({
29537
29580
  semibold: "font-semibold"
29538
29581
  };
29539
29582
  LOOKS = {
29540
- dense: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: true },
29541
- spacious: { rowPad: "px-5 py-4", headPad: "px-5 py-3", striped: false, divider: true },
29542
- striped: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: true, divider: false },
29543
- borderless: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: false },
29544
- bordered: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: true }
29583
+ dense: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: true },
29584
+ spacious: { rowPad: "px-card-lg py-card-md", headPad: "px-card-lg py-card-sm", striped: false, divider: true },
29585
+ striped: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: true, divider: false },
29586
+ borderless: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: false },
29587
+ bordered: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: true }
29545
29588
  };
29546
29589
  TableView.displayName = "TableView";
29547
29590
  }