import { Match, Show, createEffect, createMemo, createSignal, mergeProps, } from "solid-js"; function List(props) { props = mergeProps({ items: [], showHeader: true, selectable: true }, props); const [listItems, setListItems] = createSignal([]); const selectedItems = createMemo(() => listItems() .filter((item) => item.selected()) .map((item) => item.item) ); const allItemsSelected = createMemo(() => listItems().every((item) => item.selected()) ); createEffect(() => { setListItems( props.items.map((item) => { const [selected, setSelected] = createSignal(false); return { selected, setSelected, item: item, }; }) ); }); createEffect(() => { if (!props.onListItemsSelect) return; props.onListItemsSelect(selectedItems()); }); const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { if (props.onLazyLoad) { props.onLazyLoad(); } } }); }); const [lazyLoadTriggerElement, setLazyLoadTriggerElement] = createSignal(); createEffect(() => { observer.observe(lazyLoadTriggerElement()); }); const [scrollTop, setScrollTop] = createSignal(0); const itemsMutationObserver = new MutationObserver(() => { itemsContainerElement().scrollTop = scrollTop(); }); const [itemsContainerElement, setItemsContainerElement] = createSignal(); createEffect(() => { if (!itemsContainerElement()) return; itemsMutationObserver.observe(itemsContainerElement(), { childList: true }); }); function handleListItemClick(item) { if (!props.onListItemClick) return; props.onListItemClick(item); } function handleToggleAllItems() { if (allItemsSelected()) { listItems().forEach((item) => item.setSelected(false)); return; } listItems().forEach((item) => item.setSelected(true)); } function renderHeaderRow(columns) { columns = columns.filter((column) => !column.hidden); if (!props.showHeader) return null; return (
handleToggleAllItems()} >
{(column) => (
{column.name}
)}
); } function renderListItem(listItem, columns) { columns = columns.filter((column) => !column.hidden); let item = listItem.item; return (
listItem.setSelected(!listItem.selected())} >
handleListItemClick(item)} > {(column) => (
{item[column.id].html}
{item[column.id]?.text}
)}
); } return (
{renderHeaderRow(props.columns)}
setScrollTop(event.target.scrollTop)} ref={setItemsContainerElement} > {(listItem) => renderListItem(listItem, props.columns)}
); } export default List;