"use client"
import * as React from "react"
import { FoldVerticalIcon, UnfoldVerticalIcon } from "lucide-react"
import {
SegmentedControl,
type SegmentedControlOption,
type SegmentedControlProps,
} from "@/components/ui/segmented-control"
import { useDensity, type Density } from "@/hooks/use-density"
const WORDS: { value: Density; label: string; icon: React.ReactNode }[] = [
{ value: "comfortable", label: "Comfortable", icon: <UnfoldVerticalIcon /> },
{ value: "compact", label: "Compact", icon: <FoldVerticalIcon /> },
]
// Icon-only still names each option — the word moves into the accessible tree
// rather than out of it, so the control keeps two distinguishable radios.
const OPTIONS: Record<"words" | "icons", SegmentedControlOption[]> = {
words: WORDS.map((entry) => ({ value: entry.value, label: entry.label, icon: entry.icon })),
icons: WORDS.map((entry) => ({
value: entry.value,
label: <span className="sr-only">{entry.label}</span>,
icon: entry.icon,
})),
}
export type DensityToggleProps = Omit<
SegmentedControlProps,
"options" | "value" | "onValueChange"
> & {
/** Drops the words and keeps the two icons, for a header bar that is already full. */
iconOnly?: boolean
}
/**
* The row rhythm, as a two-option segmented control.
*
* It writes `data-density` onto `<html>`, which is what every primitive that
* sets a dashboard's rhythm reads — so one control retightens the tables, the
* cards, the gaps and the sidebar at once. The choice is remembered in
* `localStorage["vibra-density"]`.
*/
function DensityToggle({ size = "sm", iconOnly = false, ...props }: DensityToggleProps) {
const { density, setDensity } = useDensity()
return (
<SegmentedControl
data-slot="density-toggle"
aria-label="Density"
size={size}
options={OPTIONS[iconOnly ? "icons" : "words"]}
value={density}
onValueChange={(value) => setDensity(value as Density)}
{...props}
/>
)
}
export { DensityToggle }