@marimo-team/frontend 0.24.1-dev79 → 0.24.1-dev80

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.
Files changed (87) hide show
  1. package/dist/assets/{CellStatus-Bfn_Ysig.js → CellStatus-DMQfH9wD.js} +1 -1
  2. package/dist/assets/{JsonOutput-DFd7q8lz.js → JsonOutput-B7sDhGzR.js} +1 -1
  3. package/dist/assets/{MarimoErrorOutput-DfRv7_jc.js → MarimoErrorOutput-C0vk393J.js} +1 -1
  4. package/dist/assets/{RenderHTML-Di-OdQjY.js → RenderHTML-BnMaGpV8.js} +1 -1
  5. package/dist/assets/{RunButton-r21rSvYz.js → RunButton-nocIODpS.js} +1 -1
  6. package/dist/assets/{add-cell-with-ai-Cc3EENeX.js → add-cell-with-ai-B_TSaqjJ.js} +1 -1
  7. package/dist/assets/{add-connection-dialog-Bce8iA2c.js → add-connection-dialog-DOuojDa-.js} +1 -1
  8. package/dist/assets/{agent-panel-COvCNnaD.js → agent-panel-CkKCGjDp.js} +1 -1
  9. package/dist/assets/{ai-model-dropdown-D7nJTvh4.js → ai-model-dropdown-CfWMIzjl.js} +1 -1
  10. package/dist/assets/{app-config-button-C0IsSBiP.js → app-config-button-ii-Hj5CZ.js} +1 -1
  11. package/dist/assets/{blob-CbiWlEJN.js → blob-CYM8xQsK.js} +1 -1
  12. package/dist/assets/{cell-editor-DnyPiOtX.js → cell-editor-BVb6iKbw.js} +1 -1
  13. package/dist/assets/{cell-link-Z8JrraTv.js → cell-link-DCOAqVkE.js} +1 -1
  14. package/dist/assets/{cells-CD9Jbpoa.js → cells-C6lBv8kg.js} +51 -51
  15. package/dist/assets/{chat-display-Dxad67GU.js → chat-display-B6GBZDq8.js} +1 -1
  16. package/dist/assets/{chat-panel-b6eYwY8N.js → chat-panel-wWuBXhXw.js} +1 -1
  17. package/dist/assets/{chat-ui-DWgQGHiC.js → chat-ui-CQ7A3qdB.js} +1 -1
  18. package/dist/assets/click-outside-container-C5RF3h4V.js +1 -0
  19. package/dist/assets/{column-preview-_GkpGxG-.js → column-preview-CatwdUda.js} +1 -1
  20. package/dist/assets/{command-palette-BeHx267T.js → command-palette-DcPM_WiO.js} +1 -1
  21. package/dist/assets/{common-Bb2s_Imb.js → common-B4aMxphz.js} +1 -1
  22. package/dist/assets/{components-D5125bx8.js → components-D8-ffQsq.js} +1 -1
  23. package/dist/assets/data-grid-overlay-editor-CFYeXDX3.js +1 -0
  24. package/dist/assets/data-grid-types-DgHVN_Zz.js +1 -0
  25. package/dist/assets/{datasource-DTtEQWz7.js → datasource-D-_jFtGs.js} +1 -1
  26. package/dist/assets/{dependency-graph-panel-DiMc1DOt.js → dependency-graph-panel-BQli6zxh.js} +1 -1
  27. package/dist/assets/{documentation-panel-ChEa8OHk.js → documentation-panel-_QE3nPOg.js} +1 -1
  28. package/dist/assets/{download-BKMVrvLm.js → download-Cqjqrhzo.js} +1 -1
  29. package/dist/assets/{edit-page-C3Uo5Msq.js → edit-page-RuyN164g.js} +4 -4
  30. package/dist/assets/{error-entries-DI864MPn.js → error-entries-c5sIySli.js} +1 -1
  31. package/dist/assets/{error-panel-COOOtEg7.js → error-panel-CXKrWK_u.js} +1 -1
  32. package/dist/assets/{file-explorer-panel-DeF49Ng1.js → file-explorer-panel-BZiAb4x_.js} +1 -1
  33. package/dist/assets/{file-icons-CmmWEUGv.js → file-icons-uUY_hGYm.js} +1 -1
  34. package/dist/assets/{file-name-input-9sqInamo.js → file-name-input-DWUKg4LS.js} +1 -1
  35. package/dist/assets/{floating-outline-BxMKEygY.js → floating-outline-DhGtHg6T.js} +1 -1
  36. package/dist/assets/glide-data-editor-DZ2Minh8.js +131 -0
  37. package/dist/assets/glide-utils-CR1sWLZU.js +2 -0
  38. package/dist/assets/{home-page-G9DBo7dA.js → home-page-Bka_7H02.js} +1 -1
  39. package/dist/assets/index-ChbtcNW2.js +29 -0
  40. package/dist/assets/{layout-RSFs10mJ.js → layout-Uv1ZP5XB.js} +3 -3
  41. package/dist/assets/{logs-panel-DaLUKPBX.js → logs-panel-ragZa1sf.js} +1 -1
  42. package/dist/assets/{markdown-renderer-Cj57nlKH.js → markdown-renderer-B-uA_6mP.js} +1 -1
  43. package/dist/assets/{useNonce-BTM6-ANi.js → marked.esm-B_3iMIUq.js} +10 -10
  44. package/dist/assets/{name-cell-input-D0M2lddE.js → name-cell-input-gC1flbyT.js} +1 -1
  45. package/dist/assets/{outline-panel-UDArUDGw.js → outline-panel-D7H7bhOh.js} +1 -1
  46. package/dist/assets/{packages-panel-B8AaXFcI.js → packages-panel-BZnsUm4S.js} +1 -1
  47. package/dist/assets/{panel-accordion-state-COnGLerF.js → panel-accordion-state-BLU7OiMD.js} +1 -1
  48. package/dist/assets/{panels-DecWMR6G.js → panels-B3Y6fue9.js} +1 -1
  49. package/dist/assets/{process-output-CUf8H__q.js → process-output-DQQ8T5gv.js} +1 -1
  50. package/dist/assets/{readonly-code-display-Bof9MzZO.js → readonly-code-display-Bc0VX9i6.js} +1 -1
  51. package/dist/assets/{readonly-python-code-GMl_IocT.js → readonly-python-code-D2HXwAfT.js} +1 -1
  52. package/dist/assets/{reveal-component-yDciCkP9.js → reveal-component-BN1C8zFu.js} +1 -1
  53. package/dist/assets/{run-page-CCk94ccj.js → run-page-ByVvsH9G.js} +1 -1
  54. package/dist/assets/{scratchpad-panel-EL1m3Huh.js → scratchpad-panel-BJHlMBZV.js} +1 -1
  55. package/dist/assets/{session-panel-DKjUcjvg.js → session-panel-CdCKWAOf.js} +1 -1
  56. package/dist/assets/{skeleton-D71npu63.js → skeleton-DirOIQrj.js} +1 -1
  57. package/dist/assets/{snippets-panel-njDHc9qT.js → snippets-panel-2jq36DdG.js} +1 -1
  58. package/dist/assets/{state-CwrzGizs.js → state-C9O-2hQL.js} +1 -1
  59. package/dist/assets/{state-mneM4Ao8.js → state-DyxPdcEa.js} +1 -1
  60. package/dist/assets/{tracing-CGZCxvWG.js → tracing-91_akEkv.js} +1 -1
  61. package/dist/assets/{tracing-panel-4lmoUwoQ.js → tracing-panel-BvE81RYx.js} +2 -2
  62. package/dist/assets/{tree-actions-Bjyy0vFK.js → tree-actions-CGkbUSfG.js} +1 -1
  63. package/dist/assets/{useAddCell-h4OWLK5y.js → useAddCell-DqvY2ulx.js} +1 -1
  64. package/dist/assets/{useCellActionButton-BvuYvLCr.js → useCellActionButton-cv6xOsnc.js} +1 -1
  65. package/dist/assets/{useDeleteCell-Buwee6vZ.js → useDeleteCell-DB-bhhnO.js} +1 -1
  66. package/dist/assets/{useDependencyPanelTab-CLR1fyXm.js → useDependencyPanelTab-BDnVzNV-.js} +1 -1
  67. package/dist/assets/{useNotebookActions-C0Uw9roU.js → useNotebookActions-Dxp4gTEa.js} +1 -1
  68. package/dist/assets/{useRunCells-C6416Qeo.js → useRunCells-GCTS1YFv.js} +1 -1
  69. package/dist/assets/{useSplitCell-Ip3d7gP0.js → useSplitCell-DhT9BA2_.js} +1 -1
  70. package/dist/index.html +22 -21
  71. package/package.json +1 -1
  72. package/src/plugins/impl/DataEditorPlugin.tsx +38 -70
  73. package/src/plugins/impl/__tests__/DataEditorPlugin.test.ts +152 -1
  74. package/src/plugins/impl/data-editor/__tests__/data-utils.test.ts +73 -78
  75. package/src/plugins/impl/data-editor/__tests__/editor-state.test.ts +113 -0
  76. package/src/plugins/impl/data-editor/__tests__/glide-data-editor.test.tsx +49 -13
  77. package/src/plugins/impl/data-editor/__tests__/glide-utils.test.ts +44 -64
  78. package/src/plugins/impl/data-editor/data-utils.ts +76 -53
  79. package/src/plugins/impl/data-editor/editor-state.ts +108 -0
  80. package/src/plugins/impl/data-editor/glide-data-editor.tsx +40 -223
  81. package/src/plugins/impl/data-editor/glide-utils.ts +71 -31
  82. package/src/plugins/impl/data-editor/types.ts +30 -16
  83. package/dist/assets/click-outside-container-n76g8dsY.js +0 -1
  84. package/dist/assets/data-grid-overlay-editor-DCmC8-tb.js +0 -1
  85. package/dist/assets/glide-data-editor-CzalkCph.js +0 -132
  86. package/dist/assets/index-BmNpxjzV.js +0 -29
  87. package/dist/assets/types-BflGgckY.js +0 -1
@@ -14,13 +14,7 @@ import DataEditor, {
14
14
  type Rectangle,
15
15
  } from "@glideapps/glide-data-grid";
16
16
  import { CopyIcon, TrashIcon } from "lucide-react";
17
- import React, {
18
- useCallback,
19
- useEffect,
20
- useMemo,
21
- useRef,
22
- useState,
23
- } from "react";
17
+ import React, { useCallback, useMemo, useRef, useState } from "react";
24
18
  import useEvent from "react-use-event-hook";
25
19
  import type { FieldTypes } from "@/components/data-table/types";
26
20
  import {
@@ -34,59 +28,39 @@ import { copyToClipboard } from "@/utils/copy";
34
28
  import {
35
29
  getColumnHeaderIcon,
36
30
  getColumnKind,
37
- isColumnEdit,
38
- isPositionalEdit,
39
- isRowEdit,
31
+ isValidCellValue,
40
32
  pasteCells,
41
33
  } from "./glide-utils";
42
34
  import { getGlideTheme } from "./themes";
43
- import { BulkEdit, type Edits, type ModifiedGridColumn } from "./types";
44
35
  import "@glideapps/glide-data-grid/dist/index.css"; // TODO: We are reimporting this
45
36
  import { ErrorBoundary } from "@/components/editor/boundary/ErrorBoundary";
46
37
  import { Button } from "@/components/ui/button";
47
38
  import { toast } from "@/components/ui/use-toast";
48
39
  import type { DataType } from "@/core/kernel/messages";
49
- import { useNonce } from "@/hooks/useNonce";
50
40
  import { logNever } from "@/utils/assertNever";
51
41
  import { Events } from "@/utils/events";
52
42
  import { AddColumnSub, RenameColumnSub } from "./components";
53
- import {
54
- insertColumn,
55
- modifyColumnFields,
56
- removeColumn,
57
- renameColumn,
58
- } from "./data-utils";
59
43
  import { GlideDataEditorPortal } from "./glide-portal";
60
-
61
- interface GlideDataEditorProps<T> {
62
- data: T[];
63
- setData: (data: T[] | ((prev: T[]) => T[])) => void;
44
+ import {
45
+ BulkEdit,
46
+ type EditorRow,
47
+ type Edits,
48
+ type ModifiedGridColumn,
49
+ } from "./types";
50
+
51
+ interface GlideDataEditorProps {
52
+ data: EditorRow[];
64
53
  columnFields: FieldTypes;
65
- setColumnFields: React.Dispatch<React.SetStateAction<FieldTypes>>;
66
54
  editableColumns: string[] | "all";
67
- edits: Edits["edits"];
68
55
  onAddEdits: (edits: Edits["edits"]) => void;
69
- onAddRows: (newRows: object[]) => void;
70
- onDeleteRows: (rows: number[]) => void;
71
- onRenameColumn: (columnIdx: number, newName: string) => void;
72
- onDeleteColumn: (columnIdx: number) => void;
73
- onAddColumn: (columnIdx: number, newName: string) => void;
74
56
  }
75
57
 
76
- export const GlideDataEditor = <T,>({
58
+ export const GlideDataEditor = ({
77
59
  data,
78
- setData,
79
60
  columnFields,
80
- setColumnFields,
81
61
  editableColumns,
82
- edits,
83
62
  onAddEdits,
84
- onAddRows,
85
- onDeleteRows,
86
- onRenameColumn,
87
- onDeleteColumn,
88
- onAddColumn,
89
- }: GlideDataEditorProps<T>) => {
63
+ }: GlideDataEditorProps) => {
90
64
  const { theme } = useTheme();
91
65
  const dataEditorRef = useRef<DataEditorRef>(null);
92
66
  const portalElementRef = useRef<HTMLDivElement>(null);
@@ -99,8 +73,6 @@ export const GlideDataEditor = <T,>({
99
73
  });
100
74
 
101
75
  const [columnWidths, setColumnWidths] = useState<Record<string, number>>({});
102
- const rerender = useNonce();
103
- const hasAppliedEdits = useRef(false);
104
76
 
105
77
  const columns: ModifiedGridColumn[] = useMemo(() => {
106
78
  const columns: ModifiedGridColumn[] = [];
@@ -130,114 +102,12 @@ export const GlideDataEditor = <T,>({
130
102
  return columns;
131
103
  }, [columnFields, columnWidths, editableColumns, theme]);
132
104
 
133
- // Apply initial edits after data has loaded
134
- useEffect(() => {
135
- // Don't apply if already applied or data hasn't loaded yet
136
- if (hasAppliedEdits.current || data.length === 0) {
137
- return;
138
- }
139
-
140
- // Mark as applied once data loads - prevents re-applying user edits
141
- hasAppliedEdits.current = true;
142
-
143
- // No initial edits to apply
144
- if (edits.length === 0) {
145
- return;
146
- }
147
-
148
- // Group edits by row index to build new rows
149
- const newRows = new Map<number, Record<string, unknown>>();
150
-
151
- for (const edit of edits) {
152
- if (isPositionalEdit(edit)) {
153
- if (edit.rowIdx >= data.length) {
154
- // This is a new row
155
- if (!newRows.has(edit.rowIdx)) {
156
- newRows.set(edit.rowIdx, {});
157
- }
158
- const row = newRows.get(edit.rowIdx);
159
- if (row) {
160
- row[edit.columnId] = edit.value;
161
- }
162
- } else {
163
- // This is an existing row, update the data
164
- setData((prev) => {
165
- const newData = [...prev];
166
- newData[edit.rowIdx][edit.columnId as keyof T] =
167
- edit.value as T[keyof T];
168
- return newData;
169
- });
170
- }
171
- } else if (isRowEdit(edit) && edit.type === BulkEdit.Remove) {
172
- // Add rows is currently handled under positional edits, so we only cover deletes here
173
- setData((prev) => prev.filter((_, i) => i !== edit.rowIdx));
174
- } else if (isColumnEdit(edit)) {
175
- switch (edit.type) {
176
- case BulkEdit.Remove:
177
- // Remove the column from the data
178
- setData((prev) => removeColumn(prev, edit.columnIdx));
179
- setColumnFields((prev) =>
180
- modifyColumnFields({
181
- columnFields: prev,
182
- columnIdx: edit.columnIdx,
183
- type: "remove",
184
- }),
185
- );
186
- break;
187
- case BulkEdit.Insert:
188
- setColumnFields((prev) =>
189
- modifyColumnFields({
190
- columnFields: prev,
191
- columnIdx: edit.columnIdx,
192
- type: "insert",
193
- newColumnName: edit.newName,
194
- }),
195
- );
196
- setData((prev) => insertColumn(prev, edit.newName));
197
- break;
198
- case BulkEdit.Rename: {
199
- const oldName = columns[edit.columnIdx].title;
200
- const newName = edit.newName;
201
- if (!oldName || !newName) {
202
- return;
203
- }
204
-
205
- setColumnFields((prev) =>
206
- modifyColumnFields({
207
- columnFields: prev,
208
- columnIdx: edit.columnIdx,
209
- type: "rename",
210
- newColumnName: newName,
211
- }),
212
- );
213
-
214
- setData((prev) => renameColumn(prev, oldName, newName));
215
- break;
216
- }
217
- }
218
- }
219
- }
220
-
221
- // Add new rows in order
222
- const sortedNewRows = [...newRows.entries()]
223
- .toSorted(([a], [b]) => a - b)
224
- .map(([, row]) => row);
225
-
226
- if (sortedNewRows.length > 0) {
227
- setData((prev) => [...prev, ...(sortedNewRows as T[])]);
228
- }
229
-
230
- // Force re-render to update the total rows
231
- rerender();
232
- // oxlint-disable-next-line react-hooks/exhaustive-deps
233
- }, [data.length]);
234
-
235
105
  const getCellContent = useCallback(
236
106
  (cell: Item): GridCell => {
237
107
  const [col, row] = cell;
238
108
  const dataRow = data[row];
239
109
 
240
- const dataItem = dataRow[columns[col].title as keyof T];
110
+ const dataItem = dataRow[columns[col].title];
241
111
  const columnKind = columns[col].kind;
242
112
  const editable =
243
113
  editableColumns === "all" ||
@@ -289,15 +159,9 @@ export const GlideDataEditor = <T,>({
289
159
  newData = null;
290
160
  }
291
161
 
292
- setData((prev) => {
293
- const data = [...prev];
294
- data[row][key as keyof T] = newData as T[keyof T];
295
- return data;
296
- });
297
-
298
162
  onAddEdits([{ rowIdx: row, columnId: key, value: newData }]);
299
163
  },
300
- [columns, onAddEdits, setData],
164
+ [columns, onAddEdits],
301
165
  );
302
166
 
303
167
  const onColumnResize = useCallback((column: GridColumn, newSize: number) => {
@@ -314,22 +178,7 @@ export const GlideDataEditor = <T,>({
314
178
  const key = columns[col].title;
315
179
 
316
180
  const columnType = columnFields.get(key);
317
- // Verify the new value is of the correct type
318
- switch (columnType) {
319
- case "number":
320
- case "integer":
321
- if (Number.isNaN(Number(newValue.data))) {
322
- return false;
323
- }
324
- break;
325
- case "boolean":
326
- if (typeof newValue.data !== "boolean") {
327
- return false;
328
- }
329
- break;
330
- }
331
-
332
- return true;
181
+ return isValidCellValue(columnType, newValue.data);
333
182
  },
334
183
  [columnFields, columns],
335
184
  );
@@ -351,7 +200,6 @@ export const GlideDataEditor = <T,>({
351
200
  pasteCells({
352
201
  selection,
353
202
  data,
354
- setData,
355
203
  columns,
356
204
  editableColumns,
357
205
  onAddEdits,
@@ -371,11 +219,11 @@ export const GlideDataEditor = <T,>({
371
219
  return;
372
220
  }
373
221
  },
374
- [columns, data, editableColumns, onAddEdits, selection, setData],
222
+ [columns, data, editableColumns, onAddEdits, selection],
375
223
  );
376
224
 
377
225
  const onRowAppend = useCallback(() => {
378
- const newRow: Record<string, unknown> = Object.fromEntries(
226
+ const newRow: EditorRow = Object.fromEntries(
379
227
  columns.map((column) => {
380
228
  const dataType = column.dataType;
381
229
  switch (dataType) {
@@ -399,22 +247,23 @@ export const GlideDataEditor = <T,>({
399
247
  }
400
248
  }),
401
249
  );
402
- onAddRows([newRow]);
403
-
404
- // Update data
405
- setData((prev) => [...prev, newRow as T]);
406
- }, [columns, onAddRows, setData]);
250
+ onAddEdits(
251
+ Object.entries(newRow).map(([columnId, value]) => ({
252
+ rowIdx: data.length,
253
+ columnId,
254
+ value,
255
+ })),
256
+ );
257
+ }, [columns, data.length, onAddEdits]);
407
258
 
408
259
  const handleDeleteRows = () => {
409
260
  const rows = selection.rows.toArray();
410
- onDeleteRows(rows);
411
-
412
- let index = 0;
413
- for (const row of rows) {
414
- const adjustedRow = row - index; // Adjust for previously deleted rows
415
- setData((prev) => prev.filter((_, i) => i !== adjustedRow));
416
- index++;
417
- }
261
+ onAddEdits(
262
+ rows.map((rowIdx, index) => ({
263
+ rowIdx: rowIdx - index,
264
+ type: BulkEdit.Remove,
265
+ })),
266
+ );
418
267
 
419
268
  // Clear selection
420
269
  setSelection({
@@ -445,45 +294,20 @@ export const GlideDataEditor = <T,>({
445
294
 
446
295
  const handleRenameColumn = (newName: string) => {
447
296
  if (menu) {
448
- const oldColumnName = columns[menu.col].title;
449
-
450
297
  // Validate the new column name
451
298
  if (columnFields.has(newName)) {
452
299
  toastColumnExists(newName);
453
300
  return;
454
301
  }
455
302
 
456
- const dataType = columns[menu.col].dataType;
457
-
458
- onRenameColumn(menu.col, newName);
459
- setColumnFields((prev) =>
460
- modifyColumnFields({
461
- columnFields: prev,
462
- columnIdx: menu.col,
463
- type: "rename",
464
- dataType,
465
- newColumnName: newName,
466
- }),
467
- );
468
-
469
- // Update the data
470
- setData((prev) => renameColumn(prev, oldColumnName, newName));
303
+ onAddEdits([{ columnIdx: menu.col, newName, type: BulkEdit.Rename }]);
471
304
  setMenu(undefined);
472
305
  }
473
306
  };
474
307
 
475
308
  const handleDeleteColumn = () => {
476
309
  if (menu) {
477
- onDeleteColumn(menu.col);
478
- setColumnFields((prev) =>
479
- modifyColumnFields({
480
- columnFields: prev,
481
- columnIdx: menu.col,
482
- type: "remove",
483
- }),
484
- );
485
-
486
- setData((prev) => removeColumn(prev, menu.col));
310
+ onAddEdits([{ columnIdx: menu.col, type: BulkEdit.Remove }]);
487
311
  setMenu(undefined);
488
312
  }
489
313
  };
@@ -506,21 +330,14 @@ export const GlideDataEditor = <T,>({
506
330
  return;
507
331
  }
508
332
 
509
- onAddColumn(clampedColumnIdx, columnName);
510
-
511
- setColumnFields((prev) =>
512
- modifyColumnFields({
513
- columnFields: prev,
333
+ onAddEdits([
334
+ {
514
335
  columnIdx: clampedColumnIdx,
515
- type: "insert",
336
+ newName: columnName,
516
337
  dataType,
517
- newColumnName: columnName,
518
- }),
519
- );
520
-
521
- // Update the data - add the new column to all rows,
522
- // ordering does not matter as we call getCellContent based on columnTitle
523
- setData((prev) => insertColumn(prev, columnName));
338
+ type: BulkEdit.Insert,
339
+ },
340
+ ]);
524
341
  setMenu(undefined);
525
342
  }
526
343
  };
@@ -10,10 +10,11 @@ import { logNever } from "@/utils/assertNever";
10
10
  import { Logger } from "@/utils/Logger";
11
11
  import type {
12
12
  ColumnEdit,
13
+ EditorRow,
13
14
  Edits,
14
15
  ModifiedGridColumn,
15
16
  PositionalEdit,
16
- RowEdit,
17
+ RemoveRowEdit,
17
18
  } from "./types";
18
19
 
19
20
  export function getColumnKind(fieldType: DataType): GridCellKind {
@@ -24,7 +25,15 @@ export function getColumnKind(fieldType: DataType): GridCellKind {
24
25
  return GridCellKind.Number;
25
26
  case "boolean":
26
27
  return GridCellKind.Boolean;
28
+ case "integer":
29
+ case "date":
30
+ case "datetime":
31
+ case "time":
32
+ case "geometry":
33
+ case "unknown":
34
+ return GridCellKind.Text;
27
35
  default:
36
+ logNever(fieldType);
28
37
  return GridCellKind.Text;
29
38
  }
30
39
  }
@@ -52,13 +61,48 @@ export function getColumnHeaderIcon(fieldType: DataType): GridColumnIcon {
52
61
  }
53
62
  }
54
63
 
64
+ export function isValidCellValue(
65
+ dataType: DataType | undefined,
66
+ value: unknown,
67
+ ): boolean {
68
+ switch (dataType) {
69
+ case "number":
70
+ return Number.isFinite(Number(value));
71
+ case "integer":
72
+ if (typeof value === "bigint") {
73
+ return true;
74
+ }
75
+ if (typeof value === "number") {
76
+ return Number.isFinite(value) && Number.isInteger(value);
77
+ }
78
+ if (typeof value === "string") {
79
+ const normalized = value.trim();
80
+ return /^[+-]?[0-9]+(?:\.0+)?$/u.test(normalized);
81
+ }
82
+ return false;
83
+ case "boolean":
84
+ return typeof value === "boolean";
85
+ case undefined:
86
+ case "string":
87
+ case "date":
88
+ case "datetime":
89
+ case "time":
90
+ case "geometry":
91
+ case "unknown":
92
+ return true;
93
+ default:
94
+ logNever(dataType);
95
+ return false;
96
+ }
97
+ }
98
+
55
99
  export function isPositionalEdit(
56
100
  edit: Edits["edits"][number],
57
101
  ): edit is PositionalEdit {
58
102
  return "rowIdx" in edit && "columnId" in edit && "value" in edit;
59
103
  }
60
104
 
61
- export function isRowEdit(edit: Edits["edits"][number]): edit is RowEdit {
105
+ export function isRowEdit(edit: Edits["edits"][number]): edit is RemoveRowEdit {
62
106
  return "rowIdx" in edit && "type" in edit;
63
107
  }
64
108
 
@@ -66,16 +110,14 @@ export function isColumnEdit(edit: Edits["edits"][number]): edit is ColumnEdit {
66
110
  return "columnIdx" in edit && "type" in edit;
67
111
  }
68
112
 
69
- export function pasteCells<T>(options: {
113
+ export function pasteCells(options: {
70
114
  selection: GridSelection;
71
- data: T[];
72
- setData: (updater: (prev: T[]) => T[]) => void;
115
+ data: EditorRow[];
73
116
  columns: ModifiedGridColumn[];
74
117
  editableColumns: string[] | "all";
75
118
  onAddEdits: (edits: Edits["edits"]) => void;
76
119
  }) {
77
- const { selection, data, setData, onAddEdits, columns, editableColumns } =
78
- options;
120
+ const { selection, data, onAddEdits, columns, editableColumns } = options;
79
121
  if (!selection.current) {
80
122
  return;
81
123
  }
@@ -126,7 +168,7 @@ export function pasteCells<T>(options: {
126
168
  const targetColIdx = startCol + colIndex;
127
169
 
128
170
  // Check if we've exceeded the column bounds
129
- if (!columns || targetColIdx >= columns.length) {
171
+ if (targetColIdx >= columns.length) {
130
172
  break;
131
173
  }
132
174
 
@@ -143,10 +185,19 @@ export function pasteCells<T>(options: {
143
185
  let convertedValue: unknown = cellValue;
144
186
 
145
187
  switch (columnType) {
146
- case "integer":
188
+ case "integer": {
189
+ const numValue = Number(cellValue);
190
+ if (!isValidCellValue(columnType, cellValue)) {
191
+ continue;
192
+ }
193
+ convertedValue = Number.isSafeInteger(numValue)
194
+ ? numValue
195
+ : cellValue.trim();
196
+ break;
197
+ }
147
198
  case "number": {
148
199
  const numValue = Number(cellValue);
149
- if (Number.isNaN(numValue)) {
200
+ if (!isValidCellValue(columnType, numValue)) {
150
201
  continue;
151
202
  }
152
203
  convertedValue = numValue;
@@ -157,6 +208,16 @@ export function pasteCells<T>(options: {
157
208
  convertedValue = boolValue === "true" || boolValue === "1";
158
209
  break;
159
210
  }
211
+ case "string":
212
+ case "date":
213
+ case "datetime":
214
+ case "time":
215
+ case "geometry":
216
+ case "unknown":
217
+ break;
218
+ default:
219
+ logNever(columnType);
220
+ continue;
160
221
  }
161
222
 
162
223
  // Get the column ID from the columns array using the title
@@ -172,27 +233,6 @@ export function pasteCells<T>(options: {
172
233
 
173
234
  if (edits.length > 0) {
174
235
  onAddEdits(edits);
175
-
176
- setData((prev: T[]) => {
177
- const newData = [...prev];
178
-
179
- // Apply all edits to the data
180
- for (const edit of edits) {
181
- if (isPositionalEdit(edit)) {
182
- const rowIdx = edit.rowIdx;
183
- const columnId = edit.columnId;
184
-
185
- if (rowIdx < newData.length) {
186
- const row = newData[rowIdx] as Record<string, unknown>;
187
- if (columnId in row) {
188
- row[columnId] = edit.value;
189
- }
190
- }
191
- }
192
- }
193
-
194
- return newData;
195
- });
196
236
  }
197
237
  })
198
238
  .catch((error) => {
@@ -1,9 +1,16 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import type { GridCellKind, GridColumn } from "@glideapps/glide-data-grid";
4
- import type { FieldTypesWithExternalType } from "@/components/data-table/types";
4
+ import type { FieldTypes } from "@/components/data-table/types";
5
5
  import type { DataType } from "@/core/kernel/messages";
6
6
 
7
+ export type EditorRow = Record<string, unknown>;
8
+
9
+ export interface EditorState {
10
+ data: EditorRow[];
11
+ columnFields: FieldTypes;
12
+ }
13
+
7
14
  export interface PositionalEdit {
8
15
  rowIdx: number;
9
16
  columnId: string;
@@ -16,31 +23,38 @@ export const BulkEdit = {
16
23
  Rename: "rename",
17
24
  } as const;
18
25
 
19
- type BulkEdit = (typeof BulkEdit)[keyof typeof BulkEdit];
20
-
21
- export interface RowEdit {
26
+ export interface RemoveRowEdit {
22
27
  rowIdx: number;
23
- type: BulkEdit;
28
+ type: typeof BulkEdit.Remove;
29
+ }
30
+
31
+ export interface RemoveColumnEdit {
32
+ columnIdx: number;
33
+ type: typeof BulkEdit.Remove;
24
34
  }
25
35
 
26
- export interface ColumnEdit {
36
+ export interface RenameColumnEdit {
27
37
  columnIdx: number;
28
- newName?: string;
29
- type: BulkEdit;
38
+ newName: string;
39
+ type: typeof BulkEdit.Rename;
30
40
  }
31
41
 
42
+ export interface InsertColumnEdit {
43
+ columnIdx: number;
44
+ newName: string;
45
+ type: typeof BulkEdit.Insert;
46
+ dataType?: DataType;
47
+ }
48
+
49
+ export type ColumnEdit = RemoveColumnEdit | RenameColumnEdit | InsertColumnEdit;
50
+
51
+ export type Edit = PositionalEdit | RemoveRowEdit | ColumnEdit;
52
+
32
53
  export interface Edits {
33
- edits: (PositionalEdit | RowEdit | ColumnEdit)[];
54
+ edits: Edit[];
34
55
  }
35
56
 
36
57
  export type ModifiedGridColumn = GridColumn & {
37
58
  kind: GridCellKind;
38
59
  dataType: DataType;
39
60
  };
40
-
41
- export interface DataEditorProps<T> {
42
- data: T[];
43
- fieldTypes: FieldTypesWithExternalType | null | undefined;
44
- onAddEdits: (edits: Edits["edits"]) => void;
45
- onAddRows: (newRows: object[]) => void;
46
- }
@@ -1 +0,0 @@
1
- import{a as e,t}from"./rolldown-runtime-B0Z9INg1.js";import{t as n}from"./react-CBDbhulC.js";var r=t(((e,t)=>{var n=Object.prototype.hasOwnProperty;function r(e,t){return e!=null&&n.call(e,t)}t.exports=r})),i=t(((e,t)=>{t.exports=Array.isArray})),a=t(((e,t)=>{t.exports=typeof global==`object`&&global&&global.Object===Object&&global})),o=t(((e,t)=>{var n=a(),r=typeof self==`object`&&self&&self.Object===Object&&self;t.exports=n||r||Function(`return this`)()})),s=t(((e,t)=>{t.exports=o().Symbol})),c=t(((e,t)=>{var n=s(),r=Object.prototype,i=r.hasOwnProperty,a=r.toString,o=n?n.toStringTag:void 0;function c(e){var t=i.call(e,o),n=e[o];try{e[o]=void 0;var r=!0}catch{}var s=a.call(e);return r&&(t?e[o]=n:delete e[o]),s}t.exports=c})),l=t(((e,t)=>{var n=Object.prototype.toString;function r(e){return n.call(e)}t.exports=r})),u=t(((e,t)=>{var n=s(),r=c(),i=l(),a=`[object Null]`,o=`[object Undefined]`,u=n?n.toStringTag:void 0;function d(e){return e==null?e===void 0?o:a:u&&u in Object(e)?r(e):i(e)}t.exports=d})),d=t(((e,t)=>{function n(e){return typeof e==`object`&&!!e}t.exports=n})),f=t(((e,t)=>{var n=u(),r=d(),i=`[object Symbol]`;function a(e){return typeof e==`symbol`||r(e)&&n(e)==i}t.exports=a})),p=t(((e,t)=>{var n=i(),r=f(),a=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,o=/^\w*$/;function s(e,t){if(n(e))return!1;var i=typeof e;return i==`number`||i==`symbol`||i==`boolean`||e==null||r(e)?!0:o.test(e)||!a.test(e)||t!=null&&e in Object(t)}t.exports=s})),m=t(((e,t)=>{function n(e){var t=typeof e;return e!=null&&(t==`object`||t==`function`)}t.exports=n})),h=t(((e,t)=>{var n=u(),r=m(),i=`[object AsyncFunction]`,a=`[object Function]`,o=`[object GeneratorFunction]`,s=`[object Proxy]`;function c(e){if(!r(e))return!1;var t=n(e);return t==a||t==o||t==i||t==s}t.exports=c})),ee=t(((e,t)=>{t.exports=o()[`__core-js_shared__`]})),te=t(((e,t)=>{var n=ee(),r=function(){var e=/[^.]+$/.exec(n&&n.keys&&n.keys.IE_PROTO||``);return e?`Symbol(src)_1.`+e:``}();function i(e){return!!r&&r in e}t.exports=i})),g=t(((e,t)=>{var n=Function.prototype.toString;function r(e){if(e!=null){try{return n.call(e)}catch{}try{return e+``}catch{}}return``}t.exports=r})),_=t(((e,t)=>{var n=h(),r=te(),i=m(),a=g(),o=/[\\^$.*+?()[\]{}|]/g,s=/^\[object .+?Constructor\]$/,c=Function.prototype,l=Object.prototype,u=c.toString,d=l.hasOwnProperty,f=RegExp(`^`+u.call(d).replace(o,`\\$&`).replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,`$1.*?`)+`$`);function p(e){return!i(e)||r(e)?!1:(n(e)?f:s).test(a(e))}t.exports=p})),v=t(((e,t)=>{function n(e,t){return e?.[t]}t.exports=n})),y=t(((e,t)=>{var n=_(),r=v();function i(e,t){var i=r(e,t);return n(i)?i:void 0}t.exports=i})),b=t(((e,t)=>{t.exports=y()(Object,`create`)})),ne=t(((e,t)=>{var n=b();function r(){this.__data__=n?n(null):{},this.size=0}t.exports=r})),re=t(((e,t)=>{function n(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=+!!t,t}t.exports=n})),ie=t(((e,t)=>{var n=b(),r=`__lodash_hash_undefined__`,i=Object.prototype.hasOwnProperty;function a(e){var t=this.__data__;if(n){var a=t[e];return a===r?void 0:a}return i.call(t,e)?t[e]:void 0}t.exports=a})),ae=t(((e,t)=>{var n=b(),r=Object.prototype.hasOwnProperty;function i(e){var t=this.__data__;return n?t[e]!==void 0:r.call(t,e)}t.exports=i})),oe=t(((e,t)=>{var n=b(),r=`__lodash_hash_undefined__`;function i(e,t){var i=this.__data__;return this.size+=+!this.has(e),i[e]=n&&t===void 0?r:t,this}t.exports=i})),se=t(((e,t)=>{var n=ne(),r=re(),i=ie(),a=ae(),o=oe();function s(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}s.prototype.clear=n,s.prototype.delete=r,s.prototype.get=i,s.prototype.has=a,s.prototype.set=o,t.exports=s})),ce=t(((e,t)=>{function n(){this.__data__=[],this.size=0}t.exports=n})),x=t(((e,t)=>{function n(e,t){return e===t||e!==e&&t!==t}t.exports=n})),S=t(((e,t)=>{var n=x();function r(e,t){for(var r=e.length;r--;)if(n(e[r][0],t))return r;return-1}t.exports=r})),le=t(((e,t)=>{var n=S(),r=Array.prototype.splice;function i(e){var t=this.__data__,i=n(t,e);return i<0?!1:(i==t.length-1?t.pop():r.call(t,i,1),--this.size,!0)}t.exports=i})),ue=t(((e,t)=>{var n=S();function r(e){var t=this.__data__,r=n(t,e);return r<0?void 0:t[r][1]}t.exports=r})),de=t(((e,t)=>{var n=S();function r(e){return n(this.__data__,e)>-1}t.exports=r})),C=t(((e,t)=>{var n=S();function r(e,t){var r=this.__data__,i=n(r,e);return i<0?(++this.size,r.push([e,t])):r[i][1]=t,this}t.exports=r})),w=t(((e,t)=>{var n=ce(),r=le(),i=ue(),a=de(),o=C();function s(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}s.prototype.clear=n,s.prototype.delete=r,s.prototype.get=i,s.prototype.has=a,s.prototype.set=o,t.exports=s})),T=t(((e,t)=>{t.exports=y()(o(),`Map`)})),fe=t(((e,t)=>{var n=se(),r=w(),i=T();function a(){this.size=0,this.__data__={hash:new n,map:new(i||r),string:new n}}t.exports=a})),pe=t(((e,t)=>{function n(e){var t=typeof e;return t==`string`||t==`number`||t==`symbol`||t==`boolean`?e!==`__proto__`:e===null}t.exports=n})),E=t(((e,t)=>{var n=pe();function r(e,t){var r=e.__data__;return n(t)?r[typeof t==`string`?`string`:`hash`]:r.map}t.exports=r})),me=t(((e,t)=>{var n=E();function r(e){var t=n(this,e).delete(e);return this.size-=+!!t,t}t.exports=r})),he=t(((e,t)=>{var n=E();function r(e){return n(this,e).get(e)}t.exports=r})),ge=t(((e,t)=>{var n=E();function r(e){return n(this,e).has(e)}t.exports=r})),_e=t(((e,t)=>{var n=E();function r(e,t){var r=n(this,e),i=r.size;return r.set(e,t),this.size+=r.size==i?0:1,this}t.exports=r})),D=t(((e,t)=>{var n=fe(),r=me(),i=he(),a=ge(),o=_e();function s(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}s.prototype.clear=n,s.prototype.delete=r,s.prototype.get=i,s.prototype.has=a,s.prototype.set=o,t.exports=s})),ve=t(((e,t)=>{var n=D(),r=`Expected a function`;function i(e,t){if(typeof e!=`function`||t!=null&&typeof t!=`function`)throw TypeError(r);var a=function(){var n=arguments,r=t?t.apply(this,n):n[0],i=a.cache;if(i.has(r))return i.get(r);var o=e.apply(this,n);return a.cache=i.set(r,o)||i,o};return a.cache=new(i.Cache||n),a}i.Cache=n,t.exports=i})),ye=t(((e,t)=>{var n=ve(),r=500;function i(e){var t=n(e,function(e){return i.size===r&&i.clear(),e}),i=t.cache;return t}t.exports=i})),be=t(((e,t)=>{var n=ye(),r=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,i=/\\(\\)?/g;t.exports=n(function(e){var t=[];return e.charCodeAt(0)===46&&t.push(``),e.replace(r,function(e,n,r,a){t.push(r?a.replace(i,`$1`):n||e)}),t})})),xe=t(((e,t)=>{function n(e,t){for(var n=-1,r=e==null?0:e.length,i=Array(r);++n<r;)i[n]=t(e[n],n,e);return i}t.exports=n})),O=t(((e,t)=>{var n=s(),r=xe(),a=i(),o=f(),c=1/0,l=n?n.prototype:void 0,u=l?l.toString:void 0;function d(e){if(typeof e==`string`)return e;if(a(e))return r(e,d)+``;if(o(e))return u?u.call(e):``;var t=e+``;return t==`0`&&1/e==-c?`-0`:t}t.exports=d})),k=t(((e,t)=>{var n=O();function r(e){return e==null?``:n(e)}t.exports=r})),A=t(((e,t)=>{var n=i(),r=p(),a=be(),o=k();function s(e,t){return n(e)?e:r(e,t)?[e]:a(o(e))}t.exports=s})),j=t(((e,t)=>{var n=u(),r=d(),i=`[object Arguments]`;function a(e){return r(e)&&n(e)==i}t.exports=a})),M=t(((e,t)=>{var n=j(),r=d(),i=Object.prototype,a=i.hasOwnProperty,o=i.propertyIsEnumerable;t.exports=n(function(){return arguments}())?n:function(e){return r(e)&&a.call(e,`callee`)&&!o.call(e,`callee`)}})),N=t(((e,t)=>{var n=/^(?:0|[1-9]\d*)$/;function r(e,t){var r=typeof e;return t??=9007199254740991,!!t&&(r==`number`||r!=`symbol`&&n.test(e))&&e>-1&&e%1==0&&e<t}t.exports=r})),P=t(((e,t)=>{function n(e){return typeof e==`number`&&e>-1&&e%1==0&&e<=9007199254740991}t.exports=n})),F=t(((e,t)=>{var n=f(),r=1/0;function i(e){if(typeof e==`string`||n(e))return e;var t=e+``;return t==`0`&&1/e==-r?`-0`:t}t.exports=i})),I=t(((e,t)=>{var n=A(),r=M(),a=i(),o=N(),s=P(),c=F();function l(e,t,i){t=n(t,e);for(var l=-1,u=t.length,d=!1;++l<u;){var f=c(t[l]);if(!(d=e!=null&&i(e,f)))break;e=e[f]}return d||++l!=u?d:(u=e==null?0:e.length,!!u&&s(u)&&o(f,u)&&(a(e)||r(e)))}t.exports=l})),Se=e(t(((e,t)=>{var n=r(),i=I();function a(e,t){return e!=null&&i(e,t,n)}t.exports=a}))(),1);function L(e=`This should not happen`){throw Error(e)}function Ce(e,t=`Assertion failed`){if(!e)return L(t)}function R(e,t){return L(t??`Hell froze over`)}function we(e,t){try{return e()}catch{return t}}var z=Object.prototype.hasOwnProperty;function B(e,t){let n,r;if(e===t)return!0;if(e&&t&&(n=e.constructor)===t.constructor){if(n===Date)return e.getTime()===t.getTime();if(n===RegExp)return e.toString()===t.toString();if(n===Array){if((r=e.length)===t.length)for(;r--&&B(e[r],t[r]););return r===-1}if(!n||typeof e==`object`){for(n in r=0,e)if(z.call(e,n)&&++r&&!z.call(t,n)||!(n in t)||!B(e[n],t[n]))return!1;return Object.keys(t).length===r}}return e!==e&&t!==t}var V;(function(e){e.Uri=`uri`,e.Text=`text`,e.Image=`image`,e.RowID=`row-id`,e.Number=`number`,e.Bubble=`bubble`,e.Boolean=`boolean`,e.Loading=`loading`,e.Markdown=`markdown`,e.Drilldown=`drilldown`,e.Protected=`protected`,e.Custom=`custom`})(V||={});var H;(function(e){e.HeaderRowID=`headerRowID`,e.HeaderCode=`headerCode`,e.HeaderNumber=`headerNumber`,e.HeaderString=`headerString`,e.HeaderBoolean=`headerBoolean`,e.HeaderAudioUri=`headerAudioUri`,e.HeaderVideoUri=`headerVideoUri`,e.HeaderEmoji=`headerEmoji`,e.HeaderImage=`headerImage`,e.HeaderUri=`headerUri`,e.HeaderPhone=`headerPhone`,e.HeaderMarkdown=`headerMarkdown`,e.HeaderDate=`headerDate`,e.HeaderTime=`headerTime`,e.HeaderEmail=`headerEmail`,e.HeaderReference=`headerReference`,e.HeaderIfThenElse=`headerIfThenElse`,e.HeaderSingleValue=`headerSingleValue`,e.HeaderLookup=`headerLookup`,e.HeaderTextTemplate=`headerTextTemplate`,e.HeaderMath=`headerMath`,e.HeaderRollup=`headerRollup`,e.HeaderJoinStrings=`headerJoinStrings`,e.HeaderSplitString=`headerSplitString`,e.HeaderGeoDistance=`headerGeoDistance`,e.HeaderArray=`headerArray`,e.RowOwnerOverlay=`rowOwnerOverlay`,e.ProtectedColumnOverlay=`protectedColumnOverlay`})(H||={});var U;(function(e){e.Triangle=`triangle`,e.Dots=`dots`})(U||={});function Te(e){return`width`in e&&typeof e.width==`number`}async function Ee(e){return typeof e==`object`?e:await e()}function W(e){return e.kind!==V.Loading&&e.kind!==V.Bubble&&e.kind!==V.RowID&&e.kind!==V.Protected&&e.kind!==V.Drilldown}function De(e){return e.kind===G.Marker||e.kind===G.NewRow}function Oe(e){if(!W(e)||e.kind===V.Image)return!1;switch(e.kind){case V.Text:case V.Number:case V.Markdown:case V.Uri:case V.Custom:case V.Boolean:return e.readonly!==!0;default:R(e,`A cell was passed with an invalid kind`)}}function ke(e){return(0,Se.default)(e,`editor`)}function Ae(e){return!(e.readonly??!1)}var G;(function(e){e.NewRow=`new-row`,e.Marker=`marker`})(G||={});var je={shape:`square`,size:4,offsetX:-2,offsetY:-2,outline:0};function K(e){if(e.length===0)return[];let t=[...e],n=[];t.sort(function(e,t){return e[0]-t[0]}),n.push([...t[0]]);for(let e of t.slice(1)){let t=n[n.length-1];t[1]<e[0]?n.push([...e]):t[1]<e[1]&&(t[1]=e[1])}return n}var Me,Ne=class e{items;constructor(e){this.items=e}static create=t=>new e(K(t));static empty=()=>Me??=new e([]);static fromSingleSelection=t=>e.empty().add(t);static fromArray=t=>{if(t.length===0)return e.empty();let n=K(t.map(e=>[e,e+1]));return new e(n)};offset(t){if(t===0)return this;let n=this.items.map(e=>[e[0]+t,e[1]+t]);return new e(n)}add(t){let n=typeof t==`number`?[t,t+1]:t,r=K([...this.items,n]);return new e(r)}remove(t){let n=[...this.items],r=typeof t==`number`?t:t[0],i=typeof t==`number`?t+1:t[1];for(let[e,t]of n.entries()){let[a,o]=t;if(a<=i&&r<=o){let t=[];a<r&&t.push([a,r]),i<o&&t.push([i,o]),n.splice(e,1,...t)}}return new e(n)}first(){if(this.items.length!==0)return this.items[0][0]}last(){if(this.items.length!==0)return this.items.slice(-1)[0][1]-1}hasIndex(e){for(let t=0;t<this.items.length;t++){let[n,r]=this.items[t];if(e>=n&&e<r)return!0}return!1}hasAll(e){for(let t=e[0];t<e[1];t++)if(!this.hasIndex(t))return!1;return!0}some(e){for(let t of this)if(e(t))return!0;return!1}equals(e){if(e===this)return!0;if(e.items.length!==this.items.length)return!1;for(let t=0;t<this.items.length;t++){let n=e.items[t],r=this.items[t];if(n[0]!==r[0]||n[1]!==r[1])return!1}return!0}toArray(){let e=[];for(let[t,n]of this.items)for(let r=t;r<n;r++)e.push(r);return e}get length(){let e=0;for(let[t,n]of this.items)e+=n-t;return e}*[Symbol.iterator](){for(let[e,t]of this.items)for(let n=e;n<t;n++)yield n}},q=e(n(),1),J={},Y=null;function Pe(){let e=document.createElement(`div`);return e.style.opacity=`0`,e.style.pointerEvents=`none`,e.style.position=`fixed`,document.body.append(e),e}function X(e){let t=e.toLowerCase().trim();if(J[t]!==void 0)return J[t];Y||=Pe(),Y.style.color=`#000`,Y.style.color=t;let n=getComputedStyle(Y).color;Y.style.color=`#fff`,Y.style.color=t;let r=getComputedStyle(Y).color;if(r!==n)return[0,0,0,1];let i=r.replace(/[^\d.,]/g,``).split(`,`).map(Number.parseFloat);return i.length<4&&i.push(1),i=i.map(e=>Number.isNaN(e)?0:e),J[t]=i,i}function Fe(e,t){let[n,r,i]=X(e);return`rgba(${n}, ${r}, ${i}, ${t})`}var Z=new Map;function Ie(e,t){let n=`${e}-${t}`,r=Z.get(n);if(r!==void 0)return r;let i=Q(e,t);return Z.set(n,i),i}function Q(e,t){if(t===void 0)return e;let[n,r,i,a]=X(e);if(a===1)return e;let[o,s,c,l]=X(t),u=a+l*(1-a);return`rgba(${(a*n+l*o*(1-a))/u}, ${(a*r+l*s*(1-a))/u}, ${(a*i+l*c*(1-a))/u}, ${u})`}function Le(e){return{"--gdg-accent-color":e.accentColor,"--gdg-accent-fg":e.accentFg,"--gdg-accent-light":e.accentLight,"--gdg-text-dark":e.textDark,"--gdg-text-medium":e.textMedium,"--gdg-text-light":e.textLight,"--gdg-text-bubble":e.textBubble,"--gdg-bg-icon-header":e.bgIconHeader,"--gdg-fg-icon-header":e.fgIconHeader,"--gdg-text-header":e.textHeader,"--gdg-text-group-header":e.textGroupHeader??e.textHeader,"--gdg-bg-group-header":e.bgGroupHeader??e.bgHeader,"--gdg-bg-group-header-hovered":e.bgGroupHeaderHovered??e.bgHeaderHovered,"--gdg-text-header-selected":e.textHeaderSelected,"--gdg-bg-cell":e.bgCell,"--gdg-bg-cell-medium":e.bgCellMedium,"--gdg-bg-header":e.bgHeader,"--gdg-bg-header-has-focus":e.bgHeaderHasFocus,"--gdg-bg-header-hovered":e.bgHeaderHovered,"--gdg-bg-bubble":e.bgBubble,"--gdg-bg-bubble-selected":e.bgBubbleSelected,"--gdg-bubble-height":`${e.bubbleHeight}px`,"--gdg-bubble-padding":`${e.bubblePadding}px`,"--gdg-bubble-margin":`${e.bubbleMargin}px`,"--gdg-bg-search-result":e.bgSearchResult,"--gdg-border-color":e.borderColor,"--gdg-horizontal-border-color":e.horizontalBorderColor??e.borderColor,"--gdg-drilldown-border":e.drilldownBorder,"--gdg-link-color":e.linkColor,"--gdg-cell-horizontal-padding":`${e.cellHorizontalPadding}px`,"--gdg-cell-vertical-padding":`${e.cellVerticalPadding}px`,"--gdg-header-font-style":e.headerFontStyle,"--gdg-base-font-style":e.baseFontStyle,"--gdg-marker-font-style":e.markerFontStyle,"--gdg-font-family":e.fontFamily,"--gdg-editor-font-size":e.editorFontSize,"--gdg-checkbox-max-size":`${e.checkboxMaxSize}px`,...e.resizeIndicatorColor===void 0?{}:{"--gdg-resize-indicator-color":e.resizeIndicatorColor},...e.headerBottomBorderColor===void 0?{}:{"--gdg-header-bottom-border-color":e.headerBottomBorderColor},...e.roundingRadius===void 0?{}:{"--gdg-rounding-radius":`${e.roundingRadius}px`}}}var $={accentColor:`#4F5DFF`,accentFg:`#FFFFFF`,accentLight:`rgba(62, 116, 253, 0.1)`,textDark:`#313139`,textMedium:`#737383`,textLight:`#B2B2C0`,textBubble:`#313139`,bgIconHeader:`#737383`,fgIconHeader:`#FFFFFF`,textHeader:`#313139`,textGroupHeader:`#313139BB`,textHeaderSelected:`#FFFFFF`,bgCell:`#FFFFFF`,bgCellMedium:`#FAFAFB`,bgHeader:`#F7F7F8`,bgHeaderHasFocus:`#E9E9EB`,bgHeaderHovered:`#EFEFF1`,bgBubble:`#EDEDF3`,bgBubbleSelected:`#FFFFFF`,bubbleHeight:20,bubblePadding:6,bubbleMargin:4,bgSearchResult:`#fff9e3`,borderColor:`rgba(115, 116, 131, 0.16)`,drilldownBorder:`rgba(0, 0, 0, 0)`,linkColor:`#353fb5`,cellHorizontalPadding:8,cellVerticalPadding:3,headerIconSize:18,headerFontStyle:`600 13px`,baseFontStyle:`13px`,markerFontStyle:`9px`,fontFamily:`Inter, Roboto, -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Ubuntu, noto, arial, sans-serif`,editorFontSize:`13px`,lineHeight:1.4,checkboxMaxSize:18};function Re(){return $}var ze=q.createContext($);function Be(e,...t){let n={...e};for(let e of t)if(e!==void 0)for(let t in e)e.hasOwnProperty(t)&&(n[t]=t===`bgCell`?Q(e[t],n[t]):e[t]);return(n.headerFontFull===void 0||e.fontFamily!==n.fontFamily||e.headerFontStyle!==n.headerFontStyle)&&(n.headerFontFull=`${n.headerFontStyle} ${n.fontFamily}`),(n.baseFontFull===void 0||e.fontFamily!==n.fontFamily||e.baseFontStyle!==n.baseFontStyle)&&(n.baseFontFull=`${n.baseFontStyle} ${n.fontFamily}`),(n.markerFontFull===void 0||e.fontFamily!==n.fontFamily||e.markerFontStyle!==n.markerFontStyle)&&(n.markerFontFull=`${n.markerFontStyle} ${n.fontFamily}`),n}var Ve=class extends q.PureComponent{wrapperRef=q.createRef();componentDidMount(){let e=this.props.customEventTarget??document;e.addEventListener(`pointerdown`,this.clickOutside,!0),e.addEventListener(`contextmenu`,this.clickOutside,!0)}componentWillUnmount(){let e=this.props.customEventTarget??document;e.removeEventListener(`pointerdown`,this.clickOutside,!0),e.removeEventListener(`contextmenu`,this.clickOutside,!0)}clickOutside=e=>{if(!(this.props.isOutsideClick&&!this.props.isOutsideClick(e))&&this.wrapperRef.current!==null&&!this.wrapperRef.current.contains(e.target)){let t=e.target;for(;t!==null;){if(t.classList.contains(`click-outside-ignore`))return;t=t.parentElement}this.props.onClickOutside()}};render(){let{onClickOutside:e,isOutsideClick:t,customEventTarget:n,...r}=this.props;return q.createElement(`div`,{...r,ref:this.wrapperRef},this.props.children)}};export{M as A,p as B,R as C,F as D,I as E,x as F,o as G,d as H,y as I,a as K,g as L,D as M,T as N,P as O,w as P,h as R,Ce as S,we as T,u as U,f as V,s as W,De as _,Be as a,Te as b,Fe as c,V as d,H as f,W as g,Ae as h,Le as i,A as j,N as k,Ne as l,G as m,ze as n,Q as o,U as p,i as q,Re as r,Ie as s,Ve as t,je as u,ke as v,B as w,Ee as x,Oe as y,m as z};
@@ -1 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-B0Z9INg1.js";import{t}from"./react-CBDbhulC.js";import{t as n}from"./react-dom-BQrReHnR.js";import{_ as r,g as i,i as a,n as ee,t as o,v as s}from"./click-outside-container-n76g8dsY.js";import{t as c}from"./dist-DQS4kic4.js";var l=e(t(),1),u=e(n(),1),te=c(`div`)({name:`DataGridOverlayEditorStyle`,class:`gdg-d19meir1`,propsAsIs:!1,vars:{"d19meir1-0":[e=>e.targetY,`px`],"d19meir1-1":[e=>e.targetX,`px`],"d19meir1-2":[e=>e.targetWidth,`px`],"d19meir1-3":[e=>e.targetHeight,`px`],"d19meir1-4":[e=>e.targetY+10,`px`],"d19meir1-5":[e=>Math.max(0,(e.targetHeight-28)/2),`px`]}});function d(){let[e,t]=l.useState();return[e??void 0,t]}function f(){let[e,t]=d(),[n,r]=l.useState(0),[i,a]=l.useState(!0);return l.useLayoutEffect(()=>{if(e===void 0||!(`IntersectionObserver`in window))return;let t=new IntersectionObserver(e=>{e.length!==0&&a(e[0].isIntersecting)},{threshold:1});return t.observe(e),()=>t.disconnect()},[e]),l.useEffect(()=>{if(i||e===void 0)return;let t,n=()=>{let{right:i}=e.getBoundingClientRect();r(e=>Math.min(e+window.innerWidth-i-10,0)),t=requestAnimationFrame(n)};return t=requestAnimationFrame(n),()=>{t!==void 0&&cancelAnimationFrame(t)}},[e,i]),{ref:t,style:l.useMemo(()=>({transform:`translateX(${n}px)`}),[n])}}var p=e=>{let{target:t,content:n,onFinishEditing:c,forceEditMode:d,initialValue:p,imageEditorOverride:m,markdownDivCreateNode:h,highlight:g,className:_,theme:v,id:y,cell:b,bloom:x,portalElementRef:S,validateCell:C,getCellRenderer:w,provideEditor:T,isOutsideClick:E,customEventTarget:D,activation:O}=e,[k,A]=l.useState(d?n:void 0),j=l.useRef(k??n);j.current=k??n;let[M,N]=l.useState(()=>C===void 0||!(i(n)&&C?.(b,n,j.current)===!1)),P=l.useCallback((e,t)=>{c(M?e:void 0,t)},[M,c]),F=l.useCallback(e=>{if(C!==void 0&&e!==void 0&&i(e)){let t=C(b,e,j.current);t===!1?N(!1):(typeof t==`object`&&(e=t),N(!0))}A(e)},[b,C]),I=l.useRef(!1),L=l.useRef(void 0),R=l.useCallback(()=>{P(k,[0,0]),I.current=!0},[k,P]),z=l.useCallback((e,t)=>{P(e,t??L.current??[0,0]),I.current=!0},[P]),B=l.useCallback(async e=>{let t=!1;e.key===`Escape`?(e.stopPropagation(),e.preventDefault(),L.current=[0,0]):e.key===`Enter`&&!e.shiftKey?(e.stopPropagation(),e.preventDefault(),L.current=[0,1],t=!0):e.key===`Tab`&&(e.stopPropagation(),e.preventDefault(),L.current=[e.shiftKey?-1:1,0],t=!0),window.setTimeout(()=>{!I.current&&L.current!==void 0&&(P(t?k:void 0,L.current),I.current=!0)},0)},[P,k]),V=k??n,[H,U]=l.useMemo(()=>{if(r(n))return[];let e={...n,location:b,activation:O},t=T?.(e);return t===void 0?[w(n)?.provideEditor?.(e),!1]:[t,!1]},[b,n,w,T,O]),{ref:W,style:G}=f(),K=!0,q,J=!0,Y;if(H!==void 0){K=H.disablePadding!==!0,J=H.disableStyling!==!0;let e=s(H);e&&(Y=H.styleOverride);let n=e?H.editor:H;q=l.createElement(n,{portalElementRef:S,isHighlighted:g,activation:O,onChange:F,value:V,initialValue:p,onFinishedEditing:z,validatedSelection:i(V)?V.selectionRange:void 0,forceEditMode:d,target:t,imageEditorOverride:m,markdownDivCreateNode:h,isValid:M,theme:v})}Y={...Y,...G};let X=S?.current??document.getElementById(`portal`);if(X===null)return console.error('Cannot open Data Grid overlay editor, because portal not found. Please, either provide a portalElementRef or add `<div id="portal" />` as the last child of your `<body>`.'),null;let Z=J?`gdg-style`:`gdg-unstyle`;M||(Z+=` gdg-invalid`),K&&(Z+=` gdg-pad`);let Q=x?.[0]??1,$=x?.[1]??1;return(0,u.createPortal)(l.createElement(ee.Provider,{value:v},l.createElement(o,{style:a(v),className:_,onClickOutside:R,isOutsideClick:E,customEventTarget:D},l.createElement(te,{ref:W,id:y,className:Z,style:Y,as:U===!0?`label`:void 0,targetX:t.x-Q,targetY:t.y-$,targetWidth:t.width+Q*2,targetHeight:t.height+$*2},l.createElement(`div`,{className:`gdg-clip-region`,onKeyDown:B},q)))),X)};export{p as default};