A Lucide icon library package for Vue 3 applications.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Base functionality for rendering SVG icons from data structures. The Icon component provides the foundation for all icon components and enables direct rendering of custom icon data.
The core SVG icon renderer that all individual icon components use internally. Accepts icon data and renders it as a customizable SVG element.
/**
* Core SVG icon renderer component
* Renders SVG icons from IconNode data structures with customizable properties
*/
const Icon: FunctionalComponent<LucideProps & IconProps>;
interface IconProps {
/** SVG element data structure defining the icon's paths and shapes */
iconNode: IconNode;
/** Icon name used for CSS class generation */
name: string;
}
interface LucideProps extends Partial<SVGAttributes> {
/** Icon size in pixels (both width and height), defaults to 24 */
size?: 24 | number;
/** Stroke width for icon lines */
strokeWidth?: number | string;
/** Disable automatic stroke width scaling based on icon size */
absoluteStrokeWidth?: boolean;
/** Kebab-case version of absoluteStrokeWidth */
'absolute-stroke-width'?: boolean;
}
type IconNode = [elementName: string, attrs: Record<string, string>][];Usage Examples:
<template>
<div>
<!-- Basic icon rendering -->
<Icon
:icon-node="heartIcon"
name="heart"
/>
<!-- Customized icon -->
<Icon
:icon-node="starIcon"
name="star"
:size="32"
color="gold"
:stroke-width="2"
/>
<!-- Icon with absolute stroke width -->
<Icon
:icon-node="circleIcon"
name="circle"
:size="48"
:absolute-stroke-width="true"
:stroke-width="1"
/>
<!-- Icon with slots for custom content -->
<Icon
:icon-node="squareIcon"
name="square"
:size="40"
>
<text x="20" y="25" text-anchor="middle" font-size="12">42</text>
</Icon>
</div>
</template>
<script setup>
import { Icon } from "lucide-vue-next";
// Define custom icon data
const heartIcon = [
['path', {
d: 'M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z',
key: 'heartpath'
}]
];
const starIcon = [
['polygon', {
points: '12,2 15.09,8.26 22,9.27 17,14.14 18.18,21.02 12,17.77 5.82,21.02 7,14.14 2,9.27 8.91,8.26',
key: 'starpath'
}]
];
const circleIcon = [
['circle', { cx: '12', cy: '12', r: '10', key: 'circlepath' }]
];
const squareIcon = [
['rect', { width: '18', height: '18', x: '3', y: '3', rx: '2', key: 'squarepath' }]
];
</script>All icons rendered through the Icon component receive consistent default SVG attributes that can be overridden via props.
// Default attributes applied to all rendered icons:
const defaultAttributes = {
xmlns: 'http://www.w3.org/2000/svg',
width: 24,
height: 24,
viewBox: '0 0 24 24',
fill: 'none',
stroke: 'currentColor',
'stroke-width': 2,
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
};The Icon component automatically generates CSS classes for styling and identification:
// Generated CSS classes:
// - 'lucide' (always present)
// - 'lucide-{name}-icon' (e.g., 'lucide-heart-icon')
// - 'lucide-{kebab-case-name}' (e.g., 'lucide-heart')
// - Any additional classes passed via the 'class' propCSS Class Examples:
<template>
<!-- This Icon generates classes: lucide, lucide-heart-icon, lucide-heart, custom-heart -->
<Icon
:icon-node="heartIcon"
name="heart"
class="custom-heart"
/>
<!-- This Icon generates classes: lucide, lucide-arrow-up-icon, lucide-arrow-up -->
<Icon
:icon-node="arrowUpIcon"
name="arrowUp"
/>
</template>The Icon component provides intelligent stroke width scaling based on icon size, with options to disable this behavior.
// Automatic scaling (default behavior):
// strokeWidth is scaled proportionally with icon size
// Formula: (strokeWidth * 24) / size
// Absolute stroke width (disabled scaling):
// strokeWidth remains constant regardless of icon size
// Enabled via absoluteStrokeWidth or 'absolute-stroke-width' propsStroke Width Examples:
<template>
<div>
<!-- Scaled stroke width (default) -->
<Icon :icon-node="lineIcon" name="line" :size="48" :stroke-width="2" />
<!-- Results in actual stroke-width="1" (2 * 24 / 48) -->
<!-- Absolute stroke width -->
<Icon
:icon-node="lineIcon"
name="line"
:size="48"
:stroke-width="2"
:absolute-stroke-width="true"
/>
<!-- Results in actual stroke-width="2" -->
<!-- Kebab-case syntax -->
<Icon
:icon-node="lineIcon"
name="line"
:size="48"
stroke-width="2"
absolute-stroke-width
/>
<!-- Also results in actual stroke-width="2" -->
</div>
</template>The Icon component supports Vue slots for adding custom content inside the SVG element.
<template>
<Icon :icon-node="backgroundIcon" name="background">
<!-- Custom content rendered inside the SVG -->
<text x="12" y="16" text-anchor="middle" font-size="8" fill="white">
Badge
</text>
<circle cx="18" cy="6" r="3" fill="red" />
</Icon>
</template>