"use client" import * as React from "react" import { cn } from "../../lib/utils" import { Checkbox } from "./checkbox" import { Label } from "./label" /** * `CheckboxControl` is replacement for `@wordpress/components`' `CheckboxControl` - * **10 live usages across 9 files**. * * AN ADAPTER, NOT A RENAME. WP hands `onChange` the BOOLEAN, never the event: * * * * Radix hands `onCheckedChange` a `boolean | "indeterminate"`, which is close but not the same * thing - an indeterminate box would reach a handler typed for a boolean as the string * "indeterminate", which is truthy. The comparison here narrows it to a real boolean, so the * handlers keep the argument WP gave them. * * `checked` falls back to false. Two sites pass a react-hook-form `field.value` that is undefined * before the form is populated, which would make the box uncontrolled on the first render and * controlled on the next - React warns, and the tick can be lost. * * `label` and `help` are rendered by WP and have no equivalent on a bare checkbox. Reproducing them * here is what keeps each conversion a one-line import swap. `label` and `help` are both * `ReactNode`, because one site passes markup as help. * * `__nextHasNoMarginBottom` is deliberately NOT accepted, the same ruling made for * `ui/input-control` and `ui/toggle-control`. Call sites drop it. */ export interface CheckboxControlProps extends Omit< React.ComponentProps, "onChange" | "onCheckedChange" | "checked" > { label?: React.ReactNode help?: React.ReactNode checked?: boolean /** WP's contract: the BOOLEAN, not an event and not Radix's "indeterminate". */ onChange?: (checked: boolean) => void } function CheckboxControl({ label, help, className, checked, onChange, id, ...props }: CheckboxControlProps) { // A generated id is what lets the label be a real