kerfjs 5.0.0-beta.105 → 5.0.0-beta.107

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -8,9 +8,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
8
8
 
9
9
  ### Added
10
10
 
11
+ - **`KUI-L204`: inset-bearing children inside an embedded `Disclosure`.** `kerf-ui-doctor` (through `eslint-plugin-kerfjs`'s `ui-composition` rule) now reports a block `Text`, or any other child whose catalog geometry owns its margin, border, and padding, written directly inside `Disclosure appearance="embedded"`, where it re-adds the 1px border and 8px padding the owner chrome already provides; the message names `Text flush` / `variant="span"` or inline content as the fix. The check is catalog-driven: composition entries declare `insetFreeChildren` (prop conditions under which direct children must be inset-free) and `insetFreeWhen` (a child's inset-free forms), so a third-party catalog can declare the same contract (`KF-E8PGDQ`).
12
+ - **Inset-free metadata in `create-kerf-component`.** A component package's `kerf.components.json` can now declare `composition.insetFreeChildren` (prop conditions under which a container's direct children must bring no content-item inset) and `composition.insetFreeWhen` (a component's own inset-free forms). `kerf-component-catalog` validates each `{ prop, equals }` condition at its exact metadata path, accepting the same shapes as `@kerfjs/ui`'s catalog validator, and copies both fields into the generated `component-composition.json`, so `kerf-ui-doctor` reports `KUI-L204` for a package-declared inset-free container (`KF-3CCTAQ`).
13
+ - **`Button` `fill`.** `fill` spans a Button across its parent's available inline width instead of sizing it to its label, for a full-width primary action in a form, sheet, or narrow column; it is the same `fill` `SplitButton` takes. The icon and label stay centered as one group, the label ellipsizes once the column is narrower than it, a link Button (`href`) fills the same way, and the default outside focus ring and `focusRingInset` keep their geometry. `data-fill` is protected from `rootAttributes`. The catalog's Button demo and design template show a Full-Width Primary Action (`KF-FXKCHW`).
14
+ - **`Disclosure` `appearance="embedded"`.** A Disclosure inside a `ContentItem` (or other chrome that already owns the content-item inset) no longer frames its content twice: `embedded` drops the Disclosure's own 8px inline margin, 1px border, and 8px summary padding, so the summary row and its `DisclosureArrow` sit on the item's content inset, and the summary becomes a compact 24px-minimum row without a hover fill. The native `<details>` state, Enter/Space toggling, and the arrow's rotation are unchanged; the content (a `flush` `Text`) starts on the title's text column 8px below the summary. The UX catalog shows it in a framed ContentItem (`KF-2JTH1A`).
15
+ - **`ListHeader` `wrap`.** A `ListHeader` label is one ellipsized line by default; `wrap` breaks it onto further lines instead, for a heading whose whole label must stay readable in a narrow column. Wrapped lines keep a 4px block inset inside the unchanged minimum height, and `data-wrap` is protected from `rootAttributes` (`KF-12WBGR`).
16
+ - **`openPopupMenuAt` placement.** `openPopupMenuAt(menu, x, y, { placement })` takes an optional `PopupMenuPlacement` for that opening, so a button-triggered menu (a `ListActionRow` trailing menu opened from the row's `contextmenu`) can open `top-start` above the pointer instead of `bottom-start` below it; the viewport flip, shift, and height cap still apply, and the next opening returns to its trigger and its own placement. Omitted, nothing changes: a button-triggered menu opens `bottom-start` at the point and a context menu at its `placement` (`KF-QGT77X`).
17
+ - **`Button` and `SplitButton` `focusRingInset`.** Inside an ancestor that clips overflow, `focusRingInset` draws the focus ring inside the box (each half's, on a SplitButton) instead of 1px outside it, the same option `Select` takes. The inset ring is two-tone, a 3px surface-colored line inside the ring color, so it keeps 3:1 contrast on a loud fill of its own hue (a single-color inset ring measured 1.0:1 on the brand fill); `data-focus-ring-inset` is protected from `rootAttributes`. The default outside ring is unchanged (`KF-BZE90H`). The line paints the surface the control sits on, through a new foundation surface context (`--kui-color-surface-current`, `--kui-color-surface-current-region`, `--kui-color-surface-current-tint`) that `SunkenPanel`, sunken `Disclosure`, `FramedList`, quiet `ContentItem`s, `List` `surface`, `AnchoredSurface`, dialogs, and sunken `Pane`/`Workbench`/`TabNavigator` regions publish on their own elements, so on a lowered or tinted surface it no longer reads as a light halo (`KF-40SSN2`).
18
+ - **Dialog accessible descriptions.** `DialogSurface` takes an optional `describedBy` id, rendered as `aria-describedby` on its native `<dialog>`, so a modal dialog can name its heading `ToolbarText`'s `descriptionId` or app-owned summary copy in its body as its accessible description; `rootAttributes` still takes only `data-*` attributes and cannot set it. `WorkbenchDialog` now describes itself by its title `description` automatically (id `<id>-description`) and takes `describedBy` for other content; `ListDetailDialog` takes `describedBy` (its detail description describes the selection, not the dialog). The catalog's Viewport-Bounded Modal and Floating Title Bar dialogs demonstrate it (`KF-JNV47V`).
19
+ - **`CheckboxGroup` in `@kerfjs/ui`.** `@kerfjs/ui/checkbox-group` puts a labeled set of related options in a native fieldset of `Checkbox`es: a `choices` array with per-choice hints and disabled choices, an array `value` of checked values that all submit under `name`, a group `hint` and `error` (marking the group invalid), `default` or `compact` size, and a stacked or wrapping horizontal `orientation`. It is named by `label`, `ariaLabel`, or `labelledBy` and laid out exactly like `RadioGroup`: each box on the inline-start edge, choices at the shared 28px pitch, hints on the label column. `wa-checkbox-group` now points to it (`KF-JJ80V3`).
20
+ - **`SplitButton` `shape`.** `shape="pill"` fully rounds both outer ends of a SplitButton, the same `rounded` (default) or `pill` choice `Button` takes; the divider between the halves stays square, and each half's hover fill and focus ring follow its rounded end (`KF-4GC1J4`).
11
21
  - **`wirePaneChrome`.** `@kerfjs/ui/wire-pane-chrome` makes a Pane's open `overlay` compact chrome transient: Escape or a press outside it closes it through the app's `compactChromeOpen` signals, and focus returns to the control that opened it (`KF-EEGAT7`).
12
22
  - **ChoiceChips icon picker.** `presentation="icons"` renders square 36px icon-only choices, each named by its label (hidden, and its hover title), and `maxHeight` scrolls a long grid, with native radio (or toggle, or listbox) semantics unchanged (`KF-K60RRM`).
13
- - **`Pane` `compactChrome`.** A Pane declares what its header and footer do when its container presents compactly: `fixed` (default), `scroll` (inline with the content; a footer settles at the end and scrolls past long content), or `overlay` (over the content on the chrome material, shown while the app's `compactChromeOpen` says so). NavStack views, TabNavigator scenes, full-screen dialogs, and compact Workbenches apply it; roomy containers ignore it. `PaneConfig` forwards both props (`KF-Q8EMWE`).
23
+ - **`Pane` `compactChrome`.** A Pane declares what its header and footer do when its container presents compactly: `fixed` (default), `scroll` (inline with the content; a footer settles at the end and scrolls past long content), or `overlay` (over the content on the chrome material, shown while the app's `compactChromeOpen` says so). NavStack views, TabNavigator scenes, full-screen dialogs, and compact Workbenches apply it; roomy containers ignore it. `PaneConfig` forwards both props (`KF-Q8EMWE`). The UX catalog's NavStack Compact Chrome example now pushes a message thread from each row, whose own Pane scrolls its sender line away and keeps its reply hint fixed, so the policy visibly applies per view as the stack pushes and pops (`KF-C891G3`).
14
24
  - **Vertical `Slider`.** `orientation="vertical"` stands a Slider up with its minimum at the bottom, `length` tall (default 160px), drawn the same in Chromium, Firefox, and WebKit; the AnchoredSurface media volume popup is vertical again (`KF-SVDPSR`).
15
25
  - **`FileDropZone` `dropScope`.** A selector for an enclosing element (an attachments panel) that also takes drops: `wireFilePickers` highlights the zone while files are dragged over any part of it and reports drops there for the zone with `via: 'drop'`, so an app no longer writes the zone's `data-dragging` itself (`KF-HNRWM9`).
16
26
  - **`PopupMenu` `triggerContent`.** App content, such as a `Badge` showing a status, can be the whole trigger: Kerf owns the bare button around it (no chrome, a pill focus ring, the pointer cursor, `aria-haspopup`), `label` names it, the caret is off by default, and no help tag repeats the name. Submenus and checked choices work as on any PopupMenu (`KF-PHGQ6D`).
@@ -85,6 +95,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
85
95
 
86
96
  ### Changed
87
97
 
98
+ - **A `Switch` hint sits directly under its label.** The `Switch` hint no longer leaves a 7px gap below the switch row; it sits flush under it on the label's column, the same offset as a `Checkbox` hint or a grouped choice hint, so every toggle control reads alike (`KF-YG5CM2`).
99
+ - **A standalone `Checkbox` hint sits directly under its label.** `Checkbox` hint and error text no longer leave a 7px gap below the label row; they sit flush under it, exactly as a `CheckboxGroup` or `RadioGroup` choice hint does, so a lone Checkbox and a grouped choice read the same (`KF-X8F2K5`).
100
+ - **`ColorPicker` hue track is a fixed rainbow.** In HSL and HSB the hue slider now always paints the full-saturation, full-brightness rainbow instead of the hues at the current saturation and brightness, so a dark or nearly gray color still shows which hue each position picks. Its thumb still shows the current color, every other channel and the opacity track keep their live preview, and the rainbow follows the writing direction like every other track (`KF-2AX5T7`).
101
+ - **Stacked checkboxes and radio choices share one 28px pitch.** `RadioGroup` choices now stack 8px apart (`--kui-space-xs`) instead of 12px, the same 20px-control-plus-8px pitch as standalone `Checkbox`es in a `List gap="xs"`, which the guidance now names as the way to stack them; horizontal groups keep their 24px column gap. This deliberately departs from Web Awesome's radio spacing, so the `@kerfjs/ui/webawesome.css` theme gives stacked `wa-radio`s `0.25em` block margins (the first and last stay flush) and a Web Awesome Radio Group keeps matching Kerf (`KF-9R49CW`).
102
+ - **`ColorPicker` sliders follow the color model.** RGB shows red, green, and blue sliders; HSL hue, saturation, and lightness; HSB hue, saturation, and brightness; Grayscale one gray-level slider; each with the opacity slider when `alpha` is on, and each track previews the colors its channel produces while the others hold. The saturation and brightness area stays in every model. Sliders are named for their channel with unit value text (`210°`, `40%`), and a channel edit keeps every other channel exact, so switching models and editing round-trips without drift (an HSL saturation survives black or white). The fixed `kui-color-picker__hue` class gives way to `kui-color-picker__sliders` and `kui-color-picker__slider`; `COLOR_PICKER_CHANNELS` entries gain `unit`, and `colorPickerSlider()` exposes a slider's state (`KF-ZNKCWX`).
88
103
  - `@kerfjs/ui` marks two more Web Awesome elements `Discouraged`, for 36 in total; the profile defaults avoid both, so `KUI-L301` reports them. `wa-include` injects fetched markup outside kerf's `SafeHtml` escaping; fetch with `resource()` from `kerfjs/async` and render Kerf content instead. `wa-scroller` gives way to a `Pane`'s scroll edges or `ColumnTrack` (`KF-F5MPVE`).
89
104
  - **Breaking: one `Button` replaces `IconButton` and `IconToggleButton` in `@kerfjs/ui`.** `Button` gains `shape` (`rounded` by default, or `pill`) and `pressed`, which makes any Button a toggle: `aria-pressed` reports the state, and a pressed look draws on top of its tone and emphasis (secondary and plain take the quiet tone fill with a doubled outline; primary darkens with an inset ring). An icon-only button is a `Button` with an `icon` and an `ariaLabel` and no label, and help tags now name it on hover and focus. `IconButton`, `IconToggleButton`, and their subpaths and stylesheets are removed with no aliases; migrate `IconButton({ icon, iconName, label })` to `Button({ icon: <LucideIcon …/>, ariaLabel })`, and `IconToggleButton` to that plus `pressed` (and `shape="pill"` for its former default shape). `kerf-ui-doctor` now checks an icon-only Button's `ariaLabel` capitalization (`KF-TQCJSS`).
90
105
  - **Breaking: `Composer` is now `MessageComposer` in `@kerfjs/ui`, and its action row is a `Toolbar`.** The new name says what it is: a composer for messages, prompts, and replies. There are no compatibility aliases: `MessageComposer`, `MessageComposerProps`, `wireMessageComposers`, `@kerfjs/ui/message-composer` (and `.css`), `@kerfjs/ui/wire-message-composers`, and `kui-message-composer*`; the catalog id is `message-composer`. The row below the field is now a compact `Toolbar` footer named "<label> Actions", so every toolbar convention applies: control groups and responsive relocation. A new `leading` prop holds controls such as an attach button or a model `Select`, and the `actions` prop is now `trailing` (`KF-ANFPGA`).
@@ -126,6 +141,35 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
126
141
 
127
142
  ### Fixed
128
143
 
144
+ - **Web Awesome Carousel specimens show full slides in Firefox.** A `wa-carousel`'s scroll container is a `grid-auto-columns: 100%` track under an aspect ratio, so it has no definite intrinsic width. In the catalog's shrink-to-fit specimen column Chromium and WebKit resolved it from the aspect ratio (a 457px carousel at 1100px), but Firefox sized it to the first slide's text: a 191px carousel with a 103×34px track that clipped "Foundation" and "Focused carousel item" at every width. The Carousel and Carousel Item specimens now take the medium width tier, as the Zoomable Frame specimen does, so every engine renders the same full slides. A three-engine check asserts the track holds the whole slide at 1100px and 320px (`KF-0TGNQG`).
145
+ - **Web Awesome OTP Input cells render whole.** Upstream caps the OTP Input's segments box, which reserves its focus-ring bleed with 4px padding and an equal negative margin, at 100% of the host. In a shrink-to-fit host (the catalog's start-aligned example grid, any start-aligned grid or flex item) the host is only the cells' width minus that bleed, so the padded box was 8px too narrow and silently clipped the last cell's inline-end edge inside its scroll container at every width. `@kerfjs/ui/webawesome.css` caps it at the host's width plus the bleed its negative margins reserve: a host narrower than the code still scrolls, and the `contained` appearance keeps upstream's cap. The catalog's phone-width check now measures the cells inside the shadow root (`KF-SPEQPY`).
146
+ - **Row and Grid catalog specimens fit a 320px phone.** The Row catalog's vertical-alignment rows now `wrap`, so the Baseline Alignment row's taller chips move the third chip to a second line instead of running 13px past the example. The Grid catalog's Four Columns example shows short quarter tiles (`Q1` … `Q4 est.`) that fit a phone-width track instead of process-stage words that ran past their own tiles and up to 11px past the example; its note now says a fixed count suits short content and points longer labels at `minColumnWidth`. Both catalogs join the phone-width overrun check (`KF-37ERTC`).
147
+ - **Catalog labels and specimens fit a 320px phone.** A `CatalogExample` label is a content-width `ListHeader`, and its single unbreakable line set the header's minimum width, so about twenty long labels ("Sunken Workbench Regions Without Pane Chrome", "Accessible Name Without a Visible Label", …) ran past the example and were cut off at the stage edge instead of truncating. The label now wraps through the new `ListHeader` `wrap`. The Web Awesome OTP Input specimen uses the small size, whose six grouped cells fit the 280px specimen column (the default size needs 292px), and the ListHeader catalog's inline-header row wraps its trailing status instead of running 16px past the example (`KF-12WBGR`).
148
+ - **Aligned `CatalogExample` specimens no longer run past the example's end edge.** An aligned example (`align="glyph"`, `"inline-control"`, or `"text-trigger"`) inset each specimen with a start margin, so a full-width specimen — the SearchField catalog's Disabled field, the Select catalog's fill-width Visible Label select, the SegmentedControl catalog's control-width Rounded Rectangle frame — kept its full width and ran 8px past the example at every stage width. The inset is now the example's own grid column: the label and note span the full width and every specimen sits in the inset column, so a percentage width resolves against that column and ends on the example's edge, while specimens keep their own width caps. A page-fixed specimen (the EdgeActivityIndicator strip) no longer picks up the inset either (`KF-EE4WEN`).
149
+ - **`ColorPicker` dark design templates draw a solid opacity track end.** The templates' opacity-track stand-in drew its translucent dark checker squares straight onto the template's transparent background, so in the dark templates they took on the viewer's backdrop and showed through the track's opaque end. The checkerboard now sits on an opaque surface underlay, like the component's own, and fades out toward full opacity in light and dark alike (`KF-MV5GE6`).
150
+ - **`ColorPicker` area edge and thumb outline.** The saturation and brightness area had no boundary, so its black bottom vanished into a dark surface and its white corner into a light one; it now draws the same 1px inner edge as the slider tracks (halfway to the text color, the full text color under increased contrast, `CanvasText` in forced colors). Every thumb's outline outside its white border is now dark enough (60% black, was 20–30%) that a light thumb over a light area or track keeps at least 3:1 against it, while the white border holds against dark colors (`KF-F4J2GD`).
151
+ - **The Web Awesome Known Date and Slider catalog specimens have a field width.** Both size to their container, so in the shrink-to-fit specimen column Known Date measured 0px wide (its segments stacked and its hint wrapped a word per line) and Slider about 90px. The catalog now gives Known Date a compact field column and Slider the Kerf Slider demo's medium width, and the Slider specimen takes the field demos' `inline-control` alignment so its label and track land on the Kerf Slider's column. The theme contract notes that both need a width from their container (`KF-ZVA2S2`).
152
+ - **The Web Awesome Progress Bar, Skeleton, and Zoomable Frame catalog specimens no longer collapse.** They also size to their container, so the specimen column shrank Progress Bar to a 30px stub, Skeleton to 0px, and Zoomable Frame to an empty 16px panel. The catalog now gives Progress Bar the Kerf ProgressBar demo's medium width, Skeleton a compact text column, and Zoomable Frame a medium media frame (`KF-J214TZ`).
153
+ - **`wa-tag-input` follows the Web Awesome field theme.** `@kerfjs/ui/webawesome.css` now gives a raw `wa-tag-input` the same treatment as the other bordered fields: its label is uppercase on the 9px text column, its hint shares that column, its box takes Kerf's 44px control height (2.75em), its border sits on the host's inline-start edge, and a small one keeps a 16px editable text size on coarse touch devices. It stays Discouraged in favor of `TagField`; the catalog specimen now uses the field demos' `inline-control` alignment (`KF-S5XTY4`).
154
+ - **`kerf-ui-doctor` reads raw `wa-checkbox-group` labels.** `KUI-D040`'s title-style check already read `CheckboxGroup` and raw `wa-radio-group` labels; the `label` of a raw `wa-checkbox-group` is now read the same way, while `wa-checkbox` option text stays sentence style and unread (`KF-ZJ28W4`).
155
+ - **Every Kerf field demo shares one border and label column.** The UX catalog's ColorField, TagField, and Slider specimens now use `align="inline-control"` like the TextField, Select, Switch, Checkbox, RadioGroup, and CheckboxGroup demos, so field borders and label text line up across the catalog instead of sitting 8px apart. A `CatalogExample` `viewport` that is aligned now takes that offset out of its width, so a full-width specimen frame no longer runs 8px past the example's inline-end edge at narrow widths (`KF-ZPDYQW`).
156
+ - **The ColorSwatches catalog demo joins the field column.** ColorSwatches is a field — a person picks a value with it inline — so its specimens now use `align="inline-control"` and its legend text lands on the field label column with the other form fields. ColorPicker and FilePicker are panels (a multi-part picker and a drop zone) and stay flush; `ui/docs/catalog.md` now states the field-versus-panel rule (`KF-8YAGME`).
157
+ - **Width-sized catalog specimens join the field column.** The ProgressBar demo, the group-title `Text` specimen, the Grid and saved-view SearchField field compositions, and the Web Awesome Progress Bar, Skeleton, and Pagination specimens sat flush at the example's edge, so a bar's "Uploading Files" label started 8px left of the example label and note text. They now use `align="inline-control"` like the form fields, and their sized frames still end at the example's inline-end edge. Panels (ColorPicker, FilePicker, Zoomable Frame) and edge-to-edge compositions stay flush; `ui/docs/catalog.md` states the rule (`KF-WH27TY`).
158
+ - **Web Awesome control and text specimens align like their Kerf counterparts.** The catalog's Web Awesome Button, Button Group, Dropdown, Dropdown Item, Tab family, Badge, Tag, Avatar, Progress Ring, Toast, Toast Item, Animation, observer, and dialog/drawer/popover/tooltip trigger specimens sat flush at the example's edge while the Kerf Button demo puts its control box on the 8px column; they now use `align="inline-control"`. Specimens led by bare text or a glyph (Copy Button, Breadcrumb, Divider, Markdown, Relative Time, Pagination's summary, Stepper and Step, Spinner, Icon) now use `align="glyph"`, so their text sits on the text column as Kerf's flush Text demo does instead of at x=0. The CornerStatus "Embedded" example's banners now sit on the same 8px column as the standalone StateBanner demos. Panels and framed media (Page, Split Panel, Popup, Zoomable Frame, QR Code, Animated Image, Carousel) keep their own geometry (`KF-44TDSF`).
159
+ - **A tall `PopupMenu` or `Select` popup never covers its trigger.** When a popup fit on neither side of its trigger (a toolbar overflow menu at 1024×600), it was shifted across the trigger to stay in the viewport, so a second press on the trigger landed on a row instead of closing the popup. The shared popup placement now shifts only along the trigger's edge: when neither side fits, the popup opens on the side with more room and scrolls inside its capped height. `PopupMenu` menus, `Select` and `Combobox` listboxes, and help tags all share it (`KF-F22WMW`).
160
+ - **A context `PopupMenu` honors its `placement`.** A `context` menu always opened `bottom-start` at its anchor point whatever `placement` it was rendered with, so a menu anchored to a footer or composer could not open above the point. Its placement now applies at the point (`top-start` opens above it, `top-end` above it at its end), with the same viewport flip, shift, and height cap; a button-triggered menu opened at a pointer with `openPopupMenuAt` still opens `bottom-start` from the point for that opening (`KF-MXM1SH`).
161
+ - **A group-owned `Select` draws one focus ring.** A `Select` with `focusRingOwner="group"` inside a `ToolbarControlGroup` that draws the pill ring still painted its own trigger outline on focus, because the trigger's focus rule outranked the owner rule, so keyboard focus showed two rings. The trigger's focus ring now applies only when the Select owns it; a select-owned trigger and a per-control-ring group are unchanged (`KF-GWSEWC`).
162
+ - **`ColorPicker` slider tracks follow the writing direction.** In right-to-left text a native range runs right to left, but every channel and opacity track still painted its gradient left to right, so the thumb at a channel's minimum sat over the color of its maximum. Each track now runs in the writing direction (`to left` under `:dir(rtl)`), and a browser test checks that the thumb at the minimum sits over the gradient's start in both directions (`KF-KKMMJV`).
163
+ - **`ColorPicker` slider tracks keep their edge on a matching surface.** A dark track (a hue at low brightness, a faint opacity) used to vanish into a dark surface, and a light one into a light surface, because each drew only a faint black inner line. Every track now draws a 1px inner edge halfway to the text color, at least 3:1 against the surrounding surface in light and dark; increased contrast draws it in the full text color and forced colors in `CanvasText` (`KF-JN1ZH6`).
164
+ - **`kerf-ui-doctor` no longer reports a false `KUI-L203` for every `MessageComposer`.** The shipped composition catalog still declared the removed `actions` zone; it now declares a required `trailing` zone and an optional `leading` zone, and a test keeps every component's composition zones aligned with its real props (`KF-Z00DKT`).
165
+ - **`SplitButton` focus ring is visible on every tone.** Each half drew its keyboard focus ring inside its loud fill, where it all but vanished on the brand fill in light mode and matched the brand fill exactly in dark mode. The ring now sits outside the focused half, offset 1px like `Button`'s, so it is drawn against the surrounding surface on every tone and in both schemes (`KF-V0HSNG`).
166
+ - **`RadioGroup` circles line up with Checkbox boxes.** Each radio circle now sits on the group's inline-start edge, where a `Checkbox` draws its box, instead of 8px further in, so stacked checkboxes and radios share one control column; the group label and hint keep the text column (`KF-F68AZ9`).
167
+ - **Web Awesome Checkbox Group and Radio Group follow the same control column.** The `@kerfjs/ui/webawesome.css` theme no longer insets a `wa-checkbox-group` or `wa-radio-group` option region by 8px, so each box or circle sits on the group's inline-start edge like Kerf's `Checkbox` and `RadioGroup`, and both groups' hints now join their label on the 9px text column. The unbordered Color Picker trigger keeps its 8px inset (`KF-2X0Z47`).
168
+ - **Web Awesome fields, Switch, and Color Picker share Kerf's field columns.** The `@kerfjs/ui/webawesome.css` theme no longer insets the `wa-color-picker` swatch trigger by 8px, so it sits on the host's inline-start edge like a Kerf `ColorField` trigger, with its label on the 9px text column. The guidance now states the placement rule for every themed field: a bordered `wa-input`, `wa-select`, `wa-textarea`, `wa-number-input`, `wa-time-input`, `wa-known-date`, or `wa-otp-input`, and a `wa-switch` track, start on the host edge exactly where Kerf's `TextField`, `Select`, and `Switch` draw theirs, so place a Web Awesome field where the Kerf field would go. The catalog's field specimens now use the Kerf field demos' alignment, so their borders, labels, and hints land on the same columns in every engine (`KF-6SM43M`).
169
+ - **`NavStack` overlay chrome keeps its material during a push or pop.** The overlay top chrome and bottom toolbar used to fade as a whole while their contents cross-faded, which faded the backdrop blur with them (Safari dropped it outright), so the sliding views showed through the bars mid-transition. Now the live bar keeps the material at full opacity while its new contents fade in, and the copy fading out above it carries only the old contents (`KF-H3NNP6`).
170
+ - **Anchored surfaces follow an anchor that changes size.** `autoReposition()` (and so `popover()`, `tooltip()`, and `AnchoredSurface`) also repositions when the anchor itself resizes, where `ResizeObserver` exists, not only on scroll and resize, so a surface below a field moves down as the field grows a line. The UX catalog's Structured Ticket Search help now anchors to the whole SearchField instead of its help button, so at phone width it no longer covers the field's wrapped second line, and typing in the field leaves it open (`KF-37TGXB`).
171
+ - **Anchored surfaces follow their own size changes.** `autoReposition()` (and so `popover()`, `tooltip()`, and `AnchoredSurface`) also repositions when the positioned element itself resizes, where `ResizeObserver` exists, so an end-aligned surface that grows wider keeps its right edge on the anchor's, and an above-placed one that grows taller keeps hanging just above the anchor instead of growing over it until the next scroll. A resize that the positioning's own writes caused is not acted on again, so repositioning never feeds itself (`KF-S92WX8`).
172
+ - **A scrolled `fitHeight` surface keeps its scroll position in Safari.** To honor the element's own `max-height`, `positionAnchored()` briefly lifts the room it published around a style read. WebKit lays the element out for that read when a size container sits inside it (a `Toolbar`, a `ValueTable`), and the uncapped layout clamped the element back to its top; every scroll inside it repositions it, so wheel scrolling an `AnchoredSurface` jumped back to the first row. The element's current height is now pinned for the read, and a scroll position the read still moves is put back (`KF-PVBPJM`).
129
173
  - **`Combobox` suggestions are no longer clipped inside popups.** The listbox is a top-layer popover placed below the field at its width (flipping above when short), so an `AnchoredSurface`, a dialog, or a scrolling `List` around the field no longer cuts it off. The `--kui-combobox-z-index` token is gone; the top layer needs none (`KF-C558Z9`).
130
174
  - **`List` `vAlign="middle"` and `Row` `hAlign="center"` gather their children in the middle** with their `gap`, instead of spreading them with `space-around`. `space-around` is now its own explicit value (`data-*-align="around"`), and `center`/`middle` on the cross axis center wrapped lines (`KF-3ZJ9PF`).
131
175
  - **A SearchField no longer shows its placeholder over typed text after an unrelated re-render.** Re-rendering the host for another reason, such as an error message beside the field, reset the field's placeholder state from the app's query while the editor still held typed text. `wireSearchFields` now re-derives it from the live editor (`KF-PZ5J93`).
@@ -220,6 +264,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
220
264
 
221
265
  ### Documentation
222
266
 
267
+ - The `@kerfjs/ui` UX catalog's Structured Ticket Search help is lighter: a short title and line, then grouped filter chips (action `Chip`s) that insert their filter into the field, instead of a key/value table. The SearchField examples' notes are shorter too (`KF-XP8742`).
268
+
223
269
  - New recipe in the `kerfjs/async` API reference: move heavy app compute (fuzzy search, CSV or markdown parsing, aggregation) into a Worker by having a `resource()` fetcher post a message to the worker and resolve with its reply. It covers request/reply ids, dropping superseded results, worker errors, transferring `ArrayBuffer`s, and keeping the render on the main thread (`KF-04KHT9`).
224
270
 
225
271
  - Clarify for AI consumers that sunken/lowered token names resolve to a translucent tint, and explain intentional nested layers versus duplicate surface paint (`KF-9CM6D8`).
package/ai/manifest.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "kerfjsVersion": "5.0.0-beta.105",
2
+ "kerfjsVersion": "5.0.0-beta.107",
3
3
  "files": [
4
4
  {
5
5
  "name": "skill",
package/dist/overlay.d.ts CHANGED
@@ -341,8 +341,14 @@ declare function positionAnchored(el: HTMLElement, anchor: Element, options?: An
341
341
  /**
342
342
  * Keep `el` positioned against `anchor` (via {@link positionAnchored}) as the page
343
343
  * scrolls or resizes. Positions once immediately, then re-runs on `scroll`
344
- * (capture phase — catches scrolls in any inner container, not just `window`) and
345
- * `resize`. Returns a disposer that removes the listeners.
344
+ * (capture phase — catches scrolls in any inner container, not just `window`),
345
+ * `resize`, and, where `ResizeObserver` exists, whenever the anchor's or `el`'s
346
+ * own size changes — a field that grows a line as it fills, or an end-aligned
347
+ * or above-placed surface whose content grows — so `el` stays lined up with
348
+ * the anchor edge it hangs from. A size change that `el`'s own repositioning
349
+ * caused (a published `fitHeight` cap, a shrink-to-fit width near the viewport
350
+ * edge) is not acted on again, so positioning can never feed itself. Returns
351
+ * a disposer that removes the listeners and the observer.
346
352
  */
347
353
  declare function autoReposition(el: HTMLElement, anchor: Element, options?: AnchorPositionOptions): () => void;
348
354
 
package/dist/overlay.js CHANGED
@@ -952,10 +952,12 @@ var VERTICAL_EDGES = [
952
952
  var UNBOUNDED_ROOM = "9999999px";
953
953
  var SWAPPED = [
954
954
  AVAILABLE_HEIGHT,
955
+ "height",
955
956
  "transition-property",
956
957
  "transition-duration",
957
958
  "transition-delay"
958
959
  ];
960
+ var TRANSITIONS = 2;
959
961
  function ownMaxHeight(el) {
960
962
  const style = window.getComputedStyle(el);
961
963
  const maxHeight = animatedMaxHeight(el) ?? swappedMaxHeight(el, style);
@@ -975,27 +977,33 @@ function swappedMaxHeight(el, style) {
975
977
  inline.getPropertyPriority(name)
976
978
  ]);
977
979
  const lists = SWAPPED.map((name) => style.getPropertyValue(name).split(","));
978
- const transitions = lists[1];
980
+ const transitions = lists[TRANSITIONS];
979
981
  if (transitions[0] && transitions[0] !== "none") {
980
- for (let index = 1; index < 4; index++) {
982
+ for (let index = TRANSITIONS; index < SWAPPED.length; index++) {
981
983
  const items = lists[index];
984
+ const appended = index > TRANSITIONS ? ["0s", "0s"] : ["max-height", "height"];
982
985
  inline.setProperty(
983
986
  SWAPPED[index],
984
987
  [
985
988
  ...transitions.map((_, entry) => items[entry % items.length]),
986
- index > 1 ? "0s" : "max-height"
989
+ ...appended
987
990
  ].join(),
988
991
  "important"
989
992
  );
990
993
  }
991
994
  }
995
+ const height = style.height;
996
+ const { scrollTop, scrollLeft } = el;
997
+ if (height.endsWith("px")) inline.setProperty("height", height, "important");
992
998
  inline.setProperty(AVAILABLE_HEIGHT, UNBOUNDED_ROOM);
993
999
  const maxHeight = style.maxHeight;
994
1000
  saved.forEach(([name, value, priority], index) => {
995
1001
  if (value) inline.setProperty(name, value, priority);
996
1002
  else inline.removeProperty(name);
997
- if (!index) style.getPropertyValue("max-height");
1003
+ if (index === TRANSITIONS - 1) style.getPropertyValue("max-height");
998
1004
  });
1005
+ if (scrollTop && el.scrollTop !== scrollTop) el.scrollTop = scrollTop;
1006
+ if (scrollLeft && el.scrollLeft !== scrollLeft) el.scrollLeft = scrollLeft;
999
1007
  return maxHeight;
1000
1008
  }
1001
1009
  function animatedMaxHeight(el) {
@@ -1061,13 +1069,28 @@ function fixedBottom(el, originY, scaleY) {
1061
1069
  );
1062
1070
  }
1063
1071
  function autoReposition(el, anchor, options = {}) {
1064
- const reposition = () => positionAnchored(el, anchor, options);
1072
+ const RO = globalThis.ResizeObserver;
1073
+ const nodes = [anchor, el];
1074
+ let settled = "";
1075
+ const sizes = () => nodes.map((node) => {
1076
+ const rect = node.getBoundingClientRect();
1077
+ return [rect.width, rect.height];
1078
+ }).join();
1079
+ const reposition = () => {
1080
+ positionAnchored(el, anchor, options);
1081
+ if (RO) settled = sizes();
1082
+ };
1065
1083
  reposition();
1066
1084
  window.addEventListener("scroll", reposition, true);
1067
1085
  window.addEventListener("resize", reposition);
1086
+ const observer = RO && new RO(() => {
1087
+ if (sizes() !== settled) reposition();
1088
+ });
1089
+ nodes.forEach((node) => observer?.observe(node));
1068
1090
  return () => {
1069
1091
  window.removeEventListener("scroll", reposition, true);
1070
1092
  window.removeEventListener("resize", reposition);
1093
+ observer?.disconnect();
1071
1094
  };
1072
1095
  }
1073
1096
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/overlay-core.ts","../src/overlay-choice.ts","../src/overlay-confirm.ts","../src/overlay-prompt.ts","../src/overlay-form.ts","../src/overlay-position.ts","../src/overlay-popover.ts","../src/overlay-toast.ts","../src/overlay-tooltip.ts"],"names":["options"],"mappings":"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","file":"overlay.js","sourcesContent":["/**\n * Shared overlay lifecycle and document arbitration implementation.\n *\n * Every real kerf app hand-rolls this: `toElement → body.appendChild → mount →\n * wire dismissal → remove`, plus the fiddly parts (Escape, backdrop / outside\n * click, focus trap, restoring focus on close). `window.confirm` is a no-op in\n * Tauri WKWebViews, so a hand-built overlay is mandatory there. This subpath\n * blesses the pattern through `overlay()`, with anchored surfaces and dialog\n * helpers building on it. No per-instance framework state: each call owns its\n * DOM + listeners in a closure and returns a handle.\n *\n * import { overlay, confirm, toast } from 'kerfjs/overlay';\n *\n * const ok = await confirm('Delete this file?', { danger: true });\n * toast('Saved');\n * const dialog = overlay(<Settings />, { dismiss: ['escape', 'backdrop'] });\n * // …later: dialog.close(); or await dialog.result;\n *\n * Structural only — kerf ships no CSS. The wrapper gets your `className`; style\n * the backdrop / centering / animation yourself.\n */\nimport { attach } from './attach.js';\nimport { devHooks } from './dev-hooks.js';\nimport type { SafeHtml } from './jsx-runtime.js';\nimport { mount, type MountResult } from './mount.js';\nimport { OVERLAY_HOST_SELECTOR } from './utils/overlay-host.js';\n\n/** A user-initiated dismissal trigger. */\nexport type DismissTrigger = 'escape' | 'backdrop' | 'outside';\n\n/** Content for an overlay: static `SafeHtml`, or a render function `mount()` drives reactively. */\nexport type OverlayContent = SafeHtml | (() => MountResult);\n\n/**\n * How an overlay is presented. `'modal'` (the default) adds nothing.\n * `'bottom-sheet'` marks the wrapper `data-presentation=\"bottom-sheet\"` and,\n * while open, publishes the virtual keyboard's overlap as the inline custom\n * property `--kerf-keyboard-inset`. kerf ships no CSS: the bottom-edge\n * geometry, safe-area padding, and motion are the app's (or `@kerfjs/ui`'s).\n */\nexport type OverlayPresentation = 'modal' | 'bottom-sheet';\n\n/** Options for {@link overlay}. */\nexport interface OverlayOptions {\n /**\n * Where to append the overlay wrapper. Default `document.body`. A container\n * inside an open modal `<dialog>` (including one slotted into a shadow-root\n * modal such as Web Awesome's `wa-dialog`) is already interactive, so the\n * surface is not lifted, and it closes when that dialog closes.\n */\n container?: Element;\n /** Class on the wrapper element (you style it — kerf ships no CSS). Default `'kerf-overlay'`. */\n className?: string;\n /**\n * Which user actions dismiss the overlay. Default `['escape', 'backdrop']`.\n * `'backdrop'` = a click on the wrapper itself (not its content); `'outside'`\n * = a click anywhere outside the wrapper (for anchored popovers). `false`\n * disables user dismissal (close it programmatically).\n */\n dismiss?: DismissTrigger | DismissTrigger[] | false;\n /**\n * Where focus lands on open: a selector, `true` (first focusable element, or\n * the wrapper if none), or `false` (leave focus alone). Default `true`.\n */\n initialFocus?: string | boolean;\n /**\n * Trap Tab / Shift+Tab within the overlay while open and mark it\n * `role=\"dialog\"` / `aria-modal=\"true\"`. Default `true`. Set `false` for a\n * non-modal popover.\n */\n trap?: boolean;\n /** ARIA role for the wrapper when `trap` is on. Default `'dialog'`. */\n role?: string;\n /** Called on any user-initiated dismissal (before `close()` runs). */\n onDismiss?: () => void;\n /** For `'outside'` dismissal: clicks on these elements do NOT count as outside (e.g. the trigger button). */\n outsideIgnore?: Element | readonly Element[];\n /**\n * Opt into the browser **top layer** (`docs/19-native-overlay-backing.md`).\n * When `true` and the engine supports it, a modal overlay (`trap: true`) is\n * hosted in a `<dialog>` opened with `.showModal()` — real inerting of the rest\n * of the document + guaranteed stacking above any `z-index` — and a non-modal\n * one (`trap: false`) uses the Popover API (`[popover]` + `showPopover()`).\n * Feature-detected; falls back to today's plain `<div>` where unsupported.\n *\n * The `render` slot + promise API are unchanged — kerf just hosts your markup\n * in a `<dialog>` / `[popover]` instead of a `<div>`. Two caveats: native\n * `<dialog>` / `[popover]` carry **UA default styles** (a `::backdrop`,\n * centering, border, padding) that kerf does not reset — style the element (and\n * its `::backdrop`) via `className`; and `container` is effectively a **no-op**\n * for visual position, since the top layer ignores where the element lives in\n * the DOM. Default `false`.\n */\n native?: boolean;\n /**\n * `'bottom-sheet'` marks the wrapper `data-presentation=\"bottom-sheet\"` (on\n * both the plain `<div>` and the `native` `<dialog>` / `[popover]` hosts) and,\n * while the overlay is open, follows `visualViewport` to publish the virtual\n * keyboard's overlap as `--kerf-keyboard-inset: <px>` on the wrapper (removed\n * when there is none, while pinch-zoomed, and on close). Style the sheet with\n * those hooks — rest it on the bottom edge and add\n * `max(env(safe-area-inset-bottom), var(--kerf-keyboard-inset, 0px))` to its\n * block-end padding. kerf\n * sets no geometry of its own. Default `'modal'` (nothing added).\n */\n presentation?: OverlayPresentation;\n /**\n * Class added when the overlay closes, so CSS owns the **exit** (mirrors\n * `toast()`'s `exitClass`). Everything else happens at once — `result`\n * settles, the overlay leaves the stack, a native host leaves the top layer,\n * the wrapper turns `inert`, focus is restored — and only the node's removal\n * waits: until the CSS animations / transitions then running in the wrapper\n * finish, or `exitDuration` ms pass, whichever is first. Skipped under\n * `prefers-reduced-motion: reduce`. A closed native `<dialog>` / `[popover]`\n * is `display: none` unless your CSS keeps it shown during the exit.\n */\n exitClass?: string;\n /**\n * The exit's hard cap in ms (see `exitClass`). Also opts into an exit on its\n * own — e.g. a native `<dialog>`'s `display` / `overlay` `allow-discrete`\n * transition. Default `0`.\n */\n exitDuration?: number;\n}\n\n/** Options for {@link OverlayHandle.close}. */\nexport interface OverlayCloseOptions {\n /** Skip the exit and remove the node now — or end an exit already running. */\n instant?: boolean;\n}\n\n/** Handle returned by {@link overlay}. Holds no framework state — it's a closure. */\nexport interface OverlayHandle {\n /** The wrapper element (mounted into, appended to `container`). */\n el: HTMLElement;\n /**\n * Tear down: dispose the mount, remove listeners, restore focus, resolve\n * `result`, and remove the node — after the exit, when one is configured\n * (`{ instant: true }` skips or ends it). Idempotent.\n */\n close(result?: unknown, options?: OverlayCloseOptions): void;\n /** Resolves with the value passed to `close()` (or `undefined` on user dismissal). */\n result: Promise<unknown>;\n}\n\nconst FOCUSABLE =\n 'a[href],area[href],button:not([disabled]),input:not([disabled]),' +\n 'select:not([disabled]),textarea:not([disabled]),iframe,' +\n '[tabindex]:not([tabindex=\"-1\"]),[contenteditable=\"true\"]';\n\nfunction focusable(root: Element): HTMLElement[] {\n const items = Array.from(\n root.querySelectorAll<HTMLElement>(FOCUSABLE),\n ).filter((el) => !el.hasAttribute('hidden') && el.tabIndex >= 0);\n // WebKit on macOS follows the system's keyboard-navigation preference and\n // may omit implicitly tabbable controls from sequential focus navigation.\n // A focus trap promises stable traversal through every eligible control, so\n // make those implicit stops explicit while preserving authored tabindexes.\n for (const el of items) if (!el.hasAttribute('tabindex')) el.tabIndex = 0;\n return items;\n}\n\n// Native top-layer feature detection (KF-526). Modal → `<dialog>.showModal()`;\n// non-modal → the Popover API. Each is independent — an engine may ship one\n// without the other — and both fall back to the plain `<div>` where absent.\nfunction supportsDialog(): boolean {\n return (\n typeof HTMLDialogElement !== 'undefined' &&\n typeof HTMLDialogElement.prototype.showModal === 'function'\n );\n}\nfunction supportsPopover(): boolean {\n return (\n typeof HTMLElement !== 'undefined' &&\n typeof HTMLElement.prototype.showPopover === 'function'\n );\n}\n\n/**\n * Internal: a teardown with no exit — construction rollback, or a node (or an\n * anchored surface's anchor) already gone. Not re-exported from `kerfjs/overlay`.\n */\nexport const INSTANT: OverlayCloseOptions = { instant: true };\n\n/** The wrapper's custom property carrying a bottom sheet's keyboard overlap. */\nconst KEYBOARD_INSET = '--kerf-keyboard-inset';\n\n// A bottom sheet rests on the layout viewport's bottom edge, which a virtual\n// keyboard overlays: publish that overlap (layout height minus the visual\n// viewport's height and top offset; nothing while pinch-zoomed, when the\n// difference is zoom, not a keyboard) on `el` until the returned disposer\n// runs. Engines without `visualViewport` publish nothing. A page whose\n// viewport meta resizes content shrinks the layout viewport instead, so the\n// overlap is zero there and the sheet simply follows the viewport.\nfunction followKeyboardInset(\n el: HTMLElement,\n removers: Array<() => void>,\n): void {\n const viewport = globalThis.visualViewport;\n if (viewport == null) return;\n const publish = (): void => {\n const inset =\n viewport.scale > 1.01\n ? 0\n : Math.round(\n globalThis.innerHeight - viewport.height - viewport.offsetTop,\n );\n if (inset > 0) el.style.setProperty(KEYBOARD_INSET, `${inset}px`);\n else el.style.removeProperty(KEYBOARD_INSET);\n };\n viewport.addEventListener('resize', publish);\n viewport.addEventListener('scroll', publish);\n removers.push(() => {\n viewport.removeEventListener('resize', publish);\n viewport.removeEventListener('scroll', publish);\n el.style.removeProperty(KEYBOARD_INSET);\n });\n publish();\n}\n\n// Stacked-surface arbitration (KF-CW7GJ8: a tooltip inside a modal used to\n// become \"topmost\" and disable the modal's Escape, backdrop, and focus trap).\n// Every open overlay — native or fallback — is recorded, in open order, on a\n// per-document stack. An input kind (Escape, a backdrop / outside click, Tab\n// for the trap) belongs to the topmost surface that HANDLES that kind; a\n// surface that doesn't handle it is transparent, except that a modal surface\n// is a barrier nothing beneath it sees past. A tooltip (or any overlay with no\n// dismiss trigger and no trap) handles nothing, so it never intercepts. The\n// `handled` set marks an event a surface already acted on, so one click that is\n// both \"outside\" a popover and on the modal backdrop closes only the popover.\nconst OVERLAY_ARBITRATION = Symbol('kerf.overlayArbitration');\n\n/** An arbitration input: a dismiss trigger, or Tab for the focus trap. */\ntype ArbitrationKind = DismissTrigger | 'trap';\n\ninterface OverlaySurface {\n el: HTMLElement;\n triggers: readonly DismissTrigger[];\n modal: boolean;\n /** Where focus returns on close; re-pointed when the surface holding it closes first. */\n restoreTo: Element | null;\n /** Non-modal only: move (or re-show) into the top layer above a newly opened modal `<dialog>`. */\n liftAbove?: () => void;\n /** An anchored surface's anchor (see {@link anchorOverlay}). */\n anchor?: Element;\n /**\n * Close as cleanup because the surface this one renders in, or its anchor\n * renders in, is closing: `instant` when that host's node goes now.\n */\n leave: (instant: boolean) => void;\n}\n\ninterface OverlayArbitration {\n stack: OverlaySurface[];\n handled: WeakSet<Event>;\n /** Document capture listener, installed only while the stack is non-empty. */\n onToggle: (event: Event) => void;\n /** Open shadow roots carrying `onToggle` too (a shadow `toggle` never reaches the document). */\n shadowRoots: Set<ShadowRoot>;\n}\n\ntype ArbitratedDocument = Document & {\n [OVERLAY_ARBITRATION]?: OverlayArbitration;\n};\n\nfunction overlayArbitration(doc: Document): OverlayArbitration {\n const arbitrated = doc as ArbitratedDocument;\n return (arbitrated[OVERLAY_ARBITRATION] ??= {\n stack: [],\n handled: new WeakSet(),\n // KF-AHY6H4: an app-owned modal `<dialog>` opened outside kerf would leave\n // the kerf surfaces already showing inert beneath it. A dialog fires\n // `toggle` after it opens (it does not bubble, so listen in the capture\n // phase); re-host above it exactly as kerf does for its own dialogs, which\n // are skipped here because `overlay()` already re-hosted synchronously.\n onToggle: (event) => {\n const dialog = event.target as Element;\n const arbitration = arbitrated[OVERLAY_ARBITRATION] as OverlayArbitration;\n if (\n dialog.tagName === 'DIALOG' &&\n !arbitration.stack.some(({ el }) => el === dialog) &&\n isOpenModal(dialog, arbitration)\n )\n rehostAbove(arbitration, dialog);\n },\n shadowRoots: new Set(),\n });\n}\n\n// Every open shadow root in `root`, nested ones included (KF-1FGTX1: Web\n// Awesome's `wa-dialog` / `wa-drawer` keep their modal `<dialog>` in one, where\n// neither `querySelectorAll` nor a document `toggle` listener can see it). A\n// closed shadow root is invisible by design. One element walk per `overlay()`\n// open — a user-paced event — so the cost stays off every render path.\nfunction openShadowRoots(\n root: Document | ShadowRoot,\n found: ShadowRoot[] = [],\n): ShadowRoot[] {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);\n for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {\n const shadow = (node as Element).shadowRoot;\n if (shadow !== null) {\n found.push(shadow);\n openShadowRoots(shadow, found);\n }\n }\n return found;\n}\n\n// Install the `toggle` watch on every open shadow root not yet watched, so an\n// app-owned modal `<dialog>` opening inside one re-hosts the surfaces showing.\nfunction watchShadowRoots(\n arbitration: OverlayArbitration,\n roots: readonly ShadowRoot[],\n): void {\n for (const root of roots)\n if (!arbitration.shadowRoots.has(root)) {\n arbitration.shadowRoots.add(root);\n root.addEventListener('toggle', arbitration.onToggle, true);\n }\n}\n\n// Is `el` inside `dialog` in the flat tree — the rendered tree, where content\n// slotted into a shadow host renders inside the host's shadow `<dialog>`?\nfunction renderedInside(el: Element, dialog: Element): boolean {\n for (let node: Element | null = el; node !== null;) {\n if (node === dialog) return true;\n const root = node.getRootNode();\n node =\n node.assignedSlot ??\n node.parentElement ??\n (root instanceof ShadowRoot ? root.host : null);\n }\n return false;\n}\n\n// Every non-modal kerf surface already open is blocked beneath a modal\n// `<dialog>` that just opened: lift (or re-show) it above (KF-FJ9VD8). One\n// rendered inside that dialog — including a slot-hosted one in a shadow\n// host's light DOM — is part of its subtree already.\nfunction rehostAbove(arbitration: OverlayArbitration, dialog: Element): void {\n for (const { el, liftAbove } of arbitration.stack)\n if (el !== dialog && el.isConnected && !renderedInside(el, dialog))\n liftAbove?.();\n}\n\n// Is `dialog` an open modal `<dialog>`? kerf's own are known from the stack;\n// an app-owned one is found through `:modal`, which an older engine may not\n// parse (then only kerf's own count).\nfunction isOpenModal(\n dialog: Element,\n arbitration: OverlayArbitration,\n): boolean {\n if (!dialog.isConnected || (dialog as HTMLDialogElement).open !== true)\n return false;\n if (arbitration.stack.some(({ el, modal }) => modal && el === dialog))\n return true;\n try {\n return dialog.matches(':modal');\n } catch {\n return false; // `:modal` unsupported\n }\n}\n\n// Is a modal `<dialog>` open (KF-0V9RTE: a plain surface opened in that state\n// is inert and painted beneath the dialog's top layer)?\n// The open shadow roots count too (KF-1FGTX1: a `wa-dialog`'s modal).\nfunction modalDialogOpen(\n doc: Document,\n arbitration: OverlayArbitration,\n shadowRoots: readonly ShadowRoot[],\n): boolean {\n return (\n arbitration.stack.some(({ el }) => isOpenModal(el, arbitration)) ||\n [doc, ...shadowRoots].some((root) =>\n Array.from(root.querySelectorAll('dialog[open]')).some((dialog) =>\n isOpenModal(dialog, arbitration),\n ),\n )\n );\n}\n\n// The modal context `el` renders in, resolved across shadow boundaries\n// (KF-F52T5D: Web Awesome's `wa-dialog` / `wa-drawer` keep their modal\n// `<dialog>` in a shadow root, so `closest('dialog')` from slotted light-DOM\n// content found nothing and the surface landed, inert, in `document.body`).\n// Walks the light-DOM ancestors, continuing from a shadow tree to its host.\n// The nearest `<dialog>` decides, as before; so does a shadow host whose slot\n// for the walked-from child sits inside a `<dialog>` in its shadow root. Only\n// an OPEN MODAL dialog yields a context: `dialog` is that element, `root` the\n// light-DOM element a host slot belongs in — the dialog itself, or the shadow\n// host (content appended to it is slotted into the dialog).\ninterface ModalContext {\n dialog: Element;\n root: Element;\n}\nfunction modalContext(\n el: Element,\n arbitration: OverlayArbitration,\n): ModalContext | undefined {\n let child: Element | undefined;\n for (let node: Element | null = el; node !== null;) {\n const dialog =\n node.localName === 'dialog'\n ? node\n : child?.assignedSlot?.closest('dialog');\n if (dialog != null)\n return isOpenModal(dialog, arbitration)\n ? { dialog, root: node }\n : undefined;\n child = node;\n const root = node.getRootNode();\n node =\n node.parentElement ?? (root instanceof ShadowRoot ? root.host : null);\n }\n return undefined;\n}\n\n// The in-dialog host slot (KF-FBHQEP: a surface lifted over a modal\n// `<dialog>` is visible but inert, because every engine inerts content outside\n// the modal). A `popover()` / `tooltip()` whose anchor renders inside an open\n// modal `<dialog>` (see `modalContext`) renders into that context's\n// `[data-kerf-overlay-host]` element instead, so it is part of the modal\n// subtree and fully interactive. An app-owned native dialog opts in by marking\n// an element; a dialog kerf opened itself, and a shadow-hosted modal (whose\n// author cannot reach inside the shadow root), get one on demand —\n// `display: contents` so it adds no layout box, and `data-morph-skip` +\n// `data-morph-preserve` so the content's own `mount()` neither re-renders nor\n// removes it (`utils/overlay-host.ts` makes the slot a nested-mount boundary).\nexport function overlayHost(anchor: Element): Element | undefined {\n const arbitration = overlayArbitration(document);\n const context = modalContext(anchor, arbitration);\n if (context === undefined) return undefined;\n const { dialog, root } = context;\n let host = Array.from(root.querySelectorAll(OVERLAY_HOST_SELECTOR)).find(\n (el) => modalContext(el, arbitration)?.root === root,\n );\n if (\n host === undefined &&\n (root !== dialog || arbitration.stack.some(({ el }) => el === dialog))\n ) {\n root.insertAdjacentHTML(\n 'beforeend',\n '<div data-kerf-overlay-host data-morph-skip data-morph-preserve style=\"display:contents\"></div>',\n );\n host = root.lastElementChild as Element;\n }\n return host;\n}\n\n// `self` is on the stack and handles `kind` (its callers are exactly the\n// handlers it installed for that kind), so it owns `kind` unless some surface\n// above it handles `kind` too or is modal.\nfunction ownsInput(\n stack: readonly OverlaySurface[],\n self: OverlaySurface,\n kind: ArbitrationKind,\n): boolean {\n for (let i = stack.indexOf(self) + 1; i < stack.length; i++) {\n const above = stack[i];\n if (above.modal || (kind !== 'trap' && above.triggers.includes(kind)))\n return false;\n }\n return true;\n}\n\n// Validate a string `initialFocus` BEFORE any DOM mutation: `querySelector`\n// throws a generic `SyntaxError` DOMException on a malformed selector, and the\n// focus pass runs last — after the wrapper, mount, listeners, and stack entry\n// already exist — so an unvalidated selector would strand all of them with no\n// handle to close. An inert fragment parses the selector without matching.\nfunction assertInitialFocusSelector(selector: string): void {\n try {\n document.createDocumentFragment().querySelector(selector);\n } catch (cause) {\n throw new Error(\n `overlay(): invalid initialFocus selector ${JSON.stringify(selector)}`,\n { cause },\n );\n }\n}\n\n/**\n * Open an overlay: append a wrapper to `container`, `mount()` `content` inside\n * it, wire the requested dismissals + (optionally) a focus trap, and return a\n * handle. Concurrent fallback overlays dismiss from the top down. See\n * {@link OverlayOptions}.\n *\n * Construction is transactional: a malformed `initialFocus` selector throws a\n * descriptive error before anything is touched, and if a later setup phase\n * throws (the content's first render, `showModal()` / `showPopover()`), every\n * piece already installed — wrapper node, mount, listeners, fallback-stack\n * entry, top-layer state, moved focus — is rolled back before the original\n * error is rethrown.\n */\nexport function overlay(\n content: OverlayContent,\n options: OverlayOptions = {},\n): OverlayHandle {\n const {\n container = document.body,\n className = 'kerf-overlay',\n dismiss = ['escape', 'backdrop'],\n initialFocus = true,\n trap = true,\n role = 'dialog',\n onDismiss,\n outsideIgnore,\n native = false,\n presentation = 'modal',\n exitClass,\n exitDuration = 0,\n } = options;\n\n if (typeof initialFocus === 'string')\n assertInitialFocusSelector(initialFocus);\n\n const triggers: readonly DismissTrigger[] =\n dismiss === false ? [] : Array.isArray(dismiss) ? dismiss : [dismiss];\n\n // Native top-layer backing (KF-526), feature-detected: a modal overlay\n // (`trap`) → `<dialog>.showModal()`; a non-modal one → `[popover]`. Each falls\n // back to the plain `<div>` where the API is missing, so behavior is unchanged\n // on unsupporting engines. A surface opened while a modal `<dialog>` is open\n // is lifted the same way even without `native` (KF-0V9RTE), because a plain\n // `<div>` would be inert and painted beneath the dialog.\n const arbitration = overlayArbitration(document);\n // A surface placed inside an open modal `<dialog>` (its host slot, or an\n // explicit `container` there, including one slotted into a shadow-root\n // modal) is already part of the modal subtree: no lift.\n const containerContext = modalContext(container, arbitration);\n const shadowRoots = openShadowRoots(document);\n const liftOverModal =\n !native &&\n containerContext === undefined &&\n modalDialogOpen(document, arbitration, shadowRoots);\n const topLayer = native || liftOverModal;\n const useDialog = topLayer && trap && supportsDialog();\n const usePopover = topLayer && !trap && supportsPopover();\n\n const wrapper: HTMLElement = useDialog\n ? document.createElement('dialog')\n : document.createElement('div');\n wrapper.className = className;\n if (usePopover) wrapper.setAttribute('popover', 'manual');\n const bottomSheet = presentation === 'bottom-sheet';\n if (bottomSheet) wrapper.setAttribute('data-presentation', 'bottom-sheet');\n // `<dialog>.showModal()` conveys modality natively (role + inert), so the ARIA\n // attributes are only needed on the plain-`<div>` fallback.\n if (trap && !useDialog) {\n wrapper.setAttribute('role', role);\n wrapper.setAttribute('aria-modal', 'true');\n }\n const surface: OverlaySurface = {\n el: wrapper,\n triggers,\n modal: trap,\n restoreTo: document.activeElement,\n leave: (now) => close(undefined, now ? INSTANT : undefined),\n };\n\n // Does this surface own `kind` right now (and has no surface acted on `event`)?\n const owns = (kind: ArbitrationKind, event?: Event): boolean =>\n !(event !== undefined && arbitration.handled.has(event)) &&\n ownsInput(arbitration.stack, surface, kind);\n\n const removers: Array<() => void> = [];\n // Run at the node's removal — after the exit, when one runs — not at close().\n const finalizers: Array<() => void> = [];\n const resultBox: { resolve?: (value: unknown) => void } = {};\n const result = new Promise<unknown>((resolve) => {\n resultBox.resolve = resolve;\n });\n const state = { closed: false, removed: false };\n let disposeMount: (() => void) | undefined;\n let nativeOpened = false;\n let exitTimer: ReturnType<typeof setTimeout> | undefined;\n\n // KF-FJ9VD8: a modal `<dialog>` kerf opens later would leave this non-modal\n // surface inert beneath it, so the opener calls this to move it into the top\n // layer — or, if it is already a `[popover]`, re-show it so it stacks above\n // the new dialog (the top layer orders by most recent show).\n if (!trap)\n surface.liftAbove = () => {\n if (!supportsPopover()) {\n devHooks.overlayBlockedByModal?.('hidden');\n return;\n }\n const el = wrapper as HTMLElement & {\n showPopover(): void;\n hidePopover(): void;\n };\n if (nativeOpened) el.hidePopover();\n else {\n wrapper.setAttribute('popover', 'manual');\n wrapper.style.inset = 'auto';\n }\n el.showPopover();\n nativeOpened = true;\n if (wrapper.querySelector(FOCUSABLE) !== null)\n devHooks.overlayBlockedByModal?.('inert');\n };\n\n // Remove the node, ending the exit if one is running. Idempotent.\n function finish(): void {\n if (state.removed) return;\n state.removed = true;\n clearTimeout(exitTimer);\n for (const end of finalizers) end();\n wrapper.remove();\n }\n\n // Also the construction rollback (see the transaction below): every step\n // tolerates a phase that never ran — no mount yet, no stack entry, never\n // appended, never shown.\n //\n // The exit (KF-WAK1TW: CSS could animate an overlay in but never out) defers\n // ONLY the node's removal. Everything observable happens now: the stack entry\n // goes (a surface opened during the exit is topmost), listeners + the mount\n // are disposed, a native host leaves the top layer (so the page is no longer\n // inert and focus can return), the wrapper turns `inert` (no clicks, no\n // focus, hidden from assistive tech), focus is restored, `result` settles.\n function close(value?: unknown, closeOptions?: OverlayCloseOptions): void {\n const instant = closeOptions?.instant === true;\n if (state.closed) {\n if (instant) finish();\n return;\n }\n state.closed = true;\n const { stack } = arbitration;\n const stackIndex = stack.indexOf(surface);\n if (stackIndex !== -1) stack.splice(stackIndex, 1);\n if (stack.length === 0) {\n document.removeEventListener('toggle', arbitration.onToggle, true);\n for (const root of arbitration.shadowRoots)\n root.removeEventListener('toggle', arbitration.onToggle, true);\n arbitration.shadowRoots.clear();\n }\n // A surface opened from inside this one would restore focus into a node\n // that is about to be detached: hand it this surface's own restore target.\n for (const other of stack)\n if (other.restoreTo !== null && wrapper.contains(other.restoreTo))\n other.restoreTo = surface.restoreTo;\n const exit =\n !instant &&\n (exitClass !== undefined || exitDuration > 0) &&\n !globalThis.matchMedia('(prefers-reduced-motion: reduce)').matches;\n // KF-XNEK58: a surface rendered inside this one, or anchored to content\n // inside it, leaves with it now — not when the node is finally removed\n // (an exit can keep the inert node for `exitDuration` ms). It follows this\n // surface: its own exit alongside an exiting host, gone at once otherwise.\n for (const other of [...stack])\n if (\n stack.includes(other) &&\n (renderedInside(other.el, wrapper) ||\n (other.anchor !== undefined && renderedInside(other.anchor, wrapper)))\n )\n other.leave(!exit);\n const active = document.activeElement;\n for (const remove of removers) remove();\n disposeMount?.();\n // Exit the top layer before removing the node, so the native close steps run\n // (restore inert, fire the dialog's `close`). `<dialog>` also restores focus\n // itself; kerf's manual restore below stays as the fallback path's behavior.\n if (nativeOpened) {\n nativeOpened = false;\n if (useDialog) (wrapper as HTMLDialogElement).close();\n else (wrapper as HTMLElement & { hidePopover(): void }).hidePopover();\n }\n if (exit) {\n wrapper.inert = true;\n if (exitClass !== undefined) wrapper.classList.add(exitClass);\n } else finish();\n restoreFocus(active);\n resultBox.resolve?.(value);\n if (exit) {\n // `exitDuration` caps the exit; the finite animations running in the\n // wrapper once `exitClass` applies (reading them flushes style, so the\n // exit's own are included) end it early — at once when none run.\n exitTimer = setTimeout(finish, exitDuration);\n if ('getAnimations' in wrapper)\n void Promise.allSettled(\n wrapper\n .getAnimations({ subtree: true })\n .filter((animation) =>\n Number.isFinite(\n animation.effect?.getComputedTiming().endTime ?? Infinity,\n ),\n )\n .map((animation) => animation.finished),\n ).then(finish);\n }\n }\n\n // Closing a surface that doesn't hold focus (an out-of-order close beneath\n // another open surface) must not pull focus out of the surface that does;\n // otherwise focus returns to where it was when this surface opened.\n function restoreFocus(active: Element | null): void {\n if (\n active instanceof HTMLElement &&\n active.isConnected &&\n arbitration.stack.some((other) => other.el.contains(active))\n ) {\n if (document.activeElement !== active) active.focus();\n return;\n }\n const { restoreTo } = surface;\n if (restoreTo instanceof HTMLElement && restoreTo.isConnected)\n restoreTo.focus();\n }\n\n function userDismiss(): void {\n onDismiss?.();\n close();\n }\n\n // One transaction: if any phase below throws (the content's first render,\n // `showModal()` / `showPopover()`, …), roll back whatever the earlier phases\n // installed via `close()` and rethrow the original error. No handle is\n // returned on failure, so nothing may outlive the call.\n try {\n container.appendChild(wrapper);\n disposeMount = mount(\n wrapper,\n typeof content === 'function' ? content : () => content,\n );\n // Before the top-layer show, so the first painted frame already clears\n // a keyboard that is up when the sheet opens.\n if (bottomSheet) followKeyboardInset(wrapper, finalizers);\n // Watch for app-owned modal dialogs while any kerf surface is open.\n // Shadow roots are refreshed on every open; one attached after the latest\n // open is not watched until the next.\n if (arbitration.stack.push(surface) === 1)\n document.addEventListener('toggle', arbitration.onToggle, true);\n watchShadowRoots(arbitration, shadowRoots);\n\n // Enter the top layer after the content is mounted + connected.\n // `showModal()` moves focus into the dialog by default; kerf's\n // `initialFocus` pass below runs afterward and wins.\n if (useDialog) {\n (wrapper as HTMLDialogElement).showModal();\n nativeOpened = true;\n rehostAbove(arbitration, wrapper);\n } else if (usePopover) {\n (wrapper as HTMLElement & { showPopover(): void }).showPopover();\n nativeOpened = true;\n // Neutralize the UA `[popover] { inset: 0; margin: auto }` anchoring so\n // `positionAnchored` (which sets `top`/`left`) controls placement —\n // otherwise the retained `right`/`bottom` insets would stretch/center it.\n wrapper.style.inset = 'auto';\n }\n\n installDismissal();\n if (container.closest(OVERLAY_HOST_SELECTOR) !== null) {\n makeTabReachable();\n // KF-WZ9KQM: a slot-hosted surface leaves with its dialog even when its\n // anchor (moved out of the dialog) stays connected, so the anchor watch\n // never fires. Watch the wrapper itself: close as cleanup (no\n // `onDismiss`) and leave the open-order stack.\n removers.push(attach(wrapper, () => () => close(undefined, INSTANT)));\n }\n // KF-F52T5D: a surface inside a modal context leaves when that dialog\n // closes, as cleanup (no `onDismiss`). Closing an app-owned or\n // shadow-hosted dialog removes nothing, and a shadow dialog's `close`\n // never reaches a light-DOM listener, so a caller could not watch it.\n if (containerContext !== undefined) {\n const { dialog } = containerContext;\n const onDialogClose = (): void => close();\n dialog.addEventListener('close', onDialogClose);\n removers.push(() => dialog.removeEventListener('close', onDialogClose));\n }\n applyInitialFocus();\n } catch (error) {\n close(undefined, INSTANT);\n throw error;\n }\n\n // What the lift cannot repair: no top-layer API at all, or a lifted\n // non-modal surface whose controls the modal still inerts.\n if (liftOverModal) {\n if (!useDialog && !usePopover) devHooks.overlayBlockedByModal?.('hidden');\n else if (usePopover && wrapper.querySelector(FOCUSABLE) !== null)\n devHooks.overlayBlockedByModal?.('inert');\n }\n\n return { el: wrapper, close, result };\n\n function installDismissal(): void {\n const wantEscape = triggers.includes('escape');\n if (useDialog) {\n // A native modal `<dialog>` confines Tab focus itself and surfaces Escape as\n // a `cancel` event. Take that over: `preventDefault` so kerf owns teardown\n // (and so Escape is swallowed when it isn't a dismiss trigger), then dismiss.\n // A surface stacked above that handles Escape (or is modal) owns it; a\n // stray `cancel` then leaves this dialog open.\n const onCancel = (event: Event): void => {\n event.preventDefault();\n if (wantEscape && owns('escape')) userDismiss();\n };\n wrapper.addEventListener('cancel', onCancel);\n removers.push(() => wrapper.removeEventListener('cancel', onCancel));\n } else if (wantEscape || trap) {\n const onKeydown = (event: KeyboardEvent): void => {\n if (wantEscape && event.key === 'Escape') {\n if (!owns('escape', event)) return;\n // `preventDefault` also withholds the close request from a native\n // `<dialog>` beneath, so one Escape closes exactly one surface.\n event.stopPropagation();\n event.preventDefault();\n arbitration.handled.add(event);\n userDismiss();\n return;\n }\n if (trap && event.key === 'Tab' && owns('trap')) {\n const items = focusable(wrapper);\n if (items.length === 0) {\n event.preventDefault();\n return;\n }\n const first = items[0];\n const last = items[items.length - 1];\n const active = document.activeElement;\n const outside = !wrapper.contains(active);\n if (event.shiftKey && (active === first || outside)) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && (active === last || outside)) {\n event.preventDefault();\n first.focus();\n }\n }\n };\n document.addEventListener('keydown', onKeydown, true);\n removers.push(() =>\n document.removeEventListener('keydown', onKeydown, true),\n );\n }\n\n if (triggers.includes('backdrop')) {\n const onClick = (event: Event): void => {\n if (event.target !== wrapper || !owns('backdrop', event)) return;\n arbitration.handled.add(event);\n userDismiss();\n };\n wrapper.addEventListener('click', onClick);\n removers.push(() => wrapper.removeEventListener('click', onClick));\n }\n\n if (triggers.includes('outside')) {\n const ignore =\n outsideIgnore === undefined\n ? []\n : Array.isArray(outsideIgnore)\n ? outsideIgnore\n : [outsideIgnore];\n // Capture phase: the click that opened this overlay already passed\n // document's capture phase, so this never fires for that opening click.\n const onDocClick = (event: Event): void => {\n const target = event.target as Node | null;\n if (target === null) return;\n if (wrapper.contains(target)) return;\n if (ignore.some((el) => el === target || el.contains(target))) return;\n if (!owns('outside', event)) return;\n arbitration.handled.add(event);\n userDismiss();\n };\n document.addEventListener('click', onDocClick, true);\n removers.push(() =>\n document.removeEventListener('click', onDocClick, true),\n );\n }\n }\n\n // KF-QZ9SFG (slot-hosted controls unreachable by Tab in macOS WebKit): a\n // surface in an overlay host slot sits in the modal dialog's own Tab order,\n // not behind a kerf trap, so WebKit's system keyboard-navigation preference\n // would skip its implicitly tabbable controls. Make those stops explicit, as\n // the trap does — now, and again before each Tab so a control a re-render\n // added (or whose tabindex the morph dropped) is reachable too.\n function makeTabReachable(): void {\n focusable(wrapper);\n const onTab = (event: KeyboardEvent): void => {\n if (event.key === 'Tab') focusable(wrapper);\n };\n document.addEventListener('keydown', onTab, true);\n removers.push(() => document.removeEventListener('keydown', onTab, true));\n }\n\n function focusWrapper(): void {\n wrapper.tabIndex = -1;\n wrapper.focus();\n }\n\n function applyInitialFocus(): void {\n if (initialFocus === false) return;\n const target =\n typeof initialFocus === 'string'\n ? wrapper.querySelector<HTMLElement>(initialFocus)\n : (focusable(wrapper)[0] ?? null);\n if (target === null) {\n if (initialFocus === true) focusWrapper();\n return;\n }\n if (tryFocus(target) || !isCustomElement(target)) return;\n // A custom element that is not defined or has not rendered yet (a Web\n // Awesome `wa-button` whose `focus()` reaches into a shadow root it has\n // not built) cannot take focus now, and may throw trying. Hold focus on\n // the overlay itself, then hand it over once the element renders — unless\n // the overlay closed or the user moved focus in the meantime.\n focusWrapper();\n void whenRendered(target).then(() => {\n if (!state.closed && activeIn(wrapper) === wrapper) tryFocus(target);\n });\n }\n}\n\nfunction isCustomElement(el: Element): boolean {\n return el.localName.includes('-');\n}\n\n// Focus `el`; true when it now holds focus. A custom element's `focus()`\n// override may throw before it has rendered.\nfunction tryFocus(el: HTMLElement): boolean {\n try {\n el.focus();\n } catch {\n return false;\n }\n return activeIn(el) === el;\n}\n\n// The focused element as `el`'s own tree sees it (a shadow root retargets).\nfunction activeIn(el: Element): Element | null {\n return (el.getRootNode() as Document | ShadowRoot).activeElement;\n}\n\n// Settles once a custom element is defined, its update cycle (Lit's\n// `updateComplete`) has settled, and a frame has passed.\nasync function whenRendered(el: HTMLElement): Promise<void> {\n await globalThis.customElements.whenDefined(el.localName);\n await (el as { updateComplete?: unknown }).updateComplete;\n await new Promise((resolve) => globalThis.requestAnimationFrame(resolve));\n}\n\n/**\n * Internal: mark the just-opened `handle` as anchored to `anchor`, so it\n * leaves (closes as cleanup, no `onDismiss`) the moment an overlay holding the\n * anchor closes — even while that overlay's node lingers for its exit. `leave`\n * replaces the default `handle.close()` (with `{ instant }` when the host goes\n * at once). Not re-exported from `kerfjs/overlay`.\n */\nexport function anchorOverlay(\n handle: OverlayHandle,\n anchor: Element,\n leave?: (instant: boolean) => void,\n): void {\n const surface = overlayArbitration(document).stack.find(\n ({ el }) => el === handle.el,\n ) as OverlaySurface;\n surface.anchor = anchor;\n if (leave !== undefined) surface.leave = leave;\n}\n\n/**\n * Internal: run a promise-dialog helper's post-open wiring (required-slot\n * lookups, `delegate()` handlers, key listeners) as the tail of `overlay()`'s\n * construction transaction. `wire` registers a disposer for every listener it\n * installs via `track`; if any step throws, those listeners are removed, the\n * just-opened overlay is closed (node, mount, dismissal listeners, stack\n * entry, top-layer state, focus), and the original error is rethrown — so a\n * failed helper call returns no promise and leaves no open overlay behind.\n *\n * After construction, `guard` wraps a user-action handler (OK click, Enter).\n * KF-B0CFQP (a throwing `validate` callback): a throw inside a guarded action\n * is a programming error, so it closes the dialog (full teardown, focus\n * restored) and the returned promise REJECTS with the original error, instead\n * of the error escaping the event handler and stranding an open dialog whose\n * OK can never succeed. Otherwise the returned promise settles with\n * `settle(handle.result's value)`. Not re-exported from `kerfjs/overlay`.\n */\nexport function wireDialog<T>(\n handle: OverlayHandle,\n wire: (\n track: (dispose: () => void) => void,\n guard: (action: () => void) => () => void,\n ) => void,\n settle: (value: unknown) => T,\n): Promise<T> {\n const disposers: Array<() => void> = [];\n // Holds a guarded action's error AND is the close() value that marks the\n // failure, so only a throw that actually settles the dialog rejects it.\n const failure: unknown[] = [];\n try {\n wire(\n (dispose) => void disposers.push(dispose),\n (action) => () => {\n try {\n action();\n } catch (error) {\n failure[0] = error;\n handle.close(failure);\n }\n },\n );\n } catch (error) {\n disposers.forEach((dispose) => dispose());\n handle.close(undefined, INSTANT);\n throw error;\n }\n // One hop, not a chain: `settle` maps the value in the same reaction, so a\n // helper's promise settles as soon after `close()` as it always has.\n return handle.result.then((value) => {\n if (value === failure) throw failure[0];\n return settle(value);\n });\n}\n","/** `choice()` implementation and public option types. */\nimport { delegate } from './delegate.js';\nimport { jsx } from './jsx-runtime.js';\nimport {\n overlay,\n type OverlayContent,\n type OverlayPresentation,\n wireDialog,\n} from './overlay-core.js';\n\n/** One choosable action in a {@link choice} dialog. */\nexport interface ChoiceAction<R> {\n value: R;\n label: string;\n className?: string;\n}\n\n/** Wiring slots for a {@link ChoiceOptions.render}. */\nexport interface ChoiceRenderSlots {\n message: string;\n actions: Array<Record<string, string>>;\n}\n\n/** Options for {@link choice}. */\nexport interface ChoiceOptions<R> {\n container?: Element;\n className?: string;\n title?: string;\n defaultValue?: R;\n native?: boolean;\n /** `'bottom-sheet'` presents the dialog as a bottom sheet (see `OverlayOptions.presentation`). Default `'modal'`. */\n presentation?: OverlayPresentation;\n /** Class added on close so CSS owns the exit; the node is removed after it (see `OverlayOptions.exitClass`). The promise settles at once. */\n exitClass?: string;\n /** The exit's hard cap in ms (see `OverlayOptions.exitDuration`). Default `0`. */\n exitDuration?: number;\n render?: (slots: ChoiceRenderSlots) => OverlayContent;\n}\n\n/** The N-way sibling of {@link confirm}. */\nexport function choice<R>(\n message: string,\n actions: ReadonlyArray<ChoiceAction<R>>,\n options: ChoiceOptions<R> = {},\n): Promise<R | null> {\n const {\n container,\n className = 'kerf-overlay',\n title,\n defaultValue,\n native = false,\n presentation,\n exitClass,\n exitDuration,\n render,\n } = options;\n const hasDefault = 'defaultValue' in options;\n const actionAttrs = actions.map((_, i) => ({ 'data-choice': String(i) }));\n\n const body: OverlayContent =\n render !== undefined\n ? render({ message, actions: actionAttrs })\n : jsx('div', {\n class: 'kerf-choice',\n children: [\n title !== undefined\n ? jsx('h2', { class: 'kerf-choice__title', children: title })\n : '',\n jsx('p', { class: 'kerf-choice__message', children: message }),\n jsx('div', {\n class: 'kerf-choice__actions',\n children: actions.map((action, i) =>\n jsx('button', {\n type: 'button',\n class:\n action.className !== undefined\n ? `kerf-choice__action ${action.className}`\n : 'kerf-choice__action',\n ...actionAttrs[i],\n children: action.label,\n }),\n ),\n }),\n ],\n });\n\n let resolveChoice!: (result: R | null) => void;\n const result = new Promise<R | null>((resolve) => {\n resolveChoice = resolve;\n });\n\n const handle = overlay(body, {\n container,\n className,\n dismiss: ['escape', 'backdrop'],\n initialFocus: '[data-choice]',\n trap: true,\n native,\n presentation,\n exitClass,\n exitDuration,\n });\n\n // Post-open wiring is still construction: a throw closes the overlay. Any\n // close settles a still-pending choice as a dismissal (`null`).\n void wireDialog(\n handle,\n (track) => {\n track(\n delegate(handle.el, 'click', '[data-choice]', (_event, el) => {\n resolveChoice(actions[Number(el.getAttribute('data-choice'))].value);\n handle.close();\n }),\n );\n\n if (hasDefault) {\n const onKeydown = (event: KeyboardEvent): void => {\n if (event.key === 'Enter') {\n event.preventDefault();\n resolveChoice(defaultValue as R);\n handle.close();\n }\n };\n // Last wiring step: nothing after it can throw, so it needs no rollback.\n handle.el.addEventListener('keydown', onKeydown);\n }\n },\n () => resolveChoice(null),\n );\n return result;\n}\n","/** `confirm()` implementation and public option types. */\nimport { delegate } from './delegate.js';\nimport { jsx } from './jsx-runtime.js';\nimport {\n overlay,\n type OverlayContent,\n type OverlayPresentation,\n wireDialog,\n} from './overlay-core.js';\n\n/** Wiring slots passed to a {@link ConfirmOptions.render}. */\nexport interface ConfirmRenderSlots {\n message: string;\n /** Spread onto the confirm control. */\n ok: Record<string, string>;\n /** Spread onto the cancel control. */\n cancel: Record<string, string>;\n}\n\n/** Options for {@link confirm}. */\nexport interface ConfirmOptions {\n /** Where to append the overlay. Default `document.body`. */\n container?: Element;\n /** Wrapper class. Default `'kerf-overlay'`. */\n className?: string;\n /** Optional heading above the message. */\n title?: string;\n /** Confirm button label. Default `'OK'`. */\n okText?: string;\n /** Cancel button label. Default `'Cancel'`. */\n cancelText?: string;\n /** Add a `kerf-confirm--danger` class to the wrapper for destructive actions. */\n danger?: boolean;\n /** Host the dialog in the browser top layer where supported. */\n native?: boolean;\n /** `'bottom-sheet'` presents the dialog as a bottom sheet (see `OverlayOptions.presentation`). Default `'modal'`. */\n presentation?: OverlayPresentation;\n /** Class added on close so CSS owns the exit; the node is removed after it (see `OverlayOptions.exitClass`). The promise settles at once. */\n exitClass?: string;\n /** The exit's hard cap in ms (see `OverlayOptions.exitDuration`). Default `0`. */\n exitDuration?: number;\n /** Bring your own body while retaining kerf's dialog wiring. */\n render?: (slots: ConfirmRenderSlots) => OverlayContent;\n}\n\n/** A promise-based `window.confirm` replacement. */\nexport function confirm(\n message: string,\n options: ConfirmOptions = {},\n): Promise<boolean> {\n const {\n container,\n className = 'kerf-overlay',\n title,\n okText = 'OK',\n cancelText = 'Cancel',\n danger = false,\n native = false,\n presentation,\n exitClass,\n exitDuration,\n render,\n } = options;\n\n const body: OverlayContent =\n render !== undefined\n ? render({\n message,\n ok: { 'data-confirm': 'ok' },\n cancel: { 'data-confirm': 'cancel' },\n })\n : jsx('div', {\n class: 'kerf-confirm',\n children: [\n title !== undefined\n ? jsx('h2', { class: 'kerf-confirm__title', children: title })\n : '',\n jsx('p', { class: 'kerf-confirm__message', children: message }),\n jsx('div', {\n class: 'kerf-confirm__actions',\n children: [\n jsx('button', {\n type: 'button',\n 'data-confirm': 'cancel',\n children: cancelText,\n }),\n jsx('button', {\n type: 'button',\n 'data-confirm': 'ok',\n class: 'kerf-confirm__ok',\n children: okText,\n }),\n ],\n }),\n ],\n });\n\n const handle = overlay(body, {\n container,\n className: danger ? `${className} kerf-confirm--danger` : className,\n dismiss: ['escape', 'backdrop'],\n initialFocus: '[data-confirm=\"ok\"]',\n trap: true,\n native,\n presentation,\n exitClass,\n exitDuration,\n });\n\n // Post-open wiring is still construction: a throw closes the overlay. The\n // click table is the only (and so the last) step, so it needs no rollback.\n return wireDialog(\n handle,\n () => {\n delegate(handle.el, 'click', '[data-confirm]', (_event, el) => {\n handle.close(el.getAttribute('data-confirm') === 'ok');\n });\n },\n (value) => value === true,\n );\n}\n","/** `prompt()` implementation and public option types. */\nimport { delegate } from './delegate.js';\nimport { jsx } from './jsx-runtime.js';\nimport {\n overlay,\n type OverlayContent,\n type OverlayPresentation,\n wireDialog,\n} from './overlay-core.js';\n\n/**\n * Validate a single field's value, synchronously: return a non-empty message\n * to block OK, anything else to accept. A validator that throws is treated as\n * a programming error — the dialog closes and the returned promise rejects\n * with that error.\n */\nexport type FieldValidator = (\n value: string,\n) => string | null | undefined | void;\n\n/** Options for {@link prompt}. */\n/**\n * Run a {@link FieldValidator}: the message it reports, or `undefined` when the\n * value is valid. Validators are synchronous — a promise result is a\n * programming error that closes the dialog and rejects its promise (the stray\n * promise's own rejection is silenced so it is not reported twice).\n * Internal to the dialog helpers.\n */\nexport function runValidator(\n validate: FieldValidator | undefined,\n value: string,\n owner: string,\n): string | undefined {\n const result: unknown = validate?.(value);\n if (typeof (result as PromiseLike<unknown> | null)?.then === 'function') {\n (result as PromiseLike<unknown>).then(undefined, () => undefined);\n throw new TypeError(`${owner}: validate returned a promise.`);\n }\n return typeof result === 'string' && result.length > 0 ? result : undefined;\n}\n\nexport interface PromptOptions {\n container?: Element;\n className?: string;\n title?: string;\n defaultValue?: string;\n placeholder?: string;\n inputType?: string;\n okText?: string;\n cancelText?: string;\n validate?: FieldValidator;\n native?: boolean;\n /** `'bottom-sheet'` presents the dialog as a bottom sheet (see `OverlayOptions.presentation`). Default `'modal'`. */\n presentation?: OverlayPresentation;\n /** Class added on close so CSS owns the exit; the node is removed after it (see `OverlayOptions.exitClass`). The promise settles at once. */\n exitClass?: string;\n /** The exit's hard cap in ms (see `OverlayOptions.exitDuration`). Default `0`. */\n exitDuration?: number;\n render?: (slots: PromptRenderSlots) => OverlayContent;\n}\n\n/** Wiring slots for a {@link PromptOptions.render}. */\nexport interface PromptRenderSlots {\n message: string;\n input: Record<string, string>;\n error: Record<string, string>;\n ok: Record<string, string>;\n cancel: Record<string, string>;\n}\n\n/** A promise-based `window.prompt` replacement. */\nexport function prompt(\n message: string,\n options: PromptOptions = {},\n): Promise<string | null> {\n const {\n container,\n className = 'kerf-overlay',\n title,\n defaultValue = '',\n placeholder,\n inputType = 'text',\n okText = 'OK',\n cancelText = 'Cancel',\n validate,\n native = false,\n presentation,\n exitClass,\n exitDuration,\n render,\n } = options;\n\n const inputAttrs: Record<string, string> = {\n 'data-prompt-input': '',\n type: inputType,\n value: defaultValue,\n ...(placeholder !== undefined ? { placeholder } : {}),\n };\n\n const body: OverlayContent =\n render !== undefined\n ? render({\n message,\n input: inputAttrs,\n error: { 'data-prompt-error': '' },\n ok: { 'data-prompt': 'ok' },\n cancel: { 'data-prompt': 'cancel' },\n })\n : jsx('div', {\n class: 'kerf-prompt',\n children: [\n title !== undefined\n ? jsx('h2', { class: 'kerf-prompt__title', children: title })\n : '',\n jsx('label', { class: 'kerf-prompt__message', children: message }),\n jsx('input', { class: 'kerf-prompt__input', ...inputAttrs }),\n jsx('p', {\n class: 'kerf-prompt__error',\n 'data-prompt-error': '',\n children: '',\n }),\n jsx('div', {\n class: 'kerf-prompt__actions',\n children: [\n jsx('button', {\n type: 'button',\n 'data-prompt': 'cancel',\n children: cancelText,\n }),\n jsx('button', {\n type: 'button',\n 'data-prompt': 'ok',\n class: 'kerf-prompt__ok',\n children: okText,\n }),\n ],\n }),\n ],\n });\n\n const handle = overlay(body, {\n container,\n className,\n dismiss: ['escape', 'backdrop'],\n initialFocus: '[data-prompt-input]',\n trap: true,\n native,\n presentation,\n exitClass,\n exitDuration,\n });\n\n // Post-open wiring is still construction: a missing required input or any\n // other throw below removes what was wired, closes the overlay, and rethrows.\n return wireDialog(\n handle,\n (track, guard) => {\n // Looked up again at OK: a reactive re-render may have replaced the\n // input, and a detached node would report a stale value. Missing at\n // construction is a render bug (rolls back, throws); missing at OK\n // rejects the promise through `guard`.\n const inputFor = (problem = 'render missing'): HTMLInputElement => {\n const input = handle.el.querySelector<HTMLInputElement>(\n 'input[data-prompt-input]',\n );\n if (input !== null) return input;\n throw new Error(`prompt(): ${problem} <input data-prompt-input>.`);\n };\n inputFor();\n const errorEl = handle.el.querySelector<HTMLElement>(\n '[data-prompt-error]',\n );\n if (errorEl !== null) errorEl.hidden = true;\n\n // A throwing (or promise-returning) `validate` closes the dialog and\n // rejects the promise (guard).\n const attemptOk = guard((): void => {\n const input = inputFor('removed after open:');\n const value = input.value;\n const error = runValidator(validate, value, 'prompt()');\n if (error !== undefined) {\n if (errorEl !== null) {\n errorEl.textContent = error;\n errorEl.hidden = false;\n }\n input.focus();\n return;\n }\n handle.close(value);\n });\n\n track(\n delegate(handle.el, 'click', '[data-prompt]', (_event, el) => {\n if (el.getAttribute('data-prompt') === 'ok') attemptOk();\n else handle.close(null);\n }),\n );\n\n const onKeydown = (event: KeyboardEvent): void => {\n if (\n event.key === 'Enter' &&\n (event.target as Element | null)?.matches('input[data-prompt-input]')\n ) {\n event.preventDefault();\n attemptOk();\n }\n };\n // Last wiring step: nothing after it can throw, so it needs no rollback.\n handle.el.addEventListener('keydown', onKeydown);\n },\n (value) => (typeof value === 'string' ? value : null),\n );\n}\n","/** `form()` implementation and public option types. */\nimport { delegate } from './delegate.js';\nimport { jsx } from './jsx-runtime.js';\nimport {\n overlay,\n type OverlayContent,\n type OverlayPresentation,\n wireDialog,\n} from './overlay-core.js';\nimport { type FieldValidator, runValidator } from './overlay-prompt.js';\n\n/** A single field in a {@link form}. */\nexport interface FormField {\n name: string;\n label?: string;\n defaultValue?: string;\n placeholder?: string;\n type?: string;\n validate?: FieldValidator;\n}\n\n/** One field's wiring in a {@link FormRenderSlots}. */\nexport interface FormRenderField {\n name: string;\n label: string;\n input: Record<string, string>;\n error: Record<string, string>;\n}\n\n/** Wiring slots for a {@link FormOptions.render}. */\nexport interface FormRenderSlots {\n fields: FormRenderField[];\n ok: Record<string, string>;\n cancel: Record<string, string>;\n}\n\n/** Options for {@link form}. */\nexport interface FormOptions {\n container?: Element;\n className?: string;\n title?: string;\n okText?: string;\n cancelText?: string;\n native?: boolean;\n /** `'bottom-sheet'` presents the dialog as a bottom sheet (see `OverlayOptions.presentation`). Default `'modal'`. */\n presentation?: OverlayPresentation;\n /** Class added on close so CSS owns the exit; the node is removed after it (see `OverlayOptions.exitClass`). The promise settles at once. */\n exitClass?: string;\n /** The exit's hard cap in ms (see `OverlayOptions.exitDuration`). Default `0`. */\n exitDuration?: number;\n render?: (slots: FormRenderSlots) => OverlayContent;\n}\n\n/** A promise-based multi-field dialog. */\nexport function form(\n fields: readonly FormField[],\n options: FormOptions = {},\n): Promise<Record<string, string> | null> {\n const {\n container,\n className = 'kerf-overlay',\n title,\n okText = 'OK',\n cancelText = 'Cancel',\n native = false,\n presentation,\n exitClass,\n exitDuration,\n render,\n } = options;\n\n const fieldAttrs = (field: FormField): Record<string, string> => ({\n 'data-field': field.name,\n name: field.name,\n type: field.type ?? 'text',\n value: field.defaultValue ?? '',\n ...(field.placeholder !== undefined\n ? { placeholder: field.placeholder }\n : {}),\n });\n\n const body: OverlayContent =\n render !== undefined\n ? render({\n fields: fields.map((field) => ({\n name: field.name,\n label: field.label ?? field.name,\n input: fieldAttrs(field),\n error: { 'data-field-error': field.name },\n })),\n ok: { 'data-form': 'ok' },\n cancel: { 'data-form': 'cancel' },\n })\n : jsx('div', {\n class: 'kerf-form',\n children: [\n title !== undefined\n ? jsx('h2', { class: 'kerf-form__title', children: title })\n : '',\n ...fields.map((field) =>\n jsx('div', {\n class: 'kerf-form__field',\n children: [\n jsx('label', {\n class: 'kerf-form__label',\n children: field.label ?? field.name,\n }),\n jsx('input', {\n class: 'kerf-form__input',\n ...fieldAttrs(field),\n }),\n jsx('p', {\n class: 'kerf-form__error',\n 'data-field-error': field.name,\n children: '',\n }),\n ],\n }),\n ),\n jsx('div', {\n class: 'kerf-form__actions',\n children: [\n jsx('button', {\n type: 'button',\n 'data-form': 'cancel',\n children: cancelText,\n }),\n jsx('button', {\n type: 'button',\n 'data-form': 'ok',\n class: 'kerf-form__ok',\n children: okText,\n }),\n ],\n }),\n ],\n });\n\n const handle = overlay(body, {\n container,\n className,\n dismiss: ['escape', 'backdrop'],\n initialFocus: '[data-field]',\n trap: true,\n native,\n presentation,\n exitClass,\n exitDuration,\n });\n\n // Post-open wiring is still construction: a missing required field input or\n // any other throw below removes what was wired, closes the overlay, and\n // rethrows.\n return wireDialog(\n handle,\n (track, guard) => {\n const errorFor = (name: string): HTMLElement | null =>\n Array.from(\n handle.el.querySelectorAll<HTMLElement>('[data-field-error]'),\n ).find((el) => el.getAttribute('data-field-error') === name) ?? null;\n // KF-HRNJ4T (a field input removed after open by a reactive re-render):\n // at construction a missing input is a render bug that rolls back and\n // throws synchronously; at OK time it throws inside `guard`, so the\n // dialog closes and the promise rejects naming the field — never a\n // `null` that reads as a user Cancel.\n const inputFor = (\n name: string,\n problem = 'render missing',\n ): HTMLInputElement => {\n const input = Array.from(\n handle.el.querySelectorAll<HTMLInputElement>('input[data-field]'),\n ).find((el) => el.getAttribute('data-field') === name);\n if (input !== undefined) return input;\n throw new Error(`form(): ${problem} <input data-field=\"${name}\">.`);\n };\n\n for (const field of fields) {\n inputFor(field.name);\n const errorEl = errorFor(field.name);\n if (errorEl !== null) errorEl.hidden = true;\n }\n\n // A throwing `field.validate` closes the dialog and rejects the promise.\n const attemptOk = guard((): void => {\n const record: Record<string, string> = {};\n let firstInvalid: HTMLInputElement | null = null;\n for (const field of fields) {\n const el = inputFor(field.name, 'removed after open:');\n const value = el.value;\n record[field.name] = value;\n const error = runValidator(field.validate, value, 'form()');\n const errorEl = errorFor(field.name);\n if (error !== undefined) {\n if (errorEl !== null) {\n errorEl.textContent = error;\n errorEl.hidden = false;\n }\n if (firstInvalid === null) firstInvalid = el;\n } else if (errorEl !== null) {\n errorEl.hidden = true;\n }\n }\n if (firstInvalid !== null) {\n firstInvalid.focus();\n return;\n }\n handle.close(record);\n });\n\n track(\n delegate(handle.el, 'click', '[data-form]', (_event, el) => {\n if (el.getAttribute('data-form') === 'ok') attemptOk();\n else handle.close(null);\n }),\n );\n\n const onKeydown = (event: KeyboardEvent): void => {\n if (\n event.key === 'Enter' &&\n (event.target as Element | null)?.matches('[data-field]')\n ) {\n event.preventDefault();\n attemptOk();\n }\n };\n // Last wiring step: nothing after it can throw, so it needs no rollback.\n handle.el.addEventListener('keydown', onKeydown);\n },\n (value) =>\n value !== null && typeof value === 'object'\n ? (value as Record<string, string>)\n : null,\n );\n}\n","/**\n * Anchored positioning primitives for `kerfjs/overlay` — position an element\n * relative to an anchor, with viewport flip + clamp. These are standalone: they\n * take any element and have no overlay lifecycle, so `popover()` / `tooltip()`\n * build on them but you can also position your own element (an inline hint, a\n * custom menu). Re-exported from `src/overlay.ts` so the public `kerfjs/overlay`\n * surface is unchanged (KF-511 split out of overlay.ts's dialog + toast code).\n */\n\n/** Vertical placement relative to an anchor (used by `popover`, {@link positionAnchored}, `tooltip`). */\nexport type PopoverPlacement = 'bottom' | 'top';\n\n/** Placement options for {@link positionAnchored} / {@link autoReposition}. */\nexport interface AnchorPositionOptions {\n /** Preferred side of the anchor; flips to the other side if it would overflow the viewport. Default `'bottom'`. */\n placement?: PopoverPlacement;\n /** Horizontal edge to line up with the anchor: `'start'` (left edges) or `'end'` (right edges). Default `'start'`. */\n align?: 'start' | 'end';\n /** Gap in px between the anchor and the element. Default `4`. */\n gap?: number;\n /**\n * Gutter in px kept between the element and the viewport edges: the\n * horizontal clamp stops this far inside the left and right edges, and a\n * side fits only when the element ends this far inside the top or bottom\n * edge. Default `0` (the bare viewport edge).\n */\n viewportMargin?: number;\n /**\n * The element's height can shrink (it scrolls its overflow). When neither\n * side has room for its full height, it takes the side with more room, and\n * that room — from the gap to the viewport margin, in `el`'s CSS px — is\n * published on `el` as the `--kerf-anchor-available-height` custom property\n * on every reposition. Cap the element with it, for example\n * `max-height: var(--kerf-anchor-available-height); overflow: auto`. The\n * height measured for that choice honors the element's own `max-height`\n * (read without the published property, so `max-height: min(300px,\n * var(--kerf-anchor-available-height))` counts as a 300px cap), so an\n * app-capped element that fits the preferred side stays there. A relative\n * cap (`60%`, `calc()`, `min()`, `clamp()`) is resolved against the\n * element's fixed-position containing block (normally the viewport), and a\n * `max-height` transition on the element neither skews that read nor runs\n * because of it. While an animation or transition is already driving\n * `max-height` (an expand-from-0 entrance, a `@keyframes` animation), the\n * cap is the value it is headed to, and it is left running. An above\n * placement is pinned by its bottom edge (`bottom`, with `top: auto`), so\n * the element grows and shrinks upward, away from the anchor, as its height\n * changes between repositions; a below placement sets `top` with\n * `bottom: auto`. Default `false`.\n */\n fitHeight?: boolean;\n}\n\n/** The custom property `fitHeight` publishes on the positioned element. */\nconst AVAILABLE_HEIGHT = '--kerf-anchor-available-height';\n\n/**\n * One-shot: position `el` relative to `anchor` — below by default, flipping above\n * if it would overflow the viewport, aligned to a horizontal edge and clamped into\n * view. Sets `el.style` `position: fixed`, `margin: 0`, `left`, and `top` (fixed so\n * `left`/`top` are viewport coordinates, matching `getBoundingClientRect`). When an\n * ancestor makes itself the containing block for fixed descendants (a\n * `transform`, `filter`, `perspective`, or `contain` on a wrapping `<dialog>`),\n * `left`/`top` are translated (and unscaled) into that box's coordinates so `el`\n * still lands next to the anchor. `viewportMargin` keeps a gutter from the\n * viewport edges; `fitHeight` publishes the room on the chosen side so CSS can\n * cap a scrolling element to it, and pins an above placement by `bottom`\n * (with `top: auto`) so the element grows upward from the anchor. This is\n * `popover()`'s placement core, usable on any element (an inline hint, a tooltip) —\n * no overlay lifecycle. Pair with {@link autoReposition} to keep it glued while open.\n */\nexport function positionAnchored(\n el: HTMLElement,\n anchor: Element,\n options: AnchorPositionOptions = {},\n): void {\n const {\n placement = 'bottom',\n align = 'start',\n gap = 4,\n viewportMargin = 0,\n fitHeight = false,\n } = options;\n // Fix `el` FIRST, then measure it. Measuring a still-`display:block` wrapper\n // reports the full body-content width (≈ viewport minus body margins), which\n // collapses the horizontal clamp below and lands the element at the body's left\n // edge. As a fixed, shrink-to-fit box its `width`/`height` are its real size.\n el.style.position = 'fixed';\n el.style.margin = '0';\n const anchorRect = anchor.getBoundingClientRect();\n const elementRect = el.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n // Vertical: preferred side, flipped only if it overflows and the other side\n // fits. A height-flexible element that fits neither side takes the roomier one.\n const height = fitHeight ? fullHeight(el, elementRect) : elementRect.height;\n const belowTop = anchorRect.bottom + gap;\n const roomBelow = viewportHeight - viewportMargin - belowTop;\n const roomAbove = anchorRect.top - gap - viewportMargin;\n let below = placement !== 'top';\n if (height > roomBelow && height > roomAbove) {\n if (fitHeight) below = roomBelow >= roomAbove;\n } else if (below && height > roomBelow) below = false;\n else if (!below && height > roomAbove) below = true;\n\n // Horizontal: align to an anchor edge, then clamp inside the viewport gutter.\n let left =\n align === 'end' ? anchorRect.right - elementRect.width : anchorRect.left;\n left = Math.max(\n viewportMargin,\n Math.min(left, viewportWidth - viewportMargin - elementRect.width),\n );\n\n // `left`/`top` so far are viewport coordinates. They are only the CSS values\n // too when `el`'s fixed-position containing block is the viewport; an\n // ancestor with a `transform`, `filter`, `perspective`, `contain`, … (say a\n // modal `<dialog>` holding an overlay host slot) captures fixed descendants,\n // so map the coordinates into that box's space.\n const [originX, originY, scaleX, scaleY] = fixedOrigin(el);\n el.style.left = `${(left - originX) / scaleX}px`;\n if (fitHeight) {\n const room = Math.max(0, below ? roomBelow : roomAbove);\n el.style.setProperty(AVAILABLE_HEIGHT, `${room / scaleY}px`);\n if (!below) {\n // Above, a height-flexible element hangs from its bottom edge. Pin\n // `bottom` instead of deriving `top` from a height measured now, so\n // whatever height it goes on to lay out (the cap from the room just\n // published, a `max-height` expand still running, content that grows)\n // grows and shrinks upward, away from the anchor, never over it.\n const edge = anchorRect.top - gap;\n el.style.top = 'auto';\n el.style.bottom = `${(fixedBottom(el, originY, scaleY) - edge) / scaleY}px`;\n return;\n }\n el.style.bottom = 'auto';\n }\n const top = below ? belowTop : anchorRect.top - gap - height;\n el.style.top = `${(top - originY) / scaleY}px`;\n}\n\n/**\n * The height `el` would take without the cap a previous reposition published:\n * its laid-out height plus whatever it currently scrolls, but no more than its\n * own `max-height` (see {@link ownMaxHeight}). Read from scroll metrics rather\n * than by lifting the cap, which would reset the element's own scroll position\n * — and every scroll inside it repositions it. Scroll metrics and `max-height`\n * are CSS px, so they are scaled into the viewport px of `rect`.\n */\nfunction fullHeight(el: HTMLElement, rect: DOMRect): number {\n const scale = el.offsetHeight ? rect.height / el.offsetHeight : 1;\n const full =\n rect.height + Math.max(0, el.scrollHeight - el.clientHeight) * scale;\n return Math.min(full, ownMaxHeight(el) * scale);\n}\n\n/** The vertical padding and border a `content-box` `max-height` excludes. */\nconst VERTICAL_EDGES = [\n 'paddingTop',\n 'paddingBottom',\n 'borderTopWidth',\n 'borderBottomWidth',\n] as const;\n\n/**\n * The stand-in room published while {@link ownMaxHeight} reads the element's\n * own cap: large enough that it never binds, and a valid length so a cap such\n * as `min(300px, var(--kerf-anchor-available-height))` still resolves (removing\n * the property would make that declaration invalid, so `none`).\n */\nconst UNBOUNDED_ROOM = '9999999px';\n\n/**\n * The inline properties {@link ownMaxHeight} overrides around its read, in\n * restore order: the published room, then the transition longhands.\n */\nconst SWAPPED = [\n AVAILABLE_HEIGHT,\n 'transition-property',\n 'transition-duration',\n 'transition-delay',\n];\n\n/**\n * `el`'s own border-box `max-height` in CSS px, excluding the room kerf\n * itself published. The published property is swapped for an unbounded room\n * only around a computed-style read (a style recalc, no layout, so nothing\n * reflows or scrolls) and restored at once, so kerf never reads its own last\n * cap back as the element's.\n *\n * A `max-height` transition would report its running value for that read (the\n * published room, not the cap) and start a transition on the swap, so for the\n * read `max-height` is appended to the element's transition list with no\n * duration or delay (the last entry for a property wins); every other running\n * transition keeps running. The restored cap is settled before the app's\n * transitions return, so they see no change to animate.\n *\n * While an animation or transition on `el` drives `max-height`, the cap is\n * the value it is headed to ({@link animatedMaxHeight}) and nothing is\n * swapped.\n *\n * A cap that stays relative after computing (a percentage, `calc()`,\n * `min()`, `clamp()`) is resolved against `el`'s containing block by\n * {@link resolveHeight}; a keyword (`none`, `fit-content`) is no cap.\n */\nfunction ownMaxHeight(el: HTMLElement): number {\n const style = window.getComputedStyle(el);\n const maxHeight = animatedMaxHeight(el) ?? swappedMaxHeight(el, style);\n const inset =\n style.boxSizing === 'border-box'\n ? 0\n : VERTICAL_EDGES.reduce(\n (sum, edge) => sum + (Number.parseFloat(style[edge]) || 0),\n 0,\n );\n if (maxHeight.endsWith('px')) return Number.parseFloat(maxHeight) + inset;\n // A keyword is no cap, and so is a keyframe `var()` that only `el` could\n // resolve (the probe does not inherit `el`'s custom properties).\n if (/^[a-z-]+$|var\\(/.test(maxHeight)) return Infinity;\n return resolveHeight(el, maxHeight) + inset;\n}\n\n/**\n * `el`'s computed `max-height` with the published room swapped out, as\n * {@link ownMaxHeight} describes: the room and, when `el` has transitions,\n * the transition longhands are overridden for the read and restored exactly.\n */\nfunction swappedMaxHeight(el: HTMLElement, style: CSSStyleDeclaration): string {\n const inline = el.style;\n const saved = SWAPPED.map((name): [string, string, string] => [\n name,\n inline.getPropertyValue(name),\n inline.getPropertyPriority(name),\n ]);\n // The computed transition lists, read before any of them is overridden.\n const lists = SWAPPED.map((name) => style.getPropertyValue(name).split(','));\n const transitions = lists[1]!;\n if (transitions[0] && transitions[0] !== 'none') {\n // Repeat the duration and delay lists to the property list's length, as\n // CSS does, so appending an entry leaves every existing pairing intact.\n for (let index = 1; index < 4; index++) {\n const items = lists[index]!;\n inline.setProperty(\n SWAPPED[index]!,\n [\n ...transitions.map((_, entry) => items[entry % items.length]),\n index > 1 ? '0s' : 'max-height',\n ].join(),\n 'important',\n );\n }\n }\n inline.setProperty(AVAILABLE_HEIGHT, UNBOUNDED_ROOM);\n const maxHeight = style.maxHeight;\n saved.forEach(([name, value, priority], index) => {\n if (value) inline.setProperty(name, value, priority);\n else inline.removeProperty(name);\n // Settle the restored room before the transitions return.\n if (!index) style.getPropertyValue('max-height');\n });\n return maxHeight;\n}\n\n/**\n * The `max-height` an unfinished animation or transition on `el` is headed\n * to, or `undefined` when none drives it. While one runs (or is paused), the\n * computed value is its current frame — part-way through an app's expand\n * transition, or a `@keyframes` value — not the cap the element settles at,\n * and lifting the published room could retarget or cancel the app's\n * transition. So the cap is read from the effect instead: its last\n * `max-height` keyframe, or its first while the current iteration plays in\n * reverse. The topmost such effect in composite order wins; a finished one\n * that still fills already shows its final value in computed style.\n */\nfunction animatedMaxHeight(el: HTMLElement): string | undefined {\n // An engine (or DOM shim) without Web Animations has nothing animating.\n const animations = el.getAnimations?.() ?? [];\n for (let index = animations.length - 1; index >= 0; index--) {\n const animation = animations[index]!;\n const effect = animation.effect as KeyframeEffect | null;\n const frames = (effect?.getKeyframes() ?? []).filter(\n (frame) => frame['maxHeight'] != null,\n );\n if (!frames.length) continue;\n if (animation.playState === 'finished') return undefined;\n const { direction, currentIteration } = effect!.getComputedTiming();\n const odd = (currentIteration ?? 0) % 2 === 1;\n const reversed =\n (direction === 'reverse' ||\n (direction === 'alternate' && odd) ||\n (direction === 'alternate-reverse' && !odd)) !==\n animation.playbackRate < 0;\n return String(frames[reversed ? 0 : frames.length - 1]!['maxHeight']);\n }\n return undefined;\n}\n\n/**\n * Resolve a computed but still relative height (`60%`, `calc(50% - 1rem)`,\n * `min(300px, 60%)`) to CSS px against `el`'s fixed-position containing block\n * — the viewport, or a transformed ancestor: a fixed probe beside `el` takes it\n * as its `height`, and the probe's used height is read back. `el` itself is\n * never touched, so its scroll position and layout are unaffected. A height\n * the probe cannot take, or a detached `el`, is no cap.\n */\nfunction resolveHeight(el: HTMLElement, height: string): number {\n return withFixedProbe(\n el,\n 'width:0;box-sizing:content-box;min-height:0;max-height:none;visibility:hidden',\n (probe) => {\n probe.style.height = height;\n if (!probe.style.height) return Infinity;\n return Number.parseFloat(window.getComputedStyle(probe).height);\n },\n Infinity,\n );\n}\n\n/**\n * Run `measure` on a fixed-position probe at `left: 0; top: 0`, inserted just\n * before `el` so it shares `el`'s containing block, then remove it. The probe\n * is inserted and removed synchronously, so it is never painted. A detached\n * `el` has no containing block to share, so `detached` is returned instead.\n */\nfunction withFixedProbe<T>(\n el: HTMLElement,\n css: string,\n measure: (probe: HTMLElement) => T,\n detached: T,\n): T {\n const parent = el.parentNode;\n if (!parent) return detached;\n const probe = el.ownerDocument.createElement('div');\n probe.style.cssText = `position:fixed;left:0;top:0;display:block;margin:0;padding:0;border:0;${css}`;\n parent.insertBefore(probe, el);\n const result = measure(probe);\n probe.remove();\n return result;\n}\n\n/**\n * Where `left: 0; top: 0` actually lands for a fixed-position child of `el`'s\n * parent, plus that containing block's scale — `[x, y, scaleX, scaleY]`, which\n * is `[0, 0, 1, 1]` when the viewport is the containing block. Measured with a\n * 1px probe rather than `el` itself so `el`'s own transform or running entrance\n * animation cannot skew it. Translation and scale are compensated; a rotated\n * or skewed containing block is not.\n */\nfunction fixedOrigin(el: HTMLElement): [number, number, number, number] {\n return withFixedProbe(\n el,\n 'width:1px;height:1px',\n (probe): [number, number, number, number] => {\n const rect = probe.getBoundingClientRect();\n // A zero size (a containing block mid `scale(0)` animation, or a DOM\n // without layout) would divide by zero; treat it as unscaled.\n return [rect.left, rect.top, rect.width || 1, rect.height || 1];\n },\n [0, 0, 1, 1],\n );\n}\n\n/**\n * The viewport y of the bottom edge of `el`'s fixed-position containing block\n * (where `bottom: 0` lands), measured with a 1px probe pinned there. A\n * detached `el`, or a containing block with no layout (a DOM without layout,\n * a `scale(0)` animation), falls back to the viewport height below the origin\n * {@link fixedOrigin} measured, at its scale.\n */\nfunction fixedBottom(el: HTMLElement, originY: number, scaleY: number): number {\n const fallback = originY + window.innerHeight * scaleY;\n return withFixedProbe(\n el,\n 'width:1px;height:1px;top:auto;bottom:0',\n (probe) => {\n const rect = probe.getBoundingClientRect();\n return rect.height ? rect.bottom : fallback;\n },\n fallback,\n );\n}\n\n/**\n * Keep `el` positioned against `anchor` (via {@link positionAnchored}) as the page\n * scrolls or resizes. Positions once immediately, then re-runs on `scroll`\n * (capture phase — catches scrolls in any inner container, not just `window`) and\n * `resize`. Returns a disposer that removes the listeners.\n */\nexport function autoReposition(\n el: HTMLElement,\n anchor: Element,\n options: AnchorPositionOptions = {},\n): () => void {\n const reposition = (): void => positionAnchored(el, anchor, options);\n reposition();\n window.addEventListener('scroll', reposition, true);\n window.addEventListener('resize', reposition);\n return () => {\n window.removeEventListener('scroll', reposition, true);\n window.removeEventListener('resize', reposition);\n };\n}\n","/** Anchored popover lifecycle built on the shared overlay transaction. */\nimport { attach } from './attach.js';\nimport {\n anchorOverlay,\n type DismissTrigger,\n INSTANT,\n overlay,\n type OverlayContent,\n type OverlayHandle,\n overlayHost,\n} from './overlay-core.js';\nimport { autoReposition, type PopoverPlacement } from './overlay-position.js';\n\n/** Options for {@link popover}. */\nexport interface PopoverOptions {\n /**\n * Where to append the popover wrapper. Default: when `anchor` sits inside an\n * open modal `<dialog>`, that dialog's `[data-kerf-overlay-host]` element (a\n * dialog kerf opened gets one automatically), so the popover is part of the\n * modal subtree and stays interactive; otherwise `document.body`. A modal\n * `<dialog>` in a shadow root counts when `anchor` is slotted into it (Web\n * Awesome's `wa-dialog` / `wa-drawer`): the slot is created on demand in the\n * shadow host's light DOM. A popover inside a modal closes when that dialog\n * closes.\n */\n container?: Element;\n /** Class on the wrapper. Default `'kerf-popover'`. */\n className?: string;\n /** Preferred side of the anchor. Flips to the other side if it would overflow the viewport. Default `'bottom'`. */\n placement?: PopoverPlacement;\n /** Horizontal edge to line up with the anchor: `'start'` (left edges) or `'end'` (right edges). Default `'start'`. */\n align?: 'start' | 'end';\n /** Gap in px between the anchor and the popover. Default `4`. */\n gap?: number;\n /** Gutter in px kept from the viewport edges. See `AnchorPositionOptions.viewportMargin`. Default `0`. */\n viewportMargin?: number;\n /**\n * Fit a scrolling popover to the room beside the anchor: take the roomier\n * side when neither fits and publish that room as\n * `--kerf-anchor-available-height`. See `AnchorPositionOptions.fitHeight`.\n * Default `false`.\n */\n fitHeight?: boolean;\n /**\n * Which user actions dismiss the popover. Default `['outside']` (a click\n * outside the popover, the anchor exempt). Pass `false` to close only via `close()`.\n */\n dismiss?: DismissTrigger | DismissTrigger[] | false;\n /** Focus behavior on open. Default `false` (non-modal — leave focus alone). */\n initialFocus?: string | boolean;\n /** Extra elements (besides the anchor) whose clicks do NOT count as outside. */\n outsideIgnore?: Element | readonly Element[];\n /** Called on any user-initiated dismissal. */\n onDismiss?: () => void;\n /**\n * Host the popover in the browser top layer (the Popover API — `[popover]` +\n * `showPopover()`) where supported, so it stacks above any `z-index` without a\n * z-index war. Falls back to today's plain `<div>` where unsupported. kerf keeps\n * owning positioning + its own dismiss wiring; the popover is `popover=\"manual\"`.\n * See {@link OverlayOptions.native}. Default `false`.\n */\n native?: boolean;\n /**\n * Class added when the popover closes, so CSS owns its **exit**. See\n * {@link OverlayOptions.exitClass}: `close()` and a user dismissal play it;\n * the teardown when the anchor leaves the document is instant.\n */\n exitClass?: string;\n /** The exit's hard cap in ms. See {@link OverlayOptions.exitDuration}. Default `0`. */\n exitDuration?: number;\n}\n\n/**\n * Anchored, non-modal overlay: positions `content` relative to `anchor` (below by\n * default, flipping above if it would overflow, and clamped horizontally to the\n * viewport) and repositions on scroll / resize while open. A thin wrapper over\n * {@link overlay} with non-modal defaults — `trap: false`, `dismiss: ['outside']`,\n * and the anchor added to `outsideIgnore` so the trigger click doesn't self-close.\n * Returns the same {@link OverlayHandle}; `close()` also drops the reposition\n * listeners. `position: fixed` is set inline (you style everything else).\n */\nexport function popover(\n anchor: Element,\n content: OverlayContent,\n options: PopoverOptions = {},\n): OverlayHandle {\n const {\n container,\n className = 'kerf-popover',\n placement = 'bottom',\n align = 'start',\n gap = 4,\n viewportMargin,\n fitHeight,\n dismiss = ['outside'],\n initialFocus = false,\n outsideIgnore,\n onDismiss,\n native = false,\n exitClass,\n exitDuration,\n } = options;\n\n const extraIgnore =\n outsideIgnore === undefined\n ? []\n : Array.isArray(outsideIgnore)\n ? [...outsideIgnore]\n : [outsideIgnore];\n\n const handle = overlay(content, {\n container: container ?? overlayHost(anchor),\n className,\n dismiss,\n trap: false,\n initialFocus,\n onDismiss,\n outsideIgnore: [anchor, ...extraIgnore],\n native,\n exitClass,\n exitDuration,\n });\n\n // Position + keep it glued while open; drop the listeners on close. A throw\n // while positioning (e.g. an anchor whose geometry read fails) is still part\n // of construction: close the just-opened overlay before rethrowing.\n let stopReposition: () => void;\n try {\n stopReposition = autoReposition(handle.el, anchor, {\n placement,\n align,\n gap,\n viewportMargin,\n fitHeight,\n });\n } catch (error) {\n handle.close(undefined, INSTANT);\n throw error;\n }\n void handle.result.then(stopReposition);\n // KF-XNEK58: an overlay holding the anchor closes this popover at its own\n // close(), not when its (possibly exiting) node is finally removed.\n anchorOverlay(handle, anchor);\n\n // KF-BAVCEV: never outlive the anchor. When it leaves the document (e.g. the\n // modal holding it closes) close the popover as cleanup — not a user\n // dismissal, so no `onDismiss`. A move within the document keeps it open.\n // Instant, like construction rollback: there is no anchor left to exit from.\n // The watch's own disposal at `result` runs this teardown too, with the\n // anchor still connected — an exit then starting must not end.\n void handle.result.then(\n attach(anchor, () => () => {\n if (!anchor.isConnected) handle.close(undefined, INSTANT);\n }),\n );\n\n return handle;\n}\n","/**\n * `toast()` for `kerfjs/overlay` — a non-modal, auto-dismissing notification that\n * stacks in a shared body-level region. Split out of `overlay.ts` (KF-513) since\n * it's a distinct transient-UI concern from the modal dialogs; re-exported from\n * `overlay.ts` so the public `kerfjs/overlay` surface is unchanged. Structural\n * only — kerf ships no CSS; you style the region / toast / animations.\n */\nimport { type SafeHtml } from './jsx-runtime.js';\nimport { mount, type MountResult } from './mount.js';\nimport { escapeHtml } from './utils/escapeHtml.js';\n\n/** Content for a {@link toast}: an escaped text string, trusted `SafeHtml`, or a render function. */\nexport type ToastContent = string | SafeHtml | (() => MountResult);\n\n/** Accent variant for a {@link toast} — mapped to a `${className}--${variant}` class. */\nexport type ToastVariant = 'info' | 'success' | 'warning';\n\n/** Options for {@link toast}. */\nexport interface ToastOptions {\n /** Where toasts stack. Default: a lazily-created `<div class=\"kerf-toasts\">` on `document.body`. */\n container?: Element;\n /** Class on the toast element. Default `'kerf-toast'`. */\n className?: string;\n /** Auto-dismiss after this many ms. `0` keeps it until dismissed by hand. Default `4000`. */\n duration?: number;\n /** ARIA role. Default `'status'`. */\n role?: string;\n /**\n * `'stack'` (default) shows toasts stacked in the region; `'replace'` dismisses\n * the region's current toast(s) first (collapse-to-latest for a rapid sequence).\n */\n mode?: 'stack' | 'replace';\n /**\n * How `mode: 'replace'` drops the prior toast(s): `'fade'` (default) runs their\n * full exit transition (nice for a STACKING region), or `'instant'` removes them\n * synchronously with no exit — what a single, exactly-centered toast slot wants,\n * so the outgoing and incoming messages never cross-fade in the same spot.\n */\n collapse?: 'fade' | 'instant';\n /** Accent variant — adds a `${className}--${variant}` class (kerf ships no CSS; you style it). */\n variant?: ToastVariant;\n /** Class added on the next animation frame after mount, so a CSS **entrance** transition can run. */\n enterClass?: string;\n /**\n * Class added when dismissing, so CSS owns the **exit**. On dismiss the\n * `enterClass` (if any) is also REMOVED, so `exitClass` doesn't have to\n * out-specify it — and a symmetric single-class fade (entrance = add\n * `enterClass`, exit = remove it) works by setting only `enterClass` +\n * `exitDuration`. The node is removed `exitDuration` ms later.\n */\n exitClass?: string;\n /** ms to wait before removing the node on dismiss — applies when `exitClass` is set OR when it's > 0 (to let a removed `enterClass` transition out). Default `0`. */\n exitDuration?: number;\n}\n\n/** Handle returned by {@link toast}. */\nexport interface ToastHandle {\n /** The toast element — inspect it, or run your own entrance/exit transitions. */\n el: HTMLElement;\n /**\n * Dismiss it early. Default runs the `exitClass` transition (removed after\n * `exitDuration`); pass `{ instant: true }` to remove it **synchronously** with\n * no exit — for an action button that immediately shows a replacement toast in a\n * single centered slot (no cross-fade). Idempotent.\n */\n dismiss(options?: { instant?: boolean }): void;\n}\n\n/** The region's active toasts live on the region element (in the DOM), not in module state. */\nconst TOAST_SET = Symbol('kerf.toasts');\n/** A dismiss function with an `.removeNow()` for instant (no-exit) teardown. */\ntype Dismisser = (() => void) & { removeNow: () => void };\ntype ToastCarrier = Element & { [TOAST_SET]?: Set<Dismisser> };\n\n/** The singleton toast region lives in the DOM (queried, not held in a module variable). */\nfunction toastRegion(container?: Element): Element {\n if (container !== undefined) return container;\n const existing = document.querySelector('.kerf-toasts');\n if (existing !== null) return existing;\n const region = document.createElement('div');\n region.className = 'kerf-toasts';\n region.setAttribute('aria-live', 'polite');\n document.body.appendChild(region);\n return region;\n}\n\n/**\n * Show a non-modal, auto-dismissing notification. Stacks in a shared body-level\n * region (or your `container`). Returns a {@link ToastHandle} (`{ el, dismiss }`)\n * so you can run entrance/exit transitions, wire an action button, or inspect the\n * node. `mode: 'replace'` collapses a rapid sequence to the latest; `variant`\n * adds an accent class; `enterClass`/`exitClass` let CSS own the animation.\n */\nexport function toast(\n content: ToastContent,\n options: ToastOptions = {},\n): ToastHandle {\n const {\n container,\n className = 'kerf-toast',\n duration = 4000,\n role = 'status',\n mode = 'stack',\n collapse = 'fade',\n variant,\n enterClass,\n exitClass,\n exitDuration = 0,\n } = options;\n\n const region = toastRegion(container) as ToastCarrier;\n const active = (region[TOAST_SET] ??= new Set<Dismisser>());\n // collapse-to-latest: 'instant' removes priors synchronously (no cross-fade in a\n // centered single slot); 'fade' runs their exit transition (nice for a stack).\n if (mode === 'replace') {\n for (const d of [...active]) {\n if (collapse === 'instant') d.removeNow();\n else d();\n }\n }\n\n const el = document.createElement('div');\n el.className = className;\n if (variant !== undefined) el.classList.add(`${className}--${variant}`);\n el.setAttribute('role', role);\n region.appendChild(el);\n\n const render =\n typeof content === 'function'\n ? content\n : () => (typeof content === 'string' ? escapeHtml(content) : content);\n const disposeMount = mount(el, render);\n const state: {\n dismissed: boolean;\n removed: boolean;\n timer: ReturnType<typeof setTimeout> | undefined;\n exitTimer: ReturnType<typeof setTimeout> | undefined;\n } = {\n dismissed: false,\n removed: false,\n timer: undefined,\n exitTimer: undefined,\n };\n\n if (enterClass !== undefined) {\n globalThis.requestAnimationFrame(() => {\n if (!state.dismissed) el.classList.add(enterClass);\n });\n }\n\n const remove = (): void => {\n if (state.removed) return;\n state.removed = true;\n state.dismissed = true; // once removed, a later dismiss() is a clean no-op\n if (state.exitTimer !== undefined) clearTimeout(state.exitTimer);\n disposeMount();\n el.remove();\n active.delete(dismiss as Dismisser);\n };\n\n // Force synchronous teardown NOW, with no exit transition — even if a fade is\n // already in flight (so `mode:'replace'` collapse can clean up a mid-exit toast,\n // and `dismiss({ instant: true })` drops it immediately).\n const removeNow = (): void => {\n if (state.timer !== undefined) clearTimeout(state.timer);\n remove();\n };\n\n const fadeOut = (): void => {\n if (state.dismissed) return;\n state.dismissed = true;\n if (state.timer !== undefined) clearTimeout(state.timer);\n // Reverse the entrance (drop enterClass so exitClass needn't out-specify it),\n // add exitClass, and delay removal for the transition — including the\n // single-class idiom (enterClass removed + exitDuration, no exitClass).\n if (enterClass !== undefined) el.classList.remove(enterClass);\n if (exitClass !== undefined) el.classList.add(exitClass);\n if (exitClass !== undefined || exitDuration > 0) {\n state.exitTimer = setTimeout(remove, exitDuration);\n } else {\n remove();\n }\n };\n\n function dismiss(options?: { instant?: boolean }): void {\n if (options?.instant === true) removeNow();\n else fadeOut();\n }\n (dismiss as Dismisser).removeNow = removeNow;\n\n active.add(dismiss as Dismisser);\n if (duration > 0) state.timer = setTimeout(fadeOut, duration);\n return { el, dismiss };\n}\n","/** Hover and focus tooltip lifecycle built on the shared overlay transaction. */\nimport { attach } from './attach.js';\nimport { jsx, type SafeHtml } from './jsx-runtime.js';\nimport type { MountResult } from './mount.js';\nimport {\n anchorOverlay,\n INSTANT,\n overlay,\n type OverlayCloseOptions,\n type OverlayContent,\n type OverlayHandle,\n overlayHost,\n} from './overlay-core.js';\nimport {\n type AnchorPositionOptions,\n autoReposition,\n} from './overlay-position.js';\n\n/** Content for a {@link tooltip}: text (auto-escaped), `SafeHtml`, or a render function. */\nexport type TooltipContent = string | SafeHtml | (() => MountResult);\n\n/** Options for {@link tooltip}. */\nexport interface TooltipOptions extends AnchorPositionOptions {\n /** Where to append the tooltip wrapper. Default: the anchor's modal-dialog host slot (see {@link PopoverOptions.container}), else `document.body`. */\n container?: Element;\n /** Class on the wrapper. Default `'kerf-tooltip'`. */\n className?: string;\n /** Delay in ms before showing after hover/focus enters. Default `400`. */\n delay?: number;\n /** Delay in ms before hiding after hover/focus leaves. Default `100`. */\n hideDelay?: number;\n /** ARIA role on the wrapper. Default `'tooltip'`. */\n role?: string;\n /** Host the tooltip in the browser top layer (the Popover API) where supported. See {@link OverlayOptions.native}. Default `false`. */\n native?: boolean;\n /**\n * Class added when the tooltip hides, so CSS owns its **exit**. See\n * {@link OverlayOptions.exitClass}: the hide after `hideDelay` plays it;\n * the anchor leaving the document and the disposer hide instantly. Showing\n * again while the previous tooltip is still exiting removes that leaving\n * node at once and opens a fresh one, so an anchor never has two.\n */\n exitClass?: string;\n /** The exit's hard cap in ms. See {@link OverlayOptions.exitDuration}. Default `0`. */\n exitDuration?: number;\n}\n\n/**\n * A hover/focus-triggered, non-modal, auto-hiding tooltip anchored to `anchor`.\n * Shows after `delay` on `pointerenter`/`focus`, hides after `hideDelay` on\n * `pointerleave`/`blur`, and positions itself with {@link autoReposition} (above\n * the anchor by default). Unlike {@link popover} there is no click-dismiss model —\n * it follows the pointer/focus. Returns a disposer that removes the anchor\n * listeners and hides any shown tooltip at once (ending a running exit, too).\n * Structural only (kerf ships no CSS).\n */\nexport function tooltip(\n anchor: Element,\n content: TooltipContent,\n options: TooltipOptions = {},\n): () => void {\n const {\n container,\n className = 'kerf-tooltip',\n delay = 400,\n hideDelay = 100,\n role = 'tooltip',\n placement = 'top',\n align = 'start',\n gap = 4,\n viewportMargin,\n fitHeight,\n native = false,\n exitClass,\n exitDuration,\n } = options;\n\n const body: OverlayContent =\n typeof content === 'function'\n ? content\n : typeof content === 'string'\n ? jsx('span', { class: `${className}__text`, children: content })\n : content;\n\n const timers: {\n show?: ReturnType<typeof setTimeout>;\n hide?: ReturnType<typeof setTimeout>;\n } = {};\n let current:\n | { handle: OverlayHandle; stop: () => void; unwatch: () => void }\n | undefined;\n // The previous tooltip while its exit runs (or already removed — closing it\n // again instantly is then a no-op).\n let leaving: OverlayHandle | undefined;\n let presence = 0;\n\n // Runs from the `delay` timer, so there is no caller to throw to. A failed\n // show (a throwing render fn, `native` `showPopover()`, or positioning) is\n // rolled back before `current` is set — nothing stays on screen and the\n // next pointerenter / focus schedules a fresh attempt — and the original\n // error then escapes the timer callback for the host to report as uncaught\n // (a window `error` event in browsers), the same way kerf's other deferred\n // callbacks (debounce / throttle timers, attach teardown) surface errors.\n function show(): void {\n // The anchor left the document while the show was pending (KF-BAVCEV),\n // or sits in an inert subtree — e.g. an overlay already exiting (KF-XNEK58).\n if (!anchor.isConnected || anchor.closest('[inert]') !== null) return;\n // One tooltip per anchor: a show during the previous one's exit ends that\n // exit now. Both happen in this task, so no frame paints without a tooltip.\n leaving?.close(undefined, INSTANT);\n leaving = undefined;\n const handle = overlay(body, {\n container: container ?? overlayHost(anchor),\n className,\n dismiss: false,\n trap: false,\n initialFocus: false,\n native,\n exitClass,\n exitDuration,\n });\n handle.el.setAttribute('role', role);\n let stop: () => void;\n try {\n stop = autoReposition(handle.el, anchor, {\n placement,\n align,\n gap,\n viewportMargin,\n fitHeight,\n });\n } catch (error) {\n // Not yet tracked in `current`, so `hide()` could never reach it.\n handle.close(undefined, INSTANT);\n throw error;\n }\n // KF-BAVCEV: an anchor removed from the document (e.g. with the modal that\n // held it) fires no pointerleave / blur, so hide when it leaves and forget\n // its presence; a move within the document keeps the tooltip shown. No\n // exit: there is no anchor left to exit from.\n const unwatch = attach(anchor, () => () => drop(INSTANT));\n current = { handle, stop, unwatch };\n // KF-XNEK58: an overlay holding the anchor that closes hides this tooltip\n // at its close(), with an exit only when that overlay exits too.\n anchorOverlay(handle, anchor, (now) => drop(now ? INSTANT : undefined));\n // A surface that closed itself (its host slot left the document with the\n // dialog) must not stay `current`, or the next hover would never show.\n void handle.result.then(() => {\n if (current?.handle === handle) hide();\n });\n }\n\n // The anchor is gone (or its host is closing): forget presence and hide.\n function drop(closeOptions?: OverlayCloseOptions): void {\n presence = 0;\n if (timers.hide !== undefined) clearTimeout(timers.hide);\n hide(closeOptions);\n }\n\n function hide(closeOptions?: OverlayCloseOptions): void {\n const shown = current;\n if (shown === undefined) return;\n // Cleared first: `unwatch()` runs the anchor teardown, which re-enters here.\n current = undefined;\n shown.unwatch();\n shown.stop();\n shown.handle.close(undefined, closeOptions);\n leaving = shown.handle;\n }\n\n const onEnter = (event: Event): void => {\n presence |= event.type === 'focus' ? 2 : 1;\n if (timers.hide !== undefined) clearTimeout(timers.hide);\n if (current !== undefined) return;\n if (timers.show !== undefined) clearTimeout(timers.show); // debounce: one pending show at a time\n timers.show = setTimeout(show, delay);\n };\n const onLeave = (event: Event): void => {\n presence &= event.type === 'blur' ? ~2 : ~1;\n if (presence) return;\n if (timers.show !== undefined) clearTimeout(timers.show);\n if (current === undefined) return;\n timers.hide = setTimeout(() => hide(), hideDelay);\n };\n\n anchor.addEventListener('pointerenter', onEnter);\n anchor.addEventListener('pointerleave', onLeave);\n anchor.addEventListener('focus', onEnter);\n anchor.addEventListener('blur', onLeave);\n\n return () => {\n anchor.removeEventListener('pointerenter', onEnter);\n anchor.removeEventListener('pointerleave', onLeave);\n anchor.removeEventListener('focus', onEnter);\n anchor.removeEventListener('blur', onLeave);\n if (timers.show !== undefined) clearTimeout(timers.show);\n if (timers.hide !== undefined) clearTimeout(timers.hide);\n hide(INSTANT);\n leaving?.close(undefined, INSTANT);\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/overlay-core.ts","../src/overlay-choice.ts","../src/overlay-confirm.ts","../src/overlay-prompt.ts","../src/overlay-form.ts","../src/overlay-position.ts","../src/overlay-popover.ts","../src/overlay-toast.ts","../src/overlay-tooltip.ts"],"names":["options"],"mappings":"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","file":"overlay.js","sourcesContent":["/**\n * Shared overlay lifecycle and document arbitration implementation.\n *\n * Every real kerf app hand-rolls this: `toElement → body.appendChild → mount →\n * wire dismissal → remove`, plus the fiddly parts (Escape, backdrop / outside\n * click, focus trap, restoring focus on close). `window.confirm` is a no-op in\n * Tauri WKWebViews, so a hand-built overlay is mandatory there. This subpath\n * blesses the pattern through `overlay()`, with anchored surfaces and dialog\n * helpers building on it. No per-instance framework state: each call owns its\n * DOM + listeners in a closure and returns a handle.\n *\n * import { overlay, confirm, toast } from 'kerfjs/overlay';\n *\n * const ok = await confirm('Delete this file?', { danger: true });\n * toast('Saved');\n * const dialog = overlay(<Settings />, { dismiss: ['escape', 'backdrop'] });\n * // …later: dialog.close(); or await dialog.result;\n *\n * Structural only — kerf ships no CSS. The wrapper gets your `className`; style\n * the backdrop / centering / animation yourself.\n */\nimport { attach } from './attach.js';\nimport { devHooks } from './dev-hooks.js';\nimport type { SafeHtml } from './jsx-runtime.js';\nimport { mount, type MountResult } from './mount.js';\nimport { OVERLAY_HOST_SELECTOR } from './utils/overlay-host.js';\n\n/** A user-initiated dismissal trigger. */\nexport type DismissTrigger = 'escape' | 'backdrop' | 'outside';\n\n/** Content for an overlay: static `SafeHtml`, or a render function `mount()` drives reactively. */\nexport type OverlayContent = SafeHtml | (() => MountResult);\n\n/**\n * How an overlay is presented. `'modal'` (the default) adds nothing.\n * `'bottom-sheet'` marks the wrapper `data-presentation=\"bottom-sheet\"` and,\n * while open, publishes the virtual keyboard's overlap as the inline custom\n * property `--kerf-keyboard-inset`. kerf ships no CSS: the bottom-edge\n * geometry, safe-area padding, and motion are the app's (or `@kerfjs/ui`'s).\n */\nexport type OverlayPresentation = 'modal' | 'bottom-sheet';\n\n/** Options for {@link overlay}. */\nexport interface OverlayOptions {\n /**\n * Where to append the overlay wrapper. Default `document.body`. A container\n * inside an open modal `<dialog>` (including one slotted into a shadow-root\n * modal such as Web Awesome's `wa-dialog`) is already interactive, so the\n * surface is not lifted, and it closes when that dialog closes.\n */\n container?: Element;\n /** Class on the wrapper element (you style it — kerf ships no CSS). Default `'kerf-overlay'`. */\n className?: string;\n /**\n * Which user actions dismiss the overlay. Default `['escape', 'backdrop']`.\n * `'backdrop'` = a click on the wrapper itself (not its content); `'outside'`\n * = a click anywhere outside the wrapper (for anchored popovers). `false`\n * disables user dismissal (close it programmatically).\n */\n dismiss?: DismissTrigger | DismissTrigger[] | false;\n /**\n * Where focus lands on open: a selector, `true` (first focusable element, or\n * the wrapper if none), or `false` (leave focus alone). Default `true`.\n */\n initialFocus?: string | boolean;\n /**\n * Trap Tab / Shift+Tab within the overlay while open and mark it\n * `role=\"dialog\"` / `aria-modal=\"true\"`. Default `true`. Set `false` for a\n * non-modal popover.\n */\n trap?: boolean;\n /** ARIA role for the wrapper when `trap` is on. Default `'dialog'`. */\n role?: string;\n /** Called on any user-initiated dismissal (before `close()` runs). */\n onDismiss?: () => void;\n /** For `'outside'` dismissal: clicks on these elements do NOT count as outside (e.g. the trigger button). */\n outsideIgnore?: Element | readonly Element[];\n /**\n * Opt into the browser **top layer** (`docs/19-native-overlay-backing.md`).\n * When `true` and the engine supports it, a modal overlay (`trap: true`) is\n * hosted in a `<dialog>` opened with `.showModal()` — real inerting of the rest\n * of the document + guaranteed stacking above any `z-index` — and a non-modal\n * one (`trap: false`) uses the Popover API (`[popover]` + `showPopover()`).\n * Feature-detected; falls back to today's plain `<div>` where unsupported.\n *\n * The `render` slot + promise API are unchanged — kerf just hosts your markup\n * in a `<dialog>` / `[popover]` instead of a `<div>`. Two caveats: native\n * `<dialog>` / `[popover]` carry **UA default styles** (a `::backdrop`,\n * centering, border, padding) that kerf does not reset — style the element (and\n * its `::backdrop`) via `className`; and `container` is effectively a **no-op**\n * for visual position, since the top layer ignores where the element lives in\n * the DOM. Default `false`.\n */\n native?: boolean;\n /**\n * `'bottom-sheet'` marks the wrapper `data-presentation=\"bottom-sheet\"` (on\n * both the plain `<div>` and the `native` `<dialog>` / `[popover]` hosts) and,\n * while the overlay is open, follows `visualViewport` to publish the virtual\n * keyboard's overlap as `--kerf-keyboard-inset: <px>` on the wrapper (removed\n * when there is none, while pinch-zoomed, and on close). Style the sheet with\n * those hooks — rest it on the bottom edge and add\n * `max(env(safe-area-inset-bottom), var(--kerf-keyboard-inset, 0px))` to its\n * block-end padding. kerf\n * sets no geometry of its own. Default `'modal'` (nothing added).\n */\n presentation?: OverlayPresentation;\n /**\n * Class added when the overlay closes, so CSS owns the **exit** (mirrors\n * `toast()`'s `exitClass`). Everything else happens at once — `result`\n * settles, the overlay leaves the stack, a native host leaves the top layer,\n * the wrapper turns `inert`, focus is restored — and only the node's removal\n * waits: until the CSS animations / transitions then running in the wrapper\n * finish, or `exitDuration` ms pass, whichever is first. Skipped under\n * `prefers-reduced-motion: reduce`. A closed native `<dialog>` / `[popover]`\n * is `display: none` unless your CSS keeps it shown during the exit.\n */\n exitClass?: string;\n /**\n * The exit's hard cap in ms (see `exitClass`). Also opts into an exit on its\n * own — e.g. a native `<dialog>`'s `display` / `overlay` `allow-discrete`\n * transition. Default `0`.\n */\n exitDuration?: number;\n}\n\n/** Options for {@link OverlayHandle.close}. */\nexport interface OverlayCloseOptions {\n /** Skip the exit and remove the node now — or end an exit already running. */\n instant?: boolean;\n}\n\n/** Handle returned by {@link overlay}. Holds no framework state — it's a closure. */\nexport interface OverlayHandle {\n /** The wrapper element (mounted into, appended to `container`). */\n el: HTMLElement;\n /**\n * Tear down: dispose the mount, remove listeners, restore focus, resolve\n * `result`, and remove the node — after the exit, when one is configured\n * (`{ instant: true }` skips or ends it). Idempotent.\n */\n close(result?: unknown, options?: OverlayCloseOptions): void;\n /** Resolves with the value passed to `close()` (or `undefined` on user dismissal). */\n result: Promise<unknown>;\n}\n\nconst FOCUSABLE =\n 'a[href],area[href],button:not([disabled]),input:not([disabled]),' +\n 'select:not([disabled]),textarea:not([disabled]),iframe,' +\n '[tabindex]:not([tabindex=\"-1\"]),[contenteditable=\"true\"]';\n\nfunction focusable(root: Element): HTMLElement[] {\n const items = Array.from(\n root.querySelectorAll<HTMLElement>(FOCUSABLE),\n ).filter((el) => !el.hasAttribute('hidden') && el.tabIndex >= 0);\n // WebKit on macOS follows the system's keyboard-navigation preference and\n // may omit implicitly tabbable controls from sequential focus navigation.\n // A focus trap promises stable traversal through every eligible control, so\n // make those implicit stops explicit while preserving authored tabindexes.\n for (const el of items) if (!el.hasAttribute('tabindex')) el.tabIndex = 0;\n return items;\n}\n\n// Native top-layer feature detection (KF-526). Modal → `<dialog>.showModal()`;\n// non-modal → the Popover API. Each is independent — an engine may ship one\n// without the other — and both fall back to the plain `<div>` where absent.\nfunction supportsDialog(): boolean {\n return (\n typeof HTMLDialogElement !== 'undefined' &&\n typeof HTMLDialogElement.prototype.showModal === 'function'\n );\n}\nfunction supportsPopover(): boolean {\n return (\n typeof HTMLElement !== 'undefined' &&\n typeof HTMLElement.prototype.showPopover === 'function'\n );\n}\n\n/**\n * Internal: a teardown with no exit — construction rollback, or a node (or an\n * anchored surface's anchor) already gone. Not re-exported from `kerfjs/overlay`.\n */\nexport const INSTANT: OverlayCloseOptions = { instant: true };\n\n/** The wrapper's custom property carrying a bottom sheet's keyboard overlap. */\nconst KEYBOARD_INSET = '--kerf-keyboard-inset';\n\n// A bottom sheet rests on the layout viewport's bottom edge, which a virtual\n// keyboard overlays: publish that overlap (layout height minus the visual\n// viewport's height and top offset; nothing while pinch-zoomed, when the\n// difference is zoom, not a keyboard) on `el` until the returned disposer\n// runs. Engines without `visualViewport` publish nothing. A page whose\n// viewport meta resizes content shrinks the layout viewport instead, so the\n// overlap is zero there and the sheet simply follows the viewport.\nfunction followKeyboardInset(\n el: HTMLElement,\n removers: Array<() => void>,\n): void {\n const viewport = globalThis.visualViewport;\n if (viewport == null) return;\n const publish = (): void => {\n const inset =\n viewport.scale > 1.01\n ? 0\n : Math.round(\n globalThis.innerHeight - viewport.height - viewport.offsetTop,\n );\n if (inset > 0) el.style.setProperty(KEYBOARD_INSET, `${inset}px`);\n else el.style.removeProperty(KEYBOARD_INSET);\n };\n viewport.addEventListener('resize', publish);\n viewport.addEventListener('scroll', publish);\n removers.push(() => {\n viewport.removeEventListener('resize', publish);\n viewport.removeEventListener('scroll', publish);\n el.style.removeProperty(KEYBOARD_INSET);\n });\n publish();\n}\n\n// Stacked-surface arbitration (KF-CW7GJ8: a tooltip inside a modal used to\n// become \"topmost\" and disable the modal's Escape, backdrop, and focus trap).\n// Every open overlay — native or fallback — is recorded, in open order, on a\n// per-document stack. An input kind (Escape, a backdrop / outside click, Tab\n// for the trap) belongs to the topmost surface that HANDLES that kind; a\n// surface that doesn't handle it is transparent, except that a modal surface\n// is a barrier nothing beneath it sees past. A tooltip (or any overlay with no\n// dismiss trigger and no trap) handles nothing, so it never intercepts. The\n// `handled` set marks an event a surface already acted on, so one click that is\n// both \"outside\" a popover and on the modal backdrop closes only the popover.\nconst OVERLAY_ARBITRATION = Symbol('kerf.overlayArbitration');\n\n/** An arbitration input: a dismiss trigger, or Tab for the focus trap. */\ntype ArbitrationKind = DismissTrigger | 'trap';\n\ninterface OverlaySurface {\n el: HTMLElement;\n triggers: readonly DismissTrigger[];\n modal: boolean;\n /** Where focus returns on close; re-pointed when the surface holding it closes first. */\n restoreTo: Element | null;\n /** Non-modal only: move (or re-show) into the top layer above a newly opened modal `<dialog>`. */\n liftAbove?: () => void;\n /** An anchored surface's anchor (see {@link anchorOverlay}). */\n anchor?: Element;\n /**\n * Close as cleanup because the surface this one renders in, or its anchor\n * renders in, is closing: `instant` when that host's node goes now.\n */\n leave: (instant: boolean) => void;\n}\n\ninterface OverlayArbitration {\n stack: OverlaySurface[];\n handled: WeakSet<Event>;\n /** Document capture listener, installed only while the stack is non-empty. */\n onToggle: (event: Event) => void;\n /** Open shadow roots carrying `onToggle` too (a shadow `toggle` never reaches the document). */\n shadowRoots: Set<ShadowRoot>;\n}\n\ntype ArbitratedDocument = Document & {\n [OVERLAY_ARBITRATION]?: OverlayArbitration;\n};\n\nfunction overlayArbitration(doc: Document): OverlayArbitration {\n const arbitrated = doc as ArbitratedDocument;\n return (arbitrated[OVERLAY_ARBITRATION] ??= {\n stack: [],\n handled: new WeakSet(),\n // KF-AHY6H4: an app-owned modal `<dialog>` opened outside kerf would leave\n // the kerf surfaces already showing inert beneath it. A dialog fires\n // `toggle` after it opens (it does not bubble, so listen in the capture\n // phase); re-host above it exactly as kerf does for its own dialogs, which\n // are skipped here because `overlay()` already re-hosted synchronously.\n onToggle: (event) => {\n const dialog = event.target as Element;\n const arbitration = arbitrated[OVERLAY_ARBITRATION] as OverlayArbitration;\n if (\n dialog.tagName === 'DIALOG' &&\n !arbitration.stack.some(({ el }) => el === dialog) &&\n isOpenModal(dialog, arbitration)\n )\n rehostAbove(arbitration, dialog);\n },\n shadowRoots: new Set(),\n });\n}\n\n// Every open shadow root in `root`, nested ones included (KF-1FGTX1: Web\n// Awesome's `wa-dialog` / `wa-drawer` keep their modal `<dialog>` in one, where\n// neither `querySelectorAll` nor a document `toggle` listener can see it). A\n// closed shadow root is invisible by design. One element walk per `overlay()`\n// open — a user-paced event — so the cost stays off every render path.\nfunction openShadowRoots(\n root: Document | ShadowRoot,\n found: ShadowRoot[] = [],\n): ShadowRoot[] {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);\n for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {\n const shadow = (node as Element).shadowRoot;\n if (shadow !== null) {\n found.push(shadow);\n openShadowRoots(shadow, found);\n }\n }\n return found;\n}\n\n// Install the `toggle` watch on every open shadow root not yet watched, so an\n// app-owned modal `<dialog>` opening inside one re-hosts the surfaces showing.\nfunction watchShadowRoots(\n arbitration: OverlayArbitration,\n roots: readonly ShadowRoot[],\n): void {\n for (const root of roots)\n if (!arbitration.shadowRoots.has(root)) {\n arbitration.shadowRoots.add(root);\n root.addEventListener('toggle', arbitration.onToggle, true);\n }\n}\n\n// Is `el` inside `dialog` in the flat tree — the rendered tree, where content\n// slotted into a shadow host renders inside the host's shadow `<dialog>`?\nfunction renderedInside(el: Element, dialog: Element): boolean {\n for (let node: Element | null = el; node !== null;) {\n if (node === dialog) return true;\n const root = node.getRootNode();\n node =\n node.assignedSlot ??\n node.parentElement ??\n (root instanceof ShadowRoot ? root.host : null);\n }\n return false;\n}\n\n// Every non-modal kerf surface already open is blocked beneath a modal\n// `<dialog>` that just opened: lift (or re-show) it above (KF-FJ9VD8). One\n// rendered inside that dialog — including a slot-hosted one in a shadow\n// host's light DOM — is part of its subtree already.\nfunction rehostAbove(arbitration: OverlayArbitration, dialog: Element): void {\n for (const { el, liftAbove } of arbitration.stack)\n if (el !== dialog && el.isConnected && !renderedInside(el, dialog))\n liftAbove?.();\n}\n\n// Is `dialog` an open modal `<dialog>`? kerf's own are known from the stack;\n// an app-owned one is found through `:modal`, which an older engine may not\n// parse (then only kerf's own count).\nfunction isOpenModal(\n dialog: Element,\n arbitration: OverlayArbitration,\n): boolean {\n if (!dialog.isConnected || (dialog as HTMLDialogElement).open !== true)\n return false;\n if (arbitration.stack.some(({ el, modal }) => modal && el === dialog))\n return true;\n try {\n return dialog.matches(':modal');\n } catch {\n return false; // `:modal` unsupported\n }\n}\n\n// Is a modal `<dialog>` open (KF-0V9RTE: a plain surface opened in that state\n// is inert and painted beneath the dialog's top layer)?\n// The open shadow roots count too (KF-1FGTX1: a `wa-dialog`'s modal).\nfunction modalDialogOpen(\n doc: Document,\n arbitration: OverlayArbitration,\n shadowRoots: readonly ShadowRoot[],\n): boolean {\n return (\n arbitration.stack.some(({ el }) => isOpenModal(el, arbitration)) ||\n [doc, ...shadowRoots].some((root) =>\n Array.from(root.querySelectorAll('dialog[open]')).some((dialog) =>\n isOpenModal(dialog, arbitration),\n ),\n )\n );\n}\n\n// The modal context `el` renders in, resolved across shadow boundaries\n// (KF-F52T5D: Web Awesome's `wa-dialog` / `wa-drawer` keep their modal\n// `<dialog>` in a shadow root, so `closest('dialog')` from slotted light-DOM\n// content found nothing and the surface landed, inert, in `document.body`).\n// Walks the light-DOM ancestors, continuing from a shadow tree to its host.\n// The nearest `<dialog>` decides, as before; so does a shadow host whose slot\n// for the walked-from child sits inside a `<dialog>` in its shadow root. Only\n// an OPEN MODAL dialog yields a context: `dialog` is that element, `root` the\n// light-DOM element a host slot belongs in — the dialog itself, or the shadow\n// host (content appended to it is slotted into the dialog).\ninterface ModalContext {\n dialog: Element;\n root: Element;\n}\nfunction modalContext(\n el: Element,\n arbitration: OverlayArbitration,\n): ModalContext | undefined {\n let child: Element | undefined;\n for (let node: Element | null = el; node !== null;) {\n const dialog =\n node.localName === 'dialog'\n ? node\n : child?.assignedSlot?.closest('dialog');\n if (dialog != null)\n return isOpenModal(dialog, arbitration)\n ? { dialog, root: node }\n : undefined;\n child = node;\n const root = node.getRootNode();\n node =\n node.parentElement ?? (root instanceof ShadowRoot ? root.host : null);\n }\n return undefined;\n}\n\n// The in-dialog host slot (KF-FBHQEP: a surface lifted over a modal\n// `<dialog>` is visible but inert, because every engine inerts content outside\n// the modal). A `popover()` / `tooltip()` whose anchor renders inside an open\n// modal `<dialog>` (see `modalContext`) renders into that context's\n// `[data-kerf-overlay-host]` element instead, so it is part of the modal\n// subtree and fully interactive. An app-owned native dialog opts in by marking\n// an element; a dialog kerf opened itself, and a shadow-hosted modal (whose\n// author cannot reach inside the shadow root), get one on demand —\n// `display: contents` so it adds no layout box, and `data-morph-skip` +\n// `data-morph-preserve` so the content's own `mount()` neither re-renders nor\n// removes it (`utils/overlay-host.ts` makes the slot a nested-mount boundary).\nexport function overlayHost(anchor: Element): Element | undefined {\n const arbitration = overlayArbitration(document);\n const context = modalContext(anchor, arbitration);\n if (context === undefined) return undefined;\n const { dialog, root } = context;\n let host = Array.from(root.querySelectorAll(OVERLAY_HOST_SELECTOR)).find(\n (el) => modalContext(el, arbitration)?.root === root,\n );\n if (\n host === undefined &&\n (root !== dialog || arbitration.stack.some(({ el }) => el === dialog))\n ) {\n root.insertAdjacentHTML(\n 'beforeend',\n '<div data-kerf-overlay-host data-morph-skip data-morph-preserve style=\"display:contents\"></div>',\n );\n host = root.lastElementChild as Element;\n }\n return host;\n}\n\n// `self` is on the stack and handles `kind` (its callers are exactly the\n// handlers it installed for that kind), so it owns `kind` unless some surface\n// above it handles `kind` too or is modal.\nfunction ownsInput(\n stack: readonly OverlaySurface[],\n self: OverlaySurface,\n kind: ArbitrationKind,\n): boolean {\n for (let i = stack.indexOf(self) + 1; i < stack.length; i++) {\n const above = stack[i];\n if (above.modal || (kind !== 'trap' && above.triggers.includes(kind)))\n return false;\n }\n return true;\n}\n\n// Validate a string `initialFocus` BEFORE any DOM mutation: `querySelector`\n// throws a generic `SyntaxError` DOMException on a malformed selector, and the\n// focus pass runs last — after the wrapper, mount, listeners, and stack entry\n// already exist — so an unvalidated selector would strand all of them with no\n// handle to close. An inert fragment parses the selector without matching.\nfunction assertInitialFocusSelector(selector: string): void {\n try {\n document.createDocumentFragment().querySelector(selector);\n } catch (cause) {\n throw new Error(\n `overlay(): invalid initialFocus selector ${JSON.stringify(selector)}`,\n { cause },\n );\n }\n}\n\n/**\n * Open an overlay: append a wrapper to `container`, `mount()` `content` inside\n * it, wire the requested dismissals + (optionally) a focus trap, and return a\n * handle. Concurrent fallback overlays dismiss from the top down. See\n * {@link OverlayOptions}.\n *\n * Construction is transactional: a malformed `initialFocus` selector throws a\n * descriptive error before anything is touched, and if a later setup phase\n * throws (the content's first render, `showModal()` / `showPopover()`), every\n * piece already installed — wrapper node, mount, listeners, fallback-stack\n * entry, top-layer state, moved focus — is rolled back before the original\n * error is rethrown.\n */\nexport function overlay(\n content: OverlayContent,\n options: OverlayOptions = {},\n): OverlayHandle {\n const {\n container = document.body,\n className = 'kerf-overlay',\n dismiss = ['escape', 'backdrop'],\n initialFocus = true,\n trap = true,\n role = 'dialog',\n onDismiss,\n outsideIgnore,\n native = false,\n presentation = 'modal',\n exitClass,\n exitDuration = 0,\n } = options;\n\n if (typeof initialFocus === 'string')\n assertInitialFocusSelector(initialFocus);\n\n const triggers: readonly DismissTrigger[] =\n dismiss === false ? [] : Array.isArray(dismiss) ? dismiss : [dismiss];\n\n // Native top-layer backing (KF-526), feature-detected: a modal overlay\n // (`trap`) → `<dialog>.showModal()`; a non-modal one → `[popover]`. Each falls\n // back to the plain `<div>` where the API is missing, so behavior is unchanged\n // on unsupporting engines. A surface opened while a modal `<dialog>` is open\n // is lifted the same way even without `native` (KF-0V9RTE), because a plain\n // `<div>` would be inert and painted beneath the dialog.\n const arbitration = overlayArbitration(document);\n // A surface placed inside an open modal `<dialog>` (its host slot, or an\n // explicit `container` there, including one slotted into a shadow-root\n // modal) is already part of the modal subtree: no lift.\n const containerContext = modalContext(container, arbitration);\n const shadowRoots = openShadowRoots(document);\n const liftOverModal =\n !native &&\n containerContext === undefined &&\n modalDialogOpen(document, arbitration, shadowRoots);\n const topLayer = native || liftOverModal;\n const useDialog = topLayer && trap && supportsDialog();\n const usePopover = topLayer && !trap && supportsPopover();\n\n const wrapper: HTMLElement = useDialog\n ? document.createElement('dialog')\n : document.createElement('div');\n wrapper.className = className;\n if (usePopover) wrapper.setAttribute('popover', 'manual');\n const bottomSheet = presentation === 'bottom-sheet';\n if (bottomSheet) wrapper.setAttribute('data-presentation', 'bottom-sheet');\n // `<dialog>.showModal()` conveys modality natively (role + inert), so the ARIA\n // attributes are only needed on the plain-`<div>` fallback.\n if (trap && !useDialog) {\n wrapper.setAttribute('role', role);\n wrapper.setAttribute('aria-modal', 'true');\n }\n const surface: OverlaySurface = {\n el: wrapper,\n triggers,\n modal: trap,\n restoreTo: document.activeElement,\n leave: (now) => close(undefined, now ? INSTANT : undefined),\n };\n\n // Does this surface own `kind` right now (and has no surface acted on `event`)?\n const owns = (kind: ArbitrationKind, event?: Event): boolean =>\n !(event !== undefined && arbitration.handled.has(event)) &&\n ownsInput(arbitration.stack, surface, kind);\n\n const removers: Array<() => void> = [];\n // Run at the node's removal — after the exit, when one runs — not at close().\n const finalizers: Array<() => void> = [];\n const resultBox: { resolve?: (value: unknown) => void } = {};\n const result = new Promise<unknown>((resolve) => {\n resultBox.resolve = resolve;\n });\n const state = { closed: false, removed: false };\n let disposeMount: (() => void) | undefined;\n let nativeOpened = false;\n let exitTimer: ReturnType<typeof setTimeout> | undefined;\n\n // KF-FJ9VD8: a modal `<dialog>` kerf opens later would leave this non-modal\n // surface inert beneath it, so the opener calls this to move it into the top\n // layer — or, if it is already a `[popover]`, re-show it so it stacks above\n // the new dialog (the top layer orders by most recent show).\n if (!trap)\n surface.liftAbove = () => {\n if (!supportsPopover()) {\n devHooks.overlayBlockedByModal?.('hidden');\n return;\n }\n const el = wrapper as HTMLElement & {\n showPopover(): void;\n hidePopover(): void;\n };\n if (nativeOpened) el.hidePopover();\n else {\n wrapper.setAttribute('popover', 'manual');\n wrapper.style.inset = 'auto';\n }\n el.showPopover();\n nativeOpened = true;\n if (wrapper.querySelector(FOCUSABLE) !== null)\n devHooks.overlayBlockedByModal?.('inert');\n };\n\n // Remove the node, ending the exit if one is running. Idempotent.\n function finish(): void {\n if (state.removed) return;\n state.removed = true;\n clearTimeout(exitTimer);\n for (const end of finalizers) end();\n wrapper.remove();\n }\n\n // Also the construction rollback (see the transaction below): every step\n // tolerates a phase that never ran — no mount yet, no stack entry, never\n // appended, never shown.\n //\n // The exit (KF-WAK1TW: CSS could animate an overlay in but never out) defers\n // ONLY the node's removal. Everything observable happens now: the stack entry\n // goes (a surface opened during the exit is topmost), listeners + the mount\n // are disposed, a native host leaves the top layer (so the page is no longer\n // inert and focus can return), the wrapper turns `inert` (no clicks, no\n // focus, hidden from assistive tech), focus is restored, `result` settles.\n function close(value?: unknown, closeOptions?: OverlayCloseOptions): void {\n const instant = closeOptions?.instant === true;\n if (state.closed) {\n if (instant) finish();\n return;\n }\n state.closed = true;\n const { stack } = arbitration;\n const stackIndex = stack.indexOf(surface);\n if (stackIndex !== -1) stack.splice(stackIndex, 1);\n if (stack.length === 0) {\n document.removeEventListener('toggle', arbitration.onToggle, true);\n for (const root of arbitration.shadowRoots)\n root.removeEventListener('toggle', arbitration.onToggle, true);\n arbitration.shadowRoots.clear();\n }\n // A surface opened from inside this one would restore focus into a node\n // that is about to be detached: hand it this surface's own restore target.\n for (const other of stack)\n if (other.restoreTo !== null && wrapper.contains(other.restoreTo))\n other.restoreTo = surface.restoreTo;\n const exit =\n !instant &&\n (exitClass !== undefined || exitDuration > 0) &&\n !globalThis.matchMedia('(prefers-reduced-motion: reduce)').matches;\n // KF-XNEK58: a surface rendered inside this one, or anchored to content\n // inside it, leaves with it now — not when the node is finally removed\n // (an exit can keep the inert node for `exitDuration` ms). It follows this\n // surface: its own exit alongside an exiting host, gone at once otherwise.\n for (const other of [...stack])\n if (\n stack.includes(other) &&\n (renderedInside(other.el, wrapper) ||\n (other.anchor !== undefined && renderedInside(other.anchor, wrapper)))\n )\n other.leave(!exit);\n const active = document.activeElement;\n for (const remove of removers) remove();\n disposeMount?.();\n // Exit the top layer before removing the node, so the native close steps run\n // (restore inert, fire the dialog's `close`). `<dialog>` also restores focus\n // itself; kerf's manual restore below stays as the fallback path's behavior.\n if (nativeOpened) {\n nativeOpened = false;\n if (useDialog) (wrapper as HTMLDialogElement).close();\n else (wrapper as HTMLElement & { hidePopover(): void }).hidePopover();\n }\n if (exit) {\n wrapper.inert = true;\n if (exitClass !== undefined) wrapper.classList.add(exitClass);\n } else finish();\n restoreFocus(active);\n resultBox.resolve?.(value);\n if (exit) {\n // `exitDuration` caps the exit; the finite animations running in the\n // wrapper once `exitClass` applies (reading them flushes style, so the\n // exit's own are included) end it early — at once when none run.\n exitTimer = setTimeout(finish, exitDuration);\n if ('getAnimations' in wrapper)\n void Promise.allSettled(\n wrapper\n .getAnimations({ subtree: true })\n .filter((animation) =>\n Number.isFinite(\n animation.effect?.getComputedTiming().endTime ?? Infinity,\n ),\n )\n .map((animation) => animation.finished),\n ).then(finish);\n }\n }\n\n // Closing a surface that doesn't hold focus (an out-of-order close beneath\n // another open surface) must not pull focus out of the surface that does;\n // otherwise focus returns to where it was when this surface opened.\n function restoreFocus(active: Element | null): void {\n if (\n active instanceof HTMLElement &&\n active.isConnected &&\n arbitration.stack.some((other) => other.el.contains(active))\n ) {\n if (document.activeElement !== active) active.focus();\n return;\n }\n const { restoreTo } = surface;\n if (restoreTo instanceof HTMLElement && restoreTo.isConnected)\n restoreTo.focus();\n }\n\n function userDismiss(): void {\n onDismiss?.();\n close();\n }\n\n // One transaction: if any phase below throws (the content's first render,\n // `showModal()` / `showPopover()`, …), roll back whatever the earlier phases\n // installed via `close()` and rethrow the original error. No handle is\n // returned on failure, so nothing may outlive the call.\n try {\n container.appendChild(wrapper);\n disposeMount = mount(\n wrapper,\n typeof content === 'function' ? content : () => content,\n );\n // Before the top-layer show, so the first painted frame already clears\n // a keyboard that is up when the sheet opens.\n if (bottomSheet) followKeyboardInset(wrapper, finalizers);\n // Watch for app-owned modal dialogs while any kerf surface is open.\n // Shadow roots are refreshed on every open; one attached after the latest\n // open is not watched until the next.\n if (arbitration.stack.push(surface) === 1)\n document.addEventListener('toggle', arbitration.onToggle, true);\n watchShadowRoots(arbitration, shadowRoots);\n\n // Enter the top layer after the content is mounted + connected.\n // `showModal()` moves focus into the dialog by default; kerf's\n // `initialFocus` pass below runs afterward and wins.\n if (useDialog) {\n (wrapper as HTMLDialogElement).showModal();\n nativeOpened = true;\n rehostAbove(arbitration, wrapper);\n } else if (usePopover) {\n (wrapper as HTMLElement & { showPopover(): void }).showPopover();\n nativeOpened = true;\n // Neutralize the UA `[popover] { inset: 0; margin: auto }` anchoring so\n // `positionAnchored` (which sets `top`/`left`) controls placement —\n // otherwise the retained `right`/`bottom` insets would stretch/center it.\n wrapper.style.inset = 'auto';\n }\n\n installDismissal();\n if (container.closest(OVERLAY_HOST_SELECTOR) !== null) {\n makeTabReachable();\n // KF-WZ9KQM: a slot-hosted surface leaves with its dialog even when its\n // anchor (moved out of the dialog) stays connected, so the anchor watch\n // never fires. Watch the wrapper itself: close as cleanup (no\n // `onDismiss`) and leave the open-order stack.\n removers.push(attach(wrapper, () => () => close(undefined, INSTANT)));\n }\n // KF-F52T5D: a surface inside a modal context leaves when that dialog\n // closes, as cleanup (no `onDismiss`). Closing an app-owned or\n // shadow-hosted dialog removes nothing, and a shadow dialog's `close`\n // never reaches a light-DOM listener, so a caller could not watch it.\n if (containerContext !== undefined) {\n const { dialog } = containerContext;\n const onDialogClose = (): void => close();\n dialog.addEventListener('close', onDialogClose);\n removers.push(() => dialog.removeEventListener('close', onDialogClose));\n }\n applyInitialFocus();\n } catch (error) {\n close(undefined, INSTANT);\n throw error;\n }\n\n // What the lift cannot repair: no top-layer API at all, or a lifted\n // non-modal surface whose controls the modal still inerts.\n if (liftOverModal) {\n if (!useDialog && !usePopover) devHooks.overlayBlockedByModal?.('hidden');\n else if (usePopover && wrapper.querySelector(FOCUSABLE) !== null)\n devHooks.overlayBlockedByModal?.('inert');\n }\n\n return { el: wrapper, close, result };\n\n function installDismissal(): void {\n const wantEscape = triggers.includes('escape');\n if (useDialog) {\n // A native modal `<dialog>` confines Tab focus itself and surfaces Escape as\n // a `cancel` event. Take that over: `preventDefault` so kerf owns teardown\n // (and so Escape is swallowed when it isn't a dismiss trigger), then dismiss.\n // A surface stacked above that handles Escape (or is modal) owns it; a\n // stray `cancel` then leaves this dialog open.\n const onCancel = (event: Event): void => {\n event.preventDefault();\n if (wantEscape && owns('escape')) userDismiss();\n };\n wrapper.addEventListener('cancel', onCancel);\n removers.push(() => wrapper.removeEventListener('cancel', onCancel));\n } else if (wantEscape || trap) {\n const onKeydown = (event: KeyboardEvent): void => {\n if (wantEscape && event.key === 'Escape') {\n if (!owns('escape', event)) return;\n // `preventDefault` also withholds the close request from a native\n // `<dialog>` beneath, so one Escape closes exactly one surface.\n event.stopPropagation();\n event.preventDefault();\n arbitration.handled.add(event);\n userDismiss();\n return;\n }\n if (trap && event.key === 'Tab' && owns('trap')) {\n const items = focusable(wrapper);\n if (items.length === 0) {\n event.preventDefault();\n return;\n }\n const first = items[0];\n const last = items[items.length - 1];\n const active = document.activeElement;\n const outside = !wrapper.contains(active);\n if (event.shiftKey && (active === first || outside)) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && (active === last || outside)) {\n event.preventDefault();\n first.focus();\n }\n }\n };\n document.addEventListener('keydown', onKeydown, true);\n removers.push(() =>\n document.removeEventListener('keydown', onKeydown, true),\n );\n }\n\n if (triggers.includes('backdrop')) {\n const onClick = (event: Event): void => {\n if (event.target !== wrapper || !owns('backdrop', event)) return;\n arbitration.handled.add(event);\n userDismiss();\n };\n wrapper.addEventListener('click', onClick);\n removers.push(() => wrapper.removeEventListener('click', onClick));\n }\n\n if (triggers.includes('outside')) {\n const ignore =\n outsideIgnore === undefined\n ? []\n : Array.isArray(outsideIgnore)\n ? outsideIgnore\n : [outsideIgnore];\n // Capture phase: the click that opened this overlay already passed\n // document's capture phase, so this never fires for that opening click.\n const onDocClick = (event: Event): void => {\n const target = event.target as Node | null;\n if (target === null) return;\n if (wrapper.contains(target)) return;\n if (ignore.some((el) => el === target || el.contains(target))) return;\n if (!owns('outside', event)) return;\n arbitration.handled.add(event);\n userDismiss();\n };\n document.addEventListener('click', onDocClick, true);\n removers.push(() =>\n document.removeEventListener('click', onDocClick, true),\n );\n }\n }\n\n // KF-QZ9SFG (slot-hosted controls unreachable by Tab in macOS WebKit): a\n // surface in an overlay host slot sits in the modal dialog's own Tab order,\n // not behind a kerf trap, so WebKit's system keyboard-navigation preference\n // would skip its implicitly tabbable controls. Make those stops explicit, as\n // the trap does — now, and again before each Tab so a control a re-render\n // added (or whose tabindex the morph dropped) is reachable too.\n function makeTabReachable(): void {\n focusable(wrapper);\n const onTab = (event: KeyboardEvent): void => {\n if (event.key === 'Tab') focusable(wrapper);\n };\n document.addEventListener('keydown', onTab, true);\n removers.push(() => document.removeEventListener('keydown', onTab, true));\n }\n\n function focusWrapper(): void {\n wrapper.tabIndex = -1;\n wrapper.focus();\n }\n\n function applyInitialFocus(): void {\n if (initialFocus === false) return;\n const target =\n typeof initialFocus === 'string'\n ? wrapper.querySelector<HTMLElement>(initialFocus)\n : (focusable(wrapper)[0] ?? null);\n if (target === null) {\n if (initialFocus === true) focusWrapper();\n return;\n }\n if (tryFocus(target) || !isCustomElement(target)) return;\n // A custom element that is not defined or has not rendered yet (a Web\n // Awesome `wa-button` whose `focus()` reaches into a shadow root it has\n // not built) cannot take focus now, and may throw trying. Hold focus on\n // the overlay itself, then hand it over once the element renders — unless\n // the overlay closed or the user moved focus in the meantime.\n focusWrapper();\n void whenRendered(target).then(() => {\n if (!state.closed && activeIn(wrapper) === wrapper) tryFocus(target);\n });\n }\n}\n\nfunction isCustomElement(el: Element): boolean {\n return el.localName.includes('-');\n}\n\n// Focus `el`; true when it now holds focus. A custom element's `focus()`\n// override may throw before it has rendered.\nfunction tryFocus(el: HTMLElement): boolean {\n try {\n el.focus();\n } catch {\n return false;\n }\n return activeIn(el) === el;\n}\n\n// The focused element as `el`'s own tree sees it (a shadow root retargets).\nfunction activeIn(el: Element): Element | null {\n return (el.getRootNode() as Document | ShadowRoot).activeElement;\n}\n\n// Settles once a custom element is defined, its update cycle (Lit's\n// `updateComplete`) has settled, and a frame has passed.\nasync function whenRendered(el: HTMLElement): Promise<void> {\n await globalThis.customElements.whenDefined(el.localName);\n await (el as { updateComplete?: unknown }).updateComplete;\n await new Promise((resolve) => globalThis.requestAnimationFrame(resolve));\n}\n\n/**\n * Internal: mark the just-opened `handle` as anchored to `anchor`, so it\n * leaves (closes as cleanup, no `onDismiss`) the moment an overlay holding the\n * anchor closes — even while that overlay's node lingers for its exit. `leave`\n * replaces the default `handle.close()` (with `{ instant }` when the host goes\n * at once). Not re-exported from `kerfjs/overlay`.\n */\nexport function anchorOverlay(\n handle: OverlayHandle,\n anchor: Element,\n leave?: (instant: boolean) => void,\n): void {\n const surface = overlayArbitration(document).stack.find(\n ({ el }) => el === handle.el,\n ) as OverlaySurface;\n surface.anchor = anchor;\n if (leave !== undefined) surface.leave = leave;\n}\n\n/**\n * Internal: run a promise-dialog helper's post-open wiring (required-slot\n * lookups, `delegate()` handlers, key listeners) as the tail of `overlay()`'s\n * construction transaction. `wire` registers a disposer for every listener it\n * installs via `track`; if any step throws, those listeners are removed, the\n * just-opened overlay is closed (node, mount, dismissal listeners, stack\n * entry, top-layer state, focus), and the original error is rethrown — so a\n * failed helper call returns no promise and leaves no open overlay behind.\n *\n * After construction, `guard` wraps a user-action handler (OK click, Enter).\n * KF-B0CFQP (a throwing `validate` callback): a throw inside a guarded action\n * is a programming error, so it closes the dialog (full teardown, focus\n * restored) and the returned promise REJECTS with the original error, instead\n * of the error escaping the event handler and stranding an open dialog whose\n * OK can never succeed. Otherwise the returned promise settles with\n * `settle(handle.result's value)`. Not re-exported from `kerfjs/overlay`.\n */\nexport function wireDialog<T>(\n handle: OverlayHandle,\n wire: (\n track: (dispose: () => void) => void,\n guard: (action: () => void) => () => void,\n ) => void,\n settle: (value: unknown) => T,\n): Promise<T> {\n const disposers: Array<() => void> = [];\n // Holds a guarded action's error AND is the close() value that marks the\n // failure, so only a throw that actually settles the dialog rejects it.\n const failure: unknown[] = [];\n try {\n wire(\n (dispose) => void disposers.push(dispose),\n (action) => () => {\n try {\n action();\n } catch (error) {\n failure[0] = error;\n handle.close(failure);\n }\n },\n );\n } catch (error) {\n disposers.forEach((dispose) => dispose());\n handle.close(undefined, INSTANT);\n throw error;\n }\n // One hop, not a chain: `settle` maps the value in the same reaction, so a\n // helper's promise settles as soon after `close()` as it always has.\n return handle.result.then((value) => {\n if (value === failure) throw failure[0];\n return settle(value);\n });\n}\n","/** `choice()` implementation and public option types. */\nimport { delegate } from './delegate.js';\nimport { jsx } from './jsx-runtime.js';\nimport {\n overlay,\n type OverlayContent,\n type OverlayPresentation,\n wireDialog,\n} from './overlay-core.js';\n\n/** One choosable action in a {@link choice} dialog. */\nexport interface ChoiceAction<R> {\n value: R;\n label: string;\n className?: string;\n}\n\n/** Wiring slots for a {@link ChoiceOptions.render}. */\nexport interface ChoiceRenderSlots {\n message: string;\n actions: Array<Record<string, string>>;\n}\n\n/** Options for {@link choice}. */\nexport interface ChoiceOptions<R> {\n container?: Element;\n className?: string;\n title?: string;\n defaultValue?: R;\n native?: boolean;\n /** `'bottom-sheet'` presents the dialog as a bottom sheet (see `OverlayOptions.presentation`). Default `'modal'`. */\n presentation?: OverlayPresentation;\n /** Class added on close so CSS owns the exit; the node is removed after it (see `OverlayOptions.exitClass`). The promise settles at once. */\n exitClass?: string;\n /** The exit's hard cap in ms (see `OverlayOptions.exitDuration`). Default `0`. */\n exitDuration?: number;\n render?: (slots: ChoiceRenderSlots) => OverlayContent;\n}\n\n/** The N-way sibling of {@link confirm}. */\nexport function choice<R>(\n message: string,\n actions: ReadonlyArray<ChoiceAction<R>>,\n options: ChoiceOptions<R> = {},\n): Promise<R | null> {\n const {\n container,\n className = 'kerf-overlay',\n title,\n defaultValue,\n native = false,\n presentation,\n exitClass,\n exitDuration,\n render,\n } = options;\n const hasDefault = 'defaultValue' in options;\n const actionAttrs = actions.map((_, i) => ({ 'data-choice': String(i) }));\n\n const body: OverlayContent =\n render !== undefined\n ? render({ message, actions: actionAttrs })\n : jsx('div', {\n class: 'kerf-choice',\n children: [\n title !== undefined\n ? jsx('h2', { class: 'kerf-choice__title', children: title })\n : '',\n jsx('p', { class: 'kerf-choice__message', children: message }),\n jsx('div', {\n class: 'kerf-choice__actions',\n children: actions.map((action, i) =>\n jsx('button', {\n type: 'button',\n class:\n action.className !== undefined\n ? `kerf-choice__action ${action.className}`\n : 'kerf-choice__action',\n ...actionAttrs[i],\n children: action.label,\n }),\n ),\n }),\n ],\n });\n\n let resolveChoice!: (result: R | null) => void;\n const result = new Promise<R | null>((resolve) => {\n resolveChoice = resolve;\n });\n\n const handle = overlay(body, {\n container,\n className,\n dismiss: ['escape', 'backdrop'],\n initialFocus: '[data-choice]',\n trap: true,\n native,\n presentation,\n exitClass,\n exitDuration,\n });\n\n // Post-open wiring is still construction: a throw closes the overlay. Any\n // close settles a still-pending choice as a dismissal (`null`).\n void wireDialog(\n handle,\n (track) => {\n track(\n delegate(handle.el, 'click', '[data-choice]', (_event, el) => {\n resolveChoice(actions[Number(el.getAttribute('data-choice'))].value);\n handle.close();\n }),\n );\n\n if (hasDefault) {\n const onKeydown = (event: KeyboardEvent): void => {\n if (event.key === 'Enter') {\n event.preventDefault();\n resolveChoice(defaultValue as R);\n handle.close();\n }\n };\n // Last wiring step: nothing after it can throw, so it needs no rollback.\n handle.el.addEventListener('keydown', onKeydown);\n }\n },\n () => resolveChoice(null),\n );\n return result;\n}\n","/** `confirm()` implementation and public option types. */\nimport { delegate } from './delegate.js';\nimport { jsx } from './jsx-runtime.js';\nimport {\n overlay,\n type OverlayContent,\n type OverlayPresentation,\n wireDialog,\n} from './overlay-core.js';\n\n/** Wiring slots passed to a {@link ConfirmOptions.render}. */\nexport interface ConfirmRenderSlots {\n message: string;\n /** Spread onto the confirm control. */\n ok: Record<string, string>;\n /** Spread onto the cancel control. */\n cancel: Record<string, string>;\n}\n\n/** Options for {@link confirm}. */\nexport interface ConfirmOptions {\n /** Where to append the overlay. Default `document.body`. */\n container?: Element;\n /** Wrapper class. Default `'kerf-overlay'`. */\n className?: string;\n /** Optional heading above the message. */\n title?: string;\n /** Confirm button label. Default `'OK'`. */\n okText?: string;\n /** Cancel button label. Default `'Cancel'`. */\n cancelText?: string;\n /** Add a `kerf-confirm--danger` class to the wrapper for destructive actions. */\n danger?: boolean;\n /** Host the dialog in the browser top layer where supported. */\n native?: boolean;\n /** `'bottom-sheet'` presents the dialog as a bottom sheet (see `OverlayOptions.presentation`). Default `'modal'`. */\n presentation?: OverlayPresentation;\n /** Class added on close so CSS owns the exit; the node is removed after it (see `OverlayOptions.exitClass`). The promise settles at once. */\n exitClass?: string;\n /** The exit's hard cap in ms (see `OverlayOptions.exitDuration`). Default `0`. */\n exitDuration?: number;\n /** Bring your own body while retaining kerf's dialog wiring. */\n render?: (slots: ConfirmRenderSlots) => OverlayContent;\n}\n\n/** A promise-based `window.confirm` replacement. */\nexport function confirm(\n message: string,\n options: ConfirmOptions = {},\n): Promise<boolean> {\n const {\n container,\n className = 'kerf-overlay',\n title,\n okText = 'OK',\n cancelText = 'Cancel',\n danger = false,\n native = false,\n presentation,\n exitClass,\n exitDuration,\n render,\n } = options;\n\n const body: OverlayContent =\n render !== undefined\n ? render({\n message,\n ok: { 'data-confirm': 'ok' },\n cancel: { 'data-confirm': 'cancel' },\n })\n : jsx('div', {\n class: 'kerf-confirm',\n children: [\n title !== undefined\n ? jsx('h2', { class: 'kerf-confirm__title', children: title })\n : '',\n jsx('p', { class: 'kerf-confirm__message', children: message }),\n jsx('div', {\n class: 'kerf-confirm__actions',\n children: [\n jsx('button', {\n type: 'button',\n 'data-confirm': 'cancel',\n children: cancelText,\n }),\n jsx('button', {\n type: 'button',\n 'data-confirm': 'ok',\n class: 'kerf-confirm__ok',\n children: okText,\n }),\n ],\n }),\n ],\n });\n\n const handle = overlay(body, {\n container,\n className: danger ? `${className} kerf-confirm--danger` : className,\n dismiss: ['escape', 'backdrop'],\n initialFocus: '[data-confirm=\"ok\"]',\n trap: true,\n native,\n presentation,\n exitClass,\n exitDuration,\n });\n\n // Post-open wiring is still construction: a throw closes the overlay. The\n // click table is the only (and so the last) step, so it needs no rollback.\n return wireDialog(\n handle,\n () => {\n delegate(handle.el, 'click', '[data-confirm]', (_event, el) => {\n handle.close(el.getAttribute('data-confirm') === 'ok');\n });\n },\n (value) => value === true,\n );\n}\n","/** `prompt()` implementation and public option types. */\nimport { delegate } from './delegate.js';\nimport { jsx } from './jsx-runtime.js';\nimport {\n overlay,\n type OverlayContent,\n type OverlayPresentation,\n wireDialog,\n} from './overlay-core.js';\n\n/**\n * Validate a single field's value, synchronously: return a non-empty message\n * to block OK, anything else to accept. A validator that throws is treated as\n * a programming error — the dialog closes and the returned promise rejects\n * with that error.\n */\nexport type FieldValidator = (\n value: string,\n) => string | null | undefined | void;\n\n/** Options for {@link prompt}. */\n/**\n * Run a {@link FieldValidator}: the message it reports, or `undefined` when the\n * value is valid. Validators are synchronous — a promise result is a\n * programming error that closes the dialog and rejects its promise (the stray\n * promise's own rejection is silenced so it is not reported twice).\n * Internal to the dialog helpers.\n */\nexport function runValidator(\n validate: FieldValidator | undefined,\n value: string,\n owner: string,\n): string | undefined {\n const result: unknown = validate?.(value);\n if (typeof (result as PromiseLike<unknown> | null)?.then === 'function') {\n (result as PromiseLike<unknown>).then(undefined, () => undefined);\n throw new TypeError(`${owner}: validate returned a promise.`);\n }\n return typeof result === 'string' && result.length > 0 ? result : undefined;\n}\n\nexport interface PromptOptions {\n container?: Element;\n className?: string;\n title?: string;\n defaultValue?: string;\n placeholder?: string;\n inputType?: string;\n okText?: string;\n cancelText?: string;\n validate?: FieldValidator;\n native?: boolean;\n /** `'bottom-sheet'` presents the dialog as a bottom sheet (see `OverlayOptions.presentation`). Default `'modal'`. */\n presentation?: OverlayPresentation;\n /** Class added on close so CSS owns the exit; the node is removed after it (see `OverlayOptions.exitClass`). The promise settles at once. */\n exitClass?: string;\n /** The exit's hard cap in ms (see `OverlayOptions.exitDuration`). Default `0`. */\n exitDuration?: number;\n render?: (slots: PromptRenderSlots) => OverlayContent;\n}\n\n/** Wiring slots for a {@link PromptOptions.render}. */\nexport interface PromptRenderSlots {\n message: string;\n input: Record<string, string>;\n error: Record<string, string>;\n ok: Record<string, string>;\n cancel: Record<string, string>;\n}\n\n/** A promise-based `window.prompt` replacement. */\nexport function prompt(\n message: string,\n options: PromptOptions = {},\n): Promise<string | null> {\n const {\n container,\n className = 'kerf-overlay',\n title,\n defaultValue = '',\n placeholder,\n inputType = 'text',\n okText = 'OK',\n cancelText = 'Cancel',\n validate,\n native = false,\n presentation,\n exitClass,\n exitDuration,\n render,\n } = options;\n\n const inputAttrs: Record<string, string> = {\n 'data-prompt-input': '',\n type: inputType,\n value: defaultValue,\n ...(placeholder !== undefined ? { placeholder } : {}),\n };\n\n const body: OverlayContent =\n render !== undefined\n ? render({\n message,\n input: inputAttrs,\n error: { 'data-prompt-error': '' },\n ok: { 'data-prompt': 'ok' },\n cancel: { 'data-prompt': 'cancel' },\n })\n : jsx('div', {\n class: 'kerf-prompt',\n children: [\n title !== undefined\n ? jsx('h2', { class: 'kerf-prompt__title', children: title })\n : '',\n jsx('label', { class: 'kerf-prompt__message', children: message }),\n jsx('input', { class: 'kerf-prompt__input', ...inputAttrs }),\n jsx('p', {\n class: 'kerf-prompt__error',\n 'data-prompt-error': '',\n children: '',\n }),\n jsx('div', {\n class: 'kerf-prompt__actions',\n children: [\n jsx('button', {\n type: 'button',\n 'data-prompt': 'cancel',\n children: cancelText,\n }),\n jsx('button', {\n type: 'button',\n 'data-prompt': 'ok',\n class: 'kerf-prompt__ok',\n children: okText,\n }),\n ],\n }),\n ],\n });\n\n const handle = overlay(body, {\n container,\n className,\n dismiss: ['escape', 'backdrop'],\n initialFocus: '[data-prompt-input]',\n trap: true,\n native,\n presentation,\n exitClass,\n exitDuration,\n });\n\n // Post-open wiring is still construction: a missing required input or any\n // other throw below removes what was wired, closes the overlay, and rethrows.\n return wireDialog(\n handle,\n (track, guard) => {\n // Looked up again at OK: a reactive re-render may have replaced the\n // input, and a detached node would report a stale value. Missing at\n // construction is a render bug (rolls back, throws); missing at OK\n // rejects the promise through `guard`.\n const inputFor = (problem = 'render missing'): HTMLInputElement => {\n const input = handle.el.querySelector<HTMLInputElement>(\n 'input[data-prompt-input]',\n );\n if (input !== null) return input;\n throw new Error(`prompt(): ${problem} <input data-prompt-input>.`);\n };\n inputFor();\n const errorEl = handle.el.querySelector<HTMLElement>(\n '[data-prompt-error]',\n );\n if (errorEl !== null) errorEl.hidden = true;\n\n // A throwing (or promise-returning) `validate` closes the dialog and\n // rejects the promise (guard).\n const attemptOk = guard((): void => {\n const input = inputFor('removed after open:');\n const value = input.value;\n const error = runValidator(validate, value, 'prompt()');\n if (error !== undefined) {\n if (errorEl !== null) {\n errorEl.textContent = error;\n errorEl.hidden = false;\n }\n input.focus();\n return;\n }\n handle.close(value);\n });\n\n track(\n delegate(handle.el, 'click', '[data-prompt]', (_event, el) => {\n if (el.getAttribute('data-prompt') === 'ok') attemptOk();\n else handle.close(null);\n }),\n );\n\n const onKeydown = (event: KeyboardEvent): void => {\n if (\n event.key === 'Enter' &&\n (event.target as Element | null)?.matches('input[data-prompt-input]')\n ) {\n event.preventDefault();\n attemptOk();\n }\n };\n // Last wiring step: nothing after it can throw, so it needs no rollback.\n handle.el.addEventListener('keydown', onKeydown);\n },\n (value) => (typeof value === 'string' ? value : null),\n );\n}\n","/** `form()` implementation and public option types. */\nimport { delegate } from './delegate.js';\nimport { jsx } from './jsx-runtime.js';\nimport {\n overlay,\n type OverlayContent,\n type OverlayPresentation,\n wireDialog,\n} from './overlay-core.js';\nimport { type FieldValidator, runValidator } from './overlay-prompt.js';\n\n/** A single field in a {@link form}. */\nexport interface FormField {\n name: string;\n label?: string;\n defaultValue?: string;\n placeholder?: string;\n type?: string;\n validate?: FieldValidator;\n}\n\n/** One field's wiring in a {@link FormRenderSlots}. */\nexport interface FormRenderField {\n name: string;\n label: string;\n input: Record<string, string>;\n error: Record<string, string>;\n}\n\n/** Wiring slots for a {@link FormOptions.render}. */\nexport interface FormRenderSlots {\n fields: FormRenderField[];\n ok: Record<string, string>;\n cancel: Record<string, string>;\n}\n\n/** Options for {@link form}. */\nexport interface FormOptions {\n container?: Element;\n className?: string;\n title?: string;\n okText?: string;\n cancelText?: string;\n native?: boolean;\n /** `'bottom-sheet'` presents the dialog as a bottom sheet (see `OverlayOptions.presentation`). Default `'modal'`. */\n presentation?: OverlayPresentation;\n /** Class added on close so CSS owns the exit; the node is removed after it (see `OverlayOptions.exitClass`). The promise settles at once. */\n exitClass?: string;\n /** The exit's hard cap in ms (see `OverlayOptions.exitDuration`). Default `0`. */\n exitDuration?: number;\n render?: (slots: FormRenderSlots) => OverlayContent;\n}\n\n/** A promise-based multi-field dialog. */\nexport function form(\n fields: readonly FormField[],\n options: FormOptions = {},\n): Promise<Record<string, string> | null> {\n const {\n container,\n className = 'kerf-overlay',\n title,\n okText = 'OK',\n cancelText = 'Cancel',\n native = false,\n presentation,\n exitClass,\n exitDuration,\n render,\n } = options;\n\n const fieldAttrs = (field: FormField): Record<string, string> => ({\n 'data-field': field.name,\n name: field.name,\n type: field.type ?? 'text',\n value: field.defaultValue ?? '',\n ...(field.placeholder !== undefined\n ? { placeholder: field.placeholder }\n : {}),\n });\n\n const body: OverlayContent =\n render !== undefined\n ? render({\n fields: fields.map((field) => ({\n name: field.name,\n label: field.label ?? field.name,\n input: fieldAttrs(field),\n error: { 'data-field-error': field.name },\n })),\n ok: { 'data-form': 'ok' },\n cancel: { 'data-form': 'cancel' },\n })\n : jsx('div', {\n class: 'kerf-form',\n children: [\n title !== undefined\n ? jsx('h2', { class: 'kerf-form__title', children: title })\n : '',\n ...fields.map((field) =>\n jsx('div', {\n class: 'kerf-form__field',\n children: [\n jsx('label', {\n class: 'kerf-form__label',\n children: field.label ?? field.name,\n }),\n jsx('input', {\n class: 'kerf-form__input',\n ...fieldAttrs(field),\n }),\n jsx('p', {\n class: 'kerf-form__error',\n 'data-field-error': field.name,\n children: '',\n }),\n ],\n }),\n ),\n jsx('div', {\n class: 'kerf-form__actions',\n children: [\n jsx('button', {\n type: 'button',\n 'data-form': 'cancel',\n children: cancelText,\n }),\n jsx('button', {\n type: 'button',\n 'data-form': 'ok',\n class: 'kerf-form__ok',\n children: okText,\n }),\n ],\n }),\n ],\n });\n\n const handle = overlay(body, {\n container,\n className,\n dismiss: ['escape', 'backdrop'],\n initialFocus: '[data-field]',\n trap: true,\n native,\n presentation,\n exitClass,\n exitDuration,\n });\n\n // Post-open wiring is still construction: a missing required field input or\n // any other throw below removes what was wired, closes the overlay, and\n // rethrows.\n return wireDialog(\n handle,\n (track, guard) => {\n const errorFor = (name: string): HTMLElement | null =>\n Array.from(\n handle.el.querySelectorAll<HTMLElement>('[data-field-error]'),\n ).find((el) => el.getAttribute('data-field-error') === name) ?? null;\n // KF-HRNJ4T (a field input removed after open by a reactive re-render):\n // at construction a missing input is a render bug that rolls back and\n // throws synchronously; at OK time it throws inside `guard`, so the\n // dialog closes and the promise rejects naming the field — never a\n // `null` that reads as a user Cancel.\n const inputFor = (\n name: string,\n problem = 'render missing',\n ): HTMLInputElement => {\n const input = Array.from(\n handle.el.querySelectorAll<HTMLInputElement>('input[data-field]'),\n ).find((el) => el.getAttribute('data-field') === name);\n if (input !== undefined) return input;\n throw new Error(`form(): ${problem} <input data-field=\"${name}\">.`);\n };\n\n for (const field of fields) {\n inputFor(field.name);\n const errorEl = errorFor(field.name);\n if (errorEl !== null) errorEl.hidden = true;\n }\n\n // A throwing `field.validate` closes the dialog and rejects the promise.\n const attemptOk = guard((): void => {\n const record: Record<string, string> = {};\n let firstInvalid: HTMLInputElement | null = null;\n for (const field of fields) {\n const el = inputFor(field.name, 'removed after open:');\n const value = el.value;\n record[field.name] = value;\n const error = runValidator(field.validate, value, 'form()');\n const errorEl = errorFor(field.name);\n if (error !== undefined) {\n if (errorEl !== null) {\n errorEl.textContent = error;\n errorEl.hidden = false;\n }\n if (firstInvalid === null) firstInvalid = el;\n } else if (errorEl !== null) {\n errorEl.hidden = true;\n }\n }\n if (firstInvalid !== null) {\n firstInvalid.focus();\n return;\n }\n handle.close(record);\n });\n\n track(\n delegate(handle.el, 'click', '[data-form]', (_event, el) => {\n if (el.getAttribute('data-form') === 'ok') attemptOk();\n else handle.close(null);\n }),\n );\n\n const onKeydown = (event: KeyboardEvent): void => {\n if (\n event.key === 'Enter' &&\n (event.target as Element | null)?.matches('[data-field]')\n ) {\n event.preventDefault();\n attemptOk();\n }\n };\n // Last wiring step: nothing after it can throw, so it needs no rollback.\n handle.el.addEventListener('keydown', onKeydown);\n },\n (value) =>\n value !== null && typeof value === 'object'\n ? (value as Record<string, string>)\n : null,\n );\n}\n","/**\n * Anchored positioning primitives for `kerfjs/overlay` — position an element\n * relative to an anchor, with viewport flip + clamp. These are standalone: they\n * take any element and have no overlay lifecycle, so `popover()` / `tooltip()`\n * build on them but you can also position your own element (an inline hint, a\n * custom menu). Re-exported from `src/overlay.ts` so the public `kerfjs/overlay`\n * surface is unchanged (KF-511 split out of overlay.ts's dialog + toast code).\n */\n\n/** Vertical placement relative to an anchor (used by `popover`, {@link positionAnchored}, `tooltip`). */\nexport type PopoverPlacement = 'bottom' | 'top';\n\n/** Placement options for {@link positionAnchored} / {@link autoReposition}. */\nexport interface AnchorPositionOptions {\n /** Preferred side of the anchor; flips to the other side if it would overflow the viewport. Default `'bottom'`. */\n placement?: PopoverPlacement;\n /** Horizontal edge to line up with the anchor: `'start'` (left edges) or `'end'` (right edges). Default `'start'`. */\n align?: 'start' | 'end';\n /** Gap in px between the anchor and the element. Default `4`. */\n gap?: number;\n /**\n * Gutter in px kept between the element and the viewport edges: the\n * horizontal clamp stops this far inside the left and right edges, and a\n * side fits only when the element ends this far inside the top or bottom\n * edge. Default `0` (the bare viewport edge).\n */\n viewportMargin?: number;\n /**\n * The element's height can shrink (it scrolls its overflow). When neither\n * side has room for its full height, it takes the side with more room, and\n * that room — from the gap to the viewport margin, in `el`'s CSS px — is\n * published on `el` as the `--kerf-anchor-available-height` custom property\n * on every reposition. Cap the element with it, for example\n * `max-height: var(--kerf-anchor-available-height); overflow: auto`. The\n * height measured for that choice honors the element's own `max-height`\n * (read without the published property, so `max-height: min(300px,\n * var(--kerf-anchor-available-height))` counts as a 300px cap), so an\n * app-capped element that fits the preferred side stays there. A relative\n * cap (`60%`, `calc()`, `min()`, `clamp()`) is resolved against the\n * element's fixed-position containing block (normally the viewport), and a\n * `max-height` transition on the element neither skews that read nor runs\n * because of it. While an animation or transition is already driving\n * `max-height` (an expand-from-0 entrance, a `@keyframes` animation), the\n * cap is the value it is headed to, and it is left running. An above\n * placement is pinned by its bottom edge (`bottom`, with `top: auto`), so\n * the element grows and shrinks upward, away from the anchor, as its height\n * changes between repositions; a below placement sets `top` with\n * `bottom: auto`. Default `false`.\n */\n fitHeight?: boolean;\n}\n\n/** The custom property `fitHeight` publishes on the positioned element. */\nconst AVAILABLE_HEIGHT = '--kerf-anchor-available-height';\n\n/**\n * One-shot: position `el` relative to `anchor` — below by default, flipping above\n * if it would overflow the viewport, aligned to a horizontal edge and clamped into\n * view. Sets `el.style` `position: fixed`, `margin: 0`, `left`, and `top` (fixed so\n * `left`/`top` are viewport coordinates, matching `getBoundingClientRect`). When an\n * ancestor makes itself the containing block for fixed descendants (a\n * `transform`, `filter`, `perspective`, or `contain` on a wrapping `<dialog>`),\n * `left`/`top` are translated (and unscaled) into that box's coordinates so `el`\n * still lands next to the anchor. `viewportMargin` keeps a gutter from the\n * viewport edges; `fitHeight` publishes the room on the chosen side so CSS can\n * cap a scrolling element to it, and pins an above placement by `bottom`\n * (with `top: auto`) so the element grows upward from the anchor. This is\n * `popover()`'s placement core, usable on any element (an inline hint, a tooltip) —\n * no overlay lifecycle. Pair with {@link autoReposition} to keep it glued while open.\n */\nexport function positionAnchored(\n el: HTMLElement,\n anchor: Element,\n options: AnchorPositionOptions = {},\n): void {\n const {\n placement = 'bottom',\n align = 'start',\n gap = 4,\n viewportMargin = 0,\n fitHeight = false,\n } = options;\n // Fix `el` FIRST, then measure it. Measuring a still-`display:block` wrapper\n // reports the full body-content width (≈ viewport minus body margins), which\n // collapses the horizontal clamp below and lands the element at the body's left\n // edge. As a fixed, shrink-to-fit box its `width`/`height` are its real size.\n el.style.position = 'fixed';\n el.style.margin = '0';\n const anchorRect = anchor.getBoundingClientRect();\n const elementRect = el.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n // Vertical: preferred side, flipped only if it overflows and the other side\n // fits. A height-flexible element that fits neither side takes the roomier one.\n const height = fitHeight ? fullHeight(el, elementRect) : elementRect.height;\n const belowTop = anchorRect.bottom + gap;\n const roomBelow = viewportHeight - viewportMargin - belowTop;\n const roomAbove = anchorRect.top - gap - viewportMargin;\n let below = placement !== 'top';\n if (height > roomBelow && height > roomAbove) {\n if (fitHeight) below = roomBelow >= roomAbove;\n } else if (below && height > roomBelow) below = false;\n else if (!below && height > roomAbove) below = true;\n\n // Horizontal: align to an anchor edge, then clamp inside the viewport gutter.\n let left =\n align === 'end' ? anchorRect.right - elementRect.width : anchorRect.left;\n left = Math.max(\n viewportMargin,\n Math.min(left, viewportWidth - viewportMargin - elementRect.width),\n );\n\n // `left`/`top` so far are viewport coordinates. They are only the CSS values\n // too when `el`'s fixed-position containing block is the viewport; an\n // ancestor with a `transform`, `filter`, `perspective`, `contain`, … (say a\n // modal `<dialog>` holding an overlay host slot) captures fixed descendants,\n // so map the coordinates into that box's space.\n const [originX, originY, scaleX, scaleY] = fixedOrigin(el);\n el.style.left = `${(left - originX) / scaleX}px`;\n if (fitHeight) {\n const room = Math.max(0, below ? roomBelow : roomAbove);\n el.style.setProperty(AVAILABLE_HEIGHT, `${room / scaleY}px`);\n if (!below) {\n // Above, a height-flexible element hangs from its bottom edge. Pin\n // `bottom` instead of deriving `top` from a height measured now, so\n // whatever height it goes on to lay out (the cap from the room just\n // published, a `max-height` expand still running, content that grows)\n // grows and shrinks upward, away from the anchor, never over it.\n const edge = anchorRect.top - gap;\n el.style.top = 'auto';\n el.style.bottom = `${(fixedBottom(el, originY, scaleY) - edge) / scaleY}px`;\n return;\n }\n el.style.bottom = 'auto';\n }\n const top = below ? belowTop : anchorRect.top - gap - height;\n el.style.top = `${(top - originY) / scaleY}px`;\n}\n\n/**\n * The height `el` would take without the cap a previous reposition published:\n * its laid-out height plus whatever it currently scrolls, but no more than its\n * own `max-height` (see {@link ownMaxHeight}). Read from scroll metrics rather\n * than by lifting the cap, which would reset the element's own scroll position\n * — and every scroll inside it repositions it. Scroll metrics and `max-height`\n * are CSS px, so they are scaled into the viewport px of `rect`.\n */\nfunction fullHeight(el: HTMLElement, rect: DOMRect): number {\n const scale = el.offsetHeight ? rect.height / el.offsetHeight : 1;\n const full =\n rect.height + Math.max(0, el.scrollHeight - el.clientHeight) * scale;\n return Math.min(full, ownMaxHeight(el) * scale);\n}\n\n/** The vertical padding and border a `content-box` `max-height` excludes. */\nconst VERTICAL_EDGES = [\n 'paddingTop',\n 'paddingBottom',\n 'borderTopWidth',\n 'borderBottomWidth',\n] as const;\n\n/**\n * The stand-in room published while {@link ownMaxHeight} reads the element's\n * own cap: large enough that it never binds, and a valid length so a cap such\n * as `min(300px, var(--kerf-anchor-available-height))` still resolves (removing\n * the property would make that declaration invalid, so `none`).\n */\nconst UNBOUNDED_ROOM = '9999999px';\n\n/**\n * The inline properties {@link ownMaxHeight} overrides around its read, in\n * restore order: the published room and the pinned height, then the\n * transition longhands.\n */\nconst SWAPPED = [\n AVAILABLE_HEIGHT,\n 'height',\n 'transition-property',\n 'transition-duration',\n 'transition-delay',\n];\n\n/** Where the transition longhands start in {@link SWAPPED}. */\nconst TRANSITIONS = 2;\n\n/**\n * `el`'s own border-box `max-height` in CSS px, excluding the room kerf\n * itself published. The published property is swapped for an unbounded room\n * only around a computed-style read and restored at once, so kerf never reads\n * its own last cap back as the element's.\n *\n * That read is a style recalc, but an engine may also lay the element out for\n * it: WebKit resolves container queries with an interleaved layout, so a size\n * container inside `el` (a toolbar with `container-type`) lays `el` out with\n * the cap lifted. Uncapped, `el` would grow to its content and stop\n * scrolling, which clamps its scroll position to the top, and every scroll\n * inside it repositions it. So `el`'s current height is pinned for the read:\n * the interim layout keeps the same box, scroll range, and scrollbar, and the\n * scroll position survives. Should an engine still move it, it is put back.\n *\n * A `max-height` transition would report its running value for that read (the\n * published room, not the cap) and start a transition on the swap, so for the\n * read `max-height` and `height` are appended to the element's transition\n * list with no duration or delay (the last entry for a property wins); every\n * other running transition keeps running. The restored cap and height are\n * settled before the app's transitions return, so they see no change to\n * animate.\n *\n * While an animation or transition on `el` drives `max-height`, the cap is\n * the value it is headed to ({@link animatedMaxHeight}) and nothing is\n * swapped.\n *\n * A cap that stays relative after computing (a percentage, `calc()`,\n * `min()`, `clamp()`) is resolved against `el`'s containing block by\n * {@link resolveHeight}; a keyword (`none`, `fit-content`) is no cap.\n */\nfunction ownMaxHeight(el: HTMLElement): number {\n const style = window.getComputedStyle(el);\n const maxHeight = animatedMaxHeight(el) ?? swappedMaxHeight(el, style);\n const inset =\n style.boxSizing === 'border-box'\n ? 0\n : VERTICAL_EDGES.reduce(\n (sum, edge) => sum + (Number.parseFloat(style[edge]) || 0),\n 0,\n );\n if (maxHeight.endsWith('px')) return Number.parseFloat(maxHeight) + inset;\n // A keyword is no cap, and so is a keyframe `var()` that only `el` could\n // resolve (the probe does not inherit `el`'s custom properties).\n if (/^[a-z-]+$|var\\(/.test(maxHeight)) return Infinity;\n return resolveHeight(el, maxHeight) + inset;\n}\n\n/**\n * `el`'s computed `max-height` with the published room swapped out, as\n * {@link ownMaxHeight} describes: the room and, when `el` has transitions,\n * the transition longhands are overridden for the read and restored exactly.\n */\nfunction swappedMaxHeight(el: HTMLElement, style: CSSStyleDeclaration): string {\n const inline = el.style;\n const saved = SWAPPED.map((name): [string, string, string] => [\n name,\n inline.getPropertyValue(name),\n inline.getPropertyPriority(name),\n ]);\n // The computed transition lists, read before any of them is overridden.\n const lists = SWAPPED.map((name) => style.getPropertyValue(name).split(','));\n const transitions = lists[TRANSITIONS]!;\n if (transitions[0] && transitions[0] !== 'none') {\n // Repeat the duration and delay lists to the property list's length, as\n // CSS does, so appending entries leaves every existing pairing intact.\n for (let index = TRANSITIONS; index < SWAPPED.length; index++) {\n const items = lists[index]!;\n const appended =\n index > TRANSITIONS ? ['0s', '0s'] : ['max-height', 'height'];\n inline.setProperty(\n SWAPPED[index]!,\n [\n ...transitions.map((_, entry) => items[entry % items.length]),\n ...appended,\n ].join(),\n 'important',\n );\n }\n }\n // The current box and scroll position, from the layout positioning just\n // measured. A height the engine reports in px is pinned for the read.\n const height = style.height;\n const { scrollTop, scrollLeft } = el;\n if (height.endsWith('px')) inline.setProperty('height', height, 'important');\n inline.setProperty(AVAILABLE_HEIGHT, UNBOUNDED_ROOM);\n const maxHeight = style.maxHeight;\n saved.forEach(([name, value, priority], index) => {\n if (value) inline.setProperty(name, value, priority);\n else inline.removeProperty(name);\n // Settle the restored room and height before the transitions return.\n if (index === TRANSITIONS - 1) style.getPropertyValue('max-height');\n });\n // Only a scrolled element can have lost its position; reading it back\n // costs a layout, so an unscrolled one skips that.\n if (scrollTop && el.scrollTop !== scrollTop) el.scrollTop = scrollTop;\n if (scrollLeft && el.scrollLeft !== scrollLeft) el.scrollLeft = scrollLeft;\n return maxHeight;\n}\n\n/**\n * The `max-height` an unfinished animation or transition on `el` is headed\n * to, or `undefined` when none drives it. While one runs (or is paused), the\n * computed value is its current frame — part-way through an app's expand\n * transition, or a `@keyframes` value — not the cap the element settles at,\n * and lifting the published room could retarget or cancel the app's\n * transition. So the cap is read from the effect instead: its last\n * `max-height` keyframe, or its first while the current iteration plays in\n * reverse. The topmost such effect in composite order wins; a finished one\n * that still fills already shows its final value in computed style.\n */\nfunction animatedMaxHeight(el: HTMLElement): string | undefined {\n // An engine (or DOM shim) without Web Animations has nothing animating.\n const animations = el.getAnimations?.() ?? [];\n for (let index = animations.length - 1; index >= 0; index--) {\n const animation = animations[index]!;\n const effect = animation.effect as KeyframeEffect | null;\n const frames = (effect?.getKeyframes() ?? []).filter(\n (frame) => frame['maxHeight'] != null,\n );\n if (!frames.length) continue;\n if (animation.playState === 'finished') return undefined;\n const { direction, currentIteration } = effect!.getComputedTiming();\n const odd = (currentIteration ?? 0) % 2 === 1;\n const reversed =\n (direction === 'reverse' ||\n (direction === 'alternate' && odd) ||\n (direction === 'alternate-reverse' && !odd)) !==\n animation.playbackRate < 0;\n return String(frames[reversed ? 0 : frames.length - 1]!['maxHeight']);\n }\n return undefined;\n}\n\n/**\n * Resolve a computed but still relative height (`60%`, `calc(50% - 1rem)`,\n * `min(300px, 60%)`) to CSS px against `el`'s fixed-position containing block\n * — the viewport, or a transformed ancestor: a fixed probe beside `el` takes it\n * as its `height`, and the probe's used height is read back. `el` itself is\n * never touched, so its scroll position and layout are unaffected. A height\n * the probe cannot take, or a detached `el`, is no cap.\n */\nfunction resolveHeight(el: HTMLElement, height: string): number {\n return withFixedProbe(\n el,\n 'width:0;box-sizing:content-box;min-height:0;max-height:none;visibility:hidden',\n (probe) => {\n probe.style.height = height;\n if (!probe.style.height) return Infinity;\n return Number.parseFloat(window.getComputedStyle(probe).height);\n },\n Infinity,\n );\n}\n\n/**\n * Run `measure` on a fixed-position probe at `left: 0; top: 0`, inserted just\n * before `el` so it shares `el`'s containing block, then remove it. The probe\n * is inserted and removed synchronously, so it is never painted. A detached\n * `el` has no containing block to share, so `detached` is returned instead.\n */\nfunction withFixedProbe<T>(\n el: HTMLElement,\n css: string,\n measure: (probe: HTMLElement) => T,\n detached: T,\n): T {\n const parent = el.parentNode;\n if (!parent) return detached;\n const probe = el.ownerDocument.createElement('div');\n probe.style.cssText = `position:fixed;left:0;top:0;display:block;margin:0;padding:0;border:0;${css}`;\n parent.insertBefore(probe, el);\n const result = measure(probe);\n probe.remove();\n return result;\n}\n\n/**\n * Where `left: 0; top: 0` actually lands for a fixed-position child of `el`'s\n * parent, plus that containing block's scale — `[x, y, scaleX, scaleY]`, which\n * is `[0, 0, 1, 1]` when the viewport is the containing block. Measured with a\n * 1px probe rather than `el` itself so `el`'s own transform or running entrance\n * animation cannot skew it. Translation and scale are compensated; a rotated\n * or skewed containing block is not.\n */\nfunction fixedOrigin(el: HTMLElement): [number, number, number, number] {\n return withFixedProbe(\n el,\n 'width:1px;height:1px',\n (probe): [number, number, number, number] => {\n const rect = probe.getBoundingClientRect();\n // A zero size (a containing block mid `scale(0)` animation, or a DOM\n // without layout) would divide by zero; treat it as unscaled.\n return [rect.left, rect.top, rect.width || 1, rect.height || 1];\n },\n [0, 0, 1, 1],\n );\n}\n\n/**\n * The viewport y of the bottom edge of `el`'s fixed-position containing block\n * (where `bottom: 0` lands), measured with a 1px probe pinned there. A\n * detached `el`, or a containing block with no layout (a DOM without layout,\n * a `scale(0)` animation), falls back to the viewport height below the origin\n * {@link fixedOrigin} measured, at its scale.\n */\nfunction fixedBottom(el: HTMLElement, originY: number, scaleY: number): number {\n const fallback = originY + window.innerHeight * scaleY;\n return withFixedProbe(\n el,\n 'width:1px;height:1px;top:auto;bottom:0',\n (probe) => {\n const rect = probe.getBoundingClientRect();\n return rect.height ? rect.bottom : fallback;\n },\n fallback,\n );\n}\n\n/**\n * Keep `el` positioned against `anchor` (via {@link positionAnchored}) as the page\n * scrolls or resizes. Positions once immediately, then re-runs on `scroll`\n * (capture phase — catches scrolls in any inner container, not just `window`),\n * `resize`, and, where `ResizeObserver` exists, whenever the anchor's or `el`'s\n * own size changes — a field that grows a line as it fills, or an end-aligned\n * or above-placed surface whose content grows — so `el` stays lined up with\n * the anchor edge it hangs from. A size change that `el`'s own repositioning\n * caused (a published `fitHeight` cap, a shrink-to-fit width near the viewport\n * edge) is not acted on again, so positioning can never feed itself. Returns\n * a disposer that removes the listeners and the observer.\n */\nexport function autoReposition(\n el: HTMLElement,\n anchor: Element,\n options: AnchorPositionOptions = {},\n): () => void {\n const RO = globalThis.ResizeObserver;\n const nodes = [anchor, el];\n // The anchor's and `el`'s sizes once the last reposition's writes landed.\n let settled = '';\n const sizes = (): string =>\n nodes\n .map((node) => {\n const rect = node.getBoundingClientRect();\n return [rect.width, rect.height];\n })\n .join();\n const reposition = (): void => {\n positionAnchored(el, anchor, options);\n if (RO) settled = sizes();\n };\n reposition();\n window.addEventListener('scroll', reposition, true);\n window.addEventListener('resize', reposition);\n // Only a size that differs from what the last reposition left behind is a\n // change from outside: the observer's first report, and any resize the\n // positioning writes themselves caused, match it and are skipped.\n const observer =\n RO &&\n new RO(() => {\n if (sizes() !== settled) reposition();\n });\n nodes.forEach((node) => observer?.observe(node));\n return () => {\n window.removeEventListener('scroll', reposition, true);\n window.removeEventListener('resize', reposition);\n observer?.disconnect();\n };\n}\n","/** Anchored popover lifecycle built on the shared overlay transaction. */\nimport { attach } from './attach.js';\nimport {\n anchorOverlay,\n type DismissTrigger,\n INSTANT,\n overlay,\n type OverlayContent,\n type OverlayHandle,\n overlayHost,\n} from './overlay-core.js';\nimport { autoReposition, type PopoverPlacement } from './overlay-position.js';\n\n/** Options for {@link popover}. */\nexport interface PopoverOptions {\n /**\n * Where to append the popover wrapper. Default: when `anchor` sits inside an\n * open modal `<dialog>`, that dialog's `[data-kerf-overlay-host]` element (a\n * dialog kerf opened gets one automatically), so the popover is part of the\n * modal subtree and stays interactive; otherwise `document.body`. A modal\n * `<dialog>` in a shadow root counts when `anchor` is slotted into it (Web\n * Awesome's `wa-dialog` / `wa-drawer`): the slot is created on demand in the\n * shadow host's light DOM. A popover inside a modal closes when that dialog\n * closes.\n */\n container?: Element;\n /** Class on the wrapper. Default `'kerf-popover'`. */\n className?: string;\n /** Preferred side of the anchor. Flips to the other side if it would overflow the viewport. Default `'bottom'`. */\n placement?: PopoverPlacement;\n /** Horizontal edge to line up with the anchor: `'start'` (left edges) or `'end'` (right edges). Default `'start'`. */\n align?: 'start' | 'end';\n /** Gap in px between the anchor and the popover. Default `4`. */\n gap?: number;\n /** Gutter in px kept from the viewport edges. See `AnchorPositionOptions.viewportMargin`. Default `0`. */\n viewportMargin?: number;\n /**\n * Fit a scrolling popover to the room beside the anchor: take the roomier\n * side when neither fits and publish that room as\n * `--kerf-anchor-available-height`. See `AnchorPositionOptions.fitHeight`.\n * Default `false`.\n */\n fitHeight?: boolean;\n /**\n * Which user actions dismiss the popover. Default `['outside']` (a click\n * outside the popover, the anchor exempt). Pass `false` to close only via `close()`.\n */\n dismiss?: DismissTrigger | DismissTrigger[] | false;\n /** Focus behavior on open. Default `false` (non-modal — leave focus alone). */\n initialFocus?: string | boolean;\n /** Extra elements (besides the anchor) whose clicks do NOT count as outside. */\n outsideIgnore?: Element | readonly Element[];\n /** Called on any user-initiated dismissal. */\n onDismiss?: () => void;\n /**\n * Host the popover in the browser top layer (the Popover API — `[popover]` +\n * `showPopover()`) where supported, so it stacks above any `z-index` without a\n * z-index war. Falls back to today's plain `<div>` where unsupported. kerf keeps\n * owning positioning + its own dismiss wiring; the popover is `popover=\"manual\"`.\n * See {@link OverlayOptions.native}. Default `false`.\n */\n native?: boolean;\n /**\n * Class added when the popover closes, so CSS owns its **exit**. See\n * {@link OverlayOptions.exitClass}: `close()` and a user dismissal play it;\n * the teardown when the anchor leaves the document is instant.\n */\n exitClass?: string;\n /** The exit's hard cap in ms. See {@link OverlayOptions.exitDuration}. Default `0`. */\n exitDuration?: number;\n}\n\n/**\n * Anchored, non-modal overlay: positions `content` relative to `anchor` (below by\n * default, flipping above if it would overflow, and clamped horizontally to the\n * viewport) and repositions on scroll / resize while open. A thin wrapper over\n * {@link overlay} with non-modal defaults — `trap: false`, `dismiss: ['outside']`,\n * and the anchor added to `outsideIgnore` so the trigger click doesn't self-close.\n * Returns the same {@link OverlayHandle}; `close()` also drops the reposition\n * listeners. `position: fixed` is set inline (you style everything else).\n */\nexport function popover(\n anchor: Element,\n content: OverlayContent,\n options: PopoverOptions = {},\n): OverlayHandle {\n const {\n container,\n className = 'kerf-popover',\n placement = 'bottom',\n align = 'start',\n gap = 4,\n viewportMargin,\n fitHeight,\n dismiss = ['outside'],\n initialFocus = false,\n outsideIgnore,\n onDismiss,\n native = false,\n exitClass,\n exitDuration,\n } = options;\n\n const extraIgnore =\n outsideIgnore === undefined\n ? []\n : Array.isArray(outsideIgnore)\n ? [...outsideIgnore]\n : [outsideIgnore];\n\n const handle = overlay(content, {\n container: container ?? overlayHost(anchor),\n className,\n dismiss,\n trap: false,\n initialFocus,\n onDismiss,\n outsideIgnore: [anchor, ...extraIgnore],\n native,\n exitClass,\n exitDuration,\n });\n\n // Position + keep it glued while open; drop the listeners on close. A throw\n // while positioning (e.g. an anchor whose geometry read fails) is still part\n // of construction: close the just-opened overlay before rethrowing.\n let stopReposition: () => void;\n try {\n stopReposition = autoReposition(handle.el, anchor, {\n placement,\n align,\n gap,\n viewportMargin,\n fitHeight,\n });\n } catch (error) {\n handle.close(undefined, INSTANT);\n throw error;\n }\n void handle.result.then(stopReposition);\n // KF-XNEK58: an overlay holding the anchor closes this popover at its own\n // close(), not when its (possibly exiting) node is finally removed.\n anchorOverlay(handle, anchor);\n\n // KF-BAVCEV: never outlive the anchor. When it leaves the document (e.g. the\n // modal holding it closes) close the popover as cleanup — not a user\n // dismissal, so no `onDismiss`. A move within the document keeps it open.\n // Instant, like construction rollback: there is no anchor left to exit from.\n // The watch's own disposal at `result` runs this teardown too, with the\n // anchor still connected — an exit then starting must not end.\n void handle.result.then(\n attach(anchor, () => () => {\n if (!anchor.isConnected) handle.close(undefined, INSTANT);\n }),\n );\n\n return handle;\n}\n","/**\n * `toast()` for `kerfjs/overlay` — a non-modal, auto-dismissing notification that\n * stacks in a shared body-level region. Split out of `overlay.ts` (KF-513) since\n * it's a distinct transient-UI concern from the modal dialogs; re-exported from\n * `overlay.ts` so the public `kerfjs/overlay` surface is unchanged. Structural\n * only — kerf ships no CSS; you style the region / toast / animations.\n */\nimport { type SafeHtml } from './jsx-runtime.js';\nimport { mount, type MountResult } from './mount.js';\nimport { escapeHtml } from './utils/escapeHtml.js';\n\n/** Content for a {@link toast}: an escaped text string, trusted `SafeHtml`, or a render function. */\nexport type ToastContent = string | SafeHtml | (() => MountResult);\n\n/** Accent variant for a {@link toast} — mapped to a `${className}--${variant}` class. */\nexport type ToastVariant = 'info' | 'success' | 'warning';\n\n/** Options for {@link toast}. */\nexport interface ToastOptions {\n /** Where toasts stack. Default: a lazily-created `<div class=\"kerf-toasts\">` on `document.body`. */\n container?: Element;\n /** Class on the toast element. Default `'kerf-toast'`. */\n className?: string;\n /** Auto-dismiss after this many ms. `0` keeps it until dismissed by hand. Default `4000`. */\n duration?: number;\n /** ARIA role. Default `'status'`. */\n role?: string;\n /**\n * `'stack'` (default) shows toasts stacked in the region; `'replace'` dismisses\n * the region's current toast(s) first (collapse-to-latest for a rapid sequence).\n */\n mode?: 'stack' | 'replace';\n /**\n * How `mode: 'replace'` drops the prior toast(s): `'fade'` (default) runs their\n * full exit transition (nice for a STACKING region), or `'instant'` removes them\n * synchronously with no exit — what a single, exactly-centered toast slot wants,\n * so the outgoing and incoming messages never cross-fade in the same spot.\n */\n collapse?: 'fade' | 'instant';\n /** Accent variant — adds a `${className}--${variant}` class (kerf ships no CSS; you style it). */\n variant?: ToastVariant;\n /** Class added on the next animation frame after mount, so a CSS **entrance** transition can run. */\n enterClass?: string;\n /**\n * Class added when dismissing, so CSS owns the **exit**. On dismiss the\n * `enterClass` (if any) is also REMOVED, so `exitClass` doesn't have to\n * out-specify it — and a symmetric single-class fade (entrance = add\n * `enterClass`, exit = remove it) works by setting only `enterClass` +\n * `exitDuration`. The node is removed `exitDuration` ms later.\n */\n exitClass?: string;\n /** ms to wait before removing the node on dismiss — applies when `exitClass` is set OR when it's > 0 (to let a removed `enterClass` transition out). Default `0`. */\n exitDuration?: number;\n}\n\n/** Handle returned by {@link toast}. */\nexport interface ToastHandle {\n /** The toast element — inspect it, or run your own entrance/exit transitions. */\n el: HTMLElement;\n /**\n * Dismiss it early. Default runs the `exitClass` transition (removed after\n * `exitDuration`); pass `{ instant: true }` to remove it **synchronously** with\n * no exit — for an action button that immediately shows a replacement toast in a\n * single centered slot (no cross-fade). Idempotent.\n */\n dismiss(options?: { instant?: boolean }): void;\n}\n\n/** The region's active toasts live on the region element (in the DOM), not in module state. */\nconst TOAST_SET = Symbol('kerf.toasts');\n/** A dismiss function with an `.removeNow()` for instant (no-exit) teardown. */\ntype Dismisser = (() => void) & { removeNow: () => void };\ntype ToastCarrier = Element & { [TOAST_SET]?: Set<Dismisser> };\n\n/** The singleton toast region lives in the DOM (queried, not held in a module variable). */\nfunction toastRegion(container?: Element): Element {\n if (container !== undefined) return container;\n const existing = document.querySelector('.kerf-toasts');\n if (existing !== null) return existing;\n const region = document.createElement('div');\n region.className = 'kerf-toasts';\n region.setAttribute('aria-live', 'polite');\n document.body.appendChild(region);\n return region;\n}\n\n/**\n * Show a non-modal, auto-dismissing notification. Stacks in a shared body-level\n * region (or your `container`). Returns a {@link ToastHandle} (`{ el, dismiss }`)\n * so you can run entrance/exit transitions, wire an action button, or inspect the\n * node. `mode: 'replace'` collapses a rapid sequence to the latest; `variant`\n * adds an accent class; `enterClass`/`exitClass` let CSS own the animation.\n */\nexport function toast(\n content: ToastContent,\n options: ToastOptions = {},\n): ToastHandle {\n const {\n container,\n className = 'kerf-toast',\n duration = 4000,\n role = 'status',\n mode = 'stack',\n collapse = 'fade',\n variant,\n enterClass,\n exitClass,\n exitDuration = 0,\n } = options;\n\n const region = toastRegion(container) as ToastCarrier;\n const active = (region[TOAST_SET] ??= new Set<Dismisser>());\n // collapse-to-latest: 'instant' removes priors synchronously (no cross-fade in a\n // centered single slot); 'fade' runs their exit transition (nice for a stack).\n if (mode === 'replace') {\n for (const d of [...active]) {\n if (collapse === 'instant') d.removeNow();\n else d();\n }\n }\n\n const el = document.createElement('div');\n el.className = className;\n if (variant !== undefined) el.classList.add(`${className}--${variant}`);\n el.setAttribute('role', role);\n region.appendChild(el);\n\n const render =\n typeof content === 'function'\n ? content\n : () => (typeof content === 'string' ? escapeHtml(content) : content);\n const disposeMount = mount(el, render);\n const state: {\n dismissed: boolean;\n removed: boolean;\n timer: ReturnType<typeof setTimeout> | undefined;\n exitTimer: ReturnType<typeof setTimeout> | undefined;\n } = {\n dismissed: false,\n removed: false,\n timer: undefined,\n exitTimer: undefined,\n };\n\n if (enterClass !== undefined) {\n globalThis.requestAnimationFrame(() => {\n if (!state.dismissed) el.classList.add(enterClass);\n });\n }\n\n const remove = (): void => {\n if (state.removed) return;\n state.removed = true;\n state.dismissed = true; // once removed, a later dismiss() is a clean no-op\n if (state.exitTimer !== undefined) clearTimeout(state.exitTimer);\n disposeMount();\n el.remove();\n active.delete(dismiss as Dismisser);\n };\n\n // Force synchronous teardown NOW, with no exit transition — even if a fade is\n // already in flight (so `mode:'replace'` collapse can clean up a mid-exit toast,\n // and `dismiss({ instant: true })` drops it immediately).\n const removeNow = (): void => {\n if (state.timer !== undefined) clearTimeout(state.timer);\n remove();\n };\n\n const fadeOut = (): void => {\n if (state.dismissed) return;\n state.dismissed = true;\n if (state.timer !== undefined) clearTimeout(state.timer);\n // Reverse the entrance (drop enterClass so exitClass needn't out-specify it),\n // add exitClass, and delay removal for the transition — including the\n // single-class idiom (enterClass removed + exitDuration, no exitClass).\n if (enterClass !== undefined) el.classList.remove(enterClass);\n if (exitClass !== undefined) el.classList.add(exitClass);\n if (exitClass !== undefined || exitDuration > 0) {\n state.exitTimer = setTimeout(remove, exitDuration);\n } else {\n remove();\n }\n };\n\n function dismiss(options?: { instant?: boolean }): void {\n if (options?.instant === true) removeNow();\n else fadeOut();\n }\n (dismiss as Dismisser).removeNow = removeNow;\n\n active.add(dismiss as Dismisser);\n if (duration > 0) state.timer = setTimeout(fadeOut, duration);\n return { el, dismiss };\n}\n","/** Hover and focus tooltip lifecycle built on the shared overlay transaction. */\nimport { attach } from './attach.js';\nimport { jsx, type SafeHtml } from './jsx-runtime.js';\nimport type { MountResult } from './mount.js';\nimport {\n anchorOverlay,\n INSTANT,\n overlay,\n type OverlayCloseOptions,\n type OverlayContent,\n type OverlayHandle,\n overlayHost,\n} from './overlay-core.js';\nimport {\n type AnchorPositionOptions,\n autoReposition,\n} from './overlay-position.js';\n\n/** Content for a {@link tooltip}: text (auto-escaped), `SafeHtml`, or a render function. */\nexport type TooltipContent = string | SafeHtml | (() => MountResult);\n\n/** Options for {@link tooltip}. */\nexport interface TooltipOptions extends AnchorPositionOptions {\n /** Where to append the tooltip wrapper. Default: the anchor's modal-dialog host slot (see {@link PopoverOptions.container}), else `document.body`. */\n container?: Element;\n /** Class on the wrapper. Default `'kerf-tooltip'`. */\n className?: string;\n /** Delay in ms before showing after hover/focus enters. Default `400`. */\n delay?: number;\n /** Delay in ms before hiding after hover/focus leaves. Default `100`. */\n hideDelay?: number;\n /** ARIA role on the wrapper. Default `'tooltip'`. */\n role?: string;\n /** Host the tooltip in the browser top layer (the Popover API) where supported. See {@link OverlayOptions.native}. Default `false`. */\n native?: boolean;\n /**\n * Class added when the tooltip hides, so CSS owns its **exit**. See\n * {@link OverlayOptions.exitClass}: the hide after `hideDelay` plays it;\n * the anchor leaving the document and the disposer hide instantly. Showing\n * again while the previous tooltip is still exiting removes that leaving\n * node at once and opens a fresh one, so an anchor never has two.\n */\n exitClass?: string;\n /** The exit's hard cap in ms. See {@link OverlayOptions.exitDuration}. Default `0`. */\n exitDuration?: number;\n}\n\n/**\n * A hover/focus-triggered, non-modal, auto-hiding tooltip anchored to `anchor`.\n * Shows after `delay` on `pointerenter`/`focus`, hides after `hideDelay` on\n * `pointerleave`/`blur`, and positions itself with {@link autoReposition} (above\n * the anchor by default). Unlike {@link popover} there is no click-dismiss model —\n * it follows the pointer/focus. Returns a disposer that removes the anchor\n * listeners and hides any shown tooltip at once (ending a running exit, too).\n * Structural only (kerf ships no CSS).\n */\nexport function tooltip(\n anchor: Element,\n content: TooltipContent,\n options: TooltipOptions = {},\n): () => void {\n const {\n container,\n className = 'kerf-tooltip',\n delay = 400,\n hideDelay = 100,\n role = 'tooltip',\n placement = 'top',\n align = 'start',\n gap = 4,\n viewportMargin,\n fitHeight,\n native = false,\n exitClass,\n exitDuration,\n } = options;\n\n const body: OverlayContent =\n typeof content === 'function'\n ? content\n : typeof content === 'string'\n ? jsx('span', { class: `${className}__text`, children: content })\n : content;\n\n const timers: {\n show?: ReturnType<typeof setTimeout>;\n hide?: ReturnType<typeof setTimeout>;\n } = {};\n let current:\n | { handle: OverlayHandle; stop: () => void; unwatch: () => void }\n | undefined;\n // The previous tooltip while its exit runs (or already removed — closing it\n // again instantly is then a no-op).\n let leaving: OverlayHandle | undefined;\n let presence = 0;\n\n // Runs from the `delay` timer, so there is no caller to throw to. A failed\n // show (a throwing render fn, `native` `showPopover()`, or positioning) is\n // rolled back before `current` is set — nothing stays on screen and the\n // next pointerenter / focus schedules a fresh attempt — and the original\n // error then escapes the timer callback for the host to report as uncaught\n // (a window `error` event in browsers), the same way kerf's other deferred\n // callbacks (debounce / throttle timers, attach teardown) surface errors.\n function show(): void {\n // The anchor left the document while the show was pending (KF-BAVCEV),\n // or sits in an inert subtree — e.g. an overlay already exiting (KF-XNEK58).\n if (!anchor.isConnected || anchor.closest('[inert]') !== null) return;\n // One tooltip per anchor: a show during the previous one's exit ends that\n // exit now. Both happen in this task, so no frame paints without a tooltip.\n leaving?.close(undefined, INSTANT);\n leaving = undefined;\n const handle = overlay(body, {\n container: container ?? overlayHost(anchor),\n className,\n dismiss: false,\n trap: false,\n initialFocus: false,\n native,\n exitClass,\n exitDuration,\n });\n handle.el.setAttribute('role', role);\n let stop: () => void;\n try {\n stop = autoReposition(handle.el, anchor, {\n placement,\n align,\n gap,\n viewportMargin,\n fitHeight,\n });\n } catch (error) {\n // Not yet tracked in `current`, so `hide()` could never reach it.\n handle.close(undefined, INSTANT);\n throw error;\n }\n // KF-BAVCEV: an anchor removed from the document (e.g. with the modal that\n // held it) fires no pointerleave / blur, so hide when it leaves and forget\n // its presence; a move within the document keeps the tooltip shown. No\n // exit: there is no anchor left to exit from.\n const unwatch = attach(anchor, () => () => drop(INSTANT));\n current = { handle, stop, unwatch };\n // KF-XNEK58: an overlay holding the anchor that closes hides this tooltip\n // at its close(), with an exit only when that overlay exits too.\n anchorOverlay(handle, anchor, (now) => drop(now ? INSTANT : undefined));\n // A surface that closed itself (its host slot left the document with the\n // dialog) must not stay `current`, or the next hover would never show.\n void handle.result.then(() => {\n if (current?.handle === handle) hide();\n });\n }\n\n // The anchor is gone (or its host is closing): forget presence and hide.\n function drop(closeOptions?: OverlayCloseOptions): void {\n presence = 0;\n if (timers.hide !== undefined) clearTimeout(timers.hide);\n hide(closeOptions);\n }\n\n function hide(closeOptions?: OverlayCloseOptions): void {\n const shown = current;\n if (shown === undefined) return;\n // Cleared first: `unwatch()` runs the anchor teardown, which re-enters here.\n current = undefined;\n shown.unwatch();\n shown.stop();\n shown.handle.close(undefined, closeOptions);\n leaving = shown.handle;\n }\n\n const onEnter = (event: Event): void => {\n presence |= event.type === 'focus' ? 2 : 1;\n if (timers.hide !== undefined) clearTimeout(timers.hide);\n if (current !== undefined) return;\n if (timers.show !== undefined) clearTimeout(timers.show); // debounce: one pending show at a time\n timers.show = setTimeout(show, delay);\n };\n const onLeave = (event: Event): void => {\n presence &= event.type === 'blur' ? ~2 : ~1;\n if (presence) return;\n if (timers.show !== undefined) clearTimeout(timers.show);\n if (current === undefined) return;\n timers.hide = setTimeout(() => hide(), hideDelay);\n };\n\n anchor.addEventListener('pointerenter', onEnter);\n anchor.addEventListener('pointerleave', onLeave);\n anchor.addEventListener('focus', onEnter);\n anchor.addEventListener('blur', onLeave);\n\n return () => {\n anchor.removeEventListener('pointerenter', onEnter);\n anchor.removeEventListener('pointerleave', onLeave);\n anchor.removeEventListener('focus', onEnter);\n anchor.removeEventListener('blur', onLeave);\n if (timers.show !== undefined) clearTimeout(timers.show);\n if (timers.hide !== undefined) clearTimeout(timers.hide);\n hide(INSTANT);\n leaving?.close(undefined, INSTANT);\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kerfjs",
3
- "version": "5.0.0-beta.105",
3
+ "version": "5.0.0-beta.107",
4
4
  "description": "Tiny reactive UI framework — fine-grained signals + DOM morphing + JSX. Apply the smallest possible cut to update your DOM.",
5
5
  "type": "module",
6
6
  "sideEffects": [