combobox: add stateless mode
This commit is contained in:
@@ -50,6 +50,8 @@
|
||||
lazy?: boolean;
|
||||
/** uses a compact layout for the search input with less padding and smaller text */
|
||||
compact?: boolean;
|
||||
/** allows the user to select an option without selecting a value (events are still triggered) */
|
||||
stateless?: boolean;
|
||||
notFoundMessage?: string;
|
||||
class?: ClassValue | null | undefined;
|
||||
use?: () => void;
|
||||
@@ -77,6 +79,7 @@
|
||||
loading = false,
|
||||
lazy = false,
|
||||
compact = false,
|
||||
stateless = false,
|
||||
notFoundMessage = 'No results found',
|
||||
class: classValue,
|
||||
use,
|
||||
@@ -191,6 +194,13 @@
|
||||
onclose?.(); // trigger onclose event if defined
|
||||
};
|
||||
|
||||
/** updates the value of the combobox and triggers any callbacks, including closing the picker */
|
||||
const updateValue = (newValue: ComboboxOption) => {
|
||||
if (!stateless) value = newValue;
|
||||
closePicker();
|
||||
onchange?.(newValue);
|
||||
};
|
||||
|
||||
/** action to set the minimum width of the combobox based on the number of options */
|
||||
const minWidth: Action<HTMLDivElement, { options: ComboboxOption[] }> = (
|
||||
container,
|
||||
@@ -290,10 +300,7 @@
|
||||
export const setValueByString = (searchVal: string) => {
|
||||
const item = options.find((opt) => opt.value === searchVal);
|
||||
if (item) {
|
||||
value = item;
|
||||
searchValue = '';
|
||||
closePicker();
|
||||
onchange?.(item);
|
||||
updateValue(item);
|
||||
} else {
|
||||
console.warn(`Combobox: No option found with value "${searchVal}"`);
|
||||
}
|
||||
@@ -393,7 +400,7 @@
|
||||
aria-label={getLabel(item)}
|
||||
aria-disabled={item.disabled}
|
||||
class={[
|
||||
'picker-item options-center mb-0.5 flex min-h-10 flex-wrap py-2.5 pr-1.5 pl-5',
|
||||
'mb-0.5 flex min-h-10 flex-wrap items-center py-2.5 pr-1.5 pl-5',
|
||||
'rounded-sm text-sm capitalize outline-hidden select-none',
|
||||
'hover:bg-sui-accent-500/30 dark:hover:bg-sui-accent-700/30',
|
||||
item.value === highlighted?.value && 'bg-sui-accent-500/80 dark:bg-sui-accent-700/80',
|
||||
@@ -402,10 +409,8 @@
|
||||
role="option"
|
||||
onclick={() => {
|
||||
if (item.disabled) return;
|
||||
value = item;
|
||||
closePicker();
|
||||
updateValue(item);
|
||||
searchInput?.focus();
|
||||
onchange?.(item);
|
||||
}}
|
||||
onkeydown={() => {}}
|
||||
tabindex="-1"
|
||||
@@ -523,14 +528,12 @@
|
||||
|
||||
if (e.key === 'Tab' || e.key === 'Enter') {
|
||||
if (open && highlighted && !highlighted.disabled && highlighted.value !== value?.value) {
|
||||
value = highlighted;
|
||||
onchange?.(highlighted);
|
||||
updateValue(highlighted);
|
||||
}
|
||||
if (e.key === 'Enter') {
|
||||
closePicker();
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
closePicker();
|
||||
return;
|
||||
} else if (e.key === 'Escape') {
|
||||
closePicker();
|
||||
|
||||
@@ -136,7 +136,8 @@
|
||||
|
||||
<Combobox
|
||||
loading
|
||||
label="Loading state combobox"
|
||||
label="Loading stateless combobox"
|
||||
stateless
|
||||
placeholder="Choose..."
|
||||
options={[
|
||||
{ value: 'option1', label: 'Option 1' },
|
||||
|
||||
Reference in New Issue
Block a user