A small box of content floating next to the button that opened it.
Mirrors Popover from @digdir/designsystemet-react.
import Designsystemet.Popover as Popover
deleteInfo : Popover.Id
deleteInfo =
Popover.id "delete-info"
view : Html Msg
view =
Html.div []
[ Popover.trigger deleteInfo [] [ Html.text "Hva skjer når jeg sletter?" ]
, Popover.view deleteInfo
[ Popover.placement Placement.Bottom ]
[ Html.text "Saken flyttes til papirkurven i 30 dager." ]
]It's a native popover:
the browser opens it on a trigger click and closes it on Esc or a click
outside, and designsystemet-web positions it next to the trigger. Your model
doesn't have to track whether it's open. Use onToggle to find
out, or open to open it from your model.
<Popover id="x"> → Popover.view (Popover.id "x") []<Popover.TriggerContext> → not needed: share a Popover.Id<Popover.Trigger> → Popover.trigger id []<Popover.Trigger inline> → Popover.inlineTrigger id []<Button popovertarget="x"> → Button.view (Popover.toggle id)variant="tinted" → Popover.tintedplacement="bottom" → Popover.placement Placement.BottomautoPlacement={false} → Popover.noAutoPlacementonOpen / onClose → Popover.onToggleopen={isOpen} + onOpen/onClose → Popover.open model.isOpen, Popover.onToggle Toggledpopover="auto". React uses "manual" and implements
light dismiss (Esc, click outside) in JavaScript, which the browser does
for "auto" popovers anyway. Pass Attr.attribute "popover" "manual" for
a popover that stays open while others open.Popover.inlineTrigger is type="button", so it never submits a form.autoPlacement={false} but never renders it, so it has no
effect there. noAutoPlacement writes the
data-autoplacement="false" that designsystemet-web reads.While it is open, designsystemet-web positions the popover by writing
inline styles (translate, scroll-margin-bottom, and for lists that scroll
max-height and width), the arrow's --_ds-floating-arrow-x/-y
properties, and data-floating. Don't set those yourself, and style the
popover with classes rather than Attr.style.
To open a popover from your model (say, a hint after a save), use
open. Only showPopover() can open a popover, so open renders
data-open and the package's JavaScript (@ensolabs/designsystemet-elm,
imported once) syncs the element. designsystemet-web positions the popover
next to the element whose popovertarget points at it, so you still need a
trigger.
Popover.view saveHint
[ Popover.open model.showSaveHint
, Popover.onToggle SaveHintToggled
]
[ Html.text "Lagret!" ]The browser still closes it on Esc or a click outside, so handle
onToggle and set your state to Closed.
Name a popover. The string becomes its DOM id, so it must be unique on
the page.
filters : Popover.Id
filters =
Popover.id "case-list-filters"The DOM id, for ports and tests.
A <div class="ds-popover" popover>, placed above its trigger by default.
The id always comes from the Id so the triggers keep pointing at it.
An Attr.id in the attributes is ignored.
A tinted background instead of the default surface color.
Which side of the trigger the popover appears on. Defaults to
Placement.Top.
Keep the popover on the requested side even when there is no room. By
default designsystemet-web flips it to the opposite side.
A trigger is any button with one of the invoker attribute lists below.
trigger is a Designsystemet Button that toggles the popover.
A Button that opens and closes the popover.
Popover.trigger help [ Button.tertiary ] [ Html.text "Hjelp" ]A trigger styled as a word in running text, with a dotted underline:
Html.p []
[ Html.text "Søknaden må ha "
, Popover.inlineTrigger orgNumberHelp [] [ Html.text "organisasjonsnummer" ]
, Html.text "."
]Open the popover if closed, close it if open. This is what a trigger does.
Close the popover, or leave it closed. Use it for a "close" button inside the popover:
Button.view (Button.tertiary :: Popover.hide filters) [ Html.text "Lukk" ]Whether the popover is open, from your model. See Opening from your model.
Whether a popover is showing.
The
idthat links a popover to the buttons that open it.Make one per popover as a top-level value and use it in both places. The type keeps you from passing it to a
Dialogby mistake.