@dxos/react-ui-grid 0.8.3 → 0.8.4-main.1da679c

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-grid",
3
- "version": "0.8.3",
3
+ "version": "0.8.4-main.1da679c",
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",
@@ -10,6 +10,7 @@
10
10
  "type": "module",
11
11
  "exports": {
12
12
  ".": {
13
+ "source": "./src/index.ts",
13
14
  "types": "./dist/types/src/index.d.ts",
14
15
  "browser": "./dist/lib/browser/index.mjs"
15
16
  }
@@ -23,35 +24,35 @@
23
24
  "src"
24
25
  ],
25
26
  "dependencies": {
26
- "@codemirror/autocomplete": "^6.18.1",
27
- "@codemirror/state": "^6.4.1",
28
- "@codemirror/view": "^6.34.1",
27
+ "@codemirror/autocomplete": "^6.18.7",
28
+ "@codemirror/state": "^6.5.2",
29
+ "@codemirror/view": "^6.38.2",
29
30
  "@lit/react": "^1.0.5",
30
31
  "@preact-signals/safe-react": "^0.9.0",
31
32
  "@radix-ui/react-context": "1.1.1",
32
33
  "@radix-ui/react-popper": "1.2.2",
33
34
  "@radix-ui/react-use-controllable-state": "1.1.0",
34
- "@dxos/lit-grid": "0.8.3",
35
- "@dxos/util": "0.8.3",
36
- "@dxos/react-ui-editor": "0.8.3"
35
+ "@dxos/lit-grid": "0.8.4-main.1da679c",
36
+ "@dxos/util": "0.8.4-main.1da679c",
37
+ "@dxos/react-ui-editor": "0.8.4-main.1da679c"
37
38
  },
38
39
  "devDependencies": {
39
40
  "@types/react": "~18.2.0",
40
41
  "@types/react-dom": "~18.2.0",
41
42
  "react": "~18.2.0",
42
43
  "react-dom": "~18.2.0",
43
- "vite": "5.4.7",
44
- "@dxos/random": "0.8.3",
45
- "@dxos/react-ui": "0.8.3",
46
- "@dxos/react-ui-searchlist": "0.8.3",
47
- "@dxos/react-ui-theme": "0.8.3",
48
- "@dxos/storybook-utils": "0.8.3"
44
+ "vite": "7.1.1",
45
+ "@dxos/random": "0.8.4-main.1da679c",
46
+ "@dxos/react-ui-searchlist": "0.8.4-main.1da679c",
47
+ "@dxos/react-ui-theme": "0.8.4-main.1da679c",
48
+ "@dxos/react-ui": "0.8.4-main.1da679c",
49
+ "@dxos/storybook-utils": "0.8.4-main.1da679c"
49
50
  },
50
51
  "peerDependencies": {
51
52
  "react": "~18.2.0",
52
53
  "react-dom": "~18.2.0",
53
- "@dxos/react-ui": "0.8.3",
54
- "@dxos/react-ui-theme": "0.8.3"
54
+ "@dxos/react-ui": "0.8.4-main.1da679c",
55
+ "@dxos/react-ui-theme": "0.8.4-main.1da679c"
55
56
  },
56
57
  "publishConfig": {
57
58
  "access": "public"
@@ -0,0 +1,90 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
+ import React, { useState } from 'react';
9
+
10
+ import { withTheme } from '@dxos/storybook-utils';
11
+
12
+ import { CellEditor, type CellEditorProps, type EditorKeyEvent, editorKeys } from './CellEditor';
13
+
14
+ const DefaultStory = (props: CellEditorProps) => {
15
+ const [value, setValue] = useState(props.value || 'Edit me');
16
+ const [lastAction, setLastAction] = useState<string>('');
17
+
18
+ const handleBlur = (newValue?: string) => {
19
+ if (newValue !== undefined) {
20
+ setValue(newValue);
21
+ setLastAction(`Blur: ${newValue}`);
22
+ }
23
+ };
24
+
25
+ const handleKeyEvent = (newValue: string | undefined, event: EditorKeyEvent) => {
26
+ if (newValue !== undefined) {
27
+ setValue(newValue);
28
+ setLastAction(`Key: ${event.key}${event.shift ? ' + Shift' : ''}, Value: ${newValue}`);
29
+ } else {
30
+ setLastAction(`Key: ${event.key}${event.shift ? ' + Shift' : ''}, Cancelled`);
31
+ }
32
+ };
33
+
34
+ // Create an extension with editor keys
35
+ const extensions = props.extensions || [
36
+ editorKeys({
37
+ onClose: handleKeyEvent,
38
+ onNav: (value, event) => {
39
+ setLastAction(`Navigation: ${event.key}, Value: ${value}`);
40
+ },
41
+ }),
42
+ ];
43
+
44
+ return (
45
+ <div className='flex flex-col gap-4 p-4'>
46
+ <div className='text-sm'>
47
+ Current value: <span className='font-mono'>{value}</span>
48
+ </div>
49
+ <div className='text-sm'>
50
+ Last action: <span className='font-mono'>{lastAction}</span>
51
+ </div>
52
+ <div className='relative border border-separator h-[100px] w-[300px]'>
53
+ <CellEditor
54
+ value={value}
55
+ extensions={extensions}
56
+ autoFocus={props.autoFocus}
57
+ onBlur={handleBlur}
58
+ box={{
59
+ insetInlineStart: 10,
60
+ insetBlockStart: 10,
61
+ inlineSize: 280,
62
+ blockSize: 30,
63
+ }}
64
+ gridId='demo-grid'
65
+ />
66
+ </div>
67
+ </div>
68
+ );
69
+ };
70
+
71
+ const meta = {
72
+ title: 'ui/react-ui-grid/CellEditor',
73
+ component: CellEditor,
74
+ render: DefaultStory,
75
+ decorators: [withTheme],
76
+ parameters: {
77
+ layout: 'centered',
78
+ },
79
+ } satisfies Meta<typeof CellEditor>;
80
+
81
+ export default meta;
82
+
83
+ type Story = StoryObj<typeof meta>;
84
+
85
+ export const Default: Story = {
86
+ args: {
87
+ value: 'Edit me',
88
+ autoFocus: true,
89
+ },
90
+ };
@@ -9,12 +9,14 @@ import React, { type KeyboardEvent } from 'react';
9
9
 
10
10
  import { useThemeContext } from '@dxos/react-ui';
11
11
  import {
12
+ type ThemeExtensionsOptions,
12
13
  type UseTextEditorProps,
13
14
  createBasicExtensions,
14
15
  createThemeExtensions,
15
16
  preventNewline,
16
17
  useTextEditor,
17
18
  } from '@dxos/react-ui-editor';
19
+ import { mx } from '@dxos/react-ui-theme';
18
20
 
19
21
  import { type GridEditBox } from '../Grid';
20
22
 
@@ -114,12 +116,14 @@ export const editorKeys = ({ onNav, onClose }: EditorKeysProps): Extension => {
114
116
 
115
117
  export type CellEditorProps = {
116
118
  value?: string;
117
- extension?: Extension;
119
+ extensions?: Extension;
118
120
  box?: GridEditBox;
119
121
  gridId?: string;
120
- } & Pick<UseTextEditorProps, 'autoFocus'> & { onBlur?: EditorBlurHandler };
122
+ onBlur?: EditorBlurHandler;
123
+ } & Pick<UseTextEditorProps, 'autoFocus'> &
124
+ Pick<ThemeExtensionsOptions, 'slots'>;
121
125
 
122
- export const CellEditor = ({ value, extension, autoFocus, onBlur, box, gridId }: CellEditorProps) => {
126
+ export const CellEditor = ({ value, extensions, box, gridId, onBlur, autoFocus, slots }: CellEditorProps) => {
123
127
  const { themeMode } = useThemeContext();
124
128
  const { parentRef } = useTextEditor(() => {
125
129
  return {
@@ -127,7 +131,7 @@ export const CellEditor = ({ value, extension, autoFocus, onBlur, box, gridId }:
127
131
  initialValue: value,
128
132
  selection: { anchor: value?.length ?? 0 },
129
133
  extensions: [
130
- extension ?? [],
134
+ extensions ?? [],
131
135
  preventNewline,
132
136
  EditorView.focusChangeEffect.of((state, focusing) => {
133
137
  if (!focusing) {
@@ -135,30 +139,41 @@ export const CellEditor = ({ value, extension, autoFocus, onBlur, box, gridId }:
135
139
  }
136
140
  return null;
137
141
  }),
138
- createBasicExtensions({ lineWrapping: false }),
142
+ createBasicExtensions({ lineWrapping: true }),
139
143
  createThemeExtensions({
140
144
  themeMode,
141
145
  slots: {
142
146
  editor: {
143
- className: '[&>.cm-scroller]:scrollbar-none tabular-nums',
147
+ className: mx(
148
+ '!min-is-full !is-min !max-is-[--dx-grid-cell-editor-max-inline-size] !min-bs-full !max-bs-[--dx-grid-cell-editor-max-block-size]',
149
+ slots?.editor?.className,
150
+ ),
151
+ },
152
+ scroll: {
153
+ className: mx(
154
+ '!overflow-x-hidden !plb-[max(0,calc(var(--dx-grid-cell-editor-padding-block)-1px))] !pie-0 !pis-[--dx-grid-cell-editor-padding-inline]',
155
+ slots?.scroll?.className,
156
+ ),
144
157
  },
145
158
  content: {
146
- className:
147
- '!border !border-transparent !pli-[var(--dx-grid-cell-padding-inline)] !plb-[var(--dx-grid-cell-padding-block)]',
159
+ className: mx('!break-normal', slots?.content?.className),
148
160
  },
149
161
  },
150
162
  }),
151
163
  ],
152
164
  };
153
- }, [extension, autoFocus, value, onBlur]);
165
+ }, [extensions, autoFocus, value, onBlur, themeMode, slots]);
154
166
 
155
167
  return (
156
168
  <div
157
169
  data-testid='grid.cell-editor'
158
170
  ref={parentRef}
159
- className='absolute z-[1]'
171
+ className='absolute z-[1] dx-grid__cell-editor'
160
172
  style={{
161
- ...box,
173
+ insetInlineStart: box?.insetInlineStart ?? '0px',
174
+ insetBlockStart: box?.insetBlockStart ?? '0px',
175
+ minInlineSize: box?.inlineSize ?? '180px',
176
+ minBlockSize: box?.blockSize ?? '30px',
162
177
  ...{ '--dx-gridCellWidth': `${box?.inlineSize ?? 200}px` },
163
178
  }}
164
179
  {...(gridId && { 'data-grid': gridId })}
@@ -4,15 +4,18 @@
4
4
 
5
5
  import React, { useCallback } from 'react';
6
6
 
7
+ import { type DxGridCellIndex, type GridScopedProps, useGridContext } from '../Grid';
8
+
7
9
  import { CellEditor, type CellEditorProps } from './CellEditor';
8
- import { type GridScopedProps, useGridContext, type DxGridCellIndex } from '../Grid';
9
10
 
10
11
  export type GridCellEditorProps = GridScopedProps<
11
- Pick<CellEditorProps, 'extension' | 'onBlur'> & { getCellContent: (index: DxGridCellIndex) => string | undefined }
12
+ Pick<CellEditorProps, 'extensions' | 'onBlur' | 'slots'> & {
13
+ getCellContent: (index: DxGridCellIndex) => string | undefined;
14
+ }
12
15
  >;
13
16
 
14
- export const GridCellEditor = ({ extension, getCellContent, onBlur, __gridScope }: GridCellEditorProps) => {
15
- const { id, editing, setEditing, editBox } = useGridContext('GridSheetCellEditor', __gridScope);
17
+ export const GridCellEditor = ({ extensions, getCellContent, onBlur, slots, __gridScope }: GridCellEditorProps) => {
18
+ const { id, editing, setEditing, editBox } = useGridContext('GridCellEditor', __gridScope);
16
19
 
17
20
  const handleBlur = useCallback(
18
21
  (value?: string) => {
@@ -28,8 +31,9 @@ export const GridCellEditor = ({ extension, getCellContent, onBlur, __gridScope
28
31
  autoFocus
29
32
  box={editBox}
30
33
  onBlur={handleBlur}
31
- extension={extension}
34
+ extensions={extensions}
32
35
  gridId={id}
36
+ slots={slots}
33
37
  />
34
38
  ) : null;
35
39
  };
@@ -4,7 +4,7 @@
4
4
 
5
5
  import '@dxos-theme';
6
6
 
7
- import { type Meta, type StoryObj } from '@storybook/react';
7
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
8
8
  import React, { type MouseEvent, type MutableRefObject, useCallback, useRef, useState } from 'react';
9
9
 
10
10
  import { defaultRowSize } from '@dxos/lit-grid';
@@ -13,7 +13,7 @@ import { DropdownMenu } from '@dxos/react-ui';
13
13
  import { PopoverCombobox, type PopoverComboboxRootProps } from '@dxos/react-ui-searchlist';
14
14
  import { withTheme } from '@dxos/storybook-utils';
15
15
 
16
- import { Grid, type GridEditing, type GridContentProps, type GridRootProps } from './Grid';
16
+ import { Grid, type GridContentProps, type GridEditing, type GridRootProps } from './Grid';
17
17
 
18
18
  const storybookItems = faker.helpers.uniqueArray(faker.commerce.productName, 16);
19
19
 
@@ -101,12 +101,12 @@ const GridStory = ({ initialCells, ...props }: GridStoryProps) => {
101
101
  );
102
102
  };
103
103
 
104
- const meta: Meta<GridStoryProps> = {
104
+ const meta = {
105
105
  title: 'ui/react-ui-grid/Grid',
106
106
  component: GridStory,
107
107
  decorators: [withTheme],
108
108
  parameters: { layout: 'fullscreen' },
109
- };
109
+ } satisfies Meta<typeof GridStory>;
110
110
 
111
111
  export default meta;
112
112
 
package/src/Grid/Grid.tsx CHANGED
@@ -4,13 +4,13 @@
4
4
 
5
5
  import '@dxos/lit-grid/dx-grid.pcss';
6
6
 
7
- import { createComponent, type EventName } from '@lit/react';
8
- import { createContextScope, type Scope } from '@radix-ui/react-context';
7
+ import { type EventName, createComponent } from '@lit/react';
8
+ import { type Scope, createContextScope } from '@radix-ui/react-context';
9
9
  import { useControllableState } from '@radix-ui/react-use-controllable-state';
10
10
  import React, {
11
11
  type ComponentProps,
12
- forwardRef,
13
12
  type PropsWithChildren,
13
+ forwardRef,
14
14
  useCallback,
15
15
  useEffect,
16
16
  useState,
@@ -178,6 +178,7 @@ export {
178
178
  toPlaneCellIndex,
179
179
  parseCellIndex,
180
180
  cellQuery,
181
+ DxEditRequest,
181
182
  } from '@dxos/lit-grid';
182
183
 
183
184
  export type {