Frameworks
Learn more about using @plumeria/unplugin outside React.
Plumeria compiles the css calls, not the component. Any framework Vite can build reaches it through the same @plumeria/unplugin entry — put plumeria.vite() in plugins beside the framework plugin.
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import plumeria from '@plumeria/unplugin';
export default defineConfig({
plugins: [vue(), plumeria.vite()],
});That file is the whole integration. examples/vite-vue-ts, examples/vite-svelte-ts, examples/vite-solid, examples/vite-preact, examples/vite-qwik, examples/react-router and examples/storybook are that file with the framework plugin swapped.
The styling prop
@plumeria/core/class-style declares classStyle on React's HTMLAttributes and SVGAttributes, so anything rendering through the React namespace needs one line:
/// <reference types="@plumeria/core/class-style" />A framework that keeps its JSX types in its own module cannot be reached that way. Module augmentation resolves the package from the file that writes it, and @plumeria/core does not depend on your framework, so the declaration has to live in your project:
import 'preact';
import type { Style } from '@plumeria/core';
declare module 'preact' {
namespace JSX {
interface HTMLAttributes {
classStyle?: Style;
}
interface SVGAttributes {
classStyle?: Style;
}
}
}import '@builder.io/qwik';
import type { Style } from '@plumeria/core';
declare module '@builder.io/qwik' {
interface HTMLAttributes extends JSX.HTMLAttributes {
classStyle?: Style;
}
interface SVGAttributes extends JSX.SVGAttributes {
classStyle?: Style;
}
}Declare SVGAttributes even where the framework has it extend HTMLAttributes and one interface would do — Qwik's extends AriaAttributes instead, and an <svg classStyle={...}> under a declaration that covers only HTML is rejected outright.
The type is Style. A name the package does not export is not reported here, so a stale one leaves classStyle accepting anything at all rather than failing.
Single-file components
The transform parses TypeScript and TSX. A .vue, .svelte or .astro file is neither, so css.create goes in a .ts module the component imports from:
import * as css from '@plumeria/core';
export const styles = css.create({
main: { color: 'teal' },
});<script setup lang="ts">
import { styles } from './style';
</script>
<template>
<div :class="styles.main">card</div>
</template>The lint rules read the same TypeScript, so the style module is covered by them.
The plugin receives the component file whole, before the framework splits its script block out, so a css.create written inside one fails the build on the surrounding markup:
[plugin @plumeria/unplugin:vite] src/components/HelloWorld.vue
Error: x Expected '</', got ':'A framework whose components are TSX — Qwik, Preact, Solid, React Router — has nowhere to put the call but the component, and needs no separate module.
Qwik
plumeria.vite() goes before qwikVite(). The Qwik optimizer rewrites the component and re-exports what it finds there, so it has to run on styles that are already compiled away:
import { defineConfig } from 'vite';
import { qwikVite } from '@builder.io/qwik/optimizer';
import plumeria from '@plumeria/unplugin';
export default defineConfig({
plugins: [plumeria.vite(), qwikVite({ csr: true })],
});The other order fails the build with Export 'styles' is not defined.
Astro
Astro takes Vite plugins under vite:
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import plumeria from '@plumeria/unplugin';
export default defineConfig({
vite: {
plugins: [plumeria.vite()],
},
integrations: [react()],
});