in src/data-table/filter-menu.tsx [55:207]
function Options(props: OptionsProps) {
const [css, theme] = useStyletron();
const locale = React.useContext(LocaleContext);
const inputRef = React.useRef(null);
React.useEffect(() => {
if (inputRef.current) {
// @ts-ignore
inputRef.current.focus();
}
}, [inputRef.current]);
const [focusVisible, setFocusVisible] = React.useState(false);
const seed = useUIDSeed();
const buiRef = React.useRef(props.columns.map((col) => seed(col)));
const activeDescendant = buiRef.current[props.highlightIndex]
? `bui-${buiRef.current[props.highlightIndex]}`
: undefined;
const optionsLabelId = seed('options-label');
const handleFocus = (event: SyntheticEvent) => {
if (isFocusVisible(event)) {
setFocusVisible(true);
}
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const handleBlur = (event: SyntheticEvent) => {
if (focusVisible !== false) {
setFocusVisible(false);
}
};
return (
<div
className={css({
backgroundColor: theme.colors.menuFill,
minWidth: '320px',
outline: focusVisible ? `3px solid ${theme.colors.borderAccent}` : 'none',
paddingTop: theme.sizing.scale600,
paddingBottom: theme.sizing.scale600,
})}
>
<p
id={optionsLabelId}
className={css({
...theme.typography.font100,
marginTop: 'unset',
paddingRight: theme.sizing.scale600,
paddingLeft: theme.sizing.scale600,
})}
>
{locale.datatable.optionsLabel}
</p>
{props.searchable && (
<div
className={css({
marginBottom: theme.sizing.scale500,
marginRight: theme.sizing.scale600,
marginLeft: theme.sizing.scale600,
})}
>
<Input
inputRef={inputRef}
value={props.query}
onChange={(event) => props.onQueryChange(event.target.value)}
placeholder={locale.datatable.optionsSearch}
size={INPUT_SIZE.compact}
clearable
/>
</div>
)}
{!props.columns.length && (
<div
className={css({
...theme.typography.font100,
paddingRight: theme.sizing.scale600,
paddingLeft: theme.sizing.scale600,
})}
>
{locale.datatable.optionsEmpty}
</div>
)}
<ul
onKeyDown={props.onKeyDown}
onFocus={handleFocus}
onBlur={handleBlur}
tabIndex={0}
role="listbox"
aria-activedescendant={activeDescendant}
aria-labelledby={optionsLabelId}
className={css({
listStyleType: 'none',
marginBlockStart: 'unset',
marginBlockEnd: 'unset',
maxHeight: '256px',
paddingInlineStart: 'unset',
outline: 'none',
overflowY: 'auto',
})}
>
{props.columns.map((column, index) => {
const isHighlighted = index === props.highlightIndex;
return (
// handled on the wrapper element
// eslint-disable-next-line jsx-a11y/click-events-have-key-events
<li
id={`bui-${buiRef.current[index]}`}
role="option"
aria-selected={isHighlighted}
onMouseEnter={() => props.onMouseEnter(index)}
onClick={() => props.onClick(column)}
key={column.title}
className={css({
...theme.typography.font100,
alignItems: 'center',
// @ts-ignore
backgroundColor: isHighlighted ? theme.colors.menuFillHover : null,
cursor: 'pointer',
display: 'flex',
paddingTop: theme.sizing.scale100,
paddingRight: theme.sizing.scale600,
paddingBottom: theme.sizing.scale100,
paddingLeft: theme.sizing.scale600,
})}
>
<div
className={css({
...theme.typography.font150,
fontSize: '8px',
alignItems: 'center',
backgroundColor: theme.colors.backgroundTertiary,
borderRadius: theme.borders.radius200,
display: 'flex',
height: theme.sizing.scale800,
justifyContent: 'center',
marginRight: theme.sizing.scale300,
width: theme.sizing.scale800,
})}
>
<ColumnIcon column={column} />
</div>
{column.title}
</li>
);
})}
</ul>
</div>
);
}