Before repair nav components
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 4s
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 4s
This commit is contained in:
61
components/discarted/Autocomplete.js
Normal file
61
components/discarted/Autocomplete.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import { $, h, when, fx } from 'sigpro';
|
||||
import { Input } from '../Input.js';
|
||||
import { filterBy, listKey, getBy } from '../All.js';
|
||||
|
||||
|
||||
export const Autocomplete = ({ items, value, onselect, placeholder = 'Buscar...', ...props }) => {
|
||||
const query = $(value ? (typeof value === 'function' ? value() : value) : '');
|
||||
const isOpen = $(false);
|
||||
const filtered = $(() => filterBy(items, query()));
|
||||
const { cursor, onKey } = listKey(filtered, isOpen);
|
||||
|
||||
const pick = (item) => {
|
||||
const display = getBy(item);
|
||||
const actual = typeof item === 'string' ? item : item.value;
|
||||
query(display);
|
||||
if (typeof value === 'function') value(actual);
|
||||
onselect?.(item);
|
||||
isOpen(false);
|
||||
};
|
||||
|
||||
return h('div', { class: 'relative w-full' }, [
|
||||
Input({
|
||||
...props,
|
||||
type: 'text',
|
||||
placeholder,
|
||||
value: query,
|
||||
left: h('span', { class: 'icon-[lucide--search]' }),
|
||||
oninput: (e) => {
|
||||
query(e.target.value);
|
||||
if (typeof value === 'function') value(e.target.value);
|
||||
isOpen(true);
|
||||
},
|
||||
onfocus: () => isOpen(true),
|
||||
onblur: () => setTimeout(() => isOpen(false), 150),
|
||||
onkeydown: (e) => onKey(e, pick)
|
||||
}),
|
||||
|
||||
when(isOpen, () =>
|
||||
fx({ duration: 200, slide: true },
|
||||
h('ul', {
|
||||
class: 'absolute left-0 w-full menu bg-base-100 rounded-box mt-1 p-2 shadow-xl max-h-60 overflow-y-auto border border-base-300 z-50 flex-col flex-nowrap'
|
||||
}, [
|
||||
each(filtered, (item, idx) =>
|
||||
h('li', {}, [
|
||||
h('a', {
|
||||
class: () => cursor() === idx ? 'active bg-primary text-primary-content' : '',
|
||||
onmousedown: (e) => e.preventDefault(), // evita que el blur cierre antes del click
|
||||
onclick: () => pick(item),
|
||||
onmouseenter: () => cursor(idx)
|
||||
}, getBy(item))
|
||||
]),
|
||||
(item, idx) => getBy(item) + idx
|
||||
),
|
||||
() => filtered().length === 0
|
||||
? h('li', { class: 'p-4 opacity-50 text-center' }, 'Sin resultados')
|
||||
: null
|
||||
])
|
||||
)
|
||||
)
|
||||
]);
|
||||
};
|
||||
Reference in New Issue
Block a user