dify/web/docs/overlay.md

35 lines
2.7 KiB
Markdown

# Overlay Best Practices
Use `@langgenius/dify-ui/*` primitives for ordinary overlays in new and modified web code. Choose by interaction semantics, not visual shape. A feature may compose business content around a primitive, but it must not recreate generic portal, backdrop, positioning, focus, or z-index behavior.
## Primitive choice
- Use `Dialog` for modal surfaces that need focus containment, scroll locking, Escape handling, and outside-press dismissal.
- Use `AlertDialog` only when a destructive or must-confirm decision requires an explicit response.
- Use `Drawer` for side panels and setup or editor surfaces that follow the drawer interaction model.
- Use `DropdownMenu` for a button-triggered action list and `ContextMenu` for pointer-context actions.
- Choose `Select`, `Combobox`, or `Autocomplete` by the [Dify UI search and picker contract], not because each renders a popup.
- Use `Popover` or the web `Infotip` wrapper for explanatory content, long help text, rich layout, or interactive content.
- Use `Tooltip` only for a short, non-interactive visual label. Its trigger must already have an accessible name.
- Use `PreviewCard` only as a non-interactive visual preview of a link destination. Essential information must remain available without the preview.
## Composition
- Prefer the most specific semantic primitive over styling a generic `Dialog`.
- Use controlled `open` and `onOpenChange` when business state, analytics, or cleanup reacts to visibility; otherwise let the primitive own its state.
- For a button-like overlay trigger, keep the state-owning primitive outside and use its `render` prop to render the final `Button` or `IconButton`. Do not mirror open, pressed, or expanded state in the button.
- Use the primitive-owned content or portal part. Do not wrap a Dify UI overlay in another manual portal.
- Keep shared overlay chrome in Dify UI and feature-specific content in the feature owner.
## Feature-owned exception
The Step-by-step Tour coachmark is a deliberate feature-owned overlay because it targets arbitrary route content and owns spotlight geometry, pointer blockers, and target interaction policy. Its manual portal belongs to `web/app/components/step-by-step-tour/coachmark.tsx`; it is not a general overlay primitive or a pattern for ordinary dialogs and popovers.
## Layering
Body-portalled Dify UI overlays use `z-50`; Toast uses `z-60`. The app root keeps an isolated stacking context, and overlays at the same layer rely on DOM order.
Do not add call-site z-index overrides such as `z-9999`. If an overlay is clipped or hidden, fix the owning overlay structure instead of raising a child primitive.
[Dify UI search and picker contract]: ../../packages/dify-ui/README.md#search-and-picker-selection