From 314deed9044f2889753a022d772040f9cf8abee5 Mon Sep 17 00:00:00 2001 From: Peter van Hardenberg Date: Wed, 8 Jul 2026 15:51:35 -0700 Subject: [PATCH] reintroduce datatype-derived icons for documents in the sidebar; draft --- pnpm-lock.yaml | 42 ++-- sideboard/package.json | 1 + sideboard/src/index.css | 7 + .../sideboard/document-list/datatype-icon.tsx | 205 ++++++++++++++++++ .../sideboard/document-list/document-list.tsx | 2 + sideboard/src/sideboard/lib/solid-plugins.ts | 27 ++- 6 files changed, 268 insertions(+), 16 deletions(-) create mode 100644 sideboard/src/sideboard/document-list/datatype-icon.tsx diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 075b6c5d..3fd12b9c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -67,7 +67,7 @@ importers: version: 1.9.12(@babel/core@7.28.4(supports-color@5.5.0))(solid-js@1.9.13) solid-automerge: specifier: ^2.0.0 - version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13) + version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34(supports-color@5.5.0))(solid-js@1.9.13)(supports-color@5.5.0) solid-js: specifier: ^1.9.9 version: 1.9.13 @@ -115,7 +115,7 @@ importers: version: 2.1.1 solid-automerge: specifier: ^2.0.0 - version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13) + version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34(supports-color@5.5.0))(solid-js@1.9.13)(supports-color@5.5.0) solid-js: specifier: ^1.9.9 version: 1.9.13 @@ -228,7 +228,7 @@ importers: version: 0.2.3(@automerge/automerge-repo-solid-primitives@2.6.0-subduction.39(@automerge/automerge@3.3.0-fragments.1)(solid-js@1.9.13))(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13) solid-automerge: specifier: ^2.0.0 - version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13) + version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34(supports-color@5.5.0))(solid-js@1.9.13)(supports-color@5.5.0) solid-js: specifier: ^1.9.9 version: 1.9.13 @@ -396,7 +396,7 @@ importers: version: 0.0.7(@automerge/automerge@3.3.0-fragments.1)(@codemirror/state@6.7.0)(@codemirror/view@6.43.2)(solid-js@1.9.13) solid-automerge: specifier: ^2.0.0 - version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13) + version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34(supports-color@5.5.0))(solid-js@1.9.13)(supports-color@5.5.0) solid-js: specifier: ^1.9.9 version: 1.9.13 @@ -516,7 +516,7 @@ importers: version: 0.2.3(@automerge/automerge-repo-solid-primitives@2.6.0-subduction.39(@automerge/automerge@3.3.0-fragments.1)(solid-js@1.9.13))(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13) solid-automerge: specifier: ^2.0.0 - version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13) + version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34(supports-color@5.5.0))(solid-js@1.9.13)(supports-color@5.5.0) solid-js: specifier: ^1.9.9 version: 1.9.13 @@ -702,7 +702,7 @@ importers: version: 0.0.6(@automerge/automerge-repo@2.6.0-subduction.34)(@automerge/automerge@3.2.6)(@inkandswitch/patchwork-filesystem@0.0.4(@automerge/automerge-repo@2.6.0-subduction.34)(@automerge/automerge@3.2.6)) solid-automerge: specifier: ^2.0.0 - version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13) + version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34(supports-color@5.5.0))(solid-js@1.9.13)(supports-color@5.5.0) solid-js: specifier: ^1.9.9 version: 1.9.13 @@ -766,7 +766,7 @@ importers: version: 0.2.3(@automerge/automerge-repo-solid-primitives@2.6.0-subduction.39(@automerge/automerge@3.3.0-fragments.1)(solid-js@1.9.13))(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13) solid-automerge: specifier: ^2.0.0 - version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13) + version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34(supports-color@5.5.0))(solid-js@1.9.13)(supports-color@5.5.0) solid-js: specifier: ^1.9.10 version: 1.9.13 @@ -849,7 +849,7 @@ importers: version: 0.0.6(@automerge/automerge-repo@2.6.0-subduction.34)(@inkandswitch/patchwork-filesystem@0.0.4(@automerge/automerge-repo@2.6.0-subduction.34)(@automerge/automerge@3.2.6))(@inkandswitch/patchwork-plugins@0.0.6(@automerge/automerge-repo@2.6.0-subduction.34)(@automerge/automerge@3.2.6)(@inkandswitch/patchwork-filesystem@0.0.4(@automerge/automerge-repo@2.6.0-subduction.34)(@automerge/automerge@3.2.6))) solid-automerge: specifier: ^2.0.0 - version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13) + version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34(supports-color@5.5.0))(solid-js@1.9.13)(supports-color@5.5.0) devDependencies: '@automerge/automerge': specifier: ^3.2.5 @@ -947,9 +947,12 @@ importers: debug: specifier: ^4.4.3 version: 4.4.3(supports-color@5.5.0) + lucide-solid: + specifier: ^1.23.0 + version: 1.23.0(solid-js@1.9.13) solid-automerge: specifier: ^2.0.0 - version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13) + version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34(supports-color@5.5.0))(solid-js@1.9.13)(supports-color@5.5.0) solid-js: specifier: ^1.9.9 version: 1.9.13 @@ -1187,7 +1190,7 @@ importers: version: 4.3.5(solid-js@1.9.13) solid-automerge: specifier: ^2.0.0 - version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13) + version: 2.0.0(@automerge/automerge-repo@2.6.0-subduction.34(supports-color@5.5.0))(solid-js@1.9.13)(supports-color@5.5.0) solid-js: specifier: ^1.9.10 version: 1.9.13 @@ -4890,6 +4893,11 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + lucide-solid@1.23.0: + resolution: {integrity: sha512-vzVY2fITccYlJTrv5fHro9OONinnotXtNmAb/Sh1UOpMB/PtvFuF3FVz2Orh7/R7l5YdF1j4TOPmfgImHpzv0g==} + peerDependencies: + solid-js: ^1.4.7 + lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -10151,7 +10159,7 @@ snapshots: '@noble/hashes': 1.8.0 bs58: 6.0.0 - cabbages@0.2.8: + cabbages@0.2.8(supports-color@5.5.0): dependencies: debug: 4.4.3(supports-color@5.5.0) transitivePeerDependencies: @@ -10699,6 +10707,10 @@ snapshots: dependencies: react: 18.3.1 + lucide-solid@1.23.0(solid-js@1.9.13): + dependencies: + solid-js: 1.9.13 + lz-string@1.5.0: {} magic-string@0.30.21: @@ -11082,16 +11094,16 @@ snapshots: dependencies: '@automerge/automerge-repo': 2.5.6(supports-color@5.5.0) '@solid-primitives/utils': 6.4.1(solid-js@1.9.13) - cabbages: 0.2.8 + cabbages: 0.2.8(supports-color@5.5.0) solid-js: 1.9.13 transitivePeerDependencies: - supports-color - solid-automerge@2.0.0(@automerge/automerge-repo@2.6.0-subduction.34)(solid-js@1.9.13): + solid-automerge@2.0.0(@automerge/automerge-repo@2.6.0-subduction.34(supports-color@5.5.0))(solid-js@1.9.13)(supports-color@5.5.0): dependencies: '@automerge/automerge-repo': 2.6.0-subduction.34(supports-color@5.5.0) '@solid-primitives/utils': 6.4.1(solid-js@1.9.13) - cabbages: 0.2.8 + cabbages: 0.2.8(supports-color@5.5.0) solid-js: 1.9.13 transitivePeerDependencies: - supports-color @@ -11100,7 +11112,7 @@ snapshots: dependencies: '@automerge/automerge-repo': 2.6.0-subduction.39 '@solid-primitives/utils': 6.4.1(solid-js@1.9.13) - cabbages: 0.2.8 + cabbages: 0.2.8(supports-color@5.5.0) solid-js: 1.9.13 transitivePeerDependencies: - supports-color diff --git a/sideboard/package.json b/sideboard/package.json index d09ca31c..0064662b 100644 --- a/sideboard/package.json +++ b/sideboard/package.json @@ -32,6 +32,7 @@ "@types/debug": "^4.1.12", "debug": "^4.4.3", "solid-automerge": "^2.0.0", + "lucide-solid": "^1.23.0", "solid-js": "^1.9.9" }, "devDependencies": { diff --git a/sideboard/src/index.css b/sideboard/src/index.css index d90909f7..e2871316 100644 --- a/sideboard/src/index.css +++ b/sideboard/src/index.css @@ -415,6 +415,13 @@ button { } } +.document-list-item__icon { + flex: none; + align-self: center; + margin-right: 8px; + color: var(--placeholder-line); +} + .document-list-item__name { overflow: hidden; text-overflow: ellipsis; diff --git a/sideboard/src/sideboard/document-list/datatype-icon.tsx b/sideboard/src/sideboard/document-list/datatype-icon.tsx new file mode 100644 index 00000000..9c557cfa --- /dev/null +++ b/sideboard/src/sideboard/document-list/datatype-icon.tsx @@ -0,0 +1,205 @@ +import { + Activity, + ArrowLeft, + ArrowLeftRight, + ArrowRightLeft, + ArrowUpDown, + Backpack, + BookOpen, + Box, + Cable, + Calendar, + Cat, + ChartSpline, + CheckSquare, + CheckSquare2, + CircleDot, + CirclePlus, + CircuitBoard, + Clapperboard, + ClipboardList, + Clock, + Cpu, + Crosshair, + Database, + Dices, + Dumbbell, + Edit, + Eraser, + Eye, + File, + FileEdit, + FilePlus, + FileText, + Film, + Folder, + FolderOpen, + GitBranch, + Glasses, + Grid3x3, + Hash, + History, + Home, + Kanban, + Key, + Layers, + Layout, + LayoutGrid, + Library, + List, + ListChecks, + ListTodo, + MessageCircle, + MessageSquare, + Move, + Music, + Notebook, + Paintbrush, + Palette, + PenLine, + Play, + Plus, + Repeat, + Search, + Settings, + Sheet, + ShieldCheck, + Shuffle, + Sigma, + Sparkles, + Square, + Tag, + Target, + Trash, + Trash2, + TrendingUp, + User, + UserCircle, + Users, + Video, + Wifi, + Zap, + type LucideIcon, +} from "lucide-solid"; +import { Dynamic } from "solid-js/web"; +import { useDatatypeDescription, type MaybeAccessor } from "../lib/solid-plugins.ts"; + +// A curated subset of lucide icons, covering every `icon` currently declared +// by datatypes/tools across patchwork-base and patchwork-tools (plus a +// generic fallback). Named imports keep this tree-shakeable — unlike +// `import * as icons from "lucide-solid"`, which pulls all ~1500 icons into +// the bundle. Datatypes with an icon name outside this set (new, third-party, +// or renamed upstream) just render the fallback rather than failing. +const KNOWN_ICONS: Record = { + Activity, + ArrowLeft, + ArrowLeftRight, + ArrowRightLeft, + ArrowUpDown, + Backpack, + BookOpen, + Box, + Cable, + Calendar, + Cat, + ChartSpline, + CheckSquare, + CheckSquare2, + CircleDot, + CirclePlus, + CircuitBoard, + Clapperboard, + ClipboardList, + Clock, + Cpu, + Crosshair, + Database, + Dices, + Dumbbell, + Edit, + Eraser, + Eye, + File, + FileEdit, + FilePlus, + FileText, + Film, + Folder, + FolderOpen, + GitBranch, + Glasses, + Grid3x3, + Hash, + History, + Home, + Kanban, + Key, + Layers, + Layout, + LayoutGrid, + Library, + List, + ListChecks, + ListTodo, + MessageCircle, + MessageSquare, + Move, + Music, + Notebook, + Paintbrush, + Palette, + PenLine, + Play, + Plus, + Repeat, + Search, + Settings, + Sheet, + ShieldCheck, + Shuffle, + Sigma, + Sparkles, + Square, + Tag, + Target, + Trash, + Trash2, + TrendingUp, + User, + UserCircle, + Users, + Video, + Wifi, + Zap, +}; + +const FALLBACK_ICON = File; + +function resolveIcon(name: string | undefined): LucideIcon { + if (!name) return FALLBACK_ICON; + return ( + KNOWN_ICONS[name] ?? + KNOWN_ICONS[name[0].toUpperCase() + name.slice(1)] ?? + FALLBACK_ICON + ); +} + +/** + * Renders the icon a document's datatype registered itself with (the + * `icon` field of its `patchwork:datatype` plugin description, a lucide + * icon name e.g. "FileText"). Falls back to a generic file icon for + * datatypes with no icon, or an icon name outside our curated set. + */ +export function DatatypeIcon(props: { type: MaybeAccessor }) { + const datatype = useDatatypeDescription(props.type); + const icon = () => resolveIcon(datatype()?.icon); + + return ( +