RichTextEditor
Frames rich text toolbar and editing compositions.
See it in context
Preview
v2.0 Release Notes
Draft release notes...
- Added new rich text toolbar
- Improved editor layout
Copy a working example
Usage
Astro examples assume UIPrimitives is mounted once in your root layout. Do not add the runtime next to each component instance.
---
import { Button, ButtonGroup, Icon, RichTextEditor } from '@santi020k/lumen-astro'
---
<RichTextEditor>
<div role="toolbar" aria-label="Editor toolbar">
<ButtonGroup>
<Button data-ui-editor-command="bold" type="button" variant="ghost" size="icon" aria-label="Bold">
<Icon name="bold" decorative />
</Button>
<Button data-ui-editor-command="italic" type="button" variant="ghost" size="icon" aria-label="Italic">
<Icon name="italic" decorative />
</Button>
<Button data-ui-editor-command="underline" type="button" variant="ghost" size="icon" aria-label="Underline">
<Icon name="underline" decorative />
</Button>
<Button data-ui-editor-command="strikeThrough" type="button" variant="ghost" size="icon" aria-label="Strike">
<!-- cspell:disable-next-line -->
<Icon name="strikethrough" decorative />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button data-ui-editor-command="insertUnorderedList" type="button" variant="ghost" size="icon" aria-label="Bullet List">
<Icon name="list" decorative />
</Button>
<Button data-ui-editor-command="insertOrderedList" type="button" variant="ghost" size="icon" aria-label="Numbered List">
<Icon name="list-ordered" decorative />
</Button>
</ButtonGroup>
</div>
<div contenteditable="true">
<h2>v2.0 Release Notes</h2>
<p>Draft release notes...</p>
<ul>
<li>Added new rich text toolbar</li>
<li>Improved editor layout</li>
</ul>
</div>
</RichTextEditor>---
import { Button, ButtonGroup, Icon, RichTextEditor } from '@santi020k/lumen-astro'
---
<RichTextEditor>
<div role="toolbar" aria-label="Editor toolbar">
<ButtonGroup>
<Button data-ui-editor-command="bold" type="button" variant="ghost" size="icon" aria-label="Bold">
<Icon name="bold" decorative />
</Button>
<Button data-ui-editor-command="italic" type="button" variant="ghost" size="icon" aria-label="Italic">
<Icon name="italic" decorative />
</Button>
<Button data-ui-editor-command="underline" type="button" variant="ghost" size="icon" aria-label="Underline">
<Icon name="underline" decorative />
</Button>
<Button data-ui-editor-command="strikeThrough" type="button" variant="ghost" size="icon" aria-label="Strike">
<!-- cspell:disable-next-line -->
<Icon name="strikethrough" decorative />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button data-ui-editor-command="insertUnorderedList" type="button" variant="ghost" size="icon" aria-label="Bullet List">
<Icon name="list" decorative />
</Button>
<Button data-ui-editor-command="insertOrderedList" type="button" variant="ghost" size="icon" aria-label="Numbered List">
<Icon name="list-ordered" decorative />
</Button>
</ButtonGroup>
</div>
<div contenteditable="true">
<h2>v2.0 Release Notes</h2>
<p>Draft release notes...</p>
<ul>
<li>Added new rich text toolbar</li>
<li>Improved editor layout</li>
</ul>
</div>
</RichTextEditor>import { Button, ButtonGroup, Icon, RichTextEditor } from '@santi020k/lumen-react'
export const Example = () => (
<>
<RichTextEditor>
<div role="toolbar" aria-label="Editor toolbar">
<ButtonGroup>
<Button data-ui-editor-command="bold" type="button" variant="ghost" size="icon" aria-label="Bold">
<Icon name="bold" decorative />
</Button>
<Button data-ui-editor-command="italic" type="button" variant="ghost" size="icon" aria-label="Italic">
<Icon name="italic" decorative />
</Button>
<Button data-ui-editor-command="underline" type="button" variant="ghost" size="icon" aria-label="Underline">
<Icon name="underline" decorative />
</Button>
<Button data-ui-editor-command="strikeThrough" type="button" variant="ghost" size="icon" aria-label="Strike">
<!-- cspell:disable-next-line -->
<Icon name="strikethrough" decorative />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button data-ui-editor-command="insertUnorderedList" type="button" variant="ghost" size="icon" aria-label="Bullet List">
<Icon name="list" decorative />
</Button>
<Button data-ui-editor-command="insertOrderedList" type="button" variant="ghost" size="icon" aria-label="Numbered List">
<Icon name="list-ordered" decorative />
</Button>
</ButtonGroup>
</div>
<div contenteditable="true">
<h2>v2.0 Release Notes</h2>
<p>Draft release notes...</p>
<ul>
<li>Added new rich text toolbar</li>
<li>Improved editor layout</li>
</ul>
</div>
</RichTextEditor>
</>
)import { Button, ButtonGroup, Icon, RichTextEditor } from '@santi020k/lumen-react'
export const Example = () => (
<>
<RichTextEditor>
<div role="toolbar" aria-label="Editor toolbar">
<ButtonGroup>
<Button data-ui-editor-command="bold" type="button" variant="ghost" size="icon" aria-label="Bold">
<Icon name="bold" decorative />
</Button>
<Button data-ui-editor-command="italic" type="button" variant="ghost" size="icon" aria-label="Italic">
<Icon name="italic" decorative />
</Button>
<Button data-ui-editor-command="underline" type="button" variant="ghost" size="icon" aria-label="Underline">
<Icon name="underline" decorative />
</Button>
<Button data-ui-editor-command="strikeThrough" type="button" variant="ghost" size="icon" aria-label="Strike">
<!-- cspell:disable-next-line -->
<Icon name="strikethrough" decorative />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button data-ui-editor-command="insertUnorderedList" type="button" variant="ghost" size="icon" aria-label="Bullet List">
<Icon name="list" decorative />
</Button>
<Button data-ui-editor-command="insertOrderedList" type="button" variant="ghost" size="icon" aria-label="Numbered List">
<Icon name="list-ordered" decorative />
</Button>
</ButtonGroup>
</div>
<div contenteditable="true">
<h2>v2.0 Release Notes</h2>
<p>Draft release notes...</p>
<ul>
<li>Added new rich text toolbar</li>
<li>Improved editor layout</li>
</ul>
</div>
</RichTextEditor>
</>
)<script type="module">
import { defineLumenElements } from '@santi020k/lumen-elements/define'
defineLumenElements()
</script>
<lumen-rich-text-editor>
<div role="toolbar" aria-label="Editor toolbar">
<lumen-button-group>
<lumen-button data-ui-editor-command="bold" type="button" variant="ghost" size="icon" aria-label="Bold">
<lumen-icon name="bold" decorative></lumen-icon>
</lumen-button>
<lumen-button data-ui-editor-command="italic" type="button" variant="ghost" size="icon" aria-label="Italic">
<lumen-icon name="italic" decorative></lumen-icon>
</lumen-button>
<lumen-button data-ui-editor-command="underline" type="button" variant="ghost" size="icon" aria-label="Underline">
<lumen-icon name="underline" decorative></lumen-icon>
</lumen-button>
<lumen-button data-ui-editor-command="strikeThrough" type="button" variant="ghost" size="icon" aria-label="Strike">
<!-- cspell:disable-next-line -->
<lumen-icon name="strikethrough" decorative></lumen-icon>
</lumen-button>
</lumen-button-group>
<lumen-button-group>
<lumen-button data-ui-editor-command="insertUnorderedList" type="button" variant="ghost" size="icon" aria-label="Bullet List">
<lumen-icon name="list" decorative></lumen-icon>
</lumen-button>
<lumen-button data-ui-editor-command="insertOrderedList" type="button" variant="ghost" size="icon" aria-label="Numbered List">
<lumen-icon name="list-ordered" decorative></lumen-icon>
</lumen-button>
</lumen-button-group>
</div>
<div contenteditable="true">
<h2>v2.0 Release Notes</h2>
<p>Draft release notes...</p>
<ul>
<li>Added new rich text toolbar</li>
<li>Improved editor layout</li>
</ul>
</div>
</lumen-rich-text-editor><script type="module">
import { defineLumenElements } from '@santi020k/lumen-elements/define'
defineLumenElements()
</script>
<lumen-rich-text-editor>
<div role="toolbar" aria-label="Editor toolbar">
<lumen-button-group>
<lumen-button data-ui-editor-command="bold" type="button" variant="ghost" size="icon" aria-label="Bold">
<lumen-icon name="bold" decorative></lumen-icon>
</lumen-button>
<lumen-button data-ui-editor-command="italic" type="button" variant="ghost" size="icon" aria-label="Italic">
<lumen-icon name="italic" decorative></lumen-icon>
</lumen-button>
<lumen-button data-ui-editor-command="underline" type="button" variant="ghost" size="icon" aria-label="Underline">
<lumen-icon name="underline" decorative></lumen-icon>
</lumen-button>
<lumen-button data-ui-editor-command="strikeThrough" type="button" variant="ghost" size="icon" aria-label="Strike">
<!-- cspell:disable-next-line -->
<lumen-icon name="strikethrough" decorative></lumen-icon>
</lumen-button>
</lumen-button-group>
<lumen-button-group>
<lumen-button data-ui-editor-command="insertUnorderedList" type="button" variant="ghost" size="icon" aria-label="Bullet List">
<lumen-icon name="list" decorative></lumen-icon>
</lumen-button>
<lumen-button data-ui-editor-command="insertOrderedList" type="button" variant="ghost" size="icon" aria-label="Numbered List">
<lumen-icon name="list-ordered" decorative></lumen-icon>
</lumen-button>
</lumen-button-group>
</div>
<div contenteditable="true">
<h2>v2.0 Release Notes</h2>
<p>Draft release notes...</p>
<ul>
<li>Added new rich text toolbar</li>
<li>Improved editor layout</li>
</ul>
</div>
</lumen-rich-text-editor>Choose your target
Add this component
Choose the package for your runtime. All adapters share the Lumen stylesheet. Use the matching registry command when you want a local wrapper for that framework.
pnpm add @santi020k/lumen-astropnpm add @santi020k/lumen-astrolumen add RichTextEditorlumen add RichTextEditorpnpm add @santi020k/lumen-reactpnpm add @santi020k/lumen-reactlumen add RichTextEditor --target reactlumen add RichTextEditor --target reactpnpm add @santi020k/lumen-elementspnpm add @santi020k/lumen-elementslumen add RichTextEditor --target elementslumen add RichTextEditor --target elementsGlass
Add the glass prop to apply the shared blur, saturation, border, and highlight tokens. Glass reads best over vivid content, so place the surface above imagery or color.
---
import { Button, ButtonGroup, Icon, RichTextEditor } from '@santi020k/lumen-astro'
---
<div class="docs-glass-demo">
<RichTextEditor glass>
<div role="toolbar" aria-label="Formatting">
<ButtonGroup>
<Button data-ui-editor-command="bold" type="button" variant="ghost" size="icon" aria-label="Bold">
<Icon name="bold" decorative />
</Button>
<Button data-ui-editor-command="italic" type="button" variant="ghost" size="icon" aria-label="Italic">
<Icon name="italic" decorative />
</Button>
<Button data-ui-editor-command="underline" type="button" variant="ghost" size="icon" aria-label="Underline">
<Icon name="underline" decorative />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button data-ui-editor-command="insertUnorderedList" type="button" variant="ghost" size="icon" aria-label="Bullet List">
<Icon name="list" decorative />
</Button>
</ButtonGroup>
</div>
<div contenteditable="true">Draft the glass release notes... the editing area stays translucent so the backdrop glows through.</div>
</RichTextEditor>
</div>---
import { Button, ButtonGroup, Icon, RichTextEditor } from '@santi020k/lumen-astro'
---
<div class="docs-glass-demo">
<RichTextEditor glass>
<div role="toolbar" aria-label="Formatting">
<ButtonGroup>
<Button data-ui-editor-command="bold" type="button" variant="ghost" size="icon" aria-label="Bold">
<Icon name="bold" decorative />
</Button>
<Button data-ui-editor-command="italic" type="button" variant="ghost" size="icon" aria-label="Italic">
<Icon name="italic" decorative />
</Button>
<Button data-ui-editor-command="underline" type="button" variant="ghost" size="icon" aria-label="Underline">
<Icon name="underline" decorative />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button data-ui-editor-command="insertUnorderedList" type="button" variant="ghost" size="icon" aria-label="Bullet List">
<Icon name="list" decorative />
</Button>
</ButtonGroup>
</div>
<div contenteditable="true">Draft the glass release notes... the editing area stays translucent so the backdrop glows through.</div>
</RichTextEditor>
</div>import { Button, ButtonGroup, Icon, RichTextEditor } from '@santi020k/lumen-react'
export const Example = () => (
<>
<div className="docs-glass-demo">
<RichTextEditor glass>
<div role="toolbar" aria-label="Formatting">
<ButtonGroup>
<Button data-ui-editor-command="bold" type="button" variant="ghost" size="icon" aria-label="Bold">
<Icon name="bold" decorative />
</Button>
<Button data-ui-editor-command="italic" type="button" variant="ghost" size="icon" aria-label="Italic">
<Icon name="italic" decorative />
</Button>
<Button data-ui-editor-command="underline" type="button" variant="ghost" size="icon" aria-label="Underline">
<Icon name="underline" decorative />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button data-ui-editor-command="insertUnorderedList" type="button" variant="ghost" size="icon" aria-label="Bullet List">
<Icon name="list" decorative />
</Button>
</ButtonGroup>
</div>
<div contenteditable="true">Draft the glass release notes... the editing area stays translucent so the backdrop glows through.</div>
</RichTextEditor>
</div>
</>
)import { Button, ButtonGroup, Icon, RichTextEditor } from '@santi020k/lumen-react'
export const Example = () => (
<>
<div className="docs-glass-demo">
<RichTextEditor glass>
<div role="toolbar" aria-label="Formatting">
<ButtonGroup>
<Button data-ui-editor-command="bold" type="button" variant="ghost" size="icon" aria-label="Bold">
<Icon name="bold" decorative />
</Button>
<Button data-ui-editor-command="italic" type="button" variant="ghost" size="icon" aria-label="Italic">
<Icon name="italic" decorative />
</Button>
<Button data-ui-editor-command="underline" type="button" variant="ghost" size="icon" aria-label="Underline">
<Icon name="underline" decorative />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button data-ui-editor-command="insertUnorderedList" type="button" variant="ghost" size="icon" aria-label="Bullet List">
<Icon name="list" decorative />
</Button>
</ButtonGroup>
</div>
<div contenteditable="true">Draft the glass release notes... the editing area stays translucent so the backdrop glows through.</div>
</RichTextEditor>
</div>
</>
)<script type="module">
import { defineLumenElements } from '@santi020k/lumen-elements/define'
defineLumenElements()
</script>
<div class="docs-glass-demo">
<lumen-rich-text-editor glass>
<div role="toolbar" aria-label="Formatting">
<lumen-button-group>
<lumen-button data-ui-editor-command="bold" type="button" variant="ghost" size="icon" aria-label="Bold">
<lumen-icon name="bold" decorative></lumen-icon>
</lumen-button>
<lumen-button data-ui-editor-command="italic" type="button" variant="ghost" size="icon" aria-label="Italic">
<lumen-icon name="italic" decorative></lumen-icon>
</lumen-button>
<lumen-button data-ui-editor-command="underline" type="button" variant="ghost" size="icon" aria-label="Underline">
<lumen-icon name="underline" decorative></lumen-icon>
</lumen-button>
</lumen-button-group>
<lumen-button-group>
<lumen-button data-ui-editor-command="insertUnorderedList" type="button" variant="ghost" size="icon" aria-label="Bullet List">
<lumen-icon name="list" decorative></lumen-icon>
</lumen-button>
</lumen-button-group>
</div>
<div contenteditable="true">Draft the glass release notes... the editing area stays translucent so the backdrop glows through.</div>
</lumen-rich-text-editor>
</div><script type="module">
import { defineLumenElements } from '@santi020k/lumen-elements/define'
defineLumenElements()
</script>
<div class="docs-glass-demo">
<lumen-rich-text-editor glass>
<div role="toolbar" aria-label="Formatting">
<lumen-button-group>
<lumen-button data-ui-editor-command="bold" type="button" variant="ghost" size="icon" aria-label="Bold">
<lumen-icon name="bold" decorative></lumen-icon>
</lumen-button>
<lumen-button data-ui-editor-command="italic" type="button" variant="ghost" size="icon" aria-label="Italic">
<lumen-icon name="italic" decorative></lumen-icon>
</lumen-button>
<lumen-button data-ui-editor-command="underline" type="button" variant="ghost" size="icon" aria-label="Underline">
<lumen-icon name="underline" decorative></lumen-icon>
</lumen-button>
</lumen-button-group>
<lumen-button-group>
<lumen-button data-ui-editor-command="insertUnorderedList" type="button" variant="ghost" size="icon" aria-label="Bullet List">
<lumen-icon name="list" decorative></lumen-icon>
</lumen-button>
</lumen-button-group>
</div>
<div contenteditable="true">Draft the glass release notes... the editing area stays translucent so the backdrop glows through.</div>
</lumen-rich-text-editor>
</div>API reference
Lumen-specific props and runtime attributes for the Astro primitive. React props follow the same names; Elements use equivalent kebab-case attributes where custom elements expose them.
| Attribute | Values | Default | Description |
|---|---|---|---|
| glass | boolean | "subtle" | "strong" | false | Applies the tokenized liquid-glass surface treatment with backdrop-filter fallbacks; "subtle" and "strong" adjust the fill intensity. |
| data-ui-editor-command | bold | italic | underline | insertUnorderedList | insertOrderedList | createLink | unlink | formatBlock | removeFormat | - | Marks toolbar controls that call document.execCommand(command) and emit ui:editor-command. |
| class, className | string | "" | Merges custom classes with the generated ui-* root classes. |
| ...native attributes | HTML attributes | - | Forwards standard attributes to the root element unless the component consumes them. |
Runtime events
CustomEvents dispatched by the Astro UIPrimitives runtime for this component.
| Event | Target | Detail | When |
|---|---|---|---|
| ui:editor-command | RichTextEditor root ([data-ui-rich-text-editor]) | { command: string } | Fires after a [data-ui-editor-command] control runs document.execCommand(command). |