@sanity/assist 5.0.4 → 6.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.
Files changed (131) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +28 -254
  3. package/dist/index.d.ts +322 -410
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +3181 -2649
  6. package/dist/index.js.map +1 -1
  7. package/package.json +38 -78
  8. package/dist/index.cjs +0 -4239
  9. package/dist/index.cjs.map +0 -1
  10. package/dist/index.d.cts +0 -791
  11. package/sanity.json +0 -8
  12. package/src/_lib/connector/ConnectFromRegion.tsx +0 -25
  13. package/src/_lib/connector/ConnectToRegion.tsx +0 -23
  14. package/src/_lib/connector/ConnectorRegion.tsx +0 -24
  15. package/src/_lib/connector/ConnectorsProvider.tsx +0 -20
  16. package/src/_lib/connector/ConnectorsStore.ts +0 -122
  17. package/src/_lib/connector/ConnectorsStoreContext.ts +0 -5
  18. package/src/_lib/connector/helpers.ts +0 -5
  19. package/src/_lib/connector/index.ts +0 -9
  20. package/src/_lib/connector/mapConnectorToLine.ts +0 -83
  21. package/src/_lib/connector/types.ts +0 -56
  22. package/src/_lib/connector/useConnectorsStore.ts +0 -14
  23. package/src/_lib/connector/useRegionRects.ts +0 -142
  24. package/src/_lib/fixedListenQuery.ts +0 -101
  25. package/src/_lib/form/DocumentForm.tsx +0 -201
  26. package/src/_lib/form/constants.ts +0 -1
  27. package/src/_lib/form/helpers.ts +0 -32
  28. package/src/_lib/form/index.ts +0 -1
  29. package/src/_lib/randomKey.ts +0 -29
  30. package/src/_lib/useListeningQuery.ts +0 -62
  31. package/src/_lib/usePrevious.ts +0 -9
  32. package/src/assistConnectors/AssistConnectorsOverlay.tsx +0 -133
  33. package/src/assistConnectors/ConnectorPath.tsx +0 -63
  34. package/src/assistConnectors/draw/arrowPath.ts +0 -9
  35. package/src/assistConnectors/draw/connectorPath.ts +0 -142
  36. package/src/assistConnectors/index.ts +0 -1
  37. package/src/assistDocument/AssistDocumentContext.tsx +0 -51
  38. package/src/assistDocument/AssistDocumentContextProvider.tsx +0 -17
  39. package/src/assistDocument/AssistDocumentInput.tsx +0 -61
  40. package/src/assistDocument/AssistDocumentLayout.tsx +0 -12
  41. package/src/assistDocument/RequestRunInstructionProvider.tsx +0 -61
  42. package/src/assistDocument/components/AssistDocumentForm.tsx +0 -287
  43. package/src/assistDocument/components/AssistTypeContext.tsx +0 -7
  44. package/src/assistDocument/components/FieldRefPreview.tsx +0 -26
  45. package/src/assistDocument/components/InstructionsArrayField.tsx +0 -8
  46. package/src/assistDocument/components/InstructionsArrayInput.tsx +0 -27
  47. package/src/assistDocument/components/SelectedFieldContext.tsx +0 -10
  48. package/src/assistDocument/components/generic/HiddenFieldTitle.tsx +0 -5
  49. package/src/assistDocument/components/helpers.ts +0 -21
  50. package/src/assistDocument/components/instruction/BackToInstructionsLink.tsx +0 -32
  51. package/src/assistDocument/components/instruction/FieldRefInput.tsx +0 -54
  52. package/src/assistDocument/components/instruction/InstructionInput.tsx +0 -89
  53. package/src/assistDocument/components/instruction/InstructionOutputField.tsx +0 -46
  54. package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +0 -206
  55. package/src/assistDocument/components/instruction/PromptInput.tsx +0 -59
  56. package/src/assistDocument/components/instruction/appearance/IconInput.tsx +0 -46
  57. package/src/assistDocument/components/instruction/appearance/InstructionVisibility.tsx +0 -37
  58. package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +0 -127
  59. package/src/assistDocument/hooks/useDocumentState.ts +0 -6
  60. package/src/assistDocument/hooks/useInstructionToaster.tsx +0 -75
  61. package/src/assistDocument/hooks/useStudioAssistDocument.ts +0 -99
  62. package/src/assistDocument/index.ts +0 -1
  63. package/src/assistFormComponents/AssistField.tsx +0 -63
  64. package/src/assistFormComponents/AssistFormBlock.tsx +0 -31
  65. package/src/assistFormComponents/AssistInlineFormBlock.tsx +0 -13
  66. package/src/assistFormComponents/AssistItem.tsx +0 -21
  67. package/src/assistFormComponents/validation/listItem.tsx +0 -63
  68. package/src/assistFormComponents/validation/validationList.tsx +0 -90
  69. package/src/assistInspector/AssistInspector.tsx +0 -419
  70. package/src/assistInspector/FieldAutocomplete.tsx +0 -146
  71. package/src/assistInspector/InstructionTaskHistoryButton.tsx +0 -262
  72. package/src/assistInspector/constants.ts +0 -1
  73. package/src/assistInspector/helpers.ts +0 -211
  74. package/src/assistInspector/index.ts +0 -27
  75. package/src/assistLayout/AiAssistanceConfigContext.tsx +0 -32
  76. package/src/assistLayout/AiAssistanceConfigProvider.tsx +0 -98
  77. package/src/assistLayout/AssistLayout.tsx +0 -39
  78. package/src/assistLayout/RunInstructionProvider.tsx +0 -278
  79. package/src/assistLayout/fieldRefCache.tsx +0 -34
  80. package/src/assistTypes.ts +0 -83
  81. package/src/components/AssistFeatureBadge.tsx +0 -9
  82. package/src/components/FadeInContent.tsx +0 -40
  83. package/src/components/HideReferenceChangedBannerInput.tsx +0 -25
  84. package/src/components/ImageContext.tsx +0 -85
  85. package/src/components/SafeValueInput.tsx +0 -74
  86. package/src/components/TimeAgo.tsx +0 -18
  87. package/src/constants.ts +0 -20
  88. package/src/fieldActions/PrivateIcon.tsx +0 -20
  89. package/src/fieldActions/assistFieldActions.tsx +0 -320
  90. package/src/fieldActions/customFieldActions.tsx +0 -333
  91. package/src/fieldActions/generateCaptionActions.tsx +0 -77
  92. package/src/fieldActions/generateImageActions.tsx +0 -58
  93. package/src/fieldActions/useUserInput.ts +0 -107
  94. package/src/globals.d.ts +0 -4
  95. package/src/helpers/assistSupported.ts +0 -49
  96. package/src/helpers/conditionalMembers.test.ts +0 -319
  97. package/src/helpers/conditionalMembers.ts +0 -134
  98. package/src/helpers/ids.test.ts +0 -28
  99. package/src/helpers/ids.ts +0 -23
  100. package/src/helpers/misc.ts +0 -25
  101. package/src/helpers/styleguide.ts +0 -24
  102. package/src/helpers/typeUtils.ts +0 -60
  103. package/src/helpers/useAssistSupported.ts +0 -8
  104. package/src/index.ts +0 -26
  105. package/src/onboarding/FirstAssistedPathProvider.tsx +0 -30
  106. package/src/onboarding/InspectorOnboarding.tsx +0 -47
  107. package/src/onboarding/onboardingStore.ts +0 -32
  108. package/src/plugin.tsx +0 -162
  109. package/src/presence/AiFieldPresence.tsx +0 -28
  110. package/src/presence/AssistAvatar.tsx +0 -96
  111. package/src/presence/AssistDocumentPresence.tsx +0 -50
  112. package/src/presence/useAssistPresence.ts +0 -64
  113. package/src/schemas/assistDocumentSchema.tsx +0 -497
  114. package/src/schemas/contextDocumentSchema.tsx +0 -57
  115. package/src/schemas/index.ts +0 -69
  116. package/src/schemas/serialize/SchemTypeTool.tsx +0 -103
  117. package/src/schemas/serialize/schemaUtils.ts +0 -38
  118. package/src/schemas/serialize/serializeSchema.test.ts +0 -819
  119. package/src/schemas/serialize/serializeSchema.ts +0 -224
  120. package/src/schemas/serializedSchemaTypeSchema.ts +0 -60
  121. package/src/schemas/typeDefExtensions.ts +0 -127
  122. package/src/translate/FieldTranslationProvider.tsx +0 -382
  123. package/src/translate/getLanguageParams.ts +0 -26
  124. package/src/translate/languageStore.ts +0 -18
  125. package/src/translate/paths.test.ts +0 -181
  126. package/src/translate/paths.ts +0 -183
  127. package/src/translate/translateActions.tsx +0 -205
  128. package/src/translate/types.ts +0 -197
  129. package/src/types.ts +0 -220
  130. package/src/useApiClient.ts +0 -338
  131. package/v2-incompatible.js +0 -11
@@ -1,419 +0,0 @@
1
- import {ArrowRightIcon, CloseIcon, PlayIcon, RetryIcon} from '@sanity/icons'
2
- import {Box, Button, Card, Flex, Spinner, Stack, Text} from '@sanity/ui'
3
- import {useCallback, useMemo, useRef} from 'react'
4
- import {
5
- type DocumentInspectorProps,
6
- PerspectiveProvider,
7
- PresenceOverlay,
8
- VirtualizerScrollInstanceProvider,
9
- } from 'sanity'
10
- import {
11
- DocumentInspectorHeader,
12
- type DocumentPaneNode,
13
- DocumentPaneProvider,
14
- useDocumentPane,
15
- } from 'sanity/structure'
16
- import {styled} from 'styled-components'
17
-
18
- import {DocumentForm} from '../_lib/form'
19
- import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
20
- import {AssistTypeContext} from '../assistDocument/components/AssistTypeContext'
21
- import {useStudioAssistDocument} from '../assistDocument/hooks/useStudioAssistDocument'
22
- import {useRequestRunInstruction} from '../assistDocument/RequestRunInstructionProvider'
23
- import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
24
- import {giveFeedbackUrl, pluginTitle, releaseAnnouncementUrl, salesUrl} from '../constants'
25
- import {getConditionalMembers} from '../helpers/conditionalMembers'
26
- import {assistDocumentId} from '../helpers/ids'
27
- import {InspectorOnboarding} from '../onboarding/InspectorOnboarding'
28
- import {assistDocumentTypeName, fieldPathParam, instructionParam} from '../types'
29
- import {FieldTitle} from './FieldAutocomplete'
30
- import {
31
- type FieldRef,
32
- getFieldTitle,
33
- useAiPaneRouter,
34
- useSelectedField,
35
- useTypePath,
36
- } from './helpers'
37
- import {InstructionTaskHistoryButton} from './InstructionTaskHistoryButton'
38
- import {inspectorOnboardingKey, useOnboardingFeature} from '../onboarding/onboardingStore'
39
-
40
- const CardWithShadowBelow = styled(Card)`
41
- position: relative;
42
-
43
- &:after {
44
- content: '';
45
- display: block;
46
- position: absolute;
47
- left: 0;
48
- right: 0;
49
- bottom: -1px;
50
- border-bottom: 1px solid var(--card-border-color);
51
- opacity: 0.5;
52
- z-index: 100;
53
- }
54
- `
55
-
56
- const CardWithShadowAbove = styled(Card)`
57
- position: relative;
58
-
59
- &:after {
60
- content: '';
61
- display: block;
62
- position: absolute;
63
- left: 0;
64
- right: 0;
65
- top: -1px;
66
- border-top: 1px solid var(--card-border-color);
67
- opacity: 0.5;
68
- z-index: 100;
69
- }
70
- `
71
-
72
- export function AssistInspectorWrapper(props: DocumentInspectorProps) {
73
- const context = useAiAssistanceConfig()
74
-
75
- if (context.statusLoading) {
76
- return (
77
- <Flex align="center" height="fill" justify="center" padding={4} sizing="border">
78
- <Stack space={3} style={{textAlign: 'center'}}>
79
- <Spinner muted />
80
- <Text muted size={1}>
81
- Loading {pluginTitle}...
82
- </Text>
83
- </Stack>
84
- </Flex>
85
- )
86
- }
87
-
88
- const status = context.status
89
-
90
- if (!status?.enabled) {
91
- return (
92
- <Flex direction="column" height="fill">
93
- <DocumentInspectorHeader
94
- closeButtonLabel="Close"
95
- onClose={props.onClose}
96
- title={pluginTitle}
97
- />
98
-
99
- <Stack flex={1} overflow="auto" padding={4} space={3}>
100
- <Text as="p" size={1} weight="semibold">
101
- {pluginTitle} is not available
102
- </Text>
103
-
104
- <Text as="p" muted size={1}>
105
- Please get in touch with a Sanity account manager or{' '}
106
- <a href={salesUrl} target="_blank" rel="noreferrer">
107
- contact our sales team
108
- </a>{' '}
109
- to get started with {pluginTitle}.{' '}
110
- <a href={releaseAnnouncementUrl} target="_blank" rel="noreferrer">
111
- Learn more &rarr;
112
- </a>
113
- </Text>
114
- </Stack>
115
- </Flex>
116
- )
117
- }
118
-
119
- if (!status?.initialized || !status.validToken) {
120
- return (
121
- <Flex direction="column" height="fill">
122
- <DocumentInspectorHeader
123
- closeButtonLabel="Close"
124
- onClose={props.onClose}
125
- title={pluginTitle}
126
- />
127
-
128
- <Stack padding={4} space={3}>
129
- {context.error ? (
130
- <Text size={1} weight="semibold">
131
- Failed to start {pluginTitle}
132
- </Text>
133
- ) : null}
134
-
135
- {!context.error && !status?.initialized ? (
136
- <Text size={1} weight="semibold">
137
- {pluginTitle} is not enabled
138
- </Text>
139
- ) : null}
140
-
141
- {!context.error && status?.initialized && !status.validToken ? (
142
- <>
143
- <Text size={1} weight="semibold">
144
- Invalid token
145
- </Text>
146
- <Text muted size={1}>
147
- The token used by the AI Assistant is not valid and has to be regenerated.
148
- </Text>
149
- </>
150
- ) : null}
151
-
152
- {context.error && (
153
- <Text muted size={1}>
154
- Something went wrong. See console for details.
155
- </Text>
156
- )}
157
-
158
- {!context.error && !status?.initialized && (
159
- <Text size={1} muted>
160
- Please enable {pluginTitle}.
161
- </Text>
162
- )}
163
-
164
- <Button
165
- fontSize={1}
166
- icon={
167
- context.initLoading ? (
168
- <Box marginTop={1}>
169
- <Spinner />
170
- </Box>
171
- ) : context.error ? (
172
- RetryIcon
173
- ) : undefined
174
- }
175
- text={
176
- context.error
177
- ? 'Retry'
178
- : status?.initialized && !status.validToken
179
- ? `Restore ${pluginTitle}`
180
- : `Enable ${pluginTitle} now`
181
- }
182
- tone="primary"
183
- onClick={context.init}
184
- disabled={context.initLoading}
185
- />
186
- </Stack>
187
- </Flex>
188
- )
189
- }
190
-
191
- return <AssistInspector {...props} />
192
- }
193
-
194
- export function AssistInspector(props: DocumentInspectorProps) {
195
- const {params} = useAiPaneRouter()
196
-
197
- const boundary = useRef<HTMLDivElement | null>(null)
198
- const pathKey = params?.[fieldPathParam]
199
- const instructionKey = params?.[instructionParam]
200
- const documentPane = useDocumentPane()
201
- const {
202
- documentId,
203
- documentType,
204
- value: docValue,
205
- schemaType,
206
- onChange: documentOnChange,
207
- formState,
208
- } = documentPane
209
-
210
- const {assistableDocumentId, documentIsAssistable} = useAssistDocumentContext()
211
-
212
- const formStateRef = useRef(formState)
213
- formStateRef.current = formState
214
-
215
- const {instructionLoading, requestRunInstruction} = useRequestRunInstruction({
216
- documentOnChange,
217
- isDocAssistable: documentIsAssistable,
218
- })
219
-
220
- const typePath = useTypePath(docValue, pathKey ?? '')
221
- const selectedField = useSelectedField(schemaType, typePath)
222
-
223
- const aiDocId = assistDocumentId(documentType)
224
-
225
- const assistDocument = useStudioAssistDocument({documentId, schemaType, initDoc: true})
226
- const assistField = assistDocument?.fields?.find((f) => f.path === typePath)
227
- const instruction = assistField?.instructions?.find((i) => i._key === instructionKey)
228
- const tasks = useMemo(
229
- () =>
230
- assistDocument?.tasks?.filter((i) => !instructionKey || i.instructionKey === instructionKey),
231
- [assistDocument?.tasks, instructionKey],
232
- )
233
- const instructions = useMemo(
234
- () => assistDocument?.fields?.flatMap((f) => f.instructions ?? []),
235
- [assistDocument?.fields],
236
- )
237
-
238
- const promptValue = instruction?.prompt
239
- const isEmptyPrompt = useMemo(() => {
240
- if (!promptValue?.length) {
241
- return true
242
- }
243
- const firstBlock = promptValue[0] as any
244
- const children = firstBlock?.children
245
-
246
- return promptValue.length == 1 && children?.length === 1 && !children?.[0]?.text?.length
247
- }, [promptValue])
248
-
249
- const paneNode: DocumentPaneNode = useMemo(
250
- () => ({
251
- type: 'document',
252
- id: aiDocId,
253
- title: pluginTitle,
254
- options: {
255
- id: aiDocId,
256
- type: assistDocumentTypeName,
257
- },
258
- }),
259
- [aiDocId],
260
- )
261
-
262
- const runCurrentInstruction = useCallback(
263
- () =>
264
- instruction &&
265
- pathKey &&
266
- typePath &&
267
- requestRunInstruction({
268
- documentId: assistableDocumentId,
269
- path: pathKey,
270
- typePath,
271
- assistDocumentId: assistDocumentId(documentType),
272
- instruction,
273
- conditionalMembers: formStateRef.current ? getConditionalMembers(formStateRef.current) : [],
274
- }),
275
- [pathKey, instruction, typePath, documentType, assistableDocumentId, requestRunInstruction],
276
- )
277
-
278
- const Region = useCallback((_props: any) => {
279
- // disabled for now
280
- /* return (
281
- <ConnectToRegion
282
- {..._props}
283
- _key={`${paneKey}_${selectedField?.key || '_field'}`}
284
- style={{height: '100%', flex: 1, overflow: 'auto'}}
285
- />
286
- )*/
287
- return <div {..._props} style={{height: '100%', flex: 1, overflow: 'auto'}} />
288
- }, [])
289
-
290
- const assistTypeContext = useMemo(() => ({typePath, documentType}), [typePath, documentType])
291
-
292
- if (!documentId || !schemaType || schemaType.jsonType !== 'object') {
293
- return (
294
- <Card flex={1} padding={4}>
295
- <Text>Document not ready yet.</Text>
296
- </Card>
297
- )
298
- }
299
-
300
- return (
301
- <Flex
302
- ref={boundary}
303
- direction="column"
304
- height="fill"
305
- overflow="hidden"
306
- sizing="border"
307
- style={{lineHeight: 0}}
308
- >
309
- <AiInspectorHeader
310
- onClose={props.onClose}
311
- field={selectedField}
312
- fieldTitle={getFieldTitle(selectedField)}
313
- />
314
-
315
- <Card as={Region} flex={1} overflow="auto">
316
- <Flex direction="column" style={{minHeight: '100%'}}>
317
- <Box flex={1}>
318
- <PresenceOverlay>
319
- <Box padding={4}>
320
- {selectedField && (
321
- <AssistTypeContext.Provider value={assistTypeContext}>
322
- <VirtualizerScrollInstanceProvider
323
- scrollElement={boundary.current}
324
- containerElement={boundary}
325
- >
326
- <PerspectiveProvider selectedPerspectiveName={undefined}>
327
- <DocumentPaneProvider
328
- paneKey={documentPane.paneKey}
329
- index={documentPane.index}
330
- itemId="ai"
331
- pane={paneNode}
332
- >
333
- <DocumentForm />
334
- </DocumentPaneProvider>
335
- </PerspectiveProvider>
336
- </VirtualizerScrollInstanceProvider>
337
- </AssistTypeContext.Provider>
338
- )}
339
- </Box>
340
- </PresenceOverlay>
341
- </Box>
342
-
343
- <Box flex="none" padding={4}>
344
- <Text muted size={1}>
345
- How is Sanity AI Assist working for you?{' '}
346
- <a
347
- href={giveFeedbackUrl}
348
- target="_blank"
349
- rel="noreferrer"
350
- style={{whiteSpace: 'nowrap'}}
351
- >
352
- Let us know <ArrowRightIcon />
353
- </a>
354
- </Text>
355
- </Box>
356
- </Flex>
357
- </Card>
358
- <CardWithShadowAbove flex="none" paddingX={4} paddingY={3} style={{justifySelf: 'flex-end'}}>
359
- <Flex gap={2} flex={1} justify="flex-end">
360
- {schemaType?.name && pathKey && instructionKey && (
361
- <Stack flex={1}>
362
- <Button
363
- mode="ghost"
364
- disabled={isEmptyPrompt || instructionLoading}
365
- fontSize={1}
366
- icon={instructionLoading ? <Spinner style={{marginTop: 3}} /> : PlayIcon}
367
- onClick={runCurrentInstruction}
368
- padding={3}
369
- text={'Run instruction'}
370
- />
371
- </Stack>
372
- )}
373
-
374
- <InstructionTaskHistoryButton
375
- documentId={assistableDocumentId}
376
- tasks={tasks}
377
- instructions={instructions}
378
- showTitles={!instructionKey}
379
- />
380
- </Flex>
381
- </CardWithShadowAbove>
382
- </Flex>
383
- )
384
- }
385
-
386
- function AiInspectorHeader(props: {fieldTitle: string; field?: FieldRef; onClose: () => void}) {
387
- const {onClose, field, fieldTitle} = props
388
- const {showOnboarding, dismissOnboarding} = useOnboardingFeature(inspectorOnboardingKey)
389
-
390
- return (
391
- <CardWithShadowBelow flex="none" padding={2}>
392
- <Flex flex={1} align="center">
393
- <Flex flex={1} padding={3} gap={2} align="center">
394
- <Flex gap={1} align="center" wrap="wrap" style={{marginTop: '-4px'}}>
395
- <Box marginTop={1}>
396
- <Text size={1} weight="semibold">
397
- AI instructions for
398
- </Text>
399
- </Box>
400
- <Card radius={2} border padding={1} marginTop={1}>
401
- {field ? (
402
- <FieldTitle field={field} />
403
- ) : (
404
- <Text size={1} weight="semibold">
405
- {fieldTitle}
406
- </Text>
407
- )}
408
- </Card>
409
- </Flex>
410
- </Flex>
411
- <Box flex="none">
412
- <Button fontSize={1} icon={CloseIcon} mode="bleed" onClick={onClose} />
413
- </Box>
414
- </Flex>
415
-
416
- {showOnboarding && <InspectorOnboarding onDismiss={dismissOnboarding} />}
417
- </CardWithShadowBelow>
418
- )
419
- }
@@ -1,146 +0,0 @@
1
- import {SearchIcon} from '@sanity/icons'
2
- import {Autocomplete, Box, Breadcrumbs, Card, Flex, Text} from '@sanity/ui'
3
- import {createElement, useCallback, useMemo} from 'react'
4
- import {ObjectSchemaType} from 'sanity'
5
-
6
- import {isType} from '../helpers/typeUtils'
7
- import {FieldRef, getDocumentFieldRef} from './helpers'
8
- import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
9
-
10
- interface FieldSelectorProps {
11
- id: string
12
- schemaType: ObjectSchemaType
13
- fieldPath?: string
14
- onSelect: (path: string) => void
15
- includeDocument?: boolean
16
- filter?: (field: FieldRef) => boolean
17
- }
18
-
19
- export function FieldAutocomplete(props: FieldSelectorProps) {
20
- const {id, schemaType, fieldPath, onSelect, includeDocument, filter} = props
21
-
22
- const {getFieldRefs} = useAiAssistanceConfig()
23
-
24
- const fieldRefs = useMemo(() => {
25
- const refs = getFieldRefs(schemaType.name)
26
- if (includeDocument) {
27
- return [getDocumentFieldRef(schemaType), ...refs]
28
- }
29
- return refs
30
- }, [schemaType, includeDocument, getFieldRefs])
31
-
32
- const currentField = useMemo(
33
- () => fieldRefs.find((f) => f.key === fieldPath),
34
- [fieldPath, fieldRefs],
35
- )
36
-
37
- const autocompleteOptions = useMemo(
38
- () =>
39
- fieldRefs
40
- .filter((field) => (filter ? filter(field) : true))
41
- .filter((f) => !isType(f.schemaType, 'reference'))
42
- .map((field) => ({value: field.key, field})),
43
- [fieldRefs, filter],
44
- )
45
-
46
- const renderOption = useCallback((option: {value: string; field: FieldRef}) => {
47
- const {value, field} = option
48
-
49
- if (!value) {
50
- return (
51
- <Card as="button" padding={3} radius={1}>
52
- <Text accent size={1}>
53
- {option.value}
54
- </Text>
55
- </Card>
56
- )
57
- }
58
-
59
- if (isType(field.schemaType, 'document')) {
60
- return (
61
- <Card as="button" padding={3} radius={1}>
62
- <Text size={1} weight="semibold">
63
- The entire document
64
- </Text>
65
- </Card>
66
- )
67
- }
68
-
69
- return (
70
- <Card as="button" padding={3} radius={1}>
71
- <Flex gap={3}>
72
- <Text size={1}>{createElement(field.icon)}</Text>
73
-
74
- <FieldTitle field={field} />
75
- </Flex>
76
- </Card>
77
- )
78
- }, [])
79
-
80
- const renderValue = useCallback((value: string, option?: {value: string; field: FieldRef}) => {
81
- return option?.field.title ?? value
82
- }, [])
83
-
84
- const filterOption = useCallback((query: string, option: {value: string; field: FieldRef}) => {
85
- const lQuery = query.toLowerCase()
86
- return (
87
- option?.value?.toLowerCase().includes(lQuery) ||
88
- option?.field?.title?.toLowerCase().includes(lQuery)
89
- )
90
- }, [])
91
-
92
- return (
93
- <Autocomplete
94
- fontSize={1}
95
- icon={currentField ? currentField.icon : SearchIcon}
96
- onChange={onSelect}
97
- openButton
98
- id={id}
99
- options={autocompleteOptions}
100
- placeholder="Search for a field"
101
- radius={2}
102
- renderOption={renderOption}
103
- renderValue={renderValue}
104
- value={currentField?.key}
105
- filterOption={filterOption}
106
- />
107
- )
108
- }
109
-
110
- export function FieldTitle(props: {field: FieldRef}) {
111
- const splitTitle = props.field.title.split('/')
112
- return (
113
- <Box flex="none">
114
- <Breadcrumbs
115
- style={{
116
- display: 'flex',
117
- flexWrap: 'wrap',
118
- alignItems: 'center',
119
- marginTop: '-4px',
120
- }}
121
- separator={
122
- <Box marginTop={1}>
123
- <Text muted size={1}>
124
- /
125
- </Text>
126
- </Box>
127
- }
128
- space={1}
129
- >
130
- {splitTitle.slice(0, splitTitle.length - 1).map((pt, i) => (
131
- // eslint-disable-next-line react/no-array-index-key
132
- <Box key={i} marginTop={1}>
133
- <Text muted size={1}>
134
- {pt.trim()}
135
- </Text>
136
- </Box>
137
- ))}
138
- <Box marginTop={1}>
139
- <Text size={1} weight="medium">
140
- {splitTitle[splitTitle.length - 1]}
141
- </Text>
142
- </Box>
143
- </Breadcrumbs>
144
- </Box>
145
- )
146
- }