Toggle
A button with aria-pressed. Default is ghost until pressed
(muted fill). .toggle-outline adds a hairline.
Sizes: toggle-sm / toggle-lg.
The bookmark icon can stay stroke-only, or take fill="currentColor" when pressed.
There is no wrapper.
Preview
Code
<script>
let on = $state(false);
let outline = $state(true);
let sm = $state(false);
let mid = $state(false);
let lg = $state(false);
</script>
<button
class="toggle"
type="button"
aria-pressed={on}
aria-label="Bookmark"
onclick={() => on = !on}
>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M6 4h10v16l-5-3-5 3z"></path>
</svg>
Bookmark
</button>
<button class="toggle toggle-outline" type="button" aria-pressed={outline} onclick={() => outline = !outline}>Outline</button>
<button class="toggle toggle-sm" type="button" aria-pressed={sm} onclick={() => sm = !sm}>Small</button>
<button class="toggle" type="button" aria-pressed={mid} onclick={() => mid = !mid}>Default</button>
<button class="toggle toggle-lg" type="button" aria-pressed={lg} onclick={() => lg = !lg}>Large</button>Pressed fill
<script>
let saved = $state(true);
</script>
<button
class="toggle"
type="button"
aria-pressed={saved}
aria-label="Bookmark"
onclick={() => saved = !saved}
>
<svg viewBox="0 0 24 24" fill={saved ? "currentColor" : "none"} stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M6 4h10v16l-5-3-5 3z"></path>
</svg>
Bookmark
</button>