import { useState } from "react"; import { Badge, Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@godxjp/ui/data-display"; import { Checkbox, CheckboxGroup, Field, FormField } from "@godxjp/ui/data-entry"; import { Flex, PageContainer } from "@godxjp/ui/layout"; const ALL_SCOPES = ["read", "write", "delete"]; /** * Checkbox — a single boolean (wrap in Field for a labelled row) or a * CheckboxGroup from an options array. Composed only from real @godxjp/ui * components. */ export default function Demo() { // Controlled CheckboxGroup — selection is surfaced at rest below the group. const [channels, setChannels] = useState(["email", "sms"]); // Indeterminate "select all" — parent reflects the children's mixed state. const [scopes, setScopes] = useState(["read"]); const allChecked = scopes.length === ALL_SCOPES.length; const someChecked = scopes.length > 0 && !allChecked; const toggleScope = (scope: string) => setScopes((prev) => prev.includes(scope) ? prev.filter((s) => s !== scope) : [...prev, scope], ); return ( Single · labelled with Field Field pairs the control with a label + optional description. The last row is disabled. Required and explicit indeterminate defaults Required form semantics and both controlled/default indeterminate values are visible. CheckboxGroup custom children Children composition and className are explicit public contracts. Indeterminate · select all The parent uses checked="indeterminate" when only some children are selected (children composed from explicit Field + Checkbox). setScopes(next === true ? ALL_SCOPES : [])} /> toggleScope("read")} /> toggleScope("write")} /> toggleScope("delete")} /> Error · invalid in a FormField FormField wires aria-invalid + the error message onto the control (role=alert). CheckboxGroup (options) Multi-select from a data-driven options array, with per-option description and disabled. Horizontal orientation orientation="horizontal" lays the options out in a wrapping row. Controlled value value + onValueChange own the selection; it is surfaced below the group. {channels.length === 0 ? ( 未選択 ) : ( channels.map((c) => {c}) )} Disabled group disabled on the group disables every option at once. ); }