šŸ“ Sign Up | šŸ” Log In

← Root | ↑ Up

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ šŸ“„ shadcn/directory/udecode/plate/(plugins)/(functionality)/multi-select │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

╔══════════════════════════════════════════════════════════════════════════════════════════════╗
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘

title: Multi Select docs:

  • route: /docs/components/tag-node
  • route: /docs/components/select-editor

<ComponentPreview name="select-editor-demo" /> <PackageInfo>

Features

Unlike traditional input-based multi-selects, this component is built on top of Plate editor, providing:

  • Full history support (undo/redo)
  • Native cursor navigation between and within tags
  • Select one to many tags
  • Copy/paste tags
  • Drag and drop to reorder tags
  • Read-only mode
  • Duplicate tags prevention
  • Create new tags with case insensitive matching
  • Search text cleanup and whitespace trimming
  • Fuzzy search powered by cmdk
</PackageInfo>

Manual Usage

<Steps>

Installation

npm install @platejs/tag

Add Plugins

import { MultiSelectPlugin } from '@platejs/tag/react';
import { createPlateEditor } from 'platejs/react';

const editor = createPlateEditor({
  plugins: [
    // ...otherPlugins,
    MultiSelectPlugin, // Multi-select editor with tag functionality
  ],
});

Configure Plugins

import { MultiSelectPlugin } from '@platejs/tag/react';
import { createPlateEditor } from 'platejs/react';
import { TagElement } from '@/components/ui/tag-node';

const editor = createPlateEditor({
  plugins: [
    // ...otherPlugins,
    MultiSelectPlugin.withComponent(TagElement),
  ],
});
  • MultiSelectPlugin: Extends TagPlugin and constrains the editor to only contain tag elements
  • withComponent: Assigns TagElement to render tag components

Add SelectEditor

<ComponentInstallation name="select-editor" inline />

Basic Example

import { MultiSelectPlugin } from '@platejs/tag/react';
import { TagElement } from '@/components/ui/tag-node';
import {
  SelectEditor,
  SelectEditorContent,
  SelectEditorInput,
  SelectEditorCombobox,
  type SelectItem,
} from '@/components/ui/select-editor';

// Define your items
const ITEMS: SelectItem[] = [
  { value: 'React' },
  { value: 'TypeScript' },
  { value: 'JavaScript' },
];

export default function MySelectEditor() {
  const [value, setValue] = React.useState<SelectItem[]>([ITEMS[0]]);

  return (
    <SelectEditor
      value={value}
      onValueChange={setValue}
      items={ITEMS}
    >
      <SelectEditorContent>
        <SelectEditorInput placeholder="Select items..." />
        <SelectEditorCombobox />
      </SelectEditorContent>
    </SelectEditor>
  );
}

Form Example

<ComponentSource name="select-editor-demo" /> </Steps>

Plugins

TagPlugin

Inline void element plugin for individual tag functionality.

MultiSelectPlugin

Extension of TagPlugin that constrains the editor to only contain tag elements, enabling multi-select behavior with automatic text cleanup and duplicate prevention.

API

tf.insert.tag

Inserts new multi-select element at current selection.

<API name="tf.insert.tag"> <APIParameters> <APIItem name="props" type="TTagProps"> Properties for multi-select element. </APIItem> </APIParameters> <APIOptions type="TTagProps"> <APIItem name="value" type="string"> Unique value of multi-select element. </APIItem> </APIOptions> </API>

getSelectedItems

Gets all tag items in the editor.

<API name="getSelectedItems"> <APIReturns type="TTagProps[]"> Array of tag items in editor. </APIReturns> </API>

isEqualTags

Utility function to compare two sets of tags for equality, ignoring order.

<API name="isEqualTags"> <APIParameters> <APIItem name="newTags" type="TTagProps[]" optional> New tags to compare against current editor tags. </APIItem> </APIParameters> <APIReturns type="boolean"> Whether both sets contain same values. </APIReturns> </API>

Hooks

useSelectedItems

Hook to get the currently selected tag items in the editor.

<API name="useSelectedItems"> <APIReturns type="TTagProps[]"> Array of selected tag items with values and properties. </APIReturns> </API>

useSelectableItems

Hook to get the available items that can be selected, filtered by search and excluding already selected items.

<API name="useSelectableItems"> <APIOptions type="options"> <APIItem name="allowNew" type="boolean" optional> Whether to allow creating new items. - **Default:** `true` </APIItem> <APIItem name="filter" type="(value: string, search: string) => boolean" optional> Custom filter function for items. </APIItem> <APIItem name="items" type="T[]" optional> Array of available items. </APIItem> <APIItem name="newItemFilter" type="(search: string) => boolean" optional> Filter function for new items. </APIItem> <APIItem name="newItemPosition" type="'end' | 'start'" optional> Position of new items in list. - **Default:** `'end'` </APIItem> </APIOptions> <APIReturns type="T[]"> Filtered array of selectable items. </APIReturns> </API>

useSelectEditorCombobox

Hook to handle combobox behavior in the editor, including text cleanup and item selection.

<API name="useSelectEditorCombobox"> <APIOptions type="options"> <APIItem name="open" type="boolean"> Whether combobox is open. </APIItem> <APIItem name="selectFirstItem" type="() => void"> Function to select first combobox item. </APIItem> <APIItem name="onValueChange" type="(items: TTagProps[]) => void" optional> Callback when selected items change. </APIItem> </APIOptions> </API>

Types

TTagElement

type TTagElement = TElement & {
  value: string;
  [key: string]: unknown;
};

TTagProps

type TTagProps = {
  value: string;
  [key: string]: unknown;
};
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•

← Root | ↑ Up