diff --git a/packages/@tinacms/schema-tools/src/types/index.ts b/packages/@tinacms/schema-tools/src/types/index.ts index 53bd30bac3..e73a5706b8 100644 --- a/packages/@tinacms/schema-tools/src/types/index.ts +++ b/packages/@tinacms/schema-tools/src/types/index.ts @@ -271,69 +271,6 @@ export type DateTimeField = ( type: 'datetime'; }; -/** - * File extensions the media manager can filter on. Not a list of what may be - * uploaded — that is `media.accept` — but the vocabulary a field or filter - * uses to narrow what is shown. - */ -export const MEDIA_EXTENSIONS = [ - 'jpg', - 'jpeg', - 'png', - 'gif', - 'webp', - 'svg', - 'avif', - 'ico', - 'mp4', - 'webm', - 'mov', - 'mp3', - 'wav', - 'ogg', - 'pdf', - 'json', - 'csv', - 'txt', -] as const; - -export type MediaExtension = (typeof MEDIA_EXTENSIONS)[number]; - -export const MEDIA_CATEGORIES = { - image: ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'avif', 'ico'], - video: ['mp4', 'webm', 'mov'], - audio: ['mp3', 'wav', 'ogg'], - document: ['pdf', 'json', 'csv', 'txt'], -} as const satisfies Record; - -export type MediaCategory = keyof typeof MEDIA_CATEGORIES; - -export type MediaAccept = MediaExtension | MediaCategory; - -/** - * Flattens a field's `accept` into concrete extensions, expanding any - * category shorthand. Unknown values are dropped rather than passed through, - * so a typo narrows to nothing visible instead of silently disabling the - * filter. - */ -export const resolveMediaAccept = ( - accept: MediaAccept | MediaAccept[] | undefined -): MediaExtension[] => { - if (!accept) return []; - const requested = Array.isArray(accept) ? accept : [accept]; - const resolved = new Set(); - for (const entry of requested) { - if (entry in MEDIA_CATEGORIES) { - for (const ext of MEDIA_CATEGORIES[entry as MediaCategory]) { - resolved.add(ext); - } - } else if ((MEDIA_EXTENSIONS as readonly string[]).includes(entry)) { - resolved.add(entry as MediaExtension); - } - } - return [...resolved]; -}; - export type ImageField = ( | FieldGeneric | FieldGeneric @@ -351,19 +288,6 @@ export type ImageField = ( * ``` */ uploadDir?: (formValues: Record) => string; - /** - * Restricts this field to specific file types. Narrows what the media - * manager offers when browsing and what the field will accept on upload, - * overriding the global `media.accept`. - * - * @example - * ```ts - * accept: 'pdf' - * accept: ['png', 'svg'] - * accept: 'image' - * ``` - */ - accept?: MediaAccept | MediaAccept[]; }; type ReferenceFieldOptions = { diff --git a/packages/@tinacms/schema-tools/src/types/media-accept.test.ts b/packages/@tinacms/schema-tools/src/types/media-accept.test.ts deleted file mode 100644 index 10292601f0..0000000000 --- a/packages/@tinacms/schema-tools/src/types/media-accept.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { resolveMediaAccept } from './index'; - -describe('resolveMediaAccept', () => { - it('treats undefined as no filter', () => { - expect(resolveMediaAccept(undefined)).toEqual([]); - }); - - it('resolves a single extension', () => { - expect(resolveMediaAccept('pdf')).toEqual(['pdf']); - }); - - it('expands a category into its extensions', () => { - expect(resolveMediaAccept('video')).toEqual(['mp4', 'webm', 'mov']); - }); - - it('dedupes when a category and one of its extensions overlap', () => { - expect( - resolveMediaAccept(['png', 'image']).filter((e) => e === 'png') - ).toHaveLength(1); - }); - - it('drops unknown values instead of disabling the filter', () => { - expect(resolveMediaAccept(['pgn' as never, 'png'])).toEqual(['png']); - }); -}); diff --git a/packages/tinacms/src/toolkit/components/media/media-manager.tsx b/packages/tinacms/src/toolkit/components/media/media-manager.tsx index 5de8ed10e8..9851009bf9 100644 --- a/packages/tinacms/src/toolkit/components/media/media-manager.tsx +++ b/packages/tinacms/src/toolkit/components/media/media-manager.tsx @@ -4,10 +4,6 @@ import { MediaListError, MediaListOffset, } from '@toolkit/core'; -import { - type MediaAccept, - resolveMediaAccept, -} from '@tinacms/schema-tools'; import { LoadingDots } from '@toolkit/form-builder'; import { CloseIcon, TrashIcon } from '@toolkit/icons'; import { FullscreenModal, Modal, ModalBody } from '@toolkit/react-modals'; @@ -98,7 +94,6 @@ export interface MediaRequest { onSelect?(_media: Media): void; close?(): void; allowDelete?: boolean; - accept?: MediaAccept | MediaAccept[]; } export function MediaManager() { @@ -150,7 +145,6 @@ export function MediaPicker({ allowDelete, onSelect, close, - accept: fieldAccept, ...props }: MediaRequest) { const cms = useCMS(); @@ -211,17 +205,6 @@ export function MediaPicker({ const listRequestRef = useRef(0); const newMediaSrcsRef = useRef>(new Set()); - // A store that ignores `ext` would return everything, so honour the field's - // `accept` only when the store says it filters. The dropzone still enforces - // it on upload either way. - const acceptedExtensions = React.useMemo( - () => - cms.media.store.extensionFilterable - ? resolveMediaAccept(fieldAccept) - : [], - [fieldAccept, cms.media.store.extensionFilterable] - ); - async function loadMedia(loadFolders = true) { const requestId = ++listRequestRef.current; setListState('loading'); @@ -237,7 +220,6 @@ export function MediaPicker({ ], filesOnly: !loadFolders, search: debouncedSearch || undefined, - ext: acceptedExtensions.length ? acceptedExtensions : undefined, }); if (requestId !== listRequestRef.current) return; setList((prev) => { @@ -308,13 +290,7 @@ export function MediaPicker({ resetList(); } ); - }, [ - offset, - directory, - debouncedSearch, - acceptedExtensions, - cms.media.isConfigured, - ]); + }, [offset, directory, debouncedSearch, cms.media.isConfigured]); const onClickMediaItem = (item: Media) => { if (!item) { @@ -363,15 +339,11 @@ export function MediaPicker({ } const [uploading, setUploading] = useState(false); - const globalAccept = Array.isArray( + const accept = Array.isArray( cms.api.tina.schema.schema?.config?.media?.accept ) ? cms.api.tina.schema.schema?.config?.media?.accept.join(',') : cms.api.tina.schema.schema?.config?.media?.accept; - const fieldExtensions = resolveMediaAccept(fieldAccept); - const accept = fieldExtensions.length - ? fieldExtensions.map((ext) => `.${ext}`).join(',') - : globalAccept; const { getRootProps, getInputProps, isDragActive } = useDropzone({ accept: dropzoneAcceptFromString( accept || cms.media.accept || DEFAULT_MEDIA_UPLOAD_TYPES diff --git a/packages/tinacms/src/toolkit/core/media-store.default.ts b/packages/tinacms/src/toolkit/core/media-store.default.ts index 63981c6ad9..4a92dc8f61 100644 --- a/packages/tinacms/src/toolkit/core/media-store.default.ts +++ b/packages/tinacms/src/toolkit/core/media-store.default.ts @@ -191,10 +191,6 @@ export class TinaMediaStore implements MediaStore { searchable = true; - // Only the v2 list endpoint filters by extension; the local branch below - // and `staticMedia` both ignore it. - extensionFilterable = true; - // allow up to 100MB uploads maxSize = 100 * 1024 * 1024; @@ -880,13 +876,7 @@ export class TinaMediaStore implements MediaStore { options.limit || 20 }${options.offset ? `&cursor=${options.offset}` : ''}${ encodedBranch ? `&branch=${encodedBranch}` : '' - }${ - options.search ? `&search=${encodeURIComponent(options.search)}` : '' - }${ - options.ext?.length - ? `&ext=${encodeURIComponent(options.ext.join(','))}` - : '' - }` + }${options.search ? `&search=${encodeURIComponent(options.search)}` : ''}` ); if (res.status == 401) { diff --git a/packages/tinacms/src/toolkit/core/media.ts b/packages/tinacms/src/toolkit/core/media.ts index 11a2917141..e118fdb1be 100644 --- a/packages/tinacms/src/toolkit/core/media.ts +++ b/packages/tinacms/src/toolkit/core/media.ts @@ -1,7 +1,3 @@ -import type { - MediaAccept, - MediaExtension, -} from '@tinacms/schema-tools'; import { EventBus } from './event'; import { DummyMediaStore } from './media-store.default'; @@ -123,15 +119,6 @@ export interface MediaStore { */ searchable?: boolean; - /** - * Indicates that `list` honours the `ext` option. Stores that ignore it - * should leave this unset, so a field declaring `accept` falls back to - * showing everything rather than silently listing the wrong files. - * - * @default false - */ - extensionFilterable?: boolean; - /** * Converts a Media object to the value stored in a form field. * @@ -152,11 +139,6 @@ export interface MediaListOptions { thumbnailSizes?: { w: number; h: number }[]; filesOnly?: boolean; search?: string; - /** - * Restricts the listing to these file extensions. Resolved from categories - * before it reaches the store, so it is always concrete extensions here. - */ - ext?: MediaExtension[]; } /** @@ -314,10 +296,6 @@ export interface SelectMediaOptions { allowDelete?: boolean; directory?: string; onSelect?(media: Media): void; - /** - * Narrows the picker to these file types, from a field's `accept`. - */ - accept?: MediaAccept | MediaAccept[]; } interface MediaListErrorConfig { diff --git a/packages/tinacms/src/toolkit/fields/plugins/image-field-plugin.tsx b/packages/tinacms/src/toolkit/fields/plugins/image-field-plugin.tsx index acb7e0a05c..611d4cfe16 100644 --- a/packages/tinacms/src/toolkit/fields/plugins/image-field-plugin.tsx +++ b/packages/tinacms/src/toolkit/fields/plugins/image-field-plugin.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import { wrapFieldsWithMeta } from './wrap-field-with-meta'; import { InputProps, ImageUpload } from '../components'; import { Media } from '@toolkit/core'; -import type { MediaAccept } from '@tinacms/schema-tools'; import { useCMS } from '@toolkit/react-core'; import { parse } from './text-format'; import { useState } from 'react'; @@ -12,7 +11,6 @@ interface ImageProps { path: string; uploadDir?(formValues: any): string; clearable?: boolean; - accept?: MediaAccept | MediaAccept[]; } export const ImageField = wrapFieldsWithMeta( @@ -58,7 +56,6 @@ export const ImageField = wrapFieldsWithMeta( allowDelete: true, directory, onSelect: onChange, - accept: props.field.accept, }); }} onDrop={async ([file]: File[], fileRejections) => {