StickyTray

StickyTray

Documentation

An authored viewport-persistent content tray. StickyTray may be authored as an Element or directly as a PageSection. Its authored location establishes an anchor in document flow, while Quail Pages owns the tray markup, accessibility, viewport placement, visibility, and runtime state. The handle renders Elements; the panel renders ordinary Sections. Handle content and its disclosure button are separate interactive surfaces. When visibilityTriggers is omitted, the tray is simply available. Within each trigger group, any trigger may satisfy the group (OR). Every group must be satisfied for the tray to be presented (AND). Responsive triggers use the canonical QP mobile, tablet, and desktop presentation-width ranges. Anchor triggers are evaluated against the tray's authored anchor: anchor-passed becomes true after the anchor crosses above the viewport start, anchor-visible is true while any part of the anchor is inside the viewport, and anchor-passed-center becomes true after the anchor crosses above the viewport center line. Authored location alone enables no visibility trigger. Vertical and horizontal placement independently control where the active tray appears and default to top-center. Overlay placement accounts for occupied header/footer boundaries. Inset fills the top or bottom edge, independently of horizontal alignment, and reserves its measured handle in the document viewport. Multiple inset handles stack in authored order. The panel overlays the remaining viewport. Inset shells move to the document viewport; authored anchors stay put. Three independent choices: disclosure controls panel interaction; visibilityTriggers controls when the whole tray appears; positionMode controls whether it reserves viewport space. For a permanent sticky menu, author the menu in handle.elements with no sections and omit visibilityTriggers. To show that menu only after scrolling past its authored position, add visibilityTriggers: [["anchor-passed"]]. No disclosure button is needed.

Kind

Layout

Required fields

ariaLabel, handle, id, type

Style Guide

Used by

Authoring guidance

Use when

Content should remain available in a persistent handle, optionally with a designed panel, such as navigation or contextual page controls.

Avoid when

Content belongs directly in the normal section flow without persistent access while scrolling.

Properties

*

ariaLabel

string

Accessible name for the tray container.

class

string

Optional theme styling hook.

disclosure

enum

Panel interaction, independent from visibilityTriggers and positionMode. none keeps any panel content visible with no disclosure control. handle makes the full handle surface toggle the panel; authored links and controls inside the handle keep their own actions. chevron uses a separate disclosure button. A tray without panel sections has no disclosure in any mode.

"none" | "handle" | "chevron"

*

handle

object

Persistent content, rendered independently from the panel disclosure button.

class — string

Optional styling hook for the handle content.

elements — Element[] [REQUIRED]

Menus, cards, images, or other ordinary Elements in the persistent handle.

horizontal

enum

Horizontal viewport placement. Defaults to center when omitted. left aligns the tray to the available left side, center centers it, and right aligns it to the available right side.

"left" | "center" | "right"

*

id

string

Stable non-empty identifier used to associate the tray control and content panel.

min length: 1

positionMode

enum

Overlay leaves the document viewport unchanged. Inset reserves the measured handle at the top or bottom edge; its panel overlays the remaining viewport. Inset requires top or bottom vertical placement and fills that edge.

"overlay" | "inset"

sections

Interior Sections. Omit or leave empty for a permanent handle without a disclosure.

Items — StandardSection | RegionSection

Accepted shape 1 — StandardSection

Accepted shape 2 — RegionSection

*

type

string

Identifies the StickyTray type represented by this object.

"sticky-tray"

vertical

enum

Vertical viewport placement. Defaults to top when omitted. top anchors the tray to the top side, middle centers it vertically, and bottom anchors it to the bottom side.

"top" | "middle" | "bottom"

visibilityTriggers

Conditions controlling when the tray is presented. Trigger values within each inner group use OR; the outer groups use AND. Omit this property for an unconditionally available tray. These conditions control tray visibility, not panel expansion: use disclosure for the panel interaction. Groups and trigger values within each group must be nonempty, and values within a group must be unique.

min items: 1

Example

Required

{ "ariaLabel": "Quick links", "handle": { "elements": [] }, "id": "quick-links", "type": "sticky-tray" }

Full

{ "ariaLabel": "Quick links", "class": "example", "disclosure": "none", "handle": { "class": "example", "elements": [ { "type": "paragraph", "text": " Quick links" } ] }, "horizontal": "left", "id": "quick-links", "positionMode": "overlay", "sections": [ { "id": "quick-links-content", "title": "Quick links", "titleSrOnly": true, "appearance": "transparent", "elements": [ { "type": "menu", "ariaLabel": "Quick links", "items": [ { "label": "Example", "link": { "href": "#example" } } ] } ] } ], "type": "sticky-tray", "vertical": "top", "visibilityTriggers": [ [ "mobile" ] ] }

examples are generated from the schema.