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
@@ -1,10 +1,11 @@
1
1
  import {createSelector, createSlice, type PayloadAction} from '@reduxjs/toolkit'
2
2
  import type {ClientError, SanityAssetDocument, SanityImageAssetDocument} from '@sanity/client'
3
- import type {HttpError, MyEpic, SanityUploadProgressEvent, UploadItem} from '../../types'
4
3
  import groq from 'groq'
5
4
  import type {Selector} from 'react-redux'
6
5
  import {empty, merge, of} from 'rxjs'
7
6
  import {catchError, delay, filter, mergeMap, takeUntil, withLatestFrom} from 'rxjs/operators'
7
+
8
+ import type {HttpError, MyEpic, SanityUploadProgressEvent, UploadItem} from '../../types'
8
9
  import constructFilter from '../../utils/constructFilter'
9
10
  import {generatePreviewBlobUrl$} from '../../utils/generatePreviewBlobUrl'
10
11
  import {hashFile$, uploadAsset$} from '../../utils/uploadSanityAsset'
@@ -19,13 +20,13 @@ export type UploadsReducerState = {
19
20
 
20
21
  const initialState = {
21
22
  allIds: [],
22
- byIds: {}
23
+ byIds: {},
23
24
  } as UploadsReducerState
24
25
 
25
26
  const uploadsSlice = createSlice({
26
27
  name: 'uploads',
27
28
  initialState,
28
- extraReducers: builder => {
29
+ extraReducers: (builder) => {
29
30
  builder //
30
31
  .addCase(UPLOADS_ACTIONS.uploadComplete, (state, action) => {
31
32
  const {asset} = action.payload
@@ -37,7 +38,7 @@ const uploadsSlice = createSlice({
37
38
  reducers: {
38
39
  checkRequest(
39
40
  _state,
40
- _action: PayloadAction<{assets: (SanityAssetDocument | SanityImageAssetDocument)[]}>
41
+ _action: PayloadAction<{assets: (SanityAssetDocument | SanityImageAssetDocument)[]}>,
41
42
  ) {
42
43
  //
43
44
  },
@@ -46,7 +47,7 @@ const uploadsSlice = createSlice({
46
47
 
47
48
  const assetHashes = Object.keys(results)
48
49
 
49
- assetHashes.forEach(hash => {
50
+ assetHashes.forEach((hash) => {
50
51
  const deleteIndex = state.allIds.indexOf(hash)
51
52
  if (deleteIndex >= 0) {
52
53
  state.allIds.splice(deleteIndex, 1)
@@ -88,13 +89,13 @@ const uploadsSlice = createSlice({
88
89
  },
89
90
  uploadRequest(
90
91
  _state,
91
- _action: PayloadAction<{file: File; forceAsAssetType?: 'file' | 'image'}>
92
+ _action: PayloadAction<{file: File; forceAsAssetType?: 'file' | 'image'}>,
92
93
  ) {
93
94
  //
94
95
  },
95
96
  uploadProgress(
96
97
  state,
97
- action: PayloadAction<{event: SanityUploadProgressEvent; uploadHash: string}>
98
+ action: PayloadAction<{event: SanityUploadProgressEvent; uploadHash: string}>,
98
99
  ) {
99
100
  const {event, uploadHash} = action.payload
100
101
  state.byIds[uploadHash].percent = event.percent
@@ -106,8 +107,8 @@ const uploadsSlice = createSlice({
106
107
  state.allIds.push(uploadItem.hash)
107
108
  }
108
109
  state.byIds[uploadItem.hash] = uploadItem
109
- }
110
- }
110
+ },
111
+ },
111
112
  })
112
113
 
113
114
  // Epics
@@ -115,21 +116,21 @@ const uploadsSlice = createSlice({
115
116
  export const uploadsAssetStartEpic: MyEpic = (action$, _state$, {client}) =>
116
117
  action$.pipe(
117
118
  filter(uploadsActions.uploadStart.match),
118
- mergeMap(action => {
119
+ mergeMap((action) => {
119
120
  const {file, uploadItem} = action.payload
120
121
 
121
122
  return merge(
122
123
  // Generate low res preview
123
124
  of(null).pipe(
124
125
  mergeMap(() => generatePreviewBlobUrl$(file)),
125
- mergeMap(url => {
126
+ mergeMap((url) => {
126
127
  return of(
127
128
  uploadsActions.previewReady({
128
129
  blobUrl: url,
129
- hash: uploadItem.hash
130
- })
130
+ hash: uploadItem.hash,
131
+ }),
131
132
  )
132
- })
133
+ }),
133
134
  ),
134
135
  // Upload asset and receive progress / complete events
135
136
  of(null).pipe(
@@ -138,23 +139,23 @@ export const uploadsAssetStartEpic: MyEpic = (action$, _state$, {client}) =>
138
139
  takeUntil(
139
140
  action$.pipe(
140
141
  filter(uploadsActions.uploadCancel.match),
141
- filter(v => v.payload.hash === uploadItem.hash)
142
- )
142
+ filter((v) => v.payload.hash === uploadItem.hash),
143
+ ),
143
144
  ),
144
- mergeMap(event => {
145
+ mergeMap((event) => {
145
146
  if (event?.type === 'complete') {
146
147
  return of(
147
148
  UPLOADS_ACTIONS.uploadComplete({
148
- asset: event.asset
149
- })
149
+ asset: event.asset,
150
+ }),
150
151
  )
151
152
  }
152
153
  if (event?.type === 'progress' && event?.stage === 'upload') {
153
154
  return of(
154
155
  uploadsActions.uploadProgress({
155
156
  event,
156
- uploadHash: uploadItem.hash
157
- })
157
+ uploadHash: uploadItem.hash,
158
+ }),
158
159
  )
159
160
  }
160
161
  return empty()
@@ -164,15 +165,15 @@ export const uploadsAssetStartEpic: MyEpic = (action$, _state$, {client}) =>
164
165
  uploadsActions.uploadError({
165
166
  error: {
166
167
  message: error?.message || 'Internal error',
167
- statusCode: error?.statusCode || 500
168
+ statusCode: error?.statusCode || 500,
168
169
  },
169
- hash: uploadItem.hash
170
- })
171
- )
172
- )
173
- )
170
+ hash: uploadItem.hash,
171
+ }),
172
+ ),
173
+ ),
174
+ ),
174
175
  )
175
- })
176
+ }),
176
177
  )
177
178
 
178
179
  export const uploadsAssetUploadEpic: MyEpic = (action$, state$) =>
@@ -187,12 +188,12 @@ export const uploadsAssetUploadEpic: MyEpic = (action$, state$) =>
187
188
  // This will throw in insecure contexts (non-localhost / https)
188
189
  mergeMap(() => hashFile$(file)),
189
190
  // Ignore if the file exists and is currently being uploaded
190
- filter(hash => {
191
+ filter((hash) => {
191
192
  const exists = !!state.uploads.byIds[hash]
192
193
  return !exists
193
194
  }),
194
195
  // Dispatch start action and begin upload process
195
- mergeMap(hash => {
196
+ mergeMap((hash) => {
196
197
  const assetType = forceAsAssetType || (file.type.indexOf('image') >= 0 ? 'image' : 'file')
197
198
  const uploadItem = {
198
199
  _type: 'upload',
@@ -200,24 +201,24 @@ export const uploadsAssetUploadEpic: MyEpic = (action$, state$) =>
200
201
  hash,
201
202
  name: file.name,
202
203
  size: file.size,
203
- status: 'queued'
204
+ status: 'queued',
204
205
  } as UploadItem
205
206
  return of(uploadsActions.uploadStart({file, uploadItem}))
206
- })
207
+ }),
207
208
  )
208
- })
209
+ }),
209
210
  )
210
211
 
211
- export const uploadsCompleteQueueEpic: MyEpic = action$ =>
212
+ export const uploadsCompleteQueueEpic: MyEpic = (action$) =>
212
213
  action$.pipe(
213
214
  filter(UPLOADS_ACTIONS.uploadComplete.match),
214
- mergeMap(action => {
215
+ mergeMap((action) => {
215
216
  return of(
216
217
  uploadsActions.checkRequest({
217
- assets: [action.payload.asset]
218
- })
218
+ assets: [action.payload.asset],
219
+ }),
219
220
  )
220
- })
221
+ }),
221
222
  )
222
223
 
223
224
  export const uploadsCheckRequestEpic: MyEpic = (action$, state$, {client}) =>
@@ -227,12 +228,12 @@ export const uploadsCheckRequestEpic: MyEpic = (action$, state$, {client}) =>
227
228
  mergeMap(([action, state]) => {
228
229
  const {assets} = action.payload
229
230
 
230
- const documentIds = assets.map(asset => asset._id)
231
+ const documentIds = assets.map((asset) => asset._id)
231
232
 
232
233
  const constructedFilter = constructFilter({
233
234
  assetTypes: state.assets.assetTypes,
234
235
  searchFacets: state.search.facets,
235
- searchQuery: state.search.query
236
+ searchQuery: state.search.query,
236
237
  })
237
238
 
238
239
  const query = groq`
@@ -242,7 +243,7 @@ export const uploadsCheckRequestEpic: MyEpic = (action$, state$, {client}) =>
242
243
  return of(action).pipe(
243
244
  delay(1000), // give Sanity some time to register the recently uploaded asset
244
245
  mergeMap(() => client.observable.fetch<string[]>(query, {documentIds})),
245
- mergeMap(resultHashes => {
246
+ mergeMap((resultHashes) => {
246
247
  const checkedResults = assets.reduce((acc: Record<string, string | null>, asset) => {
247
248
  acc[asset.sha1hash] = resultHashes.includes(asset.sha1hash) ? asset._id : null
248
249
  return acc
@@ -250,11 +251,11 @@ export const uploadsCheckRequestEpic: MyEpic = (action$, state$, {client}) =>
250
251
 
251
252
  return of(
252
253
  uploadsActions.checkComplete({results: checkedResults}), //
253
- assetsActions.insertUploads({results: checkedResults})
254
+ assetsActions.insertUploads({results: checkedResults}),
254
255
  )
255
- })
256
+ }),
256
257
  )
257
- })
258
+ }),
258
259
  )
259
260
 
260
261
  // Selectors
@@ -266,14 +267,14 @@ const selectUploadsAllIds = (state: RootReducerState) => state.uploads.allIds
266
267
  export const selectUploadById = createSelector(
267
268
  [
268
269
  (state: RootReducerState) => state.uploads.byIds,
269
- (_state: RootReducerState, uploadId: string) => uploadId
270
+ (_state: RootReducerState, uploadId: string) => uploadId,
270
271
  ],
271
- (byIds, uploadId) => byIds[uploadId]
272
+ (byIds, uploadId) => byIds[uploadId],
272
273
  )
273
274
 
274
275
  export const selectUploads: Selector<RootReducerState, UploadItem[]> = createSelector(
275
276
  [selectUploadsByIds, selectUploadsAllIds],
276
- (byIds, allIds) => allIds.map(id => byIds[id])
277
+ (byIds, allIds) => allIds.map((id) => byIds[id]),
277
278
  )
278
279
 
279
280
  export const uploadsActions = {...uploadsSlice.actions}
@@ -1,28 +1,29 @@
1
1
  // @vitest-environment node
2
2
 
3
- import {describe, expect, it, vi} from 'vitest'
4
- import {firstValueFrom, of} from 'rxjs'
5
3
  import type {SanityClient} from '@sanity/client'
4
+ import {firstValueFrom, of} from 'rxjs'
5
+ import {describe, expect, it, vi} from 'vitest'
6
+
6
7
  import checkTagName from './checkTagName'
7
8
 
8
9
  describe('checkTagName', () => {
9
10
  it('errors with 409 when a tag with the same slug exists', async () => {
10
11
  const client = {
11
- fetch: vi.fn().mockResolvedValue(1)
12
+ fetch: vi.fn().mockResolvedValue(1),
12
13
  } as unknown as SanityClient
13
14
 
14
15
  await expect(
15
- firstValueFrom(of(null).pipe(checkTagName(client, 'existing')))
16
+ firstValueFrom(of(null).pipe(checkTagName(client, 'existing'))),
16
17
  ).rejects.toMatchObject({statusCode: 409, message: 'Tag already exists'})
17
18
  })
18
19
 
19
20
  it('emits true when name is available', async () => {
20
21
  const client = {
21
- fetch: vi.fn().mockResolvedValue(0)
22
+ fetch: vi.fn().mockResolvedValue(0),
22
23
  } as unknown as SanityClient
23
24
 
24
25
  await expect(firstValueFrom(of(null).pipe(checkTagName(client, 'fresh-name')))).resolves.toBe(
25
- true
26
+ true,
26
27
  )
27
28
  })
28
29
  })
@@ -1,9 +1,10 @@
1
1
  import type {SanityClient} from '@sanity/client'
2
- import type {HttpError} from '../types'
3
2
  import groq from 'groq'
4
3
  import {from, Observable, of, throwError} from 'rxjs'
5
4
  import {mergeMap} from 'rxjs/operators'
5
+
6
6
  import {TAG_DOCUMENT_NAME} from '../constants'
7
+ import type {HttpError} from '../types'
7
8
 
8
9
  const checkTagName = (client: SanityClient, name: string) => {
9
10
  return function <T>(source: Observable<T>): Observable<boolean> {
@@ -11,20 +12,20 @@ const checkTagName = (client: SanityClient, name: string) => {
11
12
  mergeMap(() => {
12
13
  return from(
13
14
  client.fetch(groq`count(*[_type == "${TAG_DOCUMENT_NAME}" && name.current == $name])`, {
14
- name
15
- })
15
+ name,
16
+ }),
16
17
  ) as Observable<number>
17
18
  }),
18
19
  mergeMap((existingTagCount: number) => {
19
20
  if (existingTagCount > 0) {
20
21
  return throwError({
21
22
  message: 'Tag already exists',
22
- statusCode: 409
23
+ statusCode: 409,
23
24
  } as HttpError)
24
25
  }
25
26
 
26
27
  return of(true)
27
- })
28
+ }),
28
29
  )
29
30
  }
30
31
  }
@@ -7,17 +7,17 @@ const debugThrottle = (throttled?: boolean) => {
7
7
  () => !!throttled,
8
8
  source.pipe(
9
9
  delay(3000),
10
- mergeMap(v => {
10
+ mergeMap((v) => {
11
11
  if (Math.random() > 0.5) {
12
12
  return throwError({
13
13
  message: 'Test error',
14
- statusCode: 500
14
+ statusCode: 500,
15
15
  })
16
16
  }
17
17
  return of(v)
18
- })
18
+ }),
19
19
  ),
20
- source
20
+ source,
21
21
  )
22
22
  }
23
23
  }
package/src/plugin.tsx CHANGED
@@ -1,54 +1,54 @@
1
- import {type AssetSource, type Tool as SanityTool, definePlugin} from 'sanity'
2
1
  import {ImageIcon} from '@sanity/icons'
2
+ import {type AssetSource, type Tool as SanityTool, definePlugin} from 'sanity'
3
+
3
4
  import FormBuilderTool from './components/FormBuilderTool'
4
5
  import Tool from './components/Tool'
6
+ import {ToolOptionsProvider} from './contexts/ToolOptionsContext'
5
7
  import mediaTag from './schemas/tag'
6
8
  import type {MediaToolOptions} from './types'
7
- import {ToolOptionsProvider} from './contexts/ToolOptionsContext'
8
9
 
9
10
  const plugin = {
10
11
  icon: ImageIcon,
11
12
  name: 'media',
12
- title: 'Media'
13
+ title: 'Media',
13
14
  }
14
15
 
15
16
  export const mediaAssetSource = {
16
17
  ...plugin,
17
- component: FormBuilderTool
18
+ component: FormBuilderTool,
18
19
  } satisfies AssetSource
19
20
 
20
21
  const tool = {
21
22
  ...plugin,
22
23
  component: Tool,
23
- // @ts-expect-error TS doesn't know about this internal field see https://github.com/sanity-io/sanity/pull/7980
24
- __internalApplicationType: 'sanity/media'
24
+ __internalApplicationType: 'sanity/media',
25
25
  } satisfies SanityTool
26
26
 
27
- export const media = definePlugin<MediaToolOptions | void>(options => ({
27
+ export const media = definePlugin<MediaToolOptions | void>((options) => ({
28
28
  name: 'media',
29
29
  studio: {
30
30
  components: {
31
- layout: props => (
31
+ layout: (props) => (
32
32
  <ToolOptionsProvider options={options}>{props.renderDefault(props)}</ToolOptionsProvider>
33
- )
34
- }
33
+ ),
34
+ },
35
35
  },
36
36
  form: {
37
37
  file: {
38
- assetSources: prev => {
38
+ assetSources: (prev) => {
39
39
  return [...prev, mediaAssetSource]
40
- }
40
+ },
41
41
  },
42
42
  image: {
43
- assetSources: prev => {
43
+ assetSources: (prev) => {
44
44
  return [...prev, mediaAssetSource]
45
- }
46
- }
45
+ },
46
+ },
47
47
  },
48
48
  schema: {
49
- types: [mediaTag]
49
+ types: [mediaTag],
50
50
  },
51
- tools: prev => {
51
+ tools: (prev) => {
52
52
  return [...prev, tool]
53
- }
53
+ },
54
54
  }))
@@ -1,5 +1,5 @@
1
- import {TAG_DOCUMENT_NAME} from '../constants'
2
1
  import TagIcon from '../components/TagIcon'
2
+ import {TAG_DOCUMENT_NAME} from '../constants'
3
3
 
4
4
  export default {
5
5
  title: 'Media Tag',
@@ -10,19 +10,19 @@ export default {
10
10
  {
11
11
  title: 'Name',
12
12
  name: 'name',
13
- type: 'slug'
14
- }
13
+ type: 'slug',
14
+ },
15
15
  ],
16
16
  preview: {
17
17
  select: {
18
- name: 'name'
18
+ name: 'name',
19
19
  },
20
20
  prepare(selection: any) {
21
21
  const {name} = selection
22
22
  return {
23
23
  media: TagIcon,
24
- title: name?.current
24
+ title: name?.current,
25
25
  }
26
- }
27
- }
26
+ },
27
+ },
28
28
  }
@@ -2,6 +2,7 @@ import {AddIcon, ChevronDownIcon, CloseIcon} from '@sanity/icons'
2
2
  import {Box, Card, Flex, rem, studioTheme, Text, type ThemeColorSchemeKey} from '@sanity/ui'
3
3
  import {components, type StylesConfig} from 'react-select'
4
4
  import {Virtuoso} from 'react-virtuoso'
5
+
5
6
  import {getSchemeColor} from '../../utils/getSchemeColor'
6
7
 
7
8
  const {radius: themeRadius, space: themeSpace} = studioTheme
@@ -18,79 +19,79 @@ export const reactSelectStyles = (scheme: ThemeColorSchemeKey): StylesConfig =>
18
19
 
19
20
  return {
20
21
  ...styles,
21
- backgroundColor: 'var(--card-bg-color)',
22
- color: 'inherit',
23
- border: 'none',
24
- borderRadius: themeRadius[1],
22
+ 'backgroundColor': 'var(--card-bg-color)',
23
+ 'color': 'inherit',
24
+ 'border': 'none',
25
+ 'borderRadius': themeRadius[1],
25
26
  boxShadow,
26
- margin: 0,
27
- minHeight: '35px',
28
- outline: 'none',
29
- padding: rem(themeSpace[1]),
30
- transition: 'none',
27
+ 'margin': 0,
28
+ 'minHeight': '35px',
29
+ 'outline': 'none',
30
+ 'padding': rem(themeSpace[1]),
31
+ 'transition': 'none',
31
32
  '&:hover': {
32
- boxShadow: `inset 0 0 0 1px ${getSchemeColor(scheme, 'inputHoveredBorder')}`
33
- }
33
+ boxShadow: `inset 0 0 0 1px ${getSchemeColor(scheme, 'inputHoveredBorder')}`,
34
+ },
34
35
  }
35
36
  },
36
37
  indicatorsContainer: (styles, {isDisabled}) => ({
37
38
  ...styles,
38
- opacity: isDisabled ? 0.25 : 1
39
+ opacity: isDisabled ? 0.25 : 1,
39
40
  }),
40
- input: styles => ({
41
+ input: (styles) => ({
41
42
  ...styles,
42
43
  color: 'var(--card-fg-color)',
43
44
  fontFamily: studioTheme.fonts.text.family,
44
- marginLeft: rem(themeSpace[2])
45
+ marginLeft: rem(themeSpace[2]),
45
46
  }),
46
- menuList: styles => ({
47
- ...styles
47
+ menuList: (styles) => ({
48
+ ...styles,
48
49
  }),
49
50
  multiValue: (styles, {isDisabled}) => ({
50
51
  ...styles,
51
52
  backgroundColor: getSchemeColor(scheme, 'mutedHoveredBg'),
52
53
  borderRadius: themeRadius[2],
53
- opacity: isDisabled ? 0.5 : 1
54
+ opacity: isDisabled ? 0.5 : 1,
54
55
  }),
55
56
  multiValueLabel: () => ({
56
57
  color: getSchemeColor(scheme, 'mutedHoveredFg'),
57
58
  fontSize: 'inherit',
58
- padding: 0
59
+ padding: 0,
59
60
  }),
60
- multiValueRemove: styles => ({
61
+ multiValueRemove: (styles) => ({
61
62
  ...styles,
62
- borderTopLeftRadius: 0,
63
- borderBottomLeftRadius: 0,
64
- svg: {color: getSchemeColor(scheme, 'mutedHoveredFg')},
63
+ 'borderTopLeftRadius': 0,
64
+ 'borderBottomLeftRadius': 0,
65
+ 'svg': {color: getSchemeColor(scheme, 'mutedHoveredFg')},
65
66
  '&:hover': {
66
- backgroundColor: getSchemeColor(scheme, 'mutedSelectedBg')
67
- }
67
+ backgroundColor: getSchemeColor(scheme, 'mutedSelectedBg'),
68
+ },
68
69
  }),
69
- noOptionsMessage: styles => ({
70
+ noOptionsMessage: (styles) => ({
70
71
  ...styles,
71
72
  fontFamily: studioTheme.fonts.text.family,
72
- lineHeight: '1em'
73
+ lineHeight: '1em',
73
74
  }),
74
75
  option: (styles, {isFocused}) => ({
75
76
  ...styles,
76
- backgroundColor: isFocused ? getSchemeColor(scheme, 'spotBlue') : 'transparent',
77
- borderRadius: themeRadius[2],
78
- color: isFocused ? getSchemeColor(scheme, 'bg') : 'inherit',
79
- padding: `${rem(themeSpace[1])} ${rem(themeSpace[2])}`,
77
+ 'backgroundColor': isFocused ? getSchemeColor(scheme, 'spotBlue') : 'transparent',
78
+ 'borderRadius': themeRadius[2],
79
+ 'color': isFocused ? getSchemeColor(scheme, 'bg') : 'inherit',
80
+ 'padding': `${rem(themeSpace[1])} ${rem(themeSpace[2])}`,
80
81
  '&:hover': {
81
82
  backgroundColor: getSchemeColor(scheme, 'spotBlue'),
82
- color: getSchemeColor(scheme, 'bg')
83
- }
83
+ color: getSchemeColor(scheme, 'bg'),
84
+ },
84
85
  }),
85
- placeholder: styles => ({
86
+ placeholder: (styles) => ({
86
87
  ...styles,
87
- marginLeft: rem(themeSpace[2])
88
+ marginLeft: rem(themeSpace[2]),
88
89
  }),
89
- valueContainer: styles => ({
90
+ valueContainer: (styles) => ({
90
91
  ...styles,
91
92
  margin: 0,
92
- padding: 0
93
- })
93
+ padding: 0,
94
+ }),
94
95
  }
95
96
  }
96
97
 
@@ -129,7 +130,7 @@ const MenuList = (props: any) => {
129
130
  return (
130
131
  <Virtuoso
131
132
  className="media__custom-scrollbar"
132
- itemContent={index => {
133
+ itemContent={(index) => {
133
134
  const item = children[index]
134
135
  return <Option {...item.props} />
135
136
  }}
@@ -179,5 +180,5 @@ export const reactSelectComponents = {
179
180
  MenuList,
180
181
  MultiValueLabel,
181
182
  MultiValueRemove,
182
- Option
183
+ Option,
183
184
  }