2025-10-22 00:43:53 -07:00
|
|
|
<svelte:options
|
|
|
|
|
customElement={{
|
|
|
|
|
props: {
|
|
|
|
|
button_aria_label: { attribute: "button-aria-label" },
|
|
|
|
|
button_class: { attribute: "button-class" },
|
2025-10-25 05:32:22 +00:00
|
|
|
alignment: { attribute: "alignment" },
|
2025-10-22 00:43:53 -07:00
|
|
|
},
|
|
|
|
|
tag: "basic-dropdown",
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<script lang="ts">
|
|
|
|
|
type Props = {
|
2025-10-25 05:32:22 +00:00
|
|
|
alignment?: string;
|
2025-10-22 00:43:53 -07:00
|
|
|
button_aria_label?: string;
|
|
|
|
|
button_class?: string;
|
2025-10-25 05:32:22 +00:00
|
|
|
on_toggle?(ev: ToggleEvent): void;
|
2025-10-22 00:43:53 -07:00
|
|
|
};
|
|
|
|
|
|
2025-10-25 05:32:22 +00:00
|
|
|
let {
|
|
|
|
|
alignment,
|
|
|
|
|
button_aria_label,
|
|
|
|
|
button_class = "button--secondary",
|
|
|
|
|
on_toggle,
|
|
|
|
|
}: Props = $props();
|
2025-10-22 00:43:53 -07:00
|
|
|
let popover_element: HTMLElement | undefined = $state();
|
2025-10-25 05:32:22 +00:00
|
|
|
// Hacky workaround because as of September 2025 implicit anchor association
|
|
|
|
|
// is still pretty broken, at least in Firefox.
|
|
|
|
|
let anchor_name = $state(`--anchor-${Math.floor(Math.random() * 1000000)}`);
|
|
|
|
|
|
|
|
|
|
let popover_left = $derived(
|
|
|
|
|
alignment?.toLocaleLowerCase("en-US") === "right"
|
|
|
|
|
? "unset"
|
|
|
|
|
: "anchor(left)",
|
|
|
|
|
);
|
|
|
|
|
let popover_right = $derived(
|
|
|
|
|
alignment?.toLocaleLowerCase("en-US") === "right"
|
|
|
|
|
? "anchor(right)"
|
|
|
|
|
: "unset",
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$effect(() => {
|
|
|
|
|
if (on_toggle) {
|
|
|
|
|
popover_element?.addEventListener("toggle", on_toggle);
|
|
|
|
|
return () => {
|
|
|
|
|
popover_element?.removeEventListener("toggle", on_toggle);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-10-22 00:43:53 -07:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
aria-label={button_aria_label}
|
|
|
|
|
class={["basic-dropdown__button", button_class]}
|
|
|
|
|
id="dropdown-button"
|
|
|
|
|
onclick={() => {
|
2025-10-25 05:32:22 +00:00
|
|
|
popover_element?.showPopover();
|
2025-10-22 00:43:53 -07:00
|
|
|
}}
|
2025-10-25 05:32:22 +00:00
|
|
|
style:anchor-name={anchor_name}
|
2025-10-22 00:43:53 -07:00
|
|
|
type="button"
|
|
|
|
|
>
|
|
|
|
|
<slot name="button-contents"></slot>
|
|
|
|
|
</button>
|
|
|
|
|
<div
|
|
|
|
|
aria-labelledby="dropdown-button"
|
|
|
|
|
bind:this={popover_element}
|
|
|
|
|
class="basic-dropdown__popover"
|
2025-10-25 05:32:22 +00:00
|
|
|
style:left={popover_left}
|
|
|
|
|
style:position-anchor={anchor_name}
|
|
|
|
|
style:right={popover_right}
|
2025-10-22 00:43:53 -07:00
|
|
|
popover="auto"
|
|
|
|
|
>
|
|
|
|
|
<slot name="popover"></slot>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<style lang="scss">
|
|
|
|
|
@use "../../sass/main";
|
|
|
|
|
</style>
|