feature: Phase4 - Clinic two-step treatment UI

This commit is contained in:
2026-06-28 17:14:02 +03:30
parent 21f545ebdb
commit 7b19d6953c
17 changed files with 1042 additions and 615 deletions

View File

@@ -1,6 +1,6 @@
'use client';
import { useId } from 'react';
import { useId, type KeyboardEvent } from 'react';
import { Check } from 'lucide-react';
type CheckboxProps = {
@@ -14,6 +14,7 @@ type CheckboxProps = {
/**
* App design-system checkbox: primary fill when checked, rounded, focus-visible ring.
* Uses a button-like label toggle so mouse clicks do not focus a hidden input (scroll jumps).
*/
export function Checkbox({
checked,
@@ -26,25 +27,42 @@ export function Checkbox({
const genId = useId();
const inputId = id ?? genId;
const toggle = () => {
if (!disabled) onChange(!checked);
};
const onKeyDown = (event: KeyboardEvent<HTMLLabelElement>) => {
if (disabled) return;
if (event.key === ' ' || event.key === 'Enter') {
event.preventDefault();
toggle();
}
};
return (
<label
htmlFor={inputId}
id={inputId}
role="checkbox"
aria-checked={checked}
aria-disabled={disabled}
tabIndex={disabled ? -1 : 0}
onKeyDown={onKeyDown}
onClick={(event) => {
event.preventDefault();
toggle();
}}
onMouseDown={(event) => {
// Avoid focus-driven scroll-into-view in overflow panels.
if (event.button === 0) event.preventDefault();
}}
className={`
inline-flex items-center gap-2.5 cursor-pointer select-none rounded-[var(--radius-sm)] -m-0.5 p-0.5
has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-primary/45 has-[:focus-visible]:ring-offset-2
has-[:focus-visible]:ring-offset-background-secondary
focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/45 focus-visible:ring-offset-2
focus-visible:ring-offset-background-secondary
${disabled ? 'opacity-50 cursor-not-allowed' : ''}
${className}
`}
>
<input
id={inputId}
type="checkbox"
className="sr-only"
checked={checked}
disabled={disabled}
onChange={(e) => onChange(e.target.checked)}
/>
<span
className={`
flex h-5 w-5 shrink-0 items-center justify-center rounded-[var(--radius-sm)] border-2 transition-all duration-200