import { ChangeEvent, InputHTMLAttributes, forwardRef } from 'react';
import styled from 'styled-components';
import { spacing, Stack } from '../../spacing';
import { Text } from '../text/Text.component';
import { FocusVisibleStyle } from '../buttonv2/Buttonv2.component';
const getCheckmarkSvgUrl = (color: string) => {
const encodedColor = color.replace('#', '%23');
return `url('data:image/svg+xml,%3Csvg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg"%3E %3Cpath d="M3 6.68646L5.0671 9L9 3" stroke="${encodedColor}" stroke-width="1.5"/%3E %3C/svg%3E')`;
};
const getIndeterminateSvgUrl = (color: string) => {
const encodedColor = color.replace('#', '%23');
return `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E %3Cline x1='6' y1='12' x2='20' y2='12' style='stroke:${encodedColor};stroke-width:4'/%3E %3C/svg%3E")`;
};
const CheckboxInput = styled.input`
transform: scale(1.5);`;
export type Props = {
/**
* Label displayed next to the checkbox.
* Use only for standalone checkboxes (not inside a FormGroup).
* When inside a FormGroup, set the label on FormGroup's `label` prop instead.
*/
label?: string;
value?: string;
checked?: boolean;
disabled?: boolean;
onChange?: (e: ChangeEvent) => void;
} & InputHTMLAttributes;
const Checkbox = forwardRef(
({ disabled, checked, label, value, onChange, ...rest }, ref) => {
return (
{label && {label}}
);
},
);
export { Checkbox };
const StyledCheckbox = styled.label<{
disabled?: boolean;
checked?: boolean;
}>`
${(props) => (props.disabled ? 'opacity: 0.5;' : '')}
/* Basic styling */
[type='checkbox'] {
width: 0.75rem;
height: 0.75rem;
color: ${(props) => props.theme.textPrimary};
vertical-align: middle;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background: none;
border: 0;
outline: 0;
flex-grow: 0;
border-radius: ${spacing.r2};
background-color: ${(props) => props.theme.backgroundLevel1};
transition: background 300ms;
cursor: pointer;
}
/* Pseudo element for check styling */
[type='checkbox']::before {
content: '';
color: transparent;
display: block;
width: inherit;
height: inherit;
border-radius: inherit;
border: 0;
background-color: transparent;
background-size: contain;
box-shadow: inset 0 0 0 ${spacing.r1} ${(props) => props.theme.textSecondary};
}
/* Checked */
[type='checkbox']:checked {
background-color: ${(props) => props.theme.selectedActive};
}
[type='checkbox']:checked::before {
box-shadow: none;
background-image: ${(props) => getCheckmarkSvgUrl(props.theme.textPrimary)};
background-repeat: no-repeat;
background-position: center;
}
/* Indeterminate */
[type='checkbox']:indeterminate::before {
box-shadow: inset 0 0 0 ${spacing.r1} ${(props) => props.theme.selectedActive};
background-color: ${(props) => props.theme.highlight};
background-image: ${(props) => getIndeterminateSvgUrl(props.theme.textPrimary)};
}
/* Hover & focus */
[type='checkbox']:hover {
${(props) =>
!props.disabled && `background-color: ${props.theme.highlight};`}
}
[type='checkbox']:hover::before {
${(props) =>
!props.disabled &&
`box-shadow: inset 0 0 0 ${spacing.r1} ${props.theme.selectedActive};`}
}
[type='checkbox']:focus-visible:enabled {
${FocusVisibleStyle}
}
/* Disabled */
[type='checkbox']:checked:disabled {
cursor: not-allowed;
background-color: ${(props) => props.theme.selectedActive};
}
[type='checkbox']:not(:checked):disabled {
cursor: not-allowed;
background-color: ${(props) => props.theme.textSecondary};
}
`