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

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.f9ba587",
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",
@@ -31,9 +31,9 @@
31
31
  "@radix-ui/react-context": "1.1.1",
32
32
  "@radix-ui/react-popper": "1.2.2",
33
33
  "@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"
34
+ "@dxos/lit-grid": "0.8.4-main.f9ba587",
35
+ "@dxos/react-ui-editor": "0.8.4-main.f9ba587",
36
+ "@dxos/util": "0.8.4-main.f9ba587"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/react": "~18.2.0",
@@ -41,17 +41,17 @@
41
41
  "react": "~18.2.0",
42
42
  "react-dom": "~18.2.0",
43
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
+ "@dxos/random": "0.8.4-main.f9ba587",
45
+ "@dxos/react-ui-searchlist": "0.8.4-main.f9ba587",
46
+ "@dxos/react-ui-theme": "0.8.4-main.f9ba587",
47
+ "@dxos/react-ui": "0.8.4-main.f9ba587",
48
+ "@dxos/storybook-utils": "0.8.4-main.f9ba587"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "react": "~18.2.0",
52
52
  "react-dom": "~18.2.0",
53
- "@dxos/react-ui": "0.8.3",
54
- "@dxos/react-ui-theme": "0.8.3"
53
+ "@dxos/react-ui": "0.8.4-main.f9ba587",
54
+ "@dxos/react-ui-theme": "0.8.4-main.f9ba587"
55
55
  },
56
56
  "publishConfig": {
57
57
  "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 = (args: CellEditorProps) => {
15
+ const [value, setValue] = useState(args.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 extension = args.extension || [
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
+ extension={extension}
56
+ autoFocus={args.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: Meta<CellEditorProps> = {
72
+ title: 'ui/react-ui-grid/CellEditor',
73
+ component: CellEditor,
74
+ render: DefaultStory,
75
+ decorators: [withTheme],
76
+ parameters: {
77
+ layout: 'centered',
78
+ },
79
+ };
80
+
81
+ export default meta;
82
+
83
+ type Story = StoryObj<CellEditorProps>;
84
+
85
+ export const Default: Story = {
86
+ args: {
87
+ value: 'Edit me',
88
+ autoFocus: true,
89
+ },
90
+ };
@@ -14,7 +14,9 @@ import {
14
14
  createThemeExtensions,
15
15
  preventNewline,
16
16
  useTextEditor,
17
+ type ThemeExtensionsOptions,
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
 
@@ -117,9 +119,11 @@ export type CellEditorProps = {
117
119
  extension?: 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, extension, autoFocus, onBlur, box, gridId, slots }: CellEditorProps) => {
123
127
  const { themeMode } = useThemeContext();
124
128
  const { parentRef } = useTextEditor(() => {
125
129
  return {
@@ -135,30 +139,39 @@ 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
+ ),
144
151
  },
145
- content: {
146
- className:
147
- '!border !border-transparent !pli-[var(--dx-grid-cell-padding-inline)] !plb-[var(--dx-grid-cell-padding-block)]',
152
+ scroller: {
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?.scroller?.className,
156
+ ),
148
157
  },
158
+ content: { className: mx('!break-normal', slots?.content?.className) },
149
159
  },
150
160
  }),
151
161
  ],
152
162
  };
153
- }, [extension, autoFocus, value, onBlur]);
163
+ }, [extension, autoFocus, value, onBlur, themeMode, slots]);
154
164
 
155
165
  return (
156
166
  <div
157
167
  data-testid='grid.cell-editor'
158
168
  ref={parentRef}
159
- className='absolute z-[1]'
169
+ className='absolute z-[1] dx-grid__cell-editor'
160
170
  style={{
161
- ...box,
171
+ insetInlineStart: box?.insetInlineStart ?? '0px',
172
+ insetBlockStart: box?.insetBlockStart ?? '0px',
173
+ minInlineSize: box?.inlineSize ?? '180px',
174
+ minBlockSize: box?.blockSize ?? '30px',
162
175
  ...{ '--dx-gridCellWidth': `${box?.inlineSize ?? 200}px` },
163
176
  }}
164
177
  {...(gridId && { 'data-grid': gridId })}
@@ -8,11 +8,13 @@ import { CellEditor, type CellEditorProps } from './CellEditor';
8
8
  import { type GridScopedProps, useGridContext, type DxGridCellIndex } from '../Grid';
9
9
 
10
10
  export type GridCellEditorProps = GridScopedProps<
11
- Pick<CellEditorProps, 'extension' | 'onBlur'> & { getCellContent: (index: DxGridCellIndex) => string | undefined }
11
+ Pick<CellEditorProps, 'extension' | 'onBlur' | 'slots'> & {
12
+ getCellContent: (index: DxGridCellIndex) => string | undefined;
13
+ }
12
14
  >;
13
15
 
14
- export const GridCellEditor = ({ extension, getCellContent, onBlur, __gridScope }: GridCellEditorProps) => {
15
- const { id, editing, setEditing, editBox } = useGridContext('GridSheetCellEditor', __gridScope);
16
+ export const GridCellEditor = ({ extension, getCellContent, onBlur, slots, __gridScope }: GridCellEditorProps) => {
17
+ const { id, editing, setEditing, editBox } = useGridContext('GridCellEditor', __gridScope);
16
18
 
17
19
  const handleBlur = useCallback(
18
20
  (value?: string) => {
@@ -30,6 +32,7 @@ export const GridCellEditor = ({ extension, getCellContent, onBlur, __gridScope
30
32
  onBlur={handleBlur}
31
33
  extension={extension}
32
34
  gridId={id}
35
+ slots={slots}
33
36
  />
34
37
  ) : null;
35
38
  };
@@ -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';
package/src/Grid/Grid.tsx CHANGED
@@ -9,8 +9,8 @@ import { createContextScope, type Scope } 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,