feat(t5): ein Checkbox-Baustein für alle 35 Stellen (T5a A7)
- ui/checkbox.tsx und form/checkbox-field.tsx: ganze Zeile, Kachel, Aufgabe oder Sheet-Zeile ist der Knopf (Base UI), Haken bzw. Strich für teilweise; role="switch" mit Daumen und Haken. ToggleChip und SwitchRow entfernt. - 14 Kacheln, 11 native Checkboxen, 3 Schalter-Zeilen, 6 Base-UI-Stellen und die Heute-Aufgaben umgestellt; Werte ans Backend unverändert. - Enter in einer Checkbox schickt kein Formular ab und schaltet nicht (Leertaste schaltet); Nachbarn mit mindestens 4 px Abstand; gesperrte Felder mit sichtbarem Grund; gesperrte Kacheln ganz gedimmt. - Baukasten-Wächter: keine eigenen Checkboxen/Schalter, auch bedingte role-Werte und setAttribute; Zeilenlisten mit Abstand. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
11bccbeb50
commit
f307e7da66
40 files changed
+1179
-409
No files matched your search
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { fetchHarvests } from "@/lib/harvests/api";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { CheckboxField } from "@/components/form/checkbox-field";
|
||||
|
||||
interface HarvestSelectFieldProps {
|
||||
idPrefix: string;
|
||||
@@ -32,34 +32,32 @@ export function HarvestSelectField({
|
||||
);
|
||||
}
|
||||
|
||||
const labelId = `${idPrefix}-label`;
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
<Label>Ernten</Label>
|
||||
<div role="group" aria-labelledby={labelId} className="flex flex-col gap-2">
|
||||
<span id={labelId} className="text-sm font-medium">
|
||||
Ernten
|
||||
</span>
|
||||
{(harvests ?? []).length === 0 ? (
|
||||
<p className="text-sm text-muted-foreground">Keine Ernten erfasst.</p>
|
||||
) : null}
|
||||
<div className="flex max-h-48 flex-col gap-2 overflow-y-auto">
|
||||
<div className="flex max-h-48 flex-col gap-1 overflow-y-auto">
|
||||
{(harvests ?? []).map((harvest) => (
|
||||
<label
|
||||
<CheckboxField
|
||||
key={harvest.id}
|
||||
className="flex min-h-11 items-center gap-3 text-sm"
|
||||
htmlFor={`${idPrefix}-${harvest.id}`}
|
||||
>
|
||||
<input
|
||||
id={`${idPrefix}-${harvest.id}`}
|
||||
type="checkbox"
|
||||
className="size-5 shrink-0"
|
||||
checked={value.includes(harvest.id)}
|
||||
onChange={(event) => toggle(harvest.id, event.target.checked)}
|
||||
/>
|
||||
<span>
|
||||
{new Date(harvest.date).toLocaleDateString("de-DE")}
|
||||
{harvest.netWeight !== null ? ` · ${harvest.netWeight} kg` : ""}
|
||||
{harvest.colonies.length > 0
|
||||
? ` · ${harvest.colonies.map((entry) => entry.colony.code).join(", ")}`
|
||||
: ""}
|
||||
</span>
|
||||
</label>
|
||||
id={`${idPrefix}-${harvest.id}`}
|
||||
label={[
|
||||
new Date(harvest.date).toLocaleDateString("de-DE"),
|
||||
harvest.netWeight !== null ? `${harvest.netWeight} kg` : null,
|
||||
harvest.colonies.length > 0
|
||||
? harvest.colonies.map((entry) => entry.colony.code).join(", ")
|
||||
: null,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" · ")}
|
||||
checked={value.includes(harvest.id)}
|
||||
onCheckedChange={(checked) => toggle(harvest.id, checked)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user