Skip to content
Snippets Groups Projects
Checkbox.tsx 2.41 KiB
Newer Older
import { Check } from "@styled-icons/boxicons-regular";
insert's avatar
insert committed
import styled, { css } from "styled-components";
insert's avatar
insert committed

insert's avatar
insert committed
import { Children } from "../../types/Preact";

insert's avatar
insert committed
const CheckboxBase = styled.label`
    gap: 4px;
    z-index: 1;
    display: flex;
    margin-top: 20px;
    align-items: center;
    border-radius: var(--border-radius);
insert's avatar
insert committed

    cursor: pointer;
    font-size: 18px;
    user-select: none;
insert's avatar
insert committed

    transition: 0.2s ease all;
insert's avatar
insert committed

    input {
        display: none;
    }
insert's avatar
insert committed

    &:hover {
        .check {
            background: var(--background);
        }
    }
    &[disabled] {
        opacity: 0.5;
        cursor: not-allowed;
        &:hover {
            background: unset;
        }
    }
insert's avatar
insert committed
`;

const CheckboxContent = styled.span`
    display: flex;
    flex-grow: 1;
    font-size: 1rem;
    font-weight: 600;
    flex-direction: column;
insert's avatar
insert committed
`;

const CheckboxDescription = styled.span`
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--secondary-foreground);
insert's avatar
insert committed
`;

const Checkmark = styled.div<{ checked: boolean }>`
    margin: 4px;
    width: 24px;
    height: 24px;
    display: grid;
    flex-shrink: 0;
    place-items: center;
    transition: 0.2s ease all;
    border-radius: var(--border-radius);
    background: var(--secondary-background);
insert's avatar
insert committed

    svg {
        color: var(--secondary-background);
    }
insert's avatar
insert committed

    ${(props) =>
        props.checked &&
        css`
            background: var(--accent) !important;
        `}
insert's avatar
insert committed
`;

insert's avatar
insert committed
export interface CheckboxProps {
    checked: boolean;
    disabled?: boolean;
    className?: string;
    children: Children;
    description?: Children;
    onChange: (state: boolean) => void;
insert's avatar
insert committed
}

insert's avatar
insert committed
export default function Checkbox(props: CheckboxProps) {
    return (
        <CheckboxBase disabled={props.disabled} className={props.className}>
            <CheckboxContent>
                <span>{props.children}</span>
                {props.description && (
                    <CheckboxDescription>
                        {props.description}
                    </CheckboxDescription>
                )}
            </CheckboxContent>
            <input
                type="checkbox"
                checked={props.checked}
                onChange={() =>
                    !props.disabled && props.onChange(!props.checked)
                }
            />
            <Checkmark checked={props.checked} className="check">
                <Check size={20} />
            </Checkmark>
        </CheckboxBase>
    );
insert's avatar
insert committed
}