Icon
Display icons from the Lucide icon library
Examples
Basic Icon
Icon Sizes
Colored Icons
Schema
interface IconSchema {
type: 'icon';
icon: string; // Lucide glyph name (kebab-case), REQUIRED
size?: number | 'sm' | 'md' | 'lg' | 'xl';
color?: string; // Tailwind color class
className?: string;
}The glyph is named by icon:
{ "type": "icon", "icon": "check" }name is identity, not the glyph
name is the SDUI identity key every node carries, alongside id. It is not
read as a glyph name on ui:icon, and writing one there renders no icon:
{ "type": "icon", "id": "save_icon", "name": "save_icon" }That node is refused by IconSchema — with a message naming this rename —
and, if it reaches the renderer unvalidated, draws a dashed-square placeholder
with an accessible name saying which icon failed, rather than rendering nothing.
There is deliberately no fallback from icon to name: a key that means
"identity" sometimes and "glyph" other times, depending on whether a lucide
lookup happened to hit, is the ambiguity this contract removes.
Migrating stored metadata
Metadata authored before this change names its glyph with name. Convert it in
bulk — once, at the source — with the converter shipped for it:
import { migrateIconNodeKeys } from '@object-ui/types';
declare const storedPage: unknown;
declare function save(document: unknown): Promise<void>;
const { document, converted, warnings } = migrateIconNodeKeys(storedPage);
console.log(`converted ${converted} icon node(s)`);
if (warnings.length) console.warn(warnings.map((w) => w.message).join('\n'));
if (document !== storedPage) await save(document);It walks the whole document, lifts name to icon on every icon node, and
reports rather than guesses for the two cases it will not touch: a node that
already declares both keys (icon wins; name stays the identity it is), and a
node that names no glyph at all.