@sanity/assist 5.0.4 → 6.0.1

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 +3205 -2670
  6. package/dist/index.js.map +1 -1
  7. package/package.json +41 -81
  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,278 +0,0 @@
1
- import {PlayIcon} from '@sanity/icons'
2
- import {Button, Dialog, Flex, Stack, Text, TextArea, Tooltip} from '@sanity/ui'
3
- import {FormFieldHeaderText} from 'sanity'
4
-
5
- import {getInstructionTitle} from '../helpers/misc'
6
- import {type UserInputBlock, userInputTypeName} from '../types'
7
- import {useApiClient, useRunInstructionApi} from '../useApiClient'
8
- import {useAiAssistanceConfig} from './AiAssistanceConfigContext'
9
- import type {RunInstructionArgs} from './AssistLayout'
10
- import {CustomInputResult, GetUserInput} from '../fieldActions/useUserInput'
11
- import {
12
- createContext,
13
- type Dispatch,
14
- type FormEvent,
15
- type PropsWithChildren,
16
- type SetStateAction,
17
- useCallback,
18
- useContext,
19
- useEffect,
20
- useId,
21
- useMemo,
22
- useRef,
23
- useState,
24
- } from 'react'
25
-
26
- type BlockInputs = Record<string, string>
27
- const NO_INPUT: BlockInputs = {}
28
-
29
- export interface RunInstructionContextValue {
30
- runInstruction: (req: RunInstructionArgs) => void
31
- getUserInput: GetUserInput
32
- instructionLoading: boolean
33
- }
34
-
35
- export const RunInstructionContext = createContext<RunInstructionContextValue>({
36
- runInstruction: () => {},
37
- getUserInput: async () => undefined,
38
- instructionLoading: false,
39
- })
40
-
41
- export function useRunInstruction() {
42
- return useContext(RunInstructionContext)
43
- }
44
-
45
- function isUserInputBlock(block: {_type: string}): block is UserInputBlock {
46
- return block._type === userInputTypeName
47
- }
48
-
49
- // eslint-disable-next-line @typescript-eslint/ban-types
50
- export function RunInstructionProvider(props: PropsWithChildren<{}>) {
51
- const {config} = useAiAssistanceConfig()
52
- const apiClient = useApiClient(config?.__customApiClient)
53
- const {runInstruction: runInstructionRequest, loading} = useRunInstructionApi(apiClient)
54
-
55
- const id = useId()
56
-
57
- const [inputs, setInputs] = useState(NO_INPUT)
58
- const [runRequest, setRunRequest] = useState<
59
- | (RunInstructionArgs & {userInputBlocks: UserInputBlock[]})
60
- | {dialogTitle: string; userInputBlocks: UserInputBlock[]}
61
- | undefined
62
- >()
63
-
64
- const [resolveUserInput, setResolveUserInput] =
65
- useState<
66
- (
67
- value: CustomInputResult[] | PromiseLike<CustomInputResult[] | undefined> | undefined,
68
- ) => void
69
- >()
70
-
71
- const getUserInput: GetUserInput = useCallback(async ({title, inputs}) => {
72
- const userInputBlocks: UserInputBlock[] = inputs.map((input, i) => ({
73
- _type: userInputTypeName,
74
- _key: input.id ?? `${i}`,
75
- message: input.title,
76
- description: input.description,
77
- }))
78
-
79
- if (!userInputBlocks.length) {
80
- return undefined
81
- }
82
- setRunRequest({dialogTitle: title, userInputBlocks})
83
- return new Promise<CustomInputResult[] | undefined>((resolve) => {
84
- setResolveUserInput(() => resolve)
85
- })
86
- }, [])
87
-
88
- const runInstruction = useCallback(
89
- (req: RunInstructionArgs) => {
90
- if (loading) {
91
- return
92
- }
93
- const {instruction, ...request} = req
94
- const instructionKey = instruction._key
95
- const userInputBlocks = instruction?.prompt
96
- ?.flatMap((block) =>
97
- block._type === 'block' ? block.children.filter(isUserInputBlock) : [block],
98
- )
99
- .filter(isUserInputBlock)
100
-
101
- if (!userInputBlocks?.length) {
102
- runInstructionRequest({
103
- ...request,
104
- instructionKey,
105
- userTexts: undefined,
106
- })
107
- return
108
- }
109
-
110
- setRunRequest({
111
- ...req,
112
- userInputBlocks,
113
- })
114
- },
115
- [runInstructionRequest, loading],
116
- )
117
-
118
- const close = useCallback(() => {
119
- setRunRequest(undefined)
120
- setInputs(NO_INPUT)
121
- if (resolveUserInput) {
122
- resolveUserInput(undefined)
123
- }
124
- setResolveUserInput(undefined)
125
- }, [resolveUserInput])
126
-
127
- const runWithInput = useCallback(() => {
128
- if (runRequest) {
129
- if ('instruction' in runRequest) {
130
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
131
- const {instruction, userTexts, ...request} = runRequest
132
- runInstructionRequest({
133
- ...request,
134
- instructionKey: instruction._key,
135
- userTexts: Object.entries(inputs).map(([key, value]) => ({
136
- blockKey: key,
137
- userInput: value,
138
- })),
139
- })
140
- } else {
141
- const userInputs = Object.values(inputs).map((input, i) => {
142
- const userInputBlock = runRequest.userInputBlocks[i]
143
- return {
144
- input: {
145
- id: userInputBlock._key,
146
- title: userInputBlock.message ?? '',
147
- description: userInputBlock.description,
148
- },
149
- result: input,
150
- }
151
- })
152
- resolveUserInput?.(userInputs)
153
- setResolveUserInput(undefined)
154
- }
155
- }
156
- close()
157
- }, [close, runInstructionRequest, runRequest, inputs, resolveUserInput])
158
-
159
- const open = !!runRequest
160
-
161
- const runDisabled = useMemo(
162
- () =>
163
- (runRequest?.userInputBlocks?.length ?? 0) >
164
- Object.entries(inputs).filter(([, value]) => !!value).length,
165
- [runRequest?.userInputBlocks, inputs],
166
- )
167
-
168
- const runButton = (
169
- <Button
170
- text="Run instruction"
171
- onClick={runWithInput}
172
- tone="primary"
173
- icon={PlayIcon}
174
- style={{width: '100%'}}
175
- disabled={runDisabled}
176
- />
177
- )
178
-
179
- const contextValue: RunInstructionContextValue = useMemo(
180
- () => ({runInstruction, getUserInput, instructionLoading: loading}),
181
- [runInstruction, loading],
182
- )
183
-
184
- return (
185
- <RunInstructionContext.Provider value={contextValue}>
186
- {open ? (
187
- <Dialog
188
- id={id}
189
- open={open}
190
- onClose={close}
191
- width={1}
192
- header={
193
- 'dialogTitle' in runRequest
194
- ? runRequest.dialogTitle
195
- : getInstructionTitle(runRequest?.instruction)
196
- }
197
- footer={
198
- <Flex justify="space-between" padding={2} flex={1}>
199
- {runDisabled ? (
200
- <Tooltip
201
- content={
202
- <Flex padding={2}>
203
- <Text>Unable to run instruction. All fields must have a value.</Text>
204
- </Flex>
205
- }
206
- placement="top"
207
- >
208
- <Flex flex={1}>{runButton}</Flex>
209
- </Tooltip>
210
- ) : (
211
- runButton
212
- )}
213
- </Flex>
214
- }
215
- >
216
- <Stack padding={4} space={2}>
217
- {runRequest?.userInputBlocks?.map((block, i) => (
218
- <UserInput
219
- key={block._key}
220
- block={block}
221
- autoFocus={i === 0}
222
- inputs={inputs}
223
- setInputs={setInputs}
224
- />
225
- ))}
226
- </Stack>
227
- </Dialog>
228
- ) : null}
229
- {props.children}
230
- </RunInstructionContext.Provider>
231
- )
232
- }
233
-
234
- export function UserInput(props: {
235
- block: UserInputBlock
236
- inputs: BlockInputs
237
- setInputs: Dispatch<SetStateAction<BlockInputs>>
238
- autoFocus?: boolean
239
- }) {
240
- const {block, autoFocus, setInputs, inputs} = props
241
- const key = block._key
242
- const textAreaRef = useRef<HTMLTextAreaElement>(null)
243
-
244
- const onChange = useCallback(
245
- (e: FormEvent<HTMLTextAreaElement>) => {
246
- setInputs((current) => ({
247
- ...current,
248
- [key]: (e.currentTarget ?? e.target).value,
249
- }))
250
- },
251
- [key, setInputs],
252
- )
253
-
254
- const value = useMemo(() => inputs[key], [inputs, key])
255
-
256
- useEffect(() => {
257
- if (!autoFocus) {
258
- return
259
- }
260
- setTimeout(() => textAreaRef.current?.focus(), 0)
261
- }, [autoFocus])
262
-
263
- return (
264
- <Stack padding={2} space={3}>
265
- <FormFieldHeaderText
266
- title={block?.message ?? 'Provide more context'}
267
- description={block.description}
268
- />
269
- <TextArea
270
- ref={textAreaRef}
271
- rows={4}
272
- value={value}
273
- onChange={onChange}
274
- style={{resize: 'vertical'}}
275
- />
276
- </Stack>
277
- )
278
- }
@@ -1,34 +0,0 @@
1
- import {
2
- asFieldRefsByTypePath,
3
- FieldRef,
4
- getFieldRefs as createFieldRefs,
5
- } from '../assistInspector/helpers'
6
- import type {ObjectSchemaType} from 'sanity'
7
-
8
- export function createFieldRefCache() {
9
- const byType: Record<
10
- string,
11
- | {
12
- fieldRefs: FieldRef[]
13
- fieldRefsByTypePath: Record<string, FieldRef | undefined>
14
- }
15
- | undefined
16
- > = {}
17
-
18
- function getRefsForType(schemaType: ObjectSchemaType) {
19
- const documentType = schemaType.name
20
- const cached = byType[documentType]
21
- if (cached) return cached
22
-
23
- const fieldRefs = createFieldRefs(schemaType)
24
- const fieldRefsByTypePath = asFieldRefsByTypePath(fieldRefs)
25
- const refs = {
26
- fieldRefs,
27
- fieldRefsByTypePath,
28
- }
29
- byType[documentType] = refs
30
- return refs
31
- }
32
-
33
- return getRefsForType
34
- }
@@ -1,83 +0,0 @@
1
- import {CurrentUser} from 'sanity'
2
-
3
- export interface AssistConfig {
4
- /**
5
- * As of v3.0 Assist can write to date and datetime fields.
6
- *
7
- * If this function is omitted from config, the plugin will use the default timeZone and locale
8
- * in the browser:
9
- *
10
- * ```ts
11
- * const {timeZone, locale} = Intl.DateTimeFormat().resolvedOptions()
12
- * ```
13
- *
14
- * The function will be called any time an instruction runs.
15
- *
16
- * @see #LocaleSettings.locale
17
- * @see #LocaleSettings.timeZone
18
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#getcanonicalocales
19
- * @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
20
- */
21
- localeSettings?: (context: LocaleSettingsContext) => LocaleSettings
22
-
23
- /**
24
- * The max depth for document paths AI Assist will write to.
25
- *
26
- * Depth is based on field path segments:
27
- * - `title` has depth 1
28
- * - `array[_key="no"].title` has depth 3
29
- *
30
- * Be careful not to set this too high in studios with recursive document schemas, as it could have
31
- * negative impact on performance.
32
- *
33
- * Depth will be counted from the field the instruction is run from. For example, if an instruction
34
- * is attached to depth 6, the count starts from there (at 0, not at 6).
35
- *
36
- * Default: 4
37
- */
38
- maxPathDepth?: number
39
-
40
- /**
41
- * Influences how much the output of an instruction will vary.
42
- *
43
- * Min: 0 – re-running an instruction will often produce the same outcomes
44
- * Max: 1 – re-running an instruction can produce wildly different outcomes
45
- *
46
- * This parameter applies to _all_ instructions in the studio.
47
- *
48
- * Prior to v3.0, this defaulted to 0
49
- *
50
- * Default: 0.3
51
- */
52
- temperature?: number
53
- }
54
-
55
- export interface LocaleSettingsContext {
56
- user: CurrentUser
57
- defaultSettings: LocaleSettings
58
- }
59
-
60
- export interface LocaleSettings {
61
- /**
62
- * A valid Unicode BCP 47 locale identifier used to interpret and format
63
- * natural language inputs and date output. Examples include "en-US", "fr-FR", or "ja-JP".
64
- *
65
- * This affects how phrases like "next Friday" or "in two weeks" are parsed,
66
- * and how resulting dates are presented (e.g., 12-hour vs 24-hour format).
67
- *
68
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#getcanonicalocales
69
- */
70
- locale: string
71
-
72
- /**
73
- * A valid IANA time zone identifier used to resolve relative and absolute
74
- * date expressions to a specific point in time. Examples include
75
- * "America/New_York", "Europe/Paris", or "Asia/Tokyo".
76
- *
77
- * This ensures phrases like "tomorrow at 9am" are interpreted correctly
78
- * based on the user's local time.
79
- *
80
- * @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
81
- */
82
- timeZone: string
83
- }
@@ -1,9 +0,0 @@
1
- import {Badge} from '@sanity/ui'
2
-
3
- export function AssistFeatureBadge() {
4
- return (
5
- <Badge fontSize={0} style={{margin: '-2px 0'}} tone="primary">
6
- Beta
7
- </Badge>
8
- )
9
- }
@@ -1,40 +0,0 @@
1
- import {forwardRef, type ReactElement, type ReactNode} from 'react'
2
- import {keyframes, styled} from 'styled-components'
3
-
4
- const fadeIn = keyframes`
5
- 0% {
6
- opacity: 0;
7
- transform: scale(0.75);
8
- }
9
- 40% {
10
- opacity: 0;
11
- transform: scale(0.75);
12
- }
13
- 100% {
14
- opacity: 1;
15
- transform: scale(1);
16
- }
17
- `
18
-
19
- const FadeInDiv = styled.div`
20
- animation-name: ${fadeIn};
21
- animation-timing-function: ease-in-out;
22
- `
23
-
24
- export const FadeInContent = forwardRef(function FadeInContent(
25
- {
26
- children,
27
- durationMs = 250,
28
- }: {
29
- children?: ReactNode
30
- ms?: number
31
- durationMs?: number
32
- },
33
- ref: any,
34
- ): ReactElement {
35
- return (
36
- <FadeInDiv ref={ref} style={{animationDuration: `${durationMs}ms`}}>
37
- {children}
38
- </FadeInDiv>
39
- )
40
- })
@@ -1,25 +0,0 @@
1
- import {Box} from '@sanity/ui'
2
- import {useEffect, useRef} from 'react'
3
- import {ObjectInputProps} from 'sanity'
4
-
5
- export function HideReferenceChangedBannerInput(props: ObjectInputProps) {
6
- const ref = useRef<HTMLDivElement>(null)
7
-
8
- // hides "reference was changed" banner (it is incorrectly flashing because the pane handler does not support the way wie use the assist pane)
9
- useEffect(() => {
10
- const parent = ref.current?.closest('[data-testid="pane-content"]')
11
- if (!parent) {
12
- return
13
- }
14
- const style = document.createElement('style')
15
- const parentId = `id-${Math.random()}`.replace('.', '-')
16
- parent.id = parentId
17
-
18
- style.innerText = `
19
- #${parentId} [data-testid="reference-changed-banner"] { display: none; }
20
- `
21
- parent.prepend(style)
22
- }, [ref])
23
-
24
- return <Box ref={ref}>{props.renderDefault(props)}</Box>
25
- }
@@ -1,85 +0,0 @@
1
- import {createContext, useEffect, useMemo, useState} from 'react'
2
- import {getPublishedId, type InputProps, pathToString, usePerspective, useSyncState} from 'sanity'
3
- import {usePaneRouter} from 'sanity/structure'
4
-
5
- import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
6
- import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
7
- import {getDescriptionFieldOption, getImageInstructionFieldOption} from '../helpers/typeUtils'
8
- import {canUseAssist, useApiClient, useGenerateCaption} from '../useApiClient'
9
-
10
- export interface ImageContextValue {
11
- imageDescriptionPath?: string
12
- imageInstructionPath?: string
13
- assetRef?: string
14
- }
15
-
16
- export const ImageContext = createContext<ImageContextValue>({})
17
-
18
- export function ImageContextProvider(props: InputProps) {
19
- const {schemaType, path, value, readOnly} = props
20
- const assetRef = (value as any)?.asset?._ref
21
- const {selectedReleaseId} = usePerspective()
22
- const [assetRefState, setAssetRefState] = useState<string | undefined>(assetRef)
23
-
24
- const {assistableDocumentId, documentSchemaType} = useAssistDocumentContext()
25
- const {config, status} = useAiAssistanceConfig()
26
- const apiClient = useApiClient(config?.__customApiClient)
27
- const {generateCaption} = useGenerateCaption(apiClient)
28
-
29
- const {isSyncing} = useSyncState(
30
- getPublishedId(assistableDocumentId),
31
- documentSchemaType.name,
32
- selectedReleaseId,
33
- )
34
-
35
- const router = usePaneRouter()
36
- const isShowingOlderRevision = !!router.params?.rev
37
-
38
- useEffect(() => {
39
- const descriptionField = getDescriptionFieldOption(schemaType)
40
- if (
41
- assetRef &&
42
- assistableDocumentId &&
43
- descriptionField?.updateOnImageChange &&
44
- assetRef !== assetRefState &&
45
- !isSyncing &&
46
- !isShowingOlderRevision &&
47
- !readOnly
48
- ) {
49
- setAssetRefState(assetRef)
50
- if (canUseAssist(status)) {
51
- generateCaption({
52
- path: pathToString([...path, descriptionField.path]),
53
- documentId: assistableDocumentId,
54
- })
55
- }
56
- }
57
- }, [
58
- schemaType,
59
- path,
60
- assetRef,
61
- assetRefState,
62
- assistableDocumentId,
63
- generateCaption,
64
- isSyncing,
65
- status,
66
- readOnly,
67
- isShowingOlderRevision,
68
- ])
69
-
70
- const context: ImageContextValue = useMemo(() => {
71
- const descriptionField = getDescriptionFieldOption(schemaType)
72
- const imageInstructionField = getImageInstructionFieldOption(schemaType)
73
- return {
74
- imageDescriptionPath: descriptionField?.path
75
- ? pathToString([...path, descriptionField.path])
76
- : undefined,
77
- imageInstructionPath: imageInstructionField
78
- ? pathToString([...path, imageInstructionField])
79
- : undefined,
80
- assetRef,
81
- }
82
- }, [schemaType, path, assetRef])
83
-
84
- return <ImageContext.Provider value={context}>{props.renderDefault(props)}</ImageContext.Provider>
85
- }
@@ -1,74 +0,0 @@
1
- import {Box, Button, Card, ErrorBoundary, Flex, Stack, Text} from '@sanity/ui'
2
- import {type ErrorInfo, type PropsWithChildren, useCallback, useMemo, useState} from 'react'
3
- import {type InputProps, isArraySchemaType, PatchEvent, unset} from 'sanity'
4
- import {styled} from 'styled-components'
5
-
6
- import {isPortableTextArray} from '../helpers/typeUtils'
7
-
8
- const WrapPreCard = styled(Card)`
9
- & pre {
10
- white-space: pre-wrap !important;
11
- }
12
- `
13
-
14
- export function SafeValueInput(props: InputProps) {
15
- return (
16
- <ErrorWrapper onChange={props.onChange}>
17
- <PteValueFixer {...props} />
18
- </ErrorWrapper>
19
- )
20
- }
21
-
22
- export function ErrorWrapper(
23
- props: PropsWithChildren<{onChange: (patchEvent: PatchEvent) => void}>,
24
- ) {
25
- const {onChange} = props
26
- const [error, setError] = useState<Error | undefined>()
27
-
28
- const catchError = useCallback((params: {error: Error; info: ErrorInfo}) => {
29
- setError(params.error)
30
- }, [])
31
-
32
- const unsetValue = useCallback(() => {
33
- onChange(PatchEvent.from(unset()))
34
- setError(undefined)
35
- }, [onChange])
36
- const dismiss = useCallback(() => setError(undefined), [])
37
- const catcher = <ErrorBoundary onCatch={catchError}>{props.children}</ErrorBoundary>
38
-
39
- return error ? (
40
- <Card border tone="critical" padding={2} contentEditable={false}>
41
- <Stack space={3}>
42
- <Text muted weight="semibold">
43
- An error occurred.
44
- </Text>
45
-
46
- <WrapPreCard flex={1} padding={2} tone="critical" border>
47
- {catcher}
48
- </WrapPreCard>
49
-
50
- <Flex width="fill" flex={1} gap={3}>
51
- <Box flex={1}>
52
- <Button text="Dismiss" onClick={dismiss} tone="primary" />
53
- </Box>
54
- <Button text="Unset value" onClick={unsetValue} tone="critical" />
55
- </Flex>
56
- </Stack>
57
- </Card>
58
- ) : (
59
- catcher
60
- )
61
- }
62
-
63
- function PteValueFixer(props: InputProps) {
64
- const isPortableText = useMemo(
65
- () => isArraySchemaType(props.schemaType) && isPortableTextArray(props.schemaType),
66
- [props.schemaType],
67
- )
68
- const value = props.value
69
- if (isPortableText && value && !(value as any[]).length) {
70
- return props.renderDefault({...props, value: undefined})
71
- }
72
-
73
- return props.renderDefault(props)
74
- }
@@ -1,18 +0,0 @@
1
- import {formatDistanceToNow} from 'date-fns'
2
- import {useEffect, useReducer} from 'react'
3
-
4
- function useInterval(ms: number) {
5
- const [tick, update] = useReducer((n) => n + 1, 0)
6
-
7
- useEffect(() => {
8
- const i = setInterval(update, ms)
9
- return () => clearInterval(i)
10
- }, [ms])
11
- return tick
12
- }
13
-
14
- export function TimeAgo({date}: {date?: string}) {
15
- useInterval(1000)
16
- const timeSince = formatDistanceToNow(date ? new Date(date) : new Date())
17
- return <span title={timeSince}>{timeSince} ago</span>
18
- }
package/src/constants.ts DELETED
@@ -1,20 +0,0 @@
1
- import {minutesToMilliseconds} from 'date-fns'
2
-
3
- export const releaseAnnouncementUrl =
4
- 'https://www.sanity.io/blog/sanity-ai-assist-announcement?utm_source=sanity-assist-plugin&utm_medium=organic_social&utm_campaign=ai-assist&utm_content='
5
-
6
- export const instructionGuideUrl =
7
- 'https://sanity.io/guides/getting-started-with-ai-assist-instructions?utm_source=sanity-assist-plugin&utm_medium=organic_social&utm_campaign=ai-assist&utm_content='
8
-
9
- export const giveFeedbackUrl = 'https://forms.gle/Kwz7CThxGeA2GiEU8'
10
-
11
- export const salesUrl =
12
- 'https://www.sanity.io/contact/sales?utm_source=sanity-assist-plugin&utm_medium=organic_social&utm_campaign=ai-assist&utm_content='
13
-
14
- export const packageName = '@sanity/assist'
15
-
16
- export const pluginTitle = 'Sanity AI Assist'
17
-
18
- export const pluginTitleShort = 'AI Assist'
19
-
20
- export const maxHistoryVisibilityMs = minutesToMilliseconds(30)
@@ -1,20 +0,0 @@
1
- import {LockIcon} from '@sanity/icons'
2
- import {Text, Tooltip} from '@sanity/ui'
3
-
4
- export function PrivateIcon() {
5
- return (
6
- <Tooltip
7
- content={
8
- <Text size={1} style={{whiteSpace: 'nowrap'}}>
9
- Only visible to you
10
- </Text>
11
- }
12
- fallbackPlacements={['bottom']}
13
- padding={2}
14
- placement="top"
15
- portal
16
- >
17
- <LockIcon />
18
- </Tooltip>
19
- )
20
- }