@ark-ui/solid
Version:
A collection of unstyled, accessible UI components for Solid, utilizing state machines for seamless interaction.
243 lines (235 loc) • 8.27 kB
JSX
import {
runIfFn
} from "./KGOB2IMX.jsx";
// src/components/collection/grid-collection.ts
import {
GridCollection
} from "@zag-js/collection";
var createGridCollection = (options) => new GridCollection(options);
// src/components/collection/list-collection.ts
import { ListCollection } from "@zag-js/collection";
var createListCollection = (options) => new ListCollection(options);
// src/components/collection/tree-collection.ts
import {
TreeCollection,
filePathToTree
} from "@zag-js/collection";
var createTreeCollection = (options) => new TreeCollection(options);
var createFileTreeCollection = (paths) => filePathToTree(paths);
// src/components/collection/use-async-list.ts
import * as asyncList from "@zag-js/async-list";
import { useMachine } from "@zag-js/solid";
import { createMemo } from "solid-js";
var useAsyncList = (props) => {
const machineProps = createMemo(() => runIfFn(props));
const service = useMachine(asyncList.machine, machineProps);
return createMemo(() => asyncList.connect(service));
};
// src/components/collection/use-list-collection.ts
import { createMemo as createMemo2, createSignal, splitProps } from "solid-js";
function useListCollection(props) {
const splittedProps = createMemo2(() => {
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 = createMemo2(() => {
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);
}
};
}
// src/components/collection/use-list-selection.ts
import { Selection } from "@zag-js/collection";
import { createEffect, createMemo as createMemo3, createSignal as createSignal2, on, splitProps as splitProps2 } from "solid-js";
function useListSelection(props) {
const splittedProps = createMemo3(() => {
const rawProps = typeof props === "function" ? props() : props;
return splitProps2(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] = createSignal2(init());
const watchDeps = () => {
const [{ collection, resetOnCollectionChange }] = splittedProps();
return [collection.getValues(), resetOnCollectionChange];
};
createEffect(
on(
watchDeps,
([, resetOnCollectionChange]) => {
if (resetOnCollectionChange) {
setSelection(createSelection());
}
},
{ defer: true }
)
);
const selectedValues = createMemo3(() => Array.from(selection()));
const isEmpty = createMemo3(() => selection().isEmpty());
const firstSelectedValue = createMemo3(() => {
const [localProps] = splittedProps();
return selection().firstSelectedValue(localProps.collection);
});
const lastSelectedValue = createMemo3(() => {
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 {
createGridCollection,
createListCollection,
createTreeCollection,
createFileTreeCollection,
useAsyncList,
useListCollection,
useListSelection
};