Overview
BlockOptions is a controlled context menu that appears next to a block and exposes actions such as duplicate, copy link, delete, or custom actions like “Turn into”. It uses Floating UI for smart positioning, a built-in overlay + portal, and the compound component pattern so you can structure the menu exactly the way you want.

Features
- ✅ Controlled API — open/close the menu programmatically from anywhere
- ✅ Floating positioning — automatically positions relative to a reference element
- ✅ Overlay + Portal — handles focus trapping, scroll locking, dismiss on outside click
- ✅ Compound components — compose groups, buttons, separators however you like
- ✅ Helper actions — duplicate, copy block link, delete helpers included
- ✅ TypeScript-first — full typings for components and hooks
Installation
Basic Usage
Controlled Architecture
BlockOptions follows the two-hook pattern:
| Hook | Purpose | Use it when… |
|---|---|---|
useBlockOptions() | Full hook with Floating UI for the component that renders <BlockOptions.Root> | Rendering the menu |
useBlockOptionsActions() | Lightweight hook with only store actions + helpers | Opening/closing menu from other components |
API Reference
Components
BlockOptions.Root
Root container rendered inside a portal + overlay.
children: ReactNodeclassName?: stringstyle?: CSSPropertiesonClose?: () => void— called when clicking outside/overlay
BlockOptions.Group
Groups buttons together (stacks vertically).
children, className?
BlockOptions.Button
Action button.
onClick?: (event) => voidicon?: ReactNodevariant?: 'default' | 'destructive'disabled?: booleantitle?: stringclassName?: string- Inherits all native
<button>attributes (type="button"by default)
BlockOptions.Separator
Visual separator between groups.
className?
Hooks
useBlockOptions()
Full hook for the component that renders the menu.
| Property | Type | Description |
|---|---|---|
isOpen | boolean | Whether the menu is currently mounted (with transitions) |
getRootProps | () => RootProps | Props for <BlockOptions.Root> (floating ref, styles, event handlers) |
open | ({ reference, blockId }) => void | Open the menu with reference element + block ID |
close | () => void | Close the menu |
duplicateBlock | (blockId: string) => void | Helper action |
copyBlockLink | (blockId: string) => void | Helper action |
deleteBlock | (blockId: string) => void | Helper action |
useBlockOptionsActions()
Lightweight hook with store actions (no Floating UI).
Examples
1. Turn Into menu + ActionMenuList
2. Custom Actions Based on Block Type
3. Integrating with FloatingBlockActions
4. With Icons + Shortcuts
Styling
CSS Variables
Custom CSS Classes
Inline Styles / Tailwind
Accessibility
BlockOptions handles focus trapping via the overlay, but keep these in mind:- Use
titleoraria-labelon buttons for screen readers - Ensure destructive actions are clearly indicated (variant + icon + tooltip)
- Keyboard users can reach buttons via Tab because buttons use
type="button"
Best Practices
Always pass blockId when opening
Always pass blockId when opening
Freeze FloatingBlockActions while menu is open
Freeze FloatingBlockActions while menu is open
Use destructive variant for dangerous actions
Use destructive variant for dangerous actions
Close menu after action completes
Close menu after action completes