@stesura/editor-react-ui
The UI primitives the editor’s own toolbar, menus and dialogs are built from. Use them in a UI extension so its controls match the built-in ones. The package also re-exports the base components (Button, DropdownMenu, Popover, Tooltip, Tabs with TabsList, TabsTrigger and TabsContent, …) and the icons. The hooks that drive these controls are in @stesura/editor-react.
Toolbar
Layout pieces for custom toolbar groups and tabs. See Create New Items.
Toolbar
The toolbar parts as one namespace: Toolbar.Content, Toolbar.Group, Toolbar.Divider, Toolbar.Wrapper.
ToolbarContent
The ribbon body: a horizontally scrolling role="toolbar" with roving
arrow-key focus across its items.
ToolbarGroup
A ribbon group: its items on top, the label underneath, and an optional
settings button (onExpand) beside the label, like Word’s dialog launchers.
| Name | Type | Default |
|---|---|---|
props | ToolbarGroupProps & RefAttributes<HTMLDivElement> |
ToolbarDivider
Vertical separator between toolbar groups.
| Name | Type | Default |
|---|---|---|
props | { height?: string; } & Omit<HTMLProps<HTMLDivElement>, "ref"> & RefAttributes<HTMLDivElement> |
ToolbarWrapper
Plain row of toolbar items, without the ribbon’s scroll area or roving focus.
| Name | Type | Default |
|---|---|---|
props | ToolbarWrapperProps & RefAttributes<HTMLDivElement> |
MenuDef
A dropdown’s contents as data (items), or a component that renders them (custom).
| Name | Type | Default |
|---|---|---|
kind | "custom" | "items" |
MenuItemDef
One entry of a MenuDef: an action, a checkbox, a separator or a submenu.
| Name | Type | Default |
|---|---|---|
kind | "action" | "separator" | "checkbox" | "submenu" | |
id | string |
ToolbarMenuContent
A dropdown’s content element with a MenuDef’s items in it. Place inside a DropdownMenu.
| Name | Type | Default |
|---|---|---|
__0 | ToolbarMenuProps |
ToolbarMenuItems
Renders a MenuDef’s items, for a dropdown whose content element you supply.
| Name | Type | Default |
|---|---|---|
__0 | { menu: MenuDef; depth?: number; } |
useRovingToolbar
WAI-ARIA roving tabindex for a toolbar: the whole container is one Tab stop and arrows move between every control inside it, across group boundaries.
Stops are discovered automatically, so a new control is keyboard-reachable by default instead of only when someone remembers to tag it. Text fields keep their arrows until the caret reaches an edge, then hand over.
| Name | Type | Default |
|---|---|---|
__0 | { orientation?: RovingOrientation; enterOnMount?: boolean; } |
{ containerRef: (node: HTMLDivElement | null) => void; handleKeyDown: (e: KeyboardEvent<HTMLDivElement>) => void; }Buttons
EditorButton
Small icon toolbar button with a tooltip, which also becomes its aria-label.
| Name | Type | Default |
|---|---|---|
props | OptimisticButtonProps & Omit<ButtonWithTooltipProps, "tooltipContent" | "tooltipShortcut"> & { tooltip?: string; tooltipContent?: string; tooltipShortcut?: string; } |
EditorButtonProps
Props of EditorButton. isActive renders it pressed; with optimistic (default) the pressed state flips on click, before the editor state catches up.
EditorButtonLarge
Tall ribbon button: icon on top, text label underneath, like Word’s large buttons.
| Name | Type | Default |
|---|---|---|
props | EditorButtonLargeProps |
EditorButtonLargeProps
The button is icon-only unless text is given, so one of the two naming
channels has to be present — a nameless variant is a type error, not a
runtime surprise.
EditorButtonLargeDropdown
EditorButtonLarge that opens a dropdown; buttonContent is the icon and children the menu content.
| Name | Type | Default |
|---|---|---|
props | EditorButtonLargeProps & { buttonContent: ReactNode; } |
EditorSplitButton
Split button: the primary half applies the action (onClick), the chevron
opens children as a dropdown. Arrow Down on either half opens it too.
| Name | Type | Default |
|---|---|---|
props | ButtonHTMLAttributes<HTMLButtonElement> & SplitButtonProps & OptimisticButtonProps & { ...; } |
EditorSplitButtonLarge
Tall split button, as Word’s Shading and Borders: the icon half applies the
action (onClick), the label half below opens children as a dropdown.
Arrow Down on the icon half opens it too. Same geometry as EditorButtonLarge.
Color picker
ColorPicker
Swatch grid with recent colors, a reset row and a fine picker behind “More”.
The host owns the recent list (recentColors, addRecentColor) and every
label.
| Name | Type | Default |
|---|---|---|
props | ColorPickerBaseProps & { options?: ColorPickerOptions; recentColors: string[]; addRecentColor: (color: string) => void; labels: ColorPickerLabels; theme?: ColorPickerTheme; } |
ColorPickerLabels
Every user-visible string the picker renders. This package carries no i18n dependency on purpose, so the whole set arrives from the consumer and a missing one is a type error rather than shipped English.
ColorPickerTheme
Word’s theme grid and Standard Colors, in place of the default palette.
currentRef selects by ref, so a themed value stays selected after a theme
switch changes its hex.
| Name | Type | Default |
|---|---|---|
swatches | readonly (readonly ThemeSwatch[])[] | |
currentRef | string | null | |
labels | ColorPickerThemeLabels |
ColorPickerThemeLabels
The theme section’s strings, from the consumer like the rest.
Dialogs
Use the parts as you would Dialog’s; on compact viewports the same tree renders as a bottom drawer.
ResponsiveDialog
Dialog on desktop, bottom drawer on compact viewports; its parts mirror Dialog’s one for one.
| Name | Type | Default |
|---|---|---|
__0 | ResponsiveDialogProps |
ResponsiveDialogTrigger
Opens the surrounding ResponsiveDialog.
| Name | Type | Default |
|---|---|---|
__0 | DialogTrigger.Props<unknown> & DrawerTrigger.Props<unknown> |
ResponsiveDialogContent
The dialog or drawer popup, with a close button labelled by closeLabel.
| Name | Type | Default |
|---|---|---|
__0 | ResponsiveDialogContentProps |
ResponsiveDialogHeader
Header block for the title.
| Name | Type | Default |
|---|---|---|
__0 | DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> |
ResponsiveDialogTitle
The dialog’s title, which also names it for assistive technology.
| Name | Type | Default |
|---|---|---|
__0 | DialogTitleProps & DrawerTitleProps |
ResponsiveDialogFooter
Footer row for the dialog’s actions.
| Name | Type | Default |
|---|---|---|
__0 | DialogFooterProps |
useIsCompactLayout
True on phone-sized viewports.
Every compact-layout decision in the editor reads this, so the breakpoint
lives in exactly one place. It sits in this package rather than
editor-react so ResponsiveDialog can share it without an illegal
dependency; editor-react re-exports it from its own hooks barrel.
Server renders and the first client paint report false (the wide layout);
it corrects on hydration.
Context menus
Items for a ContextMenuExtension element. See Customizing the Menus.
EditorContextMenu
Context-menu item with an optional leading icon and trailing shortcut hint, in the platform’s notation.
| Name | Type | Default |
|---|---|---|
props | { children: ReactNode; icon?: ReactNode; shortcut?: string; inset?: boolean; } & MenuItemProps |
Fields
UnitNumberField
The visual half of UnitNumberPicker: a unit-suffixed text input with a
preset dropdown, controlled by its TEXT rather than by a number.
Split out for forms that validate what the user typed — "", “abc”, a value past its bound — which a number-controlled field cannot express, since the value that would carry the error is the one that fails to parse.
| Name | Type | Default |
|---|---|---|
props | UnitNumberFieldProps |
UnitNumberPicker
A px-valued number input shown in the user’s display unit. Commits on Enter
and on picking a preset, always; on blur only after an edit, so tabbing
through doesn’t pin the shown (often inherited) value. Unparseable text
reverts on blur. null (mixed, or nothing to show) renders blank.
Forms that must SHOW why an entry is rejected use UnitNumberField
directly and own the text themselves — the value carrying the error is
exactly the one this component refuses to commit.
InfoTooltip
An info icon that shows children in a tooltip, for help text that would
otherwise sit under a label. Focusable, and the text is its accessible name,
so keyboard and screen-reader users get it without hovering.
| Name | Type | Default |
|---|---|---|
props | { children: string; className?: string; } |
Panels
useRowLeave
Fades a panel list row out and collapses it before it goes, as the checker panels’ Ignore does.
A list row that fades and collapses before it goes (panels.css,
stesura-panel-row-leave). leave() starts it and onLeft runs once at its
end: at once under reduced motion or when nothing animates (a hidden panel,
overridden CSS), and after a timeout if animationend never comes.
Put bind (a ref callback), className and onAnimationEnd on the row; give it a single child.
| Name | Type | Default |
|---|---|---|
onLeft | () => void |