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

Commit ec73a49

Browse files
committed
feat(v-chakra): initial implementation of v-chakra directive
1 parent 45c9fb2 commit ec73a49

File tree

6 files changed

+81
-0
lines changed

6 files changed

+81
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
import CBox from './CBox'
22
export default CBox
3+
export * from './CBox'

packages/chakra-ui-core/src/Chakra/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import VScrollLock from 'v-scroll-lock'
22
import { merge } from 'lodash-es'
33
import { parsePackIcons } from '../utils/icons'
44
import internalIcons from '../lib/internal-icons'
5+
import { createCharkaDirective } from '../directives'
56
import defaultTheme from '../../../chakra-ui-theme/src'
67
import useToast from '../CToast'
78

@@ -62,6 +63,8 @@ const Chakra = {
6263
// Recursively merge extended theme variables
6364
const mergedTheme = merge(defaultTheme, options.extendTheme)
6465

66+
Vue.directive('chakra', createCharkaDirective(mergedTheme))
67+
6568
// Bind theme and icons to prototype
6669
Vue.prototype.$chakra = {
6770
theme: mergedTheme,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { css } from 'emotion'
2+
import __css from '@styled-system/css'
3+
import { systemProps } from '../CBox'
4+
import styleProps from '../config/props'
5+
import { forwardProps, camelize } from '../utils'
6+
import { parsePseudoStyles } from '../CPseudoBox/utils'
7+
8+
/** Filter attrs and return object of chakra props */
9+
function filterChakraProps(attrs) {
10+
const pure = {}
11+
for (const prop in attrs) {
12+
if (styleProps[camelize(prop)]) {
13+
pure[prop] = attrs[prop]
14+
}
15+
}
16+
return pure
17+
}
18+
19+
/** Purify Chakra attributes */
20+
function purifyAttrs(el, props) {
21+
for (const attr in props) {
22+
el.removeAttribute(attr)
23+
}
24+
}
25+
26+
/** Creates className from styles object */
27+
function createClassName(styleObject, theme) {
28+
const pure = filterChakraProps(forwardProps(styleObject))
29+
const { pseudoStyles, baseProps } = parsePseudoStyles(pure)
30+
const baseStyles = systemProps({ ...baseProps, theme })
31+
const _pseudoStyles = __css(pseudoStyles)(theme)
32+
const className = css({ ...baseStyles, ..._pseudoStyles })
33+
return [className, pure]
34+
}
35+
36+
/** Creates Chakra Directive */
37+
export default function createCharkaDirective (theme) {
38+
return {
39+
bind (el, binding, vnode) {
40+
const [className, pure] = createClassName(vnode.data.attrs, theme)
41+
el.classList.add(className)
42+
purifyAttrs(el, pure)
43+
44+
if (binding.value && typeof binding.value === 'object') {
45+
const [className, pure] = createClassName(binding.value, theme)
46+
el.classList.add(className)
47+
purifyAttrs(el, pure)
48+
}
49+
}
50+
}
51+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { storiesOf } from '@storybook/vue'
2+
3+
storiesOf('Directives | Chakra', module)
4+
.add('Base usage - No arguments', () => ({
5+
template: `
6+
<div>
7+
<div v-chakra="{
8+
_hover: {
9+
color: 'green.400',
10+
fontWeight: 'bold'
11+
}
12+
}" p="3" color="red.400" font-weight="bold">Welcome to Chakra directive</div>
13+
</div>
14+
`
15+
}))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { default as ClickOutsideDirective } from './clickoutside.directive'
2+
export { default as createCharkaDirective } from './chakra.directive'

packages/chakra-ui-core/src/utils/strings.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,13 @@ export function kebabify (text) {
2727
.map(x => x.toLowerCase())
2828
.join('-')
2929
}
30+
31+
/**
32+
* Converts a kebab-case string into camel case
33+
* @param {String} string
34+
*/
35+
export function camelize(string) {
36+
return string.replace(/[.-](\w|$)/g, function (_,x) {
37+
return x.toUpperCase();
38+
});
39+
}

0 commit comments

Comments
 (0)