UNPKG

@ark-ui/solid

Version:

A collection of unstyled, accessible UI components for Solid, utilizing state machines for seamless interaction.

205 lines (202 loc) 7.35 kB
import { GridCollection, ListCollection, TreeCollection, filePathToTree, Selection } from '@zag-js/collection'; import { createMemo, splitProps, createSignal, createEffect, on } from 'solid-js'; // src/components/collection/grid-collection.ts var createGridCollection = (options) => new GridCollection(options); var createListCollection = (options) => new ListCollection(options); var createTreeCollection = (options) => new TreeCollection(options); var createFileTreeCollection = (paths) => filePathToTree(paths); function useListCollection(props) { const splittedProps = createMemo(() => { const rawProps = typeof props === "function" ? props() : props; return splitProps(rawProps, ["initialItems", "filter", "limit"]); }); const init = () => { const [localProps] = splittedProps(); return localProps.initialItems; }; const [items, setItemsImpl] = createSignal(init()); const [filterText, setFilterText] = createSignal(""); const setItems = (newItems) => { setItemsImpl(newItems); setFilterText(""); }; const create = (itemsToCreate) => { const [, collectionOptions] = splittedProps(); return createListCollection({ ...collectionOptions, items: itemsToCreate }); }; const collection = createMemo(() => { const [localProps, collectionOptions] = splittedProps(); const filter = localProps.filter; let activeItems = items(); if (filterText() && filter) { activeItems = create(items()).filter((itemString, _index, item) => filter(itemString, filterText(), item)).items; } const limitedItems = localProps.limit == null ? activeItems : activeItems.slice(0, localProps.limit); return createListCollection({ ...collectionOptions, items: limitedItems }); }); return { collection, filter: (inputValue = "") => { setFilterText(inputValue); }, set: (newItems) => { setItems(newItems); }, reset: () => { const [localProps] = splittedProps(); setItems(localProps.initialItems); }, clear: () => { setItems([]); }, insert: (index, ...itemsToInsert) => { const newItems = create(items()).insert(index, ...itemsToInsert).items; setItems(newItems); }, insertBefore: (value, ...itemsToInsert) => { const newItems = create(items()).insertBefore(value, ...itemsToInsert).items; setItems(newItems); }, insertAfter: (value, ...itemsToInsert) => { const newItems = create(items()).insertAfter(value, ...itemsToInsert).items; setItems(newItems); }, remove: (...itemOrValues) => { const newItems = create(items()).remove(...itemOrValues).items; setItems(newItems); }, move: (value, to) => { const newItems = create(items()).move(value, to).items; setItems(newItems); }, moveBefore: (value, ...values) => { const newItems = create(items()).moveBefore(value, ...values).items; setItems(newItems); }, moveAfter: (value, ...values) => { const newItems = create(items()).moveAfter(value, ...values).items; setItems(newItems); }, reorder: (from, to) => { const newItems = create(items()).reorder(from, to).items; setItems(newItems); }, append: (...itemsToAppend) => { const newItems = create(items()).append(...itemsToAppend).items; setItems(newItems); }, upsert: (value, item, mode = "append") => { const newItems = create(items()).upsert(value, item, mode).items; setItems(newItems); }, prepend: (...itemsToPrepend) => { const newItems = create(items()).prepend(...itemsToPrepend).items; setItems(newItems); }, update: (value, item) => { const newItems = create(items()).update(value, item).items; setItems(newItems); } }; } function useListSelection(props) { const splittedProps = createMemo(() => { const rawProps = typeof props === "function" ? props() : props; return splitProps(rawProps, [ "collection", "selectionMode", "deselectable", "initialSelectedValues", "resetOnCollectionChange" ]); }); const createSelection = (values = []) => { const [localProps] = splittedProps(); const selection2 = new Selection(values); selection2.selectionMode = localProps.selectionMode ?? "single"; selection2.deselectable = localProps.deselectable ?? true; return selection2; }; const init = () => { const [localProps] = splittedProps(); return createSelection(localProps.initialSelectedValues ?? []); }; const [selection, setSelection] = createSignal(init()); const watchDeps = () => { const [{ collection, resetOnCollectionChange }] = splittedProps(); return [collection.getValues(), resetOnCollectionChange]; }; createEffect( on( watchDeps, ([, resetOnCollectionChange]) => { if (resetOnCollectionChange) { setSelection(createSelection()); } }, { defer: true } ) ); const selectedValues = createMemo(() => Array.from(selection())); const isEmpty = createMemo(() => selection().isEmpty()); const firstSelectedValue = createMemo(() => { const [localProps] = splittedProps(); return selection().firstSelectedValue(localProps.collection); }); const lastSelectedValue = createMemo(() => { const [localProps] = splittedProps(); return selection().lastSelectedValue(localProps.collection); }); return { selectedValues, isEmpty, firstSelectedValue, lastSelectedValue, isSelected: (value) => { return selection().isSelected(value); }, isAllSelected: () => { const [localProps] = splittedProps(); const allValues = localProps.collection.getValues(); return allValues.length > 0 && allValues.every((value) => selection().isSelected(value)); }, isSomeSelected: () => { const [localProps] = splittedProps(); const allValues = localProps.collection.getValues(); return allValues.some((value) => selection().isSelected(value)); }, canSelect: (value) => { const [localProps] = splittedProps(); return selection().canSelect(localProps.collection, value); }, select: (value, forceToggle) => { const [localProps] = splittedProps(); setSelection(selection().select(localProps.collection, value, forceToggle)); }, deselect: (value) => { setSelection(selection().deselect(value)); }, toggle: (value) => { const [localProps] = splittedProps(); setSelection(selection().toggleSelection(localProps.collection, value)); }, replace: (value) => { const [localProps] = splittedProps(); setSelection(selection().replaceSelection(localProps.collection, value)); }, extend: (anchorValue, targetValue) => { const [localProps] = splittedProps(); setSelection(selection().extendSelection(localProps.collection, anchorValue, targetValue)); }, setSelectedValues: (values) => { setSelection(selection().setSelection(values)); }, clear: () => { setSelection(selection().clearSelection()); }, resetSelection: () => { setSelection(createSelection()); } }; } export { createFileTreeCollection, createGridCollection, createListCollection, createTreeCollection, useListCollection, useListSelection };