Doc Page

Patterns and Recipes

Reusable patterns for composing primitives into real product flows.

Updated: 2026-05-30 · Owner: docs@nake-ui

Composition Rule

Compose primitives by preserving each primitive's public contract. A recipe can add layout, data fetching, routing, animation, or product styling, but it should not remove required slots, break ARIA links, or hide state from DOM.

Good recipes look like production code with the contract still visible.

Sources: shared/en/patterns-recipes

Dialog From Menu

Pattern:

  1. Select a menu item.
  2. Close the active menu tree.
  3. Open a controlled dialog.
  4. Restore focus according to dialog lifecycle when the dialog closes.

Important details:

  • Menu item activation should close the active menu and open ancestors.
  • The Dialog state should be controlled by host code when opened from a menu.
  • Avoid nesting Dialog content inside Menu content if the Dialog is conceptually independent.

Sources: shared/en/patterns-recipes

Select Inside Popover

Pattern:

  1. Popover opens a lightweight editor.
  2. Select content may be portalled.
  3. Selecting an option closes Select.
  4. The Popover should not dismiss merely because Select content is outside the Popover DOM subtree.

Important details:

  • Keep aria-controls linkage intact between Select trigger and content.
  • Treat controlled portalled content as part of the active interaction boundary.
  • Same-value option activation should close Select without firing duplicate value-change semantics.

Sources: shared/en/patterns-recipes

Form-Compatible Select

Use Select when you need custom presentation plus form submission:

  • Render a hidden input.
  • Keep name, value, required, and disabled in sync.
  • Reflect invalid state on trigger with aria-invalid and data-invalid where applicable.
  • Use a visible label or aria-labelledby.

Do not use a custom Select when a native <select> is sufficient for the product need.

Sources: shared/en/patterns-recipes

Tooltip For Icon Buttons

Tooltip text should not be the only accessible name for an icon button. The trigger needs its own label:

<button aria-label="Archive" data-ui="tooltip" data-slot="trigger">...</button>

The tooltip can add aria-describedby, but it should not replace the button name.

Sources: shared/en/patterns-recipes

Recipe Checklist

  • Required slots remain present.
  • Public state remains reflected through ARIA and data-*.
  • Nested layers close in the correct order.
  • Portalled content keeps semantic ownership.
  • Form fields submit expected values.
  • Keyboard paths are tested before visual polish.

Sources: shared/en/patterns-recipes