Skip to content

Commit 7db0fe0

Browse files
authored
feat: support auto imports (#50)
* feat: add auto imports for css and jsx * feat: add playground * feat: add pattern components * feat: add pattern functions * fix: fix playground * feat: add examples * feat: add example * feat: add example * feat: add autoImports option * fix: support later
1 parent 2a3ac9d commit 7db0fe0

File tree

12 files changed

+255
-30
lines changed

12 files changed

+255
-30
lines changed

.nuxtrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
imports.autoImport=false
1+
imports.autoImport=true
22
typescript.includeWorkspace=true

playground/app.vue

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
<template>
22
<NuxtPage />
33
</template>
4+
5+
<style>
6+
#__nuxt {
7+
height: 100%;
8+
}
9+
</style>
File renamed without changes.

playground/components/PButton.vue

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script setup lang="ts">
2+
import { css, cva } from "pandacss/css";
3+
import type { SystemStyleObject } from "pandacss/types";
4+
5+
const props = withDefaults(
6+
defineProps<{
7+
css?: SystemStyleObject;
8+
}>(),
9+
{
10+
css: () => ({}),
11+
}
12+
);
13+
14+
const buttonRecipe = cva({
15+
base: { display: "flex", fontSize: "lg" },
16+
variants: {
17+
variant: {
18+
primary: { color: "white", backgroundColor: "blue.500" },
19+
},
20+
},
21+
});
22+
23+
const className = css(
24+
// using the button recipe
25+
buttonRecipe.raw({ variant: "primary" }),
26+
27+
// adding style overrides (internal)
28+
{ _hover: { color: "blue.400" } },
29+
30+
// adding style overrides (external)
31+
props.css
32+
);
33+
</script>
34+
35+
<template>
36+
<button :class="className"><slot /></button>
37+
</template>

playground/nuxt.config.ts

+9-24
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,17 @@
11
export default defineNuxtConfig({
2-
modules: ["../src/module"],
2+
modules: ["../src/module", "@nuxt/devtools"],
33
pandacss: {
4-
theme: {
5-
tokens: {
6-
colors: {
7-
primary: { value: "#0FEE0F" },
8-
secondary: { value: "#EE0F0F" },
9-
},
10-
fontSizes: {
11-
"2xs": { value: "0.5rem" },
12-
xs: { value: "0.75rem" },
13-
sm: { value: "0.875rem" },
14-
md: { value: "1rem" },
15-
lg: { value: "1.125rem" },
16-
xl: { value: "1.25rem" },
17-
"2xl": { value: "1.5rem" },
18-
"3xl": { value: "1.875rem" },
19-
"4xl": { value: "2.25rem" },
20-
"5xl": { value: "3rem" },
21-
"6xl": { value: "3.75rem" },
22-
"7xl": { value: "4.5rem" },
23-
"8xl": { value: "6rem" },
24-
"9xl": { value: "8rem" },
25-
},
4+
theme: { extend: {} },
5+
globalCss: {
6+
html: {
7+
h: "full",
8+
},
9+
body: {
10+
bg: { base: "white", _dark: "#2C2C2C" },
2611
},
2712
},
2813
jsxFramework: "vue",
29-
cssPath: "@/css/global.css",
14+
cssPath: "@/assets/css/global.css",
3015
outdir: "pandacss",
3116
},
3217
devtools: { enabled: true },

playground/pages/atomic_recipes.vue

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<script setup lang="ts">
2+
import { center } from "pandacss/patterns";
3+
4+
const button = cva({
5+
base: {
6+
borderRadius: "md",
7+
fontWeight: "semibold",
8+
h: "10",
9+
px: "4",
10+
},
11+
variants: {
12+
visual: {
13+
solid: {
14+
bg: { base: "colorPalette.500", _dark: "colorPalette.300" },
15+
color: { base: "white", _dark: "gray.800" },
16+
},
17+
outline: {
18+
border: "1px solid",
19+
color: { base: "colorPalette.600", _dark: "colorPalette.200" },
20+
borderColor: "currentColor",
21+
},
22+
},
23+
},
24+
});
25+
</script>
26+
27+
<template>
28+
<div :class="center({ colorPalette: 'yellow', h: 'full', gap: '4' })">
29+
<button :class="button({ visual: 'solid' })">Button</button>
30+
<button :class="button({ visual: 'outline' })">Button</button>
31+
</div>
32+
</template>

playground/pages/index.vue

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
<script setup lang="ts">
2-
import { css } from "pandacss/css";
3-
import { styled } from "pandacss/jsx";
2+
import { center } from "pandacss/patterns";
43
</script>
54

65
<template>
7-
<styled.h1 fontSize="5xl" fontWeight="bold">Panda CSS x Nuxt</styled.h1>
8-
<div :class="css({ fontSize: '5xl', fontWeight: 'bold', color: 'primary' })">
9-
Hello 🐼!
6+
<div :class="center({ h: 'full' })">
7+
<div
8+
:class="
9+
css({
10+
display: 'flex',
11+
flexDirection: 'column',
12+
fontWeight: 'semibold',
13+
color: 'yellow.300',
14+
textAlign: 'center',
15+
textStyle: '4xl',
16+
})
17+
"
18+
>
19+
<span>🐼</span>
20+
<span>Hello from Panda</span>
21+
</div>
1022
</div>
1123
</template>

playground/pages/patterns.vue

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<script setup lang="ts">
2+
import { square, flex, circle, center } from "pandacss/patterns";
3+
import { Circle } from "pandacss/jsx";
4+
</script>
5+
6+
<template>
7+
<div
8+
:class="
9+
cx(
10+
flex({
11+
gap: '4',
12+
direction: 'column',
13+
}),
14+
center({ h: 'full' })
15+
)
16+
"
17+
>
18+
<div :class="flex({ gap: '6', padding: '1' })">
19+
<div :class="square({ size: '11', bg: 'yellow.300' })">1</div>
20+
<div :class="square({ size: '11', bg: 'red.300' })">2</div>
21+
<div :class="square({ size: '11', bg: 'green.300' })">3</div>
22+
</div>
23+
24+
<div
25+
:class="
26+
flex({
27+
direction: 'row',
28+
align: 'center',
29+
gap: '4',
30+
})
31+
"
32+
>
33+
<div :class="circle({ size: '12', bg: 'blue.300' })">1</div>
34+
<div :class="circle({ size: '12', bg: 'orange.300' })">2</div>
35+
<Circle size="12" bg="violet.300">3</Circle>
36+
</div>
37+
</div>
38+
</template>

playground/pages/slot_recipes.vue

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<script setup lang="ts">
2+
import { center } from "pandacss/patterns";
3+
4+
const card = sva({
5+
slots: ["root", "title", "content"],
6+
base: {
7+
root: {
8+
p: "6",
9+
m: "4",
10+
w: "md",
11+
boxShadow: "md",
12+
borderRadius: "md",
13+
_dark: { bg: "#262626", color: "white" },
14+
},
15+
content: {
16+
textStyle: "lg",
17+
},
18+
title: {
19+
textStyle: "xl",
20+
fontWeight: "semibold",
21+
pb: "2",
22+
},
23+
},
24+
});
25+
26+
const styles = card();
27+
</script>
28+
29+
<template>
30+
<div :class="center({ h: 'full' })">
31+
<div :class="styles.root">
32+
<div :class="styles.title">Team Members</div>
33+
<div :class="styles.content">Content</div>
34+
</div>
35+
</div>
36+
</template>

src/imports/presets.ts

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import type { ModuleOptions } from "./../types";
2+
import type { InlinePreset } from "unimport";
3+
import { defineUnimportPreset } from "unimport";
4+
5+
export const createPresets = ({
6+
outdir,
7+
}: Pick<ModuleOptions, "outdir">): InlinePreset[] => {
8+
return [
9+
defineUnimportPreset({
10+
from: `${outdir}/css`,
11+
imports: ["css", "cva", "sva", "cx"],
12+
}),
13+
// TODO: jsx doesn't work with auto imports
14+
// defineUnimportPreset({
15+
// from: `${outdir}/jsx`,
16+
// imports: [
17+
// "styled",
18+
// "AspectRatio",
19+
// "Bleed",
20+
// "Box",
21+
// "Center",
22+
// "Circle",
23+
// "Container",
24+
// "Divider",
25+
// "Flex",
26+
// "Float",
27+
// "GridItem",
28+
// "Grid",
29+
// "HStack",
30+
// "LinkBox",
31+
// "LinkOverlay",
32+
// "Spacer",
33+
// "Square",
34+
// "Stack",
35+
// "VisuallyHidden",
36+
// "VStack",
37+
// "Wrap",
38+
// ],
39+
// }),
40+
// TODO: pattenrs doesn't work with auto imports
41+
// defineUnimportPreset({
42+
// from: `${outdir}/patterns`,
43+
// imports: [
44+
// "aspectRatio",
45+
// "bleed",
46+
// "box",
47+
// "center",
48+
// "circle",
49+
// "container",
50+
// "divider",
51+
// "flex",
52+
// "float",
53+
// "gridItem",
54+
// "grid",
55+
// "hStack",
56+
// "linkBox",
57+
// "linkOverlay",
58+
// "spacer",
59+
// "square",
60+
// "stack",
61+
// "visuallyHidden",
62+
// "vStack",
63+
// "wrap",
64+
// ],
65+
// }),
66+
];
67+
};

src/module.ts

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
addImportsSources,
23
addTemplate,
34
createResolver,
45
defineNuxtModule,
@@ -11,6 +12,7 @@ import { join } from "pathe";
1112
import { configKey, name, version } from "../package.json";
1213
import { resolveCSSPath } from "./resolvers";
1314
import type { ModuleOptions } from "./types";
15+
import { createPresets } from "./imports/presets";
1416

1517
const logger = useLogger("nuxt:pandacss");
1618

@@ -27,6 +29,7 @@ export default defineNuxtModule<ModuleOptions>({
2729
outdir: "styled-system",
2830
cwd: nuxt.options.buildDir,
2931
cssPath: `${nuxt.options.buildDir}/panda.css`,
32+
autoImports: true,
3033
}),
3134
async setup(options, nuxt) {
3235
const { resolve } = createResolver(import.meta.url);
@@ -41,6 +44,10 @@ export default defineNuxtModule<ModuleOptions>({
4144
"./*"
4245
);
4346

47+
if (options.autoImports) {
48+
addImportsSources(createPresets({ outdir: options.outdir }));
49+
}
50+
4451
if (existsSync(resolve(nuxt.options.buildDir, "panda.config.mjs"))) {
4552
await fsp.rm(resolve(nuxt.options.buildDir, "panda.config.mjs"));
4653
}

src/types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,9 @@ export interface ModuleOptions extends Config {
1515
* @example '@/assets/css/global.css'
1616
*/
1717
cssPath?: string;
18+
/**
19+
* Automatically add to the auto imports.
20+
* @default true
21+
*/
22+
autoImports?: boolean;
1823
}

0 commit comments

Comments
 (0)