@geomak/ui 7.14.0 → 7.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +72 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +72 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -2769,6 +2769,8 @@ interface DataGridProps {
|
|
|
2769
2769
|
onDeleteRow?: (index: number) => void;
|
|
2770
2770
|
/** Insert a column at `index` (from the column-header right-click menu). */
|
|
2771
2771
|
onInsertColumn?: (index: number) => void;
|
|
2772
|
+
/** Rename a column. When set, headers become editable (double-click / Rename menu). */
|
|
2773
|
+
onHeaderEdit?: (index: number, label: string) => void;
|
|
2772
2774
|
className?: string;
|
|
2773
2775
|
style?: react__default.CSSProperties;
|
|
2774
2776
|
/** Shown when there are no rows. */
|
|
@@ -2785,7 +2787,7 @@ interface DataGridProps {
|
|
|
2785
2787
|
* `onCellEdit` on commit. Wrap it with {@link Spreadsheet} for multi-sheet
|
|
2786
2788
|
* switching, file parsing and export.
|
|
2787
2789
|
*/
|
|
2788
|
-
declare function DataGrid({ columns, rows, rowHeight, headerHeight, height, width, editable, sortable, sort: sortProp, onSortChange, virtualize, overscan, rowNumbers, trailingRows, trailingCols, onCellEdit, contextMenu, onInsertRow, onDeleteRow, onInsertColumn, className, style, emptyState, }: DataGridProps): react_jsx_runtime.JSX.Element;
|
|
2790
|
+
declare function DataGrid({ columns, rows, rowHeight, headerHeight, height, width, editable, sortable, sort: sortProp, onSortChange, virtualize, overscan, rowNumbers, trailingRows, trailingCols, onCellEdit, contextMenu, onInsertRow, onDeleteRow, onInsertColumn, onHeaderEdit, className, style, emptyState, }: DataGridProps): react_jsx_runtime.JSX.Element;
|
|
2789
2791
|
|
|
2790
2792
|
interface Cell {
|
|
2791
2793
|
value: CellValue;
|
package/dist/index.d.ts
CHANGED
|
@@ -2769,6 +2769,8 @@ interface DataGridProps {
|
|
|
2769
2769
|
onDeleteRow?: (index: number) => void;
|
|
2770
2770
|
/** Insert a column at `index` (from the column-header right-click menu). */
|
|
2771
2771
|
onInsertColumn?: (index: number) => void;
|
|
2772
|
+
/** Rename a column. When set, headers become editable (double-click / Rename menu). */
|
|
2773
|
+
onHeaderEdit?: (index: number, label: string) => void;
|
|
2772
2774
|
className?: string;
|
|
2773
2775
|
style?: react__default.CSSProperties;
|
|
2774
2776
|
/** Shown when there are no rows. */
|
|
@@ -2785,7 +2787,7 @@ interface DataGridProps {
|
|
|
2785
2787
|
* `onCellEdit` on commit. Wrap it with {@link Spreadsheet} for multi-sheet
|
|
2786
2788
|
* switching, file parsing and export.
|
|
2787
2789
|
*/
|
|
2788
|
-
declare function DataGrid({ columns, rows, rowHeight, headerHeight, height, width, editable, sortable, sort: sortProp, onSortChange, virtualize, overscan, rowNumbers, trailingRows, trailingCols, onCellEdit, contextMenu, onInsertRow, onDeleteRow, onInsertColumn, className, style, emptyState, }: DataGridProps): react_jsx_runtime.JSX.Element;
|
|
2790
|
+
declare function DataGrid({ columns, rows, rowHeight, headerHeight, height, width, editable, sortable, sort: sortProp, onSortChange, virtualize, overscan, rowNumbers, trailingRows, trailingCols, onCellEdit, contextMenu, onInsertRow, onDeleteRow, onInsertColumn, onHeaderEdit, className, style, emptyState, }: DataGridProps): react_jsx_runtime.JSX.Element;
|
|
2789
2791
|
|
|
2790
2792
|
interface Cell {
|
|
2791
2793
|
value: CellValue;
|
package/dist/index.js
CHANGED
|
@@ -6501,6 +6501,7 @@ function DataGrid({
|
|
|
6501
6501
|
onInsertRow,
|
|
6502
6502
|
onDeleteRow,
|
|
6503
6503
|
onInsertColumn,
|
|
6504
|
+
onHeaderEdit,
|
|
6504
6505
|
className = "",
|
|
6505
6506
|
style,
|
|
6506
6507
|
emptyState = "No data"
|
|
@@ -6513,6 +6514,8 @@ function DataGrid({
|
|
|
6513
6514
|
const [ctxTarget, setCtxTarget] = useState(null);
|
|
6514
6515
|
const [editing, setEditing] = useState(null);
|
|
6515
6516
|
const [draft, setDraft] = useState("");
|
|
6517
|
+
const [editingHeader, setEditingHeader] = useState(null);
|
|
6518
|
+
const [headerDraft, setHeaderDraft] = useState("");
|
|
6516
6519
|
const [internalSort, setInternalSort] = useState(null);
|
|
6517
6520
|
const sort = sortProp !== void 0 ? sortProp : internalSort;
|
|
6518
6521
|
const gutter = rowNumbers ? GUTTER : 0;
|
|
@@ -6589,6 +6592,17 @@ function DataGrid({
|
|
|
6589
6592
|
setDraft(displayValue(rows[rowIndexForDisp(disp)]?.[c.key] ?? ""));
|
|
6590
6593
|
setEditing({ disp, col });
|
|
6591
6594
|
};
|
|
6595
|
+
const startHeaderEdit = (col) => {
|
|
6596
|
+
if (!onHeaderEdit) return;
|
|
6597
|
+
const c = cols[col];
|
|
6598
|
+
setHeaderDraft(typeof c.label === "string" ? c.label : String(c.key));
|
|
6599
|
+
setEditingHeader(col);
|
|
6600
|
+
};
|
|
6601
|
+
const commitHeader = () => {
|
|
6602
|
+
if (editingHeader == null) return;
|
|
6603
|
+
onHeaderEdit?.(editingHeader, headerDraft);
|
|
6604
|
+
setEditingHeader(null);
|
|
6605
|
+
};
|
|
6592
6606
|
const cellText = (sel) => displayValue(rows[rowIndexForDisp(sel.disp)]?.[cols[sel.col].key] ?? "");
|
|
6593
6607
|
const copyCell = useCallback(async () => {
|
|
6594
6608
|
if (!selected) return;
|
|
@@ -6616,7 +6630,8 @@ function DataGrid({
|
|
|
6616
6630
|
if (ctxTarget?.kind === "header") {
|
|
6617
6631
|
const ci = ctxTarget.col;
|
|
6618
6632
|
return [
|
|
6619
|
-
{ key: "
|
|
6633
|
+
{ key: "rename", value: "Rename column", disabled: !onHeaderEdit, onClick: () => startHeaderEdit(ci) },
|
|
6634
|
+
{ key: "left", value: "Add column to the left", disabled: !onInsertColumn, separatorBefore: true, onClick: () => onInsertColumn?.(ci) },
|
|
6620
6635
|
{ key: "right", value: "Add column to the right", disabled: !onInsertColumn, onClick: () => onInsertColumn?.(ci + 1) }
|
|
6621
6636
|
];
|
|
6622
6637
|
}
|
|
@@ -6634,7 +6649,7 @@ function DataGrid({
|
|
|
6634
6649
|
{ key: "cut", value: "Cut", disabled: !editable, onClick: () => void cutCell() },
|
|
6635
6650
|
{ key: "paste", value: "Paste", disabled: !editable, onClick: () => void pasteCell() }
|
|
6636
6651
|
];
|
|
6637
|
-
}, [ctxTarget, rows.length, editable, onInsertRow, onDeleteRow, onInsertColumn, copyCell, cutCell, pasteCell, order]);
|
|
6652
|
+
}, [ctxTarget, rows.length, editable, onInsertRow, onDeleteRow, onInsertColumn, onHeaderEdit, copyCell, cutCell, pasteCell, order]);
|
|
6638
6653
|
const rowHighlighted = (disp) => hoveredRow === disp || selected?.disp === disp;
|
|
6639
6654
|
const gridInner = /* @__PURE__ */ jsxs("div", { style: { position: "relative", width: gutter + totalWidth + END_PAD, height: headerHeight + totalHeight + END_PAD }, children: [
|
|
6640
6655
|
rowNumbers && /* @__PURE__ */ jsx(
|
|
@@ -6648,16 +6663,20 @@ function DataGrid({
|
|
|
6648
6663
|
const c = cols[ci];
|
|
6649
6664
|
const sortDir = sort?.key === c.key ? sort.dir : null;
|
|
6650
6665
|
const canSort = colSortable(c);
|
|
6651
|
-
|
|
6666
|
+
const renamable = !!onHeaderEdit;
|
|
6667
|
+
const isEditingHeader = editingHeader === ci;
|
|
6668
|
+
return /* @__PURE__ */ jsx(
|
|
6652
6669
|
"div",
|
|
6653
6670
|
{
|
|
6654
6671
|
role: "columnheader",
|
|
6655
6672
|
"aria-sort": sortDir ? sortDir === "asc" ? "ascending" : "descending" : void 0,
|
|
6656
|
-
onClick: canSort ? () => toggleSort(c.key) : void 0,
|
|
6673
|
+
onClick: canSort && !renamable ? () => toggleSort(c.key) : void 0,
|
|
6674
|
+
onDoubleClick: renamable ? () => startHeaderEdit(ci) : void 0,
|
|
6657
6675
|
onContextMenu: contextMenu ? () => setCtxTarget({ kind: "header", col: ci }) : void 0,
|
|
6658
6676
|
className: cx(
|
|
6659
6677
|
"flex items-center gap-1 border-b border-r border-border bg-surface px-3 font-medium text-foreground-secondary",
|
|
6660
|
-
canSort && "cursor-pointer select-none hover:text-foreground"
|
|
6678
|
+
canSort && !renamable && "cursor-pointer select-none hover:text-foreground",
|
|
6679
|
+
renamable && "cursor-default select-none"
|
|
6661
6680
|
),
|
|
6662
6681
|
style: {
|
|
6663
6682
|
position: "absolute",
|
|
@@ -6668,10 +6687,27 @@ function DataGrid({
|
|
|
6668
6687
|
zIndex: 2,
|
|
6669
6688
|
justifyContent: c.align === "right" ? "flex-end" : c.align === "center" ? "center" : "flex-start"
|
|
6670
6689
|
},
|
|
6671
|
-
children:
|
|
6690
|
+
children: isEditingHeader ? /* @__PURE__ */ jsx(
|
|
6691
|
+
"input",
|
|
6692
|
+
{
|
|
6693
|
+
autoFocus: true,
|
|
6694
|
+
value: headerDraft,
|
|
6695
|
+
onChange: (e) => setHeaderDraft(e.target.value),
|
|
6696
|
+
onBlur: commitHeader,
|
|
6697
|
+
onClick: (e) => e.stopPropagation(),
|
|
6698
|
+
onKeyDown: (e) => {
|
|
6699
|
+
if (e.key === "Enter") commitHeader();
|
|
6700
|
+
else if (e.key === "Escape") setEditingHeader(null);
|
|
6701
|
+
},
|
|
6702
|
+
className: "h-full w-full bg-transparent font-medium text-foreground outline-none"
|
|
6703
|
+
}
|
|
6704
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6672
6705
|
/* @__PURE__ */ jsx("span", { className: "truncate", children: c.label ?? c.key }),
|
|
6673
|
-
canSort && /* @__PURE__ */ jsx(
|
|
6674
|
-
|
|
6706
|
+
canSort && (renamable ? /* @__PURE__ */ jsx("button", { type: "button", title: "Sort", onClick: (e) => {
|
|
6707
|
+
e.stopPropagation();
|
|
6708
|
+
toggleSort(c.key);
|
|
6709
|
+
}, className: "flex-shrink-0 rounded hover:text-foreground", children: /* @__PURE__ */ jsx(SortCaret, { dir: sortDir }) }) : /* @__PURE__ */ jsx(SortCaret, { dir: sortDir }))
|
|
6710
|
+
] })
|
|
6675
6711
|
},
|
|
6676
6712
|
`h-${c.key}`
|
|
6677
6713
|
);
|
|
@@ -6908,12 +6944,21 @@ function Spreadsheet({
|
|
|
6908
6944
|
const sheet = sheets?.[active];
|
|
6909
6945
|
const columns = useMemo(() => sheet ? toColumns(sheet.columns) : [], [sheet]);
|
|
6910
6946
|
const plainRows = useMemo(() => sheet ? toPlainRows(sheet, columns) : [], [sheet, columns]);
|
|
6947
|
+
const displayColumns = useMemo(
|
|
6948
|
+
() => [...columns, ...makeColumns(columns, Math.max(0, emptyCols)).map((c) => ({ ...c, sortable: false }))],
|
|
6949
|
+
[columns, emptyCols]
|
|
6950
|
+
);
|
|
6951
|
+
const isSlackKey = (key) => !columns.some((c) => c.key === key);
|
|
6911
6952
|
const handleCellEdit = useCallback(({ row, column, value }) => {
|
|
6912
6953
|
let coerced = value;
|
|
6913
6954
|
setSheets((prev) => {
|
|
6914
6955
|
if (!prev) return prev;
|
|
6915
|
-
const next = prev.map((s, i) => i === active ? { ...s, rows: s.rows.map((r) => ({ ...r })) } : s);
|
|
6956
|
+
const next = prev.map((s, i) => i === active ? { ...s, columns: toColumns(s.columns), rows: s.rows.map((r) => ({ ...r })) } : s);
|
|
6916
6957
|
const target = next[active];
|
|
6958
|
+
if (isSlackKey(column)) {
|
|
6959
|
+
const j = displayColumns.findIndex((c) => c.key === column);
|
|
6960
|
+
if (j >= 0) target.columns = displayColumns.slice(0, j + 1).map((c) => ({ key: c.key, label: c.label }));
|
|
6961
|
+
}
|
|
6917
6962
|
while (target.rows.length <= row) target.rows.push({});
|
|
6918
6963
|
const existing = target.rows[row]?.[column];
|
|
6919
6964
|
const prevValue = cellValue(existing);
|
|
@@ -6927,7 +6972,22 @@ function Spreadsheet({
|
|
|
6927
6972
|
return next;
|
|
6928
6973
|
});
|
|
6929
6974
|
onCellEdit?.({ sheet: sheets?.[active]?.name ?? "", row, column, value: coerced });
|
|
6930
|
-
}, [active, onCellEdit, onChange, sheets]);
|
|
6975
|
+
}, [active, onCellEdit, onChange, sheets, displayColumns, columns]);
|
|
6976
|
+
const renameColumn = useCallback((index, label) => {
|
|
6977
|
+
setSheets((prev) => {
|
|
6978
|
+
if (!prev) return prev;
|
|
6979
|
+
const next = prev.map((s, i) => i === active ? { ...s, columns: toColumns(s.columns) } : s);
|
|
6980
|
+
const target = next[active];
|
|
6981
|
+
let tcols = target.columns;
|
|
6982
|
+
if (index >= tcols.length) {
|
|
6983
|
+
tcols = displayColumns.slice(0, index + 1).map((c) => ({ key: c.key, label: c.label }));
|
|
6984
|
+
target.columns = tcols;
|
|
6985
|
+
}
|
|
6986
|
+
if (tcols[index]) tcols[index] = { ...tcols[index], label };
|
|
6987
|
+
onChange?.(next);
|
|
6988
|
+
return next;
|
|
6989
|
+
});
|
|
6990
|
+
}, [active, onChange, displayColumns]);
|
|
6931
6991
|
const addSheet = useCallback(() => {
|
|
6932
6992
|
setSheets((prev) => {
|
|
6933
6993
|
const list = prev ?? [];
|
|
@@ -7145,17 +7205,17 @@ function Spreadsheet({
|
|
|
7145
7205
|
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx(
|
|
7146
7206
|
DataGrid,
|
|
7147
7207
|
{
|
|
7148
|
-
columns,
|
|
7208
|
+
columns: displayColumns,
|
|
7149
7209
|
rows: plainRows,
|
|
7150
7210
|
editable,
|
|
7151
7211
|
sortable,
|
|
7152
7212
|
virtualize,
|
|
7153
7213
|
trailingRows: emptyRows,
|
|
7154
|
-
trailingCols: emptyCols,
|
|
7155
7214
|
contextMenu: true,
|
|
7156
7215
|
onInsertRow: editable ? insertRow : void 0,
|
|
7157
7216
|
onDeleteRow: editable ? deleteRow : void 0,
|
|
7158
7217
|
onInsertColumn: editable ? insertColumn : void 0,
|
|
7218
|
+
onHeaderEdit: editable ? renameColumn : void 0,
|
|
7159
7219
|
onCellEdit: handleCellEdit,
|
|
7160
7220
|
height: "100%",
|
|
7161
7221
|
className: "!rounded-none !border-0"
|