Basic Styled Example
This example is a reset css-styled example. Only the basic css directives are included to make the multicomplete visually sound.
Code
StyledMulticomplete.tsx
import {useMultiComplete} from 'multicomplete'
import {useState} from 'react'
import './styles.css'
const options = [
'Autocomplete',
'MultiComplete',
'MultiSelect',
'MultiCombobox',
'MultiAutocomplete',
'MultiMultiComplete',
'MultiMultiSelect',
'MultiMultiCombobox',
'MultiMultiAutocomplete',
'MultiMultiMultiComplete',
'MultiMultiMultiSelect',
]
export const StyledMulticomplete = () => {
const [values, setValues] = useState<typeof options>([])
const [isOpen, setIsOpen] = useState(false)
const result = useMultiComplete({
isOpen,
onOpenChange: setIsOpen,
queryOptionFilter: (option, query) =>
option.toLowerCase().includes(query.toLowerCase()),
values,
onChange: setValues,
options,
id: 'basic-example',
})
return (
<div {...result.getWrapperProps()} className="multicomplete">
{values.map((value, index) => (
<span key={value} data-active={result.activeValueIndex === index}>
{value}
<button {...result.getDeleteButtonProps(value)}>×</button>
</span>
))}
<div className="input-wrapper">
<input {...result.getInputProps()} placeholder='Search' />
<button {...result.getPopoverButtonProps()} aria-label='Open Popover'>
{isOpen ? 'Close' : 'Open'}
</button>
</div>
{isOpen && result.options.length > 0 && (
<div {...result.getPopoverProps()}>
<ul>
{options.map((option, optionIndex) => (
<li
data-active={result.activeOptionIndex == optionIndex}
key={option}
{...result.getOptionProps(option, optionIndex)}
>
{option}
</li>
))}
</ul>
</div>
)}
</div>
)
}
styles.css
.multicomplete {
position: relative;
border: 1px solid #ccc;
padding: 8px;
display: flex;
box-sizing: border-box;
flex-wrap: wrap;
gap: 8px;
}
.multicomplete:focus-within {
outline: 5px auto Highlight;
outline: 5px auto -webkit-focus-ring-color;
}
.multicomplete button {
padding-left: 5px;
}
.multicomplete > [data-active="true"] {
background: #555;
}
.multicomplete [role="combobox"] {
appearance: none;
background: transparent;
flex-grow: 1;
}
.multicomplete [role="combobox"]:focus {
outline: none;
box-shadow: none;
}
.multicomplete .input-wrapper {
display: flex;
flex-grow: 1;
flex-basis: 200px;
flex-shrink: 0;
}
.multicomplete [role="listbox"] {
position: absolute;
top: 100%;
left: 0;
background: #000;
z-index: 2;
max-height: 200px;
overflow-y: auto;
width: 100%;
}
.multicomplete ul {
list-style: none;
margin: 0;
padding: 0;
}
.multicomplete [role="option"] {
padding: 8px;
cursor: pointer;
}
.multicomplete [role="option"][data-active="true"] {
background: #333;
}