@dxos/react-ui-grid 0.8.4-main.406dc2a → 0.8.4-main.422d1c7879
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 +138 -160
- 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 +3 -2
- package/dist/types/src/CellEditor/CellEditor.d.ts.map +1 -1
- package/dist/types/src/CellEditor/CellEditor.stories.d.ts +1 -1
- package/dist/types/src/CellEditor/GridCellEditor.d.ts.map +1 -1
- package/dist/types/src/Grid/Grid.d.ts +5 -5
- package/dist/types/src/Grid/Grid.d.ts.map +1 -1
- package/dist/types/src/Grid/Grid.stories.d.ts +2 -1
- package/dist/types/src/Grid/Grid.stories.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +24 -23
- package/src/CellEditor/CellEditor.stories.tsx +1 -1
- package/src/CellEditor/CellEditor.tsx +10 -11
- package/src/CellEditor/GridCellEditor.tsx +0 -1
- package/src/Grid/Grid.stories.tsx +60 -25
- package/src/Grid/Grid.tsx +10 -8
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-grid",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.422d1c7879",
|
|
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
|
".": {
|
|
@@ -16,9 +20,6 @@
|
|
|
16
20
|
}
|
|
17
21
|
},
|
|
18
22
|
"types": "dist/types/src/index.d.ts",
|
|
19
|
-
"typesVersions": {
|
|
20
|
-
"*": {}
|
|
21
|
-
},
|
|
22
23
|
"files": [
|
|
23
24
|
"dist",
|
|
24
25
|
"src"
|
|
@@ -28,31 +29,31 @@
|
|
|
28
29
|
"@codemirror/state": "^6.5.2",
|
|
29
30
|
"@codemirror/view": "^6.38.4",
|
|
30
31
|
"@lit/react": "^1.0.8",
|
|
31
|
-
"@preact-signals/safe-react": "^0.9.0",
|
|
32
32
|
"@radix-ui/react-context": "1.1.1",
|
|
33
33
|
"@radix-ui/react-popper": "1.2.2",
|
|
34
34
|
"@radix-ui/react-use-controllable-state": "1.1.0",
|
|
35
|
-
"@dxos/lit-grid": "0.8.4-main.
|
|
36
|
-
"@dxos/react-ui-editor": "0.8.4-main.
|
|
37
|
-
"@dxos/
|
|
35
|
+
"@dxos/lit-grid": "0.8.4-main.422d1c7879",
|
|
36
|
+
"@dxos/react-ui-editor": "0.8.4-main.422d1c7879",
|
|
37
|
+
"@dxos/ui-editor": "0.8.4-main.422d1c7879",
|
|
38
|
+
"@dxos/util": "0.8.4-main.422d1c7879"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
|
-
"@types/react": "~19.2.
|
|
41
|
-
"@types/react-dom": "~19.2.
|
|
42
|
-
"react": "~19.2.
|
|
43
|
-
"react-dom": "~19.2.
|
|
44
|
-
"vite": "7.1.
|
|
45
|
-
"@dxos/
|
|
46
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
47
|
-
"@dxos/
|
|
48
|
-
"@dxos/
|
|
49
|
-
"@dxos/
|
|
41
|
+
"@types/react": "~19.2.7",
|
|
42
|
+
"@types/react-dom": "~19.2.3",
|
|
43
|
+
"react": "~19.2.3",
|
|
44
|
+
"react-dom": "~19.2.3",
|
|
45
|
+
"vite": "^7.1.11",
|
|
46
|
+
"@dxos/react-ui": "0.8.4-main.422d1c7879",
|
|
47
|
+
"@dxos/react-ui-search": "0.8.4-main.422d1c7879",
|
|
48
|
+
"@dxos/random": "0.8.4-main.422d1c7879",
|
|
49
|
+
"@dxos/storybook-utils": "0.8.4-main.422d1c7879",
|
|
50
|
+
"@dxos/ui-theme": "0.8.4-main.422d1c7879"
|
|
50
51
|
},
|
|
51
52
|
"peerDependencies": {
|
|
52
|
-
"react": "
|
|
53
|
-
"react-dom": "
|
|
54
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
55
|
-
"@dxos/
|
|
53
|
+
"react": "~19.2.3",
|
|
54
|
+
"react-dom": "~19.2.3",
|
|
55
|
+
"@dxos/react-ui": "0.8.4-main.422d1c7879",
|
|
56
|
+
"@dxos/ui-theme": "0.8.4-main.422d1c7879"
|
|
56
57
|
},
|
|
57
58
|
"publishConfig": {
|
|
58
59
|
"access": "public"
|
|
@@ -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
13
|
type ThemeExtensionsOptions,
|
|
13
|
-
type UseTextEditorProps,
|
|
14
14
|
createBasicExtensions,
|
|
15
15
|
createThemeExtensions,
|
|
16
16
|
filterChars,
|
|
17
|
-
|
|
18
|
-
} from '@dxos/
|
|
19
|
-
import { mx } from '@dxos/react-ui-theme';
|
|
17
|
+
} from '@dxos/ui-editor';
|
|
18
|
+
import { mx } from '@dxos/ui-theme';
|
|
20
19
|
|
|
21
20
|
import { type GridEditBox } from '../Grid';
|
|
22
21
|
|
|
@@ -123,7 +122,7 @@ export type CellEditorProps = {
|
|
|
123
122
|
} & Pick<UseTextEditorProps, 'autoFocus'> &
|
|
124
123
|
Pick<ThemeExtensionsOptions, 'slots'>;
|
|
125
124
|
|
|
126
|
-
export const CellEditor = ({ value, extensions, box, gridId,
|
|
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 {
|
|
@@ -145,18 +144,18 @@ export const CellEditor = ({ value, extensions, box, gridId, onBlur, autoFocus,
|
|
|
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
|
+
scroller: {
|
|
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?.scroller?.className,
|
|
156
155
|
),
|
|
157
156
|
},
|
|
158
157
|
content: {
|
|
159
|
-
className: mx('
|
|
158
|
+
className: mx('break-normal!', slots?.content?.className),
|
|
160
159
|
},
|
|
161
160
|
},
|
|
162
161
|
}),
|
|
@@ -174,7 +173,7 @@ export const CellEditor = ({ value, extensions, box, gridId, onBlur, autoFocus,
|
|
|
174
173
|
insetBlockStart: box?.insetBlockStart ?? '0px',
|
|
175
174
|
minInlineSize: box?.inlineSize ?? '180px',
|
|
176
175
|
minBlockSize: box?.blockSize ?? '30px',
|
|
177
|
-
...{ '--dx-
|
|
176
|
+
...{ '--dx-grid-cell-width': `${box?.inlineSize ?? 200}px` },
|
|
178
177
|
}}
|
|
179
178
|
{...(gridId && { 'data-grid': gridId })}
|
|
180
179
|
/>
|
|
@@ -6,14 +6,16 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
|
6
6
|
import React, { type MouseEvent, type MutableRefObject, useCallback, useRef, useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import { defaultRowSize } from '@dxos/lit-grid';
|
|
9
|
-
import {
|
|
9
|
+
import { type DxGridPlaneCells } from '@dxos/lit-grid';
|
|
10
|
+
import { random } from '@dxos/random';
|
|
10
11
|
import { DropdownMenu } from '@dxos/react-ui';
|
|
11
|
-
import {
|
|
12
|
-
import { Combobox, type ComboboxRootProps } from '@dxos/react-ui-
|
|
12
|
+
import { toPlaneCellIndex } from '@dxos/react-ui-grid';
|
|
13
|
+
import { Combobox, type ComboboxRootProps, useSearchListResults } from '@dxos/react-ui-search';
|
|
14
|
+
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
13
15
|
|
|
14
16
|
import { Grid, type GridContentProps, type GridEditing, type GridRootProps } from './Grid';
|
|
15
17
|
|
|
16
|
-
const storybookItems =
|
|
18
|
+
const storybookItems = random.helpers.uniqueArray(random.commerce.productName, 16);
|
|
17
19
|
|
|
18
20
|
type GridStoryProps = GridContentProps & Pick<GridRootProps, 'onEditingChange'>;
|
|
19
21
|
|
|
@@ -62,7 +64,7 @@ const GridStory = ({ initialCells, ...props }: GridStoryProps) => {
|
|
|
62
64
|
}, []);
|
|
63
65
|
|
|
64
66
|
return (
|
|
65
|
-
<div role='none' className='
|
|
67
|
+
<div role='none' className='contents'>
|
|
66
68
|
<Grid.Root id='story' editing={editing} onEditingChange={handleEditingChange}>
|
|
67
69
|
{/* TODO(burdon): Why is this property not just "cells" or "values" */}
|
|
68
70
|
<Grid.Content {...props} initialCells={cells} onClick={handleClick} />
|
|
@@ -85,24 +87,34 @@ const GridStory = ({ initialCells, ...props }: GridStoryProps) => {
|
|
|
85
87
|
onValueChange={setMultiselectValue}
|
|
86
88
|
>
|
|
87
89
|
<Combobox.VirtualTrigger virtualRef={triggerRef} />
|
|
88
|
-
<
|
|
89
|
-
<Combobox.Input placeholder='Search...' />
|
|
90
|
-
<Combobox.List>
|
|
91
|
-
{storybookItems.map((value) => (
|
|
92
|
-
<Combobox.Item key={value}>{value}</Combobox.Item>
|
|
93
|
-
))}
|
|
94
|
-
</Combobox.List>
|
|
95
|
-
<Combobox.Arrow />
|
|
96
|
-
</Combobox.Content>
|
|
90
|
+
<ComboboxContentWithFiltering />
|
|
97
91
|
</Combobox.Root>
|
|
98
92
|
</div>
|
|
99
93
|
);
|
|
100
94
|
};
|
|
101
95
|
|
|
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
|
+
|
|
102
114
|
const meta = {
|
|
103
115
|
title: 'ui/react-ui-grid/Grid',
|
|
104
116
|
component: GridStory,
|
|
105
|
-
decorators: [withTheme],
|
|
117
|
+
decorators: [withTheme(), withLayout({ layout: 'column' })],
|
|
106
118
|
parameters: {
|
|
107
119
|
layout: 'fullscreen',
|
|
108
120
|
},
|
|
@@ -112,6 +124,8 @@ 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
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos/lit-grid/dx-grid.pcss';
|
|
6
|
-
|
|
7
5
|
import { type EventName, createComponent } from '@lit/react';
|
|
8
6
|
import { type Scope, createContextScope } from '@radix-ui/react-context';
|
|
9
7
|
import { useControllableState } from '@radix-ui/react-use-controllable-state';
|
|
@@ -16,6 +14,7 @@ import React, {
|
|
|
16
14
|
useState,
|
|
17
15
|
} from 'react';
|
|
18
16
|
|
|
17
|
+
import '@dxos/lit-grid/dx-grid.pcss';
|
|
19
18
|
import { type DxAxisResize, type DxEditRequest, type DxGridCellsSelect, DxGrid as NaturalDxGrid } from '@dxos/lit-grid';
|
|
20
19
|
|
|
21
20
|
type DxGridElement = NaturalDxGrid;
|
|
@@ -63,20 +62,23 @@ const [createGridContext, createGridScope] = createContextScope(GRID_NAME, []);
|
|
|
63
62
|
const [GridProvider, useGridContext] = createGridContext<GridContextValue>(GRID_NAME);
|
|
64
63
|
|
|
65
64
|
type GridRootProps = PropsWithChildren<
|
|
66
|
-
{
|
|
65
|
+
{
|
|
66
|
+
id: string;
|
|
67
|
+
} & Partial<{
|
|
67
68
|
editing: GridEditing;
|
|
68
69
|
defaultEditing: GridEditing;
|
|
69
70
|
onEditingChange: (nextEditing: GridEditing) => void;
|
|
70
71
|
}>
|
|
71
72
|
>;
|
|
72
73
|
|
|
74
|
+
// TODO(burdon): Make headless.
|
|
73
75
|
const GridRoot = ({
|
|
76
|
+
__gridScope,
|
|
77
|
+
children,
|
|
74
78
|
id,
|
|
75
79
|
editing: propsEditing,
|
|
76
80
|
defaultEditing,
|
|
77
81
|
onEditingChange,
|
|
78
|
-
children,
|
|
79
|
-
__gridScope,
|
|
80
82
|
}: GridScopedProps<GridRootProps>) => {
|
|
81
83
|
const [editing = null, setEditing] = useControllableState({
|
|
82
84
|
prop: propsEditing,
|
|
@@ -150,12 +152,12 @@ GridContent.displayName = GRID_CONTENT_NAME;
|
|
|
150
152
|
// Fragments
|
|
151
153
|
//
|
|
152
154
|
|
|
153
|
-
// NOTE(Zan): These fragments add border to
|
|
155
|
+
// NOTE(Zan): These fragments add border to w-end and h-end of the grid using pseudo-elements.
|
|
154
156
|
// These are offset by 1px to avoid double borders in planks.
|
|
155
157
|
const gridSeparatorInlineEnd =
|
|
156
|
-
'[&>.dx-grid]:relative [&>.dx-grid]:after:absolute [&>.dx-grid]:after:inset-
|
|
158
|
+
'[&>.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
159
|
const gridSeparatorBlockEnd =
|
|
158
|
-
'[&>.dx-grid]:relative [&>.dx-grid]:before:absolute [&>.dx-grid]:before:inset-
|
|
160
|
+
'[&>.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
161
|
|
|
160
162
|
//
|
|
161
163
|
// Exports
|