Skip to content
This repository was archived by the owner on Sep 20, 2024. It is now read-only.

Commit 87d4eba

Browse files
committed
feat(button): button with icon
1 parent c95f9d1 commit 87d4eba

File tree

2 files changed

+96
-6
lines changed

2 files changed

+96
-6
lines changed

src/App.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<theme-provider :theme="theme" :icons="$kiwi.icons">
33
<div class="root">
4-
<Button variant-color="blue" @click="setLoading" :is-loading="loading"> Button </Button>
4+
<Button variant-color="blue" left-icon="coffee" @click="setLoading" :is-loading="loading"> Buy Coffee </Button>
55
</div>
66
</theme-provider>
77
</template>

src/components/Button/index.js

+95-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,84 @@
1-
import PseudoBox from '../PseudoBox'
21
import styleProps from '../../lib/config/props'
32
import { forwardProps } from '../../lib/utils'
43
import createButtonStyles from './button.styles'
5-
import { Spinner } from '../../lib/core'
4+
import { Box, PseudoBox, Spinner, Icon } from '../../lib/core'
5+
6+
/**
7+
* Icon component in button.
8+
*/
9+
const sizes = {
10+
xs: {
11+
w: '0.75rem',
12+
h: '0.75rem'
13+
},
14+
sm: {
15+
w: '1rem',
16+
h: '1rem'
17+
},
18+
md: {
19+
w: '1.5rem',
20+
h: '1.5rem'
21+
},
22+
lg: {
23+
w: '2rem',
24+
h: '2rem'
25+
},
26+
xl: {
27+
w: '3rem',
28+
h: '3rem'
29+
}
30+
}
31+
32+
const createCustomSize = (size) => {
33+
return {
34+
w: size,
35+
h: size
36+
}
37+
}
38+
39+
const setSizes = (props) => {
40+
return sizes[props.size] || createCustomSize(props.size)
41+
}
42+
43+
const ButtonIcon = {
44+
name: 'ButtonIcon',
45+
props: {
46+
icon: {
47+
type: [String, Object]
48+
},
49+
size: {
50+
type: [String, Number]
51+
},
52+
...styleProps
53+
},
54+
render (h) {
55+
if (typeof this.icon === 'string') {
56+
return h(Icon, {
57+
props: {
58+
focusable: false,
59+
name: this.icon,
60+
color: 'currentColor',
61+
mb: '-2px',
62+
...setSizes(this.$props),
63+
...forwardProps(this.$props)
64+
}
65+
})
66+
} else {
67+
return h(Box, {
68+
props: {
69+
as: this.icon,
70+
focusable: false,
71+
color: 'currentColor',
72+
mb: '-2px',
73+
...setSizes(this.$props)
74+
},
75+
attrs: {
76+
'data-custom-icon': true
77+
}
78+
})
79+
}
80+
}
81+
}
682

783
/**
884
* @description The Button component is an accessible rich component that does what a button does :)
@@ -61,7 +137,7 @@ export default {
61137
validator: (value) => typeof value === 'string'
62138
},
63139
iconSpacing: {
64-
type: String,
140+
type: [String, Number],
65141
default: 2,
66142
validator: (value) => value >= 0
67143
},
@@ -116,7 +192,14 @@ export default {
116192
click: ($event) => this.$emit('click', $event)
117193
}
118194
}, [
119-
this.leftIcon && !this.isLoading && h(Spinner),
195+
this.leftIcon && !this.isLoading && h(ButtonIcon, {
196+
props: {
197+
ml: -1,
198+
mr: this.iconSpacing,
199+
icon: this.leftIcon,
200+
size: '1em'
201+
}
202+
}),
120203
this.isLoading && h(Spinner, {
121204
props: {
122205
position: this.loadingText ? 'relative' : 'absolute',
@@ -127,7 +210,14 @@ export default {
127210
}
128211
}),
129212
this.isLoading ? this.loadingText : this.$slots.default,
130-
this.rightIcon && !this.isLoading && h(Spinner)
213+
this.rightIcon && !this.isLoading && h(ButtonIcon, {
214+
props: {
215+
mr: -1,
216+
ml: this.iconSpacing,
217+
icon: this.rightIcon,
218+
size: '1em'
219+
}
220+
})
131221
])
132222
}
133223
}

0 commit comments

Comments
 (0)