diff --git a/web/app/components/base/ui/alert-dialog/index.tsx b/web/app/components/base/ui/alert-dialog/index.tsx index 8d48c5b998..6c76e5ad12 100644 --- a/web/app/components/base/ui/alert-dialog/index.tsx +++ b/web/app/components/base/ui/alert-dialog/index.tsx @@ -6,13 +6,6 @@ import * as React from 'react' import Button from '@/app/components/base/button' import { cn } from '@/utils/classnames' -// z-index strategy (relies on root `isolation: isolate` in layout.tsx): -// All overlay primitives (Tooltip / Popover / Dropdown / Select / Dialog / AlertDialog) — z-50 -// Overlays share the same z-index; DOM order handles stacking when multiple are open. -// This ensures overlays inside an AlertDialog (e.g. a Tooltip on a dialog button) render -// above the dialog backdrop instead of being clipped by it. -// Toast — z-[99], always on top (defined in toast component) - export const AlertDialog = BaseAlertDialog.Root export const AlertDialogTrigger = BaseAlertDialog.Trigger export const AlertDialogTitle = BaseAlertDialog.Title @@ -39,7 +32,7 @@ export function AlertDialogContent({ = ({ + {/* TODO: reduce z-[1002] to match base/ui primitives after legacy overlay migration completes */} -
+
{t('onboarding.escTip.press', { ns: 'workflow' })} {t('onboarding.escTip.toDismiss', { ns: 'workflow' })} diff --git a/web/docs/overlay-migration.md b/web/docs/overlay-migration.md index 3c9da4f3fb..b3b1bd5738 100644 --- a/web/docs/overlay-migration.md +++ b/web/docs/overlay-migration.md @@ -53,6 +53,47 @@ pnpm -C web lint:fix --prune-suppressions - If a migrated file was in the allowlist, remove it from `web/eslint.constants.mjs` in the same PR. - Never increase allowlist scope to bypass new code. +## z-index strategy + +All new overlay primitives in `base/ui/` share a single z-index value: **`z-[1002]`**. + +### Why z-[1002]? + +During the migration period, legacy and new overlays coexist. Legacy overlays +portal to `document.body` with explicit z-index values: + +| Layer | z-index | Components | +|-------|---------|------------| +| Legacy Drawer | `z-[30]` | `base/drawer` | +| Legacy Modal | `z-[60]` | `base/modal` (default) | +| Legacy PortalToFollowElem callers | up to `z-[1001]` | various business components | +| **New UI primitives** | **`z-[1002]`** | `base/ui/*` (Popover, Dialog, Tooltip, etc.) | +| Legacy Modal (highPriority) | `z-[1100]` | `base/modal` (`highPriority={true}`) | +| Toast | `z-[9999]` | `base/toast` | + +`z-[1002]` sits above all common legacy overlays, so new primitives always +render on top without needing per-call-site z-index hacks. Among themselves, +new primitives share the same z-index and rely on **DOM order** for stacking +(later portal = on top). + +### Rules + +- **Do NOT add z-index overrides** (e.g. `className="z-[1003]"`) on new + `base/ui/*` components. If you find yourself needing one, the parent legacy + overlay should be migrated instead. +- When migrating a legacy overlay that has a high z-index, remove the z-index + entirely — the new primitive's default `z-[1002]` handles it. +- `portalToFollowElemContentClassName` with z-index values (e.g. `z-[1000]`) + should be deleted when the surrounding legacy container is migrated. + +### Post-migration cleanup + +Once all legacy overlays are removed: + +1. Reduce `z-[1002]` back to `z-50` across all `base/ui/` primitives. +1. Reduce Toast from `z-[9999]` to `z-[99]`. +1. Remove this section from the migration guide. + ## React Refresh policy for base UI primitives - We keep primitive aliases (for example `DropdownMenu = Menu.Root`) in the same module.