import { useMemo, useState } from "react"; import { Button, Card, Center, Grid, Input, Stack, Text } from "@mantine/core"; import { IconSearch } from "@tabler/icons-react"; import { objectEntries } from "@homarr/common"; import type { WidgetKind } from "@homarr/definitions"; import { createModal } from "@homarr/modals"; import { useI18n } from "@homarr/translation/client"; import type { TablerIcon } from "@homarr/ui"; import { widgetImports } from "@homarr/widgets"; import { useItemActions } from "./item-actions"; export const ItemSelectModal = createModal(({ actions }) => { const [search, setSearch] = useState(""); const t = useI18n(); const { createItem } = useItemActions(); const items = useMemo( () => objectEntries(widgetImports) .map(([kind, value]) => ({ kind, icon: value.definition.icon, name: t(`widget.${kind}.name`), description: t(`widget.${kind}.description`), })) .sort((itemA, itemB) => itemA.name.localeCompare(itemB.name)), [t], ); const filteredItems = useMemo( () => items.filter((item) => item.name.toLowerCase().includes(search.toLowerCase())), [items, search], ); const handleAdd = (kind: WidgetKind) => { createItem({ kind }); actions.closeModal(); }; return ( setSearch(event.currentTarget.value)} leftSection={} placeholder={`${t("item.create.search")}...`} data-autofocus onKeyDown={(event) => { // Add item if there is only one item in the list and user presses Enter if (event.key === "Enter" && filteredItems.length === 1) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion handleAdd(filteredItems[0]!.kind); } }} /> {filteredItems.map((item) => ( handleAdd(item.kind)} /> ))} ); }).withOptions({ defaultTitle: (t) => t("item.create.title"), size: "xl", }); const WidgetItem = ({ item, onSelect, }: { item: { kind: WidgetKind; name: string; description: string; icon: TablerIcon; }; onSelect: () => void; }) => { const t = useI18n(); return (
{item.name} {item.description}
); };