// Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import type { ReactNode } from 'react'; import React, { forwardRef, useMemo } from 'react'; import { v4 as uuid } from 'uuid'; import { getClassNamesFor } from '../util/getClassNamesFor'; export type PropsType = { checked?: boolean; children?: (childrenOpts: { id: string; checkboxNode: JSX.Element; labelNode: JSX.Element; checked?: boolean; }) => JSX.Element; description?: ReactNode; disabled?: boolean; isRadio?: boolean; label: string; moduleClassName?: string; name: string; onChange: (value: boolean) => unknown; onClick?: () => unknown; }; export const Checkbox = forwardRef(function CheckboxInner( { checked, children, description, disabled, isRadio, label, moduleClassName, name, onChange, onClick, }: PropsType, ref: React.Ref<HTMLInputElement> ): JSX.Element { const getClassName = getClassNamesFor('Checkbox', moduleClassName); const id = useMemo(() => `${name}::${uuid()}`, [name]); const checkboxNode = ( <div className={getClassName('__checkbox')}> <input checked={Boolean(checked)} disabled={disabled} id={id} name={name} onChange={ev => onChange(ev.target.checked)} onClick={onClick} ref={ref} type={isRadio ? 'radio' : 'checkbox'} /> </div> ); const labelNode = ( <div> <label htmlFor={id}> <div>{label}</div> <div className={getClassName('__description')}>{description}</div> </label> </div> ); return ( <div className={getClassName('')}> <div className={getClassName('__container')}> {children ? ( children({ id, checkboxNode, labelNode, checked }) ) : ( <> {checkboxNode} {labelNode} </> )} </div> </div> ); });