AutoSuggest
To create one of the search patterns (Combobox, AutoSuggest) you will need the following:
Combobox
tsx
import { Box } from '@semcore/ui/base-components';
import Input from '@semcore/ui/input';
import Select from '@semcore/ui/select';
import { Text } from '@semcore/ui/typography';
import React from 'react';
const options = Array(12)
.fill(0)
.map((_, i) => ({
value: `${i}:00`.padStart(5, '0'),
title: `${i}:00`.padStart(5, '0'),
}));
const Demo = () => {
const [highlightedIndex, setHighlightedIndex] = React.useState<number | null>(null);
const [value, setValue] = React.useState('');
React.useEffect(() => {
const exactValueIndex = options.findIndex((option) => option.value === value);
if (exactValueIndex > -1) {
setHighlightedIndex(exactValueIndex);
}
}, [value]);
const handleHighlightedIndexChange = (index: number | null) => {
setHighlightedIndex(index);
};
return (
<>
<Text tag='label' size={200} htmlFor='release-time-picker'>
Release time
</Text>
<Box mt={2}>
<Select
interaction='focus'
onChange={setValue}
value={value}
highlightedIndex={highlightedIndex}
onHighlightedIndexChange={handleHighlightedIndexChange}
>
<Select.Trigger tag={Input} w={150}>
{() => <Input.Value value={value} onChange={setValue} id='release-time-picker' />}
</Select.Trigger>
<Select.Menu>
{options.map((option) => (
<Select.Option value={option.value} key={option.value}>
{option.title}
</Select.Option>
))}
</Select.Menu>
</Select>
</Box>
</>
);
};
export default Demo;
AutoSuggest
tsx
import { Box } from '@semcore/ui/base-components';
import Input from '@semcore/ui/input';
import Select from '@semcore/ui/select';
import { Text } from '@semcore/ui/typography';
import React from 'react';
const Highlight = ({ highlight, children }: { highlight: string; children: string }) => {
let html = children;
if (highlight) {
try {
const re = new RegExp(highlight.toLowerCase(), 'g');
html = html.replace(
re,
`<span style="font-weight: bold; padding: 2px 0">${highlight}</span>`,
);
} catch (e) {}
}
return <span dangerouslySetInnerHTML={{ __html: html }} />;
};
const debounce = (func: Function, timeout: number) => {
let timer: number;
return (...args: any[]) => {
window.clearTimeout(timer);
timer = window.setTimeout(() => {
func(...args);
}, timeout);
};
};
type Suggestion = {
value: string;
title: string;
};
const fakeFetch = async (query: string): Promise<Suggestion[]> => {
if (!query) return [];
return [
'persian',
'maine coon',
'ragdoll',
'sphynx',
'siamese',
'bengal',
'british shorthair',
'abyssinian',
'birman',
'oriental shorthair',
'scottish fold',
'devon rex',
'norwegian forest',
'siberian',
'russian blue',
'savannah',
'american shorthair',
'exotic shorthair',
'ragamuffin',
'balinese',
]
.filter((breed) => breed.toLowerCase().includes(query.toLowerCase()))
.map((value) => ({ value, title: value }));
};
const Demo = () => {
const [highlightedIndex, setHighlightedIndex] = React.useState<number | null>(-1);
const [visible, setVisible] = React.useState(false);
const [query, setQuery] = React.useState('');
const [suggestions, setSuggestions] = React.useState<Suggestion[]>([]);
const loadSuggestions = React.useCallback(
debounce(
(query: string) => fakeFetch(query).then((suggestions) => setSuggestions(suggestions)),
300,
),
[],
);
React.useEffect(() => {
loadSuggestions(query);
}, [query]);
const handleSelect = React.useCallback((x: string) => {
setQuery(x);
setVisible(false);
}, []);
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (!e.key.startsWith('Array')) {
setHighlightedIndex(-1);
}
};
const handleHighlightedIndexChange = (index: number | null) => {
setHighlightedIndex(index);
};
const handleChangeVisible = (visible: boolean) => {
setVisible(visible);
};
return (
<>
<Text tag='label' size={200} htmlFor='website-autosuggest'>
Your pet breed
</Text>
<Box mt={2}>
<Select
interaction='focus'
onChange={handleSelect}
value={query}
visible={visible}
onVisibleChange={handleChangeVisible}
highlightedIndex={highlightedIndex}
onHighlightedIndexChange={handleHighlightedIndexChange}
defaultHighlightedIndex={null}
>
<Select.Trigger tag={Input} w={250}>
{() => (
<Input.Value
value={query}
role='combobox'
placeholder='Start typing for options'
onChange={setQuery}
id='website-autosuggest'
onKeyDown={handleKeyDown}
autoComplete='off'
/>
)}
</Select.Trigger>
{suggestions.length > 0 && (
<Select.Menu>
{suggestions.map((option) => (
<Select.Option value={option.value} key={option.value}>
<Highlight highlight={query}>{option.title}</Highlight>
</Select.Option>
))}
</Select.Menu>
)}
</Select>
</Box>
</>
);
};
export default Demo;