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

Commit 72b86ee

Browse files
committed
feat(alert): added alert and alert icon component
1 parent ec0b20b commit 72b86ee

File tree

13 files changed

+312
-12
lines changed

13 files changed

+312
-12
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ yarn serve
3030
- [x] Observe theme and set it dynamically in javascript with ease.
3131
- [x] Provide icons API for icons component
3232
- [x] Accessibility (Focus) Styling
33+
- [ ] Make `createContext` API for Kiwi
34+
- [ ] This component should return provider and corresponding consumer. Should be used for component creation.
3335
- [ ] Setup NPM distribution
3436
- [ ] Set up type system for components with Typescript
3537

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"register-service-worker": "^1.6.2",
2929
"style-loader": "^1.0.0",
3030
"vue": "^2.6.10",
31+
"vue-create-context": "^1.1.0",
3132
"vue-router": "^3.0.3",
3233
"vue-styled-components": "git+https://github.com/codebender828/vue-styled-components.git"
3334
},

src/App.vue

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
11
<template>
22
<theme-provider :theme="theme" :icons="$kiwi.icons">
33
<div class="root">
4-
<IconButton _aria-label="Search" variant-color="blue" mx="3" size="md" icon="star" />
5-
<KText as="kbd">Text Component</KText>
4+
<div class="wrapper">
5+
<Alert mb="1">
6+
<AlertIcon />
7+
Chakra is going live on August 30th. Get ready!
8+
</Alert>
9+
</div>
610
</div>
711
</theme-provider>
812
</template>
913

1014
<script>
11-
import ThemeProvider from './components/ThemeProvider'
12-
import { IconButton, Text } from './lib/core/'
13-
import Badge from './components/Badge'
15+
import { ThemeProvider, Alert, AlertIcon } from './lib/core/'
1416
import theme from './lib/theme'
15-
import { setTimeout } from 'timers'
1617
1718
export default {
1819
data () {
1920
return {
2021
theme,
2122
element: true,
22-
Badge,
2323
loading: false
2424
}
2525
},
2626
name: 'App',
2727
components: {
2828
ThemeProvider,
29-
IconButton,
30-
KText: Text
29+
Alert,
30+
AlertIcon
3131
},
3232
methods: {
3333
toggle () {
@@ -59,7 +59,14 @@ body {
5959
height: 100vh;
6060
width: 100vw;
6161
display: flex;
62+
flex-direction: column;
6263
justify-content: center;
6364
align-items: center;
65+
66+
.wrapper {
67+
display: flex;
68+
flex-direction: column;
69+
justify-content: center;
70+
}
6471
}
6572
</style>

src/components/Alert/alert.styles.js

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import { colorEmphasis } from '../../lib/utils'
2+
3+
export const statuses = {
4+
info: { icon: 'info', color: 'blue' },
5+
warning: { icon: 'warning-2', color: 'orange' },
6+
success: { icon: 'check-circle', color: 'green' },
7+
error: { icon: 'warning', color: 'red' }
8+
}
9+
10+
const baseProps = {
11+
display: 'flex',
12+
alignItems: 'center',
13+
position: 'relative',
14+
overflow: 'hidden',
15+
pl: 4,
16+
pr: 4,
17+
pt: 3,
18+
pb: 3
19+
}
20+
21+
/**
22+
* @description Create leftAccent alert styles
23+
* @param {Object} props
24+
* @property {String} color
25+
*/
26+
const leftAccent = props => {
27+
const { color } = props
28+
return {
29+
light: {
30+
pl: 3,
31+
...subtle(props).light,
32+
borderLeft: '4px',
33+
borderColor: `${color}.500`
34+
},
35+
dark: {
36+
pl: 3,
37+
...subtle(props).dark,
38+
borderLeft: '4px',
39+
borderColor: `${color}.200`
40+
}
41+
}
42+
}
43+
44+
/**
45+
* @description Create topAccent alert styles
46+
* @param {Object} props
47+
* @property {String} color
48+
*/
49+
const topAccent = props => {
50+
const { color } = props
51+
return {
52+
light: {
53+
pt: 2,
54+
...subtle(props).light,
55+
borderTop: '4px',
56+
borderColor: `${color}.500`
57+
},
58+
dark: {
59+
pt: 2,
60+
...subtle(props).dark,
61+
borderTop: '4px',
62+
borderColor: `${color}.200`
63+
}
64+
}
65+
}
66+
67+
/**
68+
* @description Create solid alert styles
69+
* @param {Object} props
70+
* @property {String} color
71+
*/
72+
const solid = ({ color }) => {
73+
return {
74+
light: { bg: `${color}.500`, color: 'white' },
75+
dark: { bg: `${color}.200`, color: 'gray.900' }
76+
}
77+
}
78+
79+
/**
80+
* @description Create subtle alert styles
81+
* @param {Object} props
82+
* @property {String} color
83+
*/
84+
const subtle = ({ color, theme: { colors } }) => {
85+
let darkBg = colors[color] && colors[color][200]
86+
return {
87+
light: {
88+
bg: `${color}.100`
89+
},
90+
dark: { bg: colorEmphasis(darkBg, 'lowest') }
91+
}
92+
}
93+
94+
/**
95+
* @description Evaluate variant styles
96+
* @param {Object} props
97+
* @returns {Object} Style props
98+
*/
99+
const statusStyleProps = props => {
100+
switch (props.variant) {
101+
case 'solid':
102+
return solid(props)
103+
case 'subtle':
104+
return subtle(props)
105+
case 'topAccent':
106+
return topAccent(props)
107+
case 'leftAccent':
108+
return leftAccent(props)
109+
default:
110+
return {}
111+
}
112+
}
113+
114+
/**
115+
* @description Create styles for alert component
116+
* @param {Object} context
117+
* @property {String} variant
118+
* @property {String} color
119+
* @property {String} colorMode
120+
* @property {Object} theme
121+
* @returns {Object} Style props
122+
*/
123+
const useAlertStyle = ({ variant, color, colorMode, theme }) => {
124+
const _props = { variant, color, theme }
125+
console.log({ _props })
126+
return {
127+
...baseProps,
128+
...statusStyleProps(_props)[colorMode]
129+
}
130+
}
131+
132+
/**
133+
* @description Create alert icon styles
134+
* @param {Object} context
135+
* @property {String} variant
136+
* @property {String} colorMode
137+
* @property {String} color
138+
* @returns {Object} Style props
139+
*/
140+
export const useAlertIconStyle = ({ variant, colorMode, color }) => {
141+
if (['left-accent', 'top-accent', 'subtle'].includes(variant)) {
142+
let result = {
143+
light: { color: `${color}.500` },
144+
dark: { color: `${color}.200` }
145+
}
146+
147+
return result[colorMode]
148+
}
149+
}
150+
151+
export default useAlertStyle

src/components/Alert/index.d.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Vue from 'vue'
2+
3+
/**
4+
* The alert component for relaying useful information to the UI
5+
*/
6+
export const Alert: Vue.Component<{
7+
status?: String,
8+
variant?: String
9+
}>;
10+
11+
/**
12+
* Icon component for composing alerts
13+
*/
14+
export const AlertIcon: Vue.Component<{}>;

src/components/Alert/index.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { Box, Icon } from '../../lib/core'
2+
import { baseProps } from '../../lib/config/props'
3+
import { forwardProps } from '../../lib/utils'
4+
import useAlertStyle, { useAlertIconStyle } from './alert.styles'
5+
6+
export const statuses = {
7+
info: { icon: 'info', color: 'blue' },
8+
warning: { icon: 'warning-2', color: 'orange' },
9+
success: { icon: 'check-circle', color: 'green' },
10+
error: { icon: 'warning', color: 'red' }
11+
}
12+
13+
const Alert = {
14+
name: 'Alert',
15+
inject: ['$theme', '$colorMode'],
16+
provide () {
17+
return {
18+
_status: this.status,
19+
_variant: this.variant
20+
}
21+
},
22+
props: {
23+
status: {
24+
type: [String, Array],
25+
default: 'info'
26+
},
27+
variant: {
28+
type: [String, Array],
29+
default: 'subtle'
30+
},
31+
...baseProps
32+
},
33+
render (h) {
34+
const alertStyles = useAlertStyle({
35+
variant: this.variant,
36+
color: statuses[this.status] && statuses[this.status]['color'],
37+
colorMode: this.$colorMode,
38+
theme: this.$theme()
39+
})
40+
41+
return h(Box, {
42+
props: {
43+
...alertStyles,
44+
...forwardProps(this.$props)
45+
},
46+
attrs: {
47+
role: 'alert'
48+
}
49+
}, this.$slots.default)
50+
}
51+
}
52+
53+
const AlertIcon = {
54+
name: 'AlertIcon',
55+
inject: ['_status', '_variant', '$colorMode', '$theme'],
56+
57+
render (h) {
58+
const alertIconStyles = useAlertIconStyle({
59+
variant: this._variant,
60+
colorMode: this.$colorMode,
61+
color: statuses[this._status] && statuses[this._status]['color']
62+
})
63+
64+
return h(Icon, {
65+
props: {
66+
mr: 3,
67+
size: 5,
68+
name: statuses[this._status] && statuses[this._status]['icon'],
69+
...alertIconStyles,
70+
...forwardProps(this.$props)
71+
},
72+
attrs: {
73+
focusable: false
74+
}
75+
})
76+
}
77+
}
78+
79+
export { Alert, AlertIcon }

src/components/IconButton/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ export default {
5151
? h(Icon, {
5252
props: {
5353
...baseStyles,
54-
focusable: false,
5554
name: this.icon,
5655
color: 'currentColor',
5756
mb: '2px',

src/components/ThemeProvider/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const ThemeProvider = {
2424
$icons: this.icons
2525
}
2626
},
27-
render: function () {
27+
render () {
2828
return this.$slots.default
2929
}
3030
}

src/lib/core/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export { default as Spinner } from '../../components/Spinner'
88
export { default as VisuallyHidden } from '../../components/VisuallyHidden'
99
export { default as TransitionExpand } from '../../components/TransitionExpand'
1010
export { default as Text } from '../../components/Text'
11+
export * from '../../components/Alert'

src/lib/plugin/iconsPaths.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ const icons = {
2727
/>
2828
`
2929
},
30+
info: {
31+
path: `
32+
<path
33+
fill="currentColor"
34+
d="M12,0A12,12,0,1,0,24,12,12.013,12.013,0,0,0,12,0Zm.25,5a1.5,1.5,0,1,1-1.5,1.5A1.5,1.5,0,0,1,12.25,5ZM14.5,18.5h-4a1,1,0,0,1,0-2h.75a.25.25,0,0,0,.25-.25v-4.5a.25.25,0,0,0-.25-.25H10.5a1,1,0,0,1,0-2h1a2,2,0,0,1,2,2v4.75a.25.25,0,0,0,.25.25h.75a1,1,0,1,1,0,2Z"
35+
/>
36+
`
37+
},
3038
'question-outline': {
3139
viewBox: '0 0 24 24',
3240
path: `

0 commit comments

Comments
 (0)