-
Notifications
You must be signed in to change notification settings - Fork 391
/
GridArrayInput.tsx
115 lines (106 loc) · 3.51 KB
/
GridArrayInput.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/* eslint-disable react/jsx-handler-names */
import {Card, Stack, Text} from '@sanity/ui'
import React, {useCallback, useMemo} from 'react'
import {Item, List} from '../../common/list'
import {ArrayOfObjectsInputProps, ObjectItem, ObjectItemProps} from '../../../../types'
import {ArrayOfObjectsItem} from '../../../../members'
import {createProtoArrayValue} from '../createProtoArrayValue'
import {UploadTargetCard} from '../../common/UploadTargetCard'
import {ArrayOfObjectsFunctions} from '../ArrayOfObjectsFunctions'
import {GridItem} from './GridItem'
import {ErrorItem} from './ErrorItem'
const EMPTY: [] = []
export function GridArrayInput<Item extends ObjectItem>(props: ArrayOfObjectsInputProps<Item>) {
const {
schemaType,
onChange,
value = EMPTY,
readOnly,
members,
elementProps,
resolveUploader,
onInsert,
onItemMove,
onUpload,
renderPreview,
renderField,
renderInput,
arrayFunctions: ArrayFunctions = ArrayOfObjectsFunctions,
} = props
const handlePrepend = useCallback(
(item: Item) => {
onInsert({items: [item], position: 'before', referenceItem: 0})
},
[onInsert]
)
const handleAppend = useCallback(
(item: Item) => {
onInsert({items: [item], position: 'after', referenceItem: -1})
},
[onInsert]
)
const sortable = schemaType.options?.sortable !== false
const renderItem = useCallback((itemProps: Omit<ObjectItemProps, 'renderDefault'>) => {
// todo: consider using a different item component for references
return <GridItem {...itemProps} />
}, [])
const memberKeys = useMemo(() => members.map((member) => member.key), [members])
return (
<Stack space={3}>
<UploadTargetCard
types={schemaType.of}
resolveUploader={resolveUploader}
onUpload={onUpload}
{...elementProps}
tabIndex={0}
>
<Stack data-ui="ArrayInput__content" space={3}>
{members?.length === 0 && (
<Card padding={3} border style={{borderStyle: 'dashed'}} radius={2}>
<Text align="center" muted size={1}>
{schemaType.placeholder || <>No items</>}
</Text>
</Card>
)}
{members?.length > 0 && (
<Card border radius={1}>
<List
columns={[2, 3, 4]}
gap={3}
padding={1}
margin={1}
items={memberKeys}
onItemMove={onItemMove}
sortable={sortable}
>
{members.map((member) => (
<Item key={member.key} sortable={sortable} id={member.key} flex={1}>
{member.kind === 'item' && (
<ArrayOfObjectsItem
member={member}
renderItem={renderItem}
renderField={renderField}
renderInput={renderInput}
renderPreview={renderPreview}
/>
)}
{member.kind === 'error' && <ErrorItem sortable={sortable} member={member} />}
</Item>
))}
</List>
</Card>
)}
</Stack>
</UploadTargetCard>
<ArrayFunctions
onChange={onChange}
onItemAppend={handleAppend}
onItemPrepend={handlePrepend}
onValueCreate={createProtoArrayValue}
readOnly={readOnly}
schemaType={schemaType}
value={value}
/>
</Stack>
)
}