Skip to content

Commit cf637c8

Browse files
committed
feat(Button): accept IconIdentifier in icon prop
1 parent 8583007 commit cf637c8

File tree

2 files changed

+22
-9
lines changed

2 files changed

+22
-9
lines changed

src/components/Button.vue

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
import { computed, defineComponent, PropType } from 'vue'
33
import ASpinner from './Spinner.vue'
44
import AIcon from './Icon.vue'
5+
import { type IconIdentifier, type AnyIconName } from './icons/types'
56
67
type ButtonVariant = 'primary' | 'subtle' | 'standard'
78
89
type ButtonSize = 'sm' | 'md' | 'lg' | 'auto'
910
11+
const isIconIdentifier = (str: string): boolean => {
12+
return /-(sm|md|lg|other)$/.test(str)
13+
}
14+
1015
export default defineComponent({
1116
name: 'AButton',
1217
components: { ASpinner, AIcon },
@@ -45,11 +50,11 @@ export default defineComponent({
4550
* deprecated usage: Boolean
4651
* removes horizontal padding, use size `auto` instead
4752
*
48-
* recommended usage: icon name as a String
49-
* the icon size will be inferred from the button size prop
53+
* recommended usage: IconIdentifier (e.g., "search-sm", "check-md")
54+
* or icon name as a String (e.g., "Search") where size is inferred from button size
5055
*/
5156
icon: {
52-
type: [Boolean, String],
57+
type: [Boolean, String] as PropType<boolean | AnyIconName | IconIdentifier>,
5358
default: false
5459
},
5560
/**
@@ -99,9 +104,16 @@ export default defineComponent({
99104
return tagName.value === 'button' && (props.disabled || props.loading)
100105
})
101106
107+
const iconIdentifier = computed(() => {
108+
if (typeof props.icon === 'string' && props.icon.length && isIconIdentifier(props.icon)) {
109+
return props.icon as IconIdentifier
110+
}
111+
return undefined
112+
})
113+
102114
const iconName = computed(() => {
103-
if (typeof props.icon === 'string' && props.icon.length) {
104-
return props.icon as import('./icons/types').AnyIconName
115+
if (typeof props.icon === 'string' && props.icon.length && !isIconIdentifier(props.icon)) {
116+
return props.icon as AnyIconName
105117
}
106118
return undefined
107119
})
@@ -123,6 +135,7 @@ export default defineComponent({
123135
return {
124136
tagName,
125137
isDisabled,
138+
iconIdentifier,
126139
iconName,
127140
iconSize,
128141
ariaLabel
@@ -164,7 +177,10 @@ export default defineComponent({
164177
the value of label prop or an icon
165178
-->
166179
<slot>
167-
<template v-if="!!(iconName && iconSize)">
180+
<template v-if="iconIdentifier">
181+
<a-icon :icon="iconIdentifier"></a-icon>
182+
</template>
183+
<template v-else-if="!!(iconName && iconSize)">
168184
<a-icon :name="iconName" :size="iconSize"></a-icon>
169185
</template>
170186
<template v-else>{{ label }}</template>

src/components/icons/types.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// Auto-generated icon types - do not edit manually
2-
// Run `npm run generate:icon-types` to regenerate
3-
41
export type SmIcon =
52
| 'Ai'
63
| 'Archive'

0 commit comments

Comments
 (0)