@almadar/ui 5.9.10 → 5.12.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.
@@ -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,
@@ -29371,10 +29394,13 @@ function TableView({
29371
29394
  }
29372
29395
  const lk = LOOKS[look];
29373
29396
  const hasActions = Boolean(itemActions && itemActions.length > 0);
29397
+ const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
29398
+ const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
29399
+ const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
29374
29400
  const gridTemplateColumns = [
29375
29401
  selectable ? "auto" : null,
29376
29402
  ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
29377
- hasActions ? "auto" : null
29403
+ actionsTrack
29378
29404
  ].filter(Boolean).join(" ");
29379
29405
  const header = /* @__PURE__ */ jsxs(
29380
29406
  Box,
@@ -29461,22 +29487,41 @@ function TableView({
29461
29487
  }
29462
29488
  return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
29463
29489
  }),
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
- )) })
29490
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "justify-end flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
29491
+ (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxs(
29492
+ Button,
29493
+ {
29494
+ variant: action.variant ?? "ghost",
29495
+ size: "sm",
29496
+ onClick: handleActionClick(action, row),
29497
+ "data-testid": `action-${action.event}`,
29498
+ "data-row-id": String(row.id),
29499
+ className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
29500
+ children: [
29501
+ action.icon && /* @__PURE__ */ jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
29502
+ action.label
29503
+ ]
29504
+ },
29505
+ i
29506
+ )),
29507
+ maxInlineActions != null && itemActions.length > maxInlineActions && /* @__PURE__ */ jsx(
29508
+ Menu,
29509
+ {
29510
+ position: "bottom-end",
29511
+ 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" }) }),
29512
+ items: itemActions.slice(maxInlineActions).map((action) => ({
29513
+ label: action.label,
29514
+ icon: action.icon,
29515
+ event: action.event,
29516
+ variant: action.variant === "danger" ? "danger" : "default",
29517
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
29518
+ id: row.id,
29519
+ row
29520
+ })
29521
+ }))
29522
+ }
29523
+ )
29524
+ ] })
29480
29525
  ]
29481
29526
  }
29482
29527
  );
@@ -29524,6 +29569,7 @@ var init_TableView = __esm({
29524
29569
  init_Icon();
29525
29570
  init_Checkbox();
29526
29571
  init_Divider();
29572
+ init_Menu();
29527
29573
  init_useDataDnd();
29528
29574
  createLogger("almadar:ui:table-view");
29529
29575
  alignClass = {
@@ -29537,11 +29583,11 @@ var init_TableView = __esm({
29537
29583
  semibold: "font-semibold"
29538
29584
  };
29539
29585
  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 }
29586
+ dense: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: true },
29587
+ spacious: { rowPad: "px-card-lg py-card-md", headPad: "px-card-lg py-card-sm", striped: false, divider: true },
29588
+ striped: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: true, divider: false },
29589
+ borderless: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: false },
29590
+ bordered: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: true }
29545
29591
  };
29546
29592
  TableView.displayName = "TableView";
29547
29593
  }
@@ -23217,6 +23217,8 @@ function DataGrid({
23217
23217
  fields,
23218
23218
  columns,
23219
23219
  itemActions,
23220
+ maxInlineActions,
23221
+ scrollX = false,
23220
23222
  cols,
23221
23223
  gap = "md",
23222
23224
  minCardWidth = 280,
@@ -23356,8 +23358,8 @@ function DataGrid({
23356
23358
  /* @__PURE__ */ jsxRuntime.jsx(
23357
23359
  Box,
23358
23360
  {
23359
- className: cn("grid", gapStyles6[gap], colsClass, lookStyles5[look], className),
23360
- style: gridTemplateColumns ? { gridTemplateColumns } : void 0,
23361
+ className: cn("grid", gapStyles6[gap], scrollX ? "grid-flow-col overflow-x-auto" : colsClass, lookStyles5[look], className),
23362
+ style: scrollX ? { gridAutoFlow: "column", gridAutoColumns: `minmax(${minCardWidth}px, 1fr)` } : gridTemplateColumns ? { gridTemplateColumns } : void 0,
23361
23363
  children: data.map((item, index) => {
23362
23364
  const itemData = item;
23363
23365
  const id = itemData.id || String(index);
@@ -23484,21 +23486,39 @@ function DataGrid({
23484
23486
  )
23485
23487
  ] }, field.name);
23486
23488
  }) }) }),
23487
- 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(
23488
- Button,
23489
- {
23490
- variant: action.variant === "primary" ? "primary" : "ghost",
23491
- size: "sm",
23492
- onClick: handleActionClick(action, itemData),
23493
- "data-testid": `action-${action.event}`,
23494
- "data-row-id": String(itemData.id),
23495
- children: [
23496
- action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
23497
- action.label
23498
- ]
23499
- },
23500
- idx
23501
- )) }) })
23489
+ 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: [
23490
+ (maxInlineActions != null ? primaryActions.slice(0, maxInlineActions) : primaryActions).map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
23491
+ Button,
23492
+ {
23493
+ variant: action.variant === "primary" ? "primary" : "ghost",
23494
+ size: "sm",
23495
+ onClick: handleActionClick(action, itemData),
23496
+ "data-testid": `action-${action.event}`,
23497
+ "data-row-id": String(itemData.id),
23498
+ children: [
23499
+ action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
23500
+ action.label
23501
+ ]
23502
+ },
23503
+ idx
23504
+ )),
23505
+ maxInlineActions != null && primaryActions.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
23506
+ Menu,
23507
+ {
23508
+ position: "bottom-end",
23509
+ 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" }) }),
23510
+ items: primaryActions.slice(maxInlineActions).map((action) => ({
23511
+ label: action.label,
23512
+ icon: action.icon,
23513
+ event: action.event,
23514
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
23515
+ id: itemData.id,
23516
+ row: itemData
23517
+ })
23518
+ }))
23519
+ }
23520
+ )
23521
+ ] }) })
23502
23522
  ]
23503
23523
  },
23504
23524
  id
@@ -23548,6 +23568,7 @@ var init_DataGrid = __esm({
23548
23568
  init_Button();
23549
23569
  init_Icon();
23550
23570
  init_InfiniteScrollSentinel();
23571
+ init_Menu();
23551
23572
  init_useDataDnd();
23552
23573
  dataGridLog = logger.createLogger("almadar:ui:data-grid");
23553
23574
  BADGE_VARIANTS = /* @__PURE__ */ new Set([
@@ -23627,6 +23648,7 @@ function DataList({
23627
23648
  fields,
23628
23649
  columns,
23629
23650
  itemActions,
23651
+ maxInlineActions,
23630
23652
  itemClickEvent,
23631
23653
  gap = "none",
23632
23654
  variant = "default",
@@ -23717,6 +23739,46 @@ function DataList({
23717
23739
  };
23718
23740
  eventBus.emit(`UI:${action.event}`, payload);
23719
23741
  };
23742
+ const renderItemActions = (itemData) => {
23743
+ if (!itemActions || itemActions.length === 0) return null;
23744
+ const inline = maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions;
23745
+ const overflow = maxInlineActions != null ? itemActions.slice(maxInlineActions) : [];
23746
+ return /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "flex-shrink-0", children: [
23747
+ inline.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
23748
+ Button,
23749
+ {
23750
+ variant: action.variant ?? "ghost",
23751
+ size: "sm",
23752
+ onClick: handleActionClick(action, itemData),
23753
+ "data-testid": `action-${action.event}`,
23754
+ "data-row-id": String(itemData.id),
23755
+ className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
23756
+ children: [
23757
+ action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
23758
+ action.label
23759
+ ]
23760
+ },
23761
+ idx
23762
+ )),
23763
+ overflow.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
23764
+ Menu,
23765
+ {
23766
+ position: "bottom-end",
23767
+ 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" }) }),
23768
+ items: overflow.map((action) => ({
23769
+ label: action.label,
23770
+ icon: action.icon,
23771
+ event: action.event,
23772
+ variant: action.variant === "danger" ? "danger" : "default",
23773
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
23774
+ id: itemData.id,
23775
+ row: itemData
23776
+ })
23777
+ }))
23778
+ }
23779
+ )
23780
+ ] });
23781
+ };
23720
23782
  const handleRowClick = (itemData) => () => {
23721
23783
  if (!itemClickEvent) return;
23722
23784
  const payload = {
@@ -23806,31 +23868,7 @@ function DataList({
23806
23868
  /* @__PURE__ */ jsxRuntime.jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, onClick: itemClickEvent ? handleRowClick(itemData) : void 0, className: cn(itemClickEvent && "cursor-pointer"), children: [
23807
23869
  /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "group flex items-stretch gap-2", children: [
23808
23870
  /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "flex-1 min-w-0", children: children(itemData, index) }),
23809
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
23810
- HStack,
23811
- {
23812
- gap: "xs",
23813
- className: "flex-shrink-0",
23814
- children: itemActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
23815
- Button,
23816
- {
23817
- variant: action.variant ?? "ghost",
23818
- size: "sm",
23819
- onClick: handleActionClick(action, itemData),
23820
- "data-testid": `action-${action.event}`,
23821
- "data-row-id": String(itemData.id),
23822
- className: cn(
23823
- action.variant === "danger" && "text-error hover:bg-error/10"
23824
- ),
23825
- children: [
23826
- action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
23827
- action.label
23828
- ]
23829
- },
23830
- idx
23831
- ))
23832
- }
23833
- )
23871
+ renderItemActions(itemData)
23834
23872
  ] }),
23835
23873
  isCard && !isLast && /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "mx-6 border-b border-border/40" })
23836
23874
  ] }, id2)
@@ -23901,24 +23939,7 @@ function DataList({
23901
23939
  ] }, field.name);
23902
23940
  })
23903
23941
  ] }),
23904
- itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", className: "flex-shrink-0", children: itemActions.map((action, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
23905
- Button,
23906
- {
23907
- variant: action.variant ?? "ghost",
23908
- size: "sm",
23909
- onClick: handleActionClick(action, itemData),
23910
- "data-testid": `action-${action.event}`,
23911
- "data-row-id": String(itemData.id),
23912
- className: cn(
23913
- action.variant === "danger" && "text-error hover:bg-error/10"
23914
- ),
23915
- children: [
23916
- action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
23917
- action.label
23918
- ]
23919
- },
23920
- idx
23921
- )) })
23942
+ renderItemActions(itemData)
23922
23943
  ]
23923
23944
  }
23924
23945
  ),
@@ -23988,6 +24009,7 @@ var init_DataList = __esm({
23988
24009
  init_ProgressBar();
23989
24010
  init_Divider();
23990
24011
  init_InfiniteScrollSentinel();
24012
+ init_Menu();
23991
24013
  init_useDataDnd();
23992
24014
  dataListLog = logger.createLogger("almadar:ui:data-list");
23993
24015
  listLookStyles = {
@@ -29033,6 +29055,7 @@ function TableView({
29033
29055
  columns,
29034
29056
  fields,
29035
29057
  itemActions,
29058
+ maxInlineActions,
29036
29059
  selectable = false,
29037
29060
  selectEvent,
29038
29061
  selectedIds,
@@ -29125,10 +29148,13 @@ function TableView({
29125
29148
  }
29126
29149
  const lk = LOOKS[look];
29127
29150
  const hasActions = Boolean(itemActions && itemActions.length > 0);
29151
+ const inlineActionCount = hasActions ? maxInlineActions != null ? Math.min(itemActions.length, maxInlineActions) : itemActions.length : 0;
29152
+ const hasOverflowActions = hasActions && maxInlineActions != null && itemActions.length > maxInlineActions;
29153
+ const actionsTrack = hasActions ? `${inlineActionCount * 6 + (hasOverflowActions ? 3 : 0)}rem` : null;
29128
29154
  const gridTemplateColumns = [
29129
29155
  selectable ? "auto" : null,
29130
29156
  ...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
29131
- hasActions ? "auto" : null
29157
+ actionsTrack
29132
29158
  ].filter(Boolean).join(" ");
29133
29159
  const header = /* @__PURE__ */ jsxRuntime.jsxs(
29134
29160
  Box,
@@ -29215,22 +29241,41 @@ function TableView({
29215
29241
  }
29216
29242
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
29217
29243
  }),
29218
- 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(
29219
- Button,
29220
- {
29221
- variant: action.variant ?? "ghost",
29222
- size: "sm",
29223
- onClick: handleActionClick(action, row),
29224
- "data-testid": `action-${action.event}`,
29225
- "data-row-id": String(row.id),
29226
- className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
29227
- children: [
29228
- action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
29229
- action.label
29230
- ]
29231
- },
29232
- i
29233
- )) })
29244
+ itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "xs", className: "justify-end flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: [
29245
+ (maxInlineActions != null ? itemActions.slice(0, maxInlineActions) : itemActions).map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
29246
+ Button,
29247
+ {
29248
+ variant: action.variant ?? "ghost",
29249
+ size: "sm",
29250
+ onClick: handleActionClick(action, row),
29251
+ "data-testid": `action-${action.event}`,
29252
+ "data-row-id": String(row.id),
29253
+ className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
29254
+ children: [
29255
+ action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon, size: "xs", className: "mr-1" }),
29256
+ action.label
29257
+ ]
29258
+ },
29259
+ i
29260
+ )),
29261
+ maxInlineActions != null && itemActions.length > maxInlineActions && /* @__PURE__ */ jsxRuntime.jsx(
29262
+ Menu,
29263
+ {
29264
+ position: "bottom-end",
29265
+ 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" }) }),
29266
+ items: itemActions.slice(maxInlineActions).map((action) => ({
29267
+ label: action.label,
29268
+ icon: action.icon,
29269
+ event: action.event,
29270
+ variant: action.variant === "danger" ? "danger" : "default",
29271
+ onClick: () => eventBus.emit(`UI:${action.event}`, {
29272
+ id: row.id,
29273
+ row
29274
+ })
29275
+ }))
29276
+ }
29277
+ )
29278
+ ] })
29234
29279
  ]
29235
29280
  }
29236
29281
  );
@@ -29278,6 +29323,7 @@ var init_TableView = __esm({
29278
29323
  init_Icon();
29279
29324
  init_Checkbox();
29280
29325
  init_Divider();
29326
+ init_Menu();
29281
29327
  init_useDataDnd();
29282
29328
  logger.createLogger("almadar:ui:table-view");
29283
29329
  alignClass = {
@@ -29291,11 +29337,11 @@ var init_TableView = __esm({
29291
29337
  semibold: "font-semibold"
29292
29338
  };
29293
29339
  LOOKS = {
29294
- dense: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: true },
29295
- spacious: { rowPad: "px-5 py-4", headPad: "px-5 py-3", striped: false, divider: true },
29296
- striped: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: true, divider: false },
29297
- borderless: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: false },
29298
- bordered: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: true }
29340
+ dense: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: true },
29341
+ spacious: { rowPad: "px-card-lg py-card-md", headPad: "px-card-lg py-card-sm", striped: false, divider: true },
29342
+ striped: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: true, divider: false },
29343
+ borderless: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: false },
29344
+ bordered: { rowPad: "px-card-md py-card-sm", headPad: "px-card-md py-card-sm", striped: false, divider: true }
29299
29345
  };
29300
29346
  TableView.displayName = "TableView";
29301
29347
  }