Move UI to BoardUI with slate + salmon theme; add PDF plan export
- Adopt BoardUI (Pro init): theme tokens, Inter, .dark mode, Button, SegmentedControl, Meter, Skeleton and ThemeToggle; remap the app's color aliases onto BoardUI tokens and swap lucide for Remix icons - Retint BoardUI's neutral ramp to cool slate with a salmon accent; drop the dotted background; raise muted text contrast - Simplify the landing page and remove the overlap explorer - Planner: explicit "I have this" toggle on grocery lines, pantry panel above the menu with the staples list spelled out, sticky aisle header fix, and a "Download PDF" plan export (jsPDF, lazy-loaded) - Recipes: replace the family cabbage soup with Cade's Cabbage Soup (adds Bone-In Ham Steak to the catalog); remove Ham, Bean & Cabbage Soup - Remove unused BoardUI components, dependencies and exports Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
b02c7a024b
commit
df5dd3a70e
56 changed files with 4749 additions and 788 deletions
70
components/base/input/label.tsx
Normal file
70
components/base/input/label.tsx
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
"use client";
|
||||
|
||||
import type { ReactNode, Ref } from "react";
|
||||
import { RiInformationFill } from "@remixicon/react";
|
||||
import type { LabelProps as AriaLabelProps } from "react-aria-components";
|
||||
import { Label as AriaLabel } from "react-aria-components";
|
||||
import { cx } from "@/utils/cx";
|
||||
|
||||
/**
|
||||
* Field label. Wraps `react-aria-components`' Label so the parent `TextField`
|
||||
* automatically wires `htmlFor` / `aria-labelledby`.
|
||||
*
|
||||
* Visuals come from Figma:
|
||||
* - Inter Medium 14/20, color text/primary
|
||||
* - 2px gap between label + required asterisk + info icon
|
||||
* - asterisk is text/error-primary (red/500)
|
||||
* - info icon is 16×16 in foreground/icon/quaternary
|
||||
*
|
||||
* Pass `isRequired` to show the asterisk. Pass `tooltip` to show the info
|
||||
* icon (currently a static glyph — when the Tooltip component lands it'll
|
||||
* wire up here).
|
||||
*/
|
||||
|
||||
export interface LabelProps extends AriaLabelProps {
|
||||
children: ReactNode;
|
||||
isRequired?: boolean;
|
||||
/** Reserved for invalid-aware styling (asterisk color, etc.) once we need it. */
|
||||
isInvalid?: boolean;
|
||||
/** Show the info icon next to the label. */
|
||||
tooltip?: boolean | string;
|
||||
ref?: Ref<HTMLLabelElement>;
|
||||
}
|
||||
|
||||
export function Label({
|
||||
isRequired = false,
|
||||
isInvalid: _isInvalid,
|
||||
tooltip,
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: LabelProps) {
|
||||
void _isInvalid;
|
||||
return (
|
||||
<AriaLabel
|
||||
data-label="true"
|
||||
{...props}
|
||||
className={cx(
|
||||
"flex cursor-default items-center gap-0.5",
|
||||
"text-body-medium text-text-primary",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
{isRequired && (
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className="text-body-medium text-text-error-primary"
|
||||
>
|
||||
*
|
||||
</span>
|
||||
)}
|
||||
{tooltip && (
|
||||
<RiInformationFill
|
||||
className="size-4 shrink-0 text-foreground-icon-quaternary"
|
||||
aria-hidden
|
||||
/>
|
||||
)}
|
||||
</AriaLabel>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue