Add Phase 1 Pocket Pascal UI: home, pantry, week plan, and plate.
Replace the hello-world shell with the elevated design system, bilingual screens, recipe/extras data, and the interactive Mein Teller view. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
62
client/src/components/ui-pp/SegControl.tsx
Normal file
62
client/src/components/ui-pp/SegControl.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import { cx } from "@/lib/cx"
|
||||
|
||||
export interface SegOption<T extends string> {
|
||||
value: T
|
||||
label: string
|
||||
}
|
||||
|
||||
export interface SegControlProps<T extends string> {
|
||||
value: T
|
||||
options: SegOption<T>[]
|
||||
onChange: (value: T) => void
|
||||
className?: string
|
||||
/** Accessible name for the control group. */
|
||||
"aria-label"?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Segmented control — same interaction pattern as the prototype `.segctl`.
|
||||
* Soft track + elevated active pill. Touch targets ≥48px.
|
||||
*/
|
||||
export function SegControl<T extends string>({
|
||||
value,
|
||||
options,
|
||||
onChange,
|
||||
className,
|
||||
"aria-label": ariaLabel,
|
||||
}: SegControlProps<T>) {
|
||||
return (
|
||||
<div
|
||||
role="tablist"
|
||||
aria-label={ariaLabel}
|
||||
className={cx(
|
||||
"flex rounded-[var(--radius-pill)] p-1",
|
||||
className,
|
||||
)}
|
||||
style={{ background: "var(--green-soft)" }}
|
||||
>
|
||||
{options.map((option) => {
|
||||
const active = option.value === value
|
||||
return (
|
||||
<button
|
||||
key={option.value}
|
||||
type="button"
|
||||
role="tab"
|
||||
aria-selected={active}
|
||||
onClick={() => onChange(option.value)}
|
||||
className={cx(
|
||||
"type-button-secondary flex-1 min-h-[48px] rounded-[var(--radius-pill)] px-3",
|
||||
"no-select [-webkit-tap-highlight-color:transparent]",
|
||||
"elevation-transition",
|
||||
active
|
||||
? "bg-[var(--glass-fill)] text-[var(--ink)] shadow-[var(--shadow-resting)]"
|
||||
: "text-[var(--ink-soft)] active:brightness-95",
|
||||
)}
|
||||
>
|
||||
{option.label}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user