@dxos/react-ui-grid 0.8.3 → 0.8.4-main.1068cf700f
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 +142 -153
- 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 -4
- package/dist/types/src/CellEditor/CellEditor.d.ts.map +1 -1
- package/dist/types/src/CellEditor/CellEditor.stories.d.ts +16 -0
- package/dist/types/src/CellEditor/CellEditor.stories.d.ts.map +1 -0
- 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 +4 -4
- 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 +88 -0
- package/src/CellEditor/CellEditor.tsx +30 -16
- package/src/CellEditor/GridCellEditor.tsx +9 -5
- package/src/Grid/Grid.stories.tsx +68 -33
- package/src/Grid/Grid.tsx +12 -9
package/package.json
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-grid",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4-main.1068cf700f",
|
|
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.
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/
|
|
38
|
+
"@dxos/lit-grid": "0.8.4-main.1068cf700f",
|
|
39
|
+
"@dxos/react-ui-editor": "0.8.4-main.1068cf700f",
|
|
40
|
+
"@dxos/ui-editor": "0.8.4-main.1068cf700f",
|
|
41
|
+
"@dxos/util": "0.8.4-main.1068cf700f"
|
|
37
42
|
},
|
|
38
43
|
"devDependencies": {
|
|
39
|
-
"@types/react": "~
|
|
40
|
-
"@types/react-dom": "~
|
|
41
|
-
"react": "~
|
|
42
|
-
"react-dom": "~
|
|
43
|
-
"vite": "
|
|
44
|
-
"@dxos/random": "0.8.
|
|
45
|
-
"@dxos/react-ui": "0.8.
|
|
46
|
-
"@dxos/react-ui-searchlist": "0.8.
|
|
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.9",
|
|
49
|
+
"@dxos/random": "0.8.4-main.1068cf700f",
|
|
50
|
+
"@dxos/react-ui": "0.8.4-main.1068cf700f",
|
|
51
|
+
"@dxos/react-ui-searchlist": "0.8.4-main.1068cf700f",
|
|
52
|
+
"@dxos/storybook-utils": "0.8.4-main.1068cf700f",
|
|
53
|
+
"@dxos/ui-theme": "0.8.4-main.1068cf700f"
|
|
49
54
|
},
|
|
50
55
|
"peerDependencies": {
|
|
51
|
-
"react": "~
|
|
52
|
-
"react-dom": "~
|
|
53
|
-
"@dxos/react-ui": "0.8.
|
|
54
|
-
"@dxos/
|
|
56
|
+
"react": "~19.2.3",
|
|
57
|
+
"react-dom": "~19.2.3",
|
|
58
|
+
"@dxos/react-ui": "0.8.4-main.1068cf700f",
|
|
59
|
+
"@dxos/ui-theme": "0.8.4-main.1068cf700f"
|
|
55
60
|
},
|
|
56
61
|
"publishConfig": {
|
|
57
62
|
"access": "public"
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
import React, { useState } from 'react';
|
|
7
|
+
|
|
8
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
9
|
+
|
|
10
|
+
import { CellEditor, type CellEditorProps, type EditorKeyEvent, editorKeys } from './CellEditor';
|
|
11
|
+
|
|
12
|
+
const DefaultStory = (props: CellEditorProps) => {
|
|
13
|
+
const [value, setValue] = useState(props.value || 'Edit me');
|
|
14
|
+
const [lastAction, setLastAction] = useState<string>('');
|
|
15
|
+
|
|
16
|
+
const handleBlur = (newValue?: string) => {
|
|
17
|
+
if (newValue !== undefined) {
|
|
18
|
+
setValue(newValue);
|
|
19
|
+
setLastAction(`Blur: ${newValue}`);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const handleKeyEvent = (newValue: string | undefined, event: EditorKeyEvent) => {
|
|
24
|
+
if (newValue !== undefined) {
|
|
25
|
+
setValue(newValue);
|
|
26
|
+
setLastAction(`Key: ${event.key}${event.shift ? ' + Shift' : ''}, Value: ${newValue}`);
|
|
27
|
+
} else {
|
|
28
|
+
setLastAction(`Key: ${event.key}${event.shift ? ' + Shift' : ''}, Cancelled`);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Create an extension with editor keys
|
|
33
|
+
const extensions = props.extensions || [
|
|
34
|
+
editorKeys({
|
|
35
|
+
onClose: handleKeyEvent,
|
|
36
|
+
onNav: (value, event) => {
|
|
37
|
+
setLastAction(`Navigation: ${event.key}, Value: ${value}`);
|
|
38
|
+
},
|
|
39
|
+
}),
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div className='flex flex-col gap-4 p-4'>
|
|
44
|
+
<div className='text-sm'>
|
|
45
|
+
Current value: <span className='font-mono'>{value}</span>
|
|
46
|
+
</div>
|
|
47
|
+
<div className='text-sm'>
|
|
48
|
+
Last action: <span className='font-mono'>{lastAction}</span>
|
|
49
|
+
</div>
|
|
50
|
+
<div className='relative border border-separator bs-[100px] is-[300px]'>
|
|
51
|
+
<CellEditor
|
|
52
|
+
value={value}
|
|
53
|
+
extensions={extensions}
|
|
54
|
+
autoFocus={props.autoFocus}
|
|
55
|
+
onBlur={handleBlur}
|
|
56
|
+
box={{
|
|
57
|
+
insetInlineStart: 10,
|
|
58
|
+
insetBlockStart: 10,
|
|
59
|
+
inlineSize: 280,
|
|
60
|
+
blockSize: 30,
|
|
61
|
+
}}
|
|
62
|
+
gridId='demo-grid'
|
|
63
|
+
/>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const meta = {
|
|
70
|
+
title: 'ui/react-ui-grid/CellEditor',
|
|
71
|
+
component: CellEditor,
|
|
72
|
+
render: DefaultStory,
|
|
73
|
+
decorators: [withTheme()],
|
|
74
|
+
parameters: {
|
|
75
|
+
layout: 'centered',
|
|
76
|
+
},
|
|
77
|
+
} satisfies Meta<typeof CellEditor>;
|
|
78
|
+
|
|
79
|
+
export default meta;
|
|
80
|
+
|
|
81
|
+
type Story = StoryObj<typeof meta>;
|
|
82
|
+
|
|
83
|
+
export const Default: Story = {
|
|
84
|
+
args: {
|
|
85
|
+
value: 'Edit me',
|
|
86
|
+
autoFocus: true,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
@@ -8,13 +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
|
-
} from '@dxos/
|
|
16
|
+
filterChars,
|
|
17
|
+
} from '@dxos/ui-editor';
|
|
18
|
+
import { mx } from '@dxos/ui-theme';
|
|
18
19
|
|
|
19
20
|
import { type GridEditBox } from '../Grid';
|
|
20
21
|
|
|
@@ -114,12 +115,14 @@ export const editorKeys = ({ onNav, onClose }: EditorKeysProps): Extension => {
|
|
|
114
115
|
|
|
115
116
|
export type CellEditorProps = {
|
|
116
117
|
value?: string;
|
|
117
|
-
|
|
118
|
+
extensions?: Extension;
|
|
118
119
|
box?: GridEditBox;
|
|
119
120
|
gridId?: string;
|
|
120
|
-
|
|
121
|
+
onBlur?: EditorBlurHandler;
|
|
122
|
+
} & Pick<UseTextEditorProps, 'autoFocus'> &
|
|
123
|
+
Pick<ThemeExtensionsOptions, 'slots'>;
|
|
121
124
|
|
|
122
|
-
export const CellEditor = ({ value,
|
|
125
|
+
export const CellEditor = ({ value, extensions, box, gridId, autoFocus, slots, onBlur }: CellEditorProps) => {
|
|
123
126
|
const { themeMode } = useThemeContext();
|
|
124
127
|
const { parentRef } = useTextEditor(() => {
|
|
125
128
|
return {
|
|
@@ -127,38 +130,49 @@ export const CellEditor = ({ value, extension, autoFocus, onBlur, box, gridId }:
|
|
|
127
130
|
initialValue: value,
|
|
128
131
|
selection: { anchor: value?.length ?? 0 },
|
|
129
132
|
extensions: [
|
|
130
|
-
|
|
131
|
-
|
|
133
|
+
extensions ?? [],
|
|
134
|
+
filterChars(/[\n\r]+/),
|
|
132
135
|
EditorView.focusChangeEffect.of((state, focusing) => {
|
|
133
136
|
if (!focusing) {
|
|
134
137
|
onBlur?.(state.doc.toString());
|
|
135
138
|
}
|
|
136
139
|
return null;
|
|
137
140
|
}),
|
|
138
|
-
createBasicExtensions({ lineWrapping:
|
|
141
|
+
createBasicExtensions({ lineWrapping: true }),
|
|
139
142
|
createThemeExtensions({
|
|
140
143
|
themeMode,
|
|
141
144
|
slots: {
|
|
142
145
|
editor: {
|
|
143
|
-
className:
|
|
146
|
+
className: mx(
|
|
147
|
+
'!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]',
|
|
148
|
+
slots?.editor?.className,
|
|
149
|
+
),
|
|
150
|
+
},
|
|
151
|
+
scroll: {
|
|
152
|
+
className: mx(
|
|
153
|
+
'!overflow-x-hidden !plb-[max(0,calc(var(--dx-grid-cell-editor-padding-block)-1px))] !pie-0 !pis-[--dx-grid-cell-editor-padding-inline]',
|
|
154
|
+
slots?.scroll?.className,
|
|
155
|
+
),
|
|
144
156
|
},
|
|
145
157
|
content: {
|
|
146
|
-
className:
|
|
147
|
-
'!border !border-transparent !pli-[var(--dx-grid-cell-padding-inline)] !plb-[var(--dx-grid-cell-padding-block)]',
|
|
158
|
+
className: mx('!break-normal', slots?.content?.className),
|
|
148
159
|
},
|
|
149
160
|
},
|
|
150
161
|
}),
|
|
151
162
|
],
|
|
152
163
|
};
|
|
153
|
-
}, [
|
|
164
|
+
}, [extensions, autoFocus, value, onBlur, themeMode, slots]);
|
|
154
165
|
|
|
155
166
|
return (
|
|
156
167
|
<div
|
|
157
168
|
data-testid='grid.cell-editor'
|
|
158
169
|
ref={parentRef}
|
|
159
|
-
className='absolute z-[1]'
|
|
170
|
+
className='absolute z-[1] dx-grid__cell-editor'
|
|
160
171
|
style={{
|
|
161
|
-
|
|
172
|
+
insetInlineStart: box?.insetInlineStart ?? '0px',
|
|
173
|
+
insetBlockStart: box?.insetBlockStart ?? '0px',
|
|
174
|
+
minInlineSize: box?.inlineSize ?? '180px',
|
|
175
|
+
minBlockSize: box?.blockSize ?? '30px',
|
|
162
176
|
...{ '--dx-gridCellWidth': `${box?.inlineSize ?? 200}px` },
|
|
163
177
|
}}
|
|
164
178
|
{...(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, '
|
|
12
|
+
Pick<CellEditorProps, 'extensions' | 'onBlur' | 'slots'> & {
|
|
13
|
+
getCellContent: (index: DxGridCellIndex) => string | undefined;
|
|
14
|
+
}
|
|
12
15
|
>;
|
|
13
16
|
|
|
14
|
-
export const GridCellEditor = ({
|
|
15
|
-
const { id, editing, setEditing, editBox } = useGridContext('
|
|
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
|
-
|
|
34
|
+
extensions={extensions}
|
|
32
35
|
gridId={id}
|
|
36
|
+
slots={slots}
|
|
33
37
|
/>
|
|
34
38
|
) : null;
|
|
35
39
|
};
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
7
|
-
import { type Meta, type StoryObj } from '@storybook/react';
|
|
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-searchlist';
|
|
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',
|
|
@@ -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 bs-full is-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='bs-full flex justify-center'>
|
|
213
|
+
<div className='bs-full is-[288px] border-x border-separator'>
|
|
214
|
+
<GridStory {...args} />
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
),
|
|
183
218
|
};
|
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 {
|
|
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,
|
|
12
|
-
forwardRef,
|
|
13
12
|
type PropsWithChildren,
|
|
13
|
+
forwardRef,
|
|
14
14
|
useCallback,
|
|
15
15
|
useEffect,
|
|
16
16
|
useState,
|
|
@@ -63,7 +63,9 @@ 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;
|
|
@@ -71,12 +73,12 @@ type GridRootProps = PropsWithChildren<
|
|
|
71
73
|
>;
|
|
72
74
|
|
|
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,
|
|
@@ -102,13 +104,13 @@ const GridRoot = ({
|
|
|
102
104
|
|
|
103
105
|
GridRoot.displayName = GRID_NAME;
|
|
104
106
|
|
|
107
|
+
const GRID_CONTENT_NAME = 'GridContent';
|
|
108
|
+
|
|
105
109
|
type GridContentProps = Omit<ComponentProps<typeof DxGrid>, 'onEdit'> & {
|
|
106
110
|
getCells?: NaturalDxGrid['getCells'];
|
|
107
111
|
activeRefs?: string;
|
|
108
112
|
};
|
|
109
113
|
|
|
110
|
-
const GRID_CONTENT_NAME = 'GridContent';
|
|
111
|
-
|
|
112
114
|
const GridContent = forwardRef<NaturalDxGrid, GridScopedProps<GridContentProps>>((props, forwardedRef) => {
|
|
113
115
|
const { id, editing, setEditBox, setEditing } = useGridContext(GRID_CONTENT_NAME, props.__gridScope);
|
|
114
116
|
const [dxGrid, setDxGridInternal] = useState<NaturalDxGrid | null>(null);
|
|
@@ -166,7 +168,7 @@ export const Grid = {
|
|
|
166
168
|
Content: GridContent,
|
|
167
169
|
};
|
|
168
170
|
|
|
169
|
-
export { GridRoot, GridContent,
|
|
171
|
+
export { GridRoot, GridContent, createGridScope, gridSeparatorInlineEnd, gridSeparatorBlockEnd, useGridContext };
|
|
170
172
|
|
|
171
173
|
export type { GridRootProps, GridContentProps, GridEditing, GridEditBox, GridScopedProps, DxGridElement };
|
|
172
174
|
|
|
@@ -178,6 +180,7 @@ export {
|
|
|
178
180
|
toPlaneCellIndex,
|
|
179
181
|
parseCellIndex,
|
|
180
182
|
cellQuery,
|
|
183
|
+
DxEditRequest,
|
|
181
184
|
} from '@dxos/lit-grid';
|
|
182
185
|
|
|
183
186
|
export type {
|