Checkbox
Checkbox group
You can wrap checkbox controls into group using <fieldset>
and adding <legend>
.
tsx
import React from 'react';
import Checkbox from '@semcore/checkbox';
const fieldsetStyle = { border: 'none' };
const ulStyle = {};
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}>
<legend>Options list label</legend>
<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 React from 'react';
import { Flex } from '@semcore/flex-box';
import Checkbox from '@semcore/checkbox';
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='Options group'
onChange={handleGroupChange}
indeterminate={checked.includes(false) && checked.includes(true)}
checked={checked.includes(true)}
/>
</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 React from 'react';
import { Flex } from '@semcore/flex-box';
import Checkbox from '@semcore/checkbox';
import { DescriptionTooltip } from '@semcore/tooltip';
import InfoM from '@semcore/icon/Info/m';
import Link from '@semcore/link';
import { ButtonLink } from '@semcore/button';
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 React from 'react';
import Checkbox from '@semcore/checkbox';
const Demo = () => {
return (
<Checkbox>
<Checkbox.Value>
<Checkbox.Value.Control data-testid='checkbox_input_tag' />
<Checkbox.Value.CheckMark />
</Checkbox.Value>
<Checkbox.Text>Value</Checkbox.Text>
</Checkbox>
);
};
export default Demo;