You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2.0 KiB
2.0 KiB
Icons
Always use the project's configured iconLibrary for imports. Check the iconLibrary field from project context: lucide → @lucide/vue, tabler → @tabler/icons-vue, etc. Never assume @lucide/vue.
Icons in Button use data-icon attribute
Add data-icon="inline-start" (prefix) or data-icon="inline-end" (suffix) to the icon. No sizing classes on the icon.
Incorrect:
<Button>
<SearchIcon class="mr-2 size-4" />
Search
</Button>
Correct:
<Button>
<SearchIcon data-icon="inline-start"/>
Search
</Button>
<Button>
Next
<ArrowRightIcon data-icon="inline-end"/>
</Button>
No sizing classes on icons inside components
Components handle icon sizing via CSS. Don't add size-4, w-4 h-4, or other sizing classes to icons inside Button, DropdownMenuItem, Alert, Sidebar*, or other shadcn components. Unless the user explicitly asks for custom icon sizes.
Incorrect:
<Button>
<SearchIcon class="size-4" data-icon="inline-start" />
Search
</Button>
<DropdownMenuItem>
<SettingsIcon class="mr-2 size-4" />
Settings
</DropdownMenuItem>
Correct:
<Button>
<SearchIcon data-icon="inline-start" />
Search
</Button>
<DropdownMenuItem>
<SettingsIcon />
Settings
</DropdownMenuItem>
Pass icons as component objects, not string keys
Use :icon="CheckIcon", not a string key to a lookup map.
Incorrect:
<script setup lang="ts">
const iconMap = {
check: CheckIcon,
alert: AlertIcon,
}
defineProps({
icon: String
})
</script>
<template>
<component :is="iconMap[icon]" />
</template>
Correct:
<script setup lang="ts">
// Import from the project's configured iconLibrary (e.g. @lucide/vue, @tabler/icons-vue).
import { CheckIcon } from "@lucide/vue"
defineProps({
icon: Object // Or Component
})
</script>
<template>
<component :is="icon" />
</template>
<!-- Usage -->
<StatusBadge :icon="CheckIcon" />