sanity-plugin-media 4.3.6 → 5.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 (162) hide show
  1. package/package.json +6 -15
  2. package/dist/index.cjs +0 -4721
  3. package/dist/index.cjs.map +0 -1
  4. package/dist/index.d.cts +0 -239
  5. package/dist/index.d.cts.map +0 -1
  6. package/sanity.json +0 -8
  7. package/src/__tests__/fixtures/createEpicTestStore.ts +0 -28
  8. package/src/__tests__/fixtures/listenMock.ts +0 -9
  9. package/src/__tests__/fixtures/mockSanityClient.ts +0 -84
  10. package/src/__tests__/fixtures/renderWithProviders.tsx +0 -55
  11. package/src/__tests__/fixtures/rootState.ts +0 -27
  12. package/src/__tests__/fixtures/withinDialog.ts +0 -28
  13. package/src/components/AssetGridVirtualized/index.tsx +0 -94
  14. package/src/components/AssetMetadata/index.tsx +0 -122
  15. package/src/components/AssetTableVirtualized/index.tsx +0 -73
  16. package/src/components/AutoTagInputWrapper/index.tsx +0 -85
  17. package/src/components/Browser/Browser.test.tsx +0 -45
  18. package/src/components/Browser/index.tsx +0 -90
  19. package/src/components/Browser/useBrowserInit.ts +0 -126
  20. package/src/components/ButtonAssetCopy/index.tsx +0 -65
  21. package/src/components/ButtonViewGroup/index.tsx +0 -39
  22. package/src/components/CardAsset/CardAsset.test.tsx +0 -323
  23. package/src/components/CardAsset/index.tsx +0 -290
  24. package/src/components/CardUpload/index.tsx +0 -161
  25. package/src/components/Controls/index.tsx +0 -136
  26. package/src/components/DebugControls/index.tsx +0 -80
  27. package/src/components/Dialog/index.tsx +0 -11
  28. package/src/components/DialogAssetEdit/Details.tsx +0 -181
  29. package/src/components/DialogAssetEdit/DialogAssetEdit.test.tsx +0 -216
  30. package/src/components/DialogAssetEdit/index.tsx +0 -493
  31. package/src/components/DialogConfirm/index.tsx +0 -90
  32. package/src/components/DialogSearchFacets/index.tsx +0 -42
  33. package/src/components/DialogTagCreate/DialogTagCreate.test.tsx +0 -121
  34. package/src/components/DialogTagCreate/index.tsx +0 -111
  35. package/src/components/DialogTagEdit/DialogTagEdit.test.tsx +0 -165
  36. package/src/components/DialogTagEdit/index.tsx +0 -201
  37. package/src/components/DialogTags/index.tsx +0 -45
  38. package/src/components/Dialogs/index.tsx +0 -76
  39. package/src/components/DocumentList/index.tsx +0 -62
  40. package/src/components/FileAssetPreview/index.tsx +0 -37
  41. package/src/components/FileIcon/index.tsx +0 -43
  42. package/src/components/FormBuilderTool/FormBuilderTool.test.tsx +0 -63
  43. package/src/components/FormBuilderTool/index.tsx +0 -69
  44. package/src/components/FormFieldInputLabel/index.tsx +0 -66
  45. package/src/components/FormFieldInputTags/index.tsx +0 -98
  46. package/src/components/FormFieldInputText/index.tsx +0 -41
  47. package/src/components/FormFieldInputTextarea/index.tsx +0 -43
  48. package/src/components/FormSubmitButton/index.tsx +0 -59
  49. package/src/components/Header/index.tsx +0 -80
  50. package/src/components/Image/index.tsx +0 -41
  51. package/src/components/Items/index.tsx +0 -68
  52. package/src/components/Notifications/index.tsx +0 -24
  53. package/src/components/OrderSelect/index.tsx +0 -66
  54. package/src/components/PickedBar/index.tsx +0 -77
  55. package/src/components/Progress/index.tsx +0 -38
  56. package/src/components/ReduxProvider/index.tsx +0 -96
  57. package/src/components/SearchFacet/index.tsx +0 -66
  58. package/src/components/SearchFacetNumber/index.tsx +0 -133
  59. package/src/components/SearchFacetSelect/index.tsx +0 -110
  60. package/src/components/SearchFacetString/index.tsx +0 -88
  61. package/src/components/SearchFacetTags/index.tsx +0 -121
  62. package/src/components/SearchFacets/index.tsx +0 -72
  63. package/src/components/SearchFacetsControl/index.tsx +0 -140
  64. package/src/components/TableHeader/index.tsx +0 -110
  65. package/src/components/TableHeaderItem/index.tsx +0 -61
  66. package/src/components/TableRowAsset/index.tsx +0 -419
  67. package/src/components/TableRowUpload/index.tsx +0 -164
  68. package/src/components/Tag/index.tsx +0 -200
  69. package/src/components/TagIcon/index.tsx +0 -22
  70. package/src/components/TagView/index.tsx +0 -39
  71. package/src/components/TagViewHeader/index.tsx +0 -70
  72. package/src/components/TagsPanel/index.tsx +0 -40
  73. package/src/components/TagsVirtualized/index.tsx +0 -160
  74. package/src/components/TextInputNumber/index.tsx +0 -32
  75. package/src/components/TextInputSearch/index.tsx +0 -60
  76. package/src/components/Tool/index.tsx +0 -13
  77. package/src/components/UploadDropzone/UploadDropzone.test.tsx +0 -40
  78. package/src/components/UploadDropzone/index.tsx +0 -173
  79. package/src/config/orders.ts +0 -28
  80. package/src/config/searchFacets.ts +0 -312
  81. package/src/constants.ts +0 -87
  82. package/src/contexts/AssetSourceDispatchContext.tsx +0 -38
  83. package/src/contexts/DropzoneDispatchContext.tsx +0 -32
  84. package/src/contexts/ToolOptionsContext.tsx +0 -66
  85. package/src/formSchema/index.test.ts +0 -56
  86. package/src/formSchema/index.ts +0 -39
  87. package/src/hooks/useBreakpointIndex.ts +0 -50
  88. package/src/hooks/useKeyPress.ts +0 -39
  89. package/src/hooks/usePortalPopoverProps.ts +0 -13
  90. package/src/hooks/useTypedSelector.ts +0 -7
  91. package/src/hooks/useVersionedClient.ts +0 -6
  92. package/src/index.ts +0 -5
  93. package/src/modules/assets/actions.ts +0 -42
  94. package/src/modules/assets/deleteAndUpdateEpics.test.ts +0 -87
  95. package/src/modules/assets/fetchEpic.test.ts +0 -73
  96. package/src/modules/assets/index.ts +0 -782
  97. package/src/modules/assets/reducer.test.ts +0 -91
  98. package/src/modules/assets/tagsAndListenerEpics.test.ts +0 -206
  99. package/src/modules/debug/index.ts +0 -28
  100. package/src/modules/dialog/actions.ts +0 -10
  101. package/src/modules/dialog/epics.test.ts +0 -168
  102. package/src/modules/dialog/index.ts +0 -238
  103. package/src/modules/dialog/reducer.test.ts +0 -185
  104. package/src/modules/index.ts +0 -117
  105. package/src/modules/notifications/epics.test.ts +0 -374
  106. package/src/modules/notifications/index.ts +0 -199
  107. package/src/modules/notifications/reducer.test.ts +0 -54
  108. package/src/modules/search/index.test.ts +0 -36
  109. package/src/modules/search/index.ts +0 -167
  110. package/src/modules/selected/index.ts +0 -22
  111. package/src/modules/selectors.test.ts +0 -21
  112. package/src/modules/selectors.ts +0 -17
  113. package/src/modules/tags/epics.test.ts +0 -96
  114. package/src/modules/tags/index.test.ts +0 -42
  115. package/src/modules/tags/index.ts +0 -540
  116. package/src/modules/types.ts +0 -3
  117. package/src/modules/uploads/actions.ts +0 -13
  118. package/src/modules/uploads/epics.test.ts +0 -109
  119. package/src/modules/uploads/index.test.ts +0 -59
  120. package/src/modules/uploads/index.ts +0 -272
  121. package/src/operators/checkTagName.test.ts +0 -29
  122. package/src/operators/checkTagName.ts +0 -33
  123. package/src/operators/debugThrottle.ts +0 -25
  124. package/src/plugin.tsx +0 -54
  125. package/src/schemas/tag.ts +0 -28
  126. package/src/styled/GlobalStyles/index.tsx +0 -40
  127. package/src/styled/react-select/creatable.tsx +0 -184
  128. package/src/styled/react-select/single.tsx +0 -184
  129. package/src/types/index.ts +0 -346
  130. package/src/types/sanity-ui.d.ts +0 -5
  131. package/src/utils/applyMediaTags.ts +0 -87
  132. package/src/utils/blocksToText.test.ts +0 -43
  133. package/src/utils/blocksToText.ts +0 -27
  134. package/src/utils/constructFilter.test.ts +0 -120
  135. package/src/utils/constructFilter.ts +0 -98
  136. package/src/utils/generatePreviewBlobUrl.test.ts +0 -68
  137. package/src/utils/generatePreviewBlobUrl.ts +0 -53
  138. package/src/utils/getAssetResolution.test.ts +0 -13
  139. package/src/utils/getAssetResolution.ts +0 -7
  140. package/src/utils/getDocumentAssetIds.test.ts +0 -50
  141. package/src/utils/getDocumentAssetIds.ts +0 -35
  142. package/src/utils/getSchemeColor.test.ts +0 -12
  143. package/src/utils/getSchemeColor.ts +0 -43
  144. package/src/utils/getTagSelectOptions.test.ts +0 -44
  145. package/src/utils/getTagSelectOptions.ts +0 -16
  146. package/src/utils/getUniqueDocuments.test.ts +0 -26
  147. package/src/utils/getUniqueDocuments.ts +0 -15
  148. package/src/utils/imageDprUrl.test.ts +0 -46
  149. package/src/utils/imageDprUrl.ts +0 -27
  150. package/src/utils/isSupportedAssetType.test.ts +0 -16
  151. package/src/utils/isSupportedAssetType.ts +0 -15
  152. package/src/utils/mediaField.ts +0 -73
  153. package/src/utils/sanitizeFormData.test.ts +0 -59
  154. package/src/utils/sanitizeFormData.ts +0 -26
  155. package/src/utils/typeGuards.test.ts +0 -18
  156. package/src/utils/typeGuards.ts +0 -9
  157. package/src/utils/uploadSanityAsset.test.ts +0 -29
  158. package/src/utils/uploadSanityAsset.ts +0 -97
  159. package/src/utils/withMaxConcurrency.test.ts +0 -43
  160. package/src/utils/withMaxConcurrency.ts +0 -55
  161. package/src/utils/zodFormResolver.ts +0 -17
  162. package/v2-incompatible.js +0 -11
@@ -1,201 +0,0 @@
1
- import type {MutationEvent} from '@sanity/client'
2
- import {Box, Button, Card, Flex, Text} from '@sanity/ui'
3
- import groq from 'groq'
4
- import {type ReactNode, useCallback, useEffect, useState} from 'react'
5
- import {type SubmitHandler, useForm} from 'react-hook-form'
6
- import {useDispatch} from 'react-redux'
7
-
8
- import {tagFormSchema} from '../../formSchema'
9
- import useTypedSelector from '../../hooks/useTypedSelector'
10
- import useVersionedClient from '../../hooks/useVersionedClient'
11
- import {dialogActions} from '../../modules/dialog'
12
- import {selectTagById, tagsActions} from '../../modules/tags'
13
- import type {DialogTagEditProps, Tag, TagFormData} from '../../types'
14
- import sanitizeFormData from '../../utils/sanitizeFormData'
15
- import zodFormResolver from '../../utils/zodFormResolver'
16
- import Dialog from '../Dialog'
17
- import FormFieldInputText from '../FormFieldInputText'
18
- import FormSubmitButton from '../FormSubmitButton'
19
-
20
- type Props = {
21
- children: ReactNode
22
- dialog: DialogTagEditProps
23
- }
24
-
25
- const DialogTagEdit = (props: Props) => {
26
- const {
27
- children,
28
- dialog: {id, tagId},
29
- } = props
30
-
31
- const client = useVersionedClient()
32
-
33
- const dispatch = useDispatch()
34
- const tagItem = useTypedSelector((state) => selectTagById(state, String(tagId))) // TODO: double check string cast
35
-
36
- // - Generate a snapshot of the current tag
37
- const [tagSnapshot, setTagSnapshot] = useState(tagItem?.tag)
38
-
39
- const currentTag = tagItem ? tagItem?.tag : tagSnapshot
40
- const generateDefaultValues = useCallback(
41
- (tag?: Tag) => ({
42
- name: tag?.name?.current || '',
43
- }),
44
- [],
45
- )
46
-
47
- const {
48
- // Read the formState before render to subscribe the form state through Proxy
49
- formState: {errors, isDirty, isValid},
50
- handleSubmit,
51
- register,
52
- reset,
53
- setError,
54
- } = useForm<TagFormData>({
55
- defaultValues: generateDefaultValues(tagItem?.tag),
56
- mode: 'onChange',
57
- resolver: zodFormResolver<TagFormData>(tagFormSchema),
58
- })
59
-
60
- const formUpdating = !tagItem || tagItem?.updating
61
-
62
- const handleClose = () => {
63
- dispatch(dialogActions.remove({id}))
64
- }
65
-
66
- // Submit react-hook-form
67
- const onSubmit: SubmitHandler<TagFormData> = (formData) => {
68
- if (!tagItem?.tag) {
69
- return
70
- }
71
- const sanitizedFormData = sanitizeFormData(formData)
72
- dispatch(
73
- tagsActions.updateRequest({
74
- closeDialogId: tagItem?.tag?._id,
75
- formData: {
76
- name: {
77
- _type: 'slug',
78
- current: sanitizedFormData['name'],
79
- },
80
- },
81
- tag: tagItem?.tag,
82
- }),
83
- )
84
- }
85
-
86
- const handleDelete = () => {
87
- if (!tagItem?.tag) {
88
- return
89
- }
90
-
91
- dispatch(
92
- dialogActions.showConfirmDeleteTag({
93
- closeDialogId: tagItem?.tag?._id,
94
- tag: tagItem?.tag,
95
- }),
96
- )
97
- }
98
-
99
- const handleTagUpdate = useCallback(
100
- (update: MutationEvent) => {
101
- const {result, transition} = update
102
- if (result && transition === 'update') {
103
- // Regenerate snapshot
104
- setTagSnapshot(result as Tag)
105
- // Reset react-hook-form
106
- reset(generateDefaultValues(result as Tag))
107
- }
108
- },
109
- [reset, generateDefaultValues],
110
- )
111
-
112
- useEffect(() => {
113
- if (tagItem?.error) {
114
- setError('name', {
115
- message: tagItem.error?.message,
116
- })
117
- }
118
- }, [setError, tagItem?.error])
119
-
120
- // - Listen for asset mutations and update snapshot
121
- useEffect(() => {
122
- if (!tagItem?.tag) {
123
- return undefined
124
- }
125
-
126
- // Remember that Sanity listeners ignore joins, order clauses and projections
127
- const subscriptionAsset = client
128
- .listen(groq`*[_id == $id]`, {id: tagItem?.tag._id})
129
- .subscribe(handleTagUpdate)
130
-
131
- return () => {
132
- subscriptionAsset?.unsubscribe()
133
- }
134
- }, [client, handleTagUpdate, tagItem?.tag])
135
-
136
- const Footer = () => (
137
- <Box padding={3}>
138
- <Flex justify="space-between">
139
- {/* Delete button */}
140
- <Button
141
- disabled={formUpdating}
142
- fontSize={1}
143
- mode="bleed"
144
- onClick={handleDelete}
145
- text="Delete"
146
- tone="critical"
147
- />
148
-
149
- {/* Submit button */}
150
- <FormSubmitButton
151
- disabled={formUpdating || !isDirty || !isValid}
152
- isValid={isValid}
153
- lastUpdated={tagItem?.tag?._updatedAt}
154
- onClick={handleSubmit(onSubmit)}
155
- />
156
- </Flex>
157
- </Box>
158
- )
159
-
160
- if (!currentTag) {
161
- return null
162
- }
163
-
164
- return (
165
- <Dialog
166
- animate
167
- // oxlint-disable-next-line react/react-compiler
168
- footer={<Footer />}
169
- header="Edit Tag"
170
- id={id}
171
- onClose={handleClose}
172
- width={1}
173
- >
174
- {/* Form fields */}
175
- <Box as="form" padding={4} onSubmit={handleSubmit(onSubmit)}>
176
- {/* Deleted notification */}
177
- {!tagItem && (
178
- <Card marginBottom={3} padding={3} radius={2} shadow={1} tone="critical">
179
- <Text size={1}>This tag cannot be found – it may have been deleted.</Text>
180
- </Card>
181
- )}
182
-
183
- {/* Hidden button to enable enter key submissions */}
184
- <button style={{display: 'none'}} tabIndex={-1} type="submit" />
185
-
186
- {/* Title */}
187
- <FormFieldInputText
188
- {...register('name')}
189
- disabled={formUpdating}
190
- error={errors?.name?.message}
191
- label="Name"
192
- name="name"
193
- />
194
- </Box>
195
-
196
- {children}
197
- </Dialog>
198
- )
199
- }
200
-
201
- export default DialogTagEdit
@@ -1,45 +0,0 @@
1
- import {Box} from '@sanity/ui'
2
- import {type ReactNode, useCallback} from 'react'
3
- import {useDispatch} from 'react-redux'
4
-
5
- import {dialogActions} from '../../modules/dialog'
6
- import type {DialogTagsProps} from '../../types'
7
- import Dialog from '../Dialog'
8
- import TagView from '../TagView'
9
-
10
- type Props = {
11
- children: ReactNode
12
- dialog: DialogTagsProps
13
- }
14
-
15
- const DialogTags = (props: Props) => {
16
- const {
17
- children,
18
- dialog: {id},
19
- } = props
20
-
21
- // Redux
22
- const dispatch = useDispatch()
23
-
24
- // Callbacks
25
- const handleClose = useCallback(() => {
26
- dispatch(dialogActions.clear())
27
- }, [dispatch])
28
-
29
- return (
30
- <Dialog animate header="All Tags" id={id} onClose={handleClose} width={1}>
31
- <Box
32
- style={{
33
- height: '100%',
34
- minHeight: '420px', // explicit height required as <TagView> is virtualized
35
- }}
36
- >
37
- <TagView />
38
- </Box>
39
-
40
- {children}
41
- </Dialog>
42
- )
43
- }
44
-
45
- export default DialogTags
@@ -1,76 +0,0 @@
1
- import useTypedSelector from '../../hooks/useTypedSelector'
2
- import type {Dialog} from '../../types'
3
- import DialogAssetEdit from '../DialogAssetEdit'
4
- import DialogConfirm from '../DialogConfirm'
5
- import DialogSearchFacets from '../DialogSearchFacets'
6
- import DialogTagCreate from '../DialogTagCreate'
7
- import DialogTagEdit from '../DialogTagEdit'
8
- import DialogTags from '../DialogTags'
9
-
10
- const Dialogs = () => {
11
- // Redux
12
- const currentDialogs = useTypedSelector((state) => state.dialog.items)
13
-
14
- const renderDialogs = (dialogs: Dialog[], index: number) => {
15
- if (dialogs.length === 0 || index >= dialogs.length) {
16
- return null
17
- }
18
-
19
- const dialog = dialogs[index]!
20
- const childDialogs = renderDialogs(dialogs, index + 1)
21
-
22
- if (dialog.type === 'assetEdit') {
23
- return (
24
- <DialogAssetEdit dialog={dialog} key={index}>
25
- {childDialogs}
26
- </DialogAssetEdit>
27
- )
28
- }
29
-
30
- if (dialog.type === 'confirm') {
31
- return (
32
- <DialogConfirm dialog={dialog} key={index}>
33
- {childDialogs}
34
- </DialogConfirm>
35
- )
36
- }
37
-
38
- if (dialog.type === 'searchFacets') {
39
- return (
40
- <DialogSearchFacets dialog={dialog} key={index}>
41
- {childDialogs}
42
- </DialogSearchFacets>
43
- )
44
- }
45
-
46
- if (dialog.type === 'tagCreate') {
47
- return (
48
- <DialogTagCreate dialog={dialog} key={index}>
49
- {childDialogs}
50
- </DialogTagCreate>
51
- )
52
- }
53
-
54
- if (dialog.type === 'tagEdit') {
55
- return (
56
- <DialogTagEdit dialog={dialog} key={index}>
57
- {childDialogs}
58
- </DialogTagEdit>
59
- )
60
- }
61
-
62
- if (dialog.type === 'tags') {
63
- return (
64
- <DialogTags dialog={dialog} key={index}>
65
- {childDialogs}
66
- </DialogTags>
67
- )
68
- }
69
-
70
- return null
71
- }
72
-
73
- return renderDialogs(currentDialogs, 0)
74
- }
75
-
76
- export default Dialogs
@@ -1,62 +0,0 @@
1
- import type {SanityDocument} from '@sanity/client'
2
- import {Box, Button, Card, Stack, Text} from '@sanity/ui'
3
- import {Preview, type SchemaType, useSchema} from 'sanity'
4
- import {useIntentLink} from 'sanity/router'
5
-
6
- type Props = {
7
- documents: SanityDocument[]
8
- isLoading: boolean
9
- }
10
-
11
- const DocumentList = ({documents, isLoading}: Props) => {
12
- const schema = useSchema()
13
-
14
- if (isLoading) {
15
- return (
16
- <Text muted size={1}>
17
- Loading...
18
- </Text>
19
- )
20
- }
21
-
22
- if (documents.length === 0) {
23
- return (
24
- <Text muted size={1}>
25
- No documents are referencing this asset
26
- </Text>
27
- )
28
- }
29
-
30
- return (
31
- <Card flex={1} marginBottom={2} padding={2} radius={2} shadow={1}>
32
- <Stack space={2}>
33
- {documents?.map((doc) => (
34
- <ReferringDocument doc={doc} key={doc._id} schemaType={schema.get(doc._type)} />
35
- ))}
36
- </Stack>
37
- </Card>
38
- )
39
- }
40
-
41
- const ReferringDocument = (props: {doc: SanityDocument; schemaType?: SchemaType}) => {
42
- const {doc, schemaType} = props
43
-
44
- const {onClick} = useIntentLink({
45
- intent: 'edit',
46
- params: {id: doc._id},
47
- })
48
-
49
- return schemaType ? (
50
- <Button key={doc._id} mode="bleed" onClick={onClick} padding={2} style={{width: '100%'}}>
51
- <Preview layout="default" schemaType={schemaType} value={doc} />
52
- </Button>
53
- ) : (
54
- <Box padding={2}>
55
- <Text size={1}>
56
- A document of the unknown type <em>{doc._type}</em>
57
- </Text>
58
- </Box>
59
- )
60
- }
61
-
62
- export default DocumentList
@@ -1,37 +0,0 @@
1
- import {Flex} from '@sanity/ui'
2
-
3
- import type {Asset} from '../../types'
4
- import FileIcon from '../FileIcon'
5
-
6
- type Props = {
7
- asset: Asset
8
- }
9
-
10
- const FileAssetPreview = (props: Props) => {
11
- const {asset} = props
12
-
13
- if (asset.mimeType.search('audio') === 0) {
14
- return (
15
- <Flex align="center" justify="center" style={{height: '100%'}}>
16
- <audio controls src={asset.url} style={{width: '100%'}} />
17
- </Flex>
18
- )
19
- }
20
-
21
- if (asset.mimeType.search('video') === 0) {
22
- return (
23
- <video
24
- controls
25
- src={asset.url}
26
- style={{
27
- height: '100%',
28
- width: '100%',
29
- }}
30
- />
31
- )
32
- }
33
-
34
- return <FileIcon extension={asset.extension} width="50%" />
35
- }
36
-
37
- export default FileAssetPreview
@@ -1,43 +0,0 @@
1
- import {Box, Flex, type Theme} from '@sanity/ui'
2
- import {type MouseEvent} from 'react'
3
- import {defaultStyles, FileIcon as ReactFileIcon} from 'react-file-icon'
4
- import type {DefaultExtensionType} from 'react-file-icon'
5
- import {styled, css} from 'styled-components'
6
-
7
- type Props = {
8
- extension?: string
9
- onClick?: (e: MouseEvent) => void
10
- width: string
11
- }
12
-
13
- // Force react-file-icon styles
14
- const Container = styled(Box)(({theme}: {theme: Theme}) => {
15
- return css`
16
- text {
17
- font-family: ${theme.sanity.fonts.text.family} !important;
18
- font-size: 8px !important;
19
- font-weight: 500 !important;
20
- }
21
- `
22
- })
23
-
24
- const FileIcon = (props: Props) => {
25
- const {extension, onClick, width} = props
26
-
27
- return (
28
- <Flex align="center" justify="center" onClick={onClick} style={{height: '100%'}}>
29
- <Container style={{width}}>
30
- {extension ? (
31
- <ReactFileIcon
32
- extension={extension}
33
- {...defaultStyles[extension as DefaultExtensionType]}
34
- />
35
- ) : (
36
- <ReactFileIcon />
37
- )}
38
- </Container>
39
- </Flex>
40
- )
41
- }
42
-
43
- export default FileIcon
@@ -1,63 +0,0 @@
1
- import {LayerProvider, studioTheme, ThemeProvider, ToastProvider} from '@sanity/ui'
2
- import {render, screen, waitFor} from '@testing-library/react'
3
- import {of} from 'rxjs'
4
- import {ColorSchemeProvider} from 'sanity'
5
- import {describe, expect, it, vi, beforeEach} from 'vitest'
6
-
7
- import {createListenMock} from '../../__tests__/fixtures/listenMock'
8
- import {createMockSanityClient} from '../../__tests__/fixtures/mockSanityClient'
9
- import {ToolOptionsProvider} from '../../contexts/ToolOptionsContext'
10
- import useVersionedClient from '../../hooks/useVersionedClient'
11
- import FormBuilderTool from './index'
12
-
13
- vi.mock('../../hooks/useVersionedClient', () => ({
14
- default: vi.fn(),
15
- }))
16
-
17
- vi.mock('sanity', async (importOriginal) => {
18
- const mod = await importOriginal<typeof import('sanity')>()
19
- return {
20
- ...mod,
21
- useFormValue: () => ({_id: 'doc-1', _type: 'article'}),
22
- }
23
- })
24
-
25
- describe('FormBuilderTool', () => {
26
- beforeEach(() => {
27
- const fetch = vi.fn().mockReturnValue(of({items: []}))
28
- vi.mocked(useVersionedClient).mockReturnValue(
29
- createMockSanityClient({
30
- listen: createListenMock(),
31
- observable: {fetch},
32
- }),
33
- )
34
- })
35
-
36
- it('renders picker header for image asset type', async () => {
37
- render(
38
- <ColorSchemeProvider scheme="light">
39
- <ThemeProvider theme={studioTheme}>
40
- <ToastProvider>
41
- <LayerProvider>
42
- <ToolOptionsProvider options={{creditLine: {enabled: false}}}>
43
- <FormBuilderTool
44
- {...({
45
- assetType: 'image',
46
- onClose: vi.fn(),
47
- onSelect: vi.fn(),
48
- schemaType: {},
49
- selectedAssets: undefined,
50
- } as any)}
51
- />
52
- </ToolOptionsProvider>
53
- </LayerProvider>
54
- </ToastProvider>
55
- </ThemeProvider>
56
- </ColorSchemeProvider>,
57
- )
58
-
59
- await waitFor(() => {
60
- expect(screen.getByText(/Insert image/i)).toBeInTheDocument()
61
- })
62
- })
63
- })
@@ -1,69 +0,0 @@
1
- import {Box, Portal, PortalProvider, useLayer} from '@sanity/ui'
2
- import {type SyntheticEvent, useEffect, useState} from 'react'
3
- import {type AssetSourceComponentProps, type SanityDocument, useFormValue} from 'sanity'
4
-
5
- import useKeyPress from '../../hooks/useKeyPress'
6
- import Browser from '../Browser'
7
-
8
- const FormBuilderTool = (props: AssetSourceComponentProps) => {
9
- const {onClose} = props
10
-
11
- const portalElement = useRootPortalElement()
12
-
13
- // Get current Sanity document
14
- const currentDocument = useFormValue([]) as SanityDocument
15
-
16
- // Close on escape key press
17
- useKeyPress('escape', onClose)
18
-
19
- // Stop propagation and prevent document mouse events from firing.
20
- // This is a bit of a hack to make this work with `editModal = 'popover'` and prevent Sanity's <Popover /> component from
21
- // prematurely closing, as it attaches events on `document` to detect outside clicks.
22
- const handleStopPropagation = (event: SyntheticEvent) => {
23
- event.nativeEvent.stopImmediatePropagation()
24
- event.stopPropagation()
25
- }
26
-
27
- const {zIndex} = useLayer()
28
-
29
- return (
30
- <PortalProvider element={portalElement}>
31
- <Portal>
32
- <Box
33
- onDragEnter={handleStopPropagation}
34
- onDragLeave={handleStopPropagation}
35
- onDragOver={handleStopPropagation}
36
- onDrop={handleStopPropagation}
37
- onMouseUp={handleStopPropagation}
38
- style={{
39
- bottom: 0,
40
- height: 'auto',
41
- left: 0,
42
- position: 'fixed',
43
- top: 0,
44
- width: '100%',
45
- zIndex,
46
- }}
47
- >
48
- <Browser document={currentDocument} schemaType={props.schemaType} {...props} />
49
- </Box>
50
- </Portal>
51
- </PortalProvider>
52
- )
53
- }
54
-
55
- export default FormBuilderTool
56
-
57
- const useRootPortalElement = () => {
58
- const [container] = useState(() => document.createElement('div'))
59
-
60
- useEffect(() => {
61
- container.classList.add('media-portal')
62
- document.body.appendChild(container)
63
- return () => {
64
- document.body.removeChild(container)
65
- }
66
- }, [container])
67
-
68
- return container
69
- }
@@ -1,66 +0,0 @@
1
- import {ErrorOutlineIcon} from '@sanity/icons'
2
- import {Box, Inline, Text, Tooltip} from '@sanity/ui'
3
- import {styled} from 'styled-components'
4
-
5
- type Props = {
6
- description?: string
7
- error?: string
8
- label: string
9
- name: string
10
- }
11
-
12
- const StyledErrorOutlineIcon = styled(ErrorOutlineIcon)(({theme}) => {
13
- return {
14
- color: theme.sanity.color.spot.red,
15
- }
16
- })
17
-
18
- const FormFieldInputLabel = (props: Props) => {
19
- const {description, error, label, name} = props
20
-
21
- return (
22
- <>
23
- {/* Label */}
24
- <Box marginY={3}>
25
- <Inline space={2}>
26
- <Text as="label" htmlFor={name} size={1} weight="semibold">
27
- {label}
28
- </Text>
29
-
30
- {/* Error icon + tooltip */}
31
- {error && (
32
- <Text size={1}>
33
- <Tooltip
34
- animate
35
- content={
36
- <Box padding={2}>
37
- <Text muted size={1}>
38
- <StyledErrorOutlineIcon style={{marginRight: '0.1em'}} />
39
- {error}
40
- </Text>
41
- </Box>
42
- }
43
- fallbackPlacements={['top', 'left']}
44
- placement="right"
45
- portal
46
- >
47
- <StyledErrorOutlineIcon />
48
- </Tooltip>
49
- </Text>
50
- )}
51
- </Inline>
52
- </Box>
53
-
54
- {/* Description */}
55
- {description && (
56
- <Box marginY={3}>
57
- <Text htmlFor={name} muted size={1}>
58
- {description}
59
- </Text>
60
- </Box>
61
- )}
62
- </>
63
- )
64
- }
65
-
66
- export default FormFieldInputLabel