@sanity/table 2.0.1 → 3.0.0
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/LICENSE +4 -4
- package/README.md +6 -24
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +431 -0
- package/dist/index.js.map +1 -0
- package/package.json +33 -72
- package/lib/index.cjs +0 -432
- package/lib/index.cjs.map +0 -1
- package/lib/index.d.cts +0 -40
- package/lib/index.d.ts +0 -40
- package/lib/index.js +0 -437
- package/lib/index.js.map +0 -1
- package/sanity.json +0 -8
- package/src/components/TableComponent.tsx +0 -260
- package/src/components/TableIcon.tsx +0 -14
- package/src/components/TableInput.tsx +0 -78
- package/src/components/TableMenu.tsx +0 -144
- package/src/components/TablePreview.tsx +0 -58
- package/src/index.ts +0 -73
- package/v2-incompatible.js +0 -11
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
/* eslint-disable consistent-return */
|
|
2
|
-
import { AddIcon } from '@sanity/icons';
|
|
3
|
-
import { Box, Button, Card, Dialog, Flex, Inline, Text } from '@sanity/ui';
|
|
4
|
-
import { uuid } from '@sanity/uuid';
|
|
5
|
-
import { type FormEvent, useState } from 'react';
|
|
6
|
-
import { type ObjectInputProps, set, unset } from 'sanity';
|
|
7
|
-
|
|
8
|
-
import { TableInput } from './TableInput';
|
|
9
|
-
import { TableMenu } from './TableMenu';
|
|
10
|
-
|
|
11
|
-
const deepClone: <T>(data: T) => T =
|
|
12
|
-
globalThis.structuredClone ?? (data => JSON.parse(JSON.stringify(data)));
|
|
13
|
-
|
|
14
|
-
export interface TableValue {
|
|
15
|
-
_type: 'table';
|
|
16
|
-
rows: TableRow[];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type TableProps = ObjectInputProps<TableValue>;
|
|
20
|
-
|
|
21
|
-
export type TableRow = {
|
|
22
|
-
_type: string;
|
|
23
|
-
_key: string;
|
|
24
|
-
cells: string[];
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
// TODO refactor deeplone stuff to use proper patches
|
|
28
|
-
// TODO use callback all the things
|
|
29
|
-
|
|
30
|
-
export const TableComponent = (props: TableProps & { rowType?: string }) => {
|
|
31
|
-
const { rowType = 'tableRow', value, onChange } = props;
|
|
32
|
-
const [dialog, setDialog] = useState<{
|
|
33
|
-
type: string;
|
|
34
|
-
callback: () => void;
|
|
35
|
-
} | null>(null);
|
|
36
|
-
|
|
37
|
-
const updateValue = (v?: Omit<TableValue, '_type'>) => {
|
|
38
|
-
return onChange(set(v));
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const resetValue = () => {
|
|
42
|
-
return onChange(unset());
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const createTable = () => {
|
|
46
|
-
const newValue: Omit<TableValue, '_type'> = {
|
|
47
|
-
rows: [
|
|
48
|
-
{
|
|
49
|
-
_type: rowType,
|
|
50
|
-
_key: uuid(),
|
|
51
|
-
cells: ['', ''],
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
_type: rowType,
|
|
55
|
-
_key: uuid(),
|
|
56
|
-
cells: ['', ''],
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
};
|
|
60
|
-
return updateValue({ ...value, ...newValue });
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const confirmRemoveTable = () => {
|
|
64
|
-
setDialog({ type: 'table', callback: removeTable });
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const removeTable = () => {
|
|
68
|
-
resetValue();
|
|
69
|
-
setDialog(null);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const addRows = (count = 1) => {
|
|
73
|
-
if (!value) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
const newValue = deepClone(value);
|
|
77
|
-
// Calculate the column count from the first row
|
|
78
|
-
const columnCount = value?.rows[0].cells.length ?? 0;
|
|
79
|
-
for (let i = 0; i < count; i++) {
|
|
80
|
-
// Add as many cells as we have columns
|
|
81
|
-
newValue.rows.push({
|
|
82
|
-
_type: rowType,
|
|
83
|
-
_key: uuid(),
|
|
84
|
-
cells: Array(columnCount).fill(''),
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
// eslint-disable-next-line consistent-return
|
|
88
|
-
return updateValue(newValue);
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const addRowAt = (index = 0) => {
|
|
92
|
-
if (!value) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
const newValue = deepClone(value);
|
|
96
|
-
// Calculate the column count from the first row
|
|
97
|
-
const columnCount = value.rows[0].cells.length;
|
|
98
|
-
|
|
99
|
-
newValue.rows.splice(index, 0, {
|
|
100
|
-
_type: rowType,
|
|
101
|
-
_key: uuid(),
|
|
102
|
-
cells: Array(columnCount).fill(''),
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// eslint-disable-next-line consistent-return
|
|
106
|
-
return updateValue(newValue);
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const removeRow = (index: number) => {
|
|
110
|
-
if (!value) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
const newValue = deepClone(value);
|
|
114
|
-
newValue.rows.splice(index, 1);
|
|
115
|
-
updateValue(newValue);
|
|
116
|
-
setDialog(null);
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
const confirmRemoveRow = (index: number) => {
|
|
120
|
-
if (!value) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
if (value.rows.length <= 1) return confirmRemoveTable();
|
|
124
|
-
return setDialog({ type: 'row', callback: () => removeRow(index) });
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
const confirmRemoveColumn = (index: number) => {
|
|
128
|
-
if (!value) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
if (value.rows[0].cells.length <= 1) return confirmRemoveTable();
|
|
132
|
-
return setDialog({ type: 'column', callback: () => removeColumn(index) });
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
const addColumns = (count: number) => {
|
|
136
|
-
if (!value) {
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
const newValue = deepClone(value);
|
|
140
|
-
// Add a cell to each of the rows
|
|
141
|
-
newValue.rows.forEach((_, i) => {
|
|
142
|
-
for (let j = 0; j < count; j++) {
|
|
143
|
-
newValue.rows[i].cells.push('');
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
return updateValue(newValue);
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
const addColumnAt = (index: number) => {
|
|
150
|
-
if (!value) {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
const newValue = deepClone(value);
|
|
154
|
-
|
|
155
|
-
newValue.rows.forEach((_, i) => {
|
|
156
|
-
newValue.rows[i].cells.splice(index, 0, '');
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
return updateValue(newValue);
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
const removeColumn = (index: number) => {
|
|
163
|
-
if (!value) {
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
const newValue = deepClone(value);
|
|
167
|
-
newValue.rows.forEach(row => {
|
|
168
|
-
row.cells.splice(index, 1);
|
|
169
|
-
});
|
|
170
|
-
updateValue(newValue);
|
|
171
|
-
setDialog(null);
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
const updateCell = (
|
|
175
|
-
e: FormEvent<HTMLInputElement>,
|
|
176
|
-
rowIndex: number,
|
|
177
|
-
cellIndex: number
|
|
178
|
-
) => {
|
|
179
|
-
if (!value) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
const newValue = deepClone(value);
|
|
183
|
-
newValue.rows[rowIndex].cells[cellIndex] = (
|
|
184
|
-
e.target as HTMLInputElement
|
|
185
|
-
).value;
|
|
186
|
-
return updateValue(newValue);
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
return (
|
|
190
|
-
<div>
|
|
191
|
-
{dialog && (
|
|
192
|
-
<Dialog
|
|
193
|
-
header={`Remove ${dialog.type}`}
|
|
194
|
-
id="dialog-remove"
|
|
195
|
-
onClose={() => setDialog(null)}
|
|
196
|
-
zOffset={1000}
|
|
197
|
-
>
|
|
198
|
-
<Card padding={4}>
|
|
199
|
-
<Text>Are you sure you want to remove this {dialog.type}?</Text>
|
|
200
|
-
<Box marginTop={4}>
|
|
201
|
-
<Inline space={1} style={{ textAlign: 'right' }}>
|
|
202
|
-
<Button
|
|
203
|
-
text="Cancel"
|
|
204
|
-
mode="ghost"
|
|
205
|
-
onClick={() => setDialog(null)}
|
|
206
|
-
/>
|
|
207
|
-
<Button
|
|
208
|
-
text="Confirm"
|
|
209
|
-
tone="critical"
|
|
210
|
-
onClick={() => dialog.callback()}
|
|
211
|
-
/>
|
|
212
|
-
</Inline>
|
|
213
|
-
</Box>
|
|
214
|
-
</Card>
|
|
215
|
-
</Dialog>
|
|
216
|
-
)}
|
|
217
|
-
<Box>
|
|
218
|
-
<Flex justify="flex-end">
|
|
219
|
-
{value?.rows?.length && (
|
|
220
|
-
<TableMenu
|
|
221
|
-
addColumns={addColumns}
|
|
222
|
-
addColumnAt={addColumnAt}
|
|
223
|
-
addRows={addRows}
|
|
224
|
-
addRowAt={addRowAt}
|
|
225
|
-
remove={confirmRemoveTable}
|
|
226
|
-
placement="left"
|
|
227
|
-
/>
|
|
228
|
-
)}
|
|
229
|
-
</Flex>
|
|
230
|
-
</Box>
|
|
231
|
-
{value?.rows?.length && (
|
|
232
|
-
<TableInput
|
|
233
|
-
rows={value.rows}
|
|
234
|
-
removeRow={confirmRemoveRow}
|
|
235
|
-
removeColumn={confirmRemoveColumn}
|
|
236
|
-
updateCell={updateCell}
|
|
237
|
-
/>
|
|
238
|
-
)}
|
|
239
|
-
{(!value || !value?.rows?.length) && (
|
|
240
|
-
<Inline space={1}>
|
|
241
|
-
<Button
|
|
242
|
-
fontSize={1}
|
|
243
|
-
padding={3}
|
|
244
|
-
icon={AddIcon}
|
|
245
|
-
text="Create Table"
|
|
246
|
-
tone="primary"
|
|
247
|
-
mode="ghost"
|
|
248
|
-
onClick={createTable}
|
|
249
|
-
/>
|
|
250
|
-
</Inline>
|
|
251
|
-
)}
|
|
252
|
-
</div>
|
|
253
|
-
);
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
export function createTableComponent(rowType: string) {
|
|
257
|
-
return function Table(props: TableProps) {
|
|
258
|
-
return <TableComponent {...props} rowType={rowType} />;
|
|
259
|
-
};
|
|
260
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { RemoveIcon } from '@sanity/icons';
|
|
2
|
-
import { Box, Button, TextInput } from '@sanity/ui';
|
|
3
|
-
import type { FormEvent } from 'react';
|
|
4
|
-
|
|
5
|
-
import type { TableRow } from './TableComponent';
|
|
6
|
-
|
|
7
|
-
interface TableInputProps {
|
|
8
|
-
rows: TableRow[];
|
|
9
|
-
updateCell: (
|
|
10
|
-
e: FormEvent<HTMLInputElement>,
|
|
11
|
-
rowIndex: number,
|
|
12
|
-
cellIndex: number
|
|
13
|
-
) => void;
|
|
14
|
-
removeRow: (index: number) => void;
|
|
15
|
-
removeColumn: (index: number) => void;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const TableInput = (props: TableInputProps) => {
|
|
19
|
-
const updateCell = props.updateCell;
|
|
20
|
-
|
|
21
|
-
const renderRowCell = (rowIndex: number) =>
|
|
22
|
-
function RowCell(cell: string, cellIndex: number) {
|
|
23
|
-
return (
|
|
24
|
-
<td key={`cell-${rowIndex}-${cellIndex}`}>
|
|
25
|
-
<TextInput
|
|
26
|
-
fontSize={1}
|
|
27
|
-
padding={3}
|
|
28
|
-
value={cell}
|
|
29
|
-
onChange={e => updateCell(e, rowIndex, cellIndex)}
|
|
30
|
-
/>
|
|
31
|
-
</td>
|
|
32
|
-
);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const renderRow = (row: TableRow, rowIndex: number) => {
|
|
36
|
-
const renderCell = renderRowCell(rowIndex);
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<tr key={`row-${rowIndex}`}>
|
|
40
|
-
{row.cells.map(renderCell)}
|
|
41
|
-
{
|
|
42
|
-
<td key={rowIndex}>
|
|
43
|
-
<Box marginLeft={1} style={{ textAlign: 'center' }}>
|
|
44
|
-
<Button
|
|
45
|
-
icon={RemoveIcon}
|
|
46
|
-
padding={2}
|
|
47
|
-
onClick={() => props.removeRow(rowIndex)}
|
|
48
|
-
mode="bleed"
|
|
49
|
-
/>
|
|
50
|
-
</Box>
|
|
51
|
-
</td>
|
|
52
|
-
}
|
|
53
|
-
</tr>
|
|
54
|
-
);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
return (
|
|
58
|
-
<table style={{ width: '100%' }}>
|
|
59
|
-
<tbody>
|
|
60
|
-
{props.rows.map(renderRow)}
|
|
61
|
-
<tr>
|
|
62
|
-
{(props.rows[0]?.cells || []).map((_, i) => (
|
|
63
|
-
<td key={i}>
|
|
64
|
-
<Box marginTop={1} style={{ textAlign: 'center' }}>
|
|
65
|
-
<Button
|
|
66
|
-
icon={RemoveIcon}
|
|
67
|
-
padding={2}
|
|
68
|
-
onClick={() => props.removeColumn(i)}
|
|
69
|
-
mode="bleed"
|
|
70
|
-
/>
|
|
71
|
-
</Box>
|
|
72
|
-
</td>
|
|
73
|
-
))}
|
|
74
|
-
</tr>
|
|
75
|
-
</tbody>
|
|
76
|
-
</table>
|
|
77
|
-
);
|
|
78
|
-
};
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { AddIcon, ControlsIcon, WarningOutlineIcon } from '@sanity/icons';
|
|
2
|
-
import {
|
|
3
|
-
Box,
|
|
4
|
-
Button,
|
|
5
|
-
Card,
|
|
6
|
-
Dialog,
|
|
7
|
-
Inline,
|
|
8
|
-
Menu,
|
|
9
|
-
MenuButton,
|
|
10
|
-
MenuDivider,
|
|
11
|
-
MenuItem,
|
|
12
|
-
Placement,
|
|
13
|
-
TextInput,
|
|
14
|
-
} from '@sanity/ui';
|
|
15
|
-
import { type FormEventHandler, useState } from 'react';
|
|
16
|
-
|
|
17
|
-
interface TableMenuProps {
|
|
18
|
-
addColumns: (count: number) => void;
|
|
19
|
-
addColumnAt: (index: number) => void;
|
|
20
|
-
addRows: (count: number) => void;
|
|
21
|
-
addRowAt: (index: number) => void;
|
|
22
|
-
remove: () => void;
|
|
23
|
-
placement: Placement;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const TableMenu = (props: TableMenuProps) => {
|
|
27
|
-
const { remove: handleRemove } = props;
|
|
28
|
-
const [dialog, setDialog] = useState<{
|
|
29
|
-
type: string;
|
|
30
|
-
callback: (count: number) => void;
|
|
31
|
-
} | null>(null);
|
|
32
|
-
|
|
33
|
-
const [count, setCount] = useState<string | undefined>('');
|
|
34
|
-
|
|
35
|
-
const updateCount: FormEventHandler<HTMLInputElement> = e => {
|
|
36
|
-
setCount(e.currentTarget.value);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const addRows = () => {
|
|
40
|
-
setDialog({ type: 'rows', callback: c => props.addRows(c) });
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const addRowAt = () => {
|
|
44
|
-
setDialog({ type: 'rows', callback: index => props.addRowAt(index) });
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const addColumns = () => {
|
|
48
|
-
setDialog({
|
|
49
|
-
type: 'columns',
|
|
50
|
-
callback: c => props.addColumns(c),
|
|
51
|
-
});
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const addColumnsAt = () => {
|
|
55
|
-
setDialog({ type: 'columns', callback: index => props.addColumnAt(index) });
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const onConfirm = () => {
|
|
59
|
-
const parsedCount = parseInt(count ?? '0', 10);
|
|
60
|
-
|
|
61
|
-
if (parsedCount < 100) {
|
|
62
|
-
setDialog(null);
|
|
63
|
-
dialog?.callback(parsedCount);
|
|
64
|
-
setCount(undefined);
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
return (
|
|
69
|
-
<>
|
|
70
|
-
{dialog && (
|
|
71
|
-
<Dialog
|
|
72
|
-
header={`Add ${dialog.type}`}
|
|
73
|
-
id="dialog-add"
|
|
74
|
-
onClose={() => setDialog(null)}
|
|
75
|
-
zOffset={1000}
|
|
76
|
-
>
|
|
77
|
-
<Card padding={4}>
|
|
78
|
-
<TextInput
|
|
79
|
-
style={{ textAlign: 'left' }}
|
|
80
|
-
fontSize={2}
|
|
81
|
-
padding={3}
|
|
82
|
-
type="number"
|
|
83
|
-
value={count}
|
|
84
|
-
onChange={updateCount}
|
|
85
|
-
/>
|
|
86
|
-
<Box marginTop={4}>
|
|
87
|
-
<Inline space={1} style={{ textAlign: 'right' }}>
|
|
88
|
-
<Button
|
|
89
|
-
text="Cancel"
|
|
90
|
-
mode="ghost"
|
|
91
|
-
onClick={() => setDialog(null)}
|
|
92
|
-
/>
|
|
93
|
-
<Button text="Confirm" tone="critical" onClick={onConfirm} />
|
|
94
|
-
</Inline>
|
|
95
|
-
</Box>
|
|
96
|
-
</Card>
|
|
97
|
-
</Dialog>
|
|
98
|
-
)}
|
|
99
|
-
<MenuButton
|
|
100
|
-
button={
|
|
101
|
-
<Button icon={ControlsIcon} fontSize={1} padding={2} mode="ghost" />
|
|
102
|
-
}
|
|
103
|
-
id="menu-button-example"
|
|
104
|
-
menu={
|
|
105
|
-
<Menu>
|
|
106
|
-
<MenuItem
|
|
107
|
-
icon={AddIcon}
|
|
108
|
-
fontSize={1}
|
|
109
|
-
text="Add Row(s)"
|
|
110
|
-
onClick={addRows}
|
|
111
|
-
/>
|
|
112
|
-
<MenuItem
|
|
113
|
-
icon={AddIcon}
|
|
114
|
-
fontSize={1}
|
|
115
|
-
text="Add Row At Index"
|
|
116
|
-
onClick={addRowAt}
|
|
117
|
-
/>
|
|
118
|
-
<MenuItem
|
|
119
|
-
icon={AddIcon}
|
|
120
|
-
fontSize={1}
|
|
121
|
-
text="Add Column(s)"
|
|
122
|
-
onClick={addColumns}
|
|
123
|
-
/>
|
|
124
|
-
<MenuItem
|
|
125
|
-
icon={AddIcon}
|
|
126
|
-
fontSize={1}
|
|
127
|
-
text="Add Column At Index"
|
|
128
|
-
onClick={addColumnsAt}
|
|
129
|
-
/>
|
|
130
|
-
<MenuDivider />
|
|
131
|
-
<MenuItem
|
|
132
|
-
icon={WarningOutlineIcon}
|
|
133
|
-
fontSize={1}
|
|
134
|
-
text="Remove"
|
|
135
|
-
tone="critical"
|
|
136
|
-
onClick={handleRemove}
|
|
137
|
-
/>
|
|
138
|
-
</Menu>
|
|
139
|
-
}
|
|
140
|
-
popover={{ placement: props.placement }}
|
|
141
|
-
/>
|
|
142
|
-
</>
|
|
143
|
-
);
|
|
144
|
-
};
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { Box, Card, Grid, Inline, Label, Text } from '@sanity/ui';
|
|
2
|
-
import type { PreviewProps } from 'sanity';
|
|
3
|
-
|
|
4
|
-
import type { TableRow } from './TableComponent';
|
|
5
|
-
import { TableIcon } from './TableIcon';
|
|
6
|
-
|
|
7
|
-
interface ValueProps {
|
|
8
|
-
rows?: TableRow[];
|
|
9
|
-
title?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const Table = ({ rows }: { rows: TableRow[] }) => {
|
|
13
|
-
const numCols = rows.length === 0 ? 0 : rows[0].cells.length;
|
|
14
|
-
|
|
15
|
-
return (
|
|
16
|
-
<Grid columns={numCols} padding={2}>
|
|
17
|
-
{rows.map(row =>
|
|
18
|
-
row.cells.map((cell, i) => (
|
|
19
|
-
<Card
|
|
20
|
-
key={row._key + i}
|
|
21
|
-
padding={2}
|
|
22
|
-
style={{ outline: '1px solid #DFE2E9' }}
|
|
23
|
-
>
|
|
24
|
-
<Text style={{ textOverflow: 'elipsis' }}>{cell}</Text>
|
|
25
|
-
</Card>
|
|
26
|
-
))
|
|
27
|
-
)}
|
|
28
|
-
</Grid>
|
|
29
|
-
);
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export const TablePreview = (props: ValueProps & PreviewProps) => {
|
|
33
|
-
const { schemaType, rows = [], title = 'Title missing' } = props;
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<>
|
|
37
|
-
<Box padding={3}>
|
|
38
|
-
<Inline space={3}>
|
|
39
|
-
<Card>
|
|
40
|
-
<Label size={4}>
|
|
41
|
-
<TableIcon />
|
|
42
|
-
</Label>
|
|
43
|
-
</Card>
|
|
44
|
-
<Card>
|
|
45
|
-
<Text>{schemaType?.title ?? title}</Text>
|
|
46
|
-
</Card>
|
|
47
|
-
</Inline>
|
|
48
|
-
</Box>
|
|
49
|
-
<Box padding={2}>
|
|
50
|
-
{rows.length === 0 ? (
|
|
51
|
-
<Label muted>Empty Table</Label>
|
|
52
|
-
) : (
|
|
53
|
-
<Table rows={rows} />
|
|
54
|
-
)}
|
|
55
|
-
</Box>
|
|
56
|
-
</>
|
|
57
|
-
);
|
|
58
|
-
};
|
package/src/index.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { definePlugin, defineType } from 'sanity';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
createTableComponent,
|
|
5
|
-
TableComponent,
|
|
6
|
-
} from './components/TableComponent';
|
|
7
|
-
import { TablePreview } from './components/TablePreview';
|
|
8
|
-
export type {
|
|
9
|
-
TableProps,
|
|
10
|
-
TableRow,
|
|
11
|
-
TableValue,
|
|
12
|
-
} from './components/TableComponent';
|
|
13
|
-
|
|
14
|
-
export { TableComponent, TablePreview };
|
|
15
|
-
|
|
16
|
-
export interface TableConfig {
|
|
17
|
-
rowType?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const table = definePlugin<TableConfig | void>(config => {
|
|
21
|
-
const tableRowSchema = defineType({
|
|
22
|
-
title: 'Table Row',
|
|
23
|
-
name: config?.rowType || 'tableRow',
|
|
24
|
-
type: 'object',
|
|
25
|
-
fields: [
|
|
26
|
-
{
|
|
27
|
-
name: 'cells',
|
|
28
|
-
type: 'array',
|
|
29
|
-
of: [{ type: 'string' }],
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const tableSchema = defineType({
|
|
35
|
-
title: 'Table',
|
|
36
|
-
name: 'table',
|
|
37
|
-
type: 'object',
|
|
38
|
-
fields: [
|
|
39
|
-
{
|
|
40
|
-
name: 'rows',
|
|
41
|
-
type: 'array',
|
|
42
|
-
of: [
|
|
43
|
-
{
|
|
44
|
-
type: tableRowSchema.name,
|
|
45
|
-
},
|
|
46
|
-
],
|
|
47
|
-
},
|
|
48
|
-
],
|
|
49
|
-
components: {
|
|
50
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
51
|
-
input: createTableComponent(tableRowSchema.name) as any,
|
|
52
|
-
preview: TablePreview as any,
|
|
53
|
-
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
54
|
-
},
|
|
55
|
-
preview: {
|
|
56
|
-
select: {
|
|
57
|
-
rows: 'rows',
|
|
58
|
-
title: 'title',
|
|
59
|
-
},
|
|
60
|
-
prepare: ({ title, rows = [] }) => ({
|
|
61
|
-
title,
|
|
62
|
-
rows,
|
|
63
|
-
}),
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
name: 'table',
|
|
69
|
-
schema: {
|
|
70
|
-
types: [tableRowSchema, tableSchema],
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
});
|
package/v2-incompatible.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const { showIncompatiblePluginDialog } = require('@sanity/incompatible-plugin');
|
|
2
|
-
const { name, version, sanityExchangeUrl } = require('./package.json');
|
|
3
|
-
|
|
4
|
-
export default showIncompatiblePluginDialog({
|
|
5
|
-
name: name,
|
|
6
|
-
versions: {
|
|
7
|
-
v3: version,
|
|
8
|
-
v2: undefined,
|
|
9
|
-
},
|
|
10
|
-
sanityExchangeUrl,
|
|
11
|
-
});
|