---
title: "Custom dialog body components"
description: "A reference list of all TinyMCE dialog components."
canonical_url: "https://www.tiny.cloud/docs/tinymce/latest/dialog-components/"
md_url: "https://www.tiny.cloud/docs/tinymce/latest/dialog-components/index.md"
version: "latest"
last_updated: "2026-09-24T22:40:35Z"
tokens: 6292
---
# Custom dialog body components

The body of a dialog must be either a `panel` (a single panel) or a `tabpanel` (a collection of panels). Each panel can contain panel components, which are either [layout components](#layout-components) or [basic components](#basic-components) such as inputs, buttons and text.

## panel

The basic dialog type is a **panel** dialog. A panel is a container for [interactive panel components](#panel-components). A panel type dialog only has one panel.

```js
{
  type: 'panel',
  items: [ ... ] // array of panel components
}
```

## tabpanel

A **tabpanel** dialog contains multiple panels, and a tab navigation menu on the left-hand side of the dialog to allow for switching between panels. Each panel can contain different [panel components](#panel-components), allowing for complex dialogs.

Each tab panel is defined using the following configuration options:

| Name | Type | Requirement | Description |
| --- | --- | --- | --- |
| name | string | optional | A identifier for the tab. If not specified, the tab will be assigned a randomly generated name. |
| title | string | required | The title of the tab for the navigation menu. |
| items | array | required | An array of [panel components](#panel-components) to display inside the panel. |

> **Note:** Panel components in different tabs with the same `name` will use the same value in the [dialog’s data object](../dialog-apis/#dialog-data-and-state). This allows for transference of data between tabs. For example, the `charmap` and `emoticons` plugin dialogs contain a search input field in each tab. By assigning the same name to all the search fields, user data entered on one tab will be transferred when the user changes tabs.

```js
{
  type: 'tabpanel',
  tabs: [ // array of tab panel configurations
    {
      name: 'mytab',
      title: 'My Tab',
      items: [ ... ] // array of panel components
    },
    ... // more panel configurations
  ]
}
```

### Dialog instance API methods

The [dialog instance API](../dialog-apis/#dialog-api-methods) contains the `showTab("tabName")` method, which allows for programmatic tab switching using the registered `name` of a tab.

### Dialog configuration event callbacks

A dialog can be configured with an [`onTabChange`](../dialog-configuration/#options) callback. This function is called when the user changes tabs. It is passed the dialog instance API and a `details` object which contains `newTabName` and `oldTabName`.

As an example of when this is useful, the `charmap` and `emoticons` plugin dialogs use `newTabName` to change search results to match the character or emoticon category represented by the current tab.

### Example: using the dialog API

Below is a trivial example of how to use `onTabChange` and `showTab()`.

```js
const dialogConfig = {
  title: 'Example Dialog',
  body: {
    type: 'tabpanel',
    tabs: [ ... ] // array of panel configurations
  },
  buttons: [],
  onTabChange: (dialogApi, details) => {
    // log the contents of details
    console.log(details.newTabName);
    console.log(details.oldTabName);

    // switch back to the old tab
    dialogApi.showTab(details.oldTabName);
  }
};
```

## Panel components

Panels can contain [layout components](#layout-components) and [basic components](#basic-components), which include components for displaying information and user interaction and input.

> **Note:** Panel components in different tabs with the same `name` will use the same value in the [dialog’s data object](../dialog-apis/#dialog-data-and-state). This allows for transference of data between tabs. For example, the `charmap` and `emoticons` plugin dialogs contain a search input field in each tab. By assigning the same name to all the search fields, user data entered on one tab will be transferred when the user changes tabs.

## Layout components

Some panel components can be used to apply a layout to an array of other panel components.

### bar

A **bar** is a layout component that creates a single row of items in the dialog body.

```js
{
  type: 'bar', // component type
  items: [ ... ] // array of panel components
}
```

### collection

A **collection** is a layout component that creates a panel containing a collection of small buttons in the dialog body. For example, this component is used in the dialogs for the [`charmap`](../charmap/) and [`emoticons`](../emoticons/) plugins.

```js
{
  type: 'collection', // component type
  name: 'collection-1', // identifier
  label: 'Collection Label'
}
```
To populate the collection with collection items, specify an array of items in the dialog’s [`initialData`](../dialog-apis/#dialog-data-and-state) property. To update the items in the collection, use the [dialog API’s](#dialog-instance-api-methods) `setData()` method. Each item should contain a `text`, `value`, and `icon` property. For example:

```js
[
  {
    text: 'Bold',
    value: 'bold',
    icon: 'bold'
  },
  ... // more item configurations
]
```

### grid

A **grid** is a layout component that creates columns in the dialog body.

```js
{
  type: 'grid', // component type
  columns: 2, // number of columns
  items: [ ... ] // array of panel components
}
```

### label

A **label** is a layout component that wraps other components and adds a label above the group of components.

```js
{
  type: 'label', // component type
  label: 'Caption', // text for the group label
  for: 'findtext', // identifier of the dialog label component
  items: [ ... ] // array of panel components
}
```

## Basic components

These panel components are used either to display information or to allow for user interaction and input.

### alertbanner

An **alertbanner** is a coloured banner designed to notify users of important information. There are four "levels" of alert banner which each display in a different color. The levels are:

- `info`
- `warn`
- `error`
- `success`
Clicking the icon in the alert banner will fire the `onAction` function in the dialog’s configuration, and pass it an object containing the `name` of the alertbanner component and `value`. `value` is the value of the `url` option if it is configured, otherwise it is an empty string.

| Name | Type | Requirement | Description |
| --- | --- | --- | --- |
| type | `'alertbanner'` | required | The component type. Must be `'alertbanner'`. |
| text | string | required | HTML text to display in the alertbanner. |
| level | `'info'`, `'warn'`, `'error'` or `'success'` | required | The alertbanner’s level, which determines its styling. |
| icon | string | required | Name of the icon to be displayed. Must correspond to an icon: in the [icon pack](../editor-icon-identifiers/), in a [custom icon pack](../creating-an-icon-pack/), or added using the [`addIcon` API](../apis/tinymce.editor.ui.registry/#addIcon). |
| url | string | optional | A URL that is passed to `onAction` when the icon button is clicked. |

```js
{
  type: 'alertbanner', // component type
  level: 'info',
  text: 'An <strong>informative</strong> message to the user',
  url: 'http://my.url',
  icon: 'question'
}
```

### button

A **button** is a clickable component that can contain text or an icon. There are two types of buttons (primary and secondary buttons), though the only difference is that they are styled differently. Primary buttons are intended to stand out. The color will depend on the chosen [skin](../customize-ui/#skins).

> **Note:** Panel buttons are different to [dialog footer buttons](../dialog-footer-buttons/).
**Events:** Interacting with a **button** component will fire the `onAction` function in the dialog’s configuration, and pass it the button’s `name` in the `details` object. This allows developers to create a click handler for each button.

| Name | Type | Requirement | Description |
| --- | --- | --- | --- |
| type | `'button'` | required | The component type. Must be `'button'`. |
| text | string | required | Text to display in the button **if icon is not specified**. Also used for the button’s `title` attribute. |
| name | string | optional | A identifier for the button. If not specified, the button will be assigned a randomly generated name. |
| icon | string | optional | Name of the icon to be displayed. Must correspond to an icon: in the [icon pack](../editor-icon-identifiers/), in a [custom icon pack](../creating-an-icon-pack/), or added using the [`addIcon` API](../apis/tinymce.editor.ui.registry/#addIcon). **When configured, the button will display the icon instead of text.** |
| buttonType | `'primary'`, `'secondary'`, or `'toolbar'` | optional | default: `'secondary'` - Whether to style the button as a primary, secondary, or toolbar button. |
| borderless | boolean | optional | default: `false` - Whether to style the button without a border and background color. |
| context | string | optional | default: `mode:design` - The context property dynamically enables or disables the button based on the editor’s current state. Only effective when `enabled` is true. For details, see: [Context](../context/). |

> **Note:** Buttons do not support mixing icons and text at the moment.

```js
{
  type: 'button', // component type
  text: 'Alpha',
  buttonType: 'primary',
  name: 'alpha-button',
  enabled: true,
  borderless: false,
  context: 'mode:design'
}
```

### checkbox

A **checkbox** is a composite component with a checkbox and a label, and with `on` and `off` states.

**Events:** Interacting with a **checkbox** component will fire the `onChange` function in the dialog’s configuration.

```js
{
  type: 'checkbox', // component type
  name: 'checkbox-1', // identifier
  label: 'Checkbox Label', // text for the label
  enabled: true, // enabled state
  context: 'mode:design' // checkbox is active when the editor is in design mode, only effective when enabled is true
}
```

### colorinput

A **colorinput** is a specialized composite component with a label, an input field and button which opens a color swatch popup on click. Users can either type a hex color code into the input, or use the color swatch to choose a color. The color swatch button will change color to reflect the selected color.

```js
{
  type: 'colorinput', // component type
  name: 'colorinput', // identifier
  label: 'Color Label', // text for the label
  context: 'mode:design' // colorinput is active when the editor is in design mode, only effective when enabled is true
}
```

### colorpicker

A **colorpicker** component is an intuitive color picker tool similar to that found in modern image editors. It allows for a color to be chosen using a RGB colour slider, or for a color to be entered as either an RGB or hex color value.

```js
{
  type: 'colorpicker', // component type
  name: 'colorpicker', // identifier
}
```

### dropzone

A **dropzone** is a composite component that catches drag and drops items or lets the user browse that can send a list of files for processing and receive the result. A text label is also rendered above the dropzone.

**Events:** Interacting with a **dropzone** component will fire the `onChange` function in the dialog’s configuration.

| Name | Type | Requirement | Description |
| --- | --- | --- | --- |
| type | `'dropzone'` | required | The component type. Must be `'dropzone'`. |
| name | string | required | An identifier for the dropzone. |
| label | string | optional | Text for the label displayed above the dropzone. |
| dropAreaLabel | string | optional | default: `'Drop an image here'` - Text label for the drop area where files can be dragged. |
| buttonLabel | string | optional | default: `'Browse for an image'` - Text label for the browse button. |
| allowedFileTypes | string | optional | default: `'image/*'` - MIME type pattern that specifies allowed file types (e.g., `'image/*'`, `'application/pdf'`). |
| allowedFileExtensions | array | optional | default: [`images_file_types`](../file-image-upload/#images_file_types) - Array of allowed file extensions (e.g., `['.jpg', '.png', '.pdf']`). |
| context | string | optional | Context condition for when the dropzone is active (e.g., `'mode:design'`). Only effective when `enabled` is `true`. |

```js
{
  type: 'dropzone', // component type
  name: 'dropzone', // identifier
  label: 'Dropzone', // text for the label
  dropAreaLabel: 'Drag and drop files here', // text for the drop area (default: 'Drop an image here')
  buttonLabel: 'Browse files', // text for the browse button (default: 'Browse for an image')
  allowedFileTypes: 'image/*', // MIME type pattern (default: 'image/*')
  allowedFileExtensions: ['.jpg', '.png', '.pdf'], // allowed file extensions (default: images_file_types)
  context: 'mode:design' // dropzone is active when the editor is in design mode
}
```

### htmlpanel

A **htmlpanel** component takes any valid HTML and renders it in the dialog.

> **Note:** Despite the name an HTMLpanel can not be used as a body component like `panel` and `tabpanel`.

```js
{
  type: 'htmlpanel', // component type
  html: '<div>Html goes here</div>'
}
```

### iframe

An **iframe** component takes an HTML document as a string and displays it in the dialog within an iframe.

> **Note:** To replace the entire dialog body with an iframe that loads its content from a URL, use a [URL dialog](../urldialog/).

| Name | Type | Requirement | Description |
| --- | --- | --- | --- |
| type | `'iframe'` | required | The component type. Must be `'iframe'`. |
| name | string | required | A identifier for the button. |
| label | string | optional | String to use for the iframe’s `title` attribute. |
| sandboxed | boolean | optional | default: `true` - When true, sets the iframe’s `sandbox` attribute to `"allow-scripts allow-same-origin"`. |
| transparent | boolean | optional | default: `true` - When true, sets the iframe’s background to transparent instead of opaque. |

```js
{
  type: 'iframe', // component type
  name: 'iframe', // identifier
  label: 'Description of iframe', // text for the iframe's title attribute
  sandboxed: true,
  transparent: true
}
```
To set the iframe’s content on dialog open, specify document HTML as a string in the dialog’s [`initialData`](../dialog-apis/#dialog-data-and-state) property. To update the iframe’s content, use the [dialog API’s](../dialog-apis/#dialog-api-methods) `setData()` method. For example:

```js
dialogApi.setData({
  iframe: '<!DOCTYPE html>' +
          '<html>' +
          '<head></head>' +
          '<body><p>Content here.</p></body>' +
          '</html>'
})
```

### imagepreview

An **imagepreview** is a specialized component that allows for any image to be previewed and zoomed.

```js
{
  type: 'imagepreview', // component type
  name: 'preview', // identifier
  height: '100px', // optional CSS height to constrain the image preview to
}
```
The dialog data for the **imagepreview** component consists of a URL and an optional zoom factor.

```js
{
  url: 'https://www.example.com/image.png', // image URL
  zoom: 1.5 // optional zoom factor
}
```

### input

An **input** is a composite component that renders a label and a single line text input field.

**Events:** Interacting with an **input** component will fire the `onChange` function in the dialog’s configuration **as the user types**.

| Property | Type | Requirement | Description |
| --- | --- | --- | --- |
| type | ‘input’ | required | The component type. Must be `'input'`. |
| name | string | required | A identifier for the input. |
| label | string | optional | String to use for the input’s `title` attribute. |
| placeholder | string | optional | String of placeholder text for the input field. |
| enabled | boolean | optional | Allows the field to be disabled. Default is `true`. |
| inputMode | string | optional | Allows for the specification of input type for displaying contextual onscreen keyboards on mobile devices. |
| context | string | optional | default: `mode:design` - The context property dynamically enables or disables the input based on the editor’s current state. For details, see: [Context](../context/). |

```js
{
  type: 'input', // component type
  name: 'inputA', // identifier
  inputMode: 'text',
  label: 'Input Label', // text for the label
  placeholder: 'example', // placeholder text for the input
  enabled: true, // enabled state
  maximized: false, // grow width to take as much space as possible
  context: 'mode:design' // input is active when the editor is in design mode, only effective when enabled is true
}
```

#### inputMode

`inputMode` is a property of `input`.

Use `inputMode` to set the type of onscreen keyboard provided on mobile devices when a user focuses the input element.

For a list of valid input modes, see: [MDN Web Docs - inputmode](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode).

### listbox

A **listbox** is a composite component with a label and a dropdown list of options for users to select from. This component displays a menu-like dropdown and allows nested options to be shown to users.

**Events:** Interacting with a **listbox** component will fire the `onChange` function in the dialog’s configuration.

```js
{
  type: 'listbox', // component type
  name: 'ListBoxA', // identifier
  label: 'ListBox Label',
  enabled: true, // enabled state
  items: [
    { text: 'One', value: 'one' },
    { text: 'Two', value: 'two' },
    { text: 'Submenu', items: [
      { text: 'Three', value: 'three' }
    ]}
  ],
  context: 'mode:design' // listbox is active when the editor is in design mode, only effective when enabled is true
}
```

### selectbox

A **selectbox** is a composite component with a label and a single dropdown list of options for users to select from.

**Events:** Interacting with a **selectbox** component will fire the `onChange` function in the dialog’s configuration.

```js
{
  type: 'selectbox', // component type
  name: 'SelectA', // identifier
  label: 'Select Label',
  enabled: true, // enabled state
  size: 1, // number of visible values (optional)
  items: [
    { value: 'one', text: 'One' },
    { value: 'two', text: 'Two' }
  ],
  context: 'mode:design' // selectbox is active when the editor is in design mode, only effective when enabled is true
}
```

### sizeinput

A **sizeinput** is a specialized composite component with two input fields labelled "Width" and "Height" and a "ratio lock" button. It should be used for setting dimensions on content elements.

**Events:** Interacting with the input fields of a **sizeinput** component will fire the `onChange` function in the dialog’s configuration **when the user clicks away from the component**.

```js
{
  type: 'sizeinput', // component type
  name: 'size', // identifier
  label: 'Dimensions',
  enabled: true, // enabled state
  context: 'mode:design' // sizeinput is active when the editor is in design mode, only effective when enabled is true
}
```

### slider

A **slider** is a specialized component with a label and a horizontal sliding bar. It can be used to allow users to select a value within a specified range.

**Events:** Interacting with the **slider** component will fire the `onChange` function in the dialog’s configuration **when the user releases the slider thumb**.

```js
{
  type: 'slider', // component type
  name: 'vol', // identifier
  label: 'Volume',
  min: 0, // minimum value
  max: 100 // maximum value
}
```

### table

A **table** is a layout component that renders a simple table.

```js
{
  type: 'table', // component type
  header: [ 'Heading 1', 'Heading 2', 'Heading 3' ],
  cells: [
    [ 'Cell 1', 'Cell 2', 'Cell 3' ],
    [ 'Cell 4', 'Cell 5', 'Cell 6' ]
  ]
}
```

### textarea

A **textarea** is a multiline text field.

**Events:** Interacting with a **textbox** component will fire the `onChange` function in the dialog’s configuration.

```js
{
  type: 'textarea', // component type
  name: 'text-a', // identifier
  label: 'Text: ',
  placeholder: 'example',
  enabled: true, // enabled state
  maximized: false, // grow width to take as much space as possible
  context: 'mode:design' // textarea is active when the editor is in design mode, only effective when enabled is true
}
```

### tree

A **tree** is a component used to present a tree-style hierarchy. For example a list of folders containing other folders and files.

A **tree** can include two different items:

- a directory; and
- a leaf.
A directory item can contain other directory items and leaf items.

As well, **tree** items can be set to `fetch` other TinyMCE menus.

#### Activating items in a tree

Activating a directory item toggles the item between two states: collapsed and expanded.

Activating a leaf item triggers the `onLeafAction` callback.

Items are activated by clicking, pressing or by using keyboard-navigation.

#### Tree navigation and activation using a keyboard

- The **up–** or **down–arrow-key** highlights an item.
- If the highlighted item is a directory, the **left–** or **right–arrow-key** collapses or expands a directory item
- If the hightlighted item is a leaf, pressing **Return** triggers the `onLeafAction` callback.
**onLeafAction:** Interacting with a **tree** component executes the `onLeafAction` callback set in the dialog configuration.

```js
tinymce.init({
  selector: "textarea",
  toolbar: "tree",
  setup: (ed) => {
    ed.ui.registry.addButton('tree', {
      text: 'Tree toolbar button',
      onAction: () => {
        ed.windowManager.open({
          title: 'Tree dialog',
          buttons: [{
	    type: 'cancel',
	    text: 'Cancel'
	  }],
          body : {
            type: 'panel',
            items: [{
              type: 'tree',
              onLeafAction: (id) => {
                console.log('clicked on item with id', id);
              },
              items: [
                {
                  type: 'directory',
                  id: 'dir',
                  title: 'Directory',
                  menu: {
                    icon: 'image-options',
                    type: 'menubutton',
                    fetch: (success) => success([
                      'bold',
                      'italic',
                      'underline',
                      {
                          type: 'menuitem',
                          text: 'Menu item',
                          onAction: () => {
                            console.log('dir menu item');
                          }
                      }
                    ])
                  },
                  children: [
                    {
                      type: 'leaf',
                      title: 'Leaf 3',
                      id: '3'
                    },
                    {
                      type: 'leaf',
                      title: 'Leaf 4',
                      id: '4',
                      menu: {
                        icon: 'image-options',
                        type: 'menubutton',
                        fetch: (success) => success([
                          'blocks',
                          'fontfamily',
                          'fontsize',
                          {
                            type: 'menuitem',
                            text: 'Menu item',
                            onAction: () => {
                              console.log('leaf menu item'); // for demo purposes
                            }
                          }
                        ])
                      }
                    },
                  ]
                },
                {
                  type: 'leaf',
                  title: 'Leaf 5',
                  id: '5'
                },
                {
                  type: 'leaf',
                  title: 'Leaf 6',
                  id: '6'
                },
              ]
            }]
          }
        });
      }
    });
  },
});
```

### urlinput

A **urlinput** is a specialized composite component for URL input or file upload. It has a label, a text input field and an optional filepicker button. The urlinput component also includes a **typeahead** dropdown that will display previously-entered URLs that match the current input text and update as the user types.

> **Note:** The filepicker button will only appear if [`file_picker_callback`](../file-image-upload/#file_picker_callback) is configured.
**Events:** Interacting with a **selectbox** component will fire the `onChange` function in the dialog’s configuration **when the user clicks away from the component**.

| Name | Type | Requirement | Description |
| --- | --- | --- | --- |
| type | `'urlinput'` | required | The component type. Must be `'urlinput'`. |
| name | string | required | An identifier for the urlinput. |
| label | string | optional | String to use for the label. |
| filetype | `'file'` or

`'image'` or

`'media'` | optional | Default value: `'file'`.

Restrict the types of files that can be uploaded using the filepicker.

The default value — `file` — allows anything, including document links.

This option **requires** `file_picker_callback` to be configured. |
| enabled | boolean | optional | default: `true`

Whether the component should initially be disabled. |
| picker_text | string | optional | Sets an alternative tooltip for the file picker button.

If `picker_text` is not specified, the tooltip defaults to the value provided by the `label` property.

This option **requires** `file_picker_callback` to be configured. |
| context | string | optional | default: `mode:design` - The context property dynamically enables or disables the urlinput based on the editor’s current state. For details, see: [Context](../context/). |

#### urlinput examples

**urlinput for links**

The filepicker will accept any file type; the typeahead will include 5 previously entered URLs plus all anchor targets and headings in the document; and the file picker button will have a custom tooltip.

```js
{
  type: 'urlinput', // component type
  name: 'url', // identifier
  filetype: 'file', // allow any file types
  label: 'Url', // text for component label
  enabled: true, // enabled state
  picker_text: 'Find local files', // set a custom tooltip for the filepicker button
  context: 'mode:design' // urlinput is active when the editor is in design mode, only effective when enabled is true
}
```
**urlinput for image upload**

The filepicker will only accept images and the typeahead will include 5 previously entered image URLs.

```js
{
  type: 'urlinput', // component type
  name: 'src', // identifier
  filetype: 'image', // restrict file types to image types
  label: 'Source', // text for component label
  enabled: true, // enabled state
  context: 'mode:design' // urlinput is active when the editor is in design mode, only effective when enabled is true
}
```
