@dxos/react-ui-grid 0.6.12-main.5cc132e → 0.6.12-main.c974201

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.
@@ -1,17 +1,18 @@
1
1
  // packages/ui/react-ui-grid/src/Grid.tsx
2
2
  import "@dxos/lit-grid/dx-grid.pcss";
3
3
  import { createComponent } from "@lit/react";
4
- import React, { useCallback, useRef, useState } from "react";
4
+ import { createContextScope } from "@radix-ui/react-context";
5
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
6
+ import React, { forwardRef, useCallback, useState } from "react";
5
7
  import { DxGrid as NaturalDxGrid } from "@dxos/lit-grid";
6
- import { listener, useTextEditor } from "@dxos/react-ui-editor";
7
- import { isNotFalsy } from "@dxos/util";
8
8
  var DxGrid = createComponent({
9
9
  tagName: "dx-grid",
10
10
  elementClass: NaturalDxGrid,
11
11
  react: React,
12
12
  events: {
13
13
  onAxisResize: "dx-axis-resize",
14
- onEdit: "dx-edit-request"
14
+ onEdit: "dx-edit-request",
15
+ onSelect: "dx-grid-cells-select"
15
16
  }
16
17
  });
17
18
  var initialBox = {
@@ -20,63 +21,54 @@ var initialBox = {
20
21
  inlineSize: 0,
21
22
  blockSize: 0
22
23
  };
23
- var Grid = (props) => {
24
- const gridRef = useRef(null);
24
+ var GRID_NAME = "Grid";
25
+ var [createGridContext, createGridScope] = createContextScope(GRID_NAME, []);
26
+ var [GridProvider, useGridContext] = createGridContext(GRID_NAME);
27
+ var GridRoot = ({ id, editing: propsEditing, defaultEditing, onEditingChange, children, __gridScope }) => {
28
+ const [editing = null, setEditing] = useControllableState({
29
+ prop: propsEditing,
30
+ defaultProp: defaultEditing,
31
+ onChange: onEditingChange
32
+ });
25
33
  const [editBox, setEditBox] = useState(initialBox);
26
- const [editing, setEditing] = useState(null);
27
- const { parentRef: textboxRef, focusAttributes, view } = useTextEditor(() => ({
28
- id: props.id,
29
- autoFocus: !!editing,
30
- extensions: [
31
- listener({
32
- onFocus: (focusing) => {
33
- if (!focusing && editing) {
34
- setEditing(null);
35
- }
36
- }
37
- })
38
- ].filter(isNotFalsy)
39
- }), [
40
- editing
41
- ]);
34
+ return /* @__PURE__ */ React.createElement(GridProvider, {
35
+ id,
36
+ editing,
37
+ setEditing,
38
+ editBox,
39
+ setEditBox,
40
+ scope: __gridScope
41
+ }, children);
42
+ };
43
+ GridRoot.displayName = GRID_NAME;
44
+ var GRID_CONTENT_NAME = "GridContent";
45
+ var GridContent = /* @__PURE__ */ forwardRef((props, forwardedRef) => {
46
+ const { id, editing, setEditBox, setEditing } = useGridContext(GRID_CONTENT_NAME, props.__gridScope);
42
47
  const handleEdit = useCallback((event) => {
43
48
  setEditBox(event.cellBox);
44
- setEditing(event.cellIndex);
45
- props?.onEdit?.(event);
49
+ setEditing({
50
+ index: event.cellIndex,
51
+ initialContent: event.initialContent
52
+ });
46
53
  }, []);
47
- const handleEditorKeyDown = useCallback((event) => {
48
- if (editing) {
49
- switch (event.key) {
50
- case "Enter":
51
- setEditing(null);
52
- gridRef.current?.refocus("down");
53
- break;
54
- case "Escape":
55
- setEditing(null);
56
- gridRef.current?.refocus();
57
- break;
58
- }
59
- }
60
- }, [
61
- editing,
62
- view
63
- ]);
64
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", {
65
- className: "absolute z-[1] hidden data-[editing=true]:block border p-px border-accentSurface",
66
- "data-editing": !!editing,
67
- ...focusAttributes,
68
- style: editBox,
69
- tabIndex: editing ? 0 : -1,
70
- onKeyDown: handleEditorKeyDown,
71
- ref: textboxRef
72
- }), /* @__PURE__ */ React.createElement(DxGrid, {
54
+ return /* @__PURE__ */ React.createElement(DxGrid, {
73
55
  ...props,
56
+ gridId: id,
74
57
  mode: editing ? "edit" : "browse",
75
58
  onEdit: handleEdit,
76
- ref: gridRef
77
- }));
59
+ ref: forwardedRef
60
+ });
61
+ });
62
+ GridContent.displayName = GRID_CONTENT_NAME;
63
+ var Grid = {
64
+ Root: GridRoot,
65
+ Content: GridContent
78
66
  };
79
67
  export {
80
- Grid
68
+ Grid,
69
+ GridContent,
70
+ GridRoot,
71
+ createGridScope,
72
+ useGridContext
81
73
  };
82
74
  //# sourceMappingURL=index.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/Grid.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 React, { type KeyboardEvent, useCallback, useRef, useState } from 'react';\n\nimport { type DxAxisResize, type DxEditRequest, DxGrid as NaturalDxGrid, type DxGridProps } from '@dxos/lit-grid';\nimport { listener, useTextEditor } from '@dxos/react-ui-editor';\nimport { isNotFalsy } from '@dxos/util';\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 },\n});\n\nexport type GridProps = DxGridProps & {\n id: string;\n onAxisResize: (event: DxAxisResize) => void;\n onEdit: (event: DxEditRequest) => void;\n};\n\nconst initialBox = {\n insetInlineStart: 0,\n insetBlockStart: 0,\n inlineSize: 0,\n blockSize: 0,\n} satisfies DxEditRequest['cellBox'];\n\nexport const Grid = (props: GridProps) => {\n const gridRef = useRef<NaturalDxGrid | null>(null);\n const [editBox, setEditBox] = useState<DxEditRequest['cellBox']>(initialBox);\n const [editing, setEditing] = useState<DxEditRequest['cellIndex'] | null>(null);\n\n const {\n parentRef: textboxRef,\n focusAttributes,\n view,\n } = useTextEditor(\n () => ({\n id: props.id,\n autoFocus: !!editing,\n extensions: [\n listener({\n onFocus: (focusing: boolean) => {\n if (!focusing && editing) {\n setEditing(null);\n }\n },\n }),\n ].filter(isNotFalsy),\n }),\n [editing],\n );\n\n const handleEdit = useCallback((event: DxEditRequest) => {\n setEditBox(event.cellBox);\n setEditing(event.cellIndex);\n props?.onEdit?.(event);\n }, []);\n\n const handleEditorKeyDown = useCallback(\n (event: KeyboardEvent) => {\n if (editing) {\n switch (event.key) {\n case 'Enter':\n // console.warn('to do: save content');\n setEditing(null);\n gridRef.current?.refocus('down');\n break;\n case 'Escape':\n setEditing(null);\n gridRef.current?.refocus();\n break;\n }\n }\n },\n [editing, view],\n );\n\n return (\n <>\n <div\n className='absolute z-[1] hidden data-[editing=true]:block border p-px border-accentSurface'\n data-editing={!!editing}\n {...focusAttributes}\n style={editBox}\n tabIndex={editing ? 0 : -1}\n onKeyDown={handleEditorKeyDown}\n ref={textboxRef}\n />\n <DxGrid {...props} mode={editing ? 'edit' : 'browse'} onEdit={handleEdit} ref={gridRef} />\n </>\n );\n};\n"],
5
- "mappings": ";AAIA,OAAO;AAEP,SAASA,uBAAuC;AAChD,OAAOC,SAA6BC,aAAaC,QAAQC,gBAAgB;AAEzE,SAAgDC,UAAUC,qBAAuC;AACjG,SAASC,UAAUC,qBAAqB;AACxC,SAASC,kBAAkB;AAE3B,IAAMC,SAASC,gBAAgB;EAC7BC,SAAS;EACTC,cAAcC;EACdC,OAAOC;EACPC,QAAQ;IACNC,cAAc;IACdC,QAAQ;EACV;AACF,CAAA;AAQA,IAAMC,aAAa;EACjBC,kBAAkB;EAClBC,iBAAiB;EACjBC,YAAY;EACZC,WAAW;AACb;AAEO,IAAMC,OAAO,CAACC,UAAAA;AACnB,QAAMC,UAAUC,OAA6B,IAAA;AAC7C,QAAM,CAACC,SAASC,UAAAA,IAAcC,SAAmCX,UAAAA;AACjE,QAAM,CAACY,SAASC,UAAAA,IAAcF,SAA4C,IAAA;AAE1E,QAAM,EACJG,WAAWC,YACXC,iBACAC,KAAI,IACFC,cACF,OAAO;IACLC,IAAIb,MAAMa;IACVC,WAAW,CAAC,CAACR;IACbS,YAAY;MACVC,SAAS;QACPC,SAAS,CAACC,aAAAA;AACR,cAAI,CAACA,YAAYZ,SAAS;AACxBC,uBAAW,IAAA;UACb;QACF;MACF,CAAA;MACAY,OAAOC,UAAAA;EACX,IACA;IAACd;GAAQ;AAGX,QAAMe,aAAaC,YAAY,CAACC,UAAAA;AAC9BnB,eAAWmB,MAAMC,OAAO;AACxBjB,eAAWgB,MAAME,SAAS;AAC1BzB,WAAOP,SAAS8B,KAAAA;EAClB,GAAG,CAAA,CAAE;AAEL,QAAMG,sBAAsBJ,YAC1B,CAACC,UAAAA;AACC,QAAIjB,SAAS;AACX,cAAQiB,MAAMI,KAAG;QACf,KAAK;AAEHpB,qBAAW,IAAA;AACXN,kBAAQ2B,SAASC,QAAQ,MAAA;AACzB;QACF,KAAK;AACHtB,qBAAW,IAAA;AACXN,kBAAQ2B,SAASC,QAAAA;AACjB;MACJ;IACF;EACF,GACA;IAACvB;IAASK;GAAK;AAGjB,SACE,sBAAA,cAAA,MAAA,UAAA,MACE,sBAAA,cAACmB,OAAAA;IACCC,WAAU;IACVC,gBAAc,CAAC,CAAC1B;IACf,GAAGI;IACJuB,OAAO9B;IACP+B,UAAU5B,UAAU,IAAI;IACxB6B,WAAWT;IACXU,KAAK3B;MAEP,sBAAA,cAACzB,QAAAA;IAAQ,GAAGgB;IAAOqC,MAAM/B,UAAU,SAAS;IAAUb,QAAQ4B;IAAYe,KAAKnC;;AAGrF;",
6
- "names": ["createComponent", "React", "useCallback", "useRef", "useState", "DxGrid", "NaturalDxGrid", "listener", "useTextEditor", "isNotFalsy", "DxGrid", "createComponent", "tagName", "elementClass", "NaturalDxGrid", "react", "React", "events", "onAxisResize", "onEdit", "initialBox", "insetInlineStart", "insetBlockStart", "inlineSize", "blockSize", "Grid", "props", "gridRef", "useRef", "editBox", "setEditBox", "useState", "editing", "setEditing", "parentRef", "textboxRef", "focusAttributes", "view", "useTextEditor", "id", "autoFocus", "extensions", "listener", "onFocus", "focusing", "filter", "isNotFalsy", "handleEdit", "useCallback", "event", "cellBox", "cellIndex", "handleEditorKeyDown", "key", "current", "refocus", "div", "className", "data-editing", "style", "tabIndex", "onKeyDown", "ref", "mode"]
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, { type ComponentProps, forwardRef, type PropsWithChildren, useCallback, useState } 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\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\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={forwardedRef} />;\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"],
5
+ "mappings": ";AAIA,OAAO;AAEP,SAASA,uBAAuC;AAChD,SAASC,0BAAsC;AAC/C,SAASC,4BAA4B;AACrC,OAAOC,SAA8BC,YAAoCC,aAAaC,gBAAgB;AAEtG,SAAwEC,UAAUC,qBAAqB;AAIvG,IAAMC,SAASC,gBAAgB;EAC7BC,SAAS;EACTC,cAAcC;EACdC,OAAOC;EACPC,QAAQ;IACNC,cAAc;IACdC,QAAQ;IACRC,UAAU;EACZ;AACF,CAAA;AAIA,IAAMC,aAAa;EACjBC,kBAAkB;EAClBC,iBAAiB;EACjBC,YAAY;EACZC,WAAW;AACb;AAcA,IAAMC,YAAY;AAElB,IAAM,CAACC,mBAAmBC,eAAAA,IAAmBC,mBAAmBH,WAAW,CAAA,CAAE;AAE7E,IAAM,CAACI,cAAcC,cAAAA,IAAkBJ,kBAAoCD,SAAAA;AAU3E,IAAMM,WAAW,CAAC,EAChBC,IACAC,SAASC,cACTC,gBACAC,iBACAC,UACAC,YAAW,MACoB;AAC/B,QAAM,CAACL,UAAU,MAAMM,UAAAA,IAAcC,qBAAqB;IACxDC,MAAMP;IACNQ,aAAaP;IACbQ,UAAUP;EACZ,CAAA;AACA,QAAM,CAACQ,SAASC,UAAAA,IAAcC,SAAsB1B,UAAAA;AACpD,SACE,sBAAA,cAACS,cAAAA;IACCG;IACAC;IACAM;IACAK;IACAC;IACAE,OAAOT;KAEND,QAAAA;AAGP;AAEAN,SAASiB,cAAcvB;AAIvB,IAAMwB,oBAAoB;AAE1B,IAAMC,cAAcC,2BAA6D,CAACC,OAAOC,iBAAAA;AACvF,QAAM,EAAErB,IAAIC,SAASY,YAAYN,WAAU,IAAKT,eAAemB,mBAAmBG,MAAMd,WAAW;AAEnG,QAAMgB,aAAaC,YAAY,CAACC,UAAAA;AAC9BX,eAAWW,MAAMC,OAAO;AACxBlB,eAAW;MAAEmB,OAAOF,MAAMG;MAAWC,gBAAgBJ,MAAMI;IAAe,CAAA;EAC5E,GAAG,CAAA,CAAE;AAEL,SAAO,sBAAA,cAACnD,QAAAA;IAAQ,GAAG2C;IAAOS,QAAQ7B;IAAI8B,MAAM7B,UAAU,SAAS;IAAUf,QAAQoC;IAAYS,KAAKV;;AACpG,CAAA;AAEAH,YAAYF,cAAcC;AAEnB,IAAMe,OAAO;EAClBC,MAAMlC;EACNmC,SAAShB;AACX;",
6
+ "names": ["createComponent", "createContextScope", "useControllableState", "React", "forwardRef", "useCallback", "useState", "DxGrid", "NaturalDxGrid", "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", "handleEdit", "useCallback", "event", "cellBox", "index", "cellIndex", "initialContent", "gridId", "mode", "ref", "Grid", "Root", "Content"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/ui/react-ui-grid/src/Grid.tsx":{"bytes":9408,"imports":[{"path":"@dxos/lit-grid/dx-grid.pcss","kind":"import-statement","external":true},{"path":"@lit/react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/lit-grid","kind":"import-statement","external":true},{"path":"@dxos/react-ui-editor","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-grid/src/index.ts":{"bytes":489,"imports":[{"path":"packages/ui/react-ui-grid/src/Grid.tsx","kind":"import-statement","original":"./Grid"}],"format":"esm"}},"outputs":{"packages/ui/react-ui-grid/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":5069},"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":"react","kind":"import-statement","external":true},{"path":"@dxos/lit-grid","kind":"import-statement","external":true},{"path":"@dxos/react-ui-editor","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["Grid"],"entryPoint":"packages/ui/react-ui-grid/src/index.ts","inputs":{"packages/ui/react-ui-grid/src/Grid.tsx":{"bytesInOutput":2142},"packages/ui/react-ui-grid/src/index.ts":{"bytesInOutput":0}},"bytes":2238}}}
1
+ {"inputs":{"packages/ui/react-ui-grid/src/Grid.tsx":{"bytes":10228,"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}],"format":"esm"},"packages/ui/react-ui-grid/src/index.ts":{"bytes":489,"imports":[{"path":"packages/ui/react-ui-grid/src/Grid.tsx","kind":"import-statement","original":"./Grid"}],"format":"esm"}},"outputs":{"packages/ui/react-ui-grid/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":5768},"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}],"exports":["Grid","GridContent","GridRoot","createGridScope","useGridContext"],"entryPoint":"packages/ui/react-ui-grid/src/index.ts","inputs":{"packages/ui/react-ui-grid/src/Grid.tsx":{"bytesInOutput":2043},"packages/ui/react-ui-grid/src/index.ts":{"bytesInOutput":0}},"bytes":2203}}}
@@ -1,10 +1,51 @@
1
1
  import '@dxos/lit-grid/dx-grid.pcss';
2
- import React from 'react';
3
- import { type DxAxisResize, type DxEditRequest, type DxGridProps } from '@dxos/lit-grid';
4
- export type GridProps = DxGridProps & {
2
+ import { type EventName } from '@lit/react';
3
+ import { type Scope } from '@radix-ui/react-context';
4
+ import React, { type ComponentProps, type PropsWithChildren } from 'react';
5
+ import { type DxAxisResize, type DxEditRequest, type DxGridCellsSelect, DxGrid as NaturalDxGrid } from '@dxos/lit-grid';
6
+ type DxGridElement = NaturalDxGrid;
7
+ declare const DxGrid: import("@lit/react").ReactWebComponent<NaturalDxGrid, {
8
+ onAxisResize: EventName<DxAxisResize>;
9
+ onEdit: EventName<DxEditRequest>;
10
+ onSelect: EventName<DxGridCellsSelect>;
11
+ }>;
12
+ type GridEditBox = DxEditRequest['cellBox'];
13
+ type GridEditing = {
14
+ index: DxEditRequest['cellIndex'];
15
+ initialContent: DxEditRequest['initialContent'];
16
+ } | null;
17
+ type GridContextValue = {
5
18
  id: string;
6
- onAxisResize: (event: DxAxisResize) => void;
7
- onEdit: (event: DxEditRequest) => void;
19
+ editing: GridEditing;
20
+ setEditing: (nextEditing: GridEditing) => void;
21
+ editBox: GridEditBox;
22
+ setEditBox: (nextEditBox: GridEditBox) => void;
8
23
  };
9
- export declare const Grid: (props: GridProps) => React.JSX.Element;
24
+ type GridScopedProps<P> = P & {
25
+ __gridScope?: Scope;
26
+ };
27
+ declare const createGridScope: import("@radix-ui/react-context").CreateScope;
28
+ declare const useGridContext: (consumerName: string, scope: Scope<GridContextValue | undefined>) => GridContextValue;
29
+ type GridRootProps = PropsWithChildren<{
30
+ id: string;
31
+ } & Partial<{
32
+ editing: GridEditing;
33
+ defaultEditing: GridEditing;
34
+ onEditingChange: (nextEditing: GridEditing) => void;
35
+ }>>;
36
+ declare const GridRoot: {
37
+ ({ id, editing: propsEditing, defaultEditing, onEditingChange, children, __gridScope, }: GridScopedProps<GridRootProps>): React.JSX.Element;
38
+ displayName: string;
39
+ };
40
+ type GridContentProps = Omit<ComponentProps<typeof DxGrid>, 'onEdit'>;
41
+ declare const GridContent: React.ForwardRefExoticComponent<Omit<GridScopedProps<GridContentProps>, "ref"> & React.RefAttributes<NaturalDxGrid>>;
42
+ export declare const Grid: {
43
+ Root: {
44
+ ({ id, editing: propsEditing, defaultEditing, onEditingChange, children, __gridScope, }: GridScopedProps<GridRootProps>): React.JSX.Element;
45
+ displayName: string;
46
+ };
47
+ Content: React.ForwardRefExoticComponent<Omit<GridScopedProps<GridContentProps>, "ref"> & React.RefAttributes<NaturalDxGrid>>;
48
+ };
49
+ export { GridRoot, GridContent, useGridContext, createGridScope };
50
+ export type { GridRootProps, GridContentProps, GridEditing, GridEditBox, GridScopedProps, DxGridElement };
10
51
  //# sourceMappingURL=Grid.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Grid.d.ts","sourceRoot":"","sources":["../../../src/Grid.tsx"],"names":[],"mappings":"AAIA,OAAO,6BAA6B,CAAC;AAGrC,OAAO,KAA4D,MAAM,OAAO,CAAC;AAEjF,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAA2B,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAclH,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAC5C,MAAM,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CACxC,CAAC;AASF,eAAO,MAAM,IAAI,UAAW,SAAS,sBAiEpC,CAAC"}
1
+ {"version":3,"file":"Grid.d.ts","sourceRoot":"","sources":["../../../src/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,EAAE,KAAK,cAAc,EAAc,KAAK,iBAAiB,EAAyB,MAAM,OAAO,CAAC;AAE9G,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,CAAC;AAItE,QAAA,MAAM,WAAW,sHASf,CAAC;AAIH,eAAO,MAAM,IAAI;;iGAxCd,eAAe,CAAC,aAAa,CAAC;;;;CA2ChC,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"}
@@ -1,7 +1,10 @@
1
- import { type GridProps } from './Grid';
1
+ import '@dxos-theme';
2
+ import React from 'react';
3
+ import { type GridContentProps, type GridRootProps } from './Grid';
4
+ type StoryGridProps = GridContentProps & Pick<GridRootProps, 'onEditingChange'>;
2
5
  declare const _default: {
3
6
  title: string;
4
- component: (props: GridProps) => import("react").JSX.Element;
7
+ component: ({ onEditingChange, ...props }: StoryGridProps) => React.JSX.Element;
5
8
  decorators: import("@storybook/react/*").Decorator[];
6
9
  parameters: {
7
10
  layout: string;
@@ -42,7 +45,7 @@ export declare const Basic: {
42
45
  };
43
46
  };
44
47
  onAxisResize: (event: import("packages/ui/lit-grid/dist/types/src").DxAxisResize) => void;
45
- onEdit: (event: import("packages/ui/lit-grid/dist/types/src").DxEditRequest) => void;
48
+ onEditingChange: (event: import("./Grid").GridEditing) => void;
46
49
  };
47
50
  };
48
51
  //# sourceMappingURL=Grid.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Grid.stories.d.ts","sourceRoot":"","sources":["../../../src/Grid.stories.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;;;;;;;;;AAE9C,wBAKE;AAEF,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BjB,CAAC"}
1
+ {"version":3,"file":"Grid.stories.d.ts","sourceRoot":"","sources":["../../../src/Grid.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAQ,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEzE,KAAK,cAAc,GAAG,gBAAgB,GAAG,IAAI,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;;;+CAE9B,cAAc;;;;;;AAQhE,wBAKE;AAEF,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BjB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-grid",
3
- "version": "0.6.12-main.5cc132e",
3
+ "version": "0.6.12-main.c974201",
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",
@@ -22,11 +22,12 @@
22
22
  ],
23
23
  "dependencies": {
24
24
  "@lit/react": "^1.0.5",
25
- "@dxos/lit-grid": "0.6.12-main.5cc132e",
26
- "@dxos/react-ui": "0.6.12-main.5cc132e",
27
- "@dxos/react-ui-theme": "0.6.12-main.5cc132e",
28
- "@dxos/react-ui-editor": "0.6.12-main.5cc132e",
29
- "@dxos/util": "0.6.12-main.5cc132e"
25
+ "@radix-ui/react-context": "^1.0.0",
26
+ "@radix-ui/react-use-controllable-state": "^1.0.0",
27
+ "@dxos/lit-grid": "0.6.12-main.c974201",
28
+ "@dxos/react-ui": "0.6.12-main.c974201",
29
+ "@dxos/react-ui-theme": "0.6.12-main.c974201",
30
+ "@dxos/util": "0.6.12-main.c974201"
30
31
  },
31
32
  "devDependencies": {
32
33
  "@types/react": "~18.2.0",
@@ -34,11 +35,11 @@
34
35
  "react": "~18.2.0",
35
36
  "react-dom": "~18.2.0",
36
37
  "vite": "5.4.7",
37
- "@dxos/storybook-utils": "0.6.12-main.5cc132e"
38
+ "@dxos/storybook-utils": "0.6.12-main.c974201"
38
39
  },
39
40
  "peerDependencies": {
40
- "react": "^18.0.0",
41
- "react-dom": "^18.0.0"
41
+ "react": "~18.2.0",
42
+ "react-dom": "~18.2.0"
42
43
  },
43
44
  "publishConfig": {
44
45
  "access": "public"
@@ -2,13 +2,27 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import '@dxos-theme';
6
+
7
+ import React from 'react';
8
+
5
9
  import { withTheme } from '@dxos/storybook-utils';
6
10
 
7
- import { Grid, type GridProps } from './Grid';
11
+ import { Grid, type GridContentProps, type GridRootProps } from './Grid';
12
+
13
+ type StoryGridProps = GridContentProps & Pick<GridRootProps, 'onEditingChange'>;
14
+
15
+ const StoryGrid = ({ onEditingChange, ...props }: StoryGridProps) => {
16
+ return (
17
+ <Grid.Root id='story' onEditingChange={onEditingChange}>
18
+ <Grid.Content {...props} />
19
+ </Grid.Root>
20
+ );
21
+ };
8
22
 
9
23
  export default {
10
24
  title: 'react-ui-grid/Grid',
11
- component: Grid,
25
+ component: StoryGrid,
12
26
  decorators: [withTheme],
13
27
  parameters: { layout: 'fullscreen' },
14
28
  };
@@ -40,8 +54,8 @@ export const Basic = {
40
54
  onAxisResize: (event) => {
41
55
  console.log('[axis resize]', event);
42
56
  },
43
- onEdit: (event) => {
57
+ onEditingChange: (event) => {
44
58
  console.log('[edit]', event);
45
59
  },
46
- } satisfies GridProps,
60
+ } satisfies StoryGridProps,
47
61
  };
package/src/Grid.tsx CHANGED
@@ -5,11 +5,13 @@
5
5
  import '@dxos/lit-grid/dx-grid.pcss';
6
6
 
7
7
  import { createComponent, type EventName } from '@lit/react';
8
- import React, { type KeyboardEvent, useCallback, useRef, useState } from 'react';
8
+ import { createContextScope, type Scope } from '@radix-ui/react-context';
9
+ import { useControllableState } from '@radix-ui/react-use-controllable-state';
10
+ import React, { type ComponentProps, forwardRef, type PropsWithChildren, useCallback, useState } from 'react';
9
11
 
10
- import { type DxAxisResize, type DxEditRequest, DxGrid as NaturalDxGrid, type DxGridProps } from '@dxos/lit-grid';
11
- import { listener, useTextEditor } from '@dxos/react-ui-editor';
12
- import { isNotFalsy } from '@dxos/util';
12
+ import { type DxAxisResize, type DxEditRequest, type DxGridCellsSelect, DxGrid as NaturalDxGrid } from '@dxos/lit-grid';
13
+
14
+ type DxGridElement = NaturalDxGrid;
13
15
 
14
16
  const DxGrid = createComponent({
15
17
  tagName: 'dx-grid',
@@ -18,85 +20,97 @@ const DxGrid = createComponent({
18
20
  events: {
19
21
  onAxisResize: 'dx-axis-resize' as EventName<DxAxisResize>,
20
22
  onEdit: 'dx-edit-request' as EventName<DxEditRequest>,
23
+ onSelect: 'dx-grid-cells-select' as EventName<DxGridCellsSelect>,
21
24
  },
22
25
  });
23
26
 
24
- export type GridProps = DxGridProps & {
25
- id: string;
26
- onAxisResize: (event: DxAxisResize) => void;
27
- onEdit: (event: DxEditRequest) => void;
28
- };
27
+ type GridEditBox = DxEditRequest['cellBox'];
29
28
 
30
29
  const initialBox = {
31
30
  insetInlineStart: 0,
32
31
  insetBlockStart: 0,
33
32
  inlineSize: 0,
34
33
  blockSize: 0,
35
- } satisfies DxEditRequest['cellBox'];
36
-
37
- export const Grid = (props: GridProps) => {
38
- const gridRef = useRef<NaturalDxGrid | null>(null);
39
- const [editBox, setEditBox] = useState<DxEditRequest['cellBox']>(initialBox);
40
- const [editing, setEditing] = useState<DxEditRequest['cellIndex'] | null>(null);
41
-
42
- const {
43
- parentRef: textboxRef,
44
- focusAttributes,
45
- view,
46
- } = useTextEditor(
47
- () => ({
48
- id: props.id,
49
- autoFocus: !!editing,
50
- extensions: [
51
- listener({
52
- onFocus: (focusing: boolean) => {
53
- if (!focusing && editing) {
54
- setEditing(null);
55
- }
56
- },
57
- }),
58
- ].filter(isNotFalsy),
59
- }),
60
- [editing],
34
+ } satisfies GridEditBox;
35
+
36
+ type GridEditing = { index: DxEditRequest['cellIndex']; initialContent: DxEditRequest['initialContent'] } | null;
37
+
38
+ type GridContextValue = {
39
+ id: string;
40
+ editing: GridEditing;
41
+ setEditing: (nextEditing: GridEditing) => void;
42
+ editBox: GridEditBox;
43
+ setEditBox: (nextEditBox: GridEditBox) => void;
44
+ };
45
+
46
+ type GridScopedProps<P> = P & { __gridScope?: Scope };
47
+
48
+ const GRID_NAME = 'Grid';
49
+
50
+ const [createGridContext, createGridScope] = createContextScope(GRID_NAME, []);
51
+
52
+ const [GridProvider, useGridContext] = createGridContext<GridContextValue>(GRID_NAME);
53
+
54
+ type GridRootProps = PropsWithChildren<
55
+ { id: string } & Partial<{
56
+ editing: GridEditing;
57
+ defaultEditing: GridEditing;
58
+ onEditingChange: (nextEditing: GridEditing) => void;
59
+ }>
60
+ >;
61
+
62
+ const GridRoot = ({
63
+ id,
64
+ editing: propsEditing,
65
+ defaultEditing,
66
+ onEditingChange,
67
+ children,
68
+ __gridScope,
69
+ }: GridScopedProps<GridRootProps>) => {
70
+ const [editing = null, setEditing] = useControllableState({
71
+ prop: propsEditing,
72
+ defaultProp: defaultEditing,
73
+ onChange: onEditingChange,
74
+ });
75
+ const [editBox, setEditBox] = useState<GridEditBox>(initialBox);
76
+ return (
77
+ <GridProvider
78
+ id={id}
79
+ editing={editing}
80
+ setEditing={setEditing}
81
+ editBox={editBox}
82
+ setEditBox={setEditBox}
83
+ scope={__gridScope}
84
+ >
85
+ {children}
86
+ </GridProvider>
61
87
  );
88
+ };
89
+
90
+ GridRoot.displayName = GRID_NAME;
91
+
92
+ type GridContentProps = Omit<ComponentProps<typeof DxGrid>, 'onEdit'>;
93
+
94
+ const GRID_CONTENT_NAME = 'GridContent';
95
+
96
+ const GridContent = forwardRef<NaturalDxGrid, GridScopedProps<GridContentProps>>((props, forwardedRef) => {
97
+ const { id, editing, setEditBox, setEditing } = useGridContext(GRID_CONTENT_NAME, props.__gridScope);
62
98
 
63
99
  const handleEdit = useCallback((event: DxEditRequest) => {
64
100
  setEditBox(event.cellBox);
65
- setEditing(event.cellIndex);
66
- props?.onEdit?.(event);
101
+ setEditing({ index: event.cellIndex, initialContent: event.initialContent });
67
102
  }, []);
68
103
 
69
- const handleEditorKeyDown = useCallback(
70
- (event: KeyboardEvent) => {
71
- if (editing) {
72
- switch (event.key) {
73
- case 'Enter':
74
- // console.warn('to do: save content');
75
- setEditing(null);
76
- gridRef.current?.refocus('down');
77
- break;
78
- case 'Escape':
79
- setEditing(null);
80
- gridRef.current?.refocus();
81
- break;
82
- }
83
- }
84
- },
85
- [editing, view],
86
- );
104
+ return <DxGrid {...props} gridId={id} mode={editing ? 'edit' : 'browse'} onEdit={handleEdit} ref={forwardedRef} />;
105
+ });
87
106
 
88
- return (
89
- <>
90
- <div
91
- className='absolute z-[1] hidden data-[editing=true]:block border p-px border-accentSurface'
92
- data-editing={!!editing}
93
- {...focusAttributes}
94
- style={editBox}
95
- tabIndex={editing ? 0 : -1}
96
- onKeyDown={handleEditorKeyDown}
97
- ref={textboxRef}
98
- />
99
- <DxGrid {...props} mode={editing ? 'edit' : 'browse'} onEdit={handleEdit} ref={gridRef} />
100
- </>
101
- );
107
+ GridContent.displayName = GRID_CONTENT_NAME;
108
+
109
+ export const Grid = {
110
+ Root: GridRoot,
111
+ Content: GridContent,
102
112
  };
113
+
114
+ export { GridRoot, GridContent, useGridContext, createGridScope };
115
+
116
+ export type { GridRootProps, GridContentProps, GridEditing, GridEditBox, GridScopedProps, DxGridElement };