Skip to content

Commit

Permalink
feat(postcss): directive support in vue and svelte components (#2338)
Browse files Browse the repository at this point in the history
  • Loading branch information
sibbng committed Mar 18, 2023
1 parent f27b1fd commit 9b98b49
Show file tree
Hide file tree
Showing 17 changed files with 230 additions and 23 deletions.
1 change: 1 addition & 0 deletions examples/vite-svelte-postcss/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
shamefully-hoist=true
12 changes: 12 additions & 0 deletions examples/vite-svelte-postcss/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Svelte + TS + Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
23 changes: 23 additions & 0 deletions examples/vite-svelte-postcss/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "unocss-svelte-ts",
"type": "module",
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
"check": "svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
"@iconify-json/logos": "^1.1.23",
"@sveltejs/vite-plugin-svelte": "^2.0.3",
"@tsconfig/svelte": "^3.0.0",
"@unocss/postcss": "link:..\\..\\packages\\postcss",
"svelte": "^3.55.1",
"svelte-check": "^3.0.4",
"tslib": "^2.5.0",
"typescript": "^4.9.5",
"unocss": "link:../../packages/unocss",
"vite": "^4.1.4"
}
}
Empty file.
5 changes: 5 additions & 0 deletions examples/vite-svelte-postcss/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
plugins: {
'@unocss/postcss': {},
},
}
11 changes: 11 additions & 0 deletions examples/vite-svelte-postcss/public/uno.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions examples/vite-svelte-postcss/src/App.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<div text-center font-sans p4 flex flex-col items-center gap-8>
<div class="flex gap-4">
<div class="i-logos-svelte-icon text-3xl" />
<div class="i-logos-unocss text-3xl" />
<div class="i-logos-postcss text-3xl" />
</div>
<div text-gray2 text-2xl font-medium>
UnoCSS + Svelte + PostCSS
</div>
<div class="bg-[url(../src/uno.svg)] bg-[url(/uno.svg)]" h-220px w-220px />
<div class="flex gap-2 items-center">
<button>
Hello
</button>
<div class="dark">
<a href="#">Hello</a>
</div>
</div>
<div class="my-class">
Directives in Svelte SFC
</div>
</div>

<style lang="postcss">
@screen md {
.my-class {
@apply bg-red-800;
color: theme('colors.red.300');
}
}
</style>
8 changes: 8 additions & 0 deletions examples/vite-svelte-postcss/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import App from './App.svelte'
import './style.css'

const app = new App({
target: document.getElementById('app'),
})

export default app
30 changes: 30 additions & 0 deletions examples/vite-svelte-postcss/src/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@layer base, components, utilities;

@layer base {
@unocss preflights;
}

@layer utilities {
@unocss default;

@unocss;
}

@layer components {
html {
background: theme('colors.black');
color: theme('colors.gray.300');
}
button, a {
@apply focus-visible:outline-none focus:outline-2 focus:outline-offset-2 focus:outline-sky-600;
@apply [&:hover]:text-[#fff] bg-gray-900 hover:bg-gray-700 text-gray-200 text-base no-underline b-0 dark:hover:bg-blue-600;
@apply px-4 py-2 rounded-lg block;
}
}

@screen at-sm {
html {
background: theme('colors.gray.900');
}
}

11 changes: 11 additions & 0 deletions examples/vite-svelte-postcss/src/uno.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions examples/vite-svelte-postcss/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/// <reference types="svelte" />
/// <reference types="vite/client" />
/// <reference types="unocss/vite" />
5 changes: 5 additions & 0 deletions examples/vite-svelte-postcss/svelte.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'

export default {
preprocess: [vitePreprocess()],
}
19 changes: 19 additions & 0 deletions examples/vite-svelte-postcss/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"resolveJsonModule": true,
"baseUrl": ".",
/**
* Typecheck JS in `.svelte` and `.js` files by default.
* Disable checkJs if you'd like to use dynamic types in JS.
* Note that setting allowJs false does not prevent the use
* of JS in `.svelte` files.
*/
"allowJs": true,
"checkJs": true
},
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"]
}
29 changes: 29 additions & 0 deletions examples/vite-svelte-postcss/unocss.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {
defineConfig,
extractorSvelte,
presetAttributify,
presetIcons,
presetTypography,
presetUno,
presetWebFonts,
} from 'unocss'

export default defineConfig({
extractors: [extractorSvelte],
presets: [
presetUno({
attributifyPseudo: true,
}),
presetAttributify(),
presetIcons({
scale: 1.2,
}),
presetTypography(),
presetWebFonts({
provider: 'none',
fonts: {
script: 'Homemade Apple',
},
}),
],
})
9 changes: 9 additions & 0 deletions examples/vite-svelte-postcss/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [
svelte(),
],
})
12 changes: 12 additions & 0 deletions examples/vite-vue3-postcss/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,17 @@
<a href="#">Hello</a>
</div>
</div>
<div class="my-class">
Directives in Vue SFC
</div>
</div>
</template>

<style>
@screen md {
.my-class {
@apply bg-red-800;
color: theme('colors.red.300');
}
}
</style>
44 changes: 21 additions & 23 deletions packages/postcss/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,43 +48,48 @@ function unocss(options: UnoPostcssPluginOptions = {}) {
postcssPlugin: directiveMap.unocss,
plugins: [
async function (root: Root, result: Result) {
if (!result.opts.from?.split('?')[0].endsWith('.css'))
const from = result.opts.from?.split('?')[0]

if (!from)
return

let isTarget = false
let isTarget = targetCache.has(from)
const isScanTarget = root.toString().includes(`@${directiveMap.unocss}`)

if (targetRE.test(root.toString())) {
if (!targetCache.has(result.opts.from)) {
if (!isTarget) {
root.walkAtRules((rule) => {
if (
rule.name === directiveMap.unocss
|| rule.name === directiveMap.apply
|| rule.name === directiveMap.theme
|| rule.name === directiveMap.screen
|| rule.name === directiveMap.apply
|| rule.name === directiveMap.screen
)
isTarget = true

if (isTarget)
return false
})

if (!isTarget) {
const themeFn = themeFnRE(directiveMap.theme)
root.walkDecls((decl) => {
if (themeFn.test(decl.value))
if (themeFn.test(decl.value)) {
isTarget = true
return false
}
})
}
}
else {
isTarget = true
else {
targetCache.add(from)
}
}
}
else if (targetCache.has(result.opts.from)) {
targetCache.delete(result.opts.from)
else if (targetCache.has(from)) {
targetCache.delete(from)
}

if (!isTarget)
return
else
targetCache.add(result.opts.from)

try {
const cfg = await config
Expand All @@ -109,21 +114,14 @@ function unocss(options: UnoPostcssPluginOptions = {}) {
extension: string
}[] ?? []

const entries = await fg(globs, {
const entries = await fg(isScanTarget ? globs : from, {
cwd,
dot: true,
absolute: true,
ignore: ['**/{.git,node_modules}/**'],
stats: true,
}) as unknown as { path: string; mtimeMs: number }[]

result.messages.push({
type: 'dependency',
plugin: directiveMap.unocss,
file: result.opts.from,
parent: result.opts.from,
})

await parseApply(root, uno, directiveMap.apply)
await parseTheme(root, uno, directiveMap.theme)
await parseScreen(root, uno, directiveMap.screen)
Expand All @@ -142,7 +140,7 @@ function unocss(options: UnoPostcssPluginOptions = {}) {
type: 'dependency',
plugin: directiveMap.unocss,
file: normalize(file),
parent: result.opts.from,
parent: from,
})

if (fileMap.has(file) && mtimeMs <= fileMap.get(file))
Expand Down

0 comments on commit 9b98b49

Please sign in to comment.