Floating Panel
A window inside the page that the user drags, resizes, minimises and maximises, without blocking the page.
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
open | boolean | false | Shows the panel. show() also moves focus into it; setting open does not. |
state | FloatingPanelState | normal | normal, minimized or maximized. Setting it fires no state-change; minimize(), maximize() and restore() do. |
boundary | FloatingPanelBoundary | viewport | viewport keeps the panel inside the window (position: fixed); parent inside its nearest positioned ancestor (position: absolute). |
rect | FloatingPanelRect | null | null | The panel's place and size, { x, y, width, height } in boundary pixels, or null while it sits at its CSS place.
Set by the user's moves and resizes. A JSON attribute, to restore a saved place. |
storage-key | string | — | When set, rect and state are kept in localStorage under this key and restored when the panel loads. |
minimize | FloatingPanelMinimize | dock | dock moves a minimised panel to the bottom edge of its boundary; collapse folds it to its title bar where it is. |
label | string | — | The panel's accessible name, and the visible title when the title slot is empty. Use it when the title is not text. |
no-drag | boolean | false | The title bar does not move the panel. |
no-resize | boolean | false | The edges and the grip do not resize the panel. |
no-minimize | boolean | false | No Minimise button. |
no-maximize | boolean | false | No Maximise button, and a double-click on the title bar does nothing. |
no-close | boolean | false | No Close button. |
Slots
| Name | Description |
|---|---|
(default) | The body, which scrolls. |
title | The title, shown in the title bar; it names the panel. Falls back to label. |
icon | An icon before the title. |
actions | Extra title-bar buttons, before the window buttons. |
footer | A row under the body, such as a message input. |
Events
| Name | Type | Description |
|---|---|---|
rect-change | CustomEvent<FloatingPanelRectChangeDetail> | The panel's place or size changed: at the end of a drag or a resize, on a key press, when the boundary pushed it back inside (reason: "boundary") or from a method. detail.rect is null when it went back to its CSS place. Does not bubble. |
state-change | CustomEvent<FloatingPanelStateChangeDetail> | The user or a method minimised, maximised or restored the panel; detail is { state, previous }. Not fired when script sets state. Does not bubble. |
open | Event | The panel opened (open became true after the first render). Does not bubble. |
close | Event | The panel closed. Does not bubble. |
before-close | Event | Cancelable: the user, or close(), is about to close the panel. Call preventDefault() to keep it open, for "Discard the draft?". Does not bubble. |
CSS parts
Shadow DOM styling hooks used with ::part(name). Prefer CSS custom properties when they cover the change.
| Name | Description |
|---|---|
panel | The panel: the role="dialog" section. |
header | The title bar. |
handle | The draggable, focusable part of the title bar around the icon and the title. |
icon | The box around the icon slot. |
title | The box around the title slot. |
actions | The box around the actions slot. |
button | Each window button. |
minimize-button | The Minimise button, which reads Restore while the panel is minimised. |
maximize-button | The Maximise button, which reads Restore while the panel is maximised. |
close-button | The Close button. |
body | The scrolling body region around the default slot, which projects the panel's content inside it. |
footer | The box around the footer slot. |
grip | The resize grip in the bottom-right corner. |
CSS custom properties
Grouped by semantic target and state from --c2-<component>__<target>__<state>--<property>. Click a group to collapse it; click a name to copy it.
| Name | Type | Default | Description |
|---|---|---|---|
--c2-floating-panel--inset | inset | auto 24px 24px auto | Where the panel first appears in its boundary, as an inset shorthand: the bottom-right corner by default. |
--c2-floating-panel--width | pixel | 360px | First width, before the user resizes the panel. |
--c2-floating-panel--height | pixel | auto | First height, before the user resizes the panel. |
--c2-floating-panel--min-width | pixel | 240px | Smallest width a resize reaches. |
--c2-floating-panel--min-height | pixel | 160px | Smallest height a resize reaches. |
--c2-floating-panel--max-width | pixel | 100% | Largest width, a share of the boundary. |
--c2-floating-panel--max-height | pixel | 100% | Largest height, a share of the boundary. |
--c2-floating-panel--z-index | number | 100 | Stacking order of the panel at the back; each panel in front of it in the same boundary adds 1. |
--c2-floating-panel--transition-duration | duration | 180ms | Minimise, maximise and restore animate over this. No animation under reduced motion. |
--c2-floating-panel--background | color | #ffffff | |
--c2-floating-panel--color | color | #18181b | Text colour of the body. |
--c2-floating-panel--border | border | 1px solid #e4e4e7 | |
--c2-floating-panel--border-radius | border-radius | 8px | |
--c2-floating-panel--box-shadow | box-shadow | 0 24px 60px rgba(0, 0, 0, 0.25) | Shadow of the panel in front. |
--c2-floating-panel__inactive--box-shadow | box-shadow | 0 8px 24px rgba(24, 24, 27, 0.08) | Shadow of a panel behind another one. |
--c2-floating-panel__header--height | pixel | 40px | |
--c2-floating-panel__header--padding | padding | 0 6px 0 12px | |
--c2-floating-panel__header--background | color | #fafafa | |
--c2-floating-panel__header--border-bottom | border | 1px solid #e4e4e7 | |
--c2-floating-panel__title--font-size | pixel | 14px | |
--c2-floating-panel__title--font-weight | font-weight | 600 | |
--c2-floating-panel__title--color | color | #18181b | |
--c2-floating-panel__title__inactive--color | color | #71717a | Title of a panel behind another one. |
--c2-floating-panel__icon--color | color | #71717a | |
--c2-floating-panel__icon--size | pixel | 16px | |
--c2-floating-panel__button--size | pixel | 28px | Width and height of each window button. |
--c2-floating-panel__button--icon-size | pixel | 16px | |
--c2-floating-panel__button--border-radius | border-radius | 6px | |
--c2-floating-panel__button--color | color | #71717a | |
--c2-floating-panel__button__hover--background | color | #f4f4f5 | |
--c2-floating-panel__button__hover--color | color | #18181b | |
--c2-floating-panel__close-button__hover--background | color | #f4f4f5 | |
--c2-floating-panel__close-button__hover--color | color | #dc2626 | |
--c2-floating-panel__body--padding | padding | 16px | |
--c2-floating-panel__body--font-size | pixel | 14px | |
--c2-floating-panel__footer--padding | padding | 12px 16px | |
--c2-floating-panel__footer--border-top | border | 1px solid #e4e4e7 | |
--c2-floating-panel__grip--color | color | #a1a1aa | |
--c2-floating-panel__grip--opacity | opacity | 0 | Resting opacity of the corner grip; it shows on hover, focus and on devices without hover. |
--c2-floating-panel__grip__hover--opacity | opacity | 1 | |
--c2-floating-panel__handle--size | pixel | 8px | Thickness of the invisible resize handles on the edges and corners. |
--c2-floating-panel__docked--inset | inset | auto 16px 0 auto | Where the first docked panel sits. The next ones line up away from the side it anchors to (to its left for a right inset, to its right for a left one), sharing the width when the line runs out of room and wrapping to further lines (upward, or downward for a top inset), always inside the boundary. |
--c2-floating-panel__docked--width | pixel | 240px | |
--c2-floating-panel__docked--gap | pixel | 8px | Space between docked panels. |
--c2-floating-panel__maximized--inset | pixel | 8px | Space a maximised panel leaves around it in its boundary. |
--c2-floating-panel__focus--outline | outline | 2px solid rgba(2, 101, 220, 0.4) | Focus ring of the handle, the grip and the window buttons. |
Text and languages
The text the component shows, in English. It shows another language when the app adds one with addTranslations, under floating-panel, and the nearest lang asks for it; any message not translated stays in English. {0}, {1}… stand for the values a message carries. Languages guide.
| Key | English | Values |
|---|---|---|
untitled | Panel | — |
move | Move {0} | {0} name |
moveHint | Arrow keys move the panel | — |
resize | Resize {0} | {0} name |
resizeHint | Arrow keys resize the panel | — |
minimize | Minimise | — |
maximize | Maximise | — |
restore | Restore | — |
close | Close | — |
minimized | {0} minimised | {0} name |
maximized | {0} maximised | {0} name |
restored | {0} restored | {0} name |
moved | Moved to {0}, {1} | {0} x {1} y |
resized | Resized to {0} by {1} | {0} width {1} height |