hazo_ui 6.15.0 → 6.18.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.
package/dist/index.cjs CHANGED
@@ -877,6 +877,8 @@ var en_default = {
877
877
  "locale_picker.change_language": "Change language",
878
878
  "app_logo.alt_fallback": "Logo",
879
879
  "app_header.aria_label": "Application header",
880
+ "app_header.menu_label": "Menu",
881
+ "app_header.nav_title": "Navigation",
880
882
  "skeleton.loading_content": "Loading content",
881
883
  "spinner.loading": "Loading",
882
884
  "spinner.loading_text": "Loading...",
@@ -934,7 +936,11 @@ var en_default = {
934
936
  "charts.pct_of_first": "% of first: {{pct}}%",
935
937
  "charts.pct_of_prev": "% of prev: {{pct}}%",
936
938
  "charts.dropoff": "Drop-off: \u2212{{value}}",
937
- "toast.missing_prefix": "Missing: {{items}}"
939
+ "toast.missing_prefix": "Missing: {{items}}",
940
+ "editable_data_table.add": "Add",
941
+ "editable_data_table.delete": "Delete row",
942
+ "editable_data_table.empty": "No rows yet. Click Add to start.",
943
+ "editable_data_table.drag_to_reorder": "Drag to reorder"
938
944
  };
939
945
  var default_t = i18n.createPackageT("hazo_ui", en_default);
940
946
  var defaultHazoUiT = default_t;
@@ -12527,6 +12533,7 @@ function Logo({
12527
12533
  }
12528
12534
  function AppHeader({ identity, homeHref, navItems, actions, className }) {
12529
12535
  const t = useHazoUiT();
12536
+ const [drawerOpen, setDrawerOpen] = React27__namespace.useState(false);
12530
12537
  return /* @__PURE__ */ jsxRuntime.jsxs(
12531
12538
  "header",
12532
12539
  {
@@ -12546,9 +12553,34 @@ function AppHeader({ identity, homeHref, navItems, actions, className }) {
12546
12553
  href: homeHref
12547
12554
  }
12548
12555
  ),
12549
- navItems
12556
+ navItems && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden md:flex items-center", children: navItems })
12550
12557
  ] }),
12551
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-4", children: actions })
12558
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
12559
+ actions,
12560
+ navItems && /* @__PURE__ */ jsxRuntime.jsxs(Drawer, { open: drawerOpen, onOpenChange: setDrawerOpen, children: [
12561
+ /* @__PURE__ */ jsxRuntime.jsx(DrawerTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
12562
+ "button",
12563
+ {
12564
+ className: "md:hidden rounded-md p-1.5 hover:bg-navbar-active/10",
12565
+ "aria-label": t("app_header.menu_label"),
12566
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "h-5 w-5" })
12567
+ }
12568
+ ) }),
12569
+ /* @__PURE__ */ jsxRuntime.jsxs(DrawerContent, { children: [
12570
+ /* @__PURE__ */ jsxRuntime.jsx(DrawerTitle, { className: "sr-only", children: t("app_header.nav_title") }),
12571
+ /* @__PURE__ */ jsxRuntime.jsx(
12572
+ "div",
12573
+ {
12574
+ className: "p-4 [&_nav]:flex-col [&_nav]:gap-2 [&_nav]:items-stretch",
12575
+ onClick: (e) => {
12576
+ if (e.target.closest("a")) setDrawerOpen(false);
12577
+ },
12578
+ children: navItems
12579
+ }
12580
+ )
12581
+ ] })
12582
+ ] })
12583
+ ] })
12552
12584
  ]
12553
12585
  }
12554
12586
  );
@@ -13196,6 +13228,506 @@ function useHazoEvent(pkg, event, handler) {
13196
13228
  return () => window.removeEventListener(event_name, listener);
13197
13229
  }, [pkg, event]);
13198
13230
  }
13231
+ function EditableCell({
13232
+ value,
13233
+ type,
13234
+ options,
13235
+ defaultColorValue,
13236
+ clearable,
13237
+ onCommit,
13238
+ editable,
13239
+ forceEdit,
13240
+ onTabOut,
13241
+ onEnterDown,
13242
+ onPaste,
13243
+ onActivated
13244
+ }) {
13245
+ const [editing, setEditing] = React27.useState(false);
13246
+ const [draft, setDraft] = React27.useState(String(value ?? ""));
13247
+ const inputRef = React27.useRef(null);
13248
+ React27.useEffect(() => {
13249
+ if (forceEdit) {
13250
+ setDraft(String(value ?? ""));
13251
+ setEditing(true);
13252
+ }
13253
+ }, [forceEdit]);
13254
+ React27.useEffect(() => {
13255
+ if (editing && inputRef.current) {
13256
+ inputRef.current.focus();
13257
+ inputRef.current.select();
13258
+ if (forceEdit) {
13259
+ onActivated?.();
13260
+ }
13261
+ }
13262
+ }, [editing]);
13263
+ const commit = React27.useCallback(() => {
13264
+ setEditing(false);
13265
+ if (type === "number") {
13266
+ const n = Number(draft);
13267
+ onCommit(Number.isNaN(n) || draft.trim() === "" ? 0 : n);
13268
+ } else {
13269
+ onCommit(draft);
13270
+ }
13271
+ }, [draft, onCommit, type]);
13272
+ const cancel = React27.useCallback(() => {
13273
+ setEditing(false);
13274
+ setDraft(String(value ?? ""));
13275
+ }, [value]);
13276
+ const handleKeyDown = React27.useCallback(
13277
+ (e) => {
13278
+ if (e.key === "Enter") {
13279
+ e.preventDefault();
13280
+ onEnterDown?.();
13281
+ commit();
13282
+ } else if (e.key === "Escape") {
13283
+ e.preventDefault();
13284
+ cancel();
13285
+ } else if (e.key === "Tab") {
13286
+ const direction = e.shiftKey ? -1 : 1;
13287
+ const handled = onTabOut?.(direction) ?? false;
13288
+ if (handled) {
13289
+ e.preventDefault();
13290
+ commit();
13291
+ }
13292
+ }
13293
+ },
13294
+ [commit, cancel, onTabOut, onEnterDown]
13295
+ );
13296
+ if (!editable) {
13297
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs truncate block px-1 py-1.5", children: String(value ?? "") });
13298
+ }
13299
+ if (type === "color") {
13300
+ const colorValue = String(
13301
+ value ?? defaultColorValue ?? "#94a3b8"
13302
+ );
13303
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
13304
+ /* @__PURE__ */ jsxRuntime.jsx(
13305
+ "input",
13306
+ {
13307
+ type: "color",
13308
+ className: "h-7 w-8 cursor-pointer border border-border rounded p-0.5",
13309
+ value: colorValue,
13310
+ onChange: (e) => onCommit(e.target.value)
13311
+ }
13312
+ ),
13313
+ clearable && value != null && /* @__PURE__ */ jsxRuntime.jsx(
13314
+ "button",
13315
+ {
13316
+ type: "button",
13317
+ className: "text-xs leading-none text-muted-foreground hover:text-foreground px-0.5",
13318
+ onClick: () => onCommit(void 0),
13319
+ children: "\xD7"
13320
+ }
13321
+ )
13322
+ ] });
13323
+ }
13324
+ if (type === "select") {
13325
+ return /* @__PURE__ */ jsxRuntime.jsxs(
13326
+ Select,
13327
+ {
13328
+ value: String(value ?? ""),
13329
+ onValueChange: (v) => onCommit(v),
13330
+ children: [
13331
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-7 text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, {}) }),
13332
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: (options ?? []).map((opt) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: opt, children: opt }, opt)) })
13333
+ ]
13334
+ }
13335
+ );
13336
+ }
13337
+ if (!editing) {
13338
+ return /* @__PURE__ */ jsxRuntime.jsx(
13339
+ "span",
13340
+ {
13341
+ className: "text-xs truncate block px-1 py-1.5 cursor-text hover:bg-muted/50 rounded",
13342
+ onClick: () => {
13343
+ setDraft(String(value ?? ""));
13344
+ setEditing(true);
13345
+ },
13346
+ role: "button",
13347
+ tabIndex: 0,
13348
+ onKeyDown: (e) => {
13349
+ if (e.key === "Enter" || e.key === " ") {
13350
+ setDraft(String(value ?? ""));
13351
+ setEditing(true);
13352
+ }
13353
+ },
13354
+ children: String(value ?? "")
13355
+ }
13356
+ );
13357
+ }
13358
+ return /* @__PURE__ */ jsxRuntime.jsx(
13359
+ "input",
13360
+ {
13361
+ ref: inputRef,
13362
+ type: type === "number" ? "number" : "text",
13363
+ className: "h-7 text-xs border border-input rounded-md px-2 bg-background focus:outline-none focus:ring-1 focus:ring-ring w-full",
13364
+ value: draft,
13365
+ onChange: (e) => setDraft(e.target.value),
13366
+ onKeyDown: handleKeyDown,
13367
+ onPaste: (e) => {
13368
+ const text = e.clipboardData.getData("text/plain") || e.clipboardData.getData("text");
13369
+ if (!text) return;
13370
+ const handled = onPaste?.(text) ?? false;
13371
+ if (handled) {
13372
+ e.preventDefault();
13373
+ setEditing(false);
13374
+ }
13375
+ },
13376
+ onBlur: commit
13377
+ }
13378
+ );
13379
+ }
13380
+ var SortableRow = React27__namespace.default.memo(function SortableRow2({
13381
+ id,
13382
+ highlighted,
13383
+ children
13384
+ }) {
13385
+ const t = useHazoUiT();
13386
+ const {
13387
+ attributes,
13388
+ listeners,
13389
+ setNodeRef,
13390
+ setActivatorNodeRef,
13391
+ transform,
13392
+ transition,
13393
+ isDragging
13394
+ } = sortable.useSortable({ id });
13395
+ const style = {
13396
+ transform: utilities.CSS.Transform.toString(transform),
13397
+ transition,
13398
+ opacity: isDragging ? 0.5 : 1
13399
+ };
13400
+ return /* @__PURE__ */ jsxRuntime.jsxs(
13401
+ TableRow2,
13402
+ {
13403
+ ref: setNodeRef,
13404
+ style,
13405
+ "data-sortable-id": id,
13406
+ className: cn(highlighted && "bg-blue-50 ring-1 ring-blue-300"),
13407
+ children: [
13408
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell2, { className: "px-0 py-0.5 w-6", children: /* @__PURE__ */ jsxRuntime.jsx(
13409
+ "div",
13410
+ {
13411
+ ref: setActivatorNodeRef,
13412
+ className: "cursor-grab active:cursor-grabbing text-muted-foreground hover:text-foreground flex items-center justify-center",
13413
+ title: t("editable_data_table.drag_to_reorder"),
13414
+ ...attributes,
13415
+ ...listeners,
13416
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GripVertical, { className: "h-3.5 w-3.5" })
13417
+ }
13418
+ ) }),
13419
+ children
13420
+ ]
13421
+ }
13422
+ );
13423
+ });
13424
+ SortableRow.displayName = "SortableRow";
13425
+ var EditableTableRow = React27__namespace.default.memo(function EditableTableRow2({
13426
+ row,
13427
+ rowIndex,
13428
+ rowKey,
13429
+ isHighlighted,
13430
+ columns,
13431
+ activeEditColKey,
13432
+ deleteLabel,
13433
+ onCellCommit,
13434
+ onDeleteRow,
13435
+ onTabOutCell,
13436
+ onEnterDownCell,
13437
+ onPasteCell,
13438
+ onActivated
13439
+ }) {
13440
+ const renderCountRef = React27.useRef(0);
13441
+ renderCountRef.current += 1;
13442
+ return /* @__PURE__ */ jsxRuntime.jsxs(SortableRow, { id: rowKey, highlighted: isHighlighted, children: [
13443
+ columns.map((col, colIndex) => {
13444
+ const resolvedOptions = typeof col.options === "function" ? col.options(row) : col.options;
13445
+ return /* @__PURE__ */ jsxRuntime.jsx(
13446
+ TableCell2,
13447
+ {
13448
+ className: cn("px-1 py-0.5", col.width),
13449
+ "data-row-render-count": colIndex === 0 ? renderCountRef.current : void 0,
13450
+ children: /* @__PURE__ */ jsxRuntime.jsx(
13451
+ EditableCell,
13452
+ {
13453
+ value: row[col.key],
13454
+ type: col.type ?? "text",
13455
+ options: resolvedOptions,
13456
+ defaultColorValue: col.defaultValue?.(rowIndex),
13457
+ clearable: col.clearable,
13458
+ editable: col.editable !== false,
13459
+ forceEdit: activeEditColKey === col.key,
13460
+ onTabOut: (direction) => onTabOutCell(rowIndex, col.key, direction),
13461
+ onEnterDown: () => onEnterDownCell(rowIndex, col.key),
13462
+ onPaste: (text) => onPasteCell(rowIndex, col.key, text),
13463
+ onActivated,
13464
+ onCommit: (v) => onCellCommit(rowIndex, col.key, v)
13465
+ }
13466
+ )
13467
+ },
13468
+ col.key
13469
+ );
13470
+ }),
13471
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell2, { className: "px-0 py-0.5 w-8", children: /* @__PURE__ */ jsxRuntime.jsx(
13472
+ Button,
13473
+ {
13474
+ variant: "ghost",
13475
+ size: "icon",
13476
+ className: "h-7 w-7 text-muted-foreground hover:text-destructive",
13477
+ onClick: () => onDeleteRow(rowIndex),
13478
+ "aria-label": deleteLabel,
13479
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3 w-3" })
13480
+ }
13481
+ ) })
13482
+ ] });
13483
+ });
13484
+ EditableTableRow.displayName = "EditableTableRow";
13485
+ function EditableDataTable({
13486
+ columns,
13487
+ rows,
13488
+ onChange,
13489
+ getRowKey,
13490
+ createRow,
13491
+ highlightedKey,
13492
+ className,
13493
+ label
13494
+ }) {
13495
+ const t = useHazoUiT();
13496
+ const editableColumns = React27.useMemo(
13497
+ () => columns.filter(
13498
+ (col) => col.editable !== false && (col.type ?? "text") !== "select" && (col.type ?? "text") !== "color"
13499
+ ).map((col) => col.key),
13500
+ [columns]
13501
+ );
13502
+ const [activeEditCell, setActiveEditCell] = React27.useState(null);
13503
+ const rowsRef = React27.useRef(rows);
13504
+ rowsRef.current = rows;
13505
+ const onChangeRef = React27.useRef(onChange);
13506
+ onChangeRef.current = onChange;
13507
+ const handleTabOut = React27.useCallback(
13508
+ (rowIndex, colKey, direction) => {
13509
+ const idx = editableColumns.indexOf(colKey);
13510
+ if (idx === -1) return false;
13511
+ if (direction === 1) {
13512
+ if (idx < editableColumns.length - 1) {
13513
+ setActiveEditCell({ row: rowIndex, col: editableColumns[idx + 1] });
13514
+ return true;
13515
+ }
13516
+ if (rowIndex + 1 < rows.length) {
13517
+ setActiveEditCell({ row: rowIndex + 1, col: editableColumns[0] });
13518
+ return true;
13519
+ }
13520
+ return false;
13521
+ }
13522
+ if (idx > 0) {
13523
+ setActiveEditCell({ row: rowIndex, col: editableColumns[idx - 1] });
13524
+ return true;
13525
+ }
13526
+ if (rowIndex - 1 >= 0) {
13527
+ setActiveEditCell({
13528
+ row: rowIndex - 1,
13529
+ col: editableColumns[editableColumns.length - 1]
13530
+ });
13531
+ return true;
13532
+ }
13533
+ return false;
13534
+ },
13535
+ [editableColumns, rows.length]
13536
+ );
13537
+ const handleEnterDown = React27.useCallback(
13538
+ (rowIndex, colKey) => {
13539
+ if (rowIndex + 1 < rows.length) {
13540
+ setActiveEditCell({ row: rowIndex + 1, col: colKey });
13541
+ return true;
13542
+ }
13543
+ return false;
13544
+ },
13545
+ [rows.length]
13546
+ );
13547
+ const handlePaste = React27.useCallback(
13548
+ (rowIndex, colKey, text) => {
13549
+ const startColIdx = editableColumns.indexOf(
13550
+ colKey
13551
+ );
13552
+ if (startColIdx === -1) return false;
13553
+ const normalized = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
13554
+ const lines = normalized.split("\n");
13555
+ if (lines.length > 1 && lines[lines.length - 1] === "") {
13556
+ lines.pop();
13557
+ }
13558
+ const hasTab = normalized.includes(" ");
13559
+ const delimiter = hasTab ? " " : ",";
13560
+ const grid = lines.map((line) => line.split(delimiter));
13561
+ const isSingleCell = grid.length === 1 && grid[0].length === 1;
13562
+ if (isSingleCell) return false;
13563
+ const currentRows = rowsRef.current;
13564
+ const nextRows = currentRows.slice();
13565
+ grid.forEach((lineCells, rowOffset) => {
13566
+ const targetRowIndex = rowIndex + rowOffset;
13567
+ while (targetRowIndex >= nextRows.length) {
13568
+ nextRows.push(createRow());
13569
+ }
13570
+ const targetRow = {
13571
+ ...nextRows[targetRowIndex]
13572
+ };
13573
+ lineCells.forEach((cellValue, colOffset) => {
13574
+ const targetColIdx = startColIdx + colOffset;
13575
+ if (targetColIdx >= editableColumns.length) return;
13576
+ const targetColKey = editableColumns[targetColIdx];
13577
+ const col = columns.find((c) => c.key === targetColKey);
13578
+ if (col?.type === "number") {
13579
+ const n = Number(cellValue);
13580
+ targetRow[targetColKey] = Number.isNaN(n) || cellValue.trim() === "" ? 0 : n;
13581
+ } else {
13582
+ targetRow[targetColKey] = cellValue;
13583
+ }
13584
+ });
13585
+ nextRows[targetRowIndex] = targetRow;
13586
+ });
13587
+ onChangeRef.current(nextRows);
13588
+ return true;
13589
+ },
13590
+ [editableColumns, columns, createRow]
13591
+ );
13592
+ const handleCellChange = React27.useCallback(
13593
+ (rowIndex, colKey, value) => {
13594
+ const currentRows = rowsRef.current;
13595
+ const next = currentRows.map(
13596
+ (row, i) => i === rowIndex ? { ...row, [colKey]: value } : row
13597
+ );
13598
+ onChangeRef.current(next);
13599
+ },
13600
+ []
13601
+ );
13602
+ const handleDelete = React27.useCallback((rowIndex) => {
13603
+ const currentRows = rowsRef.current;
13604
+ onChangeRef.current(currentRows.filter((_, i) => i !== rowIndex));
13605
+ }, []);
13606
+ const onCellActivated = React27.useCallback(() => setActiveEditCell(null), []);
13607
+ const handleAdd = () => {
13608
+ onChange([...rows, createRow()]);
13609
+ };
13610
+ const sensors = core$1.useSensors(
13611
+ core$1.useSensor(core$1.PointerSensor),
13612
+ core$1.useSensor(core$1.KeyboardSensor, {
13613
+ coordinateGetter: sortable.sortableKeyboardCoordinates
13614
+ })
13615
+ );
13616
+ const rowKeys = React27.useMemo(
13617
+ () => rows.map((row, i) => getRowKey(row, i)),
13618
+ [rows, getRowKey]
13619
+ );
13620
+ const handleDragEnd = React27.useCallback(
13621
+ (event) => {
13622
+ const { active, over } = event;
13623
+ if (!over || active.id === over.id) return;
13624
+ const oldIndex = rows.findIndex(
13625
+ (row, i) => getRowKey(row, i) === active.id
13626
+ );
13627
+ const newIndex = rows.findIndex(
13628
+ (row, i) => getRowKey(row, i) === over.id
13629
+ );
13630
+ if (oldIndex === -1 || newIndex === -1) return;
13631
+ onChange(sortable.arrayMove(rows, oldIndex, newIndex));
13632
+ },
13633
+ [rows, getRowKey, onChange]
13634
+ );
13635
+ return (
13636
+ // DndContext wraps the whole component rather than just <TableBody> —
13637
+ // it renders its own hidden accessibility helpers (RestoreFocus,
13638
+ // live-region announcer) as DOM siblings of its children. Nesting it
13639
+ // directly inside <tbody> would make those helpers invalid children of
13640
+ // <tbody> (only <tr> is valid there); wrapping the outer <div> instead
13641
+ // gives them a valid home. <SortableContext> is a plain context
13642
+ // provider with no DOM output of its own, so it can stay right inside
13643
+ // <TableBody>, wrapping only the actual <tr> rows.
13644
+ /* @__PURE__ */ jsxRuntime.jsx(
13645
+ core$1.DndContext,
13646
+ {
13647
+ sensors,
13648
+ collisionDetection: core$1.closestCenter,
13649
+ onDragEnd: handleDragEnd,
13650
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-editable-data-table": true, className: cn("flex flex-col gap-1", className), children: [
13651
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-1", children: [
13652
+ label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: label }),
13653
+ /* @__PURE__ */ jsxRuntime.jsxs(
13654
+ Button,
13655
+ {
13656
+ variant: "ghost",
13657
+ size: "sm",
13658
+ className: "h-6 px-2 text-xs ml-auto",
13659
+ onClick: handleAdd,
13660
+ "aria-label": t("editable_data_table.add"),
13661
+ children: [
13662
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3 w-3 mr-1" }),
13663
+ t("editable_data_table.add")
13664
+ ]
13665
+ }
13666
+ )
13667
+ ] }),
13668
+ /* @__PURE__ */ jsxRuntime.jsxs(Table2, { children: [
13669
+ /* @__PURE__ */ jsxRuntime.jsx(TableHeader2, { children: /* @__PURE__ */ jsxRuntime.jsxs(TableRow2, { className: "bg-muted/60 hover:bg-muted/60 border-b-2 border-border", children: [
13670
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "w-6 px-0" }),
13671
+ columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx(
13672
+ TableHead,
13673
+ {
13674
+ className: cn(
13675
+ "text-[11px] font-semibold uppercase tracking-wide text-foreground px-1 py-1 h-8",
13676
+ col.width
13677
+ ),
13678
+ children: col.label
13679
+ },
13680
+ col.key
13681
+ )),
13682
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "w-8 px-0" })
13683
+ ] }) }),
13684
+ /* @__PURE__ */ jsxRuntime.jsxs(TableBody, { children: [
13685
+ rows.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(TableRow2, { children: /* @__PURE__ */ jsxRuntime.jsx(
13686
+ TableCell2,
13687
+ {
13688
+ colSpan: columns.length + 2,
13689
+ className: "text-center text-xs text-muted-foreground italic py-4",
13690
+ children: t("editable_data_table.empty")
13691
+ }
13692
+ ) }),
13693
+ /* @__PURE__ */ jsxRuntime.jsx(
13694
+ sortable.SortableContext,
13695
+ {
13696
+ items: rowKeys,
13697
+ strategy: sortable.verticalListSortingStrategy,
13698
+ children: rows.map((row, rowIndex) => {
13699
+ const key = rowKeys[rowIndex];
13700
+ const isHighlighted = highlightedKey != null && key === highlightedKey;
13701
+ const activeEditColKey = activeEditCell?.row === rowIndex ? activeEditCell.col : null;
13702
+ return /* @__PURE__ */ jsxRuntime.jsx(
13703
+ EditableTableRow,
13704
+ {
13705
+ row,
13706
+ rowIndex,
13707
+ rowKey: key,
13708
+ isHighlighted,
13709
+ columns,
13710
+ activeEditColKey,
13711
+ deleteLabel: t("editable_data_table.delete"),
13712
+ onCellCommit: handleCellChange,
13713
+ onDeleteRow: handleDelete,
13714
+ onTabOutCell: handleTabOut,
13715
+ onEnterDownCell: handleEnterDown,
13716
+ onPasteCell: handlePaste,
13717
+ onActivated: onCellActivated
13718
+ },
13719
+ key
13720
+ );
13721
+ })
13722
+ }
13723
+ )
13724
+ ] })
13725
+ ] })
13726
+ ] })
13727
+ }
13728
+ )
13729
+ );
13730
+ }
13199
13731
 
13200
13732
  Object.defineProperty(exports, "rawToast", {
13201
13733
  enumerable: true,
@@ -13288,6 +13820,7 @@ exports.DropdownMenuSub = DropdownMenuSub;
13288
13820
  exports.DropdownMenuSubContent = DropdownMenuSubContent;
13289
13821
  exports.DropdownMenuSubTrigger = DropdownMenuSubTrigger;
13290
13822
  exports.DropdownMenuTrigger = DropdownMenuTrigger;
13823
+ exports.EditableDataTable = EditableDataTable;
13291
13824
  exports.EmptyState = EmptyState;
13292
13825
  exports.ErrorBanner = ErrorBanner;
13293
13826
  exports.ErrorPage = ErrorPage;