Skip to content

Commit 5e675e1

Browse files
committed
feat(wip-styled): completed tests for styled function api
1 parent f30fac0 commit 5e675e1

25 files changed

+480
-111
lines changed

components.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* This is a generated file. Do not edit it's contents.
88
*
9-
* This file was generated on 2022-02-15T20:12:51.041Z
9+
* This file was generated on 2022-03-03T13:59:03.450Z
1010
*/
1111

1212
import { ChakraProps, chakra } from "@chakra-ui/vue-system"
@@ -191,8 +191,8 @@ declare module "@vue/runtime-core" {
191191
/* Component custom props types for JSX and TSX auto complete */
192192
export interface ComponentCustomProps
193193
extends JsxComponentCustomProps,
194+
ComponentCustomProps,
194195
ChakraProps {
195-
onClick?: () => any
196196
vSlots?: {
197197
[eleName: string]: JSX.Element
198198
}

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,9 @@
154154
"tinycolor2": "^1.4.2",
155155
"ts-jest": "^26.5.0",
156156
"ts-node": "^9.0.0",
157-
"typescript": "^4.5.4",
157+
"typescript": "^4.6.2",
158158
"unplugin-vue-components": "^0.14.0",
159-
"vite": "^2.7.4",
159+
"vite": "^2.8.6",
160160
"vite-plugin-mdx-vue": "^1.6.0",
161161
"vite-plugin-pages": "^0.20.1",
162162
"vite-plugin-vue-layouts": "^0.5.0",

packages/core/package.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,11 @@
4646
"@chakra-ui/vue-a11y": "0.1.0-alpha.9",
4747
"@chakra-ui/vue-composables": "0.1.0-alpha.9",
4848
"@chakra-ui/vue-layout": "0.1.0-alpha.11",
49+
"@chakra-ui/vue-styled": "0.0.0-alpha.0",
4950
"@chakra-ui/vue-system": "0.1.0-alpha.10",
5051
"@chakra-ui/vue-theme": "1.0.0-alpha.10",
51-
"@chakra-ui/vue-theme-tools": "0.1.0-alpha.10"
52+
"@chakra-ui/vue-theme-tools": "0.1.0-alpha.10",
53+
"@emotion/cache": "^11.7.1"
5254
},
5355
"devDependencies": {
5456
"vue": "^3.2.29"
@@ -59,4 +61,4 @@
5961
"publishConfig": {
6062
"access": "public"
6163
}
62-
}
64+
}

packages/core/src/helpers/plugin.types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ColorModeRef } from "@chakra-ui/c-color-mode"
22
import { UnwrapRef } from "vue"
33
import { ThemeOverride } from "../extend-theme"
4+
import { Options } from "@emotion/cache"
45

56
interface ExtendIconsPath {
67
path: string
@@ -17,4 +18,5 @@ export interface ChakraPluginOptions {
1718
extendTheme?: ThemeOverride
1819
icons?: IconsOptions
1920
defaultColorMode?: UnwrapRef<ColorModeRef>
21+
emotionCacheOptions?: Options
2022
}

packages/core/src/index.ts

+21-1
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,30 @@ import defaultTheme from "@chakra-ui/vue-theme"
33
import type { ColorModeRef } from "@chakra-ui/c-color-mode"
44
import { toCSSVar, WithCSSVar } from "@chakra-ui/styled-system"
55
import { chakra, injectGlobal } from "@chakra-ui/vue-system"
6+
import {
7+
EmotionThemeContextSymbol,
8+
EmotionCacheInjectionSymbol,
9+
} from "@chakra-ui/vue-styled"
10+
import createCache from "@emotion/cache"
611
import internalIcons from "./icon.internals"
712
import { extendTheme, ThemeOverride } from "./extend-theme"
813
import { MergedIcons, parseIcons } from "./parse-icons"
914
import { injectResetStyles, injectThemeGlobalStyles } from "./helpers/css-reset"
1015
import { mode } from "@chakra-ui/vue-theme-tools"
1116
import { ChakraPluginOptions } from "./helpers/plugin.types"
1217

18+
/**
19+
* 1. Support passing cache options from plugin
20+
* 2. Provide emotion theme directly from plugin
21+
* 3.
22+
*/
23+
1324
/**
1425
* Helper function to extend Chakra plugin with options
1526
* It just returns its arguments with typescript types added
1627
*/
17-
export function chakraOptions(
28+
29+
export function extendChakra(
1830
options: ChakraPluginOptions = { cssReset: true }
1931
) {
2032
return options
@@ -56,8 +68,16 @@ const ChakraUIVuePlugin: Plugin = {
5668

5769
// Bind theme to application global properties and provide to application
5870
app.config.globalProperties.$chakraTheme = computedTheme.value
71+
app.config.globalProperties.$chakraTheme = computedTheme.value
72+
app.provide(EmotionThemeContextSymbol, computedTheme.value)
5973
app.provide("$chakraTheme", computedTheme.value as ThemeOverride)
6074

75+
// Provide emotion cache
76+
if (options.emotionCacheOptions) {
77+
const emotionCache = createCache(options.emotionCacheOptions)
78+
app.provide(EmotionCacheInjectionSymbol, emotionCache)
79+
}
80+
6181
libraryIcons = parseIcons(libraryIcons)
6282

6383
// Merge internal icons and library icons

packages/layout/src/kbd.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import { vueThemingProps } from "@chakra-ui/vue-utils"
1+
import { vueThemingProps, extractStyleAttrs } from "@chakra-ui/vue-utils"
22
import {
33
chakra,
44
DOMElements,
55
ThemingProps,
66
useStyleConfig,
77
HTMLChakraProps,
8-
extractStyleAttrs,
98
ComponentWithProps,
109
DeepPartial,
1110
} from "@chakra-ui/vue-system"

packages/styled/examples/styled.vue

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<template>
2+
<div>
3+
<div>Hello world</div>
4+
<Button>Button</Button>
5+
<chakra.button
6+
aria-label="Dope button"
7+
:bg="['pink.500', 'yellow.500', 'orange.500', 'green.500']"
8+
color="white"
9+
px="4"
10+
py="2"
11+
@click="handleClick"
12+
:layer-style="{
13+
bg: 'black',
14+
color: 'white',
15+
}"
16+
>
17+
Hot pink
18+
</chakra.button>
19+
</div>
20+
</template>
21+
22+
<script lang="tsx" setup>
23+
import { defineComponent, h } from "vue"
24+
import styled from "../src"
25+
import { _chakra as chakra } from "@chakra-ui/vue-system"
26+
27+
const Button = chakra("button", {
28+
baseStyle: {
29+
bg: "blue.700",
30+
color: "white",
31+
fontWeight: "bold",
32+
px: 4,
33+
py: 3,
34+
},
35+
})
36+
37+
function handleClick(e: MouseEvent) {
38+
console.log("Clicked", e)
39+
}
40+
41+
const CButton = defineComponent({
42+
setup() {
43+
return () => (
44+
<Button height="32px" onClick={handleClick}>
45+
Main Button
46+
</Button>
47+
)
48+
},
49+
})
50+
</script>

packages/styled/package.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
"@emotion/utils": "^1.0.0",
2828
"@emotion/weak-memoize": "^0.2.5",
2929
"clsx": "^1.1.1",
30-
"lodash.camelcase": "^4.3.0"
30+
"lodash.camelcase": "^4.3.0",
31+
"lodash.memoize": "^4.1.2"
32+
},
33+
"devDependencies": {
34+
"@types/lodash.memoize": "^4.1.6"
3135
},
3236
"peerDependencies": {
3337
"vue": "^3.2.31"

packages/styled/src/cache.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
SetupContext
1212
} from "vue"
1313

14-
const [EmotionCacheProvider, useEmotionCache] = createContext<EmotionCache>({
14+
const [EmotionCacheProvider, useEmotionCache, EmotionCacheInjectionSymbol] = createContext<EmotionCache>({
1515
strict: false,
1616
name: "EmotionCacheContext",
1717
})
@@ -50,4 +50,4 @@ if (canUseDOM()) {
5050
}
5151
}
5252

53-
export { withEmotionCache, EmotionCacheProvider }
53+
export { withEmotionCache, EmotionCacheProvider, EmotionCacheInjectionSymbol }

packages/styled/src/index.ts renamed to packages/styled/src/index.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { createStyled } from "./styled"
22
import { tags } from "./tags"
33

44
export * from "./cache"
5+
export * from "./theming"
56

67
// bind it to avoid mutating the original function
78
const styled = createStyled.bind()
@@ -11,4 +12,4 @@ tags.forEach((tagName) => {
1112
styled[tagName] = styled(tagName)
1213
})
1314

14-
export default styled
15+
export default styled

packages/styled/src/styled.tsx

+16-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import clsx from 'clsx'
2-
import { CSSInterpolation, Interpolation, serializeStyles } from '@emotion/serialize'
2+
import { mergeProps, SetupContext, h, Fragment } from 'vue'
3+
import { CSSInterpolation, serializeStyles } from '@emotion/serialize'
4+
import { extractStyleAttrs } from '@chakra-ui/vue-utils'
35
import { getRegisteredStyles, insertStyles, SerializedStyles } from '@emotion/utils'
6+
import camelCase from 'lodash.camelcase'
7+
import { CreateStyled, PrivateStyledComponent, StyledOptions } from './types'
48
import { defaultCache, __unusafe_useEmotionCache } from './cache'
59
import { useEmotionTheme } from './theming'
6-
import { CreateStyled, PrivateStyledComponent, StyledOptions } from './types'
7-
import camelCase from 'lodash.camelcase'
8-
import { mergeProps, SetupContext, h, Fragment } from 'vue'
10+
import memoize from 'lodash.memoize'
911

1012
const ILLEGAL_ESCAPE_SEQUENCE_ERROR = `You have illegal escape sequence in your template literal, most likely inside content's property value.
1113
Because you write your CSS inside a JavaScript string you actually have to do double escaping, so for example "content: '\\00d7';" should become "content: '\\\\00d7';".
@@ -17,6 +19,8 @@ let isBrowser = typeof document !== 'undefined'
1719
const Noop = () => null
1820
const camelCaseCache: any = {}
1921

22+
const _camelCase = memoize((key) => camelCase(key))
23+
2024
// @ts-ignore
2125
export const createStyled: CreateStyled = (tag: any, options?: StyledOptions) => {
2226
if (process.env.NODE_ENV !== 'production') {
@@ -33,7 +37,7 @@ export const createStyled: CreateStyled = (tag: any, options?: StyledOptions) =>
3337
let identifierName: string
3438
let targetClassName: string
3539
if (options !== undefined) {
36-
identifierName = options.label as string
40+
identifierName = options.__label as string
3741
targetClassName = options.target as string
3842
}
3943

@@ -71,7 +75,7 @@ export const createStyled: CreateStyled = (tag: any, options?: StyledOptions) =>
7175

7276
let mergedProps = { ...props, ...restAttrs }
7377

74-
let className = attrs.staticClass ? `${attrs.staticClass} ` : ''
78+
let className = options?.__label ? `${cache.key}-${options?.__label || typeof tag === 'string' ? tag : 'element'} ` : ``
7579
const FinalTag = as || baseTag
7680
const classInterpolations = [] as string[]
7781

@@ -80,7 +84,7 @@ export const createStyled: CreateStyled = (tag: any, options?: StyledOptions) =>
8084
if (camelCaseCache[key]) {
8185
mergedProps[key] = camelCaseCache[key]
8286
} else {
83-
const attr = camelCase(key)
87+
const attr = _camelCase(key)
8488
camelCaseCache[attr] = props[key]
8589
mergedProps[attr] = props[key]
8690
}
@@ -120,11 +124,14 @@ export const createStyled: CreateStyled = (tag: any, options?: StyledOptions) =>
120124
className += ` ${targetClassName}`
121125
}
122126

127+
128+
const { attrs: htmlAttrs } = extractStyleAttrs(mergedProps)
123129
const vnodeProps = {
124-
...attrs,
125-
...restAttrs,
130+
...htmlAttrs,
126131
class: className,
127132
}
133+
// @ts-expect-error
134+
delete vnodeProps?.theme
128135

129136
const StyledElement = (
130137
<FinalTag {...vnodeProps}>

packages/styled/src/theming.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { createContext } from '@chakra-ui/vue-utils';
33
import { getTheme } from "./utils"
44
import { ComputedRef } from 'vue';
55

6-
const [_EmotionThemeProvider, useEmotionTheme] = createContext<object>({
6+
const [_EmotionThemeProvider, useEmotionTheme, EmotionThemeContextSymbol] = createContext<object>({
77
strict: false,
88
name: "EmotionThemeContext",
99
})
@@ -15,11 +15,11 @@ let createCacheWithTheme = /* #__PURE__ */ weakMemoize(outerTheme => {
1515
})
1616

1717
function EmotionThemeProvider (theme: object | ((Obj: object) => Object)) {
18-
let _theme = useEmotionTheme({})
18+
let _theme = useEmotionTheme()
1919
if (theme !== _theme) {
2020
_theme = createCacheWithTheme(_theme)(theme)
2121
}
2222
_EmotionThemeProvider(_theme)
2323
}
2424

25-
export { createCacheWithTheme as createThemeCache, EmotionThemeProvider, useEmotionTheme }
25+
export { createCacheWithTheme as createThemeCache, EmotionThemeProvider, useEmotionTheme, EmotionThemeContextSymbol }

packages/styled/src/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
import { StyledElementTags } from "./tags"
99

1010
export type StyledOptions = {
11-
label?: string
11+
__label?: string
1212
target?: string
1313
}
1414

packages/styled/tests/styled.test.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ describe.only("styled", () => {
8686
})
8787

8888
const { asFragment } = render(() => {
89-
// @ts-expect-error
9089
return <H2 fontSize={20} flex={1}>
9190
hello world
9291
</H2>

packages/system/package.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,18 @@
2020
"clean": "rimraf dist"
2121
},
2222
"dependencies": {
23+
"@chakra-ui/vue-styled": "0.0.0-alpha.0",
2324
"@chakra-ui/c-color-mode": "0.1.0-alpha.9",
2425
"@chakra-ui/styled-system": "^1.16.0",
2526
"@chakra-ui/utils": "^1.9.1",
2627
"@chakra-ui/vue-utils": "0.1.0-alpha.10",
2728
"@emotion/css": "^11.1.3",
2829
"lodash.camelcase": "^4.3.0",
29-
"lodash.kebabcase": "^4.1.1"
30+
"lodash.kebabcase": "^4.1.1",
31+
"lodash.memoize": "^4.1.2"
3032
},
3133
"devDependencies": {
34+
"@types/lodash.memoize": "^4.1.6",
3235
"vue": "^3.2.29"
3336
},
3437
"peerDependencies": {
@@ -37,4 +40,4 @@
3740
"publishConfig": {
3841
"access": "public"
3942
}
40-
}
43+
}

0 commit comments

Comments
 (0)