import { Button, Checkbox, ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger, Input, Label, Switch as UISwitch, } from "@tensamin/ui"; import { useEffect, useState } from "react"; import { storageDefaults, type Storage } from "@tensamin/shared/data"; import { settingsStorageDefaults } from "@tensamin/shared/settings"; import { useStorage } from "@tensamin/storage/context"; type BooleanStorageKey = { [K in keyof Storage]: Storage[K] extends boolean ? K : never; }[keyof Storage]; type ListStorageKey = { [K in keyof Storage]: Storage[K] extends (string | number)[] ? K : never; }[keyof Storage]; type ListStorageItem = Storage[K] extends Array ? Item : never; export function Switch({ label, id, }: { label: React.ReactNode; id: keyof typeof settingsStorageDefaults & BooleanStorageKey; }) { const { save, load } = useStorage(); const [value, setValue] = useState(settingsStorageDefaults[id]); useEffect(() => { load(id).then((value) => setValue(value)); }, [id, load]); return (
{ setValue(value); save(id, value); }} />
); } export function List({ label, id, }: { label: React.ReactNode; id: K; }) { const { save, load } = useStorage(); const [items, setItems] = useState(storageDefaults[id]); const [inputValue, setInputValue] = useState(""); const [selectedItems, setSelectedItems] = useState>(new Set()); useEffect(() => { load(id).then((value) => setItems(value)); }, [id, load]); const persistItems = (nextItems: Storage[K]) => { setItems(nextItems); save(id, nextItems); }; const toStorageItem = (value: string): ListStorageItem => { const referenceItem = items[0] ?? storageDefaults[id][0]; if (typeof referenceItem === "number") { return Number(value) as ListStorageItem; } return value as ListStorageItem; }; const addItem = () => { const trimmedValue = inputValue.trim(); if (!trimmedValue) return; const nextItem = toStorageItem(trimmedValue); if (typeof nextItem === "number" && Number.isNaN(nextItem)) return; persistItems([...items, nextItem] as Storage[K]); setInputValue(""); }; const deleteItems = (indexes: Set) => { const nextItems = items.filter( (_, index) => !indexes.has(index), ) as Storage[K]; setItems(nextItems); setSelectedItems(new Set()); save(id, nextItems); }; return (
setInputValue(event.target.value)} onKeyDown={(event) => { if (event.key === "Enter") addItem(); }} />
{items.map((item, index) => { const labelId = `${String(id)}-${index}`; const selected = selectedItems.has(index); const deletingSelectedItems = selectedItems.size > 1; return ( { setSelectedItems((previous) => { const nextSelected = new Set(previous); if (checked) { nextSelected.add(index); } else { nextSelected.delete(index); } return nextSelected; }); }} />
} /> deleteItems( deletingSelectedItems ? selectedItems : new Set([index]), ) } > {deletingSelectedItems ? "Delete Selected" : "Delete"}
); })}
); }