signal-desktop/ts/components/Checkbox.tsx

80 lines
1.7 KiB
TypeScript
Raw Normal View History

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