@dxos/react-ui-grid 0.8.4-main.b97322e → 0.8.4-main.bcb3aa67d6
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 +140 -161
- 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 -3
- package/dist/types/src/CellEditor/CellEditor.d.ts.map +1 -1
- package/dist/types/src/CellEditor/CellEditor.stories.d.ts +12 -4
- package/dist/types/src/CellEditor/CellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/CellEditor/GridCellEditor.d.ts +3 -3
- package/dist/types/src/CellEditor/GridCellEditor.d.ts.map +1 -1
- package/dist/types/src/Grid/Grid.d.ts +6 -6
- package/dist/types/src/Grid/Grid.d.ts.map +1 -1
- package/dist/types/src/Grid/Grid.stories.d.ts +12 -4
- package/dist/types/src/Grid/Grid.stories.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +29 -24
- package/src/CellEditor/CellEditor.stories.tsx +10 -12
- package/src/CellEditor/CellEditor.tsx +18 -17
- package/src/CellEditor/GridCellEditor.tsx +5 -4
- package/src/Grid/Grid.stories.tsx +68 -33
- package/src/Grid/Grid.tsx +15 -11
package/package.json
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-grid",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.bcb3aa67d6",
|
|
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
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/dxos/dxos"
|
|
10
|
+
},
|
|
7
11
|
"license": "MIT",
|
|
8
12
|
"author": "DXOS.org",
|
|
9
|
-
"sideEffects":
|
|
13
|
+
"sideEffects": false,
|
|
10
14
|
"type": "module",
|
|
11
15
|
"exports": {
|
|
12
16
|
".": {
|
|
17
|
+
"source": "./src/index.ts",
|
|
13
18
|
"types": "./dist/types/src/index.d.ts",
|
|
14
19
|
"browser": "./dist/lib/browser/index.mjs"
|
|
15
20
|
}
|
|
@@ -23,35 +28,35 @@
|
|
|
23
28
|
"src"
|
|
24
29
|
],
|
|
25
30
|
"dependencies": {
|
|
26
|
-
"@codemirror/autocomplete": "^6.
|
|
27
|
-
"@codemirror/state": "^6.
|
|
28
|
-
"@codemirror/view": "^6.
|
|
29
|
-
"@lit/react": "^1.0.
|
|
30
|
-
"@preact-signals/safe-react": "^0.9.0",
|
|
31
|
+
"@codemirror/autocomplete": "^6.19.0",
|
|
32
|
+
"@codemirror/state": "^6.5.2",
|
|
33
|
+
"@codemirror/view": "^6.38.4",
|
|
34
|
+
"@lit/react": "^1.0.8",
|
|
31
35
|
"@radix-ui/react-context": "1.1.1",
|
|
32
36
|
"@radix-ui/react-popper": "1.2.2",
|
|
33
37
|
"@radix-ui/react-use-controllable-state": "1.1.0",
|
|
34
|
-
"@dxos/lit-grid": "0.8.4-main.
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/
|
|
38
|
+
"@dxos/lit-grid": "0.8.4-main.bcb3aa67d6",
|
|
39
|
+
"@dxos/ui-editor": "0.8.4-main.bcb3aa67d6",
|
|
40
|
+
"@dxos/util": "0.8.4-main.bcb3aa67d6",
|
|
41
|
+
"@dxos/react-ui-editor": "0.8.4-main.bcb3aa67d6"
|
|
37
42
|
},
|
|
38
43
|
"devDependencies": {
|
|
39
|
-
"@types/react": "~
|
|
40
|
-
"@types/react-dom": "~
|
|
41
|
-
"react": "~
|
|
42
|
-
"react-dom": "~
|
|
43
|
-
"vite": "
|
|
44
|
-
"@dxos/random": "0.8.4-main.
|
|
45
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
46
|
-
"@dxos/react-ui
|
|
47
|
-
"@dxos/
|
|
48
|
-
"@dxos/
|
|
44
|
+
"@types/react": "~19.2.7",
|
|
45
|
+
"@types/react-dom": "~19.2.3",
|
|
46
|
+
"react": "~19.2.3",
|
|
47
|
+
"react-dom": "~19.2.3",
|
|
48
|
+
"vite": "^7.1.11",
|
|
49
|
+
"@dxos/random": "0.8.4-main.bcb3aa67d6",
|
|
50
|
+
"@dxos/react-ui-search": "0.8.4-main.bcb3aa67d6",
|
|
51
|
+
"@dxos/react-ui": "0.8.4-main.bcb3aa67d6",
|
|
52
|
+
"@dxos/storybook-utils": "0.8.4-main.bcb3aa67d6",
|
|
53
|
+
"@dxos/ui-theme": "0.8.4-main.bcb3aa67d6"
|
|
49
54
|
},
|
|
50
55
|
"peerDependencies": {
|
|
51
|
-
"react": "~
|
|
52
|
-
"react-dom": "~
|
|
53
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
54
|
-
"@dxos/
|
|
56
|
+
"react": "~19.2.3",
|
|
57
|
+
"react-dom": "~19.2.3",
|
|
58
|
+
"@dxos/react-ui": "0.8.4-main.bcb3aa67d6",
|
|
59
|
+
"@dxos/ui-theme": "0.8.4-main.bcb3aa67d6"
|
|
55
60
|
},
|
|
56
61
|
"publishConfig": {
|
|
57
62
|
"access": "public"
|
|
@@ -2,17 +2,15 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import React, { useState } from 'react';
|
|
9
7
|
|
|
10
|
-
import { withTheme } from '@dxos/
|
|
8
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
11
9
|
|
|
12
10
|
import { CellEditor, type CellEditorProps, type EditorKeyEvent, editorKeys } from './CellEditor';
|
|
13
11
|
|
|
14
|
-
const DefaultStory = (
|
|
15
|
-
const [value, setValue] = useState(
|
|
12
|
+
const DefaultStory = (props: CellEditorProps) => {
|
|
13
|
+
const [value, setValue] = useState(props.value || 'Edit me');
|
|
16
14
|
const [lastAction, setLastAction] = useState<string>('');
|
|
17
15
|
|
|
18
16
|
const handleBlur = (newValue?: string) => {
|
|
@@ -32,7 +30,7 @@ const DefaultStory = (args: CellEditorProps) => {
|
|
|
32
30
|
};
|
|
33
31
|
|
|
34
32
|
// Create an extension with editor keys
|
|
35
|
-
const
|
|
33
|
+
const extensions = props.extensions || [
|
|
36
34
|
editorKeys({
|
|
37
35
|
onClose: handleKeyEvent,
|
|
38
36
|
onNav: (value, event) => {
|
|
@@ -52,8 +50,8 @@ const DefaultStory = (args: CellEditorProps) => {
|
|
|
52
50
|
<div className='relative border border-separator h-[100px] w-[300px]'>
|
|
53
51
|
<CellEditor
|
|
54
52
|
value={value}
|
|
55
|
-
|
|
56
|
-
autoFocus={
|
|
53
|
+
extensions={extensions}
|
|
54
|
+
autoFocus={props.autoFocus}
|
|
57
55
|
onBlur={handleBlur}
|
|
58
56
|
box={{
|
|
59
57
|
insetInlineStart: 10,
|
|
@@ -68,19 +66,19 @@ const DefaultStory = (args: CellEditorProps) => {
|
|
|
68
66
|
);
|
|
69
67
|
};
|
|
70
68
|
|
|
71
|
-
const meta
|
|
69
|
+
const meta = {
|
|
72
70
|
title: 'ui/react-ui-grid/CellEditor',
|
|
73
71
|
component: CellEditor,
|
|
74
72
|
render: DefaultStory,
|
|
75
|
-
decorators: [withTheme],
|
|
73
|
+
decorators: [withTheme()],
|
|
76
74
|
parameters: {
|
|
77
75
|
layout: 'centered',
|
|
78
76
|
},
|
|
79
|
-
}
|
|
77
|
+
} satisfies Meta<typeof CellEditor>;
|
|
80
78
|
|
|
81
79
|
export default meta;
|
|
82
80
|
|
|
83
|
-
type Story = StoryObj<
|
|
81
|
+
type Story = StoryObj<typeof meta>;
|
|
84
82
|
|
|
85
83
|
export const Default: Story = {
|
|
86
84
|
args: {
|
|
@@ -8,15 +8,14 @@ import { EditorView, keymap } from '@codemirror/view';
|
|
|
8
8
|
import React, { type KeyboardEvent } from 'react';
|
|
9
9
|
|
|
10
10
|
import { useThemeContext } from '@dxos/react-ui';
|
|
11
|
+
import { type UseTextEditorProps, useTextEditor } from '@dxos/react-ui-editor';
|
|
11
12
|
import {
|
|
12
|
-
type
|
|
13
|
+
type ThemeExtensionsOptions,
|
|
13
14
|
createBasicExtensions,
|
|
14
15
|
createThemeExtensions,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
} from '@dxos/react-ui-editor';
|
|
19
|
-
import { mx } from '@dxos/react-ui-theme';
|
|
16
|
+
filterChars,
|
|
17
|
+
} from '@dxos/ui-editor';
|
|
18
|
+
import { mx } from '@dxos/ui-theme';
|
|
20
19
|
|
|
21
20
|
import { type GridEditBox } from '../Grid';
|
|
22
21
|
|
|
@@ -116,14 +115,14 @@ export const editorKeys = ({ onNav, onClose }: EditorKeysProps): Extension => {
|
|
|
116
115
|
|
|
117
116
|
export type CellEditorProps = {
|
|
118
117
|
value?: string;
|
|
119
|
-
|
|
118
|
+
extensions?: Extension;
|
|
120
119
|
box?: GridEditBox;
|
|
121
120
|
gridId?: string;
|
|
122
121
|
onBlur?: EditorBlurHandler;
|
|
123
122
|
} & Pick<UseTextEditorProps, 'autoFocus'> &
|
|
124
123
|
Pick<ThemeExtensionsOptions, 'slots'>;
|
|
125
124
|
|
|
126
|
-
export const CellEditor = ({ value,
|
|
125
|
+
export const CellEditor = ({ value, extensions, box, gridId, autoFocus, slots, onBlur }: CellEditorProps) => {
|
|
127
126
|
const { themeMode } = useThemeContext();
|
|
128
127
|
const { parentRef } = useTextEditor(() => {
|
|
129
128
|
return {
|
|
@@ -131,8 +130,8 @@ export const CellEditor = ({ value, extension, autoFocus, onBlur, box, gridId, s
|
|
|
131
130
|
initialValue: value,
|
|
132
131
|
selection: { anchor: value?.length ?? 0 },
|
|
133
132
|
extensions: [
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
extensions ?? [],
|
|
134
|
+
filterChars(/[\n\r]+/),
|
|
136
135
|
EditorView.focusChangeEffect.of((state, focusing) => {
|
|
137
136
|
if (!focusing) {
|
|
138
137
|
onBlur?.(state.doc.toString());
|
|
@@ -145,22 +144,24 @@ export const CellEditor = ({ value, extension, autoFocus, onBlur, box, gridId, s
|
|
|
145
144
|
slots: {
|
|
146
145
|
editor: {
|
|
147
146
|
className: mx(
|
|
148
|
-
'
|
|
147
|
+
'min-w-full! w-min! !max-w-(--dx-grid-cell-editor-max-w-size) min-h-full! !max-h-(--dx-grid-cell-editor-max-h-size)',
|
|
149
148
|
slots?.editor?.className,
|
|
150
149
|
),
|
|
151
150
|
},
|
|
152
|
-
|
|
151
|
+
scroll: {
|
|
153
152
|
className: mx(
|
|
154
|
-
'
|
|
155
|
-
slots?.
|
|
153
|
+
'overflow-x-hidden! !py-[max(0,calc(var(--dx-grid-cell-editor-padding-block)-1px))] pe-0! !pl-(--dx-grid-cell-editor-padding-inline)',
|
|
154
|
+
slots?.scroll?.className,
|
|
156
155
|
),
|
|
157
156
|
},
|
|
158
|
-
content: {
|
|
157
|
+
content: {
|
|
158
|
+
className: mx('break-normal!', slots?.content?.className),
|
|
159
|
+
},
|
|
159
160
|
},
|
|
160
161
|
}),
|
|
161
162
|
],
|
|
162
163
|
};
|
|
163
|
-
}, [
|
|
164
|
+
}, [extensions, autoFocus, value, onBlur, themeMode, slots]);
|
|
164
165
|
|
|
165
166
|
return (
|
|
166
167
|
<div
|
|
@@ -172,7 +173,7 @@ export const CellEditor = ({ value, extension, autoFocus, onBlur, box, gridId, s
|
|
|
172
173
|
insetBlockStart: box?.insetBlockStart ?? '0px',
|
|
173
174
|
minInlineSize: box?.inlineSize ?? '180px',
|
|
174
175
|
minBlockSize: box?.blockSize ?? '30px',
|
|
175
|
-
...{ '--dx-
|
|
176
|
+
...{ '--dx-grid-cell-width': `${box?.inlineSize ?? 200}px` },
|
|
176
177
|
}}
|
|
177
178
|
{...(gridId && { 'data-grid': gridId })}
|
|
178
179
|
/>
|
|
@@ -4,16 +4,17 @@
|
|
|
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, '
|
|
12
|
+
Pick<CellEditorProps, 'extensions' | 'onBlur' | 'slots'> & {
|
|
12
13
|
getCellContent: (index: DxGridCellIndex) => string | undefined;
|
|
13
14
|
}
|
|
14
15
|
>;
|
|
15
16
|
|
|
16
|
-
export const GridCellEditor = ({
|
|
17
|
+
export const GridCellEditor = ({ extensions, getCellContent, onBlur, slots, __gridScope }: GridCellEditorProps) => {
|
|
17
18
|
const { id, editing, setEditing, editBox } = useGridContext('GridCellEditor', __gridScope);
|
|
18
19
|
|
|
19
20
|
const handleBlur = useCallback(
|
|
@@ -30,7 +31,7 @@ export const GridCellEditor = ({ extension, getCellContent, onBlur, slots, __gri
|
|
|
30
31
|
autoFocus
|
|
31
32
|
box={editBox}
|
|
32
33
|
onBlur={handleBlur}
|
|
33
|
-
|
|
34
|
+
extensions={extensions}
|
|
34
35
|
gridId={id}
|
|
35
36
|
slots={slots}
|
|
36
37
|
/>
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import React, { type MouseEvent, type MutableRefObject, useCallback, useRef, useState } from 'react';
|
|
9
7
|
|
|
10
8
|
import { defaultRowSize } from '@dxos/lit-grid';
|
|
9
|
+
import { type DxGridPlaneCells } from '@dxos/lit-grid';
|
|
11
10
|
import { faker } from '@dxos/random';
|
|
12
11
|
import { DropdownMenu } from '@dxos/react-ui';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
12
|
+
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
13
|
+
import { toPlaneCellIndex } from '@dxos/react-ui-grid';
|
|
14
|
+
import { Combobox, type ComboboxRootProps, useSearchListResults } from '@dxos/react-ui-search';
|
|
15
15
|
|
|
16
|
-
import { Grid, type
|
|
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
|
|
|
@@ -33,7 +33,7 @@ const GridStory = ({ initialCells, ...props }: GridStoryProps) => {
|
|
|
33
33
|
// Multiselect
|
|
34
34
|
const [popoverOpen, setPopoverOpen] = useState(false);
|
|
35
35
|
const [multiSelectValue, setInternalMultiselectValue] = useState('');
|
|
36
|
-
const setMultiselectValue = useCallback<NonNullable<
|
|
36
|
+
const setMultiselectValue = useCallback<NonNullable<ComboboxRootProps['onValueChange']>>((nextValue) => {
|
|
37
37
|
setInternalMultiselectValue(nextValue);
|
|
38
38
|
setCells((cells) => {
|
|
39
39
|
// TODO(burdon): How can we get the cell address to update?
|
|
@@ -64,7 +64,7 @@ const GridStory = ({ initialCells, ...props }: GridStoryProps) => {
|
|
|
64
64
|
}, []);
|
|
65
65
|
|
|
66
66
|
return (
|
|
67
|
-
<div role='none' className='
|
|
67
|
+
<div role='none' className='contents'>
|
|
68
68
|
<Grid.Root id='story' editing={editing} onEditingChange={handleEditingChange}>
|
|
69
69
|
{/* TODO(burdon): Why is this property not just "cells" or "values" */}
|
|
70
70
|
<Grid.Content {...props} initialCells={cells} onClick={handleClick} />
|
|
@@ -80,38 +80,52 @@ const GridStory = ({ initialCells, ...props }: GridStoryProps) => {
|
|
|
80
80
|
</DropdownMenu.Root>
|
|
81
81
|
|
|
82
82
|
{/* Multiselect */}
|
|
83
|
-
<
|
|
83
|
+
<Combobox.Root
|
|
84
84
|
open={popoverOpen}
|
|
85
85
|
onOpenChange={setPopoverOpen}
|
|
86
86
|
value={multiSelectValue}
|
|
87
87
|
onValueChange={setMultiselectValue}
|
|
88
88
|
>
|
|
89
|
-
<
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
<PopoverCombobox.List>
|
|
93
|
-
{storybookItems.map((value) => (
|
|
94
|
-
<PopoverCombobox.Item key={value}>{value}</PopoverCombobox.Item>
|
|
95
|
-
))}
|
|
96
|
-
</PopoverCombobox.List>
|
|
97
|
-
<PopoverCombobox.Arrow />
|
|
98
|
-
</PopoverCombobox.Content>
|
|
99
|
-
</PopoverCombobox.Root>
|
|
89
|
+
<Combobox.VirtualTrigger virtualRef={triggerRef} />
|
|
90
|
+
<ComboboxContentWithFiltering />
|
|
91
|
+
</Combobox.Root>
|
|
100
92
|
</div>
|
|
101
93
|
);
|
|
102
94
|
};
|
|
103
95
|
|
|
104
|
-
const
|
|
96
|
+
const ComboboxContentWithFiltering = () => {
|
|
97
|
+
const { results, handleSearch } = useSearchListResults({
|
|
98
|
+
items: storybookItems,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<Combobox.Content onSearch={handleSearch}>
|
|
103
|
+
<Combobox.Input placeholder='Search...' />
|
|
104
|
+
<Combobox.List>
|
|
105
|
+
{results.map((value) => (
|
|
106
|
+
<Combobox.Item key={value} value={value} label={value} />
|
|
107
|
+
))}
|
|
108
|
+
</Combobox.List>
|
|
109
|
+
<Combobox.Arrow />
|
|
110
|
+
</Combobox.Content>
|
|
111
|
+
);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const meta = {
|
|
105
115
|
title: 'ui/react-ui-grid/Grid',
|
|
106
116
|
component: GridStory,
|
|
107
|
-
decorators: [withTheme],
|
|
108
|
-
parameters: {
|
|
109
|
-
|
|
117
|
+
decorators: [withTheme(), withLayout({ layout: 'column' })],
|
|
118
|
+
parameters: {
|
|
119
|
+
layout: 'fullscreen',
|
|
120
|
+
},
|
|
121
|
+
} satisfies Meta<typeof GridStory>;
|
|
110
122
|
|
|
111
123
|
export default meta;
|
|
112
124
|
|
|
113
125
|
type Story = StoryObj<typeof meta>;
|
|
114
126
|
|
|
127
|
+
export const Default: Story = {};
|
|
128
|
+
|
|
115
129
|
export const Basic: Story = {
|
|
116
130
|
args: {
|
|
117
131
|
id: 'story',
|
|
@@ -141,7 +155,7 @@ export const Basic: Story = {
|
|
|
141
155
|
'1,1': {
|
|
142
156
|
value: 'Demo decoration',
|
|
143
157
|
accessoryHtml: `
|
|
144
|
-
<button class="dx-button
|
|
158
|
+
<button class="dx-button w-6 px-0.5 min-h-0 absolute inset-y-1 right-1" data-story-action="menu">
|
|
145
159
|
<svg><use href="/icons.svg#ph--arrow-right--regular"/></svg>
|
|
146
160
|
</button>
|
|
147
161
|
`,
|
|
@@ -158,26 +172,47 @@ export const Basic: Story = {
|
|
|
158
172
|
},
|
|
159
173
|
};
|
|
160
174
|
|
|
161
|
-
|
|
162
|
-
|
|
175
|
+
const cellSize = 40;
|
|
176
|
+
|
|
177
|
+
// TODO(burdon): Calendar.
|
|
178
|
+
export const Calendar: Story = {
|
|
163
179
|
args: {
|
|
164
180
|
id: 'story',
|
|
165
|
-
limitColumns:
|
|
181
|
+
limitColumns: 7,
|
|
166
182
|
columnDefault: {
|
|
167
183
|
grid: {
|
|
168
|
-
size:
|
|
184
|
+
size: cellSize,
|
|
185
|
+
resizeable: false,
|
|
169
186
|
},
|
|
170
187
|
},
|
|
171
188
|
rowDefault: {
|
|
172
189
|
grid: {
|
|
173
|
-
size:
|
|
190
|
+
size: cellSize,
|
|
174
191
|
resizeable: false,
|
|
175
192
|
},
|
|
176
193
|
},
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
194
|
+
getCells: (range, plane) => {
|
|
195
|
+
const cells: DxGridPlaneCells = {};
|
|
196
|
+
if (plane === 'grid') {
|
|
197
|
+
for (let col = range.start.col; col <= range.end.col; col++) {
|
|
198
|
+
for (let row = range.start.row; row <= range.end.row; row++) {
|
|
199
|
+
// TODO(burdon): Formatting changes when cell is selected.
|
|
200
|
+
cells[toPlaneCellIndex({ col, row })] = {
|
|
201
|
+
readonly: true,
|
|
202
|
+
accessoryHtml: '<div class="flex h-full w-full justify-center items-center overflow-hidden">0</div>',
|
|
203
|
+
className: '',
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return cells;
|
|
181
209
|
},
|
|
182
210
|
},
|
|
211
|
+
render: (args) => (
|
|
212
|
+
<div className='h-full flex justify-center'>
|
|
213
|
+
<div className='h-full w-[288px] border-x border-separator'>
|
|
214
|
+
<GridStory {...args} />
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
),
|
|
183
218
|
};
|
package/src/Grid/Grid.tsx
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import '@dxos/lit-grid/dx-grid.pcss';
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
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,
|
|
@@ -63,20 +63,23 @@ const [createGridContext, createGridScope] = createContextScope(GRID_NAME, []);
|
|
|
63
63
|
const [GridProvider, useGridContext] = createGridContext<GridContextValue>(GRID_NAME);
|
|
64
64
|
|
|
65
65
|
type GridRootProps = PropsWithChildren<
|
|
66
|
-
{
|
|
66
|
+
{
|
|
67
|
+
id: string;
|
|
68
|
+
} & Partial<{
|
|
67
69
|
editing: GridEditing;
|
|
68
70
|
defaultEditing: GridEditing;
|
|
69
71
|
onEditingChange: (nextEditing: GridEditing) => void;
|
|
70
72
|
}>
|
|
71
73
|
>;
|
|
72
74
|
|
|
75
|
+
// TODO(burdon): Make headless.
|
|
73
76
|
const GridRoot = ({
|
|
77
|
+
__gridScope,
|
|
78
|
+
children,
|
|
74
79
|
id,
|
|
75
80
|
editing: propsEditing,
|
|
76
81
|
defaultEditing,
|
|
77
82
|
onEditingChange,
|
|
78
|
-
children,
|
|
79
|
-
__gridScope,
|
|
80
83
|
}: GridScopedProps<GridRootProps>) => {
|
|
81
84
|
const [editing = null, setEditing] = useControllableState({
|
|
82
85
|
prop: propsEditing,
|
|
@@ -102,13 +105,13 @@ const GridRoot = ({
|
|
|
102
105
|
|
|
103
106
|
GridRoot.displayName = GRID_NAME;
|
|
104
107
|
|
|
108
|
+
const GRID_CONTENT_NAME = 'GridContent';
|
|
109
|
+
|
|
105
110
|
type GridContentProps = Omit<ComponentProps<typeof DxGrid>, 'onEdit'> & {
|
|
106
111
|
getCells?: NaturalDxGrid['getCells'];
|
|
107
112
|
activeRefs?: string;
|
|
108
113
|
};
|
|
109
114
|
|
|
110
|
-
const GRID_CONTENT_NAME = 'GridContent';
|
|
111
|
-
|
|
112
115
|
const GridContent = forwardRef<NaturalDxGrid, GridScopedProps<GridContentProps>>((props, forwardedRef) => {
|
|
113
116
|
const { id, editing, setEditBox, setEditing } = useGridContext(GRID_CONTENT_NAME, props.__gridScope);
|
|
114
117
|
const [dxGrid, setDxGridInternal] = useState<NaturalDxGrid | null>(null);
|
|
@@ -150,12 +153,12 @@ GridContent.displayName = GRID_CONTENT_NAME;
|
|
|
150
153
|
// Fragments
|
|
151
154
|
//
|
|
152
155
|
|
|
153
|
-
// NOTE(Zan): These fragments add border to
|
|
156
|
+
// NOTE(Zan): These fragments add border to w-end and h-end of the grid using pseudo-elements.
|
|
154
157
|
// These are offset by 1px to avoid double borders in planks.
|
|
155
158
|
const gridSeparatorInlineEnd =
|
|
156
|
-
'[&>.dx-grid]:relative [&>.dx-grid]:after:absolute [&>.dx-grid]:after:inset-
|
|
159
|
+
'[&>.dx-grid]:relative [&>.dx-grid]:after:absolute [&>.dx-grid]:after:inset-y-0 [&>.dx-grid]:after:-right-px [&>.dx-grid]:after:w-px [&>.dx-grid]:after:bg-subdued-separator';
|
|
157
160
|
const gridSeparatorBlockEnd =
|
|
158
|
-
'[&>.dx-grid]:relative [&>.dx-grid]:before:absolute [&>.dx-grid]:before:inset-
|
|
161
|
+
'[&>.dx-grid]:relative [&>.dx-grid]:before:absolute [&>.dx-grid]:before:inset-x-0 [&>.dx-grid]:before:-bottom-px [&>.dx-grid]:before:h-px [&>.dx-grid]:before:bg-subdued-separator';
|
|
159
162
|
|
|
160
163
|
//
|
|
161
164
|
// Exports
|
|
@@ -166,7 +169,7 @@ export const Grid = {
|
|
|
166
169
|
Content: GridContent,
|
|
167
170
|
};
|
|
168
171
|
|
|
169
|
-
export { GridRoot, GridContent,
|
|
172
|
+
export { GridRoot, GridContent, createGridScope, gridSeparatorInlineEnd, gridSeparatorBlockEnd, useGridContext };
|
|
170
173
|
|
|
171
174
|
export type { GridRootProps, GridContentProps, GridEditing, GridEditBox, GridScopedProps, DxGridElement };
|
|
172
175
|
|
|
@@ -178,6 +181,7 @@ export {
|
|
|
178
181
|
toPlaneCellIndex,
|
|
179
182
|
parseCellIndex,
|
|
180
183
|
cellQuery,
|
|
184
|
+
DxEditRequest,
|
|
181
185
|
} from '@dxos/lit-grid';
|
|
182
186
|
|
|
183
187
|
export type {
|