import { wrapIndex } from "../../shared/keyboard"; import { listen } from "../../shared/helpers"; /** PettyToggleGroupItem — single item within a toggle group. */ export class PettyToggleGroupItem extends HTMLElement { static observedAttributes = ["value", "disabled"]; get value(): string { return this.getAttribute("value") ?? ""; } get disabled(): boolean { return this.hasAttribute("disabled"); } #cleanup = (): void => {}; connectedCallback(): void { this.setAttribute("role", "button"); this.setAttribute("tabindex", "0"); if (this.disabled) this.setAttribute("aria-disabled", "true"); this.#cleanup = listen(this, [["click", this.#handleClick], ["keydown", this.#handleKeydown]]); } disconnectedCallback(): void { this.#cleanup(); } attributeChangedCallback(name: string): void { if (name === "disabled") this.setAttribute("aria-disabled", String(this.disabled)); } #group(): { toggleValue(v: string): void } | null { return this.closest("petty-toggle-group") as { toggleValue(v: string): void } | null; } #siblings(): PettyToggleGroupItem[] { const group = this.closest("petty-toggle-group"); if (!group) return []; return Array.from(group.querySelectorAll("petty-toggle-group-item:not([disabled])")); } #handleClick = (): void => { if (this.disabled) return; this.#group()?.toggleValue(this.value); }; #handleKeydown = (e: Event): void => { const ke = e as KeyboardEvent; if (ke.key === " " || ke.key === "Enter") { ke.preventDefault(); this.#handleClick(); return; } const isHorizontal = this.closest("petty-toggle-group")?.getAttribute("orientation") !== "vertical"; const prev = isHorizontal ? "ArrowLeft" : "ArrowUp"; const next = isHorizontal ? "ArrowRight" : "ArrowDown"; if (ke.key !== prev && ke.key !== next) return; ke.preventDefault(); const items = this.#siblings(); const idx = items.indexOf(this); if (idx === -1) return; const delta = ke.key === next ? 1 : -1; items[wrapIndex(idx, delta, items.length)]?.focus(); }; }