Files
pbakaus_impeccable/tests/framework-fixtures/vite8-react-radix-dialog/files/src/App.jsx
T
Paul BakausandClaude Opus 4.7 630e586b01 feat(live): make picker chrome modal-host friendly (Radix, Headless UI, vaul)
Closes #113.

Picker chrome could become unclickable inside Radix Dialog portals, and
clicking it dismissed the host dialog. Three orthogonal issues surfaced
during manual verification:

1. Modal-aware chrome
   - Add `defangOutsideHandlers` and apply it to bar, picker, params
     panel, annotation overlay, global bar, and design panel host.
   - Sets `pointer-events: auto !important` on interactive chrome so
     Radix's `body { pointer-events: none }` modal scroll-lock can't
     silence our UI.
   - Stops `pointerdown` / `mousedown` / `focusin` propagation at the
     chrome boundary so DismissableLayer / FocusScope outside-handlers
     never fire for clicks that land on us.

2. detectPageTheme: misread transparent body as black
   - `getComputedStyle(body).backgroundColor` returns `rgba(0,0,0,0)`
     when no bg is set; the prior regex captured (0,0,0) and ignored
     alpha, calling every default-bg page "dark."
   - Honor alpha, walk body → html, fall back to
     `prefers-color-scheme` only when both are transparent.

3. Exit X invisible on host pages with `button { padding: ... }`
   - Every other chrome button sets padding inline; exitBtn didn't.
     Host resets like `button { padding: 0.5rem 1rem }` (in the new
     fixture, common in the wild) inflated the 24x24 button into 56x40
     and pushed the SVG into a non-rendering region — DevTools showed
     the right styles, the X just didn't paint.
   - Pin `padding: 0` + `box-sizing: border-box`, match the toggle
     icon spec (14 / stroke 1.5 / textDim → text on hover).

4. Toast no longer obscures the global bar
   - Position the toast above globalBarEl's actual rect instead of a
     fixed bottom: 16px that overlapped the bar's bottom: 14px.

Test coverage: new `vite8-react-radix-dialog` fixture exercises the
full pick → Go → cycle → Accept loop with `@radix-ui/react-dialog`
+ `Portal` + `Overlay` + `Content`. Without the fix, clicking Go
dismisses the dialog and unmounts the picked element. All 20 live
e2e fixtures pass; all 180 unit tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 16:22:00 -07:00

31 lines
1.1 KiB
React

import { useState } from 'react';
import * as DialogPrimitive from '@radix-ui/react-dialog';
export default function App() {
const [open, setOpen] = useState(false);
return (
<main className="page">
<DialogPrimitive.Root open={open} onOpenChange={setOpen}>
<DialogPrimitive.Trigger asChild>
<button data-testid="open-dialog" type="button">Open Dialog</button>
</DialogPrimitive.Trigger>
<DialogPrimitive.Portal>
<DialogPrimitive.Overlay className="dialog-overlay" />
<DialogPrimitive.Content className="dialog-content">
<aside className="lightbox">
<DialogPrimitive.Title asChild>
<h1 className="hero-title">Modal Heading</h1>
</DialogPrimitive.Title>
<p className="hero-hook">Inside a Radix DialogPrimitive.Portal.</p>
<button data-testid="close-dialog" type="button" onClick={() => setOpen(false)}>
Close
</button>
</aside>
</DialogPrimitive.Content>
</DialogPrimitive.Portal>
</DialogPrimitive.Root>
</main>
);
}