Add built-in Lucide icon library for node styling#1777
Open
jkemmererupgrade wants to merge 1 commit into
Open
Conversation
Stores icon selections as symbolic lucide:<name> references rather than data URIs, so config files remain human-readable and the picker can highlight the current selection without reverse-engineering the blob. Resolution happens at render time via two paths: - React components (VertexIcon): useResolvedIconUrl hook backed by React Query (staleTime: Infinity) converts lucide:<name> to a base64 SVG data URI on first use and caches the result. - Cytoscape pipeline (renderNode): getLucideSvgString resolves directly from the lucide-react dynamic-import map, skipping any fetch round-trip. Custom-uploaded icons (data: URIs and plain URLs) are unchanged -- they pass through both resolvers untouched. The new IconPicker component (searchable popover, 8-column grid, 50-icon default window) is wired into NodeStyleDialog alongside the existing file upload button so users can choose a Lucide icon or keep uploading their own. Also fixes a pre-existing lint-staged misconfiguration where the root oxlint --fix task matched vitest.config.ts, which oxlint then ignored (matching its own ignorePatterns), causing exit code 1. The root lint-staged config now mirrors the oxlint ignorePatterns by routing *.config.* files to oxfmt only and restricting oxlint to packages/. Pre-flight: pnpm checks, pnpm test (1738/1738), pnpm coverage all pass. This is Slice 1 of the 3-slice split of aws#1589 per @kmcginnes review.
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds the Lucide icon library as a built-in source for node icons, introducing a searchable picker in the Node Styling panel alongside the existing custom-upload button.
Key architectural decision (per #1774): icon selections are stored as symbolic
lucide:<name>references rather than data URIs. Resolution to a renderable form happens at render time, keeping config and export files human-readable and allowing the picker to highlight the current selection without reverse-engineering a blob.Resolution at render time uses two paths depending on the consumer:
VertexIcon) — a newuseResolvedIconUrlhook backed by React Query (staleTime: Infinity) convertslucide:<name>to a base64 SVG data URI on first use and caches the result per session. Plain URLs anddata:URIs pass through viainitialData, so they render immediately without an async round-trip.renderNode) —getLucideSvgStringresolves the icon directly from thelucide-reactdynamic-import map, skipping any network fetch.Custom-uploaded icons (
data:URIs) are completely unaffected — both resolvers pass them through unchanged.The
IconPickercomponent renders a searchable popover (8-column icon grid, 50-icon default window, type-to-filter). It emits the symboliclucide:<name>ref so NodeStyleDialog stores the portable reference.This commit also fixes a pre-existing lint-staged misconfiguration where the root
oxlint --fixtask matchedvitest.config.ts, which oxlint then silently ignored (per its ownignorePatterns), causing a spurious exit-code 1 on pre-commit. The root lint-staged config now mirrors the oxlint ignore patterns.This is Slice 1 of the 3-slice split of #1589, per @kmcginnes review.
Validation
All four local gates pass:
pnpm run checks— oxlint, oxfmt, and TypeScript type-check all cleanpnpm test— 1738 / 1738 tests pass (45 new tests across 4 new test files)pnpm coverage— all thresholds met; new files have ~100% line coverage (branches floor bumped 44 to 45 by the new branch coverage)pnpm build— production build completes without warningsTo validate the picker manually: open the Node Styling panel for any vertex type, click "Browse", search for an icon name (e.g. "plane"), select it, and confirm the node label updates in the graph view. Re-opening the dialog should show the selected icon highlighted in the grid.
Related Issues
Addresses #1774
Slice 1 of #1589
Check List
pnpm checkspasses with no errors.pnpm testpasses with no failures.docs/features/graph-view.md)