Checkbox
Checkbox group
You can wrap checkbox controls into group using <fieldset> and adding <legend>.
tsx
import Checkbox from '@semcore/ui/checkbox';
import { Text } from '@semcore/ui/typography';
import React from 'react';
const fieldsetStyle = { border: 'none' };
const ulStyle = { margin: 0, padding: 0 };
const liStyle = { listStyle: 'none', margin: 0 };
const Demo = () => {
const [checked, setChecked] = React.useState([false, false, false]);
const handleItemChange = React.useCallback(
(index: number) => (value: boolean) => {
setChecked((checked) => checked.map((item, i) => (i === index ? value : item)));
},
[setChecked],
);
return (
<fieldset style={fieldsetStyle}>
<Text tag='legend' size={200} mb={3}>
List of options
</Text>
<ul style={ulStyle}>
{checked.map((value, index) => (
<li key={index} style={liStyle}>
<Checkbox
mb={3}
key={index}
checked={value}
onChange={handleItemChange(index)}
label={`Option ${index + 1}`}
/>
</li>
))}
</ul>
</fieldset>
);
};
export default Demo;
Partial selection
When one or more options are selected from the list, the parent checkbox gets an indeterminate (mixed) state.
tsx
import { Flex } from '@semcore/ui/base-components';
import Checkbox from '@semcore/ui/checkbox';
import React from 'react';
const Demo = () => {
const [checked, setChecked] = React.useState([false, false, false]);
const handleGroupChange = React.useCallback(
(value: boolean) => {
setChecked((checked) => checked.map(() => value));
},
[setChecked],
);
const handleItemChange = React.useCallback(
(index: number) => (value: boolean) => {
setChecked((checked) => checked.map((item, i) => (i === index ? value : item)));
},
[setChecked],
);
return (
<>
<Flex>
<Checkbox
mb={3}
label='Group of options'
onChange={handleGroupChange}
indeterminate={checked.includes(false) && checked.includes(true)}
checked={!checked.includes(false)}
/>
</Flex>
{checked.map((value, index) => (
<Flex key={index} ml={6}>
<Checkbox
mb={3}
key={index}
checked={value}
onChange={handleItemChange(index)}
label={`Option ${index + 1}`}
/>
</Flex>
))}
</>
);
};
export default Demo;
Checkbox with other components
You can place other components next to the Checkbox or inside the Checkbox.Text components.
tsx
import { Flex } from '@semcore/ui/base-components';
import { ButtonLink } from '@semcore/ui/button';
import Checkbox from '@semcore/ui/checkbox';
import InfoM from '@semcore/ui/icon/Info/m';
import Link from '@semcore/ui/link';
import { DescriptionTooltip } from '@semcore/ui/tooltip';
import React from 'react';
function noop(e: React.SyntheticEvent) {
e.preventDefault();
}
const Demo = () => (
<>
<Flex mb={3}>
<Checkbox label='Option 1' />
<DescriptionTooltip placement='right'>
<DescriptionTooltip.Trigger
ml={1}
tag={ButtonLink}
addonLeft={InfoM}
color='icon-secondary-neutral'
aria-label='Additional info'
/>
<DescriptionTooltip.Popper aria-label='Additional info about checkbox item'>
Place an additional information here!
</DescriptionTooltip.Popper>
</DescriptionTooltip>
</Flex>
<Flex mb={3}>
<Checkbox>
<Checkbox.Value />
<Checkbox.Text>
Option 2
<Link ml={2} href='#' onClick={noop}>
Learn more
</Link>
</Checkbox.Text>
</Checkbox>
</Flex>
</>
);
export default Demo;
Additional props for input
Checkbox.Value is made of a CheckMark div and a hidden input. When you pass props to Checkbox.Value, it passes specific set of them to input props and all others goes to CheckMark div.
For more control over the input, you can pass props to Checkbox.Value.Control.
WARNING
🚨 Checkbox.Value.CheckMark should always be the next element after Checkbox.Value.Control in DOM.
tsx
import Checkbox from '@semcore/ui/checkbox';
import React from 'react';
const Demo = () => {
return (
<Checkbox>
<Checkbox.Value>
<Checkbox.Value.Control data-testid='checkbox_input_tag' />
<Checkbox.Value.CheckMark />
</Checkbox.Value>
<Checkbox.Text>Checkbox with custom properties</Checkbox.Text>
</Checkbox>
);
};
export default Demo;