Files
nage/dev/ItemList.tsx
T
2025-12-29 18:56:04 +01:00

99 lines
1.8 KiB
TypeScript

import "./ItemList.css";
import { type Accessor, type Component, For } from "solid-js";
export type ListItem = { label: string; isActive: boolean };
export type ItemHandler = (item: ListItem, index: number) => void;
export type Direction = "default" | "asc" | "desc";
export function useSort(
items: Array<ListItem>,
): [
(direction?: Direction) => Array<ListItem>,
(newItems: Array<ListItem>) => void,
] {
let itemsRef = items;
return [
(direction = "default") => {
if (direction === "default") {
return [...itemsRef];
}
const newItems = [...itemsRef];
newItems.sort((a, b) => {
const labelA = a.label.toLocaleLowerCase();
const labelB = b.label.toLocaleLowerCase();
if (labelA < labelB) {
return direction === "asc" ? -1 : 1;
}
if (labelA > labelB) {
return direction === "asc" ? 1 : -1;
}
return 0;
});
return newItems;
},
(newItems) => {
itemsRef = newItems;
},
];
}
export function useDirection(
initialDirection: Direction = "default",
): (forcedDirection?: Direction) => Direction {
let direction: Direction = initialDirection;
return (forcedDirection) => {
if (forcedDirection) {
direction = forcedDirection;
return direction;
}
switch (direction) {
case "asc": {
direction = "desc";
break;
}
case "desc": {
direction = "default";
break;
}
default: {
direction = "asc";
}
}
return direction;
};
}
export const ItemList: Component<{
items: Accessor<Array<ListItem>>;
handler: ItemHandler;
}> = (props) => (
<ul class="item-list">
<For each={props.items()}>
{(item, index) => {
return (
<li
class="item-list-item"
classList={{
active: item.isActive,
}}
onClick={() => props.handler(item, index())}
>
{item.label}
</li>
);
}}
</For>
</ul>
);