Control customization

Hide, reorder and relabel built-in editor controls

ui.selection configures the controls of the selected item: the bar above the canvas on a desktop, the floating pill, and the selection bar on a phone. ui.toolRail and ui.dock configure the tools on the left and at the bottom. ui.toolbar is the older setting for the toolbar groups. It still works, and the editor translates it.

Usage

src/App.tsx
import { VideoEditor, type ItemListConfig, type SelectionChipId } from '@layermetry/media-editor/react';

const selection: ItemListConfig<SelectionChipId> = {
  order: ['crop', 'effects'],
  hidden: ['delete'],
  labels: { crop: 'Trim edges' },
  display: { effects: 'icon' },
};

export default function App() {
  return <div style={{ position: 'fixed', inset: 0 }}>
    <VideoEditor licenseKey="YOUR_LICENSE_KEY" onClose={() => undefined}
      ui={{
        selection,
        toolRail: { display: { text: 'both' } },
        dock: { display: { media: 'icon' } },
      }} />
  </div>;
}

These settings change the controls that are currently available. They do not make an unsupported control appear for another item type.

List settings

All four settings use ItemListConfig: ui.toolRail, ui.dock, ui.selection and ui.toolbar.

FieldTypeDefaultDescription
orderRead-only id arraySurface orderPuts listed ids first, preserving the order of unlisted entries afterward.
hiddenRead-only id arrayNoneRemoves listed controls from this surface.
labelsMap of id to stringBuilt-in labelsReplaces the visible label, tooltip and accessible name.
displayMap of id to icon, label or bothSurface displayChanges how each entry is drawn.

ui.selection applies to the bar above the canvas on a desktop, the floating pill, the selection bar on a phone, and the small pill on a phone. It names controls by id, so one id applies to every type of item that has that control. ui.toolbar is the older setting. It names toolbar groups, such as Format and Images. See The old ui.toolbar setting.

An icon-only control keeps its label as a tooltip and accessible name. The right-click menu always shows words. Hiding a control removes only that control: shortcuts and programmatic editing actions remain available. Each surface is configured independently. Use roles and locks to restrict editing permissions.

Default lists

Each default order is a plain list in the editor. It is the starting view, and your ui.selection is applied after it, so your choice always wins. The lists below are the real defaults. Copy a list, change it, and pass it as ui.selection.order.

How to read a list:

  • Left to right is the order on the screen. It is also the priority. When the desktop bar runs out of width, the controls at the end of the list move into More first.
  • A control that the editor can show, but that a list does not name, is kept after the named controls. No control disappears because it is missing from a list.
  • The last five ids, bringForward, sendBackward, delete, lock and unlock, are at the end of every desktop list. In the lists below they are written as ...OBJECT_CONTROLS. lock is the Lock… button and unlock is the Unlock button. Each one shows only when it is available for the selection.
  • A control shows only when it fits the item. For example, removeBg needs a picture or a clip. Naming an id in a list does not make a control appear for an item that cannot use it.
  • copyStyle and pasteStyle are not in any list. They are always in More. Name them in ui.selection.order to bring them into the bar.

The keys are the types of item. multi is for several items selected together.

The bar above the canvas on a desktop:

const OBJECT_CONTROLS = ['bringForward', 'sendBackward', 'delete', 'lock', 'unlock'];

const desktopBar = {
  video: [
    'trim', 'split', 'speed', 'volume', 'mute', 'crop', 'mask', 'effects', 'animations',
    'audioFx', 'captions', 'fades', 'fitMode', 'opacity', 'replace', 'clearCrop', 'clearMask',
    'removeBg', 'stabilize', 'generateCaptions', 'position', 'fitToCanvas', 'matchCanvas',
    ...OBJECT_CONTROLS,
  ],
  audio: [
    'trim', 'split', 'speed', 'volume', 'mute', 'fades', 'audioFx', 'reRecordPart', 'replace',
    'position', ...OBJECT_CONTROLS,
  ],
  text: [
    'font', 'fontSize', 'textColor', 'bold', 'italic', 'underline', 'textAlign', 'textStyles',
    'effects', 'animations', 'opacity', 'rewriteWithAi', 'editText', 'textBackgrounds',
    'position', ...OBJECT_CONTROLS,
  ],
  shape: [
    'fill', 'stroke', 'strokeWidth', 'effects', 'animations', 'opacity', 'position',
    ...OBJECT_CONTROLS,
  ],
  image: [
    'crop', 'mask', 'removeBg', 'fitMode', 'replace', 'effects', 'animations', 'opacity',
    'clearCrop', 'clearMask', 'editWithAi', 'makeVideo', 'position', 'fitToCanvas',
    'matchCanvas', ...OBJECT_CONTROLS,
  ],
  sticker: [
    'mask', 'effects', 'animations', 'opacity', 'clearMask', 'position', ...OBJECT_CONTROLS,
  ],
  gif: [
    'mask', 'animations', 'opacity', 'clearMask', 'matchCanvas', 'position',
    ...OBJECT_CONTROLS,
  ],
  label: [
    'editText', 'textColor', 'animations', 'opacity', 'position', ...OBJECT_CONTROLS,
  ],
  subtitle: [
    'subtitleStyle', 'subtitleTextColor', 'subtitleBgColor', 'subtitleFont',
    'subtitleFontSize', 'subtitlePosition', 'align', 'bgOpacity', 'stroke', 'shadow',
    'subtitleAnimation', 'captions', 'position', ...OBJECT_CONTROLS,
  ],
  multi: [
    'group', 'ungroup', 'position', 'opacity', 'animations', 'viewRecommendations',
    ...OBJECT_CONTROLS,
  ],
};

On a phone, only a video clip and a sound clip have a default list. Every other type keeps the order that the editor builds:

const phoneBar = {
  video: [
    'trim', 'split', 'speed', 'volume', 'mute', 'crop', 'clearCrop', 'mask', 'clearMask',
    'effects', 'animations', 'fitMode', 'replace', 'audioFx', 'captions', 'generateCaptions',
    'fades', 'opacity', 'position', 'fitToCanvas', 'matchCanvas', 'removeBg', 'stabilize',
  ],
  audio: [
    'volume', 'audioFx', 'reRecordPart', 'split', 'speed', 'fades', 'trim', 'mute', 'replace',
    'position',
  ],
};

By default the desktop bar draws bold, italic, underline, bringForward, sendBackward, delete and mute as a picture only, because the picture says enough and the words would cost the width of two other buttons. The label is still the tooltip and the accessible name. Set display for the id to 'label' or 'both' to bring the words back.

This example puts Mute and Trim first, hides Delete, and shows the words on Mute:

import type { UiConfig } from '@layermetry/media-editor';

const ui: UiConfig = {
  selection: {
    order: ['mute', 'trim'],
    hidden: ['delete'],
    display: { mute: 'both' },
  },
};

New ids in this release:

IdWhat it does
trimVideo and sound clips. Sets where the clip starts in its file and how long it lasts, with the same limits as dragging the edges on the timeline. One change is one Undo step.
muteVideo and sound clips. Mutes or unmutes the clip.
replacePuts a new file in place of the selected one and keeps its position, size and timing. A video or sound clip uses the Replace file chooser. A picture offers it only when you pass onUploadAsset.
copyStyle, pasteStyleCopy the look of one item, and give it to others. See Copy style and paste style.
group, ungroupFor several selected items.

The old ui.toolbar setting

ui.toolbar is still accepted, but the bar above the canvas has no groups or headings now. The editor translates each group id into the controls that the group held, for the item types that showed it. hidden and order are applied to those controls, together with your ui.selection.

A labels setting, or a display of 'label' or 'both', has no heading left to change. Your own buttons are the group actions. They always come after the editor's controls with no heading. Hiding actions still works. The order, labels and display of actions are not applied.

Hiding controls with ui.toolbar.hidden also hides the page-bar extras: Insert Emoji and Save template. The page controls and More stay visible.

The editor prints one console warning that starts with [MediaEditor] ui.toolbar:. It names what was translated and what has no effect, and it tells you to use ui.selection. Use ui.selection with the control ids in new code.

Control ids

Use the union for the surface you want to configure.

Public typeIds
ToolRailIdelements, media, photo, video, audio, subtitle, text, brand, shapes, stickers, effects, background, templates, audioEffects, animations, automated
DockIdmedia, photo, video, audio, text, brand, elements, shapes, stickers, templates, captions, effects, background, aiChat, resize, automated
SelectionChipIdeditWithAi, makeVideo, rewriteWithAi, crop, clearCrop, mask, clearMask, effects, animations, fitMode, position, fitToCanvas, matchCanvas, removeBg, stabilize, volume, audioFx, captions, generateCaptions, split, speed, fades, opacity, editText, font, fontSize, bold, italic, underline, textColor, textAlign, textStyles, textBackgrounds, fill, stroke, strokeWidth, reRecordPart, viewRecommendations, subtitleStyle, subtitleFontSize, subtitleFont, subtitleTextColor, subtitleBgColor, bgOpacity, subtitlePosition, align, shadow, subtitleAnimation, bringForward, sendBackward, group, ungroup, delete, lock, unlock, trim, mute, replace, copyStyle, pasteStyle
ToolbarGroupId (old setting)text, format, style, shapes, images, crop, videos, audio, speed, fades, captions, animations, actions, controls

Effects, Animations, Audio effects and Background are not on the tool rail by default. List an id in ui.toolRail.order to bring it back. See Tools that are off the rail by default.

The main ui fields accept strings so you can share a configuration between editors. To check ids at compile time, use ItemListConfig with the SelectionChipId type argument or the corresponding union above. An unknown id is ignored with one console warning. Available controls still depend on the selected item and enabled features.

Custom action controls

Use ui.customActions.shown for custom-action overflow counts. Your own buttons come after the editor's controls on the bar above the canvas, and ui.toolbar.hidden can still hide them with the id actions. See Custom actions.

On this page