{ "$schema": "homarr-widget-package-v3", "manifest": { "id": "homarr.reference.checklist", "version": "1.0.0", "sdkVersion": "1", "name": "Shared maintenance checklist", "description": "A persistent dashboard checklist with user, placement, or installation storage and host-native commands.", "entrypoints": { "tile": "widget.tsx", "advanced": "widget.tsx" }, "handlers": {} }, "files": { "widget.tsx": "import type { FormEvent } from \"react\";\nimport type { WidgetStorageScope } from \"@homarr/widget-sdk\";\ntype ChecklistItem = {id:string;label:string;done:boolean};\nimport { Alert, Button, Checkbox, Group, Stack, Text, TextInput } from \"@mantine/core\";\nimport { useWidgetCommands, useWidgetHost, useWidgetOptions, useWidgetState, useWidgetStorage } from \"@homarr/widget-sdk\";\nexport default function Checklist() {\n const host = useWidgetHost();\n const options = useWidgetOptions<{title:string;scope:WidgetStorageScope}>();\n const [draft, setDraft] = useWidgetState(\"draft\", \"\");\n const stored = useWidgetStorage(options.scope, \"checklist-v1\", []);\n const items = Array.isArray(stored.data) ? stored.data : [];\n const locked = host.isEditMode || stored.isPending || stored.saving;\n const save = (value:ChecklistItem[]) => { void stored.set(value).catch(() => undefined); };\n useWidgetCommands([{ id: \"clear-completed\", label: \"Clear completed items\", disabled: locked || !items.some((item) => item.done), run: () => save(items.filter((item) => !item.done)) }]);\n const add = (event:FormEvent) => { event.preventDefault(); if (!draft.trim() || locked) return; save([...items, { id: crypto.randomUUID(), label: draft.trim(), done: false }]); setDraft(\"\"); };\n return \n {options.title}{items.filter((item) => item.done).length}/{items.length}\n {(stored.error || stored.saveError) && {stored.error?.message ?? stored.saveError?.message}}\n {items.map((item) => save(items.map((row) => row.id === item.id ? { ...row, done: !row.done } : row))} />)}\n {!items.length && !stored.isPending && Add your first maintenance task.}\n
setDraft(event.currentTarget.value)} style={{ flex: 1 }} />
\n {host.displayMode === \"advanced\" && Changes are saved to Homarr. The selected storage scope controls whether this checklist belongs to you, this tile, or every placement of this installation.}\n
;\n}" }, "dependencies": {}, "connections": {}, "options": { "title": { "control": "text", "label": "Title", "default": "Maintenance" }, "scope": { "control": "select", "label": "Storage scope", "default": "instance", "choices": [ { "label": "This tile", "value": "instance" }, { "label": "My checklist", "value": "user" }, { "label": "All installation placements", "value": "installation" } ] } } }