@sanity/assist 5.0.3 → 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.
- package/LICENSE +1 -1
- package/README.md +28 -254
- package/dist/index.d.ts +322 -410
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3182 -2673
- package/dist/index.js.map +1 -1
- package/package.json +41 -77
- package/dist/index.cjs +0 -4264
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -791
- package/sanity.json +0 -8
- package/src/_lib/connector/ConnectFromRegion.tsx +0 -25
- package/src/_lib/connector/ConnectToRegion.tsx +0 -23
- package/src/_lib/connector/ConnectorRegion.tsx +0 -24
- package/src/_lib/connector/ConnectorsProvider.tsx +0 -20
- package/src/_lib/connector/ConnectorsStore.ts +0 -122
- package/src/_lib/connector/ConnectorsStoreContext.ts +0 -5
- package/src/_lib/connector/helpers.ts +0 -5
- package/src/_lib/connector/index.ts +0 -9
- package/src/_lib/connector/mapConnectorToLine.ts +0 -83
- package/src/_lib/connector/types.ts +0 -56
- package/src/_lib/connector/useConnectorsStore.ts +0 -14
- package/src/_lib/connector/useRegionRects.ts +0 -142
- package/src/_lib/fixedListenQuery.ts +0 -101
- package/src/_lib/form/DocumentForm.tsx +0 -201
- package/src/_lib/form/constants.ts +0 -1
- package/src/_lib/form/helpers.ts +0 -32
- package/src/_lib/form/index.ts +0 -1
- package/src/_lib/randomKey.ts +0 -29
- package/src/_lib/useListeningQuery.ts +0 -62
- package/src/_lib/usePrevious.ts +0 -9
- package/src/assistConnectors/AssistConnectorsOverlay.tsx +0 -133
- package/src/assistConnectors/ConnectorPath.tsx +0 -63
- package/src/assistConnectors/draw/arrowPath.ts +0 -9
- package/src/assistConnectors/draw/connectorPath.ts +0 -142
- package/src/assistConnectors/index.ts +0 -1
- package/src/assistDocument/AssistDocumentContext.tsx +0 -51
- package/src/assistDocument/AssistDocumentContextProvider.tsx +0 -17
- package/src/assistDocument/AssistDocumentInput.tsx +0 -61
- package/src/assistDocument/AssistDocumentLayout.tsx +0 -12
- package/src/assistDocument/RequestRunInstructionProvider.tsx +0 -61
- package/src/assistDocument/components/AssistDocumentForm.tsx +0 -286
- package/src/assistDocument/components/AssistTypeContext.tsx +0 -7
- package/src/assistDocument/components/FieldRefPreview.tsx +0 -26
- package/src/assistDocument/components/InstructionsArrayField.tsx +0 -8
- package/src/assistDocument/components/InstructionsArrayInput.tsx +0 -27
- package/src/assistDocument/components/SelectedFieldContext.tsx +0 -10
- package/src/assistDocument/components/generic/HiddenFieldTitle.tsx +0 -5
- package/src/assistDocument/components/helpers.ts +0 -21
- package/src/assistDocument/components/instruction/BackToInstructionsLink.tsx +0 -32
- package/src/assistDocument/components/instruction/FieldRefInput.tsx +0 -54
- package/src/assistDocument/components/instruction/InstructionInput.tsx +0 -89
- package/src/assistDocument/components/instruction/InstructionOutputField.tsx +0 -46
- package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +0 -206
- package/src/assistDocument/components/instruction/PromptInput.tsx +0 -59
- package/src/assistDocument/components/instruction/appearance/IconInput.tsx +0 -46
- package/src/assistDocument/components/instruction/appearance/InstructionVisibility.tsx +0 -37
- package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +0 -129
- package/src/assistDocument/hooks/useDocumentState.ts +0 -6
- package/src/assistDocument/hooks/useInstructionToaster.tsx +0 -75
- package/src/assistDocument/hooks/useStudioAssistDocument.ts +0 -99
- package/src/assistDocument/index.ts +0 -1
- package/src/assistFormComponents/AssistField.tsx +0 -63
- package/src/assistFormComponents/AssistFormBlock.tsx +0 -31
- package/src/assistFormComponents/AssistInlineFormBlock.tsx +0 -13
- package/src/assistFormComponents/AssistItem.tsx +0 -21
- package/src/assistFormComponents/validation/listItem.tsx +0 -63
- package/src/assistFormComponents/validation/validationList.tsx +0 -90
- package/src/assistInspector/AssistInspector.tsx +0 -423
- package/src/assistInspector/FieldAutocomplete.tsx +0 -146
- package/src/assistInspector/InstructionTaskHistoryButton.tsx +0 -262
- package/src/assistInspector/constants.ts +0 -1
- package/src/assistInspector/helpers.ts +0 -211
- package/src/assistInspector/index.ts +0 -27
- package/src/assistLayout/AiAssistanceConfigContext.tsx +0 -32
- package/src/assistLayout/AiAssistanceConfigProvider.tsx +0 -98
- package/src/assistLayout/AssistLayout.tsx +0 -39
- package/src/assistLayout/RunInstructionProvider.tsx +0 -278
- package/src/assistLayout/fieldRefCache.tsx +0 -34
- package/src/assistTypes.ts +0 -83
- package/src/components/AssistFeatureBadge.tsx +0 -9
- package/src/components/FadeInContent.tsx +0 -40
- package/src/components/HideReferenceChangedBannerInput.tsx +0 -25
- package/src/components/ImageContext.tsx +0 -85
- package/src/components/SafeValueInput.tsx +0 -74
- package/src/components/TimeAgo.tsx +0 -18
- package/src/constants.ts +0 -20
- package/src/fieldActions/PrivateIcon.tsx +0 -20
- package/src/fieldActions/assistFieldActions.tsx +0 -320
- package/src/fieldActions/customFieldActions.tsx +0 -333
- package/src/fieldActions/generateCaptionActions.tsx +0 -77
- package/src/fieldActions/generateImageActions.tsx +0 -58
- package/src/fieldActions/useUserInput.ts +0 -107
- package/src/globals.d.ts +0 -4
- package/src/helpers/assistSupported.ts +0 -49
- package/src/helpers/conditionalMembers.test.ts +0 -319
- package/src/helpers/conditionalMembers.ts +0 -134
- package/src/helpers/ids.test.ts +0 -28
- package/src/helpers/ids.ts +0 -23
- package/src/helpers/misc.ts +0 -25
- package/src/helpers/styleguide.ts +0 -24
- package/src/helpers/typeUtils.ts +0 -60
- package/src/helpers/useAssistSupported.ts +0 -8
- package/src/index.ts +0 -26
- package/src/onboarding/FirstAssistedPathProvider.tsx +0 -30
- package/src/onboarding/InspectorOnboarding.tsx +0 -47
- package/src/onboarding/onboardingStore.ts +0 -32
- package/src/plugin.tsx +0 -162
- package/src/presence/AiFieldPresence.tsx +0 -28
- package/src/presence/AssistAvatar.tsx +0 -96
- package/src/presence/AssistDocumentPresence.tsx +0 -50
- package/src/presence/useAssistPresence.ts +0 -64
- package/src/schemas/assistDocumentSchema.tsx +0 -497
- package/src/schemas/contextDocumentSchema.tsx +0 -57
- package/src/schemas/index.ts +0 -69
- package/src/schemas/serialize/SchemTypeTool.tsx +0 -103
- package/src/schemas/serialize/schemaUtils.ts +0 -38
- package/src/schemas/serialize/serializeSchema.test.ts +0 -819
- package/src/schemas/serialize/serializeSchema.ts +0 -224
- package/src/schemas/serializedSchemaTypeSchema.ts +0 -60
- package/src/schemas/typeDefExtensions.ts +0 -127
- package/src/translate/FieldTranslationProvider.tsx +0 -382
- package/src/translate/getLanguageParams.ts +0 -26
- package/src/translate/languageStore.ts +0 -18
- package/src/translate/paths.test.ts +0 -181
- package/src/translate/paths.ts +0 -183
- package/src/translate/translateActions.tsx +0 -205
- package/src/translate/types.ts +0 -197
- package/src/types.ts +0 -220
- package/src/useApiClient.ts +0 -338
- package/v2-incompatible.js +0 -11
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import {Box, type BoxProps, Flex, focusFirstDescendant, Spinner, Text} from '@sanity/ui'
|
|
2
|
-
import type React from 'react'
|
|
3
|
-
import {type HTMLProps, useEffect, useMemo, useRef} from 'react'
|
|
4
|
-
import {tap} from 'rxjs/operators'
|
|
5
|
-
import {
|
|
6
|
-
createPatchChannel,
|
|
7
|
-
type DocumentMutationEvent,
|
|
8
|
-
type DocumentRebaseEvent,
|
|
9
|
-
FormBuilder,
|
|
10
|
-
fromMutationPatches,
|
|
11
|
-
type PatchMsg,
|
|
12
|
-
useDocumentPresence,
|
|
13
|
-
useDocumentStore,
|
|
14
|
-
} from 'sanity'
|
|
15
|
-
import {useDocumentPane} from 'sanity/structure'
|
|
16
|
-
|
|
17
|
-
import {assistFormId} from './constants'
|
|
18
|
-
|
|
19
|
-
const preventDefault = (ev: React.FormEvent) => ev.preventDefault()
|
|
20
|
-
|
|
21
|
-
export function DocumentForm(
|
|
22
|
-
props: Omit<BoxProps, 'as'> & Omit<HTMLProps<HTMLDivElement>, 'as' | 'onSubmit' | 'ref'>,
|
|
23
|
-
) {
|
|
24
|
-
const {
|
|
25
|
-
collapsedFieldSets,
|
|
26
|
-
collapsedPaths,
|
|
27
|
-
displayed: value,
|
|
28
|
-
documentId,
|
|
29
|
-
documentType,
|
|
30
|
-
editState,
|
|
31
|
-
formState,
|
|
32
|
-
onBlur,
|
|
33
|
-
onChange,
|
|
34
|
-
onFocus,
|
|
35
|
-
onPathOpen,
|
|
36
|
-
onSetActiveFieldGroup,
|
|
37
|
-
onSetCollapsedFieldSet,
|
|
38
|
-
onSetCollapsedPath,
|
|
39
|
-
ready,
|
|
40
|
-
validation,
|
|
41
|
-
} = useDocumentPane()
|
|
42
|
-
|
|
43
|
-
const documentStore = useDocumentStore()
|
|
44
|
-
const presence = useDocumentPresence(documentId)
|
|
45
|
-
|
|
46
|
-
// The `patchChannel` is an INTERNAL publish/subscribe channel that we use to notify form-builder
|
|
47
|
-
// nodes about both remote and local patches.
|
|
48
|
-
// - Used by the Portable Text input to modify selections.
|
|
49
|
-
// - Used by `withDocument` to reset value.
|
|
50
|
-
const patchChannel = useMemo(() => createPatchChannel(), [])
|
|
51
|
-
|
|
52
|
-
const isLocked = editState?.transactionSyncLock?.enabled
|
|
53
|
-
|
|
54
|
-
useEffect(() => {
|
|
55
|
-
const sub = documentStore.pair
|
|
56
|
-
.documentEvents(documentId, documentType)
|
|
57
|
-
.pipe(
|
|
58
|
-
tap((event) => {
|
|
59
|
-
if (event.type === 'mutation') {
|
|
60
|
-
patchChannel.publish(prepareMutationEvent(event))
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (event.type === 'rebase') {
|
|
64
|
-
patchChannel.publish(prepareRebaseEvent(event))
|
|
65
|
-
}
|
|
66
|
-
}),
|
|
67
|
-
)
|
|
68
|
-
.subscribe()
|
|
69
|
-
|
|
70
|
-
return () => {
|
|
71
|
-
sub.unsubscribe()
|
|
72
|
-
}
|
|
73
|
-
}, [documentId, documentStore, documentType, patchChannel])
|
|
74
|
-
|
|
75
|
-
const hasRev = Boolean(value?._rev)
|
|
76
|
-
useEffect(() => {
|
|
77
|
-
if (hasRev) {
|
|
78
|
-
// this is a workaround for an issue that caused the document pushed to withDocument to get
|
|
79
|
-
// stuck at the first initial value.
|
|
80
|
-
// This effect is triggered only when the document goes from not having a revision, to getting one
|
|
81
|
-
// so it will kick in as soon as the document is received from the backend
|
|
82
|
-
patchChannel.publish({
|
|
83
|
-
type: 'mutation',
|
|
84
|
-
patches: [],
|
|
85
|
-
snapshot: value,
|
|
86
|
-
})
|
|
87
|
-
}
|
|
88
|
-
// React to changes in hasRev only
|
|
89
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
90
|
-
}, [hasRev])
|
|
91
|
-
|
|
92
|
-
const formRef = useRef<null | HTMLDivElement>(null)
|
|
93
|
-
|
|
94
|
-
useEffect(() => {
|
|
95
|
-
focusFirstDescendant(formRef.current!)
|
|
96
|
-
}, [])
|
|
97
|
-
|
|
98
|
-
if (isLocked) {
|
|
99
|
-
return (
|
|
100
|
-
<Box as="form" {...props} ref={formRef}>
|
|
101
|
-
<Flex
|
|
102
|
-
align="center"
|
|
103
|
-
direction="column"
|
|
104
|
-
height="fill"
|
|
105
|
-
justify="center"
|
|
106
|
-
padding={3}
|
|
107
|
-
sizing="border"
|
|
108
|
-
>
|
|
109
|
-
<Text size={1}>
|
|
110
|
-
Please hold tight while the document is synced. This usually happens right after the
|
|
111
|
-
document has been published, and it shouldn’t take more than a few seconds
|
|
112
|
-
</Text>
|
|
113
|
-
</Flex>
|
|
114
|
-
</Box>
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return (
|
|
119
|
-
<Box as="form" {...props} onSubmit={preventDefault} ref={formRef}>
|
|
120
|
-
{ready ? (
|
|
121
|
-
formState === null ? (
|
|
122
|
-
<Flex
|
|
123
|
-
align="center"
|
|
124
|
-
direction="column"
|
|
125
|
-
height="fill"
|
|
126
|
-
justify="center"
|
|
127
|
-
padding={3}
|
|
128
|
-
sizing="border"
|
|
129
|
-
>
|
|
130
|
-
<Text size={1}>This form is hidden</Text>
|
|
131
|
-
</Flex>
|
|
132
|
-
) : (
|
|
133
|
-
<FormBuilder
|
|
134
|
-
__internal_patchChannel={patchChannel}
|
|
135
|
-
collapsedFieldSets={collapsedFieldSets}
|
|
136
|
-
collapsedPaths={collapsedPaths}
|
|
137
|
-
focusPath={formState.focusPath}
|
|
138
|
-
changed={formState.changed}
|
|
139
|
-
focused={formState.focused}
|
|
140
|
-
groups={formState.groups}
|
|
141
|
-
id={assistFormId}
|
|
142
|
-
members={formState.members}
|
|
143
|
-
onChange={onChange}
|
|
144
|
-
onFieldGroupSelect={onSetActiveFieldGroup}
|
|
145
|
-
onPathBlur={onBlur}
|
|
146
|
-
onPathFocus={onFocus}
|
|
147
|
-
onPathOpen={onPathOpen}
|
|
148
|
-
onSetFieldSetCollapsed={onSetCollapsedFieldSet}
|
|
149
|
-
onSetPathCollapsed={onSetCollapsedPath}
|
|
150
|
-
presence={presence}
|
|
151
|
-
readOnly={formState.readOnly}
|
|
152
|
-
schemaType={formState.schemaType}
|
|
153
|
-
validation={validation}
|
|
154
|
-
value={formState.value as any}
|
|
155
|
-
hasUpstreamVersion={false}
|
|
156
|
-
/>
|
|
157
|
-
)
|
|
158
|
-
) : (
|
|
159
|
-
<Flex
|
|
160
|
-
align="center"
|
|
161
|
-
direction="column"
|
|
162
|
-
height="fill"
|
|
163
|
-
justify="center"
|
|
164
|
-
padding={3}
|
|
165
|
-
sizing="border"
|
|
166
|
-
>
|
|
167
|
-
<Spinner muted />
|
|
168
|
-
|
|
169
|
-
<Box marginTop={3}>
|
|
170
|
-
<Text align="center" muted size={1}>
|
|
171
|
-
Loading document
|
|
172
|
-
</Text>
|
|
173
|
-
</Box>
|
|
174
|
-
</Flex>
|
|
175
|
-
)}
|
|
176
|
-
</Box>
|
|
177
|
-
)
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function prepareMutationEvent(event: DocumentMutationEvent): PatchMsg {
|
|
181
|
-
const patches = event.mutations.map((mut) => mut.patch).filter(Boolean)
|
|
182
|
-
|
|
183
|
-
return {
|
|
184
|
-
type: 'mutation',
|
|
185
|
-
snapshot: event.document,
|
|
186
|
-
patches: fromMutationPatches(event.origin, patches),
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function prepareRebaseEvent(event: DocumentRebaseEvent): PatchMsg {
|
|
191
|
-
const remotePatches = event.remoteMutations.map((mut) => mut.patch).filter(Boolean)
|
|
192
|
-
const localPatches = event.localMutations.map((mut) => mut.patch).filter(Boolean)
|
|
193
|
-
|
|
194
|
-
return {
|
|
195
|
-
type: 'rebase',
|
|
196
|
-
snapshot: event.document,
|
|
197
|
-
patches: fromMutationPatches('remote', remotePatches).concat(
|
|
198
|
-
fromMutationPatches('local', localPatches),
|
|
199
|
-
),
|
|
200
|
-
}
|
|
201
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const assistFormId = 'assist'
|
package/src/_lib/form/helpers.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import {isArraySchemaType, isObjectSchemaType, ObjectItem, SchemaType} from 'sanity'
|
|
2
|
-
|
|
3
|
-
import {randomKey} from '../randomKey'
|
|
4
|
-
|
|
5
|
-
export function createProtoValue(type: SchemaType): any {
|
|
6
|
-
if (isObjectSchemaType(type)) {
|
|
7
|
-
return type.name === 'object' ? {} : {_type: type.name}
|
|
8
|
-
}
|
|
9
|
-
if (isArraySchemaType(type)) {
|
|
10
|
-
return []
|
|
11
|
-
}
|
|
12
|
-
if (type.jsonType === 'string') {
|
|
13
|
-
return ''
|
|
14
|
-
}
|
|
15
|
-
if (type.jsonType === 'number') {
|
|
16
|
-
return 0
|
|
17
|
-
}
|
|
18
|
-
if (type.jsonType === 'boolean') {
|
|
19
|
-
return false
|
|
20
|
-
}
|
|
21
|
-
return undefined
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function createProtoArrayValue<Item extends ObjectItem>(type: SchemaType): Item {
|
|
25
|
-
if (!isObjectSchemaType(type)) {
|
|
26
|
-
throw new Error(
|
|
27
|
-
`Invalid item type: "${type.type}". Default array input can only contain objects (for now)`,
|
|
28
|
-
)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return {...createProtoValue(type), _key: randomKey(12)} as Item
|
|
32
|
-
}
|
package/src/_lib/form/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './DocumentForm'
|
package/src/_lib/randomKey.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import getRandomValues from 'get-random-values-esm'
|
|
2
|
-
|
|
3
|
-
// WHATWG crypto RNG - https://w3c.github.io/webcrypto/Overview.html
|
|
4
|
-
function whatwgRNG(length = 16) {
|
|
5
|
-
const rnds8 = new Uint8Array(length)
|
|
6
|
-
getRandomValues(rnds8)
|
|
7
|
-
return rnds8
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const getByteHexTable = (() => {
|
|
11
|
-
let table: string[]
|
|
12
|
-
return () => {
|
|
13
|
-
if (table) {
|
|
14
|
-
return table
|
|
15
|
-
}
|
|
16
|
-
table = []
|
|
17
|
-
for (let i = 0; i < 256; ++i) {
|
|
18
|
-
table[i] = (i + 0x100).toString(16).substring(1)
|
|
19
|
-
}
|
|
20
|
-
return table
|
|
21
|
-
}
|
|
22
|
-
})()
|
|
23
|
-
|
|
24
|
-
export function randomKey(length?: number) {
|
|
25
|
-
const table = getByteHexTable()
|
|
26
|
-
return whatwgRNG(length)
|
|
27
|
-
.reduce((str, n) => str + table[n], '')
|
|
28
|
-
.slice(0, length)
|
|
29
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import {useEffect, useRef, useState} from 'react'
|
|
2
|
-
import isEqual from 'react-fast-compare'
|
|
3
|
-
import {catchError, distinctUntilChanged} from 'rxjs/operators'
|
|
4
|
-
import {ListenQueryOptions, useClient} from 'sanity'
|
|
5
|
-
|
|
6
|
-
import {listenQuery} from './fixedListenQuery'
|
|
7
|
-
|
|
8
|
-
type Params = Record<string, string | number | boolean | string[]>
|
|
9
|
-
|
|
10
|
-
type ReturnShape<T> = {
|
|
11
|
-
loading: boolean
|
|
12
|
-
error: boolean
|
|
13
|
-
data: T | null
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
type Observable = {
|
|
17
|
-
unsubscribe: () => void
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const DEFAULT_PARAMS = {}
|
|
21
|
-
const DEFAULT_OPTIONS: ListenQueryOptions = {apiVersion: `v2022-05-09`}
|
|
22
|
-
|
|
23
|
-
export function useListeningQuery<T>(
|
|
24
|
-
query: string,
|
|
25
|
-
params: Params = DEFAULT_PARAMS,
|
|
26
|
-
options: ListenQueryOptions = DEFAULT_OPTIONS,
|
|
27
|
-
): ReturnShape<T> {
|
|
28
|
-
const [loading, setLoading] = useState(true)
|
|
29
|
-
const [error, setError] = useState(false)
|
|
30
|
-
const [data, setData] = useState<T | null>(null)
|
|
31
|
-
const subscription = useRef<null | Observable>(null)
|
|
32
|
-
|
|
33
|
-
const client = useClient({apiVersion: `v2022-05-09`})
|
|
34
|
-
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
if (query) {
|
|
37
|
-
subscription.current = listenQuery(client, query, params, options)
|
|
38
|
-
.pipe(
|
|
39
|
-
distinctUntilChanged(isEqual),
|
|
40
|
-
catchError((err) => {
|
|
41
|
-
console.error(err)
|
|
42
|
-
setError(err)
|
|
43
|
-
setLoading(false)
|
|
44
|
-
setData(null)
|
|
45
|
-
|
|
46
|
-
return err
|
|
47
|
-
}),
|
|
48
|
-
)
|
|
49
|
-
.subscribe((documents) => {
|
|
50
|
-
setData((current) => (isEqual(current, documents) ? current : documents))
|
|
51
|
-
setLoading(false)
|
|
52
|
-
setError(false)
|
|
53
|
-
})
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return () => {
|
|
57
|
-
return subscription.current ? subscription.current.unsubscribe() : undefined
|
|
58
|
-
}
|
|
59
|
-
}, [query, params, options, client])
|
|
60
|
-
|
|
61
|
-
return {loading, error, data}
|
|
62
|
-
}
|
package/src/_lib/usePrevious.ts
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import {Fragment, useEffect, useState} from 'react'
|
|
2
|
-
|
|
3
|
-
import {Connector, ConnectorOptions} from '../_lib/connector'
|
|
4
|
-
import {ConnectorPath} from './ConnectorPath'
|
|
5
|
-
|
|
6
|
-
const DEBUG = false
|
|
7
|
-
|
|
8
|
-
const options: ConnectorOptions = {
|
|
9
|
-
arrow: {
|
|
10
|
-
marginX: 10.5,
|
|
11
|
-
marginY: 5,
|
|
12
|
-
size: 4,
|
|
13
|
-
threshold: 16.5,
|
|
14
|
-
},
|
|
15
|
-
divider: {
|
|
16
|
-
offsetX: -10.5,
|
|
17
|
-
},
|
|
18
|
-
path: {
|
|
19
|
-
cornerRadius: 3,
|
|
20
|
-
marginY: 10.5,
|
|
21
|
-
strokeWidth: 1,
|
|
22
|
-
},
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function AssistConnectorsOverlay(props: {connectors: Connector[]}) {
|
|
26
|
-
const {connectors} = props
|
|
27
|
-
// const zIndexes = connectors.map((connector) => {
|
|
28
|
-
// const zIndex = connector.from.payload?.zIndex
|
|
29
|
-
|
|
30
|
-
// if (typeof zIndex === 'number') {
|
|
31
|
-
// return zIndex
|
|
32
|
-
// }
|
|
33
|
-
|
|
34
|
-
// return 1
|
|
35
|
-
// })
|
|
36
|
-
const [, setRedraw] = useState(false)
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
// hacky workaround to force redraw for connectors on initial render
|
|
39
|
-
// this seem to improve initial measurements of elements
|
|
40
|
-
setRedraw(true)
|
|
41
|
-
}, [])
|
|
42
|
-
|
|
43
|
-
// const zIndex = zIndexes.length ? Math.max(...zIndexes) : 1
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<>
|
|
47
|
-
<svg
|
|
48
|
-
fill="none"
|
|
49
|
-
width={window.innerWidth}
|
|
50
|
-
height={window.innerHeight}
|
|
51
|
-
style={{
|
|
52
|
-
position: 'absolute',
|
|
53
|
-
top: 0,
|
|
54
|
-
left: 0,
|
|
55
|
-
width: '100%',
|
|
56
|
-
height: '100%',
|
|
57
|
-
pointerEvents: 'none',
|
|
58
|
-
zIndex: 150,
|
|
59
|
-
// zIndex,
|
|
60
|
-
}}
|
|
61
|
-
>
|
|
62
|
-
{connectors.map((connector) => (
|
|
63
|
-
<ConnectorPath
|
|
64
|
-
from={connector.from}
|
|
65
|
-
key={connector.key}
|
|
66
|
-
options={options}
|
|
67
|
-
to={connector.to}
|
|
68
|
-
/>
|
|
69
|
-
))}
|
|
70
|
-
</svg>
|
|
71
|
-
{DEBUG &&
|
|
72
|
-
connectors.map(({key, from, to}) => {
|
|
73
|
-
return (
|
|
74
|
-
<Fragment key={key}>
|
|
75
|
-
<div
|
|
76
|
-
style={{
|
|
77
|
-
position: 'fixed',
|
|
78
|
-
top: from.bounds.y,
|
|
79
|
-
left: from.bounds.x,
|
|
80
|
-
width: from.bounds.w,
|
|
81
|
-
height: from.bounds.h,
|
|
82
|
-
pointerEvents: 'none',
|
|
83
|
-
overflow: 'hidden',
|
|
84
|
-
outline: '1px dotted red',
|
|
85
|
-
outlineOffset: -1,
|
|
86
|
-
zIndex: 10000000 - 1,
|
|
87
|
-
}}
|
|
88
|
-
>
|
|
89
|
-
<div
|
|
90
|
-
style={{
|
|
91
|
-
position: 'absolute',
|
|
92
|
-
top: from.element.y - from.bounds.y,
|
|
93
|
-
left: from.element.x - from.bounds.x,
|
|
94
|
-
width: from.element.w,
|
|
95
|
-
height: from.element.h,
|
|
96
|
-
border: '1px solid red',
|
|
97
|
-
boxSizing: 'border-box',
|
|
98
|
-
}}
|
|
99
|
-
/>
|
|
100
|
-
</div>
|
|
101
|
-
|
|
102
|
-
<div
|
|
103
|
-
style={{
|
|
104
|
-
position: 'fixed',
|
|
105
|
-
top: to.bounds.y,
|
|
106
|
-
left: to.bounds.x,
|
|
107
|
-
width: to.bounds.w,
|
|
108
|
-
height: to.bounds.h,
|
|
109
|
-
pointerEvents: 'none',
|
|
110
|
-
overflow: 'hidden',
|
|
111
|
-
outline: '1px dotted teal',
|
|
112
|
-
outlineOffset: -1,
|
|
113
|
-
zIndex: 10000000 - 1,
|
|
114
|
-
}}
|
|
115
|
-
>
|
|
116
|
-
<div
|
|
117
|
-
style={{
|
|
118
|
-
position: 'absolute',
|
|
119
|
-
top: to.element.y - to.bounds.y,
|
|
120
|
-
left: to.element.x - to.bounds.x,
|
|
121
|
-
width: to.element.w,
|
|
122
|
-
height: to.element.h,
|
|
123
|
-
border: '1px solid teal',
|
|
124
|
-
boxSizing: 'border-box',
|
|
125
|
-
}}
|
|
126
|
-
/>
|
|
127
|
-
</div>
|
|
128
|
-
</Fragment>
|
|
129
|
-
)
|
|
130
|
-
})}
|
|
131
|
-
</>
|
|
132
|
-
)
|
|
133
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import {rgba, useTheme} from '@sanity/ui'
|
|
2
|
-
import {useMemo} from 'react'
|
|
3
|
-
|
|
4
|
-
import {ConnectorOptions, mapConnectorToLine, Rect} from '../_lib/connector'
|
|
5
|
-
import {arrowPath} from './draw/arrowPath'
|
|
6
|
-
import {drawConnectorPath} from './draw/connectorPath'
|
|
7
|
-
|
|
8
|
-
export function ConnectorPath(props: {
|
|
9
|
-
from: {bounds: Rect; element: Rect}
|
|
10
|
-
to: {bounds: Rect; element: Rect}
|
|
11
|
-
options: ConnectorOptions
|
|
12
|
-
}) {
|
|
13
|
-
const {from, options, to} = props
|
|
14
|
-
const {strokeWidth} = options.path
|
|
15
|
-
const theme = useTheme()
|
|
16
|
-
|
|
17
|
-
const line = useMemo(() => mapConnectorToLine(options, {from, to}), [from, options, to])
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<>
|
|
21
|
-
<path
|
|
22
|
-
d={drawConnectorPath(options, line)}
|
|
23
|
-
stroke={theme.sanity.color.base.bg}
|
|
24
|
-
strokeWidth={strokeWidth + 4}
|
|
25
|
-
/>
|
|
26
|
-
|
|
27
|
-
<path
|
|
28
|
-
d={drawConnectorPath(options, line)}
|
|
29
|
-
stroke={rgba(theme.sanity.color.base.border, 0.5)}
|
|
30
|
-
strokeWidth={strokeWidth}
|
|
31
|
-
/>
|
|
32
|
-
|
|
33
|
-
{line.from.isAbove && (
|
|
34
|
-
<path
|
|
35
|
-
d={arrowPath(
|
|
36
|
-
options,
|
|
37
|
-
line.from.x + options.arrow.marginX,
|
|
38
|
-
line.from.bounds.y - options.arrow.threshold + options.arrow.marginY,
|
|
39
|
-
-1,
|
|
40
|
-
)}
|
|
41
|
-
stroke={theme.sanity.color.base.border}
|
|
42
|
-
strokeWidth={strokeWidth}
|
|
43
|
-
/>
|
|
44
|
-
)}
|
|
45
|
-
|
|
46
|
-
{line.from.isBelow && (
|
|
47
|
-
<path
|
|
48
|
-
d={arrowPath(
|
|
49
|
-
options,
|
|
50
|
-
line.from.x + options.arrow.marginX,
|
|
51
|
-
line.from.bounds.y +
|
|
52
|
-
line.from.bounds.h +
|
|
53
|
-
options.arrow.threshold -
|
|
54
|
-
options.arrow.marginY,
|
|
55
|
-
1,
|
|
56
|
-
)}
|
|
57
|
-
stroke={theme.sanity.color.base.border}
|
|
58
|
-
strokeWidth={strokeWidth}
|
|
59
|
-
/>
|
|
60
|
-
)}
|
|
61
|
-
</>
|
|
62
|
-
)
|
|
63
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import {ConnectorOptions} from '../../_lib/connector'
|
|
2
|
-
|
|
3
|
-
export function arrowPath(options: ConnectorOptions, x: number, y: number, dir: 1 | -1): string {
|
|
4
|
-
return [
|
|
5
|
-
`M ${x - options.arrow.size} ${y - options.arrow.size * dir} `,
|
|
6
|
-
`L ${x} ${y}`,
|
|
7
|
-
`L ${x + options.arrow.size} ${y - options.arrow.size * dir}`,
|
|
8
|
-
].join('')
|
|
9
|
-
}
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import {ConnectorLine, ConnectorOptions} from '../../_lib/connector'
|
|
2
|
-
|
|
3
|
-
export function drawArrowPath(
|
|
4
|
-
options: ConnectorOptions,
|
|
5
|
-
x: number,
|
|
6
|
-
y: number,
|
|
7
|
-
dir: number,
|
|
8
|
-
): string {
|
|
9
|
-
return [
|
|
10
|
-
`M ${x - options.arrow.size} ${y - options.arrow.size * dir} `,
|
|
11
|
-
`L ${x} ${y}`,
|
|
12
|
-
`L ${x + options.arrow.size} ${y - options.arrow.size * dir}`,
|
|
13
|
-
].join('')
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function moveTo(x: number, y: number) {
|
|
17
|
-
return `M${x} ${y}`
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function lineTo(x: number, y: number) {
|
|
21
|
-
return `L${x} ${y}`
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function join(strings: string[], delim = '') {
|
|
25
|
-
return strings.join(delim)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function quadCurve(x1: number, y1: number, x: number, y: number) {
|
|
29
|
-
return `Q${x1} ${y1} ${x} ${y}`
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function drawConnectorPath(options: ConnectorOptions, line: ConnectorLine): string {
|
|
33
|
-
const {cornerRadius} = options.path
|
|
34
|
-
const {from, to} = line
|
|
35
|
-
const {x: fromX, y: fromY} = from
|
|
36
|
-
const {x: _toX, y: toY} = to
|
|
37
|
-
|
|
38
|
-
const toX = _toX - 1
|
|
39
|
-
|
|
40
|
-
// Calculate divider position
|
|
41
|
-
const dividerX = to.bounds.x + options.divider.offsetX
|
|
42
|
-
|
|
43
|
-
// Calculate connector FROM path X position
|
|
44
|
-
const fromPathX = from.isAbove || from.isBelow ? fromX + options.arrow.marginX : fromX
|
|
45
|
-
|
|
46
|
-
// Calculate maximum corner radius
|
|
47
|
-
const r0 = Math.min(cornerRadius, Math.abs(fromPathX - dividerX) / 2)
|
|
48
|
-
const r1 = Math.min(cornerRadius, Math.abs(fromY - toY) / 2)
|
|
49
|
-
|
|
50
|
-
const cmds: string[] = []
|
|
51
|
-
|
|
52
|
-
// FROM
|
|
53
|
-
if (from.isAbove) {
|
|
54
|
-
cmds.push(
|
|
55
|
-
moveTo(
|
|
56
|
-
fromX + options.arrow.marginX,
|
|
57
|
-
fromY - options.arrow.threshold + options.arrow.marginY,
|
|
58
|
-
),
|
|
59
|
-
lineTo(fromX + options.arrow.marginX, fromY - r0),
|
|
60
|
-
quadCurve(fromX + options.arrow.marginX, fromY, fromX + options.arrow.marginX + r0, fromY),
|
|
61
|
-
)
|
|
62
|
-
} else if (from.isBelow) {
|
|
63
|
-
cmds.push(
|
|
64
|
-
moveTo(
|
|
65
|
-
fromX + options.arrow.marginX,
|
|
66
|
-
fromY + options.arrow.threshold - options.arrow.marginY,
|
|
67
|
-
),
|
|
68
|
-
lineTo(fromX + options.arrow.marginX, fromY + r0),
|
|
69
|
-
quadCurve(fromX + options.arrow.marginX, fromY, fromX + options.arrow.marginX + r0, fromY),
|
|
70
|
-
)
|
|
71
|
-
} else {
|
|
72
|
-
cmds.push(moveTo(fromX, fromY))
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// TO
|
|
76
|
-
if (to.isAbove) {
|
|
77
|
-
if (fromY < to.bounds.y) {
|
|
78
|
-
cmds.push(
|
|
79
|
-
lineTo(dividerX - r1, fromY),
|
|
80
|
-
quadCurve(dividerX, fromY, dividerX, fromY + r1),
|
|
81
|
-
lineTo(dividerX, toY - r1),
|
|
82
|
-
quadCurve(dividerX, toY, dividerX + r1, toY),
|
|
83
|
-
lineTo(dividerX - cornerRadius, toY),
|
|
84
|
-
quadCurve(dividerX, toY, dividerX, toY - cornerRadius),
|
|
85
|
-
lineTo(dividerX, toY - options.arrow.threshold + options.arrow.marginY),
|
|
86
|
-
)
|
|
87
|
-
} else {
|
|
88
|
-
cmds.push(
|
|
89
|
-
lineTo(dividerX - cornerRadius, fromY),
|
|
90
|
-
quadCurve(dividerX, fromY, dividerX, fromY - cornerRadius),
|
|
91
|
-
lineTo(dividerX, toY - options.arrow.threshold + options.arrow.marginY),
|
|
92
|
-
)
|
|
93
|
-
}
|
|
94
|
-
} else if (to.isBelow) {
|
|
95
|
-
if (fromY > to.bounds.y + to.bounds.h) {
|
|
96
|
-
// curl around
|
|
97
|
-
cmds.push(
|
|
98
|
-
lineTo(dividerX - options.arrow.marginX - r1, fromY),
|
|
99
|
-
quadCurve(
|
|
100
|
-
dividerX - options.arrow.marginX,
|
|
101
|
-
fromY,
|
|
102
|
-
dividerX - options.arrow.marginX,
|
|
103
|
-
fromY - r1,
|
|
104
|
-
),
|
|
105
|
-
lineTo(dividerX - options.arrow.marginX, toY + r1),
|
|
106
|
-
quadCurve(
|
|
107
|
-
dividerX - options.arrow.marginX,
|
|
108
|
-
toY,
|
|
109
|
-
dividerX - options.arrow.marginX + r1,
|
|
110
|
-
toY,
|
|
111
|
-
),
|
|
112
|
-
lineTo(dividerX - cornerRadius, toY),
|
|
113
|
-
quadCurve(dividerX, toY, dividerX, toY + cornerRadius),
|
|
114
|
-
lineTo(dividerX, toY + options.arrow.threshold - options.arrow.marginY),
|
|
115
|
-
)
|
|
116
|
-
} else {
|
|
117
|
-
cmds.push(
|
|
118
|
-
lineTo(dividerX - cornerRadius, fromY),
|
|
119
|
-
quadCurve(dividerX, fromY, dividerX, fromY + cornerRadius),
|
|
120
|
-
lineTo(dividerX, toY + options.arrow.threshold - options.arrow.marginY),
|
|
121
|
-
)
|
|
122
|
-
}
|
|
123
|
-
} else if (fromY < toY) {
|
|
124
|
-
cmds.push(
|
|
125
|
-
lineTo(dividerX - r0, fromY),
|
|
126
|
-
quadCurve(dividerX, fromY, dividerX, fromY + r1),
|
|
127
|
-
lineTo(dividerX, toY - r1),
|
|
128
|
-
quadCurve(dividerX, toY, dividerX + r1, toY),
|
|
129
|
-
lineTo(toX, toY),
|
|
130
|
-
)
|
|
131
|
-
} else {
|
|
132
|
-
cmds.push(
|
|
133
|
-
lineTo(dividerX - Math.min(r0, r1), fromY),
|
|
134
|
-
quadCurve(dividerX, fromY, dividerX, fromY - Math.min(r0, r1)),
|
|
135
|
-
lineTo(dividerX, toY + r1),
|
|
136
|
-
quadCurve(dividerX, toY, dividerX + r1, toY),
|
|
137
|
-
lineTo(toX, toY),
|
|
138
|
-
)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return join(cmds)
|
|
142
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './AssistConnectorsOverlay'
|