name: rezi-modal-dialogs description: Add modal dialogs and overlay UI with focus trapping. Use when implementing confirmations, alerts, or layered interfaces. user-invocable: true allowed-tools: Read, Glob, Grep, Edit, Write argument-hint: "[modal-type]" metadata: short-description: Add modal dialogs
When to use
Use this skill when:
- Adding confirmation dialogs, alerts, or prompts
- Building layered/overlay UI
- Need focus trapping within a dialog
Source of truth
packages/core/src/widgets/useModalStack.ts—useModalStack()hookpackages/core/src/widgets/types.ts—ModalProps,LayersPropspackages/core/src/widgets/ui.ts—ui.modal(),ui.layers()packages/core/src/ui/recipes.ts—recipe.modal()andrecipe.surface()for design-system-consistent modal styling
Steps
Option A: useModalStack (recommended for multiple modals)
- Use
useModalStack()inside adefineWidget:const modals = useModalStack(ctx); // Push a modal modals.push("confirm", { title: "Confirm", content: body, onClose: () => modals.pop(), }); // Include in view return ui.layers([mainContent, ...modals.render()]);
Option B: ui.modal (simple single modal)
Use
ui.modal()directly with a state-controlled flag:return ui.layers([ mainContent, ...(state.showModal ? [ ui.modal({ id: "confirm-modal", title: "Confirm", initialFocus: "confirm-ok", returnFocusTo: "open-confirm", onClose: () => app.update((s) => ({ ...s, showModal: false })), content: ui.text("Are you sure?"), actions: [ ui.button({ id: "confirm-cancel", label: "Cancel", intent: "secondary", onPress: () => app.update((s) => ({ ...s, showModal: false })), }), ui.button({ id: "confirm-ok", label: "OK", intent: "primary", onPress: () => app.update((s) => ({ ...s, showModal: false })), }), ], }), ] : []), ]);Overlay ordering note:
- Modal, dropdown, and toast overlays share unified z-ordering through the LayerRegistry.
- Prefer
ui.layers([...])as the common overlay composition root.
Dialog action intent note:
- Use
intentto communicate action semantics in modal/dialog button rows. - Recommended mapping: confirm/continue ->
primary, cancel/back ->secondary, destructive ->danger, positive approval ->success, cautionary acknowledgment ->warning.
- Use
Verification
- Modal opens and closes correctly
- Focus traps within the modal (Tab doesn't escape)
- Focus returns to previous element on close