klun-ui 0.3.0 → 0.4.1

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.
@@ -3,6 +3,9 @@
3
3
  var chunkTPGAXYFU_cjs = require('./chunk-TPGAXYFU.cjs');
4
4
  var react = require('react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
+ var core = require('@dnd-kit/core');
7
+ var sortable = require('@dnd-kit/sortable');
8
+ var utilities = require('@dnd-kit/utilities');
6
9
  var reactDom = require('react-dom');
7
10
  var client = require('react-dom/client');
8
11
 
@@ -3344,6 +3347,256 @@ var DiffViewer = react.forwardRef(function DiffViewer2({
3344
3347
  );
3345
3348
  });
3346
3349
  DiffViewer.displayName = "DiffViewer";
3350
+ function draggedCenterY(active, delta) {
3351
+ const translated = active.rect.current.translated;
3352
+ if (translated) return translated.top + translated.height / 2;
3353
+ const initial = active.rect.current.initial;
3354
+ return initial ? initial.top + delta.y + initial.height / 2 : null;
3355
+ }
3356
+ function resolveMove(columns, activeId, overId, after) {
3357
+ if (activeId === overId) return null;
3358
+ const from = columns.find((c) => c.cards.some((k2) => k2.id === activeId));
3359
+ if (!from) return null;
3360
+ const overCard = columns.flatMap((c) => c.cards).find((k2) => k2.id === overId);
3361
+ const to = overCard ? columns.find((c) => c.cards.some((k2) => k2.id === overCard.id)) : columns.find((c) => c.id === overId);
3362
+ if (!to) return null;
3363
+ const rest = to.cards.filter((k2) => k2.id !== activeId);
3364
+ const toIndex = overCard ? rest.findIndex((k2) => k2.id === overCard.id) + (after ? 1 : 0) : rest.length;
3365
+ if (to.id === from.id && from.cards.findIndex((k2) => k2.id === activeId) === toIndex) {
3366
+ return null;
3367
+ }
3368
+ return { fromColumn: from.id, toColumn: to.id, toIndex };
3369
+ }
3370
+ var Kanban = react.forwardRef(function Kanban2({
3371
+ columns = [],
3372
+ onMove,
3373
+ onCardClick,
3374
+ renderCard,
3375
+ columnFooter,
3376
+ columnWidth = 280,
3377
+ className,
3378
+ style,
3379
+ ...props
3380
+ }, ref) {
3381
+ const [over, setOver] = react.useState(null);
3382
+ const sensors = core.useSensors(
3383
+ core.useSensor(core.PointerSensor, { activationConstraint: { distance: 4 } }),
3384
+ core.useSensor(core.KeyboardSensor, { coordinateGetter: sortable.sortableKeyboardCoordinates })
3385
+ );
3386
+ const columnOf = (cardId) => columns.find((c) => c.cards.some((k2) => k2.id === cardId));
3387
+ const computeOver = ({
3388
+ active,
3389
+ delta,
3390
+ over: o
3391
+ }) => {
3392
+ if (!o) return null;
3393
+ const overId = String(o.id);
3394
+ const column = columnOf(overId);
3395
+ if (!column) return { columnId: overId };
3396
+ const centerY = draggedCenterY(active, delta);
3397
+ return {
3398
+ columnId: column.id,
3399
+ cardId: overId,
3400
+ after: centerY != null && centerY > o.rect.top + o.rect.height / 2
3401
+ };
3402
+ };
3403
+ const handleDragEnd = ({ active, delta, over: o }) => {
3404
+ setOver(null);
3405
+ if (!o) return;
3406
+ const overId = String(o.id);
3407
+ const column = columnOf(overId);
3408
+ const centerY = column ? draggedCenterY(active, delta) : null;
3409
+ const after = centerY != null && centerY > o.rect.top + o.rect.height / 2;
3410
+ const target = resolveMove(columns, String(active.id), overId, after);
3411
+ if (target) {
3412
+ onMove?.(String(active.id), target.fromColumn, target.toColumn, target.toIndex);
3413
+ }
3414
+ };
3415
+ return /* @__PURE__ */ jsxRuntime.jsx(
3416
+ "div",
3417
+ {
3418
+ ref,
3419
+ className: chunkTPGAXYFU_cjs.cx("klun-kanban", className),
3420
+ style: { ...style, ["--klun-kanban-col"]: `${columnWidth}px` },
3421
+ ...props,
3422
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3423
+ core.DndContext,
3424
+ {
3425
+ sensors,
3426
+ collisionDetection: core.closestCorners,
3427
+ onDragOver: (e) => setOver(computeOver(e)),
3428
+ onDragMove: (e) => setOver(computeOver(e)),
3429
+ onDragEnd: handleDragEnd,
3430
+ children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
3431
+ KanbanColumnView,
3432
+ {
3433
+ column,
3434
+ over,
3435
+ onCardClick,
3436
+ renderCard,
3437
+ columnFooter
3438
+ },
3439
+ column.id
3440
+ ))
3441
+ }
3442
+ )
3443
+ }
3444
+ );
3445
+ });
3446
+ Kanban.displayName = "Kanban";
3447
+ function KanbanColumnView({
3448
+ column,
3449
+ over,
3450
+ onCardClick,
3451
+ renderCard,
3452
+ columnFooter
3453
+ }) {
3454
+ const { setNodeRef } = core.useDroppable({ id: column.id });
3455
+ const isOver = over?.columnId === column.id;
3456
+ const full = column.limit !== void 0 && column.cards.length >= column.limit;
3457
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: chunkTPGAXYFU_cjs.cx("klun-kanban__column", isOver && "klun-kanban__column--over"), children: [
3458
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "klun-kanban__header", children: [
3459
+ column.accent ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-kanban__dot", style: { background: column.accent } }) : null,
3460
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-kanban__title", children: column.title }),
3461
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: chunkTPGAXYFU_cjs.cx("klun-kanban__count", full && "klun-kanban__count--full"), children: [
3462
+ column.cards.length,
3463
+ column.limit !== void 0 ? ` / ${column.limit}` : ""
3464
+ ] })
3465
+ ] }),
3466
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: setNodeRef, className: "klun-kanban__list", children: [
3467
+ /* @__PURE__ */ jsxRuntime.jsx(
3468
+ sortable.SortableContext,
3469
+ {
3470
+ items: column.cards.map((c) => c.id),
3471
+ strategy: sortable.verticalListSortingStrategy,
3472
+ children: column.cards.map((card) => /* @__PURE__ */ jsxRuntime.jsx(
3473
+ KanbanCardView,
3474
+ {
3475
+ card,
3476
+ columnId: column.id,
3477
+ dropBefore: isOver && over?.cardId === card.id && over?.after === false,
3478
+ dropAfter: isOver && over?.cardId === card.id && over?.after === true,
3479
+ onCardClick,
3480
+ renderCard
3481
+ },
3482
+ card.id
3483
+ ))
3484
+ }
3485
+ ),
3486
+ column.cards.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-kanban__empty", children: "Drop a card here" }) : null
3487
+ ] }),
3488
+ columnFooter ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-kanban__footer", children: columnFooter(column) }) : null
3489
+ ] });
3490
+ }
3491
+ function KanbanCardView({
3492
+ card,
3493
+ columnId,
3494
+ dropBefore,
3495
+ dropAfter,
3496
+ onCardClick,
3497
+ renderCard
3498
+ }) {
3499
+ const {
3500
+ attributes,
3501
+ listeners: listeners2,
3502
+ setNodeRef,
3503
+ transform,
3504
+ transition,
3505
+ isDragging
3506
+ } = sortable.useSortable({ id: card.id });
3507
+ return /* @__PURE__ */ jsxRuntime.jsx(
3508
+ "article",
3509
+ {
3510
+ ref: setNodeRef,
3511
+ ...attributes,
3512
+ ...listeners2,
3513
+ onClick: () => onCardClick?.(card, columnId),
3514
+ className: chunkTPGAXYFU_cjs.cx(
3515
+ "klun-kanban__card",
3516
+ isDragging && "klun-kanban__card--dragging",
3517
+ dropBefore && "klun-kanban__card--dropbefore",
3518
+ dropAfter && "klun-kanban__card--dropafter"
3519
+ ),
3520
+ style: {
3521
+ transform: utilities.CSS.Transform.toString(transform),
3522
+ transition,
3523
+ ...card.accent ? { boxShadow: `inset 3px 0 0 ${card.accent}` } : null
3524
+ },
3525
+ children: renderCard ? renderCard(card, columnId) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3526
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-kanban__card-title", children: card.title }),
3527
+ card.description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-kanban__card-desc", children: card.description }) : null,
3528
+ card.tags?.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-kanban__card-tags", children: card.tags.map((t, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { children: t }, i)) }) : null,
3529
+ card.meta ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-kanban__card-meta", children: card.meta }) : null
3530
+ ] })
3531
+ }
3532
+ );
3533
+ }
3534
+ function VirtualTable({
3535
+ rows = [],
3536
+ columns = [],
3537
+ rowHeight = 40,
3538
+ height = 420,
3539
+ getRowId,
3540
+ onRowClick,
3541
+ overscan = 8,
3542
+ zebra = true,
3543
+ empty,
3544
+ className,
3545
+ style,
3546
+ ...props
3547
+ }) {
3548
+ const [scrollTop, setScrollTop] = react.useState(0);
3549
+ const total = rows.length;
3550
+ const template = react.useMemo(
3551
+ () => columns.map((c) => c.width ? `${c.width}px` : "minmax(0, 1fr)").join(" "),
3552
+ [columns]
3553
+ );
3554
+ const bodyHeight = Math.max(0, height - 36);
3555
+ const start = Math.max(0, Math.floor(scrollTop / rowHeight) - overscan);
3556
+ const end = Math.min(total, Math.ceil((scrollTop + bodyHeight) / rowHeight) + overscan);
3557
+ const slice = rows.slice(start, end);
3558
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: void 0, className: chunkTPGAXYFU_cjs.cx("klun-vtable", className), style: { ...style, height }, ...props, children: [
3559
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-vtable__head", style: { gridTemplateColumns: template }, children: columns.map((c) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkTPGAXYFU_cjs.cx("klun-vtable__th", c.align && `klun-vtable__th--${c.align}`), children: c.header }, c.key)) }),
3560
+ /* @__PURE__ */ jsxRuntime.jsx(
3561
+ "div",
3562
+ {
3563
+ className: "klun-vtable__body",
3564
+ onScroll: (e) => setScrollTop(e.target.scrollTop),
3565
+ style: { maxHeight: bodyHeight },
3566
+ children: total === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-vtable__empty", children: empty ?? "No rows" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3567
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: start * rowHeight } }),
3568
+ slice.map((row, i) => {
3569
+ const index = start + i;
3570
+ const id = getRowId?.(row, index) ?? index;
3571
+ return /* @__PURE__ */ jsxRuntime.jsx(
3572
+ "div",
3573
+ {
3574
+ role: onRowClick ? "button" : void 0,
3575
+ tabIndex: onRowClick ? 0 : void 0,
3576
+ onClick: () => onRowClick?.(row, index),
3577
+ className: chunkTPGAXYFU_cjs.cx(
3578
+ "klun-vtable__row",
3579
+ zebra && index % 2 === 1 && "klun-vtable__row--zebra",
3580
+ onRowClick && "klun-vtable__row--clickable"
3581
+ ),
3582
+ style: { gridTemplateColumns: template, height: rowHeight },
3583
+ children: columns.map((c) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkTPGAXYFU_cjs.cx("klun-vtable__td", c.align && `klun-vtable__td--${c.align}`), children: c.render ? c.render(row, index) : String(row[c.key] ?? "") }, c.key))
3584
+ },
3585
+ id
3586
+ );
3587
+ }),
3588
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: Math.max(0, (total - end) * rowHeight) } })
3589
+ ] })
3590
+ }
3591
+ ),
3592
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "klun-vtable__foot", children: [
3593
+ total.toLocaleString("en-US"),
3594
+ " rows \xB7 rendering ",
3595
+ slice.length
3596
+ ] })
3597
+ ] });
3598
+ }
3599
+ VirtualTable.displayName = "VirtualTable";
3347
3600
  var Kbd = react.forwardRef(function Kbd2({ className, children, ...props }, ref) {
3348
3601
  return /* @__PURE__ */ jsxRuntime.jsx("kbd", { ref, className: chunkTPGAXYFU_cjs.cx("klun-kbd", className), ...props, children });
3349
3602
  });
@@ -3872,6 +4125,16 @@ function rowsToCsv(columns, rows) {
3872
4125
  const body = rows.map((r) => cols.map((c) => csvCell(c.copyValue ? c.copyValue(r) : r[c.key])).join(",")).join("\n");
3873
4126
  return head + "\n" + body;
3874
4127
  }
4128
+ function reorderRows(rows, fromId, toId, getRowId) {
4129
+ const ids = rows.map(getRowId);
4130
+ const from = ids.indexOf(fromId);
4131
+ const to = ids.indexOf(toId);
4132
+ if (from < 0 || to < 0 || from === to) return null;
4133
+ const next = rows.slice();
4134
+ const [moved] = next.splice(from, 1);
4135
+ next.splice(to, 0, moved);
4136
+ return { next, from, to };
4137
+ }
3875
4138
  function downloadCsv(filename, csv) {
3876
4139
  const blob = new Blob(["\uFEFF" + csv], { type: "text/csv;charset=utf-8;" });
3877
4140
  const url = URL.createObjectURL(blob);
@@ -4434,351 +4697,387 @@ function TableHead({
4434
4697
  })
4435
4698
  ] }) });
4436
4699
  }
4437
- function TableBody({
4438
- loading,
4439
- loadingRows,
4700
+ function TableRow(props) {
4701
+ if (!props.dragCol) return /* @__PURE__ */ jsxRuntime.jsx(RowBase, { ...props });
4702
+ return /* @__PURE__ */ jsxRuntime.jsx(SortableRow, { ...props });
4703
+ }
4704
+ function SortableRow(props) {
4705
+ const {
4706
+ attributes,
4707
+ listeners: listeners2,
4708
+ setNodeRef,
4709
+ setActivatorNodeRef,
4710
+ transform,
4711
+ transition,
4712
+ isDragging
4713
+ } = sortable.useSortable({ id: props.node.id });
4714
+ return /* @__PURE__ */ jsxRuntime.jsx(
4715
+ RowBase,
4716
+ {
4717
+ ...props,
4718
+ sortable: {
4719
+ attributes,
4720
+ listeners: listeners2,
4721
+ setNodeRef,
4722
+ setActivatorNodeRef,
4723
+ isDragging,
4724
+ style: { transform: utilities.CSS.Transform.toString(transform), transition }
4725
+ }
4726
+ }
4727
+ );
4728
+ }
4729
+ function RowBase({
4730
+ sortable,
4731
+ node,
4732
+ index,
4440
4733
  dragCol,
4441
- expandCol,
4442
- selectable,
4443
- visibleColumns,
4444
- pageRows,
4445
- colCount,
4446
- empty,
4447
- displayRows,
4448
- treeOpen,
4449
- setTreeOpen,
4734
+ tree,
4735
+ indentSize,
4736
+ zebra,
4450
4737
  selected,
4738
+ rowStatus,
4451
4739
  onRowClick,
4452
4740
  rowHref,
4741
+ expandCol,
4742
+ expandable,
4453
4743
  expanded,
4454
4744
  setExpanded,
4455
- expandable,
4456
- rowStatus,
4457
- drag,
4458
- setDrag,
4459
- reorder,
4460
- zebra,
4461
- contextMenu,
4462
- copyable,
4463
- copyRow,
4464
- setMenu,
4465
- leftFixed,
4466
- vBorderClass,
4745
+ treeOpen,
4746
+ setTreeOpen,
4747
+ selectable,
4467
4748
  selectionType,
4468
4749
  onSelectRow,
4750
+ visibleColumns,
4751
+ leftFixed,
4752
+ vBorderClass,
4469
4753
  fixedCell,
4470
4754
  editing,
4471
4755
  setEditing,
4472
4756
  startEdit,
4473
4757
  commitEdit,
4474
4758
  cancelEdit,
4475
- tree,
4476
- indentSize,
4759
+ contextMenu,
4760
+ copyable,
4761
+ copyRow,
4762
+ setMenu,
4763
+ colCount,
4477
4764
  onCopy
4478
4765
  }) {
4479
4766
  const { table } = useLocale();
4480
- const skel = /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-table__skel" });
4481
- return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: loading ? Array.from({ length: loadingRows }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: i ? "klun-table__row--bordered" : void 0, children: [
4482
- dragCol ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "klun-table__td" }) : null,
4483
- expandCol ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "klun-table__td", children: skel }) : null,
4484
- selectable ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "klun-table__td", children: skel }) : null,
4485
- visibleColumns.map((c) => /* @__PURE__ */ jsxRuntime.jsx("td", { className: "klun-table__td", children: skel }, c.key))
4486
- ] }, "sk" + i)) : pageRows.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: colCount, className: "klun-table__empty-cell", children: empty != null ? empty : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "klun-table__empty", children: [
4487
- /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-inbox-line klun-table__empty-icon" }),
4488
- table.noData
4489
- ] }) }) }) : displayRows.map((node, i) => {
4490
- const row = node.row;
4491
- const id = node.id;
4492
- const depth = node.depth;
4493
- const treeHasKids = node.hasChildren;
4494
- const treeIsOpen = treeOpen.has(id);
4495
- const toggleTree = () => {
4496
- const n = new Set(treeOpen);
4497
- n.has(id) ? n.delete(id) : n.add(id);
4498
- setTreeOpen(n);
4499
- };
4500
- const on = selected.includes(id);
4501
- const clickable = !!(onRowClick || rowHref);
4502
- const isOpen = expanded.has(id);
4503
- const canExpand = expandCol && (!expandable.rowExpandable || expandable.rowExpandable(row));
4504
- const toggleRow = () => {
4505
- const next = new Set(expanded);
4506
- next.has(id) ? next.delete(id) : next.add(id);
4507
- setExpanded(next);
4508
- expandable?.onExpand?.(row, !isOpen);
4509
- };
4510
- const st = rowStatus ? rowStatus(row) : null;
4511
- const dragging = !!(drag && drag.id === id);
4512
- const dropOver = !!(drag && drag.overId === id && drag.id !== id);
4513
- const borderTop = i > 0;
4514
- const tdBorder = borderTop ? "klun-table__td--bordered" : "";
4515
- return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
4516
- /* @__PURE__ */ jsxRuntime.jsxs(
4517
- "tr",
4518
- {
4519
- className: chunkTPGAXYFU_cjs.cx(
4520
- "klun-table__row",
4521
- on && "klun-table__row--selected",
4522
- zebra && i % 2 === 1 && "klun-table__row--zebra",
4523
- st && `klun-table__row--status-${st}`,
4524
- clickable && "klun-table__row--clickable",
4525
- dragging && "klun-table__row--dragging",
4526
- dropOver && "klun-table__row--dropover",
4527
- dropOver && drag.after && "klun-table__row--dropover-after"
4528
- ),
4529
- onClick: clickable ? () => rowHref ? window.location.href = rowHref(row) : onRowClick(row) : void 0,
4530
- onDragOver: dragCol && drag ? (e) => {
4531
- e.preventDefault();
4532
- const r = e.currentTarget.getBoundingClientRect();
4533
- const after = e.clientY - r.top > r.height / 2;
4534
- if (drag.overId !== id || drag.after !== after)
4535
- setDrag((dd) => dd ? { ...dd, overId: id, after } : dd);
4536
- } : void 0,
4537
- onDrop: dragCol && drag ? (e) => {
4767
+ const row = node.row;
4768
+ const id = node.id;
4769
+ const depth = node.depth;
4770
+ const treeHasKids = node.hasChildren;
4771
+ const treeIsOpen = treeOpen.has(id);
4772
+ const toggleTree = () => {
4773
+ const n = new Set(treeOpen);
4774
+ n.has(id) ? n.delete(id) : n.add(id);
4775
+ setTreeOpen(n);
4776
+ };
4777
+ const on = selected.includes(id);
4778
+ const clickable = !!(onRowClick || rowHref);
4779
+ const isOpen = expanded.has(id);
4780
+ const canExpand = expandCol && (!expandable.rowExpandable || expandable.rowExpandable(row));
4781
+ const toggleRow = () => {
4782
+ const next = new Set(expanded);
4783
+ next.has(id) ? next.delete(id) : next.add(id);
4784
+ setExpanded(next);
4785
+ expandable?.onExpand?.(row, !isOpen);
4786
+ };
4787
+ const st = rowStatus ? rowStatus(row) : null;
4788
+ const tdBorder = index > 0 ? "klun-table__td--bordered" : "";
4789
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
4790
+ /* @__PURE__ */ jsxRuntime.jsxs(
4791
+ "tr",
4792
+ {
4793
+ ref: sortable?.setNodeRef,
4794
+ style: sortable?.style,
4795
+ className: chunkTPGAXYFU_cjs.cx(
4796
+ "klun-table__row",
4797
+ on && "klun-table__row--selected",
4798
+ zebra && index % 2 === 1 && "klun-table__row--zebra",
4799
+ st && `klun-table__row--status-${st}`,
4800
+ clickable && "klun-table__row--clickable",
4801
+ sortable?.isDragging && "klun-table__row--dragging"
4802
+ ),
4803
+ onClick: clickable ? () => rowHref ? window.location.href = rowHref(row) : onRowClick(row) : void 0,
4804
+ onContextMenu: contextMenu || copyable ? (e) => {
4805
+ const custom = contextMenu ? contextMenu(row, { copyRow, copyText }) : null;
4806
+ const items2 = custom && custom.length ? custom : [
4807
+ {
4808
+ label: table.copyRow,
4809
+ icon: "ri-file-copy-line",
4810
+ onClick: () => copyRow(row)
4811
+ }
4812
+ ];
4813
+ if (items2 && items2.length) {
4538
4814
  e.preventDefault();
4539
- reorder(drag.id, id, drag.after);
4540
- setDrag(null);
4541
- } : void 0,
4542
- onContextMenu: contextMenu || copyable ? (e) => {
4543
- const custom = contextMenu ? contextMenu(row, { copyRow, copyText }) : null;
4544
- const items2 = custom && custom.length ? custom : [
4545
- {
4546
- label: table.copyRow,
4547
- icon: "ri-file-copy-line",
4548
- onClick: () => copyRow(row)
4549
- }
4550
- ];
4551
- if (items2 && items2.length) {
4552
- e.preventDefault();
4553
- setMenu({ x: e.clientX, y: e.clientY, items: items2 });
4815
+ setMenu({ x: e.clientX, y: e.clientY, items: items2 });
4816
+ }
4817
+ } : void 0,
4818
+ children: [
4819
+ dragCol ? /* @__PURE__ */ jsxRuntime.jsx(
4820
+ "td",
4821
+ {
4822
+ ref: sortable?.setActivatorNodeRef,
4823
+ ...sortable?.attributes,
4824
+ ...sortable?.listeners,
4825
+ onClick: (e) => e.stopPropagation(),
4826
+ "aria-label": table.dragToReorder,
4827
+ title: table.dragToReorder,
4828
+ className: chunkTPGAXYFU_cjs.cx("klun-table__td", "klun-table__td--util", tdBorder),
4829
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-table__draghandle", children: /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-draggable" }) })
4554
4830
  }
4555
- } : void 0,
4556
- children: [
4557
- dragCol ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: chunkTPGAXYFU_cjs.cx("klun-table__td", "klun-table__td--util", tdBorder), children: /* @__PURE__ */ jsxRuntime.jsx(
4831
+ ) : null,
4832
+ expandCol ? /* @__PURE__ */ jsxRuntime.jsx(
4833
+ "td",
4834
+ {
4835
+ className: chunkTPGAXYFU_cjs.cx(
4836
+ "klun-table__td",
4837
+ "klun-table__td--lead",
4838
+ tdBorder,
4839
+ (leftFixed.length || selectable) && "klun-table__cell--fixed klun-table__cell--fixed-body"
4840
+ ),
4841
+ style: leftFixed.length || selectable ? { left: 0 } : void 0,
4842
+ children: canExpand ? /* @__PURE__ */ jsxRuntime.jsx(
4843
+ "button",
4844
+ {
4845
+ type: "button",
4846
+ "aria-label": isOpen ? table.collapse : table.expand,
4847
+ "aria-expanded": isOpen,
4848
+ onClick: (e) => {
4849
+ e.stopPropagation();
4850
+ toggleRow();
4851
+ },
4852
+ className: "klun-table__expand-btn",
4853
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4854
+ "i",
4855
+ {
4856
+ className: chunkTPGAXYFU_cjs.cx(
4857
+ "ri-arrow-right-s-line",
4858
+ "klun-table__chevron",
4859
+ isOpen && "klun-table__chevron--open"
4860
+ )
4861
+ }
4862
+ )
4863
+ }
4864
+ ) : null
4865
+ }
4866
+ ) : null,
4867
+ selectable ? /* @__PURE__ */ jsxRuntime.jsx(
4868
+ "td",
4869
+ {
4870
+ className: chunkTPGAXYFU_cjs.cx(
4871
+ "klun-table__td",
4872
+ tdBorder,
4873
+ vBorderClass,
4874
+ leftFixed.length && "klun-table__cell--fixed klun-table__cell--fixed-body"
4875
+ ),
4876
+ style: leftFixed.length ? { left: expandCol ? 44 : 0 } : void 0,
4877
+ children: selectionType === "radio" ? /* @__PURE__ */ jsxRuntime.jsx(
4878
+ "button",
4879
+ {
4880
+ type: "button",
4881
+ role: "radio",
4882
+ "aria-checked": on,
4883
+ onClick: (e) => {
4884
+ e.stopPropagation();
4885
+ onSelectRow?.(id);
4886
+ },
4887
+ className: chunkTPGAXYFU_cjs.cx("klun-table__radio", on && "klun-table__radio--on"),
4888
+ children: on ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-table__radio-dot" }) : null
4889
+ }
4890
+ ) : /* @__PURE__ */ jsxRuntime.jsx(Check, { checked: on, onChange: () => onSelectRow?.(id) })
4891
+ }
4892
+ ) : null,
4893
+ visibleColumns.map((c, ci) => {
4894
+ const fx = fixedCell(c, false);
4895
+ const last = ci === visibleColumns.length - 1;
4896
+ const content = c.render ? c.render(row) : row[c.key];
4897
+ const inner = c.copyable ? /* @__PURE__ */ jsxRuntime.jsxs(
4558
4898
  "span",
4559
4899
  {
4560
- draggable: true,
4561
- onDragStart: (e) => {
4562
- e.stopPropagation();
4563
- setDrag({ id, overId: id, after: false });
4564
- try {
4565
- e.dataTransfer.effectAllowed = "move";
4566
- e.dataTransfer.setData("text/plain", String(id));
4567
- } catch (x) {
4568
- }
4900
+ className: "klun-table__copycell",
4901
+ onMouseEnter: (e) => {
4902
+ const b = e.currentTarget.querySelector(
4903
+ "[data-copy]"
4904
+ );
4905
+ if (b) b.style.opacity = "1";
4906
+ },
4907
+ onMouseLeave: (e) => {
4908
+ const b = e.currentTarget.querySelector(
4909
+ "[data-copy]"
4910
+ );
4911
+ if (b) b.style.opacity = "0";
4569
4912
  },
4570
- onDragEnd: () => setDrag(null),
4913
+ children: [
4914
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: c.ellipsis ? "klun-table__ellipsis" : void 0, children: content }),
4915
+ /* @__PURE__ */ jsxRuntime.jsx(
4916
+ "button",
4917
+ {
4918
+ type: "button",
4919
+ "data-copy": true,
4920
+ "aria-label": table.copy,
4921
+ onClick: (e) => {
4922
+ e.stopPropagation();
4923
+ copyText(c.copyValue ? c.copyValue(row) : row[c.key]);
4924
+ onCopy?.("cell", row, c.key);
4925
+ },
4926
+ className: "klun-table__copybtn",
4927
+ children: /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-file-copy-line" })
4928
+ }
4929
+ )
4930
+ ]
4931
+ }
4932
+ ) : content;
4933
+ const isEditing = editing && editing.id === id && editing.key === c.key;
4934
+ const editor = isEditing ? c.editor === "select" ? /* @__PURE__ */ jsxRuntime.jsx(
4935
+ "select",
4936
+ {
4937
+ autoFocus: true,
4938
+ value: editing.value ?? "",
4571
4939
  onClick: (e) => e.stopPropagation(),
4572
- "aria-label": table.dragToReorder,
4573
- title: table.dragToReorder,
4574
- className: "klun-table__draghandle",
4575
- children: /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-draggable" })
4940
+ onChange: (e) => setEditing((ed) => ed ? { ...ed, value: e.target.value } : ed),
4941
+ onBlur: commitEdit,
4942
+ onKeyDown: (e) => {
4943
+ if (e.key === "Enter") commitEdit();
4944
+ if (e.key === "Escape") cancelEdit();
4945
+ },
4946
+ className: "klun-table__editor",
4947
+ children: (c.options || []).map((o) => {
4948
+ const ov = typeof o === "object" ? o.value : o;
4949
+ const ol = typeof o === "object" ? o.label : o;
4950
+ return /* @__PURE__ */ jsxRuntime.jsx("option", { value: ov, children: ol }, ov);
4951
+ })
4576
4952
  }
4577
- ) }) : null,
4578
- expandCol ? /* @__PURE__ */ jsxRuntime.jsx(
4579
- "td",
4953
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
4954
+ "input",
4580
4955
  {
4581
- className: chunkTPGAXYFU_cjs.cx(
4582
- "klun-table__td",
4583
- "klun-table__td--lead",
4584
- tdBorder,
4585
- (leftFixed.length || selectable) && "klun-table__cell--fixed klun-table__cell--fixed-body"
4586
- ),
4587
- style: leftFixed.length || selectable ? { left: 0 } : void 0,
4588
- children: canExpand ? /* @__PURE__ */ jsxRuntime.jsx(
4589
- "button",
4590
- {
4591
- type: "button",
4592
- "aria-label": isOpen ? table.collapse : table.expand,
4593
- "aria-expanded": isOpen,
4594
- onClick: (e) => {
4595
- e.stopPropagation();
4596
- toggleRow();
4597
- },
4598
- className: "klun-table__expand-btn",
4599
- children: /* @__PURE__ */ jsxRuntime.jsx(
4600
- "i",
4601
- {
4602
- className: chunkTPGAXYFU_cjs.cx(
4603
- "ri-arrow-right-s-line",
4604
- "klun-table__chevron",
4605
- isOpen && "klun-table__chevron--open"
4606
- )
4607
- }
4608
- )
4609
- }
4610
- ) : null
4956
+ autoFocus: true,
4957
+ type: c.editor === "number" ? "number" : "text",
4958
+ value: editing.value ?? "",
4959
+ onClick: (e) => e.stopPropagation(),
4960
+ onChange: (e) => setEditing((ed) => ed ? { ...ed, value: e.target.value } : ed),
4961
+ onBlur: commitEdit,
4962
+ onKeyDown: (e) => {
4963
+ if (e.key === "Enter") commitEdit();
4964
+ if (e.key === "Escape") cancelEdit();
4965
+ },
4966
+ className: "klun-table__editor",
4967
+ style: { textAlign: c.align || "left" }
4611
4968
  }
4612
- ) : null,
4613
- selectable ? /* @__PURE__ */ jsxRuntime.jsx(
4969
+ ) : null;
4970
+ return /* @__PURE__ */ jsxRuntime.jsx(
4614
4971
  "td",
4615
4972
  {
4973
+ onDoubleClick: c.editable && !isEditing ? (e) => {
4974
+ e.stopPropagation();
4975
+ startEdit(id, c, row);
4976
+ } : void 0,
4616
4977
  className: chunkTPGAXYFU_cjs.cx(
4617
4978
  "klun-table__td",
4618
4979
  tdBorder,
4619
- vBorderClass,
4620
- leftFixed.length && "klun-table__cell--fixed klun-table__cell--fixed-body"
4980
+ isEditing && "klun-table__td--editing",
4981
+ (c.nowrap || c.ellipsis) && "klun-table__td--nowrap",
4982
+ c.ellipsis && "klun-table__td--ellipsis",
4983
+ c.editable && !isEditing && "klun-table__td--editable",
4984
+ !last && vBorderClass,
4985
+ fx.cls
4621
4986
  ),
4622
- style: leftFixed.length ? { left: expandCol ? 44 : 0 } : void 0,
4623
- children: selectionType === "radio" ? /* @__PURE__ */ jsxRuntime.jsx(
4624
- "button",
4625
- {
4626
- type: "button",
4627
- role: "radio",
4628
- "aria-checked": on,
4629
- onClick: (e) => {
4630
- e.stopPropagation();
4631
- onSelectRow?.(id);
4632
- },
4633
- className: chunkTPGAXYFU_cjs.cx("klun-table__radio", on && "klun-table__radio--on"),
4634
- children: on ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-table__radio-dot" }) : null
4635
- }
4636
- ) : /* @__PURE__ */ jsxRuntime.jsx(Check, { checked: on, onChange: () => onSelectRow?.(id) })
4637
- }
4638
- ) : null,
4639
- visibleColumns.map((c, ci) => {
4640
- const fx = fixedCell(c, false);
4641
- const last = ci === visibleColumns.length - 1;
4642
- const content = c.render ? c.render(row) : row[c.key];
4643
- const inner = c.copyable ? /* @__PURE__ */ jsxRuntime.jsxs(
4644
- "span",
4645
- {
4646
- className: "klun-table__copycell",
4647
- onMouseEnter: (e) => {
4648
- const b = e.currentTarget.querySelector(
4649
- "[data-copy]"
4650
- );
4651
- if (b) b.style.opacity = "1";
4652
- },
4653
- onMouseLeave: (e) => {
4654
- const b = e.currentTarget.querySelector(
4655
- "[data-copy]"
4656
- );
4657
- if (b) b.style.opacity = "0";
4658
- },
4659
- children: [
4660
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: c.ellipsis ? "klun-table__ellipsis" : void 0, children: content }),
4661
- /* @__PURE__ */ jsxRuntime.jsx(
4662
- "button",
4663
- {
4664
- type: "button",
4665
- "data-copy": true,
4666
- "aria-label": table.copy,
4667
- onClick: (e) => {
4668
- e.stopPropagation();
4669
- copyText(c.copyValue ? c.copyValue(row) : row[c.key]);
4670
- onCopy?.("cell", row, c.key);
4671
- },
4672
- className: "klun-table__copybtn",
4673
- children: /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-file-copy-line" })
4674
- }
4675
- )
4676
- ]
4677
- }
4678
- ) : content;
4679
- const isEditing = editing && editing.id === id && editing.key === c.key;
4680
- const editor = isEditing ? c.editor === "select" ? /* @__PURE__ */ jsxRuntime.jsx(
4681
- "select",
4682
- {
4683
- autoFocus: true,
4684
- value: editing.value ?? "",
4685
- onClick: (e) => e.stopPropagation(),
4686
- onChange: (e) => setEditing((ed) => ed ? { ...ed, value: e.target.value } : ed),
4687
- onBlur: commitEdit,
4688
- onKeyDown: (e) => {
4689
- if (e.key === "Enter") commitEdit();
4690
- if (e.key === "Escape") cancelEdit();
4691
- },
4692
- className: "klun-table__editor",
4693
- children: (c.options || []).map((o) => {
4694
- const ov = typeof o === "object" ? o.value : o;
4695
- const ol = typeof o === "object" ? o.label : o;
4696
- return /* @__PURE__ */ jsxRuntime.jsx("option", { value: ov, children: ol }, ov);
4697
- })
4698
- }
4699
- ) : /* @__PURE__ */ jsxRuntime.jsx(
4700
- "input",
4701
- {
4702
- autoFocus: true,
4703
- type: c.editor === "number" ? "number" : "text",
4704
- value: editing.value ?? "",
4705
- onClick: (e) => e.stopPropagation(),
4706
- onChange: (e) => setEditing((ed) => ed ? { ...ed, value: e.target.value } : ed),
4707
- onBlur: commitEdit,
4708
- onKeyDown: (e) => {
4709
- if (e.key === "Enter") commitEdit();
4710
- if (e.key === "Escape") cancelEdit();
4711
- },
4712
- className: "klun-table__editor",
4713
- style: { textAlign: c.align || "left" }
4714
- }
4715
- ) : null;
4716
- return /* @__PURE__ */ jsxRuntime.jsx(
4717
- "td",
4718
- {
4719
- onDoubleClick: c.editable && !isEditing ? (e) => {
4720
- e.stopPropagation();
4721
- startEdit(id, c, row);
4722
- } : void 0,
4723
- className: chunkTPGAXYFU_cjs.cx(
4724
- "klun-table__td",
4725
- tdBorder,
4726
- isEditing && "klun-table__td--editing",
4727
- (c.nowrap || c.ellipsis) && "klun-table__td--nowrap",
4728
- c.ellipsis && "klun-table__td--ellipsis",
4729
- c.editable && !isEditing && "klun-table__td--editable",
4730
- !last && vBorderClass,
4731
- fx.cls
4732
- ),
4733
- style: {
4734
- textAlign: c.align || "left",
4735
- ...c.ellipsis ? { maxWidth: c.width || 200 } : null,
4736
- ...fx.style
4737
- },
4738
- title: c.editable && !isEditing ? table.editHint : c.ellipsis && typeof content === "string" ? content : void 0,
4739
- children: isEditing ? editor : tree && ci === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "klun-table__tree-cell", children: [
4740
- /* @__PURE__ */ jsxRuntime.jsx(
4741
- "span",
4742
- {
4743
- className: "klun-table__tree-indent",
4744
- style: { width: depth * indentSize }
4745
- }
4746
- ),
4747
- treeHasKids ? /* @__PURE__ */ jsxRuntime.jsx(
4748
- "button",
4749
- {
4750
- type: "button",
4751
- "aria-label": treeIsOpen ? table.collapse : table.expand,
4752
- "aria-expanded": treeIsOpen,
4753
- onClick: (e) => {
4754
- e.stopPropagation();
4755
- toggleTree();
4756
- },
4757
- className: "klun-table__tree-toggle",
4758
- children: /* @__PURE__ */ jsxRuntime.jsx(
4759
- "i",
4760
- {
4761
- className: chunkTPGAXYFU_cjs.cx(
4762
- "ri-arrow-right-s-line",
4763
- "klun-table__chevron",
4764
- treeIsOpen && "klun-table__chevron--open"
4765
- )
4766
- }
4767
- )
4768
- }
4769
- ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-table__tree-spacer" }),
4770
- inner
4771
- ] }) : inner
4987
+ style: {
4988
+ textAlign: c.align || "left",
4989
+ ...c.ellipsis ? { maxWidth: c.width || 200 } : null,
4990
+ ...fx.style
4772
4991
  },
4773
- c.key
4774
- );
4775
- })
4776
- ]
4777
- }
4778
- ),
4779
- expandCol && isOpen ? /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "klun-table__expand-row", children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: colCount, className: "klun-table__expand-cell", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-table__expand-panel", children: expandable.render(row) }) }) }) : null
4780
- ] }, id);
4781
- }) });
4992
+ title: c.editable && !isEditing ? table.editHint : c.ellipsis && typeof content === "string" ? content : void 0,
4993
+ children: isEditing ? editor : tree && ci === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "klun-table__tree-cell", children: [
4994
+ /* @__PURE__ */ jsxRuntime.jsx(
4995
+ "span",
4996
+ {
4997
+ className: "klun-table__tree-indent",
4998
+ style: { width: depth * indentSize }
4999
+ }
5000
+ ),
5001
+ treeHasKids ? /* @__PURE__ */ jsxRuntime.jsx(
5002
+ "button",
5003
+ {
5004
+ type: "button",
5005
+ "aria-label": treeIsOpen ? table.collapse : table.expand,
5006
+ "aria-expanded": treeIsOpen,
5007
+ onClick: (e) => {
5008
+ e.stopPropagation();
5009
+ toggleTree();
5010
+ },
5011
+ className: "klun-table__tree-toggle",
5012
+ children: /* @__PURE__ */ jsxRuntime.jsx(
5013
+ "i",
5014
+ {
5015
+ className: chunkTPGAXYFU_cjs.cx(
5016
+ "ri-arrow-right-s-line",
5017
+ "klun-table__chevron",
5018
+ treeIsOpen && "klun-table__chevron--open"
5019
+ )
5020
+ }
5021
+ )
5022
+ }
5023
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-table__tree-spacer" }),
5024
+ inner
5025
+ ] }) : inner
5026
+ },
5027
+ c.key
5028
+ );
5029
+ })
5030
+ ]
5031
+ }
5032
+ ),
5033
+ expandCol && isOpen ? /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "klun-table__expand-row", children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: colCount, className: "klun-table__expand-cell", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-table__expand-panel", children: expandable.render(row) }) }) }) : null
5034
+ ] });
5035
+ }
5036
+ function TableBody({
5037
+ loading,
5038
+ loadingRows,
5039
+ pageRows,
5040
+ empty,
5041
+ displayRows,
5042
+ dragCol,
5043
+ expandCol,
5044
+ selectable,
5045
+ visibleColumns,
5046
+ colCount,
5047
+ ...row
5048
+ }) {
5049
+ const { table } = useLocale();
5050
+ const skel = /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-table__skel" });
5051
+ const bodyRows = displayRows.map((node, index) => /* @__PURE__ */ jsxRuntime.jsx(
5052
+ TableRow,
5053
+ {
5054
+ node,
5055
+ index,
5056
+ dragCol,
5057
+ expandCol,
5058
+ selectable,
5059
+ visibleColumns,
5060
+ colCount,
5061
+ ...row
5062
+ },
5063
+ node.id
5064
+ ));
5065
+ return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: loading ? Array.from({ length: loadingRows }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: i ? "klun-table__row--bordered" : void 0, children: [
5066
+ dragCol ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "klun-table__td" }) : null,
5067
+ expandCol ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "klun-table__td", children: skel }) : null,
5068
+ selectable ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "klun-table__td", children: skel }) : null,
5069
+ visibleColumns.map((c) => /* @__PURE__ */ jsxRuntime.jsx("td", { className: "klun-table__td", children: skel }, c.key))
5070
+ ] }, "sk" + i)) : pageRows.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: colCount, className: "klun-table__empty-cell", children: empty != null ? empty : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "klun-table__empty", children: [
5071
+ /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-inbox-line klun-table__empty-icon" }),
5072
+ table.noData
5073
+ ] }) }) }) : dragCol ? /* @__PURE__ */ jsxRuntime.jsx(
5074
+ sortable.SortableContext,
5075
+ {
5076
+ items: displayRows.map((n) => n.id),
5077
+ strategy: sortable.verticalListSortingStrategy,
5078
+ children: bodyRows
5079
+ }
5080
+ ) : bodyRows });
4782
5081
  }
4783
5082
  function TableFooter({
4784
5083
  summary,
@@ -4981,28 +5280,6 @@ function useExpandedRows({
4981
5280
  }, [tree, pageRows, treeOpen, childrenKey, getRowId]);
4982
5281
  return { treeOpen, setTreeOpen, expanded, setExpanded, displayRows };
4983
5282
  }
4984
- function useRowReorder({
4985
- rows,
4986
- getRowId,
4987
- onReorder
4988
- }) {
4989
- const [drag, setDrag] = react.useState(null);
4990
- const reorder = (fromId, toId, after) => {
4991
- if (fromId === toId) return;
4992
- const ids = rows.map(getRowId);
4993
- const from = ids.indexOf(fromId);
4994
- const to = ids.indexOf(toId);
4995
- if (from < 0 || to < 0) return;
4996
- const next = rows.slice();
4997
- const [moved] = next.splice(from, 1);
4998
- let insert = rows.findIndex((r, i) => getRowId(r, i) === toId);
4999
- if (after) insert += 1;
5000
- if (from < insert) insert -= 1;
5001
- next.splice(insert, 0, moved);
5002
- onReorder?.(next, from, insert);
5003
- };
5004
- return { drag, setDrag, reorder };
5005
- }
5006
5283
  function useCellEdit({
5007
5284
  columns,
5008
5285
  rows,
@@ -5026,6 +5303,27 @@ function useCellEdit({
5026
5303
  const cancelEdit = () => setEditing(null);
5027
5304
  return { editing, setEditing, startEdit, commitEdit, cancelEdit };
5028
5305
  }
5306
+ var dragModifiers = [({ transform }) => ({ ...transform, x: 0 })];
5307
+ function RowsDnd({
5308
+ enabled,
5309
+ sensors,
5310
+ onDragEnd,
5311
+ instructions,
5312
+ children
5313
+ }) {
5314
+ if (!enabled) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
5315
+ return /* @__PURE__ */ jsxRuntime.jsx(
5316
+ core.DndContext,
5317
+ {
5318
+ sensors,
5319
+ collisionDetection: core.closestCenter,
5320
+ modifiers: dragModifiers,
5321
+ onDragEnd,
5322
+ accessibility: { screenReaderInstructions: { draggable: instructions } },
5323
+ children
5324
+ }
5325
+ );
5326
+ }
5029
5327
  var DENSITY = {
5030
5328
  compact: "klun-table--compact",
5031
5329
  comfortable: "klun-table--comfortable",
@@ -5039,7 +5337,7 @@ function Table({
5039
5337
  selected = [],
5040
5338
  onSelectRow,
5041
5339
  onSelectAll,
5042
- sortable = false,
5340
+ sortable: sortable$1 = false,
5043
5341
  sort,
5044
5342
  onSortChange,
5045
5343
  defaultSort = null,
@@ -5172,7 +5470,16 @@ function Table({
5172
5470
  );
5173
5471
  const showToolbar = title != null || toolbar != null || !!exportable || columnSettings;
5174
5472
  const clearSelection = () => onSelectAll && onSelectAll([]);
5175
- const { drag, setDrag, reorder } = useRowReorder({ rows, getRowId, onReorder });
5473
+ const { table: t } = useLocale();
5474
+ const sensors = core.useSensors(
5475
+ core.useSensor(core.PointerSensor, { activationConstraint: { distance: 4 } }),
5476
+ core.useSensor(core.KeyboardSensor, { coordinateGetter: sortable.sortableKeyboardCoordinates })
5477
+ );
5478
+ const handleDragEnd = ({ active, over }) => {
5479
+ if (!over) return;
5480
+ const moved = reorderRows(rows, active.id, over.id, getRowId);
5481
+ if (moved) onReorder?.(moved.next, moved.from, moved.to);
5482
+ };
5176
5483
  const { editing, setEditing, startEdit, commitEdit, cancelEdit } = useCellEdit({
5177
5484
  columns,
5178
5485
  rows,
@@ -5215,113 +5522,119 @@ function Table({
5215
5522
  }
5216
5523
  ),
5217
5524
  /* @__PURE__ */ jsxRuntime.jsx(
5218
- "div",
5525
+ RowsDnd,
5219
5526
  {
5220
- className: "klun-table__scroller",
5221
- style: stickyHeader ? {
5222
- ["--klun-table-max-height"]: `${style && style.maxHeight || 420}${typeof (style && style.maxHeight) === "number" ? "px" : ""}`
5223
- } : void 0,
5224
- children: /* @__PURE__ */ jsxRuntime.jsxs(
5225
- "table",
5527
+ enabled: dragCol,
5528
+ sensors,
5529
+ onDragEnd: handleDragEnd,
5530
+ instructions: t.dragToReorder,
5531
+ children: /* @__PURE__ */ jsxRuntime.jsx(
5532
+ "div",
5226
5533
  {
5227
- className: chunkTPGAXYFU_cjs.cx(
5228
- "klun-table__table",
5229
- Object.keys(colW).length && "klun-table__table--fixed-layout"
5230
- ),
5231
- children: [
5232
- /* @__PURE__ */ jsxRuntime.jsxs("colgroup", { children: [
5233
- dragCol ? /* @__PURE__ */ jsxRuntime.jsx("col", { className: "klun-table__col-util" }) : null,
5234
- expandCol ? /* @__PURE__ */ jsxRuntime.jsx("col", { className: "klun-table__col-lead" }) : null,
5235
- selectable ? /* @__PURE__ */ jsxRuntime.jsx("col", { className: "klun-table__col-lead" }) : null,
5236
- columns.map((c) => {
5237
- const w = widthOf(c);
5238
- return hiddenCols.has(c.key) ? null : /* @__PURE__ */ jsxRuntime.jsx("col", { style: w ? { width: w } : void 0 }, c.key);
5239
- })
5240
- ] }),
5241
- caption ? /* @__PURE__ */ jsxRuntime.jsx("caption", { className: "klun-table__caption", children: caption }) : null,
5242
- /* @__PURE__ */ jsxRuntime.jsx(
5243
- TableHead,
5244
- {
5245
- dragCol,
5246
- expandCol,
5247
- selectable,
5248
- leftFixed,
5249
- vBorderClass,
5250
- selectionType,
5251
- allOn,
5252
- someOn,
5253
- toggleAll,
5254
- visibleColumns,
5255
- sortable,
5256
- activeSort,
5257
- resizable,
5258
- widthOf,
5259
- fixedCell,
5260
- setSort,
5261
- activeFilters,
5262
- setFilter,
5263
- startResize
5264
- }
5265
- ),
5266
- /* @__PURE__ */ jsxRuntime.jsx(
5267
- TableBody,
5268
- {
5269
- loading,
5270
- loadingRows,
5271
- dragCol,
5272
- expandCol,
5273
- selectable,
5274
- visibleColumns,
5275
- pageRows,
5276
- colCount,
5277
- empty,
5278
- displayRows,
5279
- treeOpen,
5280
- setTreeOpen,
5281
- selected,
5282
- onRowClick,
5283
- rowHref,
5284
- expanded,
5285
- setExpanded,
5286
- expandable,
5287
- rowStatus,
5288
- drag,
5289
- setDrag,
5290
- reorder,
5291
- zebra,
5292
- contextMenu,
5293
- copyable,
5294
- copyRow,
5295
- setMenu,
5296
- leftFixed,
5297
- vBorderClass,
5298
- selectionType,
5299
- onSelectRow,
5300
- fixedCell,
5301
- editing,
5302
- setEditing,
5303
- startEdit,
5304
- commitEdit,
5305
- cancelEdit,
5306
- tree,
5307
- indentSize,
5308
- onCopy
5309
- }
5310
- ),
5311
- /* @__PURE__ */ jsxRuntime.jsx(
5312
- TableFooter,
5313
- {
5314
- summary,
5315
- expandCol,
5316
- selectable,
5317
- pageRows,
5318
- visibleColumns,
5319
- vBorderClass,
5320
- footer,
5321
- colCount
5322
- }
5323
- )
5324
- ]
5534
+ className: "klun-table__scroller",
5535
+ style: stickyHeader ? {
5536
+ ["--klun-table-max-height"]: `${style && style.maxHeight || 420}${typeof (style && style.maxHeight) === "number" ? "px" : ""}`
5537
+ } : void 0,
5538
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
5539
+ "table",
5540
+ {
5541
+ className: chunkTPGAXYFU_cjs.cx(
5542
+ "klun-table__table",
5543
+ Object.keys(colW).length && "klun-table__table--fixed-layout"
5544
+ ),
5545
+ children: [
5546
+ /* @__PURE__ */ jsxRuntime.jsxs("colgroup", { children: [
5547
+ dragCol ? /* @__PURE__ */ jsxRuntime.jsx("col", { className: "klun-table__col-util" }) : null,
5548
+ expandCol ? /* @__PURE__ */ jsxRuntime.jsx("col", { className: "klun-table__col-lead" }) : null,
5549
+ selectable ? /* @__PURE__ */ jsxRuntime.jsx("col", { className: "klun-table__col-lead" }) : null,
5550
+ columns.map((c) => {
5551
+ const w = widthOf(c);
5552
+ return hiddenCols.has(c.key) ? null : /* @__PURE__ */ jsxRuntime.jsx("col", { style: w ? { width: w } : void 0 }, c.key);
5553
+ })
5554
+ ] }),
5555
+ caption ? /* @__PURE__ */ jsxRuntime.jsx("caption", { className: "klun-table__caption", children: caption }) : null,
5556
+ /* @__PURE__ */ jsxRuntime.jsx(
5557
+ TableHead,
5558
+ {
5559
+ dragCol,
5560
+ expandCol,
5561
+ selectable,
5562
+ leftFixed,
5563
+ vBorderClass,
5564
+ selectionType,
5565
+ allOn,
5566
+ someOn,
5567
+ toggleAll,
5568
+ visibleColumns,
5569
+ sortable: sortable$1,
5570
+ activeSort,
5571
+ resizable,
5572
+ widthOf,
5573
+ fixedCell,
5574
+ setSort,
5575
+ activeFilters,
5576
+ setFilter,
5577
+ startResize
5578
+ }
5579
+ ),
5580
+ /* @__PURE__ */ jsxRuntime.jsx(
5581
+ TableBody,
5582
+ {
5583
+ loading,
5584
+ loadingRows,
5585
+ dragCol,
5586
+ expandCol,
5587
+ selectable,
5588
+ visibleColumns,
5589
+ pageRows,
5590
+ colCount,
5591
+ empty,
5592
+ displayRows,
5593
+ treeOpen,
5594
+ setTreeOpen,
5595
+ selected,
5596
+ onRowClick,
5597
+ rowHref,
5598
+ expanded,
5599
+ setExpanded,
5600
+ expandable,
5601
+ rowStatus,
5602
+ zebra,
5603
+ contextMenu,
5604
+ copyable,
5605
+ copyRow,
5606
+ setMenu,
5607
+ leftFixed,
5608
+ vBorderClass,
5609
+ selectionType,
5610
+ onSelectRow,
5611
+ fixedCell,
5612
+ editing,
5613
+ setEditing,
5614
+ startEdit,
5615
+ commitEdit,
5616
+ cancelEdit,
5617
+ tree,
5618
+ indentSize,
5619
+ onCopy
5620
+ }
5621
+ ),
5622
+ /* @__PURE__ */ jsxRuntime.jsx(
5623
+ TableFooter,
5624
+ {
5625
+ summary,
5626
+ expandCol,
5627
+ selectable,
5628
+ pageRows,
5629
+ visibleColumns,
5630
+ vBorderClass,
5631
+ footer,
5632
+ colCount
5633
+ }
5634
+ )
5635
+ ]
5636
+ }
5637
+ )
5325
5638
  }
5326
5639
  )
5327
5640
  }
@@ -7499,6 +7812,149 @@ var CompactSelectForInput = react.forwardRef(function CompactSelectForInput2({
7499
7812
  );
7500
7813
  });
7501
7814
  CompactSelectForInput.displayName = "CompactSelectForInput";
7815
+ var CRON_PRESETS = [
7816
+ { label: "Every 5 minutes", value: "*/5 * * * *" },
7817
+ { label: "Every 15 minutes", value: "*/15 * * * *" },
7818
+ { label: "Hourly", value: "0 * * * *" },
7819
+ { label: "Every day at 03:00", value: "0 3 * * *" },
7820
+ { label: "Weekdays at 09:00", value: "0 9 * * 1-5" },
7821
+ { label: "Mondays at 09:00", value: "0 9 * * 1" },
7822
+ { label: "1st of the month", value: "0 6 1 * *" }
7823
+ ];
7824
+ var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
7825
+ var DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
7826
+ var pad = (n) => n.padStart(2, "0");
7827
+ function describeCron(cron) {
7828
+ const parts = cron.trim().split(/\s+/);
7829
+ if (parts.length !== 5) return cron;
7830
+ const [min, hour, day, month, week] = parts;
7831
+ const everyMin = min.startsWith("*/") ? `every ${min.slice(2)} minutes` : min === "*" ? "every minute" : null;
7832
+ const at = hour === "*" ? "" : ` at ${pad(hour)}:${pad(min)}`;
7833
+ const dayPart = week === "*" && day === "*" ? month === "*" ? "every day" : `on day ${day} of month ${month}` : week !== "*" ? `on ${week.split(",").map((w) => w.includes("-") ? w.split("-").map((x) => DAYS[Number(x)] ?? x).join("\u2013") : DAYS[Number(w)] ?? w).join(", ")}` : `on day ${day} of the month`;
7834
+ if (everyMin) return `${everyMin.charAt(0).toUpperCase()}${everyMin.slice(1)}${at}`;
7835
+ if (min !== "*" && hour !== "*" && day === "*" && week === "*") {
7836
+ return `${month === "*" ? "Every day" : `On day ${day} of month ${MONTHS[Number(month) - 1] ?? month}`}${at}`;
7837
+ }
7838
+ return `${dayPart.charAt(0).toUpperCase()}${dayPart.slice(1)}${at}`;
7839
+ }
7840
+ function parse(cron) {
7841
+ const p = cron.trim().split(/\s+/);
7842
+ return [p[0] ?? "*", p[1] ?? "*", p[2] ?? "*", p[3] ?? "*", p[4] ?? "*"];
7843
+ }
7844
+ var CronEditor = react.forwardRef(function CronEditor2({
7845
+ value,
7846
+ defaultValue = "0 3 * * *",
7847
+ onChange,
7848
+ hidePresets = false,
7849
+ disabled = false,
7850
+ size: sizeProp,
7851
+ labels,
7852
+ className,
7853
+ style,
7854
+ ...props
7855
+ }, ref) {
7856
+ const size = useSize(sizeProp) === "small" ? "small" : "medium";
7857
+ const text = {
7858
+ minute: "Minute",
7859
+ hour: "Hour",
7860
+ day: "Day",
7861
+ month: "Month",
7862
+ weekday: "Weekday",
7863
+ every: "Every",
7864
+ expression: "Expression",
7865
+ ...labels
7866
+ };
7867
+ const [inner, setInner] = react.useState(defaultValue);
7868
+ const current = value ?? inner;
7869
+ const [fields, setFields] = react.useState(parse(current));
7870
+ react.useEffect(() => {
7871
+ setFields(parse(current));
7872
+ }, [current]);
7873
+ const commit = (next) => {
7874
+ if (value === void 0) setInner(next);
7875
+ onChange?.(next);
7876
+ };
7877
+ const setField = (index, next) => {
7878
+ const copy = [...fields];
7879
+ copy[index] = next;
7880
+ setFields(copy);
7881
+ commit(copy.join(" "));
7882
+ };
7883
+ const options = react.useMemo(
7884
+ () => ({
7885
+ minute: ["*", "*/5", "*/10", "*/15", "*/30", "0", "15", "30", "45"],
7886
+ hour: ["*", ...Array.from({ length: 24 }, (_, i) => String(i))],
7887
+ day: ["*", ...Array.from({ length: 31 }, (_, i) => String(i + 1))],
7888
+ month: ["*", ...Array.from({ length: 12 }, (_, i) => String(i + 1))],
7889
+ weekday: ["*", "1-5", "0", "1", "2", "3", "4", "5", "6"]
7890
+ }),
7891
+ []
7892
+ );
7893
+ const fieldLabel = (key, v) => {
7894
+ if (v === "*") return text.every;
7895
+ if (key === "month") return MONTHS[Number(v) - 1] ?? v;
7896
+ if (key === "weekday") return v.includes("-") ? "Mon\u2013Fri" : DAYS[Number(v)] ?? v;
7897
+ if (key === "hour") return `${pad(v)}:00`;
7898
+ return v;
7899
+ };
7900
+ const desc = describeCron(current);
7901
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7902
+ "div",
7903
+ {
7904
+ ref,
7905
+ className: chunkTPGAXYFU_cjs.cx("klun-cron", `klun-cron--${size}`, disabled && "klun-cron--disabled", className),
7906
+ style,
7907
+ ...props,
7908
+ children: [
7909
+ !hidePresets ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-cron__presets", children: CRON_PRESETS.map((p) => /* @__PURE__ */ jsxRuntime.jsx(
7910
+ "button",
7911
+ {
7912
+ type: "button",
7913
+ disabled,
7914
+ onClick: () => commit(p.value),
7915
+ "data-active": current === p.value || void 0,
7916
+ className: "klun-cron__preset",
7917
+ children: p.label
7918
+ },
7919
+ p.value
7920
+ )) }) : null,
7921
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-cron__fields", children: ["minute", "hour", "day", "month", "weekday"].map((key, i) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "klun-cron__field", children: [
7922
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-cron__field-label", children: text[key] }),
7923
+ /* @__PURE__ */ jsxRuntime.jsx(
7924
+ "select",
7925
+ {
7926
+ disabled,
7927
+ value: fields[i],
7928
+ onChange: (e) => setField(i, e.target.value),
7929
+ className: "klun-cron__select",
7930
+ children: options[key].map((v) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: v, children: fieldLabel(key, v) }, v))
7931
+ }
7932
+ )
7933
+ ] }, key)) }),
7934
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "klun-cron__footer", children: [
7935
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "klun-cron__raw", children: [
7936
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "klun-cron__field-label", children: text.expression }),
7937
+ /* @__PURE__ */ jsxRuntime.jsx(
7938
+ "input",
7939
+ {
7940
+ disabled,
7941
+ value: current,
7942
+ onChange: (e) => commit(e.target.value),
7943
+ spellCheck: false,
7944
+ className: "klun-cron__input"
7945
+ }
7946
+ )
7947
+ ] }),
7948
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "klun-cron__preview", children: [
7949
+ /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-time-line" }),
7950
+ desc
7951
+ ] })
7952
+ ] })
7953
+ ]
7954
+ }
7955
+ );
7956
+ });
7957
+ CronEditor.displayName = "CronEditor";
7502
7958
  var CounterInput = react.forwardRef(function CounterInput2({
7503
7959
  value = 0,
7504
7960
  min = -Infinity,
@@ -7928,7 +8384,7 @@ var DateRangePicker = react.forwardRef(
7928
8384
  }
7929
8385
  );
7930
8386
  DateRangePicker.displayName = "DateRangePicker";
7931
- var pad = (n) => String(n).padStart(2, "0");
8387
+ var pad2 = (n) => String(n).padStart(2, "0");
7932
8388
  var TimePicker = react.forwardRef(
7933
8389
  function TimePicker2({ value = "09:00", onChange, className, style, ...props }, ref) {
7934
8390
  const t = useLocale();
@@ -7938,7 +8394,7 @@ var TimePicker = react.forwardRef(
7938
8394
  const set = (nh, nm, nmer) => {
7939
8395
  let hh = nh % 12;
7940
8396
  if (nmer === "PM") hh += 12;
7941
- onChange?.(`${pad(hh)}:${pad(nm)}`);
8397
+ onChange?.(`${pad2(hh)}:${pad2(nm)}`);
7942
8398
  };
7943
8399
  const [open, setOpen] = react.useState(null);
7944
8400
  const rootRef = react.useRef(null);
@@ -7957,11 +8413,11 @@ var TimePicker = react.forwardRef(
7957
8413
  }, [open]);
7958
8414
  const hourOpts = Array.from({ length: 12 }, (_, i) => ({
7959
8415
  value: String(i + 1),
7960
- label: pad(i + 1)
8416
+ label: pad2(i + 1)
7961
8417
  }));
7962
8418
  const minOpts = Array.from({ length: 60 }, (_, i) => ({
7963
8419
  value: String(i),
7964
- label: pad(i)
8420
+ label: pad2(i)
7965
8421
  }));
7966
8422
  const merOpts = [
7967
8423
  { value: "AM", label: t.timePicker.am },
@@ -8128,7 +8584,7 @@ function TimeColumn({
8128
8584
  ] });
8129
8585
  }
8130
8586
  TimePicker.displayName = "TimePicker";
8131
- var pad2 = (n) => String(n).padStart(2, "0");
8587
+ var pad3 = (n) => String(n).padStart(2, "0");
8132
8588
  var DEFAULT_FORMAT3 = {
8133
8589
  year: "numeric",
8134
8590
  month: "short",
@@ -8137,7 +8593,7 @@ var DEFAULT_FORMAT3 = {
8137
8593
  minute: "2-digit"
8138
8594
  };
8139
8595
  function DateTimePanel({ value, onChange }) {
8140
- const hhmm = value ? `${pad2(value.getHours())}:${pad2(value.getMinutes())}` : "09:00";
8596
+ const hhmm = value ? `${pad3(value.getHours())}:${pad3(value.getMinutes())}` : "09:00";
8141
8597
  const setDate = (d) => {
8142
8598
  const next = new Date(d);
8143
8599
  if (value) next.setHours(value.getHours(), value.getMinutes(), 0, 0);
@@ -9120,6 +9576,192 @@ var RichEditorToolbar = react.forwardRef(
9120
9576
  }
9121
9577
  );
9122
9578
  RichEditorToolbar.displayName = "RichEditorToolbar";
9579
+ var Textarea = react.forwardRef(function Textarea2({ error = false, disabled = false, readOnly = false, size: sizeProp, rows = 4, className, style, ...props }, ref) {
9580
+ const size = useSize(sizeProp);
9581
+ return /* @__PURE__ */ jsxRuntime.jsx(
9582
+ "div",
9583
+ {
9584
+ className: chunkTPGAXYFU_cjs.cx(
9585
+ "klun-textarea",
9586
+ `klun-textarea--${size}`,
9587
+ error && "klun-textarea--error",
9588
+ disabled && "klun-textarea--disabled",
9589
+ readOnly && "klun-textarea--readonly",
9590
+ className
9591
+ ),
9592
+ style,
9593
+ children: /* @__PURE__ */ jsxRuntime.jsx(
9594
+ "textarea",
9595
+ {
9596
+ ref,
9597
+ className: "klun-textarea__field",
9598
+ rows,
9599
+ disabled,
9600
+ readOnly,
9601
+ ...props
9602
+ }
9603
+ )
9604
+ }
9605
+ );
9606
+ });
9607
+ Textarea.displayName = "Textarea";
9608
+ function runCommand(id) {
9609
+ const exec = (cmd, arg) => document.execCommand(cmd, false, arg);
9610
+ if (typeof document.execCommand !== "function") return;
9611
+ switch (id) {
9612
+ case "bold":
9613
+ case "italic":
9614
+ case "underline":
9615
+ case "strikeThrough":
9616
+ exec(id);
9617
+ break;
9618
+ case "strike":
9619
+ exec("strikeThrough");
9620
+ break;
9621
+ case "h1":
9622
+ exec("formatBlock", "<h1>");
9623
+ break;
9624
+ case "h2":
9625
+ exec("formatBlock", "<h2>");
9626
+ break;
9627
+ case "quote":
9628
+ exec("formatBlock", "<blockquote>");
9629
+ break;
9630
+ case "code":
9631
+ exec("formatBlock", "<pre>");
9632
+ break;
9633
+ case "ul":
9634
+ exec("insertUnorderedList");
9635
+ break;
9636
+ case "ol":
9637
+ exec("insertOrderedList");
9638
+ break;
9639
+ case "link": {
9640
+ const url = typeof window !== "undefined" ? window.prompt("Link URL", "https://") : null;
9641
+ if (url) exec("createLink", url);
9642
+ break;
9643
+ }
9644
+ case "image": {
9645
+ const url = typeof window !== "undefined" ? window.prompt("Image URL", "https://") : null;
9646
+ if (url) exec("insertImage", url);
9647
+ break;
9648
+ }
9649
+ }
9650
+ }
9651
+ var RichEditor = react.forwardRef(function RichEditor2({
9652
+ value,
9653
+ defaultValue = "",
9654
+ onChange,
9655
+ placeholder = "Write something\u2026",
9656
+ disabled = false,
9657
+ hideToolbar = false,
9658
+ minHeight = 160,
9659
+ maxHeight,
9660
+ allowSource = true,
9661
+ editorLabel = "Rich text editor",
9662
+ className,
9663
+ style,
9664
+ ...props
9665
+ }, ref) {
9666
+ const editorRef = react.useRef(null);
9667
+ const [active, setActive] = react.useState([]);
9668
+ const [source, setSource] = react.useState(false);
9669
+ const [html, setHtml] = react.useState(value ?? defaultValue);
9670
+ react.useEffect(() => {
9671
+ const el = editorRef.current;
9672
+ if (!el) return;
9673
+ const next = value ?? html;
9674
+ if (document.activeElement !== el && el.innerHTML !== next) el.innerHTML = next;
9675
+ }, [value]);
9676
+ react.useEffect(() => {
9677
+ if (disabled || typeof document.execCommand !== "function") return;
9678
+ document.execCommand("defaultParagraphSeparator", false, "p");
9679
+ }, [disabled]);
9680
+ const emit2 = () => {
9681
+ const next = editorRef.current?.innerHTML ?? "";
9682
+ setHtml(next);
9683
+ onChange?.(next);
9684
+ };
9685
+ const syncActive = () => {
9686
+ if (typeof document.queryCommandState !== "function") return;
9687
+ const next = [];
9688
+ ["bold", "italic", "underline"].forEach((c) => {
9689
+ if (document.queryCommandState(c)) next.push(c);
9690
+ });
9691
+ setActive(next);
9692
+ };
9693
+ const onAction = (id) => {
9694
+ if (disabled) return;
9695
+ editorRef.current?.focus();
9696
+ runCommand(id);
9697
+ emit2();
9698
+ syncActive();
9699
+ };
9700
+ const setRefs = (node) => {
9701
+ editorRef.current = node;
9702
+ if (typeof ref === "function") ref(node);
9703
+ else if (ref) ref.current = node;
9704
+ };
9705
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9706
+ "div",
9707
+ {
9708
+ className: chunkTPGAXYFU_cjs.cx("klun-rich-editor", disabled && "klun-rich-editor--disabled", className),
9709
+ style,
9710
+ ...props,
9711
+ children: [
9712
+ !hideToolbar ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "klun-rich-editor__bar", children: [
9713
+ /* @__PURE__ */ jsxRuntime.jsx(RichEditorToolbar, { active, onAction }),
9714
+ allowSource ? /* @__PURE__ */ jsxRuntime.jsxs(
9715
+ "button",
9716
+ {
9717
+ type: "button",
9718
+ className: "klun-rich-editor__source",
9719
+ onClick: () => setSource((s) => !s),
9720
+ "data-active": source || void 0,
9721
+ "aria-pressed": source,
9722
+ children: [
9723
+ /* @__PURE__ */ jsxRuntime.jsx("i", { className: "ri-code-s-slash-line" }),
9724
+ "HTML"
9725
+ ]
9726
+ }
9727
+ ) : null
9728
+ ] }) : null,
9729
+ source && allowSource ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "klun-rich-editor__sourcearea", children: /* @__PURE__ */ jsxRuntime.jsx(
9730
+ Textarea,
9731
+ {
9732
+ rows: Math.max(4, Math.round(minHeight / 22)),
9733
+ value: html,
9734
+ style: { border: "none", boxShadow: "none", fontFamily: "var(--klun-font-mono, monospace)" },
9735
+ onChange: (e) => {
9736
+ setHtml(e.target.value);
9737
+ onChange?.(e.target.value);
9738
+ if (editorRef.current) editorRef.current.innerHTML = e.target.value;
9739
+ }
9740
+ }
9741
+ ) }) : null,
9742
+ /* @__PURE__ */ jsxRuntime.jsx(
9743
+ "div",
9744
+ {
9745
+ ref: setRefs,
9746
+ role: "textbox",
9747
+ "aria-multiline": "true",
9748
+ "aria-label": editorLabel,
9749
+ contentEditable: !disabled,
9750
+ suppressContentEditableWarning: true,
9751
+ "data-placeholder": placeholder,
9752
+ className: "klun-rich-editor__area",
9753
+ style: { minHeight, maxHeight, overflowY: maxHeight ? "auto" : void 0 },
9754
+ onInput: emit2,
9755
+ onBlur: emit2,
9756
+ onKeyUp: syncActive,
9757
+ onMouseUp: syncActive
9758
+ }
9759
+ )
9760
+ ]
9761
+ }
9762
+ );
9763
+ });
9764
+ RichEditor.displayName = "RichEditor";
9123
9765
  var Select = react.forwardRef(function Select2({
9124
9766
  size: sizeProp,
9125
9767
  placeholder,
@@ -9399,35 +10041,6 @@ var Switch = react.forwardRef(function Switch2({ disabled = false, size: sizePro
9399
10041
  );
9400
10042
  });
9401
10043
  Switch.displayName = "Switch";
9402
- var Textarea = react.forwardRef(function Textarea2({ error = false, disabled = false, readOnly = false, size: sizeProp, rows = 4, className, style, ...props }, ref) {
9403
- const size = useSize(sizeProp);
9404
- return /* @__PURE__ */ jsxRuntime.jsx(
9405
- "div",
9406
- {
9407
- className: chunkTPGAXYFU_cjs.cx(
9408
- "klun-textarea",
9409
- `klun-textarea--${size}`,
9410
- error && "klun-textarea--error",
9411
- disabled && "klun-textarea--disabled",
9412
- readOnly && "klun-textarea--readonly",
9413
- className
9414
- ),
9415
- style,
9416
- children: /* @__PURE__ */ jsxRuntime.jsx(
9417
- "textarea",
9418
- {
9419
- ref,
9420
- className: "klun-textarea__field",
9421
- rows,
9422
- disabled,
9423
- readOnly,
9424
- ...props
9425
- }
9426
- )
9427
- }
9428
- );
9429
- });
9430
- Textarea.displayName = "Textarea";
9431
10044
  var Card = react.forwardRef(function Card2({ variant = "stroke", padding, className, style, children, ...props }, ref) {
9432
10045
  return /* @__PURE__ */ jsxRuntime.jsx(
9433
10046
  "div",
@@ -11641,6 +12254,7 @@ exports.BulkAction = BulkAction;
11641
12254
  exports.BulkActionBar = BulkActionBar;
11642
12255
  exports.Button = Button;
11643
12256
  exports.ButtonGroup = ButtonGroup;
12257
+ exports.CRON_PRESETS = CRON_PRESETS;
11644
12258
  exports.Card = Card;
11645
12259
  exports.Carousel = Carousel;
11646
12260
  exports.Cascader = Cascader;
@@ -11667,6 +12281,7 @@ exports.ContentLabel = ContentLabel;
11667
12281
  exports.ContextMenu = ContextMenu2;
11668
12282
  exports.CopyButton = CopyButton;
11669
12283
  exports.CounterInput = CounterInput;
12284
+ exports.CronEditor = CronEditor;
11670
12285
  exports.CrossRefBadge = CrossRefBadge;
11671
12286
  exports.DatePicker = DatePicker;
11672
12287
  exports.DateRangePicker = DateRangePicker;
@@ -11694,6 +12309,7 @@ exports.ImageViewer = ImageViewer;
11694
12309
  exports.InlineInput = InlineInput;
11695
12310
  exports.InlineSelect = InlineSelect;
11696
12311
  exports.Input = Input;
12312
+ exports.Kanban = Kanban;
11697
12313
  exports.Kbd = Kbd;
11698
12314
  exports.KeyIcon = KeyIcon;
11699
12315
  exports.Label = Label;
@@ -11725,6 +12341,7 @@ exports.RangeSlider = RangeSlider;
11725
12341
  exports.Rating = Rating;
11726
12342
  exports.RelativeTime = RelativeTime;
11727
12343
  exports.Result = Result;
12344
+ exports.RichEditor = RichEditor;
11728
12345
  exports.RichEditorToolbar = RichEditorToolbar;
11729
12346
  exports.Row = Row;
11730
12347
  exports.SegmentedControl = SegmentedControl;
@@ -11753,9 +12370,11 @@ exports.Toast = Toast;
11753
12370
  exports.Toaster = Toaster;
11754
12371
  exports.Tooltip = Tooltip;
11755
12372
  exports.Tree = Tree;
12373
+ exports.VirtualTable = VirtualTable;
11756
12374
  exports.Wizard = Wizard;
11757
12375
  exports.arSA = arSA;
11758
12376
  exports.deDE = deDE;
12377
+ exports.describeCron = describeCron;
11759
12378
  exports.enUS = enUS;
11760
12379
  exports.esES = esES;
11761
12380
  exports.fmt = fmt;
@@ -11786,5 +12405,5 @@ exports.useSize = useSize;
11786
12405
  exports.viVN = viVN;
11787
12406
  exports.zhCN = zhCN;
11788
12407
  exports.zhTW = zhTW;
11789
- //# sourceMappingURL=chunk-YSCRS555.cjs.map
11790
- //# sourceMappingURL=chunk-YSCRS555.cjs.map
12408
+ //# sourceMappingURL=chunk-IETPQZRQ.cjs.map
12409
+ //# sourceMappingURL=chunk-IETPQZRQ.cjs.map