@electrolux-oss/sanity-plugin-media 4.0.0 → 4.1.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.
package/README.md CHANGED
@@ -115,7 +115,9 @@ export default defineConfig({
115
115
  // Don't use this plugin when selecting files only (but allow all other enabled asset sources)
116
116
  file: {
117
117
  assetSources: previousAssetSources => {
118
- return previousAssetSources.filter(assetSource => assetSource !== mediaAssetSource)
118
+ return previousAssetSources.filter(
119
+ assetSource => assetSource.name !== mediaAssetSource.name
120
+ )
119
121
  }
120
122
  }
121
123
  }
@@ -147,9 +149,20 @@ export default defineConfig({
147
149
  // wish to prevent users overwriting the creditLine based on the `source.name`
148
150
  },
149
151
  maximumUploadSize: 10000000,
150
- // number - maximum file size (in bytes) that can be uploaded through the plugin interface
152
+ // number - maximum file size (in bytes) for uploads, both through the plugin interface and
153
+ // through the image / file fields' own upload button (any upload-capable asset source)
151
154
  directUploads: true,
152
155
  // boolean - enable / disable direct uploads through the plugin interface (default true)
156
+ createTagsOnUpload: true,
157
+ // boolean - create tags listed in a field's `mediaTags` if they don't exist yet (default true)
158
+ uploadMenu: false,
159
+ // boolean - offer "Media" as an upload target in image / file fields (default true).
160
+ // Set to false to make the upload button use the workspace's own uploader directly;
161
+ // "Media" is then only listed under "Select"
162
+ excludeTags: ['internal', 'archived'],
163
+ // string[] (optional) - tag slugs (`media.tag` `name.current`). Assets with any of these
164
+ // tags are hidden from the Media browser and asset picker, and the tags themselves are
165
+ // hidden in the tag panel and tag search facet. The asset edit dialog still lists all tags.
153
166
  components: {
154
167
  details: CustomDetails
155
168
  }
@@ -158,6 +171,58 @@ export default defineConfig({
158
171
  })
159
172
  ```
160
173
 
174
+ ### Auto-tagging assets from a field
175
+
176
+ Assets selected or uploaded through a field can be tagged automatically. The same tags pre-filter the media browser when it is opened from that field.
177
+
178
+ ```ts
179
+ import { mediaField } from '@electrolux-oss/sanity-plugin-media'
180
+
181
+ defineType({
182
+ name: 'product',
183
+ type: 'document',
184
+ fields: [
185
+ mediaField({
186
+ name: 'image',
187
+ type: 'image',
188
+ mediaTags: ['product']
189
+ })
190
+ ]
191
+ })
192
+ ```
193
+
194
+ Or use the input component directly:
195
+
196
+ ```tsx
197
+ import { AutoTagInput } from '@electrolux-oss/sanity-plugin-media'
198
+
199
+ defineField({
200
+ name: 'image',
201
+ type: 'image',
202
+ options: { mediaTags: ['product'] }, // pre-filters the browser
203
+ components: { input: AutoTagInput } // applies tags on select
204
+ })
205
+
206
+ // Or pass mediaTags as a prop to override the field options:
207
+ defineField({
208
+ name: 'image',
209
+ type: 'image',
210
+ components: {
211
+ input: props => <AutoTagInput {...props} mediaTags={['product']} />
212
+ }
213
+ })
214
+ ```
215
+
216
+ Only assets selected after the document is opened are tagged. Existing values are left untouched. Tags missing from the dataset are created unless `createTagsOnUpload` is `false`.
217
+
218
+ ### Uploaded by
219
+
220
+ The asset details panel shows who uploaded an asset. It is recorded as `opt.media.uploadedBy` (`{ id }`, the Sanity user ID only; the sync button next to it fetches the person's name, and email when Sanity returns it, on demand) when a logged-in user uploads through the Studio: in the Media browser, or with an image / file field's own upload button and drag and drop. Only uploads made in that user's browser are recorded, so collaborators editing the same document are never credited. Assets uploaded by scripts, the CLI, API tokens or before this feature existed show **Unknown**.
221
+
222
+ ### Edit Media
223
+
224
+ The plugin adds an **Edit Media** option to the asset menu of image and file fields. It opens the edit dialog (title, alt texts, description, tags, …) for the field's current asset, without leaving the document.
225
+
161
226
  ## Develop locally
162
227
 
163
228
  ### Test your plugin locally
package/dist/index.d.ts CHANGED
@@ -1,8 +1,12 @@
1
1
  import { AssetSourceComponentProps } from 'sanity'
2
2
  import type { ComponentType } from 'react'
3
3
  import type { Control } from 'react-hook-form'
4
+ import type { FieldDefinitionBase } from 'sanity'
4
5
  import type { FieldErrors } from 'react-hook-form'
6
+ import type { FileDefinition } from 'sanity'
5
7
  import { ForwardRefExoticComponent } from 'react'
8
+ import type { ImageDefinition } from 'sanity'
9
+ import type { InputProps } from 'sanity'
6
10
  import { JSX } from 'react'
7
11
  import { Plugin as Plugin_2 } from 'sanity'
8
12
  import { RefAttributes } from 'react'
@@ -10,6 +14,8 @@ import type { SanityAssetDocument } from '@sanity/client'
10
14
  import type { SanityImageAssetDocument } from '@sanity/client'
11
15
  import { SVGProps } from 'react'
12
16
  import type { UseFormRegister } from 'react-hook-form'
17
+ import type { WidenInitialValue } from 'sanity'
18
+ import type { WidenValidation } from 'sanity'
13
19
  import * as z from 'zod'
14
20
 
15
21
  declare type Asset = FileAsset | ImageAsset
@@ -18,6 +24,19 @@ declare type AssetFormData = z.infer<AssetFormSchemaObject>
18
24
 
19
25
  declare type AssetFormSchemaObject = ReturnType<typeof createAssetFormSchema>
20
26
 
27
+ /**
28
+ * Image / file input that tags the selected or uploaded asset with `mediaTags`.
29
+ *
30
+ * Tags come from the `mediaTags` prop, falling back to `options.mediaTags` on the field
31
+ * (which also pre-filters the media browser). Only changes made after mount are tagged,
32
+ * so opening a document never patches its existing assets.
33
+ */
34
+ export declare function AutoTagInput(props: AutoTagInputProps): JSX
35
+
36
+ export declare type AutoTagInputProps = InputProps & {
37
+ mediaTags?: string[]
38
+ }
39
+
21
40
  declare const createAssetFormSchema: (
22
41
  languages: MediaToolOptions['languages'],
23
42
  validateAltTexts?: boolean
@@ -152,6 +171,7 @@ declare type CustomFields = {
152
171
  opt?: {
153
172
  media?: {
154
173
  tags?: SanityReference[]
174
+ uploadedBy?: Uploader | string
155
175
  }
156
176
  }
157
177
  title?: string
@@ -195,6 +215,42 @@ export declare const mediaAssetSource: {
195
215
  title: string
196
216
  }
197
217
 
218
+ /**
219
+ * Defines an image or file field whose selected / uploaded assets are tagged with `mediaTags`.
220
+ *
221
+ * `mediaTags` is copied to `options.mediaTags` (which pre-filters the media browser) and
222
+ * {@link AutoTagInput} is set as the input component.
223
+ *
224
+ * ```ts
225
+ * mediaField({ name: 'image', type: 'image', mediaTags: ['product'] })
226
+ * ```
227
+ */
228
+ export declare function mediaField(
229
+ config: MediaFieldConfig<ImageDefinition>
230
+ ): MediaFieldResult<ImageDefinition>
231
+
232
+ export declare function mediaField(
233
+ config: MediaFieldConfig<FileDefinition>
234
+ ): MediaFieldResult<FileDefinition>
235
+
236
+ declare type MediaFieldConfig<T extends ImageDefinition | FileDefinition> = Omit<T, 'options'> &
237
+ FieldDefinitionBase & {
238
+ name: string
239
+ mediaTags: string[]
240
+ options?: T['options']
241
+ }
242
+
243
+ declare type MediaFieldResult<T extends ImageDefinition | FileDefinition> = Omit<T, 'options'> &
244
+ FieldDefinitionBase & {
245
+ options?: T['options'] & {
246
+ mediaTags: string[]
247
+ }
248
+ components: {
249
+ input: typeof AutoTagInput
250
+ }
251
+ } & WidenValidation &
252
+ WidenInitialValue
253
+
198
254
  export declare type MediaToolOptions = {
199
255
  languages: {
200
256
  code: string
@@ -202,6 +258,7 @@ export declare type MediaToolOptions = {
202
258
  default?: boolean
203
259
  }[]
204
260
  maximumUploadSize?: number
261
+ createTagsOnUpload?: boolean
205
262
  components?: {
206
263
  details?: ComponentType<
207
264
  DetailsProps & {
@@ -214,6 +271,13 @@ export declare type MediaToolOptions = {
214
271
  excludeSources?: string | string[]
215
272
  }
216
273
  directUploads?: boolean
274
+ uploadMenu?: boolean
275
+ /**
276
+ * Tag slugs (`media.tag` `name.current`) whose assets are hidden from the Media browser and
277
+ * asset picker, along with the tags themselves in the tag panel and tag search facet.
278
+ * The asset edit dialog still lists every tag.
279
+ */
280
+ excludeTags?: string[]
217
281
  }
218
282
 
219
283
  declare type SanityReference = {
@@ -241,4 +305,17 @@ declare const tagOptionSchema: z.ZodObject<
241
305
 
242
306
  declare type TagSelectOption = z.infer<typeof tagOptionSchema>
243
307
 
308
+ declare type Uploader = {
309
+ id: string
310
+ /** Only set by earlier builds; the name is now looked up on demand. */
311
+ name?: string
312
+ }
313
+
244
314
  export {}
315
+
316
+ declare module 'sanity' {
317
+ interface FileOptions {
318
+ /** Tags applied by `AutoTagInput` / `mediaField`, also used to pre-filter the media browser. */
319
+ mediaTags?: string[]
320
+ }
321
+ }