re-frame.fresco.overlay¶
Use this module for popovers and modal dialogs on the browser's own top layer.
popover and modal make the one call an attribute cannot, showPopover or
showModal, and leave everything else to the platform.
It is an optional namespace: re-frame.fresco does not require it, so an
application that never requires it carries none of its code. It is ClojureScript
only; the namespace does not exist on the JVM.
The platform handles the rest of an overlay. <dialog> makes the page behind it
inert, enforced by the engine rather than by a key handler. popover provides
light dismiss (a click outside or Escape closes it) and keeps nested popovers in
last-opened, first-closed order. The top layer paints above everything, so no
ancestor's overflow, transform or z-index can clip or out-stack a panel. CSS
anchor positioning places the panel. What none of them does is enter the top layer:
an element does not get there by having an attribute, so the module calls
showModal / showPopover at the point React offers before paint, and the inverse
before React removes the node.
Overlays and focus teaches the popover and modal patterns and the focus rules.
The heads¶
Both are legal hiccup heads but not Fresco views: they read no subscriptions. They take these props. A closed overlay does not mount its child views. Reads made in the enclosing view while constructing those children still run in that view.
| Prop | Head | Meaning |
|---|---|---|
:open? |
both | Whether the overlay exists. False renders nothing: no element, no listener, no anchor name. An overlay is open exactly when your app-db says so. |
:on-dismiss |
both | Event vector dispatched when the browser dismisses the overlay. Without it the overlay ignores dismissal (see each head). |
:label |
both | The accessible name, set as aria-label. When given, it replaces an :aria-label you pass. |
:anchor |
popover | The DOM id of the trigger to position against. |
:placement |
popover | :top, :bottom, :left or :right, alone or with -start or -end. |
:light-dismiss? |
modal | Whether a backdrop click dismisses. Default false. |
Every other prop reaches the element unchanged, except the ones the module writes
itself: :ref on both, :on-cancel, :on-key-down and :closedby on a modal, and
:on-before-toggle and :popover on a popover. A value you pass at one of those
is replaced. A :style you pass is merged, with your keys winning over the
position-area that :placement sets.
- Errors:
:rf.error/fresco-intent-outside-boundarywhen an open overlay has:on-dismissand no frame is in scope, since nothing could dispatch it.:rf.error/fresco-overlay-anchor-missingwhen a popover opens with an:anchorthat names no element in the document. Omitting:anchoris legal.
popover¶
- Kind: component (Fresco head)
- Signature:
- Description: Renders an anchored, light-dismissable panel on the browser's
top layer.
- While the panel is open, the module gives the
:anchorelement a generated CSS anchor name, and restores whatever it found when the panel closes. Changing:anchoron an open panel moves it to the new trigger without closing it. :placementbecomes a CSSposition-areaagainst the anchor;:bottom-startlines the panel's left edge up with the trigger's. Any other value is passed through as a literalposition-areastring rather than rejected, so a misspelt word is an invalid CSS value and the panel lands at the browser's default position.- With
:on-dismiss, the panel ispopover="auto"and joins the platform's stack of open popovers. Without it, the panel ispopover="manual"and nothing dismisses it, because a dismissal nothing handles would leave the browser, instead of your:open?value, deciding whether the panel is open.
- While the panel is open, the module gives the
- Example:
modal¶
- Kind: component (Fresco head)
- Signature:
- Description: Renders a blocking dialog on the browser's top layer, opened
with
showModal.- The engine provides modality: the rest of the document is inert, and
::backdropis a real CSS selector. Inertness keeps Tab from reaching the page, and the module wraps focus at both ends, so Tab from the last control goes back to the first instead of through<body>. - Escape dispatches
:on-dismiss. A backdrop click does so only with:light-dismiss? true(default false), so a destructive confirmation does not close on a stray click. Without:on-dismiss, the dialog ignores every close request. - Initial focus goes to the first focusable control in tree order, by the platform's own dialog focusing steps, so order the controls instead of using an autofocus attribute.
- The engine provides modality: the rest of the document is inert, and
- Example:
See also¶
- Fresco API reference — every Fresco name, with the chapter that teaches it.
re-frame.fresco—h/portal, for containers the application does not own.