planmymeal/app/components/Chip.tsx

41 lines
1.6 KiB
TypeScript
Raw Normal View History

import { RiCheckLine } from "@remixicon/react";
2026-10-31 20:44:29 -05:00
import type { ReactNode } from "react";
import { cx } from "@/utils/cx";
2026-10-31 20:44:29 -05:00
// A pill-shaped on/off filter toggle on BoardUI tokens.
// Shows a check when pressed so state never relies on color alone.
2026-10-31 20:44:29 -05:00
interface ChipProps {
pressed: boolean;
onClick: () => void;
children: ReactNode;
/** "sm" for dense filter rows, "md" for settings panels. */
size?: "sm" | "md";
/** Dashed outline when off: tells a second filter row apart from the first. */
dashed?: boolean;
}
export function Chip({ pressed, onClick, children, size = "md", dashed = false }: ChipProps) {
return (
<button
type="button"
aria-pressed={pressed}
onClick={onClick}
className={cx(
"inline-flex cursor-pointer items-center gap-1.5 rounded-full border transition-colors duration-150 ease",
"outline-none focus-visible:ring-2 focus-visible:ring-border-focus-ring",
size === "sm" ? "min-h-8 px-2.5 py-1 text-caption-1-medium" : "min-h-9 px-3.5 py-1.5 text-body-medium",
pressed
? "border-accent-500 bg-button-ghost-background text-button-ghost-foreground"
: cx(
"border-border-button-default bg-background-primary-default text-text-secondary hover:border-border-button-hover hover:bg-background-secondary-hover hover:text-text-primary",
dashed && "border-dashed",
),
)}
2026-10-31 20:44:29 -05:00
>
{pressed && <RiCheckLine className="size-3.5 shrink-0" aria-hidden />}
2026-10-31 20:44:29 -05:00
<span className="inline-flex items-center gap-1.5">{children}</span>
</button>
);
}