Skip to content

Commit 205cdff

Browse files
authored
feat: support tailwindcss function and directives feature (opentiny#1653)
1 parent a6e91ae commit 205cdff

5 files changed

Lines changed: 57 additions & 7 deletions

File tree

packages/build/vite-config/src/default-config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ const getDefaultConfig = (engineConfig) => {
8989
]
9090
}
9191
},
92+
define: {
93+
'process.env': {}
94+
},
9295
build: {
9396
commonjsOptions: {
9497
transformMixedEsModules: true,

packages/canvas/DesignCanvas/src/DesignCanvas.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,8 @@ export default {
290290
getBlockByName: useMaterial().getBlockByName,
291291
useModal,
292292
useMessage,
293-
useNotify
293+
useNotify,
294+
enableTailwindCSS: getMergeMeta('engine.config')?.enableTailwindCSS
294295
},
295296
isBlock,
296297
getMoveDragBarState,

packages/canvas/render/src/material-function/page-getter.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,31 @@ async function fetchPageSchema(pageId: string) {
1212
return res.page_content
1313
})
1414
}
15-
const styleSheetMap = new Map()
15+
16+
// tailwindcss function and directive 特性需要使用 <style type="text/tailwindcss"> 标签
17+
// https://tailwindcss.com/docs/functions-and-directives
18+
// 所以原来 new CSSStyleSheet 的方式改成了 document.createElement('style') 的方式
1619
export function initStyle(key: string, content: string) {
1720
if (!content) {
1821
return
1922
}
20-
let styleSheet = styleSheetMap.get(key)
23+
24+
let styleSheet = document.querySelector(`#${key}`)
25+
2126
if (!styleSheet) {
22-
styleSheet = new CSSStyleSheet()
23-
styleSheetMap.set(key, styleSheet)
24-
document.adoptedStyleSheets.push(styleSheet)
27+
styleSheet = document.createElement('style')
28+
styleSheet.setAttribute('id', key)
29+
if (getController().enableTailwindCSS) {
30+
styleSheet.setAttribute('type', 'text/tailwindcss')
31+
}
32+
document.head.appendChild(styleSheet)
2533
}
34+
2635
handleScopedCss(key, content).then((scopedCss) => {
27-
styleSheet.replaceSync(scopedCss)
36+
styleSheet.textContent = scopedCss.css
2837
})
2938
}
39+
3040
export const wrapPageComponent = (pageId: string) => {
3141
const key = `data-te-page-${pageId}`
3242
const asyncData = ref(null)

packages/design-core/src/preview/src/preview/generate.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ export const processAppJsCode = (code, cssList, enableTailwindCSS) => {
163163

164164
if (enableTailwindCSS && !code.includes('@tailwindcss/browser')) {
165165
res += `\nimport('@tailwindcss/browser')\n`
166+
res += `\nenableTailwindCSS()\n`
166167
}
167168

168169
return res

packages/design-core/src/preview/src/preview/srcFiles/app.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,38 @@ function addCss(href) {
1818
}
1919
addCss('${VITE_CDN_DOMAIN}/@opentiny/vue-theme${versionDelimiter}3.20${fileDelimiter}/index.css')
2020
addCss('${VITE_CDN_DOMAIN}/@opentiny/vue-theme-mobile${versionDelimiter}3.20${fileDelimiter}/index.css')
21+
22+
// tailwindcss function and directive 特性需要使用 <style type="text/tailwindcss"> 标签
23+
// https://tailwindcss.com/docs/functions-and-directives
24+
// vue-repl 默认是使用 style[css] 标签,我们需要将它转换为 <style type="text/tailwindcss"> 标签
25+
// 并重新插入一遍使得 tailwindcss 识别并生效
26+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
27+
async function enableTailwindCSS(tryCount = 0) {
28+
if (tryCount > 100) {
29+
return
30+
}
31+
32+
while (!document.querySelectorAll('style[css]').length) {
33+
await new Promise((resolve) => setTimeout(resolve, 200))
34+
enableTailwindCSS(tryCount + 1)
35+
return
36+
}
37+
38+
const allStyles = document.querySelectorAll('style[css]')
39+
allStyles.forEach((el) => {
40+
const content = el.innerHTML
41+
const attributes = {}
42+
Array.from(el.attributes).forEach((attr) => {
43+
attributes[attr.name] = attr.value
44+
})
45+
46+
el.remove()
47+
48+
attributes.type = 'text/tailwindcss'
49+
const attributeText = Object.entries(attributes)
50+
.map(([key, value]) => `${key}="${value}"`)
51+
.join(' ')
52+
53+
document.head.insertAdjacentHTML('beforeend', `<style ${attributeText}>${content}</style>`)
54+
})
55+
}

0 commit comments

Comments
 (0)