@lensui/lens-table 0.1.76 → 0.1.78

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
@@ -332,10 +332,25 @@ function LoadingSpinnerIcon() {
332
332
 
333
333
  // src/components/editors/ChoiceEditor.tsx
334
334
  var import_jsx_runtime3 = require("react/jsx-runtime");
335
+ var SEARCHABLE_CHOICE_POPUP_MAX_WIDTH = 360;
336
+ var SEARCHABLE_CHOICE_POPUP_HORIZONTAL_PADDING = 44;
337
+ var SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP = 8;
338
+ function getSearchableChoicePopupHorizontalLayout(anchorLeft, anchorWidth, longestLabelWidth, viewportWidth) {
339
+ const availableWidth = Math.max(0, viewportWidth - SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP * 2);
340
+ const desiredWidth = Math.max(anchorWidth, longestLabelWidth + SEARCHABLE_CHOICE_POPUP_HORIZONTAL_PADDING);
341
+ const width = Math.min(desiredWidth, SEARCHABLE_CHOICE_POPUP_MAX_WIDTH, availableWidth);
342
+ const left = Math.max(
343
+ SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP,
344
+ Math.min(anchorLeft, viewportWidth - SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP - width)
345
+ );
346
+ return { left, width };
347
+ }
335
348
  function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownHeight, style, labels, onChange, onCommit, onCancel }) {
336
349
  const editorRef = (0, import_react2.useRef)(null);
337
350
  const popupRef = (0, import_react2.useRef)(null);
338
351
  const activeOptionRef = (0, import_react2.useRef)(null);
352
+ const popupReadyRef = (0, import_react2.useRef)(false);
353
+ const navigationSourceRef = (0, import_react2.useRef)(null);
339
354
  const originalValueRef = (0, import_react2.useRef)(value);
340
355
  const listboxId = (0, import_react2.useId)();
341
356
  const originalValue = originalValueRef.current;
@@ -344,7 +359,10 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
344
359
  const selectedIndex = options.findIndex((option) => option.value === value);
345
360
  return selectedIndex >= 0 ? selectedIndex : 0;
346
361
  });
347
- const [popupStyle, setPopupStyle] = (0, import_react2.useState)({});
362
+ const [popupStyle, setPopupStyle] = (0, import_react2.useState)({
363
+ position: "fixed",
364
+ visibility: "hidden"
365
+ });
348
366
  const filteredOptions = (0, import_react2.useMemo)(() => {
349
367
  const query = inputValue.trim().toLocaleLowerCase();
350
368
  if (!query || query === originalValue.toLocaleLowerCase()) return options;
@@ -354,24 +372,36 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
354
372
  const positionPopup = () => {
355
373
  const rect = editorRef.current?.getBoundingClientRect();
356
374
  if (!rect) return;
375
+ const longestLabelWidth = Math.max(
376
+ 0,
377
+ ...Array.from(popupRef.current?.querySelectorAll(".rvg-choice-item > span") ?? []).map((label) => label.scrollWidth)
378
+ );
379
+ const horizontal = getSearchableChoicePopupHorizontalLayout(
380
+ rect.left,
381
+ rect.width,
382
+ longestLabelWidth,
383
+ window.innerWidth
384
+ );
357
385
  const availableBelow = window.innerHeight - rect.bottom - 8;
358
386
  const availableAbove = rect.top - 8;
359
387
  if (availableBelow < 120 && availableAbove > availableBelow) {
360
388
  setPopupStyle({
361
389
  position: "fixed",
362
390
  bottom: window.innerHeight - rect.top + 4,
363
- left: rect.left,
364
- width: rect.width,
365
- maxHeight: Math.min(maxDropdownHeight, availableAbove)
391
+ left: horizontal.left,
392
+ width: horizontal.width,
393
+ maxHeight: Math.min(maxDropdownHeight, availableAbove),
394
+ visibility: popupReadyRef.current ? "visible" : "hidden"
366
395
  });
367
396
  return;
368
397
  }
369
398
  setPopupStyle({
370
399
  position: "fixed",
371
400
  top: rect.bottom + 4,
372
- left: rect.left,
373
- width: rect.width,
374
- maxHeight: Math.min(maxDropdownHeight, Math.max(80, availableBelow))
401
+ left: horizontal.left,
402
+ width: horizontal.width,
403
+ maxHeight: Math.min(maxDropdownHeight, Math.max(80, availableBelow)),
404
+ visibility: popupReadyRef.current ? "visible" : "hidden"
375
405
  });
376
406
  };
377
407
  positionPopup();
@@ -383,8 +413,22 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
383
413
  };
384
414
  }, [maxDropdownHeight]);
385
415
  (0, import_react2.useLayoutEffect)(() => {
386
- activeOptionRef.current?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
387
- }, [activeIndex, filteredOptions, popupStyle]);
416
+ if (popupReadyRef.current) return;
417
+ if (popupStyle.top === void 0 && popupStyle.bottom === void 0) return;
418
+ const selectedOption = popupRef.current?.querySelector('[aria-selected="true"]') ?? activeOptionRef.current;
419
+ selectedOption?.scrollIntoView?.({ block: "center", inline: "nearest" });
420
+ popupReadyRef.current = true;
421
+ setPopupStyle((current) => ({ ...current, visibility: "visible" }));
422
+ }, [popupStyle.bottom, popupStyle.top]);
423
+ (0, import_react2.useLayoutEffect)(() => {
424
+ if (!popupReadyRef.current) return;
425
+ if (navigationSourceRef.current === "keyboard") {
426
+ activeOptionRef.current?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
427
+ } else if (navigationSourceRef.current === "filter" && popupRef.current) {
428
+ popupRef.current.scrollTop = 0;
429
+ }
430
+ navigationSourceRef.current = null;
431
+ }, [activeIndex, filteredOptions]);
388
432
  (0, import_react2.useEffect)(() => {
389
433
  const handleOutsidePointer = (event) => {
390
434
  const target = event.target;
@@ -404,10 +448,12 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
404
448
  if (event.key === "Escape") onCancel();
405
449
  if (event.key === "ArrowDown") {
406
450
  event.preventDefault();
451
+ navigationSourceRef.current = "keyboard";
407
452
  setActiveIndex((index) => Math.min(filteredOptions.length - 1, index + 1));
408
453
  }
409
454
  if (event.key === "ArrowUp") {
410
455
  event.preventDefault();
456
+ navigationSourceRef.current = "keyboard";
411
457
  setActiveIndex((index) => Math.max(0, index - 1));
412
458
  }
413
459
  if (event.key === "Enter") {
@@ -430,6 +476,7 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
430
476
  onChange: (event) => {
431
477
  setInputValue(event.target.value);
432
478
  onChange(event.target.value);
479
+ navigationSourceRef.current = "filter";
433
480
  setActiveIndex(0);
434
481
  },
435
482
  onKeyDown: handleKeyDown
@@ -445,7 +492,10 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
445
492
  "aria-selected": option.value === originalValue,
446
493
  className: `rvg-choice-item${index === activeIndex ? " is-active" : ""}${option.value === originalValue ? " is-selected" : ""}`,
447
494
  onPointerDown: (event) => event.preventDefault(),
448
- onMouseEnter: () => setActiveIndex(index),
495
+ onMouseEnter: () => {
496
+ navigationSourceRef.current = "pointer";
497
+ setActiveIndex(index);
498
+ },
449
499
  onClick: () => selectOption(option),
450
500
  children: [
451
501
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: option.label }),
@@ -941,25 +991,6 @@ function TextAreaEditor({ value, title, maxLength, style, labels, onChange, onCo
941
991
  ] });
942
992
  }
943
993
 
944
- // src/icons/domIcons.ts
945
- function createRowDragHandleSvg() {
946
- const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
947
- svg.setAttribute("viewBox", "0 0 16 16");
948
- for (const [cx, cy] of [[5, 4], [11, 4], [5, 8], [11, 8], [5, 12], [11, 12]]) {
949
- const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
950
- circle.setAttribute("cx", String(cx));
951
- circle.setAttribute("cy", String(cy));
952
- circle.setAttribute("r", "1");
953
- svg.appendChild(circle);
954
- }
955
- return svg;
956
- }
957
-
958
- // src/Table.tsx
959
- var import_adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
960
- var import_set_custom_native_drag_preview = require("@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview");
961
- var import_closest_edge = require("@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge");
962
-
963
994
  // src/core/format.ts
964
995
  function getDisplayLabel(column, row, rowIndex) {
965
996
  const value = column.dataIndex === void 0 ? void 0 : row[column.dataIndex];
@@ -2041,6 +2072,7 @@ function TableInner({
2041
2072
  const columnDragRef = (0, import_react8.useRef)(null);
2042
2073
  const columnOrderDragRef = (0, import_react8.useRef)(null);
2043
2074
  const columnOrderLongPressTimerRef = (0, import_react8.useRef)(null);
2075
+ const rowOrderDragRef = (0, import_react8.useRef)(null);
2044
2076
  const dragGuideRef = (0, import_react8.useRef)(null);
2045
2077
  const rowDragGuideRef = (0, import_react8.useRef)(null);
2046
2078
  const selectionFocusRef = (0, import_react8.useRef)(null);
@@ -3341,131 +3373,61 @@ function TableInner({
3341
3373
  const rowIndex = Math.floor((localY - bodyTop + scrollRef.current.top) / rowHeight);
3342
3374
  return rowIndex >= 0 && rowIndex < rows.length ? rowIndex : -1;
3343
3375
  }, [bodyTop, rowHeight, rows.length]);
3344
- (0, import_react8.useEffect)(() => {
3345
- const canvas = canvasRef.current;
3346
- if (!canvas || !rowDraggable) return;
3347
- const cleanupDrag = (0, import_adapter.draggable)({
3348
- element: canvas,
3349
- canDrag: ({ input }) => {
3350
- const columnIndex = locateColumn(input.clientX);
3351
- return columnIndex >= 0 && Boolean(columns[columnIndex].rowDragHandle) && locateRow(input.clientY) >= 0;
3352
- },
3353
- getInitialData: ({ input }) => ({ type: "table-row", sourceIndex: locateRow(input.clientY) }),
3354
- onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
3355
- const sourceIndex = Number(source.data.sourceIndex);
3356
- const canvasRect = canvas.getBoundingClientRect();
3357
- const input = location.current.input;
3358
- const previewOffset = {
3359
- x: Math.max(0, Math.min(canvasRect.width, input.clientX - canvasRect.left)) + 2,
3360
- y: Math.max(0, Math.min(rowHeight, input.clientY - canvasRect.top - bodyTop - sourceIndex * rowHeight + scrollRef.current.top)) + 2
3361
- };
3362
- (0, import_set_custom_native_drag_preview.setCustomNativeDragPreview)({
3363
- nativeSetDragImage,
3364
- getOffset: () => previewOffset,
3365
- render: ({ container }) => {
3366
- const frame = document.createElement("div");
3367
- frame.className = "rvg-row-drag-preview-frame";
3368
- frame.style.width = `${canvasRect.width + 4}px`;
3369
- frame.style.height = `${rowHeight + 4}px`;
3370
- const preview = document.createElement("div");
3371
- preview.className = "rvg-row-drag-preview";
3372
- preview.style.width = `${canvasRect.width}px`;
3373
- preview.style.height = `${rowHeight}px`;
3374
- const row = rows[sourceIndex];
3375
- const rowKey2 = getRowKey(row, sourceIndex);
3376
- columns.forEach((column, columnIndex) => {
3377
- const left = getDisplayedColumnLeft(columnIndex);
3378
- const columnWidth = metrics[columnIndex].width;
3379
- if (left + columnWidth <= 0 || left >= canvasRect.width) return;
3380
- const cell = document.createElement("div");
3381
- cell.className = "rvg-row-drag-preview-cell";
3382
- cell.style.left = `${left}px`;
3383
- cell.style.width = `${columnWidth}px`;
3384
- cell.style.justifyContent = column.align === "right" ? "flex-end" : column.align === "center" ? "center" : "flex-start";
3385
- if (column.rowDragHandle && !column.rowSelection) {
3386
- cell.appendChild(createRowDragHandleSvg());
3387
- } else if (column.rowSelection) {
3388
- if (column.rowSelectionIndicator !== "none") {
3389
- const checkbox = document.createElement("span");
3390
- checkbox.className = selectedRowKeySet.has(rowKey2) ? "rvg-preview-checkbox is-checked" : "rvg-preview-checkbox";
3391
- checkbox.textContent = selectedRowKeySet.has(rowKey2) ? "\u2713" : "";
3392
- cell.appendChild(checkbox);
3393
- }
3394
- } else {
3395
- cell.textContent = getCellLabel(sourceIndex, columnIndex);
3396
- }
3397
- if (selection?.rowKey === rowKey2 && selection.columnKey === column.key) cell.classList.add("is-selected");
3398
- preview.appendChild(cell);
3399
- });
3400
- frame.appendChild(preview);
3401
- container.appendChild(frame);
3402
- return () => frame.remove();
3403
- }
3404
- });
3405
- },
3406
- onDragStart: ({ source }) => {
3407
- const sourceIndex = Number(source.data.sourceIndex);
3408
- suppressClickRef.current = true;
3409
- hideDragTooltips();
3410
- document.documentElement.classList.add("rvg-is-dragging");
3411
- canvas.style.cursor = "move";
3412
- setRowDragPreview({ sourceIndex, targetIndex: sourceIndex });
3413
- },
3414
- onDrag: ({ source, location }) => {
3415
- const target = location.current.dropTargets[0]?.data;
3416
- const sourceIndex = Number(source.data.sourceIndex);
3417
- const rawTargetIndex = Number(target?.targetIndex);
3418
- if (!Number.isInteger(rawTargetIndex)) {
3419
- setRowDragPreview(null);
3420
- setRowDragGuide(null);
3421
- return;
3422
- }
3423
- const edge = target?.rowEdge;
3424
- let targetIndex = rawTargetIndex + (edge === "bottom" ? 1 : 0);
3425
- if (sourceIndex < targetIndex) targetIndex -= 1;
3426
- targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
3427
- setRowDragPreview((current) => current?.sourceIndex === sourceIndex && current.targetIndex === targetIndex ? current : { sourceIndex, targetIndex });
3428
- setRowDragGuide(bodyTop + rawTargetIndex * rowHeight - scrollRef.current.top + (edge === "bottom" ? rowHeight : 0));
3429
- },
3430
- onDrop: ({ source, location }) => {
3431
- const target = location.current.dropTargets[0]?.data;
3432
- const sourceIndex = Number(source.data.sourceIndex);
3433
- const rawTargetIndex = Number(target?.targetIndex);
3434
- let targetIndex = rawTargetIndex + (target?.rowEdge === "bottom" ? 1 : 0);
3435
- if (sourceIndex < targetIndex) targetIndex -= 1;
3436
- targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
3437
- scrollerRef.current?.classList.add("rvg-row-drop-settling");
3438
- setRowDragPreview(null);
3439
- setRowDragGuide(null);
3440
- document.documentElement.classList.remove("rvg-is-dragging");
3441
- canvas.style.cursor = "default";
3442
- if (Number.isInteger(rawTargetIndex) && sourceIndex !== targetIndex) applyRowOrder(sourceIndex, targetIndex);
3443
- requestAnimationFrame(() => {
3444
- requestAnimationFrame(() => scrollerRef.current?.classList.remove("rvg-row-drop-settling"));
3445
- });
3446
- window.setTimeout(() => {
3447
- suppressClickRef.current = false;
3448
- }, 0);
3449
- }
3450
- });
3451
- const cleanupDrop = (0, import_adapter.dropTargetForElements)({
3452
- element: canvas,
3453
- canDrop: ({ source }) => source.data.type === "table-row",
3454
- getDropEffect: () => "move",
3455
- getData: ({ input, element }) => {
3456
- const targetIndex = locateRow(input.clientY);
3457
- if (targetIndex < 0) return { targetIndex: -1 };
3458
- const rowTop = bodyTop + targetIndex * rowHeight - scrollRef.current.top;
3459
- const rowEdge = input.clientY - canvas.getBoundingClientRect().top < rowTop + rowHeight / 2 ? "top" : "bottom";
3460
- return (0, import_closest_edge.attachClosestEdge)({ targetIndex, rowEdge }, { element, input, allowedEdges: ["top", "bottom"] });
3461
- }
3462
- });
3463
- return () => {
3464
- document.documentElement.classList.remove("rvg-is-dragging");
3465
- cleanupDrag();
3466
- cleanupDrop();
3376
+ const handleRowOrderPointerDown = (0, import_react8.useCallback)((event) => {
3377
+ if (!rowDraggable || event.button !== 0 || rowOrderDragRef.current) return;
3378
+ const columnIndex = locateColumn(event.clientX);
3379
+ const sourceIndex = locateRow(event.clientY);
3380
+ if (columnIndex < 0 || sourceIndex < 0 || !columns[columnIndex].rowDragHandle) return;
3381
+ event.currentTarget.setPointerCapture?.(event.pointerId);
3382
+ rowOrderDragRef.current = {
3383
+ pointerId: event.pointerId,
3384
+ startY: event.clientY,
3385
+ active: false,
3386
+ sourceIndex,
3387
+ targetIndex: sourceIndex
3467
3388
  };
3468
- }, [applyRowOrder, bodyTop, columns, getCellLabel, getDisplayedColumnLeft, getRowKey, hideDragTooltips, locateColumn, locateRow, metrics, rowDraggable, rowHeight, rows, selectedRowKeySet, selection, setRowDragGuide]);
3389
+ }, [columns, locateColumn, locateRow, rowDraggable]);
3390
+ const handleRowOrderPointerMove = (0, import_react8.useCallback)((event) => {
3391
+ const drag = rowOrderDragRef.current;
3392
+ if (!drag || drag.pointerId !== event.pointerId) return;
3393
+ if (!drag.active) {
3394
+ if (Math.abs(event.clientY - drag.startY) < 4) return;
3395
+ drag.active = true;
3396
+ suppressClickRef.current = true;
3397
+ hideDragTooltips();
3398
+ document.documentElement.classList.add("rvg-is-dragging");
3399
+ event.currentTarget.style.cursor = "move";
3400
+ }
3401
+ event.preventDefault();
3402
+ const rawTargetIndex = locateRow(event.clientY);
3403
+ if (rawTargetIndex < 0) return;
3404
+ const canvasTop = event.currentTarget.getBoundingClientRect().top;
3405
+ const rowTop = bodyTop + rawTargetIndex * rowHeight - scrollRef.current.top;
3406
+ const edge = event.clientY - canvasTop < rowTop + rowHeight / 2 ? "top" : "bottom";
3407
+ let targetIndex = rawTargetIndex + (edge === "bottom" ? 1 : 0);
3408
+ if (drag.sourceIndex < targetIndex) targetIndex -= 1;
3409
+ targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
3410
+ drag.targetIndex = targetIndex;
3411
+ setRowDragPreview((current) => current?.sourceIndex === drag.sourceIndex && current.targetIndex === targetIndex ? current : { sourceIndex: drag.sourceIndex, targetIndex });
3412
+ setRowDragGuide(rowTop + (edge === "bottom" ? rowHeight : 0));
3413
+ }, [bodyTop, hideDragTooltips, locateRow, rowHeight, rows.length, setRowDragGuide]);
3414
+ const finishRowOrderPointerDrag = (0, import_react8.useCallback)((event, apply) => {
3415
+ const drag = rowOrderDragRef.current;
3416
+ if (!drag || drag.pointerId !== event.pointerId) return;
3417
+ if (event.currentTarget.hasPointerCapture?.(event.pointerId)) event.currentTarget.releasePointerCapture?.(event.pointerId);
3418
+ rowOrderDragRef.current = null;
3419
+ setRowDragPreview(null);
3420
+ setRowDragGuide(null);
3421
+ document.documentElement.classList.remove("rvg-is-dragging");
3422
+ event.currentTarget.style.cursor = "default";
3423
+ if (apply && drag.active && drag.sourceIndex !== drag.targetIndex) {
3424
+ scrollerRef.current?.classList.add("rvg-row-drop-settling");
3425
+ applyRowOrder(drag.sourceIndex, drag.targetIndex);
3426
+ requestAnimationFrame(() => {
3427
+ requestAnimationFrame(() => scrollerRef.current?.classList.remove("rvg-row-drop-settling"));
3428
+ });
3429
+ }
3430
+ }, [applyRowOrder, setRowDragGuide]);
3469
3431
  const locateCell = (0, import_react8.useCallback)((clientX, clientY) => {
3470
3432
  const canvas = canvasRef.current;
3471
3433
  if (!canvas) return null;
@@ -5058,7 +5020,7 @@ function TableInner({
5058
5020
  }
5059
5021
  }
5060
5022
  }
5061
- const cursor = inHeader && locateHeaderResizeCell(event.clientX, event.clientY) ? "col-resize" : hoveredAction ? "pointer" : hoveredDragHandle ? "move" : columnIndex >= 0 && columns[columnIndex].rowSelection ? "pointer" : !inHeader && rowDraggable && columnIndex >= 0 && columns[columnIndex].rowDragHandle ? "move" : "default";
5023
+ const cursor = inHeader && locateHeaderResizeCell(event.clientX, event.clientY) ? "col-resize" : hoveredAction ? "pointer" : hoveredDragHandle ? "move" : !inHeader && rowDraggable && columnIndex >= 0 && columns[columnIndex].rowDragHandle ? "move" : columnIndex >= 0 && columns[columnIndex].rowSelection ? "pointer" : "default";
5062
5024
  if (event.currentTarget.style.cursor !== cursor) event.currentTarget.style.cursor = cursor;
5063
5025
  },
5064
5026
  onMouseLeave: (event) => {
@@ -5077,6 +5039,7 @@ function TableInner({
5077
5039
  }
5078
5040
  },
5079
5041
  onPointerDown: (event) => {
5042
+ handleRowOrderPointerDown(event);
5080
5043
  handleColumnPointerDown(event);
5081
5044
  if (columnDragRef.current) return;
5082
5045
  const headerDragCell = columnDraggable ? locateHeaderCell(event.clientX, event.clientY) : null;
@@ -5089,16 +5052,19 @@ function TableInner({
5089
5052
  beginRangeDrag(event);
5090
5053
  },
5091
5054
  onPointerMove: (event) => {
5055
+ handleRowOrderPointerMove(event);
5092
5056
  handleColumnPointerMove(event);
5093
5057
  handleColumnOrderPointerMove(event);
5094
5058
  updateRangeDrag(event);
5095
5059
  },
5096
5060
  onPointerUp: (event) => {
5061
+ finishRowOrderPointerDrag(event, true);
5097
5062
  handleColumnPointerUp(event);
5098
5063
  finishColumnOrderPointerDrag(event, true);
5099
5064
  endRangeDrag(event);
5100
5065
  },
5101
5066
  onPointerCancel: (event) => {
5067
+ finishRowOrderPointerDrag(event, false);
5102
5068
  handleColumnPointerUp(event);
5103
5069
  finishColumnOrderPointerDrag(event, false);
5104
5070
  endRangeDrag(event);
package/dist/index.css CHANGED
@@ -2704,10 +2704,17 @@
2704
2704
  }
2705
2705
  .rvg-searchable-choice-content .rvg-choice-item {
2706
2706
  width: 100%;
2707
+ min-width: 0;
2707
2708
  border: 0;
2708
2709
  background: transparent;
2709
2710
  text-align: left;
2710
2711
  }
2712
+ .rvg-searchable-choice-content .rvg-choice-item > span {
2713
+ min-width: 0;
2714
+ overflow: hidden;
2715
+ white-space: nowrap;
2716
+ text-overflow: ellipsis;
2717
+ }
2711
2718
  .rvg-searchable-choice-content .rvg-choice-item:is(:hover, .is-active) {
2712
2719
  background: var(--rvg-color-hover);
2713
2720
  }
package/dist/index.js CHANGED
@@ -302,10 +302,25 @@ function LoadingSpinnerIcon() {
302
302
 
303
303
  // src/components/editors/ChoiceEditor.tsx
304
304
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
305
+ var SEARCHABLE_CHOICE_POPUP_MAX_WIDTH = 360;
306
+ var SEARCHABLE_CHOICE_POPUP_HORIZONTAL_PADDING = 44;
307
+ var SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP = 8;
308
+ function getSearchableChoicePopupHorizontalLayout(anchorLeft, anchorWidth, longestLabelWidth, viewportWidth) {
309
+ const availableWidth = Math.max(0, viewportWidth - SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP * 2);
310
+ const desiredWidth = Math.max(anchorWidth, longestLabelWidth + SEARCHABLE_CHOICE_POPUP_HORIZONTAL_PADDING);
311
+ const width = Math.min(desiredWidth, SEARCHABLE_CHOICE_POPUP_MAX_WIDTH, availableWidth);
312
+ const left = Math.max(
313
+ SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP,
314
+ Math.min(anchorLeft, viewportWidth - SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP - width)
315
+ );
316
+ return { left, width };
317
+ }
305
318
  function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownHeight, style, labels, onChange, onCommit, onCancel }) {
306
319
  const editorRef = useRef(null);
307
320
  const popupRef = useRef(null);
308
321
  const activeOptionRef = useRef(null);
322
+ const popupReadyRef = useRef(false);
323
+ const navigationSourceRef = useRef(null);
309
324
  const originalValueRef = useRef(value);
310
325
  const listboxId = useId2();
311
326
  const originalValue = originalValueRef.current;
@@ -314,7 +329,10 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
314
329
  const selectedIndex = options.findIndex((option) => option.value === value);
315
330
  return selectedIndex >= 0 ? selectedIndex : 0;
316
331
  });
317
- const [popupStyle, setPopupStyle] = useState({});
332
+ const [popupStyle, setPopupStyle] = useState({
333
+ position: "fixed",
334
+ visibility: "hidden"
335
+ });
318
336
  const filteredOptions = useMemo(() => {
319
337
  const query = inputValue.trim().toLocaleLowerCase();
320
338
  if (!query || query === originalValue.toLocaleLowerCase()) return options;
@@ -324,24 +342,36 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
324
342
  const positionPopup = () => {
325
343
  const rect = editorRef.current?.getBoundingClientRect();
326
344
  if (!rect) return;
345
+ const longestLabelWidth = Math.max(
346
+ 0,
347
+ ...Array.from(popupRef.current?.querySelectorAll(".rvg-choice-item > span") ?? []).map((label) => label.scrollWidth)
348
+ );
349
+ const horizontal = getSearchableChoicePopupHorizontalLayout(
350
+ rect.left,
351
+ rect.width,
352
+ longestLabelWidth,
353
+ window.innerWidth
354
+ );
327
355
  const availableBelow = window.innerHeight - rect.bottom - 8;
328
356
  const availableAbove = rect.top - 8;
329
357
  if (availableBelow < 120 && availableAbove > availableBelow) {
330
358
  setPopupStyle({
331
359
  position: "fixed",
332
360
  bottom: window.innerHeight - rect.top + 4,
333
- left: rect.left,
334
- width: rect.width,
335
- maxHeight: Math.min(maxDropdownHeight, availableAbove)
361
+ left: horizontal.left,
362
+ width: horizontal.width,
363
+ maxHeight: Math.min(maxDropdownHeight, availableAbove),
364
+ visibility: popupReadyRef.current ? "visible" : "hidden"
336
365
  });
337
366
  return;
338
367
  }
339
368
  setPopupStyle({
340
369
  position: "fixed",
341
370
  top: rect.bottom + 4,
342
- left: rect.left,
343
- width: rect.width,
344
- maxHeight: Math.min(maxDropdownHeight, Math.max(80, availableBelow))
371
+ left: horizontal.left,
372
+ width: horizontal.width,
373
+ maxHeight: Math.min(maxDropdownHeight, Math.max(80, availableBelow)),
374
+ visibility: popupReadyRef.current ? "visible" : "hidden"
345
375
  });
346
376
  };
347
377
  positionPopup();
@@ -353,8 +383,22 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
353
383
  };
354
384
  }, [maxDropdownHeight]);
355
385
  useLayoutEffect(() => {
356
- activeOptionRef.current?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
357
- }, [activeIndex, filteredOptions, popupStyle]);
386
+ if (popupReadyRef.current) return;
387
+ if (popupStyle.top === void 0 && popupStyle.bottom === void 0) return;
388
+ const selectedOption = popupRef.current?.querySelector('[aria-selected="true"]') ?? activeOptionRef.current;
389
+ selectedOption?.scrollIntoView?.({ block: "center", inline: "nearest" });
390
+ popupReadyRef.current = true;
391
+ setPopupStyle((current) => ({ ...current, visibility: "visible" }));
392
+ }, [popupStyle.bottom, popupStyle.top]);
393
+ useLayoutEffect(() => {
394
+ if (!popupReadyRef.current) return;
395
+ if (navigationSourceRef.current === "keyboard") {
396
+ activeOptionRef.current?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
397
+ } else if (navigationSourceRef.current === "filter" && popupRef.current) {
398
+ popupRef.current.scrollTop = 0;
399
+ }
400
+ navigationSourceRef.current = null;
401
+ }, [activeIndex, filteredOptions]);
358
402
  useEffect(() => {
359
403
  const handleOutsidePointer = (event) => {
360
404
  const target = event.target;
@@ -374,10 +418,12 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
374
418
  if (event.key === "Escape") onCancel();
375
419
  if (event.key === "ArrowDown") {
376
420
  event.preventDefault();
421
+ navigationSourceRef.current = "keyboard";
377
422
  setActiveIndex((index) => Math.min(filteredOptions.length - 1, index + 1));
378
423
  }
379
424
  if (event.key === "ArrowUp") {
380
425
  event.preventDefault();
426
+ navigationSourceRef.current = "keyboard";
381
427
  setActiveIndex((index) => Math.max(0, index - 1));
382
428
  }
383
429
  if (event.key === "Enter") {
@@ -400,6 +446,7 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
400
446
  onChange: (event) => {
401
447
  setInputValue(event.target.value);
402
448
  onChange(event.target.value);
449
+ navigationSourceRef.current = "filter";
403
450
  setActiveIndex(0);
404
451
  },
405
452
  onKeyDown: handleKeyDown
@@ -415,7 +462,10 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
415
462
  "aria-selected": option.value === originalValue,
416
463
  className: `rvg-choice-item${index === activeIndex ? " is-active" : ""}${option.value === originalValue ? " is-selected" : ""}`,
417
464
  onPointerDown: (event) => event.preventDefault(),
418
- onMouseEnter: () => setActiveIndex(index),
465
+ onMouseEnter: () => {
466
+ navigationSourceRef.current = "pointer";
467
+ setActiveIndex(index);
468
+ },
419
469
  onClick: () => selectOption(option),
420
470
  children: [
421
471
  /* @__PURE__ */ jsx3("span", { children: option.label }),
@@ -911,25 +961,6 @@ function TextAreaEditor({ value, title, maxLength, style, labels, onChange, onCo
911
961
  ] });
912
962
  }
913
963
 
914
- // src/icons/domIcons.ts
915
- function createRowDragHandleSvg() {
916
- const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
917
- svg.setAttribute("viewBox", "0 0 16 16");
918
- for (const [cx, cy] of [[5, 4], [11, 4], [5, 8], [11, 8], [5, 12], [11, 12]]) {
919
- const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
920
- circle.setAttribute("cx", String(cx));
921
- circle.setAttribute("cy", String(cy));
922
- circle.setAttribute("r", "1");
923
- svg.appendChild(circle);
924
- }
925
- return svg;
926
- }
927
-
928
- // src/Table.tsx
929
- import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
930
- import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
931
- import { attachClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
932
-
933
964
  // src/core/format.ts
934
965
  function getDisplayLabel(column, row, rowIndex) {
935
966
  const value = column.dataIndex === void 0 ? void 0 : row[column.dataIndex];
@@ -2011,6 +2042,7 @@ function TableInner({
2011
2042
  const columnDragRef = useRef4(null);
2012
2043
  const columnOrderDragRef = useRef4(null);
2013
2044
  const columnOrderLongPressTimerRef = useRef4(null);
2045
+ const rowOrderDragRef = useRef4(null);
2014
2046
  const dragGuideRef = useRef4(null);
2015
2047
  const rowDragGuideRef = useRef4(null);
2016
2048
  const selectionFocusRef = useRef4(null);
@@ -3311,131 +3343,61 @@ function TableInner({
3311
3343
  const rowIndex = Math.floor((localY - bodyTop + scrollRef.current.top) / rowHeight);
3312
3344
  return rowIndex >= 0 && rowIndex < rows.length ? rowIndex : -1;
3313
3345
  }, [bodyTop, rowHeight, rows.length]);
3314
- useEffect3(() => {
3315
- const canvas = canvasRef.current;
3316
- if (!canvas || !rowDraggable) return;
3317
- const cleanupDrag = draggable({
3318
- element: canvas,
3319
- canDrag: ({ input }) => {
3320
- const columnIndex = locateColumn(input.clientX);
3321
- return columnIndex >= 0 && Boolean(columns[columnIndex].rowDragHandle) && locateRow(input.clientY) >= 0;
3322
- },
3323
- getInitialData: ({ input }) => ({ type: "table-row", sourceIndex: locateRow(input.clientY) }),
3324
- onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
3325
- const sourceIndex = Number(source.data.sourceIndex);
3326
- const canvasRect = canvas.getBoundingClientRect();
3327
- const input = location.current.input;
3328
- const previewOffset = {
3329
- x: Math.max(0, Math.min(canvasRect.width, input.clientX - canvasRect.left)) + 2,
3330
- y: Math.max(0, Math.min(rowHeight, input.clientY - canvasRect.top - bodyTop - sourceIndex * rowHeight + scrollRef.current.top)) + 2
3331
- };
3332
- setCustomNativeDragPreview({
3333
- nativeSetDragImage,
3334
- getOffset: () => previewOffset,
3335
- render: ({ container }) => {
3336
- const frame = document.createElement("div");
3337
- frame.className = "rvg-row-drag-preview-frame";
3338
- frame.style.width = `${canvasRect.width + 4}px`;
3339
- frame.style.height = `${rowHeight + 4}px`;
3340
- const preview = document.createElement("div");
3341
- preview.className = "rvg-row-drag-preview";
3342
- preview.style.width = `${canvasRect.width}px`;
3343
- preview.style.height = `${rowHeight}px`;
3344
- const row = rows[sourceIndex];
3345
- const rowKey2 = getRowKey(row, sourceIndex);
3346
- columns.forEach((column, columnIndex) => {
3347
- const left = getDisplayedColumnLeft(columnIndex);
3348
- const columnWidth = metrics[columnIndex].width;
3349
- if (left + columnWidth <= 0 || left >= canvasRect.width) return;
3350
- const cell = document.createElement("div");
3351
- cell.className = "rvg-row-drag-preview-cell";
3352
- cell.style.left = `${left}px`;
3353
- cell.style.width = `${columnWidth}px`;
3354
- cell.style.justifyContent = column.align === "right" ? "flex-end" : column.align === "center" ? "center" : "flex-start";
3355
- if (column.rowDragHandle && !column.rowSelection) {
3356
- cell.appendChild(createRowDragHandleSvg());
3357
- } else if (column.rowSelection) {
3358
- if (column.rowSelectionIndicator !== "none") {
3359
- const checkbox = document.createElement("span");
3360
- checkbox.className = selectedRowKeySet.has(rowKey2) ? "rvg-preview-checkbox is-checked" : "rvg-preview-checkbox";
3361
- checkbox.textContent = selectedRowKeySet.has(rowKey2) ? "\u2713" : "";
3362
- cell.appendChild(checkbox);
3363
- }
3364
- } else {
3365
- cell.textContent = getCellLabel(sourceIndex, columnIndex);
3366
- }
3367
- if (selection?.rowKey === rowKey2 && selection.columnKey === column.key) cell.classList.add("is-selected");
3368
- preview.appendChild(cell);
3369
- });
3370
- frame.appendChild(preview);
3371
- container.appendChild(frame);
3372
- return () => frame.remove();
3373
- }
3374
- });
3375
- },
3376
- onDragStart: ({ source }) => {
3377
- const sourceIndex = Number(source.data.sourceIndex);
3378
- suppressClickRef.current = true;
3379
- hideDragTooltips();
3380
- document.documentElement.classList.add("rvg-is-dragging");
3381
- canvas.style.cursor = "move";
3382
- setRowDragPreview({ sourceIndex, targetIndex: sourceIndex });
3383
- },
3384
- onDrag: ({ source, location }) => {
3385
- const target = location.current.dropTargets[0]?.data;
3386
- const sourceIndex = Number(source.data.sourceIndex);
3387
- const rawTargetIndex = Number(target?.targetIndex);
3388
- if (!Number.isInteger(rawTargetIndex)) {
3389
- setRowDragPreview(null);
3390
- setRowDragGuide(null);
3391
- return;
3392
- }
3393
- const edge = target?.rowEdge;
3394
- let targetIndex = rawTargetIndex + (edge === "bottom" ? 1 : 0);
3395
- if (sourceIndex < targetIndex) targetIndex -= 1;
3396
- targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
3397
- setRowDragPreview((current) => current?.sourceIndex === sourceIndex && current.targetIndex === targetIndex ? current : { sourceIndex, targetIndex });
3398
- setRowDragGuide(bodyTop + rawTargetIndex * rowHeight - scrollRef.current.top + (edge === "bottom" ? rowHeight : 0));
3399
- },
3400
- onDrop: ({ source, location }) => {
3401
- const target = location.current.dropTargets[0]?.data;
3402
- const sourceIndex = Number(source.data.sourceIndex);
3403
- const rawTargetIndex = Number(target?.targetIndex);
3404
- let targetIndex = rawTargetIndex + (target?.rowEdge === "bottom" ? 1 : 0);
3405
- if (sourceIndex < targetIndex) targetIndex -= 1;
3406
- targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
3407
- scrollerRef.current?.classList.add("rvg-row-drop-settling");
3408
- setRowDragPreview(null);
3409
- setRowDragGuide(null);
3410
- document.documentElement.classList.remove("rvg-is-dragging");
3411
- canvas.style.cursor = "default";
3412
- if (Number.isInteger(rawTargetIndex) && sourceIndex !== targetIndex) applyRowOrder(sourceIndex, targetIndex);
3413
- requestAnimationFrame(() => {
3414
- requestAnimationFrame(() => scrollerRef.current?.classList.remove("rvg-row-drop-settling"));
3415
- });
3416
- window.setTimeout(() => {
3417
- suppressClickRef.current = false;
3418
- }, 0);
3419
- }
3420
- });
3421
- const cleanupDrop = dropTargetForElements({
3422
- element: canvas,
3423
- canDrop: ({ source }) => source.data.type === "table-row",
3424
- getDropEffect: () => "move",
3425
- getData: ({ input, element }) => {
3426
- const targetIndex = locateRow(input.clientY);
3427
- if (targetIndex < 0) return { targetIndex: -1 };
3428
- const rowTop = bodyTop + targetIndex * rowHeight - scrollRef.current.top;
3429
- const rowEdge = input.clientY - canvas.getBoundingClientRect().top < rowTop + rowHeight / 2 ? "top" : "bottom";
3430
- return attachClosestEdge({ targetIndex, rowEdge }, { element, input, allowedEdges: ["top", "bottom"] });
3431
- }
3432
- });
3433
- return () => {
3434
- document.documentElement.classList.remove("rvg-is-dragging");
3435
- cleanupDrag();
3436
- cleanupDrop();
3346
+ const handleRowOrderPointerDown = useCallback2((event) => {
3347
+ if (!rowDraggable || event.button !== 0 || rowOrderDragRef.current) return;
3348
+ const columnIndex = locateColumn(event.clientX);
3349
+ const sourceIndex = locateRow(event.clientY);
3350
+ if (columnIndex < 0 || sourceIndex < 0 || !columns[columnIndex].rowDragHandle) return;
3351
+ event.currentTarget.setPointerCapture?.(event.pointerId);
3352
+ rowOrderDragRef.current = {
3353
+ pointerId: event.pointerId,
3354
+ startY: event.clientY,
3355
+ active: false,
3356
+ sourceIndex,
3357
+ targetIndex: sourceIndex
3437
3358
  };
3438
- }, [applyRowOrder, bodyTop, columns, getCellLabel, getDisplayedColumnLeft, getRowKey, hideDragTooltips, locateColumn, locateRow, metrics, rowDraggable, rowHeight, rows, selectedRowKeySet, selection, setRowDragGuide]);
3359
+ }, [columns, locateColumn, locateRow, rowDraggable]);
3360
+ const handleRowOrderPointerMove = useCallback2((event) => {
3361
+ const drag = rowOrderDragRef.current;
3362
+ if (!drag || drag.pointerId !== event.pointerId) return;
3363
+ if (!drag.active) {
3364
+ if (Math.abs(event.clientY - drag.startY) < 4) return;
3365
+ drag.active = true;
3366
+ suppressClickRef.current = true;
3367
+ hideDragTooltips();
3368
+ document.documentElement.classList.add("rvg-is-dragging");
3369
+ event.currentTarget.style.cursor = "move";
3370
+ }
3371
+ event.preventDefault();
3372
+ const rawTargetIndex = locateRow(event.clientY);
3373
+ if (rawTargetIndex < 0) return;
3374
+ const canvasTop = event.currentTarget.getBoundingClientRect().top;
3375
+ const rowTop = bodyTop + rawTargetIndex * rowHeight - scrollRef.current.top;
3376
+ const edge = event.clientY - canvasTop < rowTop + rowHeight / 2 ? "top" : "bottom";
3377
+ let targetIndex = rawTargetIndex + (edge === "bottom" ? 1 : 0);
3378
+ if (drag.sourceIndex < targetIndex) targetIndex -= 1;
3379
+ targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
3380
+ drag.targetIndex = targetIndex;
3381
+ setRowDragPreview((current) => current?.sourceIndex === drag.sourceIndex && current.targetIndex === targetIndex ? current : { sourceIndex: drag.sourceIndex, targetIndex });
3382
+ setRowDragGuide(rowTop + (edge === "bottom" ? rowHeight : 0));
3383
+ }, [bodyTop, hideDragTooltips, locateRow, rowHeight, rows.length, setRowDragGuide]);
3384
+ const finishRowOrderPointerDrag = useCallback2((event, apply) => {
3385
+ const drag = rowOrderDragRef.current;
3386
+ if (!drag || drag.pointerId !== event.pointerId) return;
3387
+ if (event.currentTarget.hasPointerCapture?.(event.pointerId)) event.currentTarget.releasePointerCapture?.(event.pointerId);
3388
+ rowOrderDragRef.current = null;
3389
+ setRowDragPreview(null);
3390
+ setRowDragGuide(null);
3391
+ document.documentElement.classList.remove("rvg-is-dragging");
3392
+ event.currentTarget.style.cursor = "default";
3393
+ if (apply && drag.active && drag.sourceIndex !== drag.targetIndex) {
3394
+ scrollerRef.current?.classList.add("rvg-row-drop-settling");
3395
+ applyRowOrder(drag.sourceIndex, drag.targetIndex);
3396
+ requestAnimationFrame(() => {
3397
+ requestAnimationFrame(() => scrollerRef.current?.classList.remove("rvg-row-drop-settling"));
3398
+ });
3399
+ }
3400
+ }, [applyRowOrder, setRowDragGuide]);
3439
3401
  const locateCell = useCallback2((clientX, clientY) => {
3440
3402
  const canvas = canvasRef.current;
3441
3403
  if (!canvas) return null;
@@ -5028,7 +4990,7 @@ function TableInner({
5028
4990
  }
5029
4991
  }
5030
4992
  }
5031
- const cursor = inHeader && locateHeaderResizeCell(event.clientX, event.clientY) ? "col-resize" : hoveredAction ? "pointer" : hoveredDragHandle ? "move" : columnIndex >= 0 && columns[columnIndex].rowSelection ? "pointer" : !inHeader && rowDraggable && columnIndex >= 0 && columns[columnIndex].rowDragHandle ? "move" : "default";
4993
+ const cursor = inHeader && locateHeaderResizeCell(event.clientX, event.clientY) ? "col-resize" : hoveredAction ? "pointer" : hoveredDragHandle ? "move" : !inHeader && rowDraggable && columnIndex >= 0 && columns[columnIndex].rowDragHandle ? "move" : columnIndex >= 0 && columns[columnIndex].rowSelection ? "pointer" : "default";
5032
4994
  if (event.currentTarget.style.cursor !== cursor) event.currentTarget.style.cursor = cursor;
5033
4995
  },
5034
4996
  onMouseLeave: (event) => {
@@ -5047,6 +5009,7 @@ function TableInner({
5047
5009
  }
5048
5010
  },
5049
5011
  onPointerDown: (event) => {
5012
+ handleRowOrderPointerDown(event);
5050
5013
  handleColumnPointerDown(event);
5051
5014
  if (columnDragRef.current) return;
5052
5015
  const headerDragCell = columnDraggable ? locateHeaderCell(event.clientX, event.clientY) : null;
@@ -5059,16 +5022,19 @@ function TableInner({
5059
5022
  beginRangeDrag(event);
5060
5023
  },
5061
5024
  onPointerMove: (event) => {
5025
+ handleRowOrderPointerMove(event);
5062
5026
  handleColumnPointerMove(event);
5063
5027
  handleColumnOrderPointerMove(event);
5064
5028
  updateRangeDrag(event);
5065
5029
  },
5066
5030
  onPointerUp: (event) => {
5031
+ finishRowOrderPointerDrag(event, true);
5067
5032
  handleColumnPointerUp(event);
5068
5033
  finishColumnOrderPointerDrag(event, true);
5069
5034
  endRangeDrag(event);
5070
5035
  },
5071
5036
  onPointerCancel: (event) => {
5037
+ finishRowOrderPointerDrag(event, false);
5072
5038
  handleColumnPointerUp(event);
5073
5039
  finishColumnOrderPointerDrag(event, false);
5074
5040
  endRangeDrag(event);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensui/lens-table",
3
- "version": "0.1.76",
3
+ "version": "0.1.78",
4
4
  "description": "A lightweight, canvas-rendered React table component for LensUI.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",