sanity-plugin-media 4.3.1 → 4.3.2

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 (145) hide show
  1. package/LICENSE +4 -4
  2. package/README.md +12 -12
  3. package/dist/index.d.mts +263 -195
  4. package/dist/index.d.ts +263 -195
  5. package/dist/index.js +83 -203
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +84 -203
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +41 -63
  10. package/src/__tests__/fixtures/createEpicTestStore.ts +5 -4
  11. package/src/__tests__/fixtures/mockSanityClient.ts +8 -8
  12. package/src/__tests__/fixtures/renderWithProviders.tsx +8 -7
  13. package/src/__tests__/fixtures/rootState.ts +4 -4
  14. package/src/components/AssetGridVirtualized/index.tsx +8 -7
  15. package/src/components/AssetMetadata/index.tsx +6 -5
  16. package/src/components/AssetTableVirtualized/index.tsx +7 -6
  17. package/src/components/AutoTagInputWrapper/index.tsx +9 -4
  18. package/src/components/Browser/Browser.test.tsx +9 -8
  19. package/src/components/Browser/index.tsx +2 -1
  20. package/src/components/Browser/useBrowserInit.ts +9 -9
  21. package/src/components/ButtonAssetCopy/index.tsx +1 -0
  22. package/src/components/ButtonViewGroup/index.tsx +4 -3
  23. package/src/components/CardAsset/CardAsset.test.tsx +53 -52
  24. package/src/components/CardAsset/index.tsx +52 -49
  25. package/src/components/CardUpload/index.tsx +7 -6
  26. package/src/components/Controls/index.tsx +7 -6
  27. package/src/components/DebugControls/index.tsx +5 -4
  28. package/src/components/DialogAssetEdit/Details.tsx +3 -2
  29. package/src/components/DialogAssetEdit/DialogAssetEdit.test.tsx +28 -27
  30. package/src/components/DialogAssetEdit/index.tsx +37 -37
  31. package/src/components/DialogConfirm/index.tsx +2 -1
  32. package/src/components/DialogSearchFacets/index.tsx +3 -2
  33. package/src/components/DialogTagCreate/DialogTagCreate.test.tsx +16 -15
  34. package/src/components/DialogTagCreate/index.tsx +11 -10
  35. package/src/components/DialogTagEdit/DialogTagEdit.test.tsx +28 -27
  36. package/src/components/DialogTagEdit/index.tsx +17 -16
  37. package/src/components/DialogTags/index.tsx +4 -3
  38. package/src/components/Dialogs/index.tsx +2 -3
  39. package/src/components/DocumentList/index.tsx +2 -3
  40. package/src/components/FileAssetPreview/index.tsx +2 -2
  41. package/src/components/FormBuilderTool/FormBuilderTool.test.tsx +12 -11
  42. package/src/components/FormBuilderTool/index.tsx +2 -1
  43. package/src/components/FormFieldInputLabel/index.tsx +1 -2
  44. package/src/components/FormFieldInputTags/index.tsx +4 -3
  45. package/src/components/FormSubmitButton/index.tsx +1 -1
  46. package/src/components/Header/index.tsx +3 -3
  47. package/src/components/Image/index.tsx +10 -4
  48. package/src/components/Items/index.tsx +5 -4
  49. package/src/components/Notifications/index.tsx +3 -2
  50. package/src/components/OrderSelect/index.tsx +4 -3
  51. package/src/components/PickedBar/index.tsx +2 -1
  52. package/src/components/Progress/index.tsx +3 -3
  53. package/src/components/ReduxProvider/index.tsx +15 -12
  54. package/src/components/SearchFacet/index.tsx +3 -2
  55. package/src/components/SearchFacetNumber/index.tsx +8 -8
  56. package/src/components/SearchFacetSelect/index.tsx +7 -8
  57. package/src/components/SearchFacetString/index.tsx +1 -1
  58. package/src/components/SearchFacetTags/index.tsx +13 -12
  59. package/src/components/SearchFacets/index.tsx +2 -3
  60. package/src/components/SearchFacetsControl/index.tsx +13 -12
  61. package/src/components/TableHeader/index.tsx +18 -17
  62. package/src/components/TableHeaderItem/index.tsx +4 -4
  63. package/src/components/TableRowAsset/index.tsx +37 -36
  64. package/src/components/TableRowUpload/index.tsx +7 -6
  65. package/src/components/Tag/index.tsx +8 -7
  66. package/src/components/TagView/index.tsx +2 -2
  67. package/src/components/TagViewHeader/index.tsx +5 -4
  68. package/src/components/TagsPanel/index.tsx +3 -3
  69. package/src/components/TagsVirtualized/index.tsx +25 -24
  70. package/src/components/TextInputSearch/index.tsx +3 -2
  71. package/src/components/UploadDropzone/UploadDropzone.test.tsx +8 -7
  72. package/src/components/UploadDropzone/index.tsx +14 -13
  73. package/src/config/orders.ts +6 -6
  74. package/src/config/searchFacets.ts +56 -55
  75. package/src/constants.ts +15 -14
  76. package/src/contexts/AssetSourceDispatchContext.tsx +1 -1
  77. package/src/contexts/ToolOptionsContext.tsx +6 -5
  78. package/src/formSchema/index.test.ts +6 -5
  79. package/src/formSchema/index.ts +5 -5
  80. package/src/hooks/useBreakpointIndex.ts +6 -6
  81. package/src/hooks/useKeyPress.ts +2 -2
  82. package/src/hooks/usePortalPopoverProps.ts +1 -1
  83. package/src/modules/assets/actions.ts +8 -7
  84. package/src/modules/assets/deleteAndUpdateEpics.test.ts +18 -17
  85. package/src/modules/assets/fetchEpic.test.ts +12 -11
  86. package/src/modules/assets/index.ts +134 -133
  87. package/src/modules/assets/reducer.test.ts +9 -8
  88. package/src/modules/assets/tagsAndListenerEpics.test.ts +36 -35
  89. package/src/modules/debug/index.ts +3 -3
  90. package/src/modules/dialog/actions.ts +2 -2
  91. package/src/modules/dialog/epics.test.ts +29 -28
  92. package/src/modules/dialog/index.ts +36 -35
  93. package/src/modules/dialog/reducer.test.ts +31 -30
  94. package/src/modules/index.ts +9 -9
  95. package/src/modules/notifications/epics.test.ts +71 -70
  96. package/src/modules/notifications/index.ts +50 -49
  97. package/src/modules/notifications/reducer.test.ts +8 -7
  98. package/src/modules/search/index.test.ts +2 -1
  99. package/src/modules/search/index.ts +22 -22
  100. package/src/modules/selected/index.ts +2 -2
  101. package/src/modules/selectors.test.ts +4 -3
  102. package/src/modules/selectors.ts +5 -5
  103. package/src/modules/tags/epics.test.ts +16 -15
  104. package/src/modules/tags/index.test.ts +2 -1
  105. package/src/modules/tags/index.ts +82 -81
  106. package/src/modules/uploads/actions.ts +3 -3
  107. package/src/modules/uploads/epics.test.ts +13 -12
  108. package/src/modules/uploads/index.test.ts +8 -7
  109. package/src/modules/uploads/index.ts +48 -47
  110. package/src/operators/checkTagName.test.ts +7 -6
  111. package/src/operators/checkTagName.ts +6 -5
  112. package/src/operators/debugThrottle.ts +4 -4
  113. package/src/plugin.tsx +18 -18
  114. package/src/schemas/tag.ts +7 -7
  115. package/src/styled/react-select/creatable.tsx +40 -39
  116. package/src/styled/react-select/single.tsx +39 -38
  117. package/src/types/index.ts +4 -3
  118. package/src/utils/applyMediaTags.ts +11 -10
  119. package/src/utils/blocksToText.test.ts +5 -4
  120. package/src/utils/blocksToText.ts +2 -2
  121. package/src/utils/constructFilter.test.ts +15 -14
  122. package/src/utils/constructFilter.ts +7 -7
  123. package/src/utils/generatePreviewBlobUrl.test.ts +6 -5
  124. package/src/utils/generatePreviewBlobUrl.ts +2 -2
  125. package/src/utils/getAssetResolution.test.ts +3 -2
  126. package/src/utils/getDocumentAssetIds.test.ts +7 -6
  127. package/src/utils/getDocumentAssetIds.ts +2 -2
  128. package/src/utils/getSchemeColor.test.ts +1 -0
  129. package/src/utils/getSchemeColor.ts +9 -9
  130. package/src/utils/getTagSelectOptions.test.ts +6 -5
  131. package/src/utils/getTagSelectOptions.ts +1 -1
  132. package/src/utils/getUniqueDocuments.test.ts +4 -3
  133. package/src/utils/getUniqueDocuments.ts +2 -2
  134. package/src/utils/imageDprUrl.test.ts +4 -3
  135. package/src/utils/imageDprUrl.ts +1 -1
  136. package/src/utils/isSupportedAssetType.test.ts +1 -0
  137. package/src/utils/mediaField.ts +4 -3
  138. package/src/utils/sanitizeFormData.test.ts +14 -13
  139. package/src/utils/typeGuards.test.ts +2 -1
  140. package/src/utils/uploadSanityAsset.test.ts +5 -4
  141. package/src/utils/uploadSanityAsset.ts +17 -16
  142. package/src/utils/withMaxConcurrency.test.ts +5 -4
  143. package/src/utils/withMaxConcurrency.ts +4 -4
  144. package/src/utils/zodFormResolver.ts +17 -0
  145. package/v2-incompatible.js +2 -2
@@ -4,12 +4,13 @@ import {type ReactNode} from 'react'
4
4
  import {type DropEvent, type DropzoneOptions, useDropzone} from 'react-dropzone'
5
5
  import {useDispatch} from 'react-redux'
6
6
  import {styled} from 'styled-components'
7
+
7
8
  import {useAssetSourceActions} from '../../contexts/AssetSourceDispatchContext'
8
9
  import {DropzoneDispatchProvider} from '../../contexts/DropzoneDispatchContext'
10
+ import {useToolOptions} from '../../contexts/ToolOptionsContext'
9
11
  import useTypedSelector from '../../hooks/useTypedSelector'
10
12
  import {notificationsActions} from '../../modules/notifications'
11
13
  import {uploadsActions} from '../../modules/uploads'
12
- import {useToolOptions} from '../../contexts/ToolOptionsContext'
13
14
 
14
15
  type Props = {
15
16
  children: ReactNode
@@ -65,38 +66,38 @@ const UploadDropzone = (props: Props) => {
65
66
 
66
67
  const {
67
68
  dropzone: {maxSize},
68
- directUploads
69
+ directUploads,
69
70
  } = useToolOptions()
70
71
 
71
72
  const {onSelect} = useAssetSourceActions()
72
73
 
73
74
  // Redux
74
75
  const dispatch = useDispatch()
75
- const assetTypes = useTypedSelector(state => state.assets.assetTypes)
76
+ const assetTypes = useTypedSelector((state) => state.assets.assetTypes)
76
77
 
77
78
  const isImageAssetType = assetTypes.length === 1 && assetTypes[0] === 'image'
78
79
 
79
80
  // Callbacks
80
81
  const handleDrop = async (acceptedFiles: File[]) => {
81
- acceptedFiles.forEach(file =>
82
+ acceptedFiles.forEach((file) =>
82
83
  dispatch(
83
84
  uploadsActions.uploadRequest({
84
85
  file,
85
- forceAsAssetType: assetTypes.length === 1 ? assetTypes[0] : undefined
86
- })
87
- )
86
+ forceAsAssetType: assetTypes.length === 1 ? assetTypes[0] : undefined,
87
+ }),
88
+ ),
88
89
  )
89
90
  }
90
91
 
91
- const handleDropRejected: DropzoneOptions['onDropRejected'] = rejections => {
92
+ const handleDropRejected: DropzoneOptions['onDropRejected'] = (rejections) => {
92
93
  const errorCodes = rejections.flatMap(({errors}) => errors.map(({code}) => code))
93
94
 
94
95
  if (errorCodes.includes('file-too-large')) {
95
96
  dispatch(
96
97
  notificationsActions.add({
97
98
  status: 'error',
98
- title: 'One or more files exceed the maximum upload size.'
99
- })
99
+ title: 'One or more files exceed the maximum upload size.',
100
+ }),
100
101
  )
101
102
  }
102
103
  }
@@ -126,8 +127,8 @@ const UploadDropzone = (props: Props) => {
126
127
  dispatch(
127
128
  notificationsActions.add({
128
129
  status: 'error',
129
- title: `Unable to upload some items (folders and packages aren't supported)`
130
- })
130
+ title: `Unable to upload some items (folders and packages aren't supported)`,
131
+ }),
131
132
  )
132
133
  }
133
134
 
@@ -145,7 +146,7 @@ const UploadDropzone = (props: Props) => {
145
146
  onDrop: handleDrop,
146
147
  maxSize,
147
148
  onDropRejected: handleDropRejected,
148
- disabled: !directUploads
149
+ disabled: !directUploads,
149
150
  })
150
151
 
151
152
  return (
@@ -3,24 +3,24 @@ import type {OrderDirection} from '../types'
3
3
  const ORDER_DICTIONARY: Record<string, {asc: string; desc: string}> = {
4
4
  _createdAt: {
5
5
  asc: 'Last created: Oldest first',
6
- desc: 'Last created: Newest first'
6
+ desc: 'Last created: Newest first',
7
7
  },
8
8
  _updatedAt: {
9
9
  asc: 'Last updated: Oldest first',
10
- desc: 'Last updated: Newest first'
10
+ desc: 'Last updated: Newest first',
11
11
  },
12
12
  mimeType: {
13
13
  asc: 'MIME type: A to Z',
14
- desc: 'MIME type: Z to A'
14
+ desc: 'MIME type: Z to A',
15
15
  },
16
16
  originalFilename: {
17
17
  asc: 'File name: A to Z',
18
- desc: 'File name: Z to A'
18
+ desc: 'File name: Z to A',
19
19
  },
20
20
  size: {
21
21
  asc: 'File size: Smallest first',
22
- desc: 'File size: Largest first'
23
- }
22
+ desc: 'File size: Largest first',
23
+ },
24
24
  }
25
25
 
26
26
  export const getOrderTitle = (field: string, direction: OrderDirection): string => {
@@ -1,10 +1,11 @@
1
+ import groq from 'groq'
2
+
1
3
  import type {
2
4
  SearchFacetDivider,
3
5
  SearchFacetInputProps,
4
6
  SearchFacetName,
5
- SearchFacetOperators
7
+ SearchFacetOperators,
6
8
  } from '../types'
7
- import groq from 'groq'
8
9
 
9
10
  export const divider: SearchFacetDivider = {type: 'divider'}
10
11
 
@@ -17,7 +18,7 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
17
18
  operatorTypes: ['empty', 'notEmpty', null, 'includes', 'doesNotInclude'],
18
19
  title: 'Alt text',
19
20
  type: 'string',
20
- value: ''
21
+ value: '',
21
22
  },
22
23
  creditLine: {
23
24
  assetTypes: ['file', 'image'],
@@ -27,7 +28,7 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
27
28
  operatorTypes: ['empty', 'notEmpty', null, 'includes', 'doesNotInclude'],
28
29
  title: 'Credit',
29
30
  type: 'string',
30
- value: ''
31
+ value: '',
31
32
  },
32
33
  description: {
33
34
  assetTypes: ['file', 'image'],
@@ -37,7 +38,7 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
37
38
  operatorTypes: ['empty', 'notEmpty', null, 'includes', 'doesNotInclude'],
38
39
  title: 'Description',
39
40
  type: 'string',
40
- value: ''
41
+ value: '',
41
42
  },
42
43
  fileName: {
43
44
  assetTypes: ['file', 'image'],
@@ -47,7 +48,7 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
47
48
  operatorTypes: ['includes', 'doesNotInclude'],
48
49
  title: 'File name',
49
50
  type: 'string',
50
- value: ''
51
+ value: '',
51
52
  },
52
53
  height: {
53
54
  assetTypes: ['image'],
@@ -60,11 +61,11 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
60
61
  'lessThan',
61
62
  'lessThanOrEqualTo',
62
63
  null,
63
- 'equalTo'
64
+ 'equalTo',
64
65
  ],
65
66
  title: 'Height',
66
67
  type: 'number',
67
- value: 400
68
+ value: 400,
68
69
  },
69
70
  inCurrentDocument: {
70
71
  assetTypes: ['file', 'image'],
@@ -74,18 +75,18 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
74
75
  {
75
76
  name: 'true',
76
77
  title: 'True',
77
- value: groq`_id in $documentAssetIds`
78
+ value: groq`_id in $documentAssetIds`,
78
79
  },
79
80
  {
80
81
  name: 'false',
81
82
  title: 'False',
82
- value: groq`!(_id in $documentAssetIds)`
83
- }
83
+ value: groq`!(_id in $documentAssetIds)`,
84
+ },
84
85
  ],
85
86
  selectOnly: true,
86
87
  title: 'In use in current document',
87
88
  type: 'select',
88
- value: 'true'
89
+ value: 'true',
89
90
  },
90
91
  inUse: {
91
92
  assetTypes: ['file', 'image'],
@@ -95,17 +96,17 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
95
96
  {
96
97
  name: 'true',
97
98
  title: 'True',
98
- value: groq`count(*[references(^._id)]) > 0`
99
+ value: groq`count(*[references(^._id)]) > 0`,
99
100
  },
100
101
  {
101
102
  name: 'false',
102
103
  title: 'False',
103
- value: groq`count(*[references(^._id)]) == 0`
104
- }
104
+ value: groq`count(*[references(^._id)]) == 0`,
105
+ },
105
106
  ],
106
107
  title: 'In use',
107
108
  type: 'select',
108
- value: 'true'
109
+ value: 'true',
109
110
  },
110
111
  isOpaque: {
111
112
  assetTypes: ['image'],
@@ -116,17 +117,17 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
116
117
  {
117
118
  name: 'true',
118
119
  title: 'True',
119
- value: `false`
120
+ value: `false`,
120
121
  },
121
122
  {
122
123
  name: 'false',
123
124
  title: 'False',
124
- value: `true`
125
- }
125
+ value: `true`,
126
+ },
126
127
  ],
127
128
  title: 'Has transparency',
128
129
  type: 'select',
129
- value: 'true'
130
+ value: 'true',
130
131
  },
131
132
  orientation: {
132
133
  assetTypes: ['image'],
@@ -137,22 +138,22 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
137
138
  {
138
139
  name: 'portrait',
139
140
  title: 'Portrait',
140
- value: 'metadata.dimensions.aspectRatio < 1'
141
+ value: 'metadata.dimensions.aspectRatio < 1',
141
142
  },
142
143
  {
143
144
  name: 'landscape',
144
145
  title: 'Landscape',
145
- value: 'metadata.dimensions.aspectRatio > 1'
146
+ value: 'metadata.dimensions.aspectRatio > 1',
146
147
  },
147
148
  {
148
149
  name: 'square',
149
150
  title: 'Square',
150
- value: 'metadata.dimensions.aspectRatio == 1'
151
- }
151
+ value: 'metadata.dimensions.aspectRatio == 1',
152
+ },
152
153
  ],
153
154
  title: 'Orientation',
154
155
  type: 'select',
155
- value: 'portrait'
156
+ value: 'portrait',
156
157
  },
157
158
  size: {
158
159
  assetTypes: ['file', 'image'],
@@ -162,13 +163,13 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
162
163
  {
163
164
  name: 'kb',
164
165
  title: 'KB',
165
- fieldModifier: fieldName => `round(${fieldName} / 1000)`
166
+ fieldModifier: (fieldName) => `round(${fieldName} / 1000)`,
166
167
  },
167
168
  {
168
169
  name: 'mb',
169
170
  title: 'MB',
170
- fieldModifier: fieldName => `round(${fieldName} / 1000000)`
171
- }
171
+ fieldModifier: (fieldName) => `round(${fieldName} / 1000000)`,
172
+ },
172
173
  ],
173
174
  name: 'size',
174
175
  operatorType: 'greaterThan',
@@ -178,11 +179,11 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
178
179
  'lessThan',
179
180
  'lessThanOrEqualTo',
180
181
  null,
181
- 'equalTo'
182
+ 'equalTo',
182
183
  ],
183
184
  title: 'File size',
184
185
  type: 'number',
185
- value: 0
186
+ value: 0,
186
187
  },
187
188
  tag: {
188
189
  assetTypes: ['file', 'image'],
@@ -191,7 +192,7 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
191
192
  operatorType: 'references',
192
193
  operatorTypes: ['references', 'doesNotReference', null, 'empty', 'notEmpty'],
193
194
  title: 'Tags',
194
- type: 'searchable'
195
+ type: 'searchable',
195
196
  },
196
197
  title: {
197
198
  assetTypes: ['file', 'image'],
@@ -201,7 +202,7 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
201
202
  operatorTypes: ['empty', 'notEmpty', null, 'includes', 'doesNotInclude'],
202
203
  title: 'Title',
203
204
  type: 'string',
204
- value: ''
205
+ value: '',
205
206
  },
206
207
  type: {
207
208
  assetTypes: ['file', 'image'],
@@ -212,27 +213,27 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
212
213
  {
213
214
  name: 'image',
214
215
  title: 'Image',
215
- value: 'mimeType match "image*"'
216
+ value: 'mimeType match "image*"',
216
217
  },
217
218
  {
218
219
  name: 'video',
219
220
  title: 'Video',
220
- value: 'mimeType match "video*"'
221
+ value: 'mimeType match "video*"',
221
222
  },
222
223
  {
223
224
  name: 'audio',
224
225
  title: 'Audio',
225
- value: 'mimeType match "audio*"'
226
+ value: 'mimeType match "audio*"',
226
227
  },
227
228
  {
228
229
  name: 'pdf',
229
230
  title: 'PDF',
230
- value: 'mimeType == "application/pdf"'
231
- }
231
+ value: 'mimeType == "application/pdf"',
232
+ },
232
233
  ],
233
234
  title: 'File type',
234
235
  type: 'select',
235
- value: 'image'
236
+ value: 'image',
236
237
  },
237
238
  width: {
238
239
  assetTypes: ['image'],
@@ -245,67 +246,67 @@ export const inputs: Record<SearchFacetName, SearchFacetInputProps> = {
245
246
  'lessThan',
246
247
  'lessThanOrEqualTo',
247
248
  null,
248
- 'equalTo'
249
+ 'equalTo',
249
250
  ],
250
251
  title: 'Width',
251
252
  type: 'number',
252
- value: 400
253
- }
253
+ value: 400,
254
+ },
254
255
  }
255
256
 
256
257
  export const operators: SearchFacetOperators = {
257
258
  doesNotInclude: {
258
259
  fn: (value, field) => (value ? `!(${field} match '*${value}*')` : undefined),
259
- label: 'does not include'
260
+ label: 'does not include',
260
261
  },
261
262
  doesNotReference: {
262
263
  fn: (value, _field) => (value ? `!references('${value}')` : undefined),
263
- label: 'does not include'
264
+ label: 'does not include',
264
265
  },
265
266
  empty: {
266
267
  fn: (_value, field) => `!defined(${field})`,
267
268
  hideInput: true,
268
- label: 'is empty'
269
+ label: 'is empty',
269
270
  },
270
271
  equalTo: {
271
272
  fn: (value, field) => (value ? `${field} == ${value}` : undefined),
272
- label: 'is equal to'
273
+ label: 'is equal to',
273
274
  },
274
275
  greaterThan: {
275
276
  fn: (value, field) => (value ? `${field} > ${value}` : undefined),
276
- label: 'is greater than'
277
+ label: 'is greater than',
277
278
  },
278
279
  greaterThanOrEqualTo: {
279
280
  fn: (value, field) => (value ? `${field} >= ${value}` : undefined),
280
- label: 'is greater than or equal to'
281
+ label: 'is greater than or equal to',
281
282
  },
282
283
  includes: {
283
284
  fn: (value, field) => (value ? `${field} match '*${value}*'` : undefined),
284
- label: 'includes'
285
+ label: 'includes',
285
286
  },
286
287
  is: {
287
288
  fn: (value, _field) => `${value}`,
288
- label: 'is'
289
+ label: 'is',
289
290
  },
290
291
  isNot: {
291
292
  fn: (value, _field) => `!(${value})`,
292
- label: 'is not'
293
+ label: 'is not',
293
294
  },
294
295
  lessThan: {
295
296
  fn: (value, field) => (value ? `${field} < ${value}` : undefined),
296
- label: 'is less than'
297
+ label: 'is less than',
297
298
  },
298
299
  lessThanOrEqualTo: {
299
300
  fn: (value, field) => (value ? `${field} <= ${value}` : undefined),
300
- label: 'is less than or equal to'
301
+ label: 'is less than or equal to',
301
302
  },
302
303
  notEmpty: {
303
304
  fn: (_value, field) => `defined(${field})`,
304
305
  hideInput: true,
305
- label: 'is not empty'
306
+ label: 'is not empty',
306
307
  },
307
308
  references: {
308
309
  fn: (value, _field) => (value ? `references('${value}')` : undefined),
309
- label: 'includes'
310
- }
310
+ label: 'includes',
311
+ },
311
312
  }
package/src/constants.ts CHANGED
@@ -1,15 +1,16 @@
1
1
  import type {AssetSourceComponentProps} from 'sanity'
2
+
3
+ import {divider, inputs} from './config/searchFacets'
2
4
  import type {
3
5
  SearchFacetInputProps,
4
6
  SearchFacetDivider,
5
7
  SearchFacetGroup,
6
- OrderDirection
8
+ OrderDirection,
7
9
  } from './types'
8
- import {divider, inputs} from './config/searchFacets'
9
10
 
10
11
  export const SUPPORTED_ASSET_TYPES = [
11
12
  'file',
12
- 'image'
13
+ 'image',
13
14
  ] as const satisfies AssetSourceComponentProps['assetType'][]
14
15
 
15
16
  // Sort order dropdown options
@@ -17,42 +18,42 @@ export const SUPPORTED_ASSET_TYPES = [
17
18
  export const ORDER_OPTIONS: ({direction: OrderDirection; field: string} | null)[] = [
18
19
  {
19
20
  direction: 'desc',
20
- field: '_createdAt'
21
+ field: '_createdAt',
21
22
  },
22
23
  {
23
24
  direction: 'asc',
24
- field: '_createdAt'
25
+ field: '_createdAt',
25
26
  },
26
27
  // Divider
27
28
  null,
28
29
  {
29
30
  direction: 'desc',
30
- field: '_updatedAt'
31
+ field: '_updatedAt',
31
32
  },
32
33
  {
33
34
  direction: 'asc' as OrderDirection,
34
- field: '_updatedAt'
35
+ field: '_updatedAt',
35
36
  },
36
37
  // Divider
37
38
  null,
38
39
  {
39
40
  direction: 'asc',
40
- field: 'originalFilename'
41
+ field: 'originalFilename',
41
42
  },
42
43
  {
43
44
  direction: 'desc',
44
- field: 'originalFilename'
45
+ field: 'originalFilename',
45
46
  },
46
47
  // Divider
47
48
  null,
48
49
  {
49
50
  direction: 'desc',
50
- field: 'size'
51
+ field: 'size',
51
52
  },
52
53
  {
53
54
  direction: 'asc',
54
- field: 'size'
55
- }
55
+ field: 'size',
56
+ },
56
57
  ]
57
58
 
58
59
  export const FACETS: (SearchFacetDivider | SearchFacetGroup | SearchFacetInputProps)[] = [
@@ -74,12 +75,12 @@ export const FACETS: (SearchFacetDivider | SearchFacetGroup | SearchFacetInputPr
74
75
  divider,
75
76
  inputs.orientation,
76
77
  inputs.width,
77
- inputs.height
78
+ inputs.height,
78
79
  ]
79
80
 
80
81
  export const GRID_TEMPLATE_COLUMNS = {
81
82
  SMALL: '3rem 100px auto 1.5rem',
82
- LARGE: '3rem 100px auto 5.5rem 5.5rem 3.5rem 8.5rem 4.75rem 2rem'
83
+ LARGE: '3rem 100px auto 5.5rem 5.5rem 3.5rem 8.5rem 4.75rem 2rem',
83
84
  }
84
85
  export const PANEL_HEIGHT = 32 // px
85
86
  export const TAG_DOCUMENT_NAME = 'media.tag'
@@ -16,7 +16,7 @@ export const AssetBrowserDispatchProvider = (props: Props) => {
16
16
  const {children, onSelect} = props
17
17
 
18
18
  const contextValue: ContextProps = {
19
- onSelect
19
+ onSelect,
20
20
  }
21
21
 
22
22
  return (
@@ -1,7 +1,8 @@
1
- import type {MediaToolOptions, Locale} from '../types'
2
1
  import {type PropsWithChildren, createContext, useContext, useMemo} from 'react'
3
2
  import type {DropzoneOptions} from 'react-dropzone'
4
3
 
4
+ import type {MediaToolOptions, Locale} from '../types'
5
+
5
6
  type ContextProps = {
6
7
  dropzone: Pick<DropzoneOptions, 'maxSize'>
7
8
  components: MediaToolOptions['components']
@@ -30,15 +31,15 @@ export const ToolOptionsProvider = ({options, children}: PropsWithChildren<Props
30
31
  return {
31
32
  dropzone: {maxSize: options?.maximumUploadSize},
32
33
  components: {
33
- details: options?.components?.details
34
+ details: options?.components?.details,
34
35
  },
35
36
  createTagsOnUpload: options?.createTagsOnUpload ?? true,
36
37
  creditLine: {
37
38
  enabled: options?.creditLine?.enabled || false,
38
- excludeSources: creditLineExcludeSources
39
+ excludeSources: creditLineExcludeSources,
39
40
  },
40
41
  directUploads: options?.directUploads ?? true,
41
- locales: options?.locales
42
+ locales: options?.locales,
42
43
  }
43
44
  }, [
44
45
  options?.creditLine?.enabled,
@@ -47,7 +48,7 @@ export const ToolOptionsProvider = ({options, children}: PropsWithChildren<Props
47
48
  options?.creditLine?.excludeSources,
48
49
  options?.maximumUploadSize,
49
50
  options?.directUploads,
50
- options?.locales
51
+ options?.locales,
51
52
  ])
52
53
 
53
54
  return <ToolOptionsContext.Provider value={value}>{children}</ToolOptionsContext.Provider>
@@ -1,6 +1,7 @@
1
1
  // @vitest-environment node
2
2
 
3
3
  import {describe, expect, it} from 'vitest'
4
+
4
5
  import {assetFormSchema, tagFormSchema, tagOptionSchema} from './index'
5
6
 
6
7
  describe('tagOptionSchema', () => {
@@ -28,7 +29,7 @@ describe('assetFormSchema', () => {
28
29
  description: '',
29
30
  opt: {media: {tags: null}},
30
31
  originalFilename: 'file.png',
31
- title: ''
32
+ title: '',
32
33
  }
33
34
 
34
35
  it('accepts valid asset form payload', () => {
@@ -39,8 +40,8 @@ describe('assetFormSchema', () => {
39
40
  expect(
40
41
  assetFormSchema.safeParse({
41
42
  ...base,
42
- originalFilename: ' '
43
- }).success
43
+ originalFilename: ' ',
44
+ }).success,
44
45
  ).toBe(false)
45
46
  })
46
47
 
@@ -48,8 +49,8 @@ describe('assetFormSchema', () => {
48
49
  expect(
49
50
  assetFormSchema.safeParse({
50
51
  ...base,
51
- opt: {media: {tags: [{label: '', value: 'v'}]}}
52
- }).success
52
+ opt: {media: {tags: [{label: '', value: 'v'}]}},
53
+ }).success,
53
54
  ).toBe(false)
54
55
  })
55
56
  })
@@ -14,7 +14,7 @@ export function localizedStringSchema(locales?: {id: string}[]) {
14
14
 
15
15
  export const tagOptionSchema = z.object({
16
16
  label: z.string().trim().min(1, {message: 'Label cannot be empty'}),
17
- value: z.string().trim().min(1, {message: 'Value cannot be empty'})
17
+ value: z.string().trim().min(1, {message: 'Value cannot be empty'}),
18
18
  })
19
19
 
20
20
  export function getAssetFormSchema(locales?: {id: string}[]) {
@@ -24,16 +24,16 @@ export function getAssetFormSchema(locales?: {id: string}[]) {
24
24
  description: localizedStringSchema(locales),
25
25
  opt: z.object({
26
26
  media: z.object({
27
- tags: z.array(tagOptionSchema).nullable()
28
- })
27
+ tags: z.array(tagOptionSchema).nullable(),
28
+ }),
29
29
  }),
30
30
  originalFilename: z.string().trim().min(1, {message: 'Filename cannot be empty'}),
31
- title: localizedStringSchema(locales)
31
+ title: localizedStringSchema(locales),
32
32
  })
33
33
  }
34
34
 
35
35
  export const assetFormSchema = getAssetFormSchema()
36
36
 
37
37
  export const tagFormSchema = z.object({
38
- name: z.string().min(1, {message: 'Name cannot be empty'})
38
+ name: z.string().min(1, {message: 'Name cannot be empty'}),
39
39
  })
@@ -5,11 +5,11 @@ import {useEffect, useState} from 'react'
5
5
  // - create MediaQueryLists from every breakpoint defined in our sanity studio theme
6
6
  // - for each MQL, listen to change events and return the selected breakpoint index
7
7
  const useBreakpointIndex = (): number => {
8
- const mediaQueryLists = studioTheme?.container?.map(width =>
9
- window.matchMedia(`(max-width: ${width}px)`)
8
+ const mediaQueryLists = studioTheme?.container?.map((width) =>
9
+ window.matchMedia(`(max-width: ${width}px)`),
10
10
  )
11
11
 
12
- const getBreakpointIndex = () => mediaQueryLists.findIndex(mql => mql.matches)
12
+ const getBreakpointIndex = () => mediaQueryLists.findIndex((mql) => mql.matches)
13
13
 
14
14
  const [value, setValue] = useState(getBreakpointIndex())
15
15
 
@@ -19,7 +19,7 @@ const useBreakpointIndex = (): number => {
19
19
  }
20
20
 
21
21
  // NOTE: older versions of Safari use the older `addListener` and `removeListener` methods
22
- mediaQueryLists.forEach(mql => {
22
+ mediaQueryLists.forEach((mql) => {
23
23
  try {
24
24
  mql.addEventListener('change', handleBreakpoint)
25
25
  } catch (err) {
@@ -32,10 +32,10 @@ const useBreakpointIndex = (): number => {
32
32
  })
33
33
  return () => {
34
34
  try {
35
- mediaQueryLists.forEach(mql => mql.removeEventListener('change', handleBreakpoint))
35
+ mediaQueryLists.forEach((mql) => mql.removeEventListener('change', handleBreakpoint))
36
36
  } catch (err) {
37
37
  try {
38
- mediaQueryLists.forEach(mql => mql.removeListener(handleBreakpoint))
38
+ mediaQueryLists.forEach((mql) => mql.removeListener(handleBreakpoint))
39
39
  } catch (_err) {
40
40
  // Do nothing
41
41
  }