@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,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'
@@ -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
- }
@@ -1 +0,0 @@
1
- export * from './DocumentForm'
@@ -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
- }
@@ -1,9 +0,0 @@
1
- import {useEffect, useRef} from 'react'
2
-
3
- export function usePrevious<T>(value: T) {
4
- const ref = useRef<T>(undefined)
5
- useEffect(() => {
6
- ref.current = value
7
- }, [value])
8
- return ref.current
9
- }
@@ -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'