Skip to content

Commit 800ddaf

Browse files
committed
feat: support use tailwind css(#17)
1 parent a6973f9 commit 800ddaf

18 files changed

+410
-40
lines changed

.eslintrc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
22
"env": {
33
"browser": true,
4-
"es2021": true
4+
"es2021": true,
5+
"node": true
56
},
67
"extends": [
78
"eslint:recommended",

packages/core/index.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
1-
export { ThemeProvider, type DefaultTheme } from './src/providers/theme'
2-
export {
3-
createGlobalStyle,
4-
css,
5-
cssClass,
6-
withAttrs,
7-
isTag,
8-
isVueComponent,
9-
isStyledComponent,
10-
isValidElementType,
11-
keyframes,
12-
} from './src/helper'
1+
export * from './src/providers/theme'
2+
export * from './src/helper'
133
// export * from './hooks'
144

15-
export { styled as default, styled } from './src/styled'
5+
export * from './src/styled'

packages/core/src/helper/createGlobalStyle.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ export const createGlobalStyle = (styles: TemplateStringsArray, ...expressions:
77
return defineComponent(
88
(_, { attrs }) => {
99
const cssStringsWithExpression = insertExpressions(styles, expressions)
10+
1011
injectStyle('', cssStringsWithExpression, attrs)
12+
1113
return () => {
1214
return h('div', { style: 'display: none' })
1315
}

packages/core/src/helper/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export * from './createGlobalStyle'
44
export * from './keyframes'
55
export * from './css'
66
export * from './cssClass'
7+
export * from './tw'

packages/core/src/helper/tw.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export function tw(classNames: TemplateStringsArray, ...expressions: string[]): any {
2+
return {
3+
source: 'tw',
4+
value: classNames[0]
5+
?.replace(/(\s|\\n)+/g, ' ')
6+
.trim()
7+
.split(' ')
8+
.concat(expressions),
9+
}
10+
}

packages/core/src/styled.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
PropType,
99
PublicProps,
1010
reactive,
11+
ref,
1112
SlotsType,
1213
watch,
1314
} from 'vue'
@@ -65,14 +66,26 @@ function baseStyled<P extends Record<string, any>>(target: string | InstanceType
6566
const componentName = generateComponentName(type)
6667
return defineComponent(
6768
(props, { slots }) => {
68-
const myAttrs = { ...attributes }
69+
const tailwindClasses = ref<string[]>([])
70+
const myAttrs = ref({ ...attributes })
6971
const theme = inject<Record<string, string | number>>('$theme', reactive({}))
7072
let context = {
7173
theme,
7274
...props,
7375
}
7476

75-
myAttrs.class = generateClassName()
77+
const defaultClassName = generateClassName()
78+
79+
myAttrs.value.class = defaultClassName
80+
81+
// Inject the tailwind classes to the class attribute
82+
watch(
83+
tailwindClasses,
84+
(classNames) => {
85+
myAttrs.value.class = `${defaultClassName} ${classNames.join(' ')}`
86+
},
87+
{ deep: true },
88+
)
7689

7790
watch(
7891
[theme, props],
@@ -81,19 +94,19 @@ function baseStyled<P extends Record<string, any>>(target: string | InstanceType
8194
theme,
8295
...props,
8396
}
84-
injectStyle<T & { theme: DefaultTheme }>(myAttrs.class, cssWithExpression, context)
97+
tailwindClasses.value = injectStyle<T & { theme: DefaultTheme }>(defaultClassName, cssWithExpression, context)
8598
},
8699
{
87100
deep: true,
88101
},
89102
)
90103

91104
onMounted(() => {
92-
injectStyle<T & { theme: DefaultTheme }>(myAttrs.class, cssWithExpression, context)
105+
tailwindClasses.value = injectStyle<T & { theme: DefaultTheme }>(defaultClassName, cssWithExpression, context)
93106
})
94107

95108
onUnmounted(() => {
96-
removeStyle(myAttrs.class)
109+
removeStyle(myAttrs.value.class)
97110
})
98111

99112
// Return the render function
@@ -102,7 +115,7 @@ function baseStyled<P extends Record<string, any>>(target: string | InstanceType
102115
return h(
103116
node,
104117
{
105-
...myAttrs,
118+
...myAttrs.value,
106119
},
107120
slots,
108121
)
Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
1-
export function applyExpressions(chunks: any[], executionContext: Record<string, any>): string[] {
1+
export function applyExpressions(chunks: any[], executionContext: Record<string, any>, tailwindClasses: string[]): string[] {
22
return chunks.reduce((ruleSet, chunk) => {
3-
if (chunk === undefined || chunk === null || chunk === false || chunk === '') return ruleSet
4-
if (Array.isArray(chunk)) return [...ruleSet, ...applyExpressions(chunk, executionContext)]
3+
if (chunk === undefined || chunk === null || chunk === false || chunk === '') {
4+
return ruleSet
5+
}
6+
7+
if (Array.isArray(chunk)) {
8+
return [...ruleSet, ...applyExpressions(chunk, executionContext, tailwindClasses)]
9+
}
10+
511
if (typeof chunk === 'function') {
6-
return executionContext ? ruleSet.concat(...applyExpressions([chunk(executionContext)], executionContext)) : ruleSet.concat(chunk)
12+
return executionContext
13+
? ruleSet.concat(...applyExpressions([chunk(executionContext)], executionContext, tailwindClasses))
14+
: ruleSet.concat(chunk)
15+
}
16+
17+
if (typeof chunk === 'object' && chunk?.source === 'tw') {
18+
tailwindClasses.push(...chunk.value)
19+
return ruleSet
720
}
21+
822
return ruleSet.concat(chunk.toString())
923
}, [])
1024
}

packages/core/src/utils/styleManagement.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function insert(className: string, cssString: string) {
2626

2727
const ruleNode = insertedRuleMap[className]
2828
const rule = cssString
29-
29+
3030
if (ruleNode) {
3131
ruleNode.data = rule
3232
return
@@ -47,12 +47,15 @@ export function removeStyle(className: string): void {
4747
}
4848
}
4949

50-
export function injectStyle<T>(className: string, cssWithExpression: ExpressionType<T>[], context: Record<string, any>): void {
51-
const appliedCss = applyExpressions(cssWithExpression, context).join('')
50+
export function injectStyle<T>(className: string, cssWithExpression: ExpressionType<T>[], context: Record<string, any>): string[] {
51+
const tailwindClasses: string[] = []
52+
const appliedCss = applyExpressions(cssWithExpression, context, tailwindClasses).join('')
5253
let cssString = appliedCss
5354
if (className !== '') {
5455
cssString = `.${className}{${appliedCss}}`
5556
}
5657
const compiledCss = serialize(compile(cssString), middleware([prefixer, stringify]))
5758
insert(className, compiledCss)
59+
60+
return tailwindClasses
5861
}

packages/playground/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
</head>
88
<body>
99
<div id="app"></div>
10-
<script type="module" src="main.ts"></script>
10+
<script type="module" src="src/main.ts"></script>
1111
</body>
1212
</html>

packages/playground/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,10 @@
55
},
66
"dependencies": {
77
"vue": "^3.4.38"
8+
},
9+
"devDependencies": {
10+
"autoprefixer": "^10.4.20",
11+
"postcss": "^8.4.41",
12+
"tailwindcss": "^3.4.10"
813
}
914
}

packages/playground/postcss.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
}

packages/playground/App.vue renamed to packages/playground/src/App.vue

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { styled, ThemeProvider, keyframes, withAttrs, css, cssClass, createGlobalStyle } from '@vue-styled-components/core'
2+
import { styled, ThemeProvider, keyframes, withAttrs, css, cssClass, createGlobalStyle, tw } from '@/index'
33
import Component from './Component.vue'
44
import { ref } from 'vue'
55
@@ -126,13 +126,18 @@ const Global = createGlobalStyle`
126126
display: flex
127127
}
128128
`
129+
const tt = 'bg-white'
130+
const TwComponent = styled.div`
131+
${tw`text-2xl text-gray-100 text-lg ${tt}`}
132+
`
129133
</script>
130134

131135
<template>
132136
<ThemeProvider :theme="theme">
137+
<TwComponent>Test</TwComponent>
133138
<Global />
134139
<div @click="visible = !visible">Test Remove</div>
135-
<StyledComp3 @click="update">12345</StyledComp3>
140+
<StyledComp3 class="text-white" @click="update">12345</StyledComp3>
136141
<StyledComp4>12345</StyledComp4>
137142
<StyledComp5>12345</StyledComp5>
138143
<WithAttrsComp color="red">123</WithAttrsComp>
@@ -144,8 +149,6 @@ const Global = createGlobalStyle`
144149
<TestEmbedComponent :show="show"> White </TestEmbedComponent>
145150
<TestEmbedComponent :show="!show" @click="show = !show"> Blue </TestEmbedComponent>
146151

147-
<IconInner color="red" size="55"> 666 </IconInner>
148-
149152
<BlueButton v-if="visible" />
150153
</ThemeProvider>
151154
</template>

packages/playground/main.ts renamed to packages/playground/src/main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createApp } from 'vue'
22
import App from './App.vue'
3+
import './style.css'
34

45
const app = createApp(App)
56

packages/playground/src/style.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
File renamed without changes.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/** @type {import('tailwindcss').Config} */
2+
module.exports = {
3+
content: ['./src/**/*.{js,jsx,ts,tsx,vue}'],
4+
theme: {
5+
extend: {},
6+
},
7+
plugins: [],
8+
}

0 commit comments

Comments
 (0)