~james/core

core/web/src/lib/components/ui/ButtonGroup.svelte -rw-r--r-- 2.0 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 15 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<script module lang="ts">
	import { tv, type VariantProps } from "tailwind-variants";

	export const buttonGroup = tv({
		base: "inline-flex items-center",
		variants: {
			spaced: {
				true: "gap-xs",
				false: [
					// isolate keeps the z-10 segments and z-20 outline ordered inside the
					// group instead of against page chrome like the topbar search dropdown
					"relative isolate items-stretch gap-none overflow-hidden rounded-md bg-background-subtle [--btn-press:1] dark:bg-background-canvas",
					"after:pointer-events-none after:absolute after:inset-0 after:z-20 after:rounded-md after:border after:border-border-default after:content-['']",
					"*:relative",
					"[&>*:not(:first-child)]:-ml-px [&>*:not(:first-child)]:[--btn-radius-l:0px]",
					"[&>*:not(:last-child)]:[--btn-radius-r:0px]",
					// a Dropdown keeps its trigger one level down, and the radius vars only
					// inherit that far — Button re-declares them on itself, so the wrapper's
					// value loses. reach the nested trigger directly.
					"[&>*:not(:first-child)>button]:[--btn-radius-l:0px]",
					"[&>*:not(:last-child)>button]:[--btn-radius-r:0px]",
					"[&>*:not([data-variant=ghost])]:z-10",
					"[&>*:focus-visible]:-outline-offset-2"
				]
			},
			direction: {
				horizontal: [""],
				vertical: ["flex-col"]
			}
		},
		defaultVariants: {
			spaced: false,
			direction: "horizontal"
		}
	});

	export type ButtonGroupVariants = VariantProps<typeof buttonGroup>;
</script>

<script lang="ts">
	import type { Snippet } from "svelte";
	import type { HTMLAttributes } from "svelte/elements";

	interface Props extends Omit<HTMLAttributes<HTMLDivElement>, "class" | "children"> {
		spaced?: ButtonGroupVariants["spaced"];
		direction?: ButtonGroupVariants["direction"];
		class?: string;
		children: Snippet;
	}

	let {
		spaced = false,
		direction = "horizontal",
		class: className,
		children,
		...rest
	}: Props = $props();

	const classes = $derived(buttonGroup({ spaced, direction, class: className }));
</script>

<div class={classes} {...rest}>
	{@render children()}
</div>