~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/knotless

git that lives in your Atmosphere account

Forked from chadtmiller.com/knotless

0
0
46 lines · 1.3 KB Raw History
<script lang="ts" module>
	import type { IconName } from '#lib/icons.ts';
	/** One thing a menu does: go to `href`, or `run` it, or open the popover `opens`, or both; marked by `icon`, when given. */
	export type Action = {
		label: string;
		href?: string;
		run?: () => void;
		opens?: string;
		icon?: IconName;
		danger?: boolean;
	};
</script>

<script lang="ts">
	import Icon from '#lib/atoms/Icon.svelte';
	/** A "…" menu of what can be done with the thing it is beside, as `label` names it for those who cannot see it. */
	let { actions, label = 'More' }: { actions: Action[]; label?: string } = $props();
	let open = $state(false);
</script>

{#if actions.length}
	<details class="popover action-menu" bind:open>
		<summary class="bare" aria-label={label} title={label}><Icon name="kebab" /></summary>
		<div class="menu">
			{#each actions as a (a.label)}
				{#if a.href}
					<a class="menu-item" class:danger={a.danger} href={a.href} onclick={() => (open = false)}
						>{#if a.icon}<Icon name={a.icon} />{/if}{a.label}</a
					>
				{:else}
					<button
						class="menu-item"
						class:danger={a.danger}
						type="button"
						popovertarget={a.opens}
						onclick={() => {
							open = false;
							a.run?.();
						}}
						>{#if a.icon}<Icon name={a.icon} />{/if}{a.label}</button
					>
				{/if}
			{/each}
		</div>
	</details>
{/if}