{#- Popovers and dropdown menus. Shared arguments (class, attrs, kwargs): see components/button.html. Both need the hxPopover Alpine component from layout.html and the vendored @alpinejs/anchor and @alpinejs/focus plugins. popover(id, trigger, label=None, trigger_class=None, placement="bottom-start", size="md", class="", attrs=None, **kwargs) A trigger button plus a floating panel (the {% call %} block). id names the panel; the trigger gets id ~ "-trigger". trigger is the button's content (markup: text, icons, badges); label, if given, becomes its aria-label (required when trigger has no text). trigger_class defaults to button_classes("secondary", "md"). placement: an x-anchor placement (bottom-start, bottom-end, top, right-start, …); the panel flips when there is no room and is fixed-positioned, so overflow containers do not clip it. size is the panel width: sm (14rem) | md (18rem) | lg (24rem). class, attrs and kwargs go on the panel. Behaviour: click toggles; opening focuses the first focusable element in the panel; Esc closes and returns focus to the trigger; a click outside or focus leaving closes it. The trigger carries aria-expanded, aria-controls and aria-haspopup="dialog"; the panel has role="dialog" labelled by the trigger. Inside, `expanded` and `close(restore)` are in scope (named so that an outer `open`, e.g. a dialog's, is not shadowed). menu(id, trigger, label=None, trigger_class=None, placement="bottom-start", class="", attrs=None, **kwargs) A dropdown menu: a popover whose panel has role="menu" and holds menu_item, menu_separator and menu_label. The trigger has aria-haspopup="menu"; Enter, Space or ArrowDown opens it on the first item and ArrowUp on the last. In the menu, ArrowUp and ArrowDown move (wrapping), Home and End jump, Tab and Esc close, and activating an item closes the menu. menu_item(label, href=None, icon=None, tone="neutral", shortcut=None, type="button", disabled=False, role="menuitem", inset=False, class="", attrs=None, **kwargs) A menu entry: an with href, else a
{{- caller() -}}
{%- endmacro %} {% macro popover(id, trigger, label=None, trigger_class=None, placement="bottom-start", size="md", class="", attrs=None) -%} {%- set body = caller() -%} {%- call _floating("popover", id, trigger, label, trigger_class, placement, hx_pick(_popover_sizes, size, "popover size") ~ " " ~ class, attrs, kwargs) %}{{ body }}{% endcall -%} {%- endmacro %} {% macro menu(id, trigger, label=None, trigger_class=None, placement="bottom-start", class="", attrs=None) -%} {%- set body = caller() -%} {%- call _floating("menu", id, trigger, label, trigger_class, placement, "min-w-44 p-1 " ~ class, attrs, kwargs) %}{{ body }}{% endcall -%} {%- endmacro %} {% macro menu_item(label, href=None, icon=None, tone="neutral", shortcut=None, type="button", disabled=False, role="menuitem", inset=False, class="", attrs=None) -%} {%- set classes = ("flex w-full select-none items-center gap-2 rounded-sm py-1.5 pr-2 text-left text-sm outline-none focus-visible:outline-none aria-disabled:pointer-events-none aria-disabled:opacity-50 " ~ ("pl-8 " if inset and not icon else "pl-2 ") ~ hx_pick(_item_tones, tone, "menu item tone") ~ " " ~ class)|trim -%} {%- set icon_class = "size-4 shrink-0" ~ (" text-fg-muted" if tone == "neutral" else "") -%} {%- set extra = hx_attrs(attrs, kwargs) -%} {%- if href is not none and not disabled -%}
{%- else -%} {% endif -%} {%- endmacro %} {% macro menu_separator() -%} {%- endmacro %} {% macro menu_label(text) -%} {%- endmacro %}