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

Commit 8b11589

Browse files
committed
feat(system): create Chakra UI plugin
1 parent 93e8918 commit 8b11589

File tree

14 files changed

+974
-1134
lines changed

14 files changed

+974
-1134
lines changed

lerna.json

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
{
2-
"packages": [
3-
"packages/*"
4-
],
5-
"version": "0.0.0"
6-
}
2+
"packages": ["packages/*", "website", "tooling/*"],
3+
"version": "independent",
4+
"npmClient": "yarn",
5+
"useWorkspaces": true,
6+
"registry": "https://registry.npmjs.org/",
7+
"command": {
8+
"version": { "exact": true },
9+
"publish": {
10+
"conventionalCommits": true,
11+
"message": "chore(release): publish",
12+
"ignoreChanges": ["**/stories/**", "**/tests/**"],
13+
"allowBranch": "master"
14+
}
15+
}
16+
}

package.json

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"lint": "eslint '*/**/*.{js,ts,tsx}' --quiet --fix",
1515
"scaffold": "hygen",
1616
"playground:routes": "ts-node ./scripts/parse-routes.ts",
17-
"dev": "yarn playground:routes && NODE_ENV=development vite serve playground",
17+
"dev": "yarn playground:routes && NODE_ENV=development vite serve playground --config ./vite.config.ts",
1818
"playground:build": "yarn install && yarn build && yarn playground:routes && NODE_ENV=production vite build playground",
1919
"c-alert": "yarn workspace @chakra-ui/c-alert",
2020
"c-box": "yarn workspace @chakra-ui/c-box",
@@ -32,6 +32,7 @@
3232
"@types/recursive-readdir": "^2.2.0",
3333
"@typescript-eslint/eslint-plugin": "^2.34.0",
3434
"@typescript-eslint/parser": "4.0.1",
35+
"@vitejs/plugin-vue": "^1.0.6",
3536
"@vue/eslint-config-typescript": "^5.1.0",
3637
"concurrently": "^5.3.0",
3738
"consola": "^2.15.0",
@@ -52,18 +53,25 @@
5253
"recursive-readdir": "^2.2.2",
5354
"ts-node": "^9.0.0",
5455
"typescript": "^4.1.2",
55-
"vite": "^1.0.0-rc.13",
56-
"vue": "^3",
56+
"@vue/compiler-sfc": "^3.0.5",
57+
"@vuedx/typecheck": "^0.4.1",
58+
"@vuedx/typescript-plugin-vue": "^0.4.1",
59+
"vite": "^2.0.0-beta.12",
60+
"vue": "^3.0.5",
5761
"vue-router": "4.0.0-beta.10"
5862
},
5963
"dependencies": {
64+
"@chakra-ui/styled-system": "^1.4.1",
65+
"@emotion/css": "^11.1.3",
66+
"@emotion/server": "^11.0.0",
6067
"@types/lodash.mergewith": "^4.6.6",
6168
"@types/tinycolor2": "^1.4.2",
6269
"change-case": "^4.1.1",
6370
"css-get-unit": "^1.0.1",
6471
"csstype": "^3.0.5",
6572
"lodash.mergewith": "^4.6.2",
6673
"object-assign": "^4.1.1",
74+
"react": "^17.0.1",
6775
"tinycolor2": "^1.4.2"
6876
}
6977
}

packages/c-alert/examples/base-alert.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<c-alert class="chakra-alert"> HELLO ALERT </c-alert>
2+
<c-alert> HELLO ALERT </c-alert>
33
<p>Alert paragraph</p>
44
</template>
55

packages/c-alert/src/index.ts

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,33 @@
1-
import {
2-
h,
3-
defineComponent,
4-
VNodeProps,
5-
VNode,
6-
Component,
7-
Fragment,
8-
Teleport,
9-
Suspense,
10-
DefineComponent,
11-
onMounted,
12-
} from 'vue'
1+
import { h, defineComponent } from 'vue'
132

14-
import { css } from '@chakra-ui/vue-styled-system'
3+
import { css } from '@chakra-ui/styled-system'
4+
import { css as emotionCss, cx } from '@emotion/css'
155
import theme from '@chakra-ui/vue-theme'
166

17-
type Tag =
18-
| string
19-
| typeof Fragment
20-
| typeof Teleport
21-
| typeof Suspense
22-
| Component
23-
247
const CAlert = defineComponent({
258
props: {
269
as: {
2710
type: [String, Object],
2811
default: 'div',
2912
},
3013
},
31-
setup() {
32-
onMounted(() => {
33-
console.log(
34-
css({
35-
bg: 'blue.400',
36-
p: 4,
37-
color: 'white',
38-
})({ theme })
39-
)
40-
})
41-
},
4214
render() {
15+
const alertStyles = css({
16+
bg: 'blue.400',
17+
p: 4,
18+
color: 'white',
19+
_hover: {
20+
bg: 'green.400',
21+
},
22+
})({ theme })
23+
24+
const className = emotionCss(alertStyles)
25+
4326
return h(
4427
this.as,
4528
{
4629
...this.$attrs,
30+
class: cx('chakra-alert', className),
4731
role: 'alert',
4832
},
4933
this.$slots.default && this.$slots.default()

packages/core/src/extend-theme.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import defaultTheme, { Theme } from '@chakra-ui/vue-theme'
2+
import { isFunction, mergeWith } from '@chakra-ui/utils'
3+
import { ColorHues } from '@chakra-ui/vue-theme/dist/types/foundations/colors'
4+
5+
type ThemeExtensionTypeHints = {
6+
colors: Record<string, Partial<ColorHues> | Record<string, string> | string>
7+
}
8+
9+
/**
10+
* Represents a loose but specific type for the theme override.
11+
* It provides autocomplete hints for extending the theme, but leaves room
12+
* for adding properties.
13+
*/
14+
type DeepThemeExtension<ThemeObject, TypeHints> = {
15+
[Key in keyof ThemeObject]?:
16+
| Omit<DeepThemeExtension<ThemeObject[Key], TypeHints>, keyof TypeHints> // recursive type clone
17+
| (ThemeObject[Key] extends (...args: any[]) => any
18+
? Partial<ReturnType<ThemeObject[Key]>>
19+
: Partial<ThemeObject[Key]>) // allow function or object
20+
} &
21+
Partial<TypeHints> &
22+
Record<string, any> // escape hatch
23+
24+
export type ThemeOverride = DeepThemeExtension<Theme, ThemeExtensionTypeHints>
25+
26+
/**
27+
* Function to override or customize the Chakra UI theme conveniently
28+
* @param overrides - Your custom theme object overrides
29+
* @param baseTheme - theme to customize
30+
*/
31+
export function extendTheme<T extends ThemeOverride>(
32+
overrides: T,
33+
baseTheme: any = defaultTheme
34+
) {
35+
function customizer(source: unknown, override: unknown) {
36+
if (isFunction(source)) {
37+
return (...args: unknown[]) => {
38+
const sourceValue = source(...args)
39+
40+
const overrideValue = isFunction(override)
41+
? override(...args)
42+
: override
43+
44+
return mergeWith({}, sourceValue, overrideValue, customizer)
45+
}
46+
}
47+
48+
// fallback to default behaviour
49+
return undefined
50+
}
51+
52+
return mergeWith({}, baseTheme, overrides, customizer)
53+
}

packages/core/src/index.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1-
const myName = 'Hello Jonas from `@chakra-ui/vue-next`'
1+
import { Plugin } from 'vue'
2+
import { ThemeOverride, extendTheme } from './extend-theme'
23

3-
export default myName
4+
interface ExtendIconsPath {
5+
path: string
6+
viewBox?: string
7+
}
8+
interface IconsOptions {
9+
pack?: 'fa' | 'fe'
10+
library?: {}
11+
extend?: Record<string, ExtendIconsPath>
12+
}
13+
interface ChakraUIVuePluginOptions {
14+
extendTheme?: ThemeOverride
15+
icons?: IconsOptions
16+
}
17+
18+
const ChakraUIVuePlugin: Plugin = {
19+
install(app, options: ChakraUIVuePluginOptions = {}) {
20+
app.config.globalProperties.$chakraTheme = options.extendTheme
21+
},
22+
}
23+
24+
export default ChakraUIVuePlugin
25+
export { extendTheme }

packages/system/src/index.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
1-
const System = () => {
2-
return {}
3-
}
1+
import {
2+
Component,
3+
defineComponent,
4+
Fragment,
5+
Suspense,
6+
Teleport,
7+
h,
8+
} from 'vue'
9+
import { DOMElements } from './system.utils'
10+
11+
type Tag =
12+
| string
13+
| typeof Fragment
14+
| typeof Teleport
15+
| typeof Suspense
16+
| Component
417

5-
export { System }
18+
export const chakra = (tag: DOMElements, componentProps = {}) => {
19+
return defineComponent({
20+
inheritAttrs: false,
21+
props: componentProps,
22+
setup(props, { slots, attrs }) {
23+
return () => h(tag, {}, slots)
24+
},
25+
})
26+
}

packages/system/src/system.utils.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { UnionStringArray } from '@chakra-ui/utils'
2+
3+
/**
4+
* Carefully selected html elements for chakra components.
5+
* This is mostly for `chakra.[element]` syntax.
6+
*
7+
* Adapted from React package
8+
*/
9+
export const domElements = [
10+
'a',
11+
'b',
12+
'article',
13+
'aside',
14+
'blockquote',
15+
'button',
16+
'caption',
17+
'cite',
18+
'circle',
19+
'code',
20+
'dd',
21+
'div',
22+
'dl',
23+
'dt',
24+
'fieldset',
25+
'figcaption',
26+
'figure',
27+
'footer',
28+
'form',
29+
'h1',
30+
'h2',
31+
'h3',
32+
'h4',
33+
'h5',
34+
'h6',
35+
'header',
36+
'hr',
37+
'img',
38+
'input',
39+
'kbd',
40+
'label',
41+
'li',
42+
'mark',
43+
'nav',
44+
'ol',
45+
'p',
46+
'path',
47+
'pre',
48+
'q',
49+
'rect',
50+
's',
51+
'svg',
52+
'section',
53+
'select',
54+
'strong',
55+
'small',
56+
'span',
57+
'sub',
58+
'sup',
59+
'table',
60+
'tbody',
61+
'td',
62+
'textarea',
63+
'tfoot',
64+
'th',
65+
'thead',
66+
'tr',
67+
'ul',
68+
] as const
69+
70+
export type DOMElements = UnionStringArray<typeof domElements>

packages/utils/src/object.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import type { Dict, Omit } from './types'
33

44
export { default as objectAssign } from 'object-assign'
55

6-
console.log(mergeWith)
7-
86
export function omit<T extends Dict, K extends keyof T>(object: T, keys: K[]) {
97
const result: Dict = {}
108

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<template>
2+
<h1>{{ msg }}</h1>
3+
4+
<p>
5+
<a href="https://vitejs.dev/guide/features.html" target="_blank">Vite Documentation</a> |
6+
<a href="https://v3.vuejs.org/" target="_blank">Vue 3 Documentation</a>
7+
</p>
8+
9+
<p>
10+
Recommended setup:
11+
<a href="https://code.visualstudio.com/" target="_blank">VSCode</a>
12+
+
13+
<a
14+
href="https://marketplace.visualstudio.com/items?itemName=octref.vetur"
15+
target="_blank"
16+
>Vetur</a>
17+
+
18+
<a
19+
href="https://marketplace.visualstudio.com/items?itemName=znck.vue-language-features"
20+
target="_blank"
21+
>Vue DX</a>
22+
</p>
23+
<p>
24+
Make sure to use workspace version of TypeScript to get improved support via
25+
<a
26+
href="https://github.com/znck/vue-developer-experience"
27+
target="_blank"
28+
>@vuedx</a>.
29+
<br />Note @vuedx is still experimental and this setup is provided for early feedback.
30+
</p>
31+
<button @click="count++">count is: {{ count }}</button>
32+
<p>
33+
Edit
34+
<code>components/HelloWorld.vue</code> to test hot module replacement.
35+
</p>
36+
</template>
37+
38+
<script lang="ts">
39+
import { ref, defineComponent } from 'vue'
40+
41+
export default defineComponent({
42+
name: 'HelloWorld',
43+
props: {
44+
msg: {
45+
type: String,
46+
required: true
47+
}
48+
},
49+
setup: () => {
50+
const count = ref(0)
51+
return { count }
52+
}
53+
})
54+
</script>
55+
56+
<style scoped>
57+
a {
58+
color: #42b983;
59+
}
60+
</style>

0 commit comments

Comments
 (0)