Overlay
<caos-overlay>
the one scrim-and-panel shell behind every modal and drawer
Nowhere yet — this piece is not offered to a page.
Inputs
Section titled “Inputs”| Name | Attribute | Description | Type | Default | Required |
|---|---|---|---|---|---|
label |
label, markup only |
The accessible name of the dialog. It is what a screen reader announces on entering the panel, so it should say which dialog this is rather than what it contains. | text | none declared | Optional |
placement |
placement, markup only |
Where the panel sits: center, a modal floating near the top of the page, or end, a full-height drawer flush against the right-hand edge. Everything else about the two is identical. | text — one of center, end | center | Optional |
Events
Section titled “Events”| Name | When it fires | What it carries |
|---|---|---|
caos-overlay-close |
The scrim is clicked or Escape is pressed. It is a REQUEST — the overlay does not remove itself, and the event is cancelable, so a host with unsaved changes can prevent it and ask. | nothing |
| Name | What goes in it |
|---|---|
| the default slot | The panel body. It gets no padding from the shell, so whatever goes in brings its own — a padded head with a full-bleed divider under it is the shape every caller uses. |
Styling hooks
Section titled “Styling hooks”| Design token | What it controls |
|---|---|
--caos-overlay-width |
How wide the panel is: the max width of a centred modal (760px by default) and the fixed width of a drawer (420px). Set by the caller per dialog — a two-column record form needs more than a confirmation does. |
--caos-overlay-scrim |
The dimming behind the panel. Defined on the element itself with a default of rgba(0, 0, 0, 0.6) — a token that names this component rather than a platform axis, which is recorded here rather than left buried in the stylesheet. |
--caos-color-surface |
The panel fill. |
--caos-color-border-strong |
The panel edge. |
--caos-shadow-float |
The one elevation reserved for pieces that float. |
--caos-radius-lg |
The corner radius of a centred modal. A drawer has none on its flush edge. |
--caos-space-4 |
The gap between a centred modal and the edge of the screen. |
Methods
Section titled “Methods”| Name | Description | Arguments |
|---|---|---|
requestClose() |
Raise the close request from code, exactly as the scrim and Escape do — for a Cancel button inside the panel, so one path decides what closing means. | takes none |
alertDialog() |
Say something and wait for it to be acknowledged. One button, nothing to read back: the button, the scrim and Escape all mean the same thing. Takes { message, heading, confirmLabel }. This and the two below are CALLS against this one overlay rather than small dialog components of their own — they are the same dialog with different footers, so they share the scrim, the focus trap, the Escape behaviour and the dialog role instead of each keeping a copy. | options: CaosDialogOptions |
confirmDialog() |
Ask before going ahead. Resolves true only if the committing button was the answer — the scrim and Escape are a no, because a dialog somebody dismissed is not a dialog somebody agreed to. Told that committing is destructive, the committing button takes the destructive colour and nothing else about the dialog changes. | options: CaosDialogOptions |
promptDialog() |
Ask for something and read it back. Resolves the text as typed, or null if the dialog was cancelled or dismissed — which is how a caller tells “they typed nothing” from “they said no”, two answers an empty string cannot keep apart. The field is focused first, because it is what the dialog is for. | options: CaosPromptOptions |
Readable state
Section titled “Readable state”Nothing on this piece can be read back.
Styling parts
Section titled “Styling parts”| Part | Which piece of it | When it is there |
|---|---|---|
::part(scrim) |
the dimmed backdrop, which is also the click-to-close target | Always |
::part(panel) |
the floating panel | Always |
When to use it
Section titled “When to use it”Something has to be dealt with in front of the page, rather than on it: a form for a new record, a confirmation, a picker, a detail panel that arrives from the side. Reach for this one whether it ends up centred or on the edge — it is the same shell either way.
What to use instead
Section titled “What to use instead”- Inspector — The panel belongs BESIDE the work rather than over it, and the page behind it stays usable while somebody edits the properties of what they have selected.
- SplitView — The second pane is part of the surface — a list on the left, the record you are reading on the right.
- OverflowMenu — What opens is a short list of actions off a trigger, not a panel of content.
Accessibility
Section titled “Accessibility”The panel is a role=“dialog” with aria-modal, named by the label attribute. On mount it moves focus inside (deferred a frame so slotted content has rendered its controls), traps Tab within the panel — piercing slotted custom elements, so a button whose real control lives in its own shadow root is still in the ring — and returns focus to whatever opened it when it is unmounted. The scrim is a real button with an accessible name, and Escape does the same thing it does. What is left to the author: set label, or the dialog has no name; and actually unmount on close, because the focus return happens on disconnect.
Examples
Section titled “Examples”As a centred modal
Section titled “As a centred modal”The shell with its default placement: a dialog floating near the top of the page, scrim behind it, capped at the width its caller gives it.
The page around it: sets the panel width, the way the create form and the package picker each set theirs, and unmounts the overlay when it reports a close — presence in the DOM is what open means
{ "id": "example", "section": "As a centred modal", "columns": 1, "items": [ { "id": "overlay_1", "type": "component", "key": "overlay", "inputs": { "label": "Order details" }, "children": [ { "id": "inspector_2", "type": "component", "key": "inspector", "inputs": { "heading": "ORD-4471" }, "children": [ { "id": "key_value_row_3", "type": "component", "key": "key_value_row", "inputs": { "label": "Account", "value": "Meridian Supply" } }, { "id": "key_value_row_4", "type": "component", "key": "key_value_row", "inputs": { "label": "Total", "value": "$12,400" } } ] } ] } ]}<caos-overlay label="Order details"> <caos-inspector heading="ORD-4471"> <caos-key-value-row label="Account" value="Meridian Supply"></caos-key-value-row> <caos-key-value-row label="Total" value="$12,400"></caos-key-value-row> </caos-inspector></caos-overlay>As a right-hand drawer
Section titled “As a right-hand drawer”The same declaration with placement set to end: full height, flush against the right edge, no rounded corners on the side it is flush with — one input apart from the modal above.
The page around it: sets the drawer width and unmounts the overlay when it reports a close
{ "id": "example", "section": "As a right-hand drawer", "columns": 1, "items": [ { "id": "overlay_1", "type": "component", "key": "overlay", "inputs": { "label": "Order details", "placement": "end" }, "children": [ { "id": "inspector_2", "type": "component", "key": "inspector", "inputs": { "heading": "ORD-4471" }, "children": [ { "id": "key_value_row_3", "type": "component", "key": "key_value_row", "inputs": { "label": "Account", "value": "Meridian Supply" } }, { "id": "key_value_row_4", "type": "component", "key": "key_value_row", "inputs": { "label": "Total", "value": "$12,400" } } ] } ] } ]}<caos-overlay label="Order details" placement="end"> <caos-inspector heading="ORD-4471"> <caos-key-value-row label="Account" value="Meridian Supply"></caos-key-value-row> <caos-key-value-row label="Total" value="$12,400"></caos-key-value-row> </caos-inspector></caos-overlay>