11<script lang="ts">
2- import { defineComponent , computed , type PropType } from ' vue'
3- import icons , { DEPRECATED_ICONS } from ' ./icons'
4- import { type IconSize , type IconIdentifier , type AnyIconName } from ' ./icons/types'
5-
62export type {
73 IconSize ,
84 IconName ,
@@ -17,79 +13,82 @@ export type {
1713 LgIconId ,
1814 OtherIconId
1915} from ' ./icons/types'
16+ </script >
17+
18+ <script setup lang="ts">
19+ import { computed } from ' vue'
20+ import icons , { DEPRECATED_ICONS } from ' ./icons'
21+ import { type IconSize , type IconIdentifier , type AnyIconName } from ' ./icons/types'
2022
21- export default defineComponent ({
22- name: ' AIcon' ,
23- props: {
23+ defineOptions ({
24+ name: ' AIcon'
25+ })
26+
27+ const props = withDefaults (
28+ defineProps <{
2429 /**
25- * Type-safe icon identifier in format "name-size" (e.g., "search-sm", "check-md")
30+ * Type-safe icon identifier in format "name-size" (e.g., "search-sm", "check-md").
2631 * This is the recommended way to specify icons as it enforces valid name+size combinations.
2732 */
28- icon: {
29- type: String as PropType <IconIdentifier >,
30- default: undefined
31- },
33+ icon? : IconIdentifier
3234 /**
33- * @deprecated Use `icon` prop instead (e.g., icon="search-sm")
34- * Icon name in PascalCase (e.g. ArrowDown, Warning) or camelCase (e.g. arrowDown, warning)
35+ * @deprecated Use `icon` prop instead (e.g., icon="search-sm").
36+ * Icon name in PascalCase (e.g. ArrowDown, Warning) or camelCase (e.g. arrowDown, warning).
3537 */
36- name: {
37- type: String as PropType <AnyIconName >,
38- default: undefined
39- },
38+ name? : AnyIconName
4039 /**
41- * @deprecated Use `icon` prop instead (e.g., icon="search-sm")
42- * Icon size - used to set width and height on an `svg` element
40+ * @deprecated Use `icon` prop instead (e.g., icon="search-sm").
41+ * Icon size - used to set width and height on an `svg` element.
4342 */
44- size: {
45- type: String as PropType <IconSize >,
46- default: ' md'
47- }
48- },
49- setup(props ) {
50- const iconComponent = computed (() => {
51- let size: IconSize
52- let name: string
43+ size? : IconSize
44+ }>(),
45+ {
46+ icon: undefined ,
47+ name: undefined ,
48+ size: ' md'
49+ }
50+ )
5351
54- if (props .icon ) {
55- // New format: "search-sm" -> extract size from suffix
56- const lastDash = props .icon .lastIndexOf (' -' )
57- size = props .icon .slice (lastDash + 1 ) as IconSize
58- // Convert kebab-case name to PascalCase: "arrow-left" -> "ArrowLeft"
59- name = props .icon
60- .slice (0 , lastDash )
61- .split (' -' )
62- .map (s => s .charAt (0 ).toUpperCase () + s .slice (1 ))
63- .join (' ' )
64- } else if (props .name ) {
65- // Legacy format
66- size = props .size
67- // Capitalize first letter to handle camelCase input
68- name = props .name .charAt (0 ).toUpperCase () + props .name .slice (1 )
69- } else {
70- console .error (' [Honeycomb] a-icon: either icon or name prop is required' )
71- return null
72- }
52+ const iconComponent = computed (() => {
53+ let size: IconSize
54+ let name: string
7355
74- if (DEPRECATED_ICONS [size ].includes (name )) {
75- console .warn (
76- ` Icon "${name }" in size "${size }" is deprecated and will be removed in the next major version.
77- Use another supported size or alternative icon, see storybook docs https://honeycomb.archilogic.com `
78- )
79- }
56+ if (props .icon ) {
57+ // New format: "search-sm" -> extract size from suffix
58+ const lastDash = props .icon .lastIndexOf (' -' )
59+ size = props .icon .slice (lastDash + 1 ) as IconSize
60+ // Convert kebab-case name to PascalCase: "arrow-left" -> "ArrowLeft"
61+ name = props .icon
62+ .slice (0 , lastDash )
63+ .split (' -' )
64+ .map (s => s .charAt (0 ).toUpperCase () + s .slice (1 ))
65+ .join (' ' )
66+ } else if (props .name ) {
67+ // Legacy format
68+ size = props .size
69+ // Capitalize first letter to handle camelCase input
70+ name = props .name .charAt (0 ).toUpperCase () + props .name .slice (1 )
71+ } else {
72+ console .error (' [Honeycomb] a-icon: either icon or name prop is required' )
73+ return null
74+ }
8075
81- if (icons [size ][name ]) {
82- return icons [size ][name ]
83- } else {
84- console .error (` Icon ${name } of size ${size } does not exist. ` , ' Available icons' , icons )
85- return null
86- }
87- })
76+ if (DEPRECATED_ICONS [size ].includes (name )) {
77+ console .warn (
78+ ` Icon "${name }" in size "${size }" is deprecated and will be removed in the next major version.
79+ Use another supported size or alternative icon, see storybook docs https://honeycomb.archilogic.com `
80+ )
81+ }
8882
89- return { iconComponent }
83+ if (icons [size ][name ]) {
84+ return icons [size ][name ]
85+ } else {
86+ console .error (` Icon ${name } of size ${size } does not exist. ` , ' Available icons' , icons )
87+ return null
9088 }
9189})
9290 </script >
91+
9392<template >
9493 <component :is =" iconComponent" v-if =" iconComponent" aria-hidden class =" flex-shrink-0" />
9594</template >
0 commit comments