IconRef: add url kind, point registered kinds at palette assets
User pointed at the palette's PNG icons in the bottom toolbar — they
expected the inspector title to use the same artwork, not the iconify
lucide glyphs. Different visual style.
- IconRef gains `{ kind: 'url'; src: string }`. Plain `<img>` render
in ParametricInspector (no next/image — the inspector is
`'use client'`).
- All currently-registered kinds switched to URL refs matching their
palette `iconSrc`:
fence → /icons/fence.png
slab → /icons/floor.png
ceiling → /icons/ceiling.png
wall → /icons/wall.png
spawn → /icons/site.png
shelf → /icons/column.png (placeholder, same as palette)
- Kind-owned panels (slab/ceiling) already pass URL strings to their
own PanelWrapper; unchanged.
Door/window/item will get URL refs when they register at Stage A.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
8c2b03f99b
commit
6a1d853dd8
@@ -230,6 +230,10 @@ export type IconRef =
|
|||||||
/** Iconify identifier, e.g. `lucide:square`. Matches the @iconify-react
|
/** Iconify identifier, e.g. `lucide:square`. Matches the @iconify-react
|
||||||
* setup the editor app already uses for tool icons. */
|
* setup the editor app already uses for tool icons. */
|
||||||
| { kind: 'iconify'; name: string }
|
| { kind: 'iconify'; name: string }
|
||||||
|
/** URL path to a raster or vector asset (PNG/SVG/...). Matches the
|
||||||
|
* palette's PNG/SVG assets — use this to share the same artwork
|
||||||
|
* between the bottom toolbar and the inspector title. */
|
||||||
|
| { kind: 'url'; src: string }
|
||||||
/** Inline SVG path data. Use for asset packs or plugins that want a custom
|
/** Inline SVG path data. Use for asset packs or plugins that want a custom
|
||||||
* mark without contributing a React component. */
|
* mark without contributing a React component. */
|
||||||
| { kind: 'svg'; viewBox: string; path: string }
|
| { kind: 'svg'; viewBox: string; path: string }
|
||||||
|
|||||||
@@ -137,6 +137,12 @@ export function ParametricInspector() {
|
|||||||
|
|
||||||
function renderIcon(ref: IconRef | undefined): React.ReactNode | undefined {
|
function renderIcon(ref: IconRef | undefined): React.ReactNode | undefined {
|
||||||
if (!ref) return undefined
|
if (!ref) return undefined
|
||||||
|
if (ref.kind === 'url') {
|
||||||
|
// Plain <img> here so the inspector doesn't pull in next/image's
|
||||||
|
// server-only requirements (the file is `'use client'`). Same
|
||||||
|
// 16x16 box the legacy panels use.
|
||||||
|
return <img alt="" className="h-4 w-4 shrink-0 object-contain" src={ref.src} />
|
||||||
|
}
|
||||||
if (ref.kind === 'iconify') {
|
if (ref.kind === 'iconify') {
|
||||||
return <Icon height={16} icon={ref.name} width={16} />
|
return <Icon height={16} icon={ref.name} width={16} />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export const ceilingDefinition: NodeDefinition<typeof CeilingNode> = {
|
|||||||
presentation: {
|
presentation: {
|
||||||
label: 'Ceiling',
|
label: 'Ceiling',
|
||||||
description: 'A polygon-bounded ceiling surface that hosts ceiling-mounted items.',
|
description: 'A polygon-bounded ceiling surface that hosts ceiling-mounted items.',
|
||||||
icon: { kind: 'iconify', name: 'lucide:square-dashed' },
|
icon: { kind: 'url', src: '/icons/ceiling.png' },
|
||||||
paletteSection: 'structure',
|
paletteSection: 'structure',
|
||||||
paletteOrder: 40,
|
paletteOrder: 40,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ export const fenceDefinition: NodeDefinition<typeof FenceNode> = {
|
|||||||
presentation: {
|
presentation: {
|
||||||
label: 'Fence',
|
label: 'Fence',
|
||||||
description: 'A straight or curved fence segment with configurable posts and infill.',
|
description: 'A straight or curved fence segment with configurable posts and infill.',
|
||||||
icon: { kind: 'iconify', name: 'lucide:fence' },
|
icon: { kind: 'url', src: '/icons/fence.png' },
|
||||||
paletteSection: 'structure',
|
paletteSection: 'structure',
|
||||||
paletteOrder: 20,
|
paletteOrder: 20,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export const shelfDefinition: NodeDefinition<typeof ShelfNode> = {
|
|||||||
presentation: {
|
presentation: {
|
||||||
label: 'Shelf',
|
label: 'Shelf',
|
||||||
description: 'A horizontal surface for stacking other items.',
|
description: 'A horizontal surface for stacking other items.',
|
||||||
icon: { kind: 'iconify', name: 'lucide:layers' },
|
icon: { kind: 'url', src: '/icons/column.png' },
|
||||||
paletteSection: 'structure',
|
paletteSection: 'structure',
|
||||||
paletteOrder: 50,
|
paletteOrder: 50,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export const slabDefinition: NodeDefinition<typeof SlabNode> = {
|
|||||||
presentation: {
|
presentation: {
|
||||||
label: 'Slab',
|
label: 'Slab',
|
||||||
description: 'A polygon-bounded floor surface that hosts items on top.',
|
description: 'A polygon-bounded floor surface that hosts items on top.',
|
||||||
icon: { kind: 'iconify', name: 'lucide:square' },
|
icon: { kind: 'url', src: '/icons/floor.png' },
|
||||||
paletteSection: 'structure',
|
paletteSection: 'structure',
|
||||||
paletteOrder: 30,
|
paletteOrder: 30,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export const spawnDefinition: NodeDefinition<typeof SpawnNode> = {
|
|||||||
presentation: {
|
presentation: {
|
||||||
label: 'Spawn Point',
|
label: 'Spawn Point',
|
||||||
description: 'Player or camera origin within a level. One per level.',
|
description: 'Player or camera origin within a level. One per level.',
|
||||||
icon: { kind: 'iconify', name: 'lucide:flag' },
|
icon: { kind: 'url', src: '/icons/site.png' },
|
||||||
paletteSection: 'structure',
|
paletteSection: 'structure',
|
||||||
paletteOrder: 90, // bottom of structure list — matches legacy palette order
|
paletteOrder: 90, // bottom of structure list — matches legacy palette order
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ export const wallDefinition: NodeDefinition<typeof WallNode> = {
|
|||||||
presentation: {
|
presentation: {
|
||||||
label: 'Wall',
|
label: 'Wall',
|
||||||
description: 'A straight or curved wall segment. Hosts doors, windows, and wall-mounted items.',
|
description: 'A straight or curved wall segment. Hosts doors, windows, and wall-mounted items.',
|
||||||
icon: { kind: 'iconify', name: 'lucide:wall' },
|
icon: { kind: 'url', src: '/icons/wall.png' },
|
||||||
paletteSection: 'structure',
|
paletteSection: 'structure',
|
||||||
paletteOrder: 10,
|
paletteOrder: 10,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user