sanity-plugin-media 4.3.1 → 4.3.3

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 (147) hide show
  1. package/LICENSE +4 -4
  2. package/README.md +12 -12
  3. package/dist/{index.mjs → index.cjs} +1115 -1242
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +462 -0
  6. package/dist/index.d.ts +263 -195
  7. package/dist/index.js +1125 -1237
  8. package/dist/index.js.map +1 -1
  9. package/package.json +45 -68
  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
  146. package/dist/index.d.mts +0 -394
  147. package/dist/index.mjs.map +0 -1
@@ -1,11 +1,12 @@
1
- import type {RefObject} from 'react'
2
- import userEvent from '@testing-library/user-event'
3
1
  import {screen} from '@testing-library/react'
2
+ import userEvent from '@testing-library/user-event'
3
+ import type {RefObject} from 'react'
4
4
  import {beforeEach, describe, expect, it, vi} from 'vitest'
5
- import CardAsset from './index'
5
+
6
6
  import {renderWithProviders} from '../../__tests__/fixtures/renderWithProviders'
7
7
  import {initialState as assetsInitialState} from '../../modules/assets'
8
8
  import type {AssetItem, AssetType, FileAsset, ImageAsset} from '../../types'
9
+ import CardAsset from './index'
9
10
 
10
11
  const SHIFT_FLAG = '__CARD_ASSET_TEST_SHIFT__'
11
12
 
@@ -23,25 +24,25 @@ vi.mock('../../hooks/useKeyPress', () => ({
23
24
  ({
24
25
  get current() {
25
26
  return Boolean((globalThis as unknown as Record<string, unknown>)[SHIFT_FLAG])
26
- }
27
- } as RefObject<boolean>)
27
+ },
28
+ }) as RefObject<boolean>,
28
29
  }))
29
30
 
30
31
  vi.mock('../Image', () => ({
31
- default: () => <div data-testid="card-image" />
32
+ default: () => <div data-testid="card-image" />,
32
33
  }))
33
34
 
34
35
  vi.mock('../FileIcon', () => ({
35
36
  default: ({extension}: {extension?: string}) => (
36
37
  <div data-testid="card-file-icon" data-extension={extension ?? ''} />
37
- )
38
+ ),
38
39
  }))
39
40
 
40
- vi.mock('sanity', async importOriginal => {
41
+ vi.mock('sanity', async (importOriginal) => {
41
42
  const actual = await importOriginal<typeof import('sanity')>()
42
43
  return {
43
44
  ...actual,
44
- useColorSchemeValue: () => 'light'
45
+ useColorSchemeValue: () => 'light',
45
46
  }
46
47
  })
47
48
 
@@ -55,7 +56,7 @@ const imageAsset = {
55
56
  size: 1,
56
57
  mimeType: 'image/png',
57
58
  url: 'https://example.com/photo.png',
58
- metadata: {dimensions: {width: 100, height: 100}, isOpaque: true}
59
+ metadata: {dimensions: {width: 100, height: 100}, isOpaque: true},
59
60
  } as ImageAsset
60
61
 
61
62
  const fileAsset = {
@@ -68,7 +69,7 @@ const fileAsset = {
68
69
  extension: 'pdf',
69
70
  size: 1,
70
71
  mimeType: 'application/pdf',
71
- url: 'https://example.com/doc.pdf'
72
+ url: 'https://example.com/doc.pdf',
72
73
  } as FileAsset
73
74
 
74
75
  function assetItem(asset: ImageAsset | FileAsset, partial?: Partial<AssetItem>): AssetItem {
@@ -77,7 +78,7 @@ function assetItem(asset: ImageAsset | FileAsset, partial?: Partial<AssetItem>):
77
78
  asset,
78
79
  picked: false,
79
80
  updating: false,
80
- ...partial
81
+ ...partial,
81
82
  }
82
83
  }
83
84
 
@@ -87,7 +88,7 @@ function assetsState(byIds: Record<string, AssetItem>, extra?: Partial<typeof as
87
88
  assetTypes: ['file', 'image'] as AssetType[],
88
89
  allIds: Object.keys(byIds),
89
90
  byIds,
90
- ...extra
91
+ ...extra,
91
92
  }
92
93
  }
93
94
 
@@ -121,8 +122,8 @@ describe('CardAsset', () => {
121
122
  it('renders nothing when the asset id is not in the store', () => {
122
123
  renderWithProviders(<CardAsset id="missing" selected={false} />, {
123
124
  preloaded: {
124
- assets: assetsState({})
125
- }
125
+ assets: assetsState({}),
126
+ },
126
127
  })
127
128
  expect(screen.queryAllByTestId('card-image')).toHaveLength(0)
128
129
  expect(screen.queryAllByTestId('card-file-icon')).toHaveLength(0)
@@ -131,8 +132,8 @@ describe('CardAsset', () => {
131
132
  it('renders image preview and original filename for an image asset', () => {
132
133
  renderWithProviders(<CardAsset id="img-1" selected={false} />, {
133
134
  preloaded: {
134
- assets: assetsState({'img-1': assetItem(imageAsset)})
135
- }
135
+ assets: assetsState({'img-1': assetItem(imageAsset)}),
136
+ },
136
137
  })
137
138
  expect(screen.getAllByTestId('card-image').length).toBeGreaterThan(0)
138
139
  expect(screen.getAllByText('photo.png').length).toBeGreaterThan(0)
@@ -141,8 +142,8 @@ describe('CardAsset', () => {
141
142
  it('renders file icon with extension for a file asset', () => {
142
143
  renderWithProviders(<CardAsset id="file-1" selected={false} />, {
143
144
  preloaded: {
144
- assets: assetsState({'file-1': assetItem(fileAsset)})
145
- }
145
+ assets: assetsState({'file-1': assetItem(fileAsset)}),
146
+ },
146
147
  })
147
148
  const icon = screen.getAllByTestId('card-file-icon').at(-1)!
148
149
  expect(icon).toHaveAttribute('data-extension', 'pdf')
@@ -153,14 +154,14 @@ describe('CardAsset', () => {
153
154
  const user = userEvent.setup()
154
155
  const {store} = renderWithProviders(<CardAsset id="img-1" selected={false} />, {
155
156
  preloaded: {
156
- assets: assetsState({'img-1': assetItem(imageAsset)})
157
- }
157
+ assets: assetsState({'img-1': assetItem(imageAsset)}),
158
+ },
158
159
  })
159
160
 
160
161
  await user.click(clickPreview())
161
162
 
162
163
  expect(
163
- store.getState().dialog.items.some(d => d.type === 'assetEdit' && d.assetId === 'img-1')
164
+ store.getState().dialog.items.some((d) => d.type === 'assetEdit' && d.assetId === 'img-1'),
164
165
  ).toBe(true)
165
166
  })
166
167
 
@@ -170,8 +171,8 @@ describe('CardAsset', () => {
170
171
  renderWithProviders(<CardAsset id="img-1" selected={false} />, {
171
172
  onSelect,
172
173
  preloaded: {
173
- assets: assetsState({'img-1': assetItem(imageAsset)})
174
- }
174
+ assets: assetsState({'img-1': assetItem(imageAsset)}),
175
+ },
175
176
  })
176
177
 
177
178
  await user.click(clickPreview())
@@ -179,8 +180,8 @@ describe('CardAsset', () => {
179
180
  expect(onSelect).toHaveBeenCalledWith([
180
181
  {
181
182
  kind: 'assetDocumentId',
182
- value: 'img-1'
183
- }
183
+ value: 'img-1',
184
+ },
184
185
  ])
185
186
  })
186
187
 
@@ -188,8 +189,8 @@ describe('CardAsset', () => {
188
189
  const user = userEvent.setup()
189
190
  const {store} = renderWithProviders(<CardAsset id="img-1" selected={false} />, {
190
191
  preloaded: {
191
- assets: assetsState({'img-1': assetItem(imageAsset, {picked: false})})
192
- }
192
+ assets: assetsState({'img-1': assetItem(imageAsset, {picked: false})}),
193
+ },
193
194
  })
194
195
 
195
196
  await user.click(clickFooterFilename('photo.png'))
@@ -203,15 +204,15 @@ describe('CardAsset', () => {
203
204
  const {store} = renderWithProviders(<CardAsset id="img-1" selected={false} />, {
204
205
  onSelect,
205
206
  preloaded: {
206
- assets: assetsState({'img-1': assetItem(imageAsset)})
207
- }
207
+ assets: assetsState({'img-1': assetItem(imageAsset)}),
208
+ },
208
209
  })
209
210
 
210
211
  await user.click(clickFooterFilename('photo.png'))
211
212
 
212
213
  expect(onSelect).not.toHaveBeenCalled()
213
214
  expect(
214
- store.getState().dialog.items.some(d => d.type === 'assetEdit' && d.assetId === 'img-1')
215
+ store.getState().dialog.items.some((d) => d.type === 'assetEdit' && d.assetId === 'img-1'),
215
216
  ).toBe(true)
216
217
  })
217
218
 
@@ -219,8 +220,8 @@ describe('CardAsset', () => {
219
220
  const user = userEvent.setup()
220
221
  const {store} = renderWithProviders(<CardAsset id="img-1" selected={false} />, {
221
222
  preloaded: {
222
- assets: assetsState({'img-1': assetItem(imageAsset, {picked: true})})
223
- }
223
+ assets: assetsState({'img-1': assetItem(imageAsset, {picked: true})}),
224
+ },
224
225
  })
225
226
 
226
227
  setShiftPressed(true)
@@ -238,11 +239,11 @@ describe('CardAsset', () => {
238
239
  assets: assetsState(
239
240
  {
240
241
  'prev-1': assetItem(prevAsset),
241
- 'img-1': assetItem(imageAsset, {picked: false})
242
+ 'img-1': assetItem(imageAsset, {picked: false}),
242
243
  },
243
- {lastPicked: 'prev-1'}
244
- )
245
- }
244
+ {lastPicked: 'prev-1'},
245
+ ),
246
+ },
246
247
  })
247
248
 
248
249
  setShiftPressed(true)
@@ -258,18 +259,18 @@ describe('CardAsset', () => {
258
259
  const anchorAsset = {
259
260
  ...imageAsset,
260
261
  _id: 'anchor-9',
261
- originalFilename: 'anchor.png'
262
+ originalFilename: 'anchor.png',
262
263
  } as ImageAsset
263
264
  const {store} = renderWithProviders(<CardAsset id="img-1" selected={false} />, {
264
265
  preloaded: {
265
266
  assets: assetsState(
266
267
  {
267
268
  'anchor-9': assetItem(anchorAsset),
268
- 'img-1': assetItem(imageAsset, {picked: false})
269
+ 'img-1': assetItem(imageAsset, {picked: false}),
269
270
  },
270
- {lastPicked: 'anchor-9'}
271
- )
272
- }
271
+ {lastPicked: 'anchor-9'},
272
+ ),
273
+ },
273
274
  })
274
275
 
275
276
  setShiftPressed(true)
@@ -283,19 +284,19 @@ describe('CardAsset', () => {
283
284
  it('shows the selection checkmark when selected and not updating', () => {
284
285
  const {container} = renderWithProviders(<CardAsset id="img-1" selected />, {
285
286
  preloaded: {
286
- assets: assetsState({'img-1': assetItem(imageAsset, {updating: false})})
287
- }
287
+ assets: assetsState({'img-1': assetItem(imageAsset, {updating: false})}),
288
+ },
288
289
  })
289
290
  expect(
290
- container.querySelectorAll('[data-sanity-icon="checkmark-circle"]').length
291
+ container.querySelectorAll('[data-sanity-icon="checkmark-circle"]').length,
291
292
  ).toBeGreaterThan(0)
292
293
  })
293
294
 
294
295
  it('does not show the checkmark overlay while updating even if selected', () => {
295
296
  const {container} = renderWithProviders(<CardAsset id="img-1" selected />, {
296
297
  preloaded: {
297
- assets: assetsState({'img-1': assetItem(imageAsset, {updating: true})})
298
- }
298
+ assets: assetsState({'img-1': assetItem(imageAsset, {updating: true})}),
299
+ },
299
300
  })
300
301
  expect(container.querySelectorAll('[data-sanity-icon="checkmark-circle"]')).toHaveLength(0)
301
302
  })
@@ -303,8 +304,8 @@ describe('CardAsset', () => {
303
304
  it('shows a spinner while updating', () => {
304
305
  renderWithProviders(<CardAsset id="img-1" selected={false} />, {
305
306
  preloaded: {
306
- assets: assetsState({'img-1': assetItem(imageAsset, {updating: true})})
307
- }
307
+ assets: assetsState({'img-1': assetItem(imageAsset, {updating: true})}),
308
+ },
308
309
  })
309
310
  expect(document.body.querySelectorAll('[data-ui="Spinner"]').length).toBeGreaterThan(0)
310
311
  })
@@ -312,11 +313,11 @@ describe('CardAsset', () => {
312
313
  it('shows a warning icon when the asset item has an error', () => {
313
314
  const {container} = renderWithProviders(<CardAsset id="img-1" selected={false} />, {
314
315
  preloaded: {
315
- assets: assetsState({'img-1': assetItem(imageAsset, {error: 'Upload failed'})})
316
- }
316
+ assets: assetsState({'img-1': assetItem(imageAsset, {error: 'Upload failed'})}),
317
+ },
317
318
  })
318
319
  expect(
319
- container.querySelectorAll('[data-sanity-icon="warning-filled"]').length
320
+ container.querySelectorAll('[data-sanity-icon="warning-filled"]').length,
320
321
  ).toBeGreaterThan(0)
321
322
  })
322
323
  })
@@ -8,23 +8,24 @@ import {
8
8
  Text,
9
9
  type Theme,
10
10
  type ThemeColorSchemeKey,
11
- Tooltip
11
+ Tooltip,
12
12
  } from '@sanity/ui'
13
13
  import {memo, type MouseEvent, type RefObject} from 'react'
14
14
  import {useDispatch} from 'react-redux'
15
15
  import {useColorSchemeValue} from 'sanity'
16
16
  import {styled, css} from 'styled-components'
17
+
17
18
  import {PANEL_HEIGHT} from '../../constants'
18
19
  import {useAssetSourceActions} from '../../contexts/AssetSourceDispatchContext'
19
20
  import useKeyPress from '../../hooks/useKeyPress'
20
21
  import useTypedSelector from '../../hooks/useTypedSelector'
21
22
  import {assetsActions, selectAssetById} from '../../modules/assets'
22
23
  import {dialogActions} from '../../modules/dialog'
24
+ import {getSchemeColor} from '../../utils/getSchemeColor'
23
25
  import imageDprUrl from '../../utils/imageDprUrl'
24
26
  import {isFileAsset, isImageAsset} from '../../utils/typeGuards'
25
27
  import FileIcon from '../FileIcon'
26
28
  import Image from '../Image'
27
- import {getSchemeColor} from '../../utils/getSchemeColor'
28
29
 
29
30
  type Props = {
30
31
  id: string
@@ -39,51 +40,53 @@ const CardWrapper = styled(Flex)`
39
40
  width: 100%;
40
41
  `
41
42
 
42
- const CardContainer = styled(Flex)<{$picked?: boolean; theme: Theme; $updating?: boolean}>(
43
- ({$picked, theme, $updating}) => {
44
- return css`
45
- border: 1px solid transparent;
46
- height: 100%;
47
- pointer-events: ${$updating ? 'none' : 'auto'};
48
- position: relative;
49
- transition: all 300ms;
50
- user-select: none;
51
- width: 100%;
43
+ const CardContainer = styled(Flex)<{$picked?: boolean; theme: Theme; $updating?: boolean}>(({
44
+ $picked,
45
+ theme,
46
+ $updating,
47
+ }) => {
48
+ return css`
49
+ border: 1px solid transparent;
50
+ height: 100%;
51
+ pointer-events: ${$updating ? 'none' : 'auto'};
52
+ position: relative;
53
+ transition: all 300ms;
54
+ user-select: none;
55
+ width: 100%;
52
56
 
53
- border: ${$picked
54
- ? `1px solid ${theme.sanity.color.spot.orange} !important`
55
- : '1px solid inherit'};
57
+ border: ${$picked
58
+ ? `1px solid ${theme.sanity.color.spot.orange} !important`
59
+ : '1px solid inherit'};
56
60
 
57
- ${!$updating &&
58
- css`
59
- @media (hover: hover) and (pointer: fine) {
60
- &:hover {
61
- border: 1px solid var(--card-border-color);
62
- }
63
- }
64
- `}
65
- `
66
- }
67
- )
68
-
69
- const ContextActionContainer = styled<typeof Flex, {$scheme: ThemeColorSchemeKey}>(Flex)(
70
- ({$scheme}) => {
71
- return css`
72
- cursor: pointer;
73
- height: ${PANEL_HEIGHT}px;
74
- transition: all 300ms;
61
+ ${!$updating &&
62
+ css`
75
63
  @media (hover: hover) and (pointer: fine) {
76
64
  &:hover {
77
- background: ${getSchemeColor($scheme, 'bg')};
65
+ border: 1px solid var(--card-border-color);
78
66
  }
79
67
  }
80
- `
81
- }
82
- )
68
+ `}
69
+ `
70
+ })
71
+
72
+ const ContextActionContainer = styled<typeof Flex, {$scheme: ThemeColorSchemeKey}>(Flex)(({
73
+ $scheme,
74
+ }) => {
75
+ return css`
76
+ cursor: pointer;
77
+ height: ${PANEL_HEIGHT}px;
78
+ transition: all 300ms;
79
+ @media (hover: hover) and (pointer: fine) {
80
+ &:hover {
81
+ background: ${getSchemeColor($scheme, 'bg')};
82
+ }
83
+ }
84
+ `
85
+ })
83
86
 
84
87
  const StyledWarningOutlineIcon = styled(WarningFilledIcon)(({theme}) => {
85
88
  return {
86
- color: theme.sanity.color.spot.red
89
+ color: theme.sanity.color.spot.red,
87
90
  }
88
91
  })
89
92
 
@@ -97,8 +100,8 @@ const CardAsset = (props: Props) => {
97
100
 
98
101
  // Redux
99
102
  const dispatch = useDispatch()
100
- const lastPicked = useTypedSelector(state => state.assets.lastPicked)
101
- const item = useTypedSelector(state => selectAssetById(state, id))
103
+ const lastPicked = useTypedSelector((state) => state.assets.lastPicked)
104
+ const item = useTypedSelector((state) => selectAssetById(state, id))
102
105
 
103
106
  const asset = item?.asset
104
107
  const error = item?.error
@@ -121,8 +124,8 @@ const CardAsset = (props: Props) => {
121
124
  onSelect([
122
125
  {
123
126
  kind: 'assetDocumentId',
124
- value: asset._id
125
- }
127
+ value: asset._id,
128
+ },
126
129
  ])
127
130
  } else if (shiftPressed.current) {
128
131
  if (picked) {
@@ -158,7 +161,7 @@ const CardAsset = (props: Props) => {
158
161
  flex={1}
159
162
  style={{
160
163
  cursor: selected ? 'default' : 'pointer',
161
- position: 'relative'
164
+ position: 'relative',
162
165
  }}
163
166
  >
164
167
  <div onClick={handleAssetClick} style={{height: '100%', opacity: opacityPreview}}>
@@ -174,7 +177,7 @@ const CardAsset = (props: Props) => {
174
177
  src={imageDprUrl(asset, {height: 250, width: 250})}
175
178
  style={{
176
179
  draggable: false,
177
- transition: 'opacity 1000ms'
180
+ transition: 'opacity 1000ms',
178
181
  }}
179
182
  />
180
183
  )}
@@ -191,7 +194,7 @@ const CardAsset = (props: Props) => {
191
194
  opacity: opacityContainer,
192
195
  position: 'absolute',
193
196
  top: 0,
194
- width: '100%'
197
+ width: '100%',
195
198
  }}
196
199
  >
197
200
  <Text size={2}>
@@ -210,7 +213,7 @@ const CardAsset = (props: Props) => {
210
213
  left: 0,
211
214
  position: 'absolute',
212
215
  top: 0,
213
- width: '100%'
216
+ width: '100%',
214
217
  }}
215
218
  >
216
219
  <Spinner />
@@ -230,7 +233,7 @@ const CardAsset = (props: Props) => {
230
233
  <EditIcon
231
234
  style={{
232
235
  flexShrink: 0,
233
- opacity: 0.5
236
+ opacity: 0.5,
234
237
  }}
235
238
  />
236
239
  ) : (
@@ -240,7 +243,7 @@ const CardAsset = (props: Props) => {
240
243
  style={{
241
244
  flexShrink: 0,
242
245
  pointerEvents: 'none',
243
- transform: 'scale(0.8)'
246
+ transform: 'scale(0.8)',
244
247
  }}
245
248
  />
246
249
  )}
@@ -260,7 +263,7 @@ const CardAsset = (props: Props) => {
260
263
  style={{
261
264
  position: 'absolute',
262
265
  right: 0,
263
- top: 0
266
+ top: 0,
264
267
  }}
265
268
  >
266
269
  <Tooltip
@@ -4,12 +4,13 @@ import filesize from 'filesize'
4
4
  import {useDispatch} from 'react-redux'
5
5
  import {useColorSchemeValue} from 'sanity'
6
6
  import {styled} from 'styled-components'
7
+
7
8
  import {PANEL_HEIGHT} from '../../constants'
8
9
  import useTypedSelector from '../../hooks/useTypedSelector'
9
10
  import {selectUploadById, uploadsActions} from '../../modules/uploads'
11
+ import {getSchemeColor} from '../../utils/getSchemeColor'
10
12
  import FileIcon from '../FileIcon'
11
13
  import Image from '../Image'
12
- import {getSchemeColor} from '../../utils/getSchemeColor'
13
14
 
14
15
  type Props = {
15
16
  id: string
@@ -30,7 +31,7 @@ const CardUpload = (props: Props) => {
30
31
 
31
32
  // Redux
32
33
  const dispatch = useDispatch()
33
- const item = useTypedSelector(state => selectUploadById(state, id))
34
+ const item = useTypedSelector((state) => selectUploadById(state, id))
34
35
 
35
36
  if (!item) {
36
37
  return null
@@ -68,7 +69,7 @@ const CardUpload = (props: Props) => {
68
69
  background: getSchemeColor(scheme, 'bg'),
69
70
  border: '1px solid transparent',
70
71
  height: '100%',
71
- position: 'relative'
72
+ position: 'relative',
72
73
  }}
73
74
  >
74
75
  {/* Progress bar */}
@@ -82,7 +83,7 @@ const CardUpload = (props: Props) => {
82
83
  width: '100%',
83
84
  transform: `scaleX(${percentLoaded * 0.01})`,
84
85
  transformOrigin: 'bottom left',
85
- transition: 'all 1000ms ease-out'
86
+ transition: 'all 1000ms ease-out',
86
87
  }}
87
88
  />
88
89
 
@@ -93,7 +94,7 @@ const CardUpload = (props: Props) => {
93
94
  $scheme={scheme}
94
95
  src={item.objectUrl}
95
96
  style={{
96
- opacity: 0.4
97
+ opacity: 0.4,
97
98
  }}
98
99
  />
99
100
  )}
@@ -120,7 +121,7 @@ const CardUpload = (props: Props) => {
120
121
  left: 0,
121
122
  position: 'absolute',
122
123
  top: 0,
123
- width: '100%'
124
+ width: '100%',
124
125
  }}
125
126
  >
126
127
  <Button
@@ -1,5 +1,6 @@
1
1
  import {Box, Button, Flex, Inline, useMediaIndex} from '@sanity/ui'
2
2
  import {useDispatch} from 'react-redux'
3
+
3
4
  import useTypedSelector from '../../hooks/useTypedSelector'
4
5
  import {dialogActions} from '../../modules/dialog'
5
6
  import {tagsActions} from '../../modules/tags'
@@ -14,10 +15,10 @@ import TextInputSearch from '../TextInputSearch'
14
15
  const Controls = () => {
15
16
  // Redux
16
17
  const dispatch = useDispatch()
17
- const fetching = useTypedSelector(state => state.assets.fetching)
18
- const pageIndex = useTypedSelector(state => state.assets.pageIndex)
19
- const searchFacets = useTypedSelector(state => state.search.facets)
20
- const tagsPanelVisible = useTypedSelector(state => state.tags.panelVisible)
18
+ const fetching = useTypedSelector((state) => state.assets.fetching)
19
+ const pageIndex = useTypedSelector((state) => state.assets.pageIndex)
20
+ const searchFacets = useTypedSelector((state) => state.search.facets)
21
+ const tagsPanelVisible = useTypedSelector((state) => state.tags.panelVisible)
21
22
 
22
23
  const mediaIndex = useMediaIndex()
23
24
 
@@ -39,7 +40,7 @@ const Controls = () => {
39
40
  paddingY={2}
40
41
  style={{
41
42
  borderBottom: '1px solid var(--card-border-color)',
42
- zIndex: 2
43
+ zIndex: 2,
43
44
  }}
44
45
  >
45
46
  {/* Rows: search / filters / orders */}
@@ -58,7 +59,7 @@ const Controls = () => {
58
59
  height: '100%',
59
60
  justifyContent: mediaIndex < 2 ? 'space-between' : 'flex-start',
60
61
  position: 'relative',
61
- width: '100%'
62
+ width: '100%',
62
63
  }}
63
64
  >
64
65
  <Box marginX={2} style={{minWidth: '200px'}}>
@@ -2,6 +2,7 @@ import {PlugIcon} from '@sanity/icons'
2
2
  import {Box, Flex, Switch, Text, Tooltip} from '@sanity/ui'
3
3
  import {type ChangeEvent} from 'react'
4
4
  import {useDispatch} from 'react-redux'
5
+
5
6
  import useKeyPress from '../../hooks/useKeyPress'
6
7
  import useTypedSelector from '../../hooks/useTypedSelector'
7
8
  import {debugActions} from '../../modules/debug'
@@ -9,8 +10,8 @@ import {debugActions} from '../../modules/debug'
9
10
  const DebugControls = () => {
10
11
  // Redux
11
12
  const dispatch = useDispatch()
12
- const badConnection = useTypedSelector(state => state.debug.badConnection)
13
- const debugEnabled = useTypedSelector(state => state.debug.enabled)
13
+ const badConnection = useTypedSelector((state) => state.debug.badConnection)
14
+ const debugEnabled = useTypedSelector((state) => state.debug.enabled)
14
15
 
15
16
  // Callbacks
16
17
  const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
@@ -38,7 +39,7 @@ const DebugControls = () => {
38
39
  left: 0,
39
40
  pointerEvents: 'none',
40
41
  position: 'fixed',
41
- width: '100%'
42
+ width: '100%',
42
43
  }}
43
44
  >
44
45
  {/* Bad connection toggle */}
@@ -67,7 +68,7 @@ const DebugControls = () => {
67
68
  checked={badConnection}
68
69
  onChange={handleChange}
69
70
  style={{
70
- pointerEvents: 'auto'
71
+ pointerEvents: 'auto',
71
72
  }}
72
73
  />
73
74
  </Tooltip>
@@ -1,6 +1,7 @@
1
1
  import {Card, Stack, Tab, TabList, TabPanel} from '@sanity/ui'
2
2
  import {useState} from 'react'
3
3
  import {type Control, type FieldErrors, type UseFormRegister} from 'react-hook-form'
4
+
4
5
  import type {Asset, AssetFormData, Locale, TagSelectOption} from '../../types'
5
6
  import FormFieldInputTags from '../FormFieldInputTags'
6
7
  import FormFieldInputText from '../FormFieldInputText'
@@ -12,7 +13,7 @@ type LocalizedErrors = Record<string, {message?: string} | undefined>
12
13
  function toStringField(value: unknown): string | undefined {
13
14
  if (typeof value === 'string') return value
14
15
  if (typeof value === 'object' && value !== null) {
15
- const found = Object.values(value as Record<string, string>).find(v => v)
16
+ const found = Object.values(value as Record<string, string>).find((v) => v)
16
17
  return found || undefined
17
18
  }
18
19
  return undefined
@@ -44,7 +45,7 @@ export default function Details({
44
45
  assetTagOptions,
45
46
  currentAsset,
46
47
  creditLine,
47
- locales
48
+ locales,
48
49
  }: DetailsProps) {
49
50
  const hasLocales = locales && locales.length > 0
50
51
  const [activeLocaleTab, setActiveLocaleTab] = useState(0)