Skip to main content

File picker

Two components for working with the WordPress Media library:

  • ManageFileButton — a single button that opens the media modal in browse, upload, or replace mode.
  • FileSelector — a complete file-picker UI (preview + replace + remove) built around FilePickerShell from Eightshift UI components.

Both support different kinds (file, image, video, subtitle, geoJson, lottie, rive, custom) which control labels and icons in the modal and on the buttons.

ManageFileButton

A customizable button that opens the media modal. Use it directly when you only need a single action (e.g., a standalone "Upload" or "Replace" button) and don't want the surrounding FilePickerShell.

import { ManageFileButton } from '@eightshift/frontend-libs-tailwind/scripts';

<ManageFileButton
onChange={(media) => setAttributes({ fileId: media.id, fileUrl: media.url })}
allowedTypes={['application/pdf']}
/>;

Highlighted props

PropTypeDescription
onChange(media) => voidRequired. Called with the selected media item ({ id, url, ... }).
type'browse' | 'upload' | 'replace'Mode for the underlying media modal. Defaults to browse.
kind'file' | 'image' | 'video' | 'subtitle' | 'geoJson' | 'lottie' | 'rive' | 'custom'Controls labels and icons. Defaults to file.
currentIdstringID of the currently selected item. Used with type='replace' to mark the current selection in the modal.
allowedTypesstring[]Required. Allowed MIME types.
compactbooleanRenders the button as icon-only.
labels{ buttonLabel?, modalTitle?, buttonIcon?, removeIcon? }Only applies when kind='custom'. Overrides labels and icons.
buttonPropsobjectForwarded to the trigger Button.
hiddenbooleanIf true, nothing is rendered.

Replace mode

<ManageFileButton
type='replace'
kind='image'
currentId={imageId}
allowedTypes={['image']}
onChange={onChange}
/>

Custom labels and icons

<ManageFileButton
kind='custom'
labels={{
buttonLabel: { browse: __('Pick a thing', 'my-theme') },
modalTitle: { browse: __('Choose your thing', 'my-theme') },
buttonIcon: { browse: myIcon },
}}
allowedTypes={['application/pdf']}
onChange={onChange}
/>

FileSelector

A higher-level picker that wraps FilePickerShell: it shows the empty state (browse + upload) when no file is selected, and a replace/remove pair when one is. Pass any FilePickerShell prop through and it will be forwarded.

import { FileSelector } from '@eightshift/frontend-libs-tailwind/scripts';

<FileSelector
onChange={onChange}
fileId={fileId}
fileName={fileName}
allowedTypes={['video']}
kind='video'
/>;

Highlighted props

PropTypeDescription
onChange(media) => voidRequired. Called with { id, url, ... } on select, or { id: undefined, url: undefined } on remove.
fileIdstringRequired. ID of the current file.
fileNamestringRequired. Name/URL of the current file, used both for the preview and as the URL passed to FilePickerShell.
allowedTypesstring[]Required. Allowed MIME types.
kind'file' | 'image' | 'video' | 'subtitle' | 'geoJson' | 'lottie' | 'rive' | 'custom'Controls labels and icons. Defaults to file.
noDeletebooleanHide the "Remove" button.
noUploadbooleanHide the "Upload" button in the empty state.
labelsobjectSame shape as ManageFileButton.labels. Applies when kind='custom'.
Note

FileSelector forwards any unrecognized prop to the underlying FilePickerShell, so you can also pass icon, noUrlContent overrides, custom class names, etc.