Updates
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
import React, {
|
||||
ComponentProps,
|
||||
DetailedHTMLProps,
|
||||
HTMLAttributes,
|
||||
ReactNode,
|
||||
} from "react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import CheckMarkSVG from "../svgs/CheckMarkSVG";
|
||||
import Stack from "../layout/Stack";
|
||||
import Row from "../layout/Row";
|
||||
import { Info } from "lucide-react";
|
||||
import Span from "../layout/Span";
|
||||
|
||||
export type CheckboxProps = Omit<
|
||||
React.DetailedHTMLProps<
|
||||
React.HTMLAttributes<HTMLDivElement>,
|
||||
HTMLDivElement
|
||||
>,
|
||||
"title"
|
||||
> & {
|
||||
title?: string | ReactNode;
|
||||
wrapperProps?: DetailedHTMLProps<
|
||||
HTMLAttributes<HTMLDivElement>,
|
||||
HTMLDivElement
|
||||
>;
|
||||
label?: string | ReactNode;
|
||||
labelProps?: React.DetailedHTMLProps<
|
||||
React.HTMLAttributes<HTMLDivElement>,
|
||||
HTMLDivElement
|
||||
>;
|
||||
defaultChecked?: boolean;
|
||||
wrapperClassName?: string;
|
||||
setChecked?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
checked?: boolean;
|
||||
readOnly?: boolean;
|
||||
noLabel?: boolean;
|
||||
size?: number;
|
||||
changeHandler?: (value: boolean) => void;
|
||||
info?: string | ReactNode;
|
||||
wrapperWrapperProps?: ComponentProps<typeof Stack>;
|
||||
};
|
||||
|
||||
/**
|
||||
* # Checkbox Component
|
||||
* @className twui-checkbox
|
||||
* @className twui-checkbox-checked
|
||||
* @className twui-checkbox-unchecked
|
||||
*/
|
||||
export default function Checkbox({
|
||||
wrapperProps,
|
||||
label,
|
||||
labelProps,
|
||||
size,
|
||||
wrapperClassName,
|
||||
defaultChecked,
|
||||
setChecked: externalSetChecked,
|
||||
readOnly,
|
||||
checked: externalChecked,
|
||||
changeHandler,
|
||||
info,
|
||||
wrapperWrapperProps,
|
||||
noLabel,
|
||||
title,
|
||||
...props
|
||||
}: CheckboxProps) {
|
||||
const finalSize = size || 20;
|
||||
|
||||
const [checked, setChecked] = React.useState(
|
||||
defaultChecked || externalChecked || false,
|
||||
);
|
||||
|
||||
const finalTitle = title
|
||||
? title
|
||||
: `Checkbox-${Math.round(Math.random() * 100000)}`;
|
||||
|
||||
React.useEffect(() => {
|
||||
if (typeof externalChecked == "undefined") return;
|
||||
setChecked(externalChecked);
|
||||
}, [externalChecked]);
|
||||
|
||||
React.useEffect(() => {
|
||||
changeHandler?.(checked);
|
||||
}, [checked]);
|
||||
|
||||
return (
|
||||
<Stack
|
||||
{...wrapperWrapperProps}
|
||||
className={twMerge("gap-1.5", wrapperWrapperProps?.className)}
|
||||
>
|
||||
<div
|
||||
{...wrapperProps}
|
||||
className={twMerge(
|
||||
"flex items-start md:items-center gap-2 flex-wrap md:flex-nowrap",
|
||||
readOnly ? "opacity-70 pointer-events-none" : "",
|
||||
wrapperClassName,
|
||||
wrapperProps?.className,
|
||||
)}
|
||||
onClick={() => {
|
||||
setChecked(!checked);
|
||||
externalSetChecked?.(!checked);
|
||||
}}
|
||||
>
|
||||
<div
|
||||
{...props}
|
||||
className={twMerge(
|
||||
"flex items-center justify-center p-[3px] rounded-default",
|
||||
checked
|
||||
? "bg-primary twui-checkbox-checked text-white outline-slate-400"
|
||||
: "dark:outline-white/50 outline-2 -outline-offset-2 twui-checkbox-unchecked",
|
||||
"twui-checkbox",
|
||||
props.className,
|
||||
)}
|
||||
style={{
|
||||
minWidth: finalSize + "px",
|
||||
width: finalSize + "px",
|
||||
height: finalSize + "px",
|
||||
...props.style,
|
||||
}}
|
||||
>
|
||||
{checked && <CheckMarkSVG />}
|
||||
</div>
|
||||
{!noLabel && (
|
||||
<Stack className="gap-0.5">
|
||||
<div
|
||||
{...labelProps}
|
||||
className={twMerge(
|
||||
"select-none whitespace-normal md:whitespace-nowrap",
|
||||
labelProps?.className,
|
||||
)}
|
||||
>
|
||||
{label || finalTitle}
|
||||
</div>
|
||||
</Stack>
|
||||
)}
|
||||
</div>
|
||||
{info && (
|
||||
<Row className="gap-1 flex-nowrap" title={info.toString()}>
|
||||
<Info size={13} className="opacity-40 min-w-[20px]" />
|
||||
<Span size="smaller" className="opacity-70">
|
||||
{info}
|
||||
</Span>
|
||||
</Row>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user