@dxos/react-ui-grid 0.6.14-main.7bd9c89 → 0.6.14-main.8b352a0
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/lib/browser/index.mjs +31 -18
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/CellEditor/CellEditor.d.ts +4 -2
- package/dist/types/src/CellEditor/CellEditor.d.ts.map +1 -1
- package/dist/types/src/CellEditor/GridCellEditor.d.ts +1 -1
- package/dist/types/src/CellEditor/GridCellEditor.d.ts.map +1 -1
- package/dist/types/src/Grid/Grid.d.ts +2 -1
- package/dist/types/src/Grid/Grid.d.ts.map +1 -1
- package/dist/types/src/Grid/Grid.stories.d.ts.map +1 -1
- package/package.json +14 -11
- package/src/CellEditor/CellEditor.tsx +6 -7
- package/src/CellEditor/GridCellEditor.tsx +6 -3
- package/src/Grid/Grid.stories.tsx +68 -28
- package/src/Grid/Grid.tsx +25 -11
|
@@ -3,10 +3,9 @@ import "@dxos/lit-grid/dx-grid.pcss";
|
|
|
3
3
|
import { createComponent } from "@lit/react";
|
|
4
4
|
import { createContextScope } from "@radix-ui/react-context";
|
|
5
5
|
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
6
|
-
import React, { forwardRef, useCallback,
|
|
6
|
+
import React, { forwardRef, useCallback, useEffect, useState } from "react";
|
|
7
7
|
import { DxGrid as NaturalDxGrid } from "@dxos/lit-grid";
|
|
8
|
-
import {
|
|
9
|
-
import { colToA1Notation, rowToA1Notation, closestCell } from "@dxos/lit-grid";
|
|
8
|
+
import { colToA1Notation, rowToA1Notation, closestCell, commentedClassName } from "@dxos/lit-grid";
|
|
10
9
|
var DxGrid = createComponent({
|
|
11
10
|
tagName: "dx-grid",
|
|
12
11
|
elementClass: NaturalDxGrid,
|
|
@@ -46,14 +45,28 @@ GridRoot.displayName = GRID_NAME;
|
|
|
46
45
|
var GRID_CONTENT_NAME = "GridContent";
|
|
47
46
|
var GridContent = /* @__PURE__ */ forwardRef((props, forwardedRef) => {
|
|
48
47
|
const { id, editing, setEditBox, setEditing } = useGridContext(GRID_CONTENT_NAME, props.__gridScope);
|
|
49
|
-
const dxGrid =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
const [dxGrid, setDxGridInternal] = useState(null);
|
|
49
|
+
const setDxGrid = useCallback((nextDxGrid) => {
|
|
50
|
+
setDxGridInternal(nextDxGrid);
|
|
51
|
+
if (forwardedRef) {
|
|
52
|
+
if (typeof forwardedRef === "function") {
|
|
53
|
+
forwardedRef?.(nextDxGrid);
|
|
54
|
+
} else {
|
|
55
|
+
forwardedRef.current = nextDxGrid;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}, [
|
|
59
|
+
forwardedRef,
|
|
60
|
+
dxGrid
|
|
61
|
+
]);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (dxGrid && props.getCells) {
|
|
64
|
+
dxGrid.getCells = props.getCells;
|
|
65
|
+
dxGrid.requestUpdate("initialCells");
|
|
54
66
|
}
|
|
55
67
|
}, [
|
|
56
|
-
props.getCells
|
|
68
|
+
props.getCells,
|
|
69
|
+
dxGrid
|
|
57
70
|
]);
|
|
58
71
|
const handleEdit = useCallback((event) => {
|
|
59
72
|
setEditBox(event.cellBox);
|
|
@@ -67,7 +80,7 @@ var GridContent = /* @__PURE__ */ forwardRef((props, forwardedRef) => {
|
|
|
67
80
|
gridId: id,
|
|
68
81
|
mode: editing ? "edit" : "browse",
|
|
69
82
|
onEdit: handleEdit,
|
|
70
|
-
ref:
|
|
83
|
+
ref: setDxGrid
|
|
71
84
|
});
|
|
72
85
|
});
|
|
73
86
|
GridContent.displayName = GRID_CONTENT_NAME;
|
|
@@ -193,7 +206,8 @@ var editorVariants = {
|
|
|
193
206
|
grid: {
|
|
194
207
|
root: "absolute z-[1]",
|
|
195
208
|
editor: "[&>.cm-scroller]:scrollbar-none tabular-nums",
|
|
196
|
-
|
|
209
|
+
// This must match cell styling in `dx-grid.pcss`.
|
|
210
|
+
content: "!border !border-transparent !pli-[3px] !plb-0.5"
|
|
197
211
|
}
|
|
198
212
|
};
|
|
199
213
|
var CellEditor = ({ value, extension, autoFocus, onBlur, variant = "legacy", box, gridId }) => {
|
|
@@ -208,11 +222,9 @@ var CellEditor = ({ value, extension, autoFocus, onBlur, variant = "legacy", box
|
|
|
208
222
|
extensions: [
|
|
209
223
|
extension ?? [],
|
|
210
224
|
preventNewline,
|
|
211
|
-
EditorView.focusChangeEffect.of((
|
|
225
|
+
EditorView.focusChangeEffect.of((state, focusing) => {
|
|
212
226
|
if (!focusing) {
|
|
213
|
-
onBlur?.(
|
|
214
|
-
type: "blur"
|
|
215
|
-
});
|
|
227
|
+
onBlur?.(state.doc.toString());
|
|
216
228
|
}
|
|
217
229
|
return null;
|
|
218
230
|
}),
|
|
@@ -251,14 +263,14 @@ var CellEditor = ({ value, extension, autoFocus, onBlur, variant = "legacy", box
|
|
|
251
263
|
|
|
252
264
|
// packages/ui/react-ui-grid/src/CellEditor/GridCellEditor.tsx
|
|
253
265
|
import React3 from "react";
|
|
254
|
-
var GridCellEditor = ({ extension, getCellContent, __gridScope }) => {
|
|
255
|
-
const { id, editing,
|
|
266
|
+
var GridCellEditor = ({ extension, getCellContent, onBlur, __gridScope }) => {
|
|
267
|
+
const { id, editing, editBox } = useGridContext("GridSheetCellEditor", __gridScope);
|
|
256
268
|
return editing ? /* @__PURE__ */ React3.createElement(CellEditor, {
|
|
257
269
|
variant: "grid",
|
|
258
270
|
value: editing.initialContent ?? getCellContent(editing.index),
|
|
259
271
|
autoFocus: true,
|
|
260
272
|
box: editBox,
|
|
261
|
-
onBlur
|
|
273
|
+
onBlur,
|
|
262
274
|
extension,
|
|
263
275
|
gridId: id
|
|
264
276
|
}) : null;
|
|
@@ -271,6 +283,7 @@ export {
|
|
|
271
283
|
GridRoot,
|
|
272
284
|
closestCell,
|
|
273
285
|
colToA1Notation,
|
|
286
|
+
commentedClassName,
|
|
274
287
|
createGridScope,
|
|
275
288
|
editorKeys,
|
|
276
289
|
rowToA1Notation,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/Grid/Grid.tsx", "../../../src/CellEditor/CellEditor.tsx", "../../../src/CellEditor/GridCellEditor.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport '@dxos/lit-grid/dx-grid.pcss';\n\nimport { createComponent, type EventName } from '@lit/react';\nimport { createContextScope, type Scope } from '@radix-ui/react-context';\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport React, {\n type ComponentProps,\n forwardRef,\n type PropsWithChildren,\n useCallback,\n useLayoutEffect,\n useState,\n} from 'react';\n\nimport { type DxAxisResize, type DxEditRequest, type DxGridCellsSelect, DxGrid as NaturalDxGrid } from '@dxos/lit-grid';\nimport { useForwardedRef } from '@dxos/react-ui';\n\ntype DxGridElement = NaturalDxGrid;\n\nconst DxGrid = createComponent({\n tagName: 'dx-grid',\n elementClass: NaturalDxGrid,\n react: React,\n events: {\n onAxisResize: 'dx-axis-resize' as EventName<DxAxisResize>,\n onEdit: 'dx-edit-request' as EventName<DxEditRequest>,\n onSelect: 'dx-grid-cells-select' as EventName<DxGridCellsSelect>,\n },\n});\n\ntype GridEditBox = DxEditRequest['cellBox'];\n\nconst initialBox = {\n insetInlineStart: 0,\n insetBlockStart: 0,\n inlineSize: 0,\n blockSize: 0,\n} satisfies GridEditBox;\n\ntype GridEditing = { index: DxEditRequest['cellIndex']; initialContent: DxEditRequest['initialContent'] } | null;\n\ntype GridContextValue = {\n id: string;\n editing: GridEditing;\n setEditing: (nextEditing: GridEditing) => void;\n editBox: GridEditBox;\n setEditBox: (nextEditBox: GridEditBox) => void;\n};\n\ntype GridScopedProps<P> = P & { __gridScope?: Scope };\n\nconst GRID_NAME = 'Grid';\n\nconst [createGridContext, createGridScope] = createContextScope(GRID_NAME, []);\n\nconst [GridProvider, useGridContext] = createGridContext<GridContextValue>(GRID_NAME);\n\ntype GridRootProps = PropsWithChildren<\n { id: string } & Partial<{\n editing: GridEditing;\n defaultEditing: GridEditing;\n onEditingChange: (nextEditing: GridEditing) => void;\n }>\n>;\n\nconst GridRoot = ({\n id,\n editing: propsEditing,\n defaultEditing,\n onEditingChange,\n children,\n __gridScope,\n}: GridScopedProps<GridRootProps>) => {\n const [editing = null, setEditing] = useControllableState({\n prop: propsEditing,\n defaultProp: defaultEditing,\n onChange: onEditingChange,\n });\n const [editBox, setEditBox] = useState<GridEditBox>(initialBox);\n return (\n <GridProvider\n id={id}\n editing={editing}\n setEditing={setEditing}\n editBox={editBox}\n setEditBox={setEditBox}\n scope={__gridScope}\n >\n {children}\n </GridProvider>\n );\n};\n\nGridRoot.displayName = GRID_NAME;\n\ntype GridContentProps = Omit<ComponentProps<typeof DxGrid>, 'onEdit'> & {\n getCells?: NonNullable<NaturalDxGrid['getCells']>;\n};\n\nconst GRID_CONTENT_NAME = 'GridContent';\n\nconst GridContent = forwardRef<NaturalDxGrid, GridScopedProps<GridContentProps>>((props, forwardedRef) => {\n const { id, editing, setEditBox, setEditing } = useGridContext(GRID_CONTENT_NAME, props.__gridScope);\n const dxGrid = useForwardedRef(forwardedRef);\n\n // Needed instead of `useEffect` to ensure the DxGrid ref is defined.\n useLayoutEffect(() => {\n if (dxGrid.current && props.getCells) {\n dxGrid.current.getCells = props.getCells;\n dxGrid.current.requestUpdate('initialCells');\n }\n }, [props.getCells]);\n\n const handleEdit = useCallback((event: DxEditRequest) => {\n setEditBox(event.cellBox);\n setEditing({ index: event.cellIndex, initialContent: event.initialContent });\n }, []);\n\n return <DxGrid {...props} gridId={id} mode={editing ? 'edit' : 'browse'} onEdit={handleEdit} ref={dxGrid} />;\n});\n\nGridContent.displayName = GRID_CONTENT_NAME;\n\nexport const Grid = {\n Root: GridRoot,\n Content: GridContent,\n};\n\nexport { GridRoot, GridContent, useGridContext, createGridScope };\n\nexport type { GridRootProps, GridContentProps, GridEditing, GridEditBox, GridScopedProps, DxGridElement };\n\nexport { colToA1Notation, rowToA1Notation, closestCell } from '@dxos/lit-grid';\n\nexport type {\n DxGridRange,\n DxGridAxisMeta,\n DxAxisResize,\n DxGridCells,\n DxGridPlaneRange,\n DxGridPlaneCells,\n DxGridCellIndex,\n DxGridCellValue,\n DxGridPlane,\n DxGridPosition,\n} from '@dxos/lit-grid';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { completionStatus } from '@codemirror/autocomplete';\nimport { type Extension } from '@codemirror/state';\nimport { EditorView, keymap } from '@codemirror/view';\nimport React, { type DOMAttributes, type KeyboardEvent } from 'react';\n\nimport { useThemeContext } from '@dxos/react-ui';\nimport {\n type UseTextEditorProps,\n createBasicExtensions,\n createThemeExtensions,\n preventNewline,\n useTextEditor,\n} from '@dxos/react-ui-editor';\n\nimport { type GridEditBox } from '../Grid';\n\nexport type EditorKeyEvent = Pick<KeyboardEvent<HTMLInputElement>, 'key'> & { shift?: boolean };\n\nexport type EditorKeysProps = {\n onClose: (value: string | undefined, event: EditorKeyEvent) => void;\n onNav?: (value: string | undefined, event: EditorKeyEvent) => void;\n};\n\n// TODO(Zan): Should each consumer be responsible for defining these?\nexport const editorKeys = ({ onNav, onClose }: EditorKeysProps): Extension => {\n return keymap.of([\n {\n key: 'ArrowUp',\n run: (editor) => {\n const value = editor.state.doc.toString();\n onNav?.(value, { key: 'ArrowUp' });\n return !!onNav;\n },\n },\n {\n key: 'ArrowDown',\n run: (editor) => {\n const value = editor.state.doc.toString();\n onNav?.(value, { key: 'ArrowDown' });\n return !!onNav;\n },\n },\n {\n key: 'ArrowLeft',\n run: (editor) => {\n const value = editor.state.doc.toString();\n onNav?.(value, { key: 'ArrowLeft' });\n return !!onNav;\n },\n },\n {\n key: 'ArrowRight',\n run: (editor) => {\n const value = editor.state.doc.toString();\n onNav?.(value, { key: 'ArrowRight' });\n return !!onNav;\n },\n },\n {\n key: 'Enter',\n run: (editor) => {\n if (completionStatus(editor.state)) {\n return false;\n } else {\n onClose(editor.state.doc.toString(), { key: 'Enter' });\n return true;\n }\n },\n shift: (editor) => {\n if (completionStatus(editor.state)) {\n return false;\n } else {\n onClose(editor.state.doc.toString(), { key: 'Enter', shift: true });\n return true;\n }\n },\n },\n {\n key: 'Tab',\n run: (editor) => {\n if (completionStatus(editor.state)) {\n return false;\n } else {\n onClose(editor.state.doc.toString(), { key: 'Tab' });\n return true;\n }\n },\n shift: (editor) => {\n if (completionStatus(editor.state)) {\n return false;\n } else {\n onClose(editor.state.doc.toString(), { key: 'Tab', shift: true });\n return true;\n }\n },\n },\n {\n key: 'Escape',\n run: () => {\n onClose(undefined, { key: 'Escape' });\n return true;\n },\n },\n ]);\n};\n\nexport type CellEditorProps = {\n value?: string;\n extension?: Extension;\n variant?: keyof typeof editorVariants;\n box?: GridEditBox;\n gridId?: string;\n} & Pick<UseTextEditorProps, 'autoFocus'> &\n Pick<DOMAttributes<HTMLInputElement>, 'onBlur' | 'onKeyDown'>;\n\nconst editorVariants = {\n // TODO(thure): remove when legacy is no longer used.\n legacy: {\n root: 'flex w-full',\n editor: 'flex w-full [&>.cm-scroller]:scrollbar-none',\n content: '!px-2 !py-1',\n },\n grid: {\n root: 'absolute z-[1]',\n editor: '[&>.cm-scroller]:scrollbar-none tabular-nums',\n content: '!border !border-transparent !p-0.5',\n },\n};\n\nexport const CellEditor = ({\n value,\n extension,\n autoFocus,\n onBlur,\n variant = 'legacy',\n box,\n gridId,\n}: CellEditorProps) => {\n const { themeMode } = useThemeContext();\n const { parentRef } = useTextEditor(() => {\n return {\n autoFocus,\n initialValue: value,\n selection: { anchor: value?.length ?? 0 },\n extensions: [\n extension ?? [],\n preventNewline,\n EditorView.focusChangeEffect.of((_, focusing) => {\n if (!focusing) {\n onBlur?.({ type: 'blur' } as any);\n }\n return null;\n }),\n createBasicExtensions({ lineWrapping: false }),\n createThemeExtensions({\n themeMode,\n slots: {\n editor: {\n className: editorVariants[variant].editor,\n },\n content: {\n className: editorVariants[variant].content,\n },\n },\n }),\n ],\n };\n }, [extension, autoFocus, value, variant, onBlur]);\n\n return (\n <div\n ref={parentRef}\n className={editorVariants[variant].root}\n style={box}\n {...(gridId && { 'data-grid': gridId })}\n />\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport React from 'react';\n\nimport { CellEditor, type CellEditorProps } from './CellEditor';\nimport { type GridScopedProps, useGridContext } from '../Grid';\n\nexport const GridCellEditor = ({\n extension,\n getCellContent,\n __gridScope,\n}: GridScopedProps<Pick<CellEditorProps, 'extension'> & { getCellContent: (index: string) => string | undefined }>) => {\n const { id, editing, setEditing, editBox } = useGridContext('GridSheetCellEditor', __gridScope);\n\n return editing ? (\n <CellEditor\n variant='grid'\n value={editing.initialContent ?? getCellContent(editing.index)}\n autoFocus\n box={editBox}\n onBlur={() => setEditing(null)}\n extension={extension}\n gridId={id}\n />\n ) : null;\n};\n"],
|
|
5
|
-
"mappings": ";AAIA,OAAO;AAEP,SAASA,uBAAuC;AAChD,SAASC,0BAAsC;AAC/C,SAASC,4BAA4B;AACrC,OAAOC,SAELC,YAEAC,aACAC,
|
|
6
|
-
"names": ["createComponent", "createContextScope", "useControllableState", "React", "forwardRef", "useCallback", "
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport '@dxos/lit-grid/dx-grid.pcss';\n\nimport { createComponent, type EventName } from '@lit/react';\nimport { createContextScope, type Scope } from '@radix-ui/react-context';\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport React, {\n type ComponentProps,\n forwardRef,\n type PropsWithChildren,\n useCallback,\n useEffect,\n useState,\n} from 'react';\n\nimport { type DxAxisResize, type DxEditRequest, type DxGridCellsSelect, DxGrid as NaturalDxGrid } from '@dxos/lit-grid';\n\ntype DxGridElement = NaturalDxGrid;\n\nconst DxGrid = createComponent({\n tagName: 'dx-grid',\n elementClass: NaturalDxGrid,\n react: React,\n events: {\n onAxisResize: 'dx-axis-resize' as EventName<DxAxisResize>,\n onEdit: 'dx-edit-request' as EventName<DxEditRequest>,\n onSelect: 'dx-grid-cells-select' as EventName<DxGridCellsSelect>,\n },\n});\n\ntype GridEditBox = DxEditRequest['cellBox'];\n\nconst initialBox = {\n insetInlineStart: 0,\n insetBlockStart: 0,\n inlineSize: 0,\n blockSize: 0,\n} satisfies GridEditBox;\n\ntype GridEditing = { index: DxEditRequest['cellIndex']; initialContent: DxEditRequest['initialContent'] } | null;\n\ntype GridContextValue = {\n id: string;\n editing: GridEditing;\n setEditing: (nextEditing: GridEditing) => void;\n editBox: GridEditBox;\n setEditBox: (nextEditBox: GridEditBox) => void;\n};\n\ntype GridScopedProps<P> = P & { __gridScope?: Scope };\n\nconst GRID_NAME = 'Grid';\n\nconst [createGridContext, createGridScope] = createContextScope(GRID_NAME, []);\n\nconst [GridProvider, useGridContext] = createGridContext<GridContextValue>(GRID_NAME);\n\ntype GridRootProps = PropsWithChildren<\n { id: string } & Partial<{\n editing: GridEditing;\n defaultEditing: GridEditing;\n onEditingChange: (nextEditing: GridEditing) => void;\n }>\n>;\n\nconst GridRoot = ({\n id,\n editing: propsEditing,\n defaultEditing,\n onEditingChange,\n children,\n __gridScope,\n}: GridScopedProps<GridRootProps>) => {\n const [editing = null, setEditing] = useControllableState({\n prop: propsEditing,\n defaultProp: defaultEditing,\n onChange: onEditingChange,\n });\n const [editBox, setEditBox] = useState<GridEditBox>(initialBox);\n return (\n <GridProvider\n id={id}\n editing={editing}\n setEditing={setEditing}\n editBox={editBox}\n setEditBox={setEditBox}\n scope={__gridScope}\n >\n {children}\n </GridProvider>\n );\n};\n\nGridRoot.displayName = GRID_NAME;\n\ntype GridContentProps = Omit<ComponentProps<typeof DxGrid>, 'onEdit'> & {\n getCells?: NonNullable<NaturalDxGrid['getCells']>;\n activeRefs?: string;\n};\n\nconst GRID_CONTENT_NAME = 'GridContent';\n\nconst GridContent = forwardRef<NaturalDxGrid, GridScopedProps<GridContentProps>>((props, forwardedRef) => {\n const { id, editing, setEditBox, setEditing } = useGridContext(GRID_CONTENT_NAME, props.__gridScope);\n const [dxGrid, setDxGridInternal] = useState<NaturalDxGrid | null>(null);\n\n // NOTE(thure): using `useState` instead of `useRef` works with refs provided by `@lit/react` and gives us a reliable dependency for `useEffect` whereas `useLayoutEffect` does not guarantee the element will be defined.\n const setDxGrid = useCallback(\n (nextDxGrid: NaturalDxGrid | null) => {\n setDxGridInternal(nextDxGrid);\n if (forwardedRef) {\n if (typeof forwardedRef === 'function') {\n forwardedRef?.(nextDxGrid);\n } else {\n forwardedRef.current = nextDxGrid;\n }\n }\n },\n [forwardedRef, dxGrid],\n );\n\n useEffect(() => {\n if (dxGrid && props.getCells) {\n dxGrid.getCells = props.getCells;\n dxGrid.requestUpdate('initialCells');\n }\n }, [props.getCells, dxGrid]);\n\n const handleEdit = useCallback((event: DxEditRequest) => {\n setEditBox(event.cellBox);\n setEditing({ index: event.cellIndex, initialContent: event.initialContent });\n }, []);\n\n return <DxGrid {...props} gridId={id} mode={editing ? 'edit' : 'browse'} onEdit={handleEdit} ref={setDxGrid} />;\n});\n\nGridContent.displayName = GRID_CONTENT_NAME;\n\nexport const Grid = {\n Root: GridRoot,\n Content: GridContent,\n};\n\nexport { GridRoot, GridContent, useGridContext, createGridScope };\n\nexport type { GridRootProps, GridContentProps, GridEditing, GridEditBox, GridScopedProps, DxGridElement };\n\nexport { colToA1Notation, rowToA1Notation, closestCell, commentedClassName } from '@dxos/lit-grid';\n\nexport type {\n DxGridRange,\n DxGridAxisMeta,\n DxAxisResize,\n DxGridCells,\n DxGridPlaneRange,\n DxGridPlaneCells,\n DxGridCellIndex,\n DxGridCellValue,\n DxGridPlane,\n DxGridPosition,\n} from '@dxos/lit-grid';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { completionStatus } from '@codemirror/autocomplete';\nimport { type Extension } from '@codemirror/state';\nimport { EditorView, keymap } from '@codemirror/view';\nimport React, { type KeyboardEvent } from 'react';\n\nimport { useThemeContext } from '@dxos/react-ui';\nimport {\n type UseTextEditorProps,\n createBasicExtensions,\n createThemeExtensions,\n preventNewline,\n useTextEditor,\n} from '@dxos/react-ui-editor';\n\nimport { type GridEditBox } from '../Grid';\n\nexport type EditorKeyEvent = Pick<KeyboardEvent<HTMLInputElement>, 'key'> & { shift?: boolean };\n\nexport type EditorKeysProps = {\n onClose: (value: string | undefined, event: EditorKeyEvent) => void;\n onNav?: (value: string | undefined, event: EditorKeyEvent) => void;\n};\n// TODO(Zan): Should each consumer be responsible for defining these?\nexport const editorKeys = ({ onNav, onClose }: EditorKeysProps): Extension => {\n return keymap.of([\n {\n key: 'ArrowUp',\n run: (editor) => {\n const value = editor.state.doc.toString();\n onNav?.(value, { key: 'ArrowUp' });\n return !!onNav;\n },\n },\n {\n key: 'ArrowDown',\n run: (editor) => {\n const value = editor.state.doc.toString();\n onNav?.(value, { key: 'ArrowDown' });\n return !!onNav;\n },\n },\n {\n key: 'ArrowLeft',\n run: (editor) => {\n const value = editor.state.doc.toString();\n onNav?.(value, { key: 'ArrowLeft' });\n return !!onNav;\n },\n },\n {\n key: 'ArrowRight',\n run: (editor) => {\n const value = editor.state.doc.toString();\n onNav?.(value, { key: 'ArrowRight' });\n return !!onNav;\n },\n },\n {\n key: 'Enter',\n run: (editor) => {\n if (completionStatus(editor.state)) {\n return false;\n } else {\n onClose(editor.state.doc.toString(), { key: 'Enter' });\n return true;\n }\n },\n shift: (editor) => {\n if (completionStatus(editor.state)) {\n return false;\n } else {\n onClose(editor.state.doc.toString(), { key: 'Enter', shift: true });\n return true;\n }\n },\n },\n {\n key: 'Tab',\n run: (editor) => {\n if (completionStatus(editor.state)) {\n return false;\n } else {\n onClose(editor.state.doc.toString(), { key: 'Tab' });\n return true;\n }\n },\n shift: (editor) => {\n if (completionStatus(editor.state)) {\n return false;\n } else {\n onClose(editor.state.doc.toString(), { key: 'Tab', shift: true });\n return true;\n }\n },\n },\n {\n key: 'Escape',\n run: () => {\n onClose(undefined, { key: 'Escape' });\n return true;\n },\n },\n ]);\n};\n\nexport type CellEditorProps = {\n value?: string;\n extension?: Extension;\n variant?: keyof typeof editorVariants;\n box?: GridEditBox;\n gridId?: string;\n} & Pick<UseTextEditorProps, 'autoFocus'> & { onBlur?: (value?: string) => void };\n\nconst editorVariants = {\n // TODO(thure): remove when legacy is no longer used.\n legacy: {\n root: 'flex w-full',\n editor: 'flex w-full [&>.cm-scroller]:scrollbar-none',\n content: '!px-2 !py-1',\n },\n grid: {\n root: 'absolute z-[1]',\n editor: '[&>.cm-scroller]:scrollbar-none tabular-nums',\n // This must match cell styling in `dx-grid.pcss`.\n content: '!border !border-transparent !pli-[3px] !plb-0.5',\n },\n};\n\nexport const CellEditor = ({\n value,\n extension,\n autoFocus,\n onBlur,\n variant = 'legacy',\n box,\n gridId,\n}: CellEditorProps) => {\n const { themeMode } = useThemeContext();\n const { parentRef } = useTextEditor(() => {\n return {\n autoFocus,\n initialValue: value,\n selection: { anchor: value?.length ?? 0 },\n extensions: [\n extension ?? [],\n preventNewline,\n EditorView.focusChangeEffect.of((state, focusing) => {\n if (!focusing) {\n onBlur?.(state.doc.toString());\n }\n return null;\n }),\n createBasicExtensions({ lineWrapping: false }),\n createThemeExtensions({\n themeMode,\n slots: {\n editor: {\n className: editorVariants[variant].editor,\n },\n content: {\n className: editorVariants[variant].content,\n },\n },\n }),\n ],\n };\n }, [extension, autoFocus, value, variant, onBlur]);\n\n return (\n <div\n ref={parentRef}\n className={editorVariants[variant].root}\n style={box}\n {...(gridId && { 'data-grid': gridId })}\n />\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport React from 'react';\n\nimport { CellEditor, type CellEditorProps } from './CellEditor';\nimport { type GridScopedProps, useGridContext } from '../Grid';\n\nexport const GridCellEditor = ({\n extension,\n getCellContent,\n onBlur,\n __gridScope,\n}: GridScopedProps<\n Pick<CellEditorProps, 'extension' | 'onBlur'> & { getCellContent: (index: string) => string | undefined }\n>) => {\n const { id, editing, editBox } = useGridContext('GridSheetCellEditor', __gridScope);\n\n return editing ? (\n <CellEditor\n variant='grid'\n value={editing.initialContent ?? getCellContent(editing.index)}\n autoFocus\n box={editBox}\n onBlur={onBlur}\n extension={extension}\n gridId={id}\n />\n ) : null;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["createComponent", "createContextScope", "useControllableState", "React", "forwardRef", "useCallback", "useEffect", "useState", "DxGrid", "NaturalDxGrid", "colToA1Notation", "rowToA1Notation", "closestCell", "commentedClassName", "DxGrid", "createComponent", "tagName", "elementClass", "NaturalDxGrid", "react", "React", "events", "onAxisResize", "onEdit", "onSelect", "initialBox", "insetInlineStart", "insetBlockStart", "inlineSize", "blockSize", "GRID_NAME", "createGridContext", "createGridScope", "createContextScope", "GridProvider", "useGridContext", "GridRoot", "id", "editing", "propsEditing", "defaultEditing", "onEditingChange", "children", "__gridScope", "setEditing", "useControllableState", "prop", "defaultProp", "onChange", "editBox", "setEditBox", "useState", "scope", "displayName", "GRID_CONTENT_NAME", "GridContent", "forwardRef", "props", "forwardedRef", "dxGrid", "setDxGridInternal", "setDxGrid", "useCallback", "nextDxGrid", "current", "useEffect", "getCells", "requestUpdate", "handleEdit", "event", "cellBox", "index", "cellIndex", "initialContent", "gridId", "mode", "ref", "Grid", "Root", "Content", "completionStatus", "EditorView", "keymap", "React", "useThemeContext", "createBasicExtensions", "createThemeExtensions", "preventNewline", "useTextEditor", "editorKeys", "onNav", "onClose", "keymap", "of", "key", "run", "editor", "value", "state", "doc", "toString", "completionStatus", "shift", "undefined", "editorVariants", "legacy", "root", "content", "grid", "CellEditor", "extension", "autoFocus", "onBlur", "variant", "box", "gridId", "themeMode", "useThemeContext", "parentRef", "useTextEditor", "initialValue", "selection", "anchor", "length", "extensions", "preventNewline", "EditorView", "focusChangeEffect", "focusing", "createBasicExtensions", "lineWrapping", "createThemeExtensions", "slots", "className", "React", "div", "ref", "style", "React", "GridCellEditor", "extension", "getCellContent", "onBlur", "__gridScope", "id", "editing", "editBox", "useGridContext", "React", "CellEditor", "variant", "value", "initialContent", "index", "autoFocus", "box", "gridId"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/ui/react-ui-grid/src/Grid/Grid.tsx":{"bytes":
|
|
1
|
+
{"inputs":{"packages/ui/react-ui-grid/src/Grid/Grid.tsx":{"bytes":13811,"imports":[{"path":"@dxos/lit-grid/dx-grid.pcss","kind":"import-statement","external":true},{"path":"@lit/react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"@radix-ui/react-use-controllable-state","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/lit-grid","kind":"import-statement","external":true},{"path":"@dxos/lit-grid","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-grid/src/Grid/index.ts":{"bytes":494,"imports":[{"path":"packages/ui/react-ui-grid/src/Grid/Grid.tsx","kind":"import-statement","original":"./Grid"}],"format":"esm"},"packages/ui/react-ui-grid/src/CellEditor/CellEditor.tsx":{"bytes":16671,"imports":[{"path":"@codemirror/autocomplete","kind":"import-statement","external":true},{"path":"@codemirror/view","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-editor","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-grid/src/CellEditor/GridCellEditor.tsx":{"bytes":2833,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-grid/src/CellEditor/CellEditor.tsx","kind":"import-statement","original":"./CellEditor"},{"path":"packages/ui/react-ui-grid/src/Grid/index.ts","kind":"import-statement","original":"../Grid"}],"format":"esm"},"packages/ui/react-ui-grid/src/CellEditor/index.ts":{"bytes":620,"imports":[{"path":"packages/ui/react-ui-grid/src/CellEditor/CellEditor.tsx","kind":"import-statement","original":"./CellEditor"},{"path":"packages/ui/react-ui-grid/src/CellEditor/GridCellEditor.tsx","kind":"import-statement","original":"./GridCellEditor"}],"format":"esm"},"packages/ui/react-ui-grid/src/index.ts":{"bytes":583,"imports":[{"path":"packages/ui/react-ui-grid/src/Grid/index.ts","kind":"import-statement","original":"./Grid"},{"path":"packages/ui/react-ui-grid/src/CellEditor/index.ts","kind":"import-statement","original":"./CellEditor"}],"format":"esm"}},"outputs":{"packages/ui/react-ui-grid/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":17185},"packages/ui/react-ui-grid/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/lit-grid/dx-grid.pcss","kind":"import-statement","external":true},{"path":"@lit/react","kind":"import-statement","external":true},{"path":"@radix-ui/react-context","kind":"import-statement","external":true},{"path":"@radix-ui/react-use-controllable-state","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/lit-grid","kind":"import-statement","external":true},{"path":"@dxos/lit-grid","kind":"import-statement","external":true},{"path":"@codemirror/autocomplete","kind":"import-statement","external":true},{"path":"@codemirror/view","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-editor","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"exports":["CellEditor","Grid","GridCellEditor","GridContent","GridRoot","closestCell","colToA1Notation","commentedClassName","createGridScope","editorKeys","rowToA1Notation","useGridContext"],"entryPoint":"packages/ui/react-ui-grid/src/index.ts","inputs":{"packages/ui/react-ui-grid/src/Grid/Grid.tsx":{"bytesInOutput":2702},"packages/ui/react-ui-grid/src/Grid/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-grid/src/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-grid/src/CellEditor/CellEditor.tsx":{"bytesInOutput":4072},"packages/ui/react-ui-grid/src/CellEditor/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-grid/src/CellEditor/GridCellEditor.tsx":{"bytesInOutput":450}},"bytes":7634}}}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Extension } from '@codemirror/state';
|
|
2
|
-
import React, { type
|
|
2
|
+
import React, { type KeyboardEvent } from 'react';
|
|
3
3
|
import { type UseTextEditorProps } from '@dxos/react-ui-editor';
|
|
4
4
|
import { type GridEditBox } from '../Grid';
|
|
5
5
|
export type EditorKeyEvent = Pick<KeyboardEvent<HTMLInputElement>, 'key'> & {
|
|
@@ -16,7 +16,9 @@ export type CellEditorProps = {
|
|
|
16
16
|
variant?: keyof typeof editorVariants;
|
|
17
17
|
box?: GridEditBox;
|
|
18
18
|
gridId?: string;
|
|
19
|
-
} & Pick<UseTextEditorProps, 'autoFocus'> &
|
|
19
|
+
} & Pick<UseTextEditorProps, 'autoFocus'> & {
|
|
20
|
+
onBlur?: (value?: string) => void;
|
|
21
|
+
};
|
|
20
22
|
declare const editorVariants: {
|
|
21
23
|
legacy: {
|
|
22
24
|
root: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CellEditor.d.ts","sourceRoot":"","sources":["../../../../src/CellEditor/CellEditor.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,KAAK,EAAE,EAAE,KAAK,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"CellEditor.d.ts","sourceRoot":"","sources":["../../../../src/CellEditor/CellEditor.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,KAAK,EAAE,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAGlD,OAAO,EACL,KAAK,kBAAkB,EAKxB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,EAAE,KAAK,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhG,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACpE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CACpE,CAAC;AAEF,eAAO,MAAM,UAAU,uBAAwB,eAAe,KAAG,SAgFhE,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,OAAO,cAAc,CAAC;IACtC,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,IAAI,CAAC,kBAAkB,EAAE,WAAW,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAAC;AAElF,QAAA,MAAM,cAAc;;;;;;;;;;;CAanB,CAAC;AAEF,eAAO,MAAM,UAAU,mEAQpB,eAAe,sBAwCjB,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type CellEditorProps } from './CellEditor';
|
|
3
3
|
import { type GridScopedProps } from '../Grid';
|
|
4
|
-
export declare const GridCellEditor: ({ extension, getCellContent, __gridScope, }: GridScopedProps<Pick<CellEditorProps, "extension"> & {
|
|
4
|
+
export declare const GridCellEditor: ({ extension, getCellContent, onBlur, __gridScope, }: GridScopedProps<Pick<CellEditorProps, "extension" | "onBlur"> & {
|
|
5
5
|
getCellContent: (index: string) => string | undefined;
|
|
6
6
|
}>) => React.JSX.Element | null;
|
|
7
7
|
//# sourceMappingURL=GridCellEditor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GridCellEditor.d.ts","sourceRoot":"","sources":["../../../../src/CellEditor/GridCellEditor.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,KAAK,eAAe,EAAkB,MAAM,SAAS,CAAC;AAE/D,eAAO,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"GridCellEditor.d.ts","sourceRoot":"","sources":["../../../../src/CellEditor/GridCellEditor.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,KAAK,eAAe,EAAkB,MAAM,SAAS,CAAC;AAE/D,eAAO,MAAM,cAAc,wDAKxB,eAAe,CAChB,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,QAAQ,CAAC,GAAG;IAAE,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;CAAE,CAC1G,6BAcA,CAAC"}
|
|
@@ -39,6 +39,7 @@ declare const GridRoot: {
|
|
|
39
39
|
};
|
|
40
40
|
type GridContentProps = Omit<ComponentProps<typeof DxGrid>, 'onEdit'> & {
|
|
41
41
|
getCells?: NonNullable<NaturalDxGrid['getCells']>;
|
|
42
|
+
activeRefs?: string;
|
|
42
43
|
};
|
|
43
44
|
declare const GridContent: React.ForwardRefExoticComponent<Omit<GridScopedProps<GridContentProps>, "ref"> & React.RefAttributes<NaturalDxGrid>>;
|
|
44
45
|
export declare const Grid: {
|
|
@@ -50,6 +51,6 @@ export declare const Grid: {
|
|
|
50
51
|
};
|
|
51
52
|
export { GridRoot, GridContent, useGridContext, createGridScope };
|
|
52
53
|
export type { GridRootProps, GridContentProps, GridEditing, GridEditBox, GridScopedProps, DxGridElement };
|
|
53
|
-
export { colToA1Notation, rowToA1Notation, closestCell } from '@dxos/lit-grid';
|
|
54
|
+
export { colToA1Notation, rowToA1Notation, closestCell, commentedClassName } from '@dxos/lit-grid';
|
|
54
55
|
export type { DxGridRange, DxGridAxisMeta, DxAxisResize, DxGridCells, DxGridPlaneRange, DxGridPlaneCells, DxGridCellIndex, DxGridCellValue, DxGridPlane, DxGridPosition, } from '@dxos/lit-grid';
|
|
55
56
|
//# sourceMappingURL=Grid.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Grid.d.ts","sourceRoot":"","sources":["../../../../src/Grid/Grid.tsx"],"names":[],"mappings":"AAIA,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAsB,KAAK,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,KAAK,EAAE,EACZ,KAAK,cAAc,EAEnB,KAAK,iBAAiB,EAIvB,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Grid.d.ts","sourceRoot":"","sources":["../../../../src/Grid/Grid.tsx"],"names":[],"mappings":"AAIA,OAAO,6BAA6B,CAAC;AAErC,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAsB,KAAK,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,KAAK,EAAE,EACZ,KAAK,cAAc,EAEnB,KAAK,iBAAiB,EAIvB,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAExH,KAAK,aAAa,GAAG,aAAa,CAAC;AAEnC,QAAA,MAAM,MAAM;kBAK0B,SAAS,CAAC,YAAY,CAAC;YAC5B,SAAS,CAAC,aAAa,CAAC;cACjB,SAAS,CAAC,iBAAiB,CAAC;EAElE,CAAC;AAEH,KAAK,WAAW,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;AAS5C,KAAK,WAAW,GAAG;IAAE,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAAC,cAAc,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAA;CAAE,GAAG,IAAI,CAAC;AAEjH,KAAK,gBAAgB,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAC;IAC/C,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAC;CAChD,CAAC;AAEF,KAAK,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAItD,QAAA,MAA0B,eAAe,+CAAqC,CAAC;AAE/E,QAAA,MAAqB,cAAc,wFAAkD,CAAC;AAEtF,KAAK,aAAa,GAAG,iBAAiB,CACpC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB,cAAc,EAAE,WAAW,CAAC;IAC5B,eAAe,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,IAAI,CAAC;CACrD,CAAC,CACH,CAAC;AAEF,QAAA,MAAM,QAAQ;6FAOX,eAAe,CAAC,aAAa,CAAC;;CAmBhC,CAAC;AAIF,KAAK,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,QAAQ,CAAC,GAAG;IACtE,QAAQ,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAIF,QAAA,MAAM,WAAW,sHAgCf,CAAC;AAIH,eAAO,MAAM,IAAI;;iGAlEd,eAAe,CAAC,aAAa,CAAC;;;;CAqEhC,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC;AAElE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC;AAE1G,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEnG,YAAY,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,WAAW,EACX,cAAc,GACf,MAAM,gBAAgB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Grid.stories.d.ts","sourceRoot":"","sources":["../../../../src/Grid/Grid.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"Grid.stories.d.ts","sourceRoot":"","sources":["../../../../src/Grid/Grid.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAgF,MAAM,OAAO,CAAC;AAOrG,OAAO,EAAQ,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEzE,KAAK,cAAc,GAAG,gBAAgB,GAAG,IAAI,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;;;+CAiB9B,cAAc;;;;;;AAiEhE,wBAKE;AAEF,eAAO,MAAM,KAAK,EAAE,QAAQ,CAAC,cAAc,CA+B1C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-grid",
|
|
3
|
-
"version": "0.6.14-main.
|
|
3
|
+
"version": "0.6.14-main.8b352a0",
|
|
4
4
|
"description": "React component which manages a `dx-grid` Lit web component.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"author": "DXOS.org",
|
|
9
|
+
"sideEffects": true,
|
|
9
10
|
"exports": {
|
|
10
11
|
".": {
|
|
11
|
-
"
|
|
12
|
-
"
|
|
12
|
+
"types": "./dist/types/src/index.d.ts",
|
|
13
|
+
"browser": "./dist/lib/browser/index.mjs"
|
|
13
14
|
}
|
|
14
15
|
},
|
|
15
16
|
"types": "dist/types/src/index.d.ts",
|
|
@@ -28,9 +29,9 @@
|
|
|
28
29
|
"@radix-ui/react-context": "^1.0.0",
|
|
29
30
|
"@radix-ui/react-popper": "^1.1.2",
|
|
30
31
|
"@radix-ui/react-use-controllable-state": "^1.0.0",
|
|
31
|
-
"@dxos/lit-grid": "0.6.14-main.
|
|
32
|
-
"@dxos/
|
|
33
|
-
"@dxos/
|
|
32
|
+
"@dxos/lit-grid": "0.6.14-main.8b352a0",
|
|
33
|
+
"@dxos/util": "0.6.14-main.8b352a0",
|
|
34
|
+
"@dxos/react-ui-editor": "0.6.14-main.8b352a0"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@types/react": "~18.2.0",
|
|
@@ -38,15 +39,17 @@
|
|
|
38
39
|
"react": "~18.2.0",
|
|
39
40
|
"react-dom": "~18.2.0",
|
|
40
41
|
"vite": "5.4.7",
|
|
41
|
-
"@dxos/react-ui": "0.6.14-main.
|
|
42
|
-
"@dxos/
|
|
43
|
-
"@dxos/
|
|
42
|
+
"@dxos/react-ui": "0.6.14-main.8b352a0",
|
|
43
|
+
"@dxos/random": "0.6.14-main.8b352a0",
|
|
44
|
+
"@dxos/react-ui-theme": "0.6.14-main.8b352a0",
|
|
45
|
+
"@dxos/react-ui-searchlist": "0.6.14-main.8b352a0",
|
|
46
|
+
"@dxos/storybook-utils": "0.6.14-main.8b352a0"
|
|
44
47
|
},
|
|
45
48
|
"peerDependencies": {
|
|
46
49
|
"react": "~18.2.0",
|
|
47
50
|
"react-dom": "~18.2.0",
|
|
48
|
-
"@dxos/react-ui": "0.6.14-main.
|
|
49
|
-
"@dxos/react-ui-theme": "0.6.14-main.
|
|
51
|
+
"@dxos/react-ui": "0.6.14-main.8b352a0",
|
|
52
|
+
"@dxos/react-ui-theme": "0.6.14-main.8b352a0"
|
|
50
53
|
},
|
|
51
54
|
"publishConfig": {
|
|
52
55
|
"access": "public"
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { completionStatus } from '@codemirror/autocomplete';
|
|
6
6
|
import { type Extension } from '@codemirror/state';
|
|
7
7
|
import { EditorView, keymap } from '@codemirror/view';
|
|
8
|
-
import React, { type
|
|
8
|
+
import React, { type KeyboardEvent } from 'react';
|
|
9
9
|
|
|
10
10
|
import { useThemeContext } from '@dxos/react-ui';
|
|
11
11
|
import {
|
|
@@ -24,7 +24,6 @@ export type EditorKeysProps = {
|
|
|
24
24
|
onClose: (value: string | undefined, event: EditorKeyEvent) => void;
|
|
25
25
|
onNav?: (value: string | undefined, event: EditorKeyEvent) => void;
|
|
26
26
|
};
|
|
27
|
-
|
|
28
27
|
// TODO(Zan): Should each consumer be responsible for defining these?
|
|
29
28
|
export const editorKeys = ({ onNav, onClose }: EditorKeysProps): Extension => {
|
|
30
29
|
return keymap.of([
|
|
@@ -114,8 +113,7 @@ export type CellEditorProps = {
|
|
|
114
113
|
variant?: keyof typeof editorVariants;
|
|
115
114
|
box?: GridEditBox;
|
|
116
115
|
gridId?: string;
|
|
117
|
-
} & Pick<UseTextEditorProps, 'autoFocus'> &
|
|
118
|
-
Pick<DOMAttributes<HTMLInputElement>, 'onBlur' | 'onKeyDown'>;
|
|
116
|
+
} & Pick<UseTextEditorProps, 'autoFocus'> & { onBlur?: (value?: string) => void };
|
|
119
117
|
|
|
120
118
|
const editorVariants = {
|
|
121
119
|
// TODO(thure): remove when legacy is no longer used.
|
|
@@ -127,7 +125,8 @@ const editorVariants = {
|
|
|
127
125
|
grid: {
|
|
128
126
|
root: 'absolute z-[1]',
|
|
129
127
|
editor: '[&>.cm-scroller]:scrollbar-none tabular-nums',
|
|
130
|
-
|
|
128
|
+
// This must match cell styling in `dx-grid.pcss`.
|
|
129
|
+
content: '!border !border-transparent !pli-[3px] !plb-0.5',
|
|
131
130
|
},
|
|
132
131
|
};
|
|
133
132
|
|
|
@@ -149,9 +148,9 @@ export const CellEditor = ({
|
|
|
149
148
|
extensions: [
|
|
150
149
|
extension ?? [],
|
|
151
150
|
preventNewline,
|
|
152
|
-
EditorView.focusChangeEffect.of((
|
|
151
|
+
EditorView.focusChangeEffect.of((state, focusing) => {
|
|
153
152
|
if (!focusing) {
|
|
154
|
-
onBlur?.(
|
|
153
|
+
onBlur?.(state.doc.toString());
|
|
155
154
|
}
|
|
156
155
|
return null;
|
|
157
156
|
}),
|
|
@@ -10,9 +10,12 @@ import { type GridScopedProps, useGridContext } from '../Grid';
|
|
|
10
10
|
export const GridCellEditor = ({
|
|
11
11
|
extension,
|
|
12
12
|
getCellContent,
|
|
13
|
+
onBlur,
|
|
13
14
|
__gridScope,
|
|
14
|
-
}: GridScopedProps<
|
|
15
|
-
|
|
15
|
+
}: GridScopedProps<
|
|
16
|
+
Pick<CellEditorProps, 'extension' | 'onBlur'> & { getCellContent: (index: string) => string | undefined }
|
|
17
|
+
>) => {
|
|
18
|
+
const { id, editing, editBox } = useGridContext('GridSheetCellEditor', __gridScope);
|
|
16
19
|
|
|
17
20
|
return editing ? (
|
|
18
21
|
<CellEditor
|
|
@@ -20,7 +23,7 @@ export const GridCellEditor = ({
|
|
|
20
23
|
value={editing.initialContent ?? getCellContent(editing.index)}
|
|
21
24
|
autoFocus
|
|
22
25
|
box={editBox}
|
|
23
|
-
onBlur={
|
|
26
|
+
onBlur={onBlur}
|
|
24
27
|
extension={extension}
|
|
25
28
|
gridId={id}
|
|
26
29
|
/>
|
|
@@ -4,46 +4,95 @@
|
|
|
4
4
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
|
-
import * as ModalPrimitive from '@radix-ui/react-popper';
|
|
8
7
|
import { type StoryObj } from '@storybook/react';
|
|
9
|
-
import React, { type MouseEvent, useCallback, useRef, useState } from 'react';
|
|
8
|
+
import React, { type MouseEvent, type MutableRefObject, useCallback, useRef, useState } from 'react';
|
|
10
9
|
|
|
11
|
-
import {
|
|
10
|
+
import { faker } from '@dxos/random';
|
|
11
|
+
import { DropdownMenu } from '@dxos/react-ui';
|
|
12
|
+
import { PopoverCombobox } from '@dxos/react-ui-searchlist';
|
|
12
13
|
import { withTheme } from '@dxos/storybook-utils';
|
|
13
14
|
|
|
14
15
|
import { Grid, type GridContentProps, type GridRootProps } from './Grid';
|
|
15
16
|
|
|
16
17
|
type StoryGridProps = GridContentProps & Pick<GridRootProps, 'onEditingChange'>;
|
|
17
18
|
|
|
19
|
+
const storybookItems = faker.helpers.uniqueArray(faker.commerce.productName, 16);
|
|
20
|
+
|
|
21
|
+
const storybookInitialCells = (value?: string) => ({
|
|
22
|
+
grid: {
|
|
23
|
+
'1,1': {
|
|
24
|
+
accessoryHtml:
|
|
25
|
+
'<button class="ch-button is-6 pli-0.5 min-bs-0 absolute inset-block-1 inline-end-1" data-story-action="menu"><svg><use href="/icons.svg#ph--arrow-right--regular"/></svg></button>',
|
|
26
|
+
value: 'Weekly sales report',
|
|
27
|
+
},
|
|
28
|
+
'2,2': {
|
|
29
|
+
accessoryHtml: `<dx-grid-multiselect-cell ${value ? `values='${JSON.stringify([{ label: value }])}'` : ''} placeholder="Select…"></dx-grid-multiselect-cell>`,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
18
34
|
const StoryGrid = ({ onEditingChange, ...props }: StoryGridProps) => {
|
|
19
35
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
20
|
-
const
|
|
21
|
-
const
|
|
36
|
+
const [popoverOpen, setPopoverOpen] = useState(false);
|
|
37
|
+
const [multiSelectValue, setInternalMultiselectValue] = useState('');
|
|
38
|
+
const triggerRef = useRef<HTMLButtonElement>(null) as MutableRefObject<HTMLButtonElement>;
|
|
22
39
|
|
|
23
40
|
const handleClick = useCallback((event: MouseEvent) => {
|
|
24
|
-
const
|
|
25
|
-
if (
|
|
26
|
-
triggerRef.current =
|
|
27
|
-
setMenuOpen(true);
|
|
41
|
+
const closestStoryAction = (event.target as HTMLElement).closest('button[data-story-action]');
|
|
42
|
+
if (closestStoryAction) {
|
|
43
|
+
triggerRef.current = closestStoryAction as HTMLButtonElement;
|
|
44
|
+
return setMenuOpen(true);
|
|
45
|
+
}
|
|
46
|
+
const closestAccessory = (event.target as HTMLElement).closest('[data-dx-grid-accessory]');
|
|
47
|
+
if (closestAccessory) {
|
|
48
|
+
const action = closestAccessory.getAttribute('data-dx-grid-accessory');
|
|
49
|
+
switch (action) {
|
|
50
|
+
case 'invoke-multiselect':
|
|
51
|
+
triggerRef.current = closestAccessory as HTMLButtonElement;
|
|
52
|
+
return setPopoverOpen(true);
|
|
53
|
+
}
|
|
28
54
|
}
|
|
29
55
|
}, []);
|
|
30
56
|
|
|
57
|
+
const [initialCells, setInitialCells] = useState<GridContentProps['initialCells']>(storybookInitialCells());
|
|
58
|
+
|
|
59
|
+
const setMultiselectValue = useCallback((nextValue: string) => {
|
|
60
|
+
const nextInitialCells = storybookInitialCells(nextValue);
|
|
61
|
+
console.log('[set initial cells]', nextInitialCells);
|
|
62
|
+
setInitialCells(nextInitialCells);
|
|
63
|
+
setInternalMultiselectValue(nextValue);
|
|
64
|
+
}, []);
|
|
65
|
+
|
|
31
66
|
return (
|
|
32
|
-
|
|
33
|
-
<ModalPrimitive.Root>
|
|
67
|
+
<>
|
|
34
68
|
<Grid.Root id='story' onEditingChange={onEditingChange}>
|
|
35
|
-
<Grid.Content {...props} onClick={handleClick} />
|
|
69
|
+
<Grid.Content {...props} initialCells={initialCells} onClick={handleClick} />
|
|
36
70
|
</Grid.Root>
|
|
37
|
-
<ModalPrimitive.Anchor virtualRef={triggerRef} />
|
|
38
71
|
<DropdownMenu.Root open={menuOpen} onOpenChange={setMenuOpen}>
|
|
39
|
-
<DropdownMenu.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
</ModalPrimitive.Content>
|
|
72
|
+
<DropdownMenu.VirtualTrigger virtualRef={triggerRef} />
|
|
73
|
+
<DropdownMenu.Content>
|
|
74
|
+
<DropdownMenu.Item onClick={() => console.log('[Click on dropdown menu item]')}>Hello</DropdownMenu.Item>
|
|
75
|
+
<DropdownMenu.Arrow />
|
|
44
76
|
</DropdownMenu.Content>
|
|
45
77
|
</DropdownMenu.Root>
|
|
46
|
-
|
|
78
|
+
<PopoverCombobox.Root
|
|
79
|
+
open={popoverOpen}
|
|
80
|
+
onOpenChange={setPopoverOpen}
|
|
81
|
+
value={multiSelectValue}
|
|
82
|
+
onValueChange={setMultiselectValue}
|
|
83
|
+
>
|
|
84
|
+
<PopoverCombobox.VirtualTrigger virtualRef={triggerRef} />
|
|
85
|
+
<PopoverCombobox.Content filter={(value, search) => (value.includes(search) ? 1 : 0)}>
|
|
86
|
+
<PopoverCombobox.Input placeholder='Search...' />
|
|
87
|
+
<PopoverCombobox.List>
|
|
88
|
+
{storybookItems.map((value) => (
|
|
89
|
+
<PopoverCombobox.Item key={value}>{value}</PopoverCombobox.Item>
|
|
90
|
+
))}
|
|
91
|
+
</PopoverCombobox.List>
|
|
92
|
+
<PopoverCombobox.Arrow />
|
|
93
|
+
</PopoverCombobox.Content>
|
|
94
|
+
</PopoverCombobox.Root>
|
|
95
|
+
</>
|
|
47
96
|
);
|
|
48
97
|
};
|
|
49
98
|
|
|
@@ -57,15 +106,6 @@ export default {
|
|
|
57
106
|
export const Basic: StoryObj<StoryGridProps> = {
|
|
58
107
|
args: {
|
|
59
108
|
id: 'story',
|
|
60
|
-
initialCells: {
|
|
61
|
-
grid: {
|
|
62
|
-
'1,1': {
|
|
63
|
-
accessoryHtml:
|
|
64
|
-
'<button class="ch-button is-6 pli-0.5 min-bs-0 absolute inset-block-1 inline-end-1" data-story-action="menu"><svg><use href="/icons.svg#ph--arrow-right--regular"/></svg></button>',
|
|
65
|
-
value: 'Weekly sales report',
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
109
|
columnDefault: {
|
|
70
110
|
grid: {
|
|
71
111
|
size: 180,
|
package/src/Grid/Grid.tsx
CHANGED
|
@@ -12,12 +12,11 @@ import React, {
|
|
|
12
12
|
forwardRef,
|
|
13
13
|
type PropsWithChildren,
|
|
14
14
|
useCallback,
|
|
15
|
-
|
|
15
|
+
useEffect,
|
|
16
16
|
useState,
|
|
17
17
|
} from 'react';
|
|
18
18
|
|
|
19
19
|
import { type DxAxisResize, type DxEditRequest, type DxGridCellsSelect, DxGrid as NaturalDxGrid } from '@dxos/lit-grid';
|
|
20
|
-
import { useForwardedRef } from '@dxos/react-ui';
|
|
21
20
|
|
|
22
21
|
type DxGridElement = NaturalDxGrid;
|
|
23
22
|
|
|
@@ -99,28 +98,43 @@ GridRoot.displayName = GRID_NAME;
|
|
|
99
98
|
|
|
100
99
|
type GridContentProps = Omit<ComponentProps<typeof DxGrid>, 'onEdit'> & {
|
|
101
100
|
getCells?: NonNullable<NaturalDxGrid['getCells']>;
|
|
101
|
+
activeRefs?: string;
|
|
102
102
|
};
|
|
103
103
|
|
|
104
104
|
const GRID_CONTENT_NAME = 'GridContent';
|
|
105
105
|
|
|
106
106
|
const GridContent = forwardRef<NaturalDxGrid, GridScopedProps<GridContentProps>>((props, forwardedRef) => {
|
|
107
107
|
const { id, editing, setEditBox, setEditing } = useGridContext(GRID_CONTENT_NAME, props.__gridScope);
|
|
108
|
-
const dxGrid =
|
|
108
|
+
const [dxGrid, setDxGridInternal] = useState<NaturalDxGrid | null>(null);
|
|
109
|
+
|
|
110
|
+
// NOTE(thure): using `useState` instead of `useRef` works with refs provided by `@lit/react` and gives us a reliable dependency for `useEffect` whereas `useLayoutEffect` does not guarantee the element will be defined.
|
|
111
|
+
const setDxGrid = useCallback(
|
|
112
|
+
(nextDxGrid: NaturalDxGrid | null) => {
|
|
113
|
+
setDxGridInternal(nextDxGrid);
|
|
114
|
+
if (forwardedRef) {
|
|
115
|
+
if (typeof forwardedRef === 'function') {
|
|
116
|
+
forwardedRef?.(nextDxGrid);
|
|
117
|
+
} else {
|
|
118
|
+
forwardedRef.current = nextDxGrid;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
[forwardedRef, dxGrid],
|
|
123
|
+
);
|
|
109
124
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
dxGrid.
|
|
114
|
-
dxGrid.current.requestUpdate('initialCells');
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
if (dxGrid && props.getCells) {
|
|
127
|
+
dxGrid.getCells = props.getCells;
|
|
128
|
+
dxGrid.requestUpdate('initialCells');
|
|
115
129
|
}
|
|
116
|
-
}, [props.getCells]);
|
|
130
|
+
}, [props.getCells, dxGrid]);
|
|
117
131
|
|
|
118
132
|
const handleEdit = useCallback((event: DxEditRequest) => {
|
|
119
133
|
setEditBox(event.cellBox);
|
|
120
134
|
setEditing({ index: event.cellIndex, initialContent: event.initialContent });
|
|
121
135
|
}, []);
|
|
122
136
|
|
|
123
|
-
return <DxGrid {...props} gridId={id} mode={editing ? 'edit' : 'browse'} onEdit={handleEdit} ref={
|
|
137
|
+
return <DxGrid {...props} gridId={id} mode={editing ? 'edit' : 'browse'} onEdit={handleEdit} ref={setDxGrid} />;
|
|
124
138
|
});
|
|
125
139
|
|
|
126
140
|
GridContent.displayName = GRID_CONTENT_NAME;
|
|
@@ -134,7 +148,7 @@ export { GridRoot, GridContent, useGridContext, createGridScope };
|
|
|
134
148
|
|
|
135
149
|
export type { GridRootProps, GridContentProps, GridEditing, GridEditBox, GridScopedProps, DxGridElement };
|
|
136
150
|
|
|
137
|
-
export { colToA1Notation, rowToA1Notation, closestCell } from '@dxos/lit-grid';
|
|
151
|
+
export { colToA1Notation, rowToA1Notation, closestCell, commentedClassName } from '@dxos/lit-grid';
|
|
138
152
|
|
|
139
153
|
export type {
|
|
140
154
|
DxGridRange,
|