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

Commit b426895

Browse files
committed
feat(button): variant styles
1 parent dde1b26 commit b426895

File tree

10 files changed

+259
-170
lines changed

10 files changed

+259
-170
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"@babel/preset-env": "^7.6.3",
1818
"@styled-system/should-forward-prop": "^5.1.2",
1919
"@vue/composition-api": "^0.3.2",
20+
"color": "^3.1.2",
2021
"core-js": "^2.6.5",
2122
"css-loader": "^3.2.0",
2223
"esm": "^3.2.25",

src/App.vue

+7-5
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
d="flex"
88
justify-content="center"
99
align-items="center"
10-
bg="gray.100"
10+
bg="gray.50"
1111
>
12-
<Button @click="alert">
13-
I am a button
14-
</Button>
12+
<Button @click="alert" mx="3" variant-color="blue">Solid</Button>
13+
<Button variant="outline" mx="3" variant-color="blue" @click="alert">Outlined</Button>
14+
<Button variant="ghost" mx="3" variant-color="blue" @click="alert">Ghost</Button>
15+
<Button variant="flat" mx="3" variant-color="blue" @click="alert">Flat</Button>
16+
<Button variant="link" mx="3" variant-color="blue" @click="alert">Link</Button>
1517
</Box>
1618
</theme-provider>
1719
</template>
@@ -40,7 +42,7 @@ export default {
4042
this.element = !this.element
4143
},
4244
alert () {
43-
alert('clicked')
45+
console.log('button clicked')
4446
}
4547
}
4648
}

src/components/Button/index.js

+13-11
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import PseudoBox from '../PseudoBox'
22
import styleProps from '../../lib/config/props'
3+
import { cleanProps } from '../../lib/utils'
4+
import createButtonStyles from './styles'
35

4-
let generatedProps = {
5-
lineHeight: '3rem'
6-
}
76
/**
87
* @description The Button component is an accessible rich component that does what a button does :)
98
*/
@@ -26,13 +25,13 @@ export default {
2625
type: String,
2726
default: 'primary',
2827
validator: (value) =>
29-
value.match(/^(primary|secondary|success|warning|danger|dark)$/)
28+
value.match(/^(primary|secondary|success|warning|danger)$/)
3029
},
3130
variant: {
3231
type: String,
3332
default: 'solid',
3433
validator: (value) =>
35-
value.match(/^(solid|outlined|ghost|flat|link)$/)
34+
value.match(/^(solid|outline|ghost|flat|link)$/)
3635
},
3736
variantColor: {
3837
type: [String, Array],
@@ -75,22 +74,25 @@ export default {
7574
...styleProps
7675
},
7776
render (h) {
77+
const buttonStyles = createButtonStyles({
78+
color: this.variantColor || this.cast,
79+
variant: this.variant,
80+
theme: this.$theme,
81+
colorMode: this.$colorMode,
82+
size: this.size || 'md'
83+
})
7884
return h(PseudoBox, {
7985
props: {
8086
as: this.as,
81-
p: '3',
8287
outline: 'none',
8388
cursor: 'pointer',
8489
fontSize: 'md',
8590
fontWeight: '700',
8691
border: 'none',
8792
transition: 'all 0.2s ease-in',
8893
rounded: 'md',
89-
_focus: {
90-
outline: 'none',
91-
boxShadow: 'outline'
92-
},
93-
...generatedProps
94+
...buttonStyles,
95+
...cleanProps(this.$props)
9496
},
9597
attrs: {
9698
type: this.type,

src/components/Button/styles.js

+208-41
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,229 @@
1-
import styled from 'vue-styled-components'
2-
// import { colors } from '../../lib/theme'
1+
import { addOpacity } from '../../lib/utils'
2+
const baseStyles = {
3+
display: 'inline-flex',
4+
appearance: 'none',
5+
alignItems: 'center',
6+
justifyContent: 'center',
7+
transition: 'all 250ms',
8+
userSelect: 'none',
9+
position: 'relative',
10+
whiteSpace: 'nowrap',
11+
verticalAlign: 'middle',
12+
lineHeight: '1.2',
13+
outline: 'none'
14+
}
315

4-
const buttonProps = {
5-
variant: String
16+
/**
17+
* Size values
18+
*/
19+
const sizes = {
20+
lg: {
21+
height: 12,
22+
minWidth: 12,
23+
fontSize: 'lg',
24+
px: 6,
25+
py: 4
26+
},
27+
md: {
28+
height: 10,
29+
minWidth: 10,
30+
fontSize: 'md',
31+
px: 4,
32+
py: 3
33+
},
34+
sm: {
35+
height: 8,
36+
minWidth: 8,
37+
fontSize: 'sm',
38+
px: 3,
39+
py: 2
40+
},
41+
xs: {
42+
height: 6,
43+
minWidth: 6,
44+
fontSize: 'xs',
45+
px: 2,
46+
py: 1
47+
}
648
}
749

850
/**
9-
* @description Determines style colors for solid variant
10-
* @param {{color:String, colorMode:String, _theme:Object }} params
51+
* @description Determines size props
52+
* @param {Object} param0 Props object
53+
* @returns {Object} Size style props
1154
*/
12-
const solidVariantProps = ({ color, colorMode = 'light', _theme }) => {
55+
const sizeProps = ({ size }) => sizes[size]
56+
57+
/**
58+
* @description Get solid button style values
59+
* @param {Object} props - Style props object
60+
* @returns {Object} - Solid styles object
61+
*/
62+
const getSolidStyles = ({ color, colorMode }) => {
1363
let style = {
1464
light: {
1565
bg: `${color}.400`,
16-
color: 'white',
66+
color: `${color}.50`,
1767
_hover: {
18-
bg: `${color}.600`
68+
bg: `${color}.500`
1969
},
2070
_active: {
21-
bg: `${color}.700`
71+
bg: `${color}.600`
2272
}
2373
}
2474
}
2575
return style[colorMode]
2676
}
2777

2878
/**
29-
* @description Generates styled for variants
30-
* @param {Object} props
31-
* @returns {Object} Variant styles object
79+
* @description Get ghost button style values
80+
* @param {Object} props - Style Props
81+
* @returns {Object} - Ghost styles object
82+
*/
83+
const getGhostStyles = ({ color, colorMode, theme }) => {
84+
const _theme = theme()
85+
const _color = _theme.colors[color] && _theme.colors[color][200]
86+
let result = {
87+
light: {
88+
color: `${color}.400`,
89+
bg: `${color}.50`,
90+
_hover: {
91+
bg: `${color}.100`
92+
},
93+
_active: {
94+
bg: `${color}.200`
95+
}
96+
},
97+
dark: {
98+
color: `${color}.200`,
99+
bg: 'transparent',
100+
_hover: {
101+
bg: addOpacity(_color, 0.12)
102+
},
103+
_active: {
104+
bg: addOpacity(_color, 0.24)
105+
}
106+
}
107+
}
108+
return result[colorMode]
109+
}
110+
111+
/**
112+
* @description Get flat button style values
113+
* @param {Object} props - Style Props
114+
* @returns {Object} - Ghost styles object
115+
*/
116+
const getFlatStyles = ({ color, colorMode, theme }) => {
117+
const _theme = theme()
118+
const _color = _theme.colors[color] && _theme.colors[color][200]
119+
let result = {
120+
light: {
121+
color: `${color}.400`,
122+
bg: 'transparent',
123+
_hover: {
124+
bg: `${color}.50`
125+
},
126+
_active: {
127+
bg: `${color}.100`
128+
}
129+
},
130+
dark: {
131+
color: `${color}.200`,
132+
bg: 'transparent',
133+
_hover: {
134+
bg: addOpacity(_color, 0.12)
135+
},
136+
_active: {
137+
bg: addOpacity(_color, 0.24)
138+
}
139+
}
140+
}
141+
return result[colorMode]
142+
}
143+
144+
/**
145+
* @description Get outline button style values
146+
* @param {Object} props - Style props object
147+
* @returns {Object} - Solid styles object
148+
*/
149+
const getOutlineStyles = props => {
150+
const { color, colorMode } = props
151+
const borderColor = { light: 'gray.200', dark: 'whiteAlpha.300' }
152+
153+
return {
154+
border: '1px',
155+
borderColor: color === 'gray' ? borderColor[colorMode] : 'current',
156+
...getFlatStyles(props)
157+
}
158+
}
159+
160+
/**
161+
* @description Get link button style values
162+
* @param {Object} props - Style props object
163+
* @returns {Object} - Solid styles object
164+
*/
165+
const getLinkStyles = ({ color, colorMode }) => {
166+
const _color = { light: `${color}.400`, dark: `${color}.200` }
167+
const _activeColor = { light: `${color}.700`, dark: `${color}.500` }
168+
return {
169+
p: 0,
170+
height: 'auto',
171+
lineHeight: 'normal',
172+
color: _color[colorMode],
173+
_hover: {
174+
textDecoration: 'underline'
175+
},
176+
_active: {
177+
color: _activeColor[colorMode]
178+
}
179+
}
180+
}
181+
182+
/**
183+
* @description Determines styles for a given v
184+
* @param {Object} props - Props Object
185+
* @returns {Object} - Variant styles object
32186
*/
33-
const variantProps = props => {
187+
const getVariantStyles = (props) => {
34188
switch (props.variant) {
35189
case 'solid':
36-
return solidVariantProps(props)
37-
}
38-
}
39-
40-
// const baseProps = {
41-
// display: 'inline-flex',
42-
// appearance: 'none',
43-
// alignItems: 'center',
44-
// justifyContent: 'center',
45-
// transition: 'all 250ms',
46-
// userSelect: 'none',
47-
// position: 'relative',
48-
// whiteSpace: 'nowrap',
49-
// verticalAlign: 'middle',
50-
// lineHeight: '1.2',
51-
// outline: 'none'
52-
// }
53-
54-
const Button = styled('button', buttonProps)`
55-
font-size: 1em;
56-
text-align: center;
57-
padding: 10px 15px;
58-
border-radius: ${({ radius }) => radius ? '6px' : null};
59-
${(props) => variantProps(props)}
60-
`
61-
62-
export default Button
190+
return getSolidStyles(props)
191+
case 'outline':
192+
return getOutlineStyles(props)
193+
case 'ghost':
194+
return getGhostStyles(props)
195+
case 'flat':
196+
return getFlatStyles(props)
197+
case 'link':
198+
return getLinkStyles(props)
199+
default:
200+
return {}
201+
}
202+
}
203+
204+
/**
205+
* Button focus styles
206+
*/
207+
const focusStyles = {
208+
_focus: {
209+
outline: 'none',
210+
boxShadow: 'outline'
211+
}
212+
}
213+
214+
/**
215+
* @description Generates Button styles based on passed variant props and theme colors.
216+
* @param {{color: String|Array<String>, theme: Object, colorMode: String, size: String|Array<String>}} props - Style props object
217+
* @returns {Object} Style object to be passed to styled component
218+
* @todo Pass the `theme` from the ThemeProvider context. Will need to create a context provider for theme.
219+
*/
220+
const createButtonStyles = (props) => {
221+
return {
222+
...baseStyles,
223+
...focusStyles,
224+
...sizeProps(props),
225+
...getVariantStyles(props)
226+
}
227+
}
228+
229+
export default createButtonStyles

src/lib/config/props/props.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export const config = {
113113
property: 'border-bottom',
114114
scale: 'borders'
115115
},
116-
textDecoration: { property: 'textDecoration' },
116+
textDecoration: true,
117117
overflowX: true,
118118
overflowY: true,
119119
textTransform: true,

src/lib/theme/colors.js

+7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ const colors = {
33
current: 'currentColor',
44
black: '#000',
55
white: '#fff',
6+
primary: '#1a72ff',
7+
secondary: '#7425f3',
8+
tertiary: '#fe9e4d',
9+
success: '#3ea76a',
10+
warning: '#ffc61a',
11+
error: '#dd3b4b',
12+
613
whiteAlpha: {
714
50: 'rgba(255, 255, 255, 0.04)',
815
100: 'rgba(255, 255, 255, 0.06)',

0 commit comments

Comments
 (0)