### Install @plumeria/headlessui with pnpm Source: https://plumeria.dev/docs/api-reference/components/headlessui.md Install the package using pnpm. Requires configuration of @plumeria/core and your bundler as described in the Installation section. ```sh pnpm i @plumeria/headlessui ``` -------------------------------- ### Install @plumeria/headlessui with yarn Source: https://plumeria.dev/docs/api-reference/components/headlessui.md Install the package using yarn. Requires configuration of @plumeria/core and your bundler as described in the Installation section. ```sh yarn add @plumeria/headlessui ``` -------------------------------- ### Install @plumeria/headlessui with npm Source: https://plumeria.dev/docs/api-reference/components/headlessui.md Install the package using npm. Requires configuration of @plumeria/core and your bundler as described in the Installation section. ```sh npm i @plumeria/headlessui ``` -------------------------------- ### Minimum context Source: https://plumeria.dev/docs/ai-agent-resources.md Use this minimal context to provide an agent with the essential Plumeria documentation links when a shorter prompt is sufficient. It includes the installation guide, the AI rules, and the core documentation. ```text https://plumeria.dev/docs/getting-started/installation.md https://plumeria.dev/docs/ai.md https://plumeria.dev/docs.md ``` -------------------------------- ### Install Plumeria with yarn Source: https://plumeria.dev/docs/getting-started Install @plumeria/core as a dev dependency using yarn. ```bash yarn add -D @plumeria/core ``` -------------------------------- ### Install Plumeria with pnpm Source: https://plumeria.dev/docs/getting-started Install @plumeria/core as a dev dependency using pnpm. ```bash pnpm add -D @plumeria/core ``` -------------------------------- ### Install Plumeria with npm Source: https://plumeria.dev/docs/getting-started Install @plumeria/core as a dev dependency using npm. ```bash npm install -D @plumeria/core ``` -------------------------------- ### Configure @plumeria/unplugin Source: https://plumeria.dev/docs/api-reference/plugins/unplugin.md Basic configuration example for the Plumeria plugin within a bundler setup. ```ts import plumeria from '@plumeria/unplugin'; export default { plugins: [ plumeria.vite({ include: ['**/*.{ts,tsx}'], exclude: ['**/node_modules/**'], devEmitToDisk: false, styleProp: 'sx', }), ], }; ``` -------------------------------- ### Install @plumeria/inspector with yarn Source: https://plumeria.dev/docs/api-reference/components/inspector.md Install the package using the yarn package manager. ```sh yarn add @plumeria/inspector ``` -------------------------------- ### StaticStyles usage examples Source: https://plumeria.dev/docs/api-reference/types/StaticStyles.md Usage examples for the Chip component. Passing a static style is accepted, while passing a dynamic style results in a type error. ```tsx // ok // Type error ``` -------------------------------- ### Install @plumeria/inspector with pnpm Source: https://plumeria.dev/docs/api-reference/components/inspector.md Install the package using the pnpm package manager. ```sh pnpm i @plumeria/inspector ``` -------------------------------- ### Configure withPlumeria options Source: https://plumeria.dev/docs/api-reference/plugins/next-plugin.md Example of passing options to withPlumeria, including include, exclude, and styleProp. ```ts export default withPlumeria(nextConfig, { include: ['./src/**/*.{ts,tsx}'], exclude: ['**/node_modules/**', '**/.next/**'], styleProp: 'sx', }); ``` -------------------------------- ### Install @plumeria/next-plugin with npm, yarn, or pnpm Source: https://plumeria.dev/docs/getting-started/installation.md Install the Next.js plugin as a dev dependency using your preferred package manager. ```sh npm i -D @plumeria/next-plugin ``` ```sh yarn add -D @plumeria/next-plugin ``` ```sh pnpm add -D @plumeria/next-plugin ``` -------------------------------- ### Install oxlint and rimraf for plumerialint Source: https://plumeria.dev/docs/getting-started/installation.md Install `oxlint` and `rimraf` as dev dependencies. `oxlint` is required to run the `plumerialint` command, and `rimraf` is recommended for cleaning the cache in Next.js projects. ```sh pnpm i -D oxlint rimraf ``` -------------------------------- ### Install @plumeria/inspector with npm Source: https://plumeria.dev/docs/api-reference/components/inspector.md Install the package using the npm package manager. ```sh npm i @plumeria/inspector ``` -------------------------------- ### Install Plumeria ESLint plugin with npm Source: https://plumeria.dev/docs/getting-started/editor-integration.md Install the required ESLint plugin and oxlint using npm. ```sh npm i --save-dev @plumeria/eslint-plugin oxlint ``` -------------------------------- ### Install @plumeria/unplugin with yarn Source: https://plumeria.dev/docs/api-reference/plugins/unplugin.md Install the plugin using the yarn package manager. ```sh yarn add -D @plumeria/unplugin ``` -------------------------------- ### Install @plumeria/unplugin with npm Source: https://plumeria.dev/docs/api-reference/plugins/unplugin.md Install the plugin using the npm package manager. ```sh npm i -D @plumeria/unplugin ``` -------------------------------- ### Install @plumeria/eslint-plugin with npm, yarn, or pnpm Source: https://plumeria.dev/docs/api-reference/plugins/eslint-plugin.md Install the @plumeria/eslint-plugin package using npm, yarn, or pnpm. Choose the command that matches your package manager. ```sh npm i --save-dev @plumeria/eslint-plugin ``` ```sh yarn add -D @plumeria/eslint-plugin ``` ```sh pnpm i --save-dev @plumeria/eslint-plugin ``` -------------------------------- ### User integration example (app.tsx) Source: https://plumeria.dev/docs/integration/component-library.md Shows the entire integration from a user's perspective: import the component and use it. The component brings its own stylesheet, so no bundler configuration or `@plumeria/*` dependency is needed. ```tsx import { Card } from 'your-lib'; export const App = () => ; ``` -------------------------------- ### css.use() usage example Source: https://plumeria.dev/docs/api-reference/javascript/use.md Shows how to use css.use() to get a class name string for external components. Both classStyle and css.use() are compiled at build time with zero runtime overhead. ```ts import * as css from '@plumeria/core'; const styles = css.create({ text: { fontSize: '16px' } }); // Get the class name as a string const className = css.use(styles.text); // Apply to an external component ``` -------------------------------- ### Install @plumeria/unplugin with npm, yarn, or pnpm Source: https://plumeria.dev/docs/integration/rolldown.md Install the @plumeria/unplugin package using npm, yarn, or pnpm. These are alternative package manager commands for the same installation step. ```sh npm i -D @plumeria/unplugin ``` ```sh yarn add -D @plumeria/unplugin ``` ```sh pnpm i -D @plumeria/unplugin ``` -------------------------------- ### Define physical and logical padding properties Source: https://plumeria.dev/docs/reference/specificity.md Example showing how paddingTop and paddingBlockStart are treated as the same property in horizontal writing modes. ```js const styles = css.create({ physical: { paddingTop: 4 }, logical: { paddingBlockStart: 10 }, }); ``` -------------------------------- ### Install @plumeria/unplugin with pnpm Source: https://plumeria.dev/docs/api-reference/plugins/unplugin.md Install the plugin using the pnpm package manager. ```sh pnpm i -D @plumeria/unplugin ``` -------------------------------- ### Define static media query breakpoints with createStatic Source: https://plumeria.dev/docs/api-reference/javascript/createStatic.md Example from the '#example' section defining breakpoints for standard media queries using createStatic. These static values can be used inside create or createTheme as conditions. ```ts import * as css from '@plumeria/core'; export const breakpoints = css.createStatic({ xs: '@media (max-width: 480px)', sm: '@media (max-width: 640px)', md: '@media (max-width: 768px)', lg: '@media (max-width: 1024px)', xl: '@media (max-width: 1280px)', }); ``` -------------------------------- ### Install Plumeria ESLint plugin with yarn Source: https://plumeria.dev/docs/getting-started/editor-integration.md Install the required ESLint plugin and oxlint using yarn. ```sh yarn add -D @plumeria/eslint-plugin oxlint ``` -------------------------------- ### Define and use keyframes Source: https://plumeria.dev/docs/api-reference/javascript/keyframes.md Example showing how to define an animation using css.keyframes and apply it within a css.create style object. ```ts import * as css from '@plumeria/core' const fadeIn = css.keyframes({ from: { opacity: 0, }, to: { opacity: 1, }, }); const styles = css.create({ box: { animationName: fadeIn, animationDuration: '1s', animationTimingFunction: 'ease-in-out', }, }); ``` ```css @keyframes kf-x34h9adh { from { opacity: 0; } to { opacity: 1; } } .xhc714s1:not(#\#) { animation-name: kf-x34h9adh; } .xdm4omap:not(#\#) { animation-duration: 1s; } .xvct32ng:not(#\#) { animation-timing-function: ease-in-out; } ``` -------------------------------- ### Install @plumeria/unplugin with npm, yarn, or pnpm Source: https://plumeria.dev/docs/getting-started/installation.md Install the Vite plugin as a dev dependency using your preferred package manager. ```sh npm i -D @plumeria/unplugin ``` ```sh yarn add -D @plumeria/unplugin ``` ```sh pnpm add -D @plumeria/unplugin ``` -------------------------------- ### Macro usage example Source: https://plumeria.dev/docs/getting-started/editor-integration.md The expected expansion behavior for the classStyle snippet in JSX. ```jsx
-> Enter ->
``` -------------------------------- ### Install @plumeria/codemod with npm, yarn, or pnpm Source: https://plumeria.dev/docs/api-reference/codemod.md Install the codemod as a dev dependency using npm, yarn, or pnpm. The package depends on ESLint and its TypeScript parser, and on nothing from Plumeria. ```sh npm i --save-dev @plumeria/codemod ``` ```sh yarn add -D @plumeria/codemod ``` ```sh pnpm i --save-dev @plumeria/codemod ``` -------------------------------- ### Example compiled component output Source: https://plumeria.dev/docs/testing.md The resulting HTML after the Plumeria plugin compiles a component, showing generated class names. ```html

Vite + React

``` -------------------------------- ### Install @plumeria/core with npm, yarn, or pnpm Source: https://plumeria.dev/docs/getting-started/installation.md Install the core package as a dev dependency using your preferred package manager. The core package contains only type definitions; the bundle and runtime are not included. ```sh npm i -D @plumeria/core ``` ```sh yarn add -D @plumeria/core ``` ```sh pnpm i -D @plumeria/core ``` -------------------------------- ### Define styles with pseudo-classes Source: https://plumeria.dev/docs/reference/specificity.md Example of defining separate styles for :hover and :focus states using css.create. ```js const styles = css.create({ hovered: { ':hover': { color: 'red' } }, focused: { ':focus': { color: 'blue' } }, }); ``` -------------------------------- ### TypeScript example using marker and extended Source: https://plumeria.dev/docs/api-reference/javascript/marker.md Complete TypeScript example showing how to use `css.marker` and `css.extended` to style a child element based on parent hover states. It defines keyframes, creates styles with markers on 'grand' and 'parent', and applies extended styles to the child. ```tsx import * as css from '@plumeria/core'; const animation = css.keyframes({ '0%': { scale: 1.2, }, '50%': { scale: 1.3, }, '100%': { scale: 1.2, }, }); const styles = css.create({ grand: { display: 'flex', flexDirection: 'column', gap: 15, alignItems: 'center', justifyContent: 'center', width: '100%', minHeight: 250, padding: 20, border: '2px dashed #c4c4c466', borderRadius: 12, transition: 'all 0.3s', ...css.marker('grand', ':hover'), // [!code highlight] }, parent: { display: 'flex', flexDirection: 'column', gap: 10, alignItems: 'center', justifyContent: 'center', width: '80%', minHeight: 120, padding: 10, backgroundColor: '#f5f5f7', border: '2px solid #c4c4c444', borderRadius: 8, transition: 'all 0.3s', ...css.marker('parent', ':hover'), // [!code highlight] }, child: { padding: '8px 16px', fontWeight: 'bold', color: '#86868b', background: '#e8e8ed', borderRadius: 6, transition: 'all 0.3s', [css.extended('grand', ':hover')]: { // [!code highlight] color: '#0066cc', background: '#e1f0ff', }, [css.extended('parent', ':hover')]: { // [!code highlight] color: '#ffffff', background: '#ff9500', scale: 1.2, ':hover': { background: 'skyblue', animationName: animation, animationDuration: '1.2s', animationTimingFunction: 'ease-in-out', animationIterationCount: 'infinite', }, }, }, discription: { fontSize: '14px', color: '#86868b', }, }); const MarkerExtended = () => { return (
Grand Container (Hover me)
Parent Container (Hover me too)
Child Element
); }; ``` -------------------------------- ### Use static breakpoints in create for responsive styles Source: https://plumeria.dev/docs/api-reference/javascript/createStatic.md Usage example showing how to use static values defined by createStatic (like breakpoints.sm and breakpoints.lg) as keys in the create function to apply conditional styles. ```ts import * as css from "@plumeria/core"; import { breakpoints } from "lib/mediaQuery"; export const styles = css.create({ container: { [breakpoints.sm]: { padding: 16, }, [breakpoints.lg]: { padding: 32, }, }, }); ``` -------------------------------- ### Spinner.module.css with keyframes Source: https://plumeria.dev/docs/api-reference/codemod.md Example stylesheet with a `@keyframes` rule and an `animation` shorthand. The migration converts the keyframes into a `css.keyframes` binding and splits the shorthand into longhands. ```css /* Spinner.module.css */ @keyframes spin { from { rotate: 0deg } to { rotate: 360deg } } .icon { animation: spin 1s linear infinite } ``` -------------------------------- ### Card.module.css before migration Source: https://plumeria.dev/docs/api-reference/codemod.md Example `Card.module.css` stylesheet that the migration converts. It shows a base class, a `composes` rule, a hover state, and a descendant selector. ```css .base { font-size: 12px } .card { composes: base; padding: 16px } .card:hover { background: teal } .card .card-title { color: red } ``` -------------------------------- ### Generated CSS from marker and extended example Source: https://plumeria.dev/docs/api-reference/javascript/marker.md The CSS output generated from the TypeScript example. It shows how `marker` sets CSS variables on hover and `extended` uses `@container style()` queries to apply styles to child elements. ```css .xtkxh191:hover { --xl0a2l54-grand-hover: 1; } .xhcsnlrf:hover { --xmlppxj5-parent-hover: 1; } @container style(--xl0a2l54-grand-hover: 1) { .x84muc4x:not(#\#) { color: #06c; } .x2x6k4j2:not(#\#):not(#\#) { background-color: #e1f0ff; } } @container style(--xmlppxj5-parent-hover: 1) { .xr8ck8y9:not(#\#) { color: #fff; } .xb1yp2w2:not(#\#):not(#\#) { background-color: #ff9500; } .xewf73ay:not(#\#) { scale: 1.3; } .x8odz1r5:not(#\#):not(#\#) { animation-name: kf-xmortmuw; } .x0guwijo:not(#\#):not(#\#) { animation-duration: 1.2s; } .xek6euru:not(#\#):not(#\#) { animation-timing-function: ease-in-out; } .xwdc6dqv:not(#\#):not(#\#) { animation-iteration-count: infinite; } .xd9yj17o:not(#\#):hover { color: #0ff; } } ``` -------------------------------- ### Configure property rejection options Source: https://plumeria.dev/docs/api-reference/plugins/unplugin.md Examples of using withoutPhysicalProperties to enforce property naming conventions. ```ts plumeria.vite({ withoutPhysicalProperties: true }); ``` ```ts plumeria.vite({ withoutPhysicalProperties: { sizes: true } }); ``` -------------------------------- ### Trigger animations on hover Source: https://plumeria.dev/docs/api-reference/javascript/keyframes.md Example demonstrating how to apply keyframes within pseudo-selectors like :hover. ```ts const styles = css.create({ card: { transition: 'transform 0.3s ease', ':hover': { animationName: fadeIn, animationDuration: '0.5s', }, }, }); ``` -------------------------------- ### Rename property signature Source: https://plumeria.dev/docs/api-reference/codemod.md Example of the transformation applied to property signatures annotated with Style. ```diff interface CardProps { - classStyle?: Style; + sx?: Style; } ``` -------------------------------- ### classStyle usage example Source: https://plumeria.dev/docs/api-reference/javascript/use.md Shows how to apply styles with the classStyle prop. Supports arrays for conditional styles; false values are excluded automatically. ```tsx import * as css from '@plumeria/core'; const styles = css.create({ base: { color: 'red' }, active: { fontWeight: 'bold' } }); function Component({ active }) { return (
Hello
); } ``` -------------------------------- ### Use Style in Component Source: https://plumeria.dev/docs/api-reference/types/Style.md Example of using styles created with css.create in a component's classStyle prop. ```tsx import * as css from '@plumeria/core'; const styles = css.create({ base: { color: 'red', }, active: { fontWeight: 'bold', }, }); export function Component({ active }: { active: boolean }) { return
; } ``` -------------------------------- ### Configure esbuild with @plumeria/unplugin Source: https://plumeria.dev/docs/integration/esbuild.md Example esbuild build script that uses the plumeria.esbuild plugin to compile Plumeria styles into the CSS asset. The plugin is configured with an include regex for JSX/TSX files. ```ts import esbuild from 'esbuild'; import plumeria from '@plumeria/unplugin'; esbuild .build({ entryPoints: ['src/index.tsx'], bundle: true, outfile: 'dist/bundle.js', plugins: [ plumeria.esbuild({ include: /\.[jt]sx?$/, }), ], loader: { '.tsx': 'tsx', '.ts': 'ts', }, format: 'esm', minify: false, }) .catch(() => process.exit(1)); ``` -------------------------------- ### Run rename-prop with npx Source: https://plumeria.dev/docs/api-reference/codemod.md Runs the codemod without installing it locally. Use this to apply the rename-prop transform directly via npx. ```sh npx @plumeria/codemod rename-prop classStyle sx ``` -------------------------------- ### Class list order in JSX Source: https://plumeria.dev/docs/api-reference/codemod.md Demonstrates that class lists in JSX carry no inherent order, as both examples render the same page. ```tsx
``` -------------------------------- ### Generated CSS for markers and extended styles Source: https://plumeria.dev/docs/api-reference/codemod.md Example of how css.marker and css.extended are compiled into CSS custom properties and container queries. ```css .grand:hover { --xl0a2l54-grand-hover: 1; } @container style(--xl0a2l54-grand-hover: 1) { .child { color: #0066cc; } } ``` -------------------------------- ### Reported conversion issues Source: https://plumeria.dev/docs/api-reference/codemod.md Example of the diagnostic output generated when Plumeria constructs cannot be statically resolved or exported. ```text src/Card.tsx 8:5 dynamic-value The value of `color` cannot be represented statically. 12:3 spread-create Top-level spreads cannot name a CSS Module class. 19:16 style-type-reference `css.StaticStyles` has no CSS Modules equivalent, and the import that declares it does not survive the export of Card.tsx. ``` -------------------------------- ### Using CSSProperties with satisfies in createStatic Source: https://plumeria.dev/docs/api-reference/types/CSSProperties.md Example showing how to use CSSProperties with satisfies to create a static style object and then use it in a create call. The spread of flexBox is compiled by createStatic. ```typescript import * as css from '@plumeria/core'; const flexBox = css.createStatic({ display: 'flex', alignItems: 'center', justifyContent: 'center', } satisfies css.CSSProperties); export const styles = css.create({ container: { ...flexBox, backgroundColor: 'red', }, }); ``` -------------------------------- ### Define overlapping border shorthands Source: https://plumeria.dev/docs/reference/specificity.md Example of borderTop and borderBlockWidth overlapping on border-top-width without a clear specificity ranking. ```js const styles = css.create({ edge: { borderTop: '1px solid red' }, axis: { borderBlockWidth: 5 }, }); ``` -------------------------------- ### Rename JSX attribute Source: https://plumeria.dev/docs/api-reference/codemod.md Example of the transformation applied to JSX attributes. ```diff -
+
``` -------------------------------- ### Composition order override Source: https://plumeria.dev/docs/api-reference/codemod.md Example showing the transformation of a dynamic classStyle array into an override class to maintain composition order. ```diff -
+
``` ```css .surfaceOverRaised:not(#\#) { padding: 8px; color: black; } ``` -------------------------------- ### Build error for css.create in component markup Source: https://plumeria.dev/docs/integration/frameworks.md Example of the build error encountered when attempting to use css.create directly inside a component file. ```text [plugin @plumeria/unplugin:vite] src/components/HelloWorld.vue Error: x Expected '; }; ``` -------------------------------- ### Configure custom styleProp Source: https://plumeria.dev/docs/api-reference/plugins/unplugin.md Example of setting a custom style property name in the plugin configuration and declaring it for TypeScript. ```ts plumeria.vite({ styleProp: 'sx' }); ``` ```ts import type { Style } from '@plumeria/core'; declare global { namespace React { interface HTMLAttributes { sx?: Style; } interface SVGAttributes { sx?: Style; } } } ``` -------------------------------- ### Using StyleProps in a component (TypeScript) Source: https://plumeria.dev/docs/api-reference/types/StyleProps.md Shows how to use StyleProps to type a component's style prop, restricting it to specific properties like 'color' and 'fontSize'. The example imports from '@plumeria/core' and creates a Text component that accepts a classStyle prop. ```tsx import * as css from '@plumeria/core'; const styles = css.create({ base: { fontSize: '14px', }, }); type TextProps = { classStyle?: css.StyleProps<'color' | 'fontSize'>; }; export function Text({ classStyle }: TextProps) { return ; } ``` -------------------------------- ### Migrate from CSS Modules Source: https://plumeria.dev/docs/why-plumeria.md Run this command to convert each `*.module.css` file to a `*.styles.ts` file and update consumers. Unconvertible descendant rules become markers with extended styles. ```sh npx @plumeria/codemod migrate --from css-modules ``` -------------------------------- ### Migrate from Plumeria back to CSS Modules Source: https://plumeria.dev/docs/why-plumeria.md Run this command to convert `*.styles.ts` files back to `*.module.css`, moving theme tokens and animations to global CSS and call sites to `className`. This is an export, not a round trip. ```sh npx @plumeria/codemod migrate --from plumeria ``` -------------------------------- ### Configure rollup.config.js with plumeria.rollup() Source: https://plumeria.dev/docs/integration/rollup.md Configure rollup to use the Plumeria unplugin. The plugin is added as plumeria.rollup() and must be placed before postcss({ extract: true }) to compile Plumeria styles into the CSS asset. The example also includes plugins for resolving modules, commonjs, replacing process.env.NODE_ENV, and esbuild for JSX/TSX. ```js import plumeria from '@plumeria/unplugin'; import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import replace from '@rollup/plugin-replace'; import esbuild from 'rollup-plugin-esbuild'; import postcss from 'rollup-plugin-postcss'; export default { input: 'src/index.tsx', output: { dir: 'dist', format: 'esm', }, plugins: [ plumeria.rollup(), postcss({ extract: true }), resolve({ extensions: ['.js', '.jsx', '.ts', '.tsx'] }), commonjs(), replace({ 'process.env.NODE_ENV': JSON.stringify('development'), preventAssignment: true, }), esbuild({ include: /\.[jt]sx?$/, sourceMap: false, minify: false, target: 'es2022', jsx: 'automatic', }), ], }; ``` -------------------------------- ### Rspack configuration with Plumeria plugin Source: https://plumeria.dev/docs/integration/rspack.md Example rspack.config.js that sets up the Plumeria unplugin, SWC loader for TypeScript/React, and React refresh in development. The plugin is added via plumeria.rspack() and the config enables HMR on port 3000. ```ts import { rspack } from '@rspack/core'; import { ReactRefreshRspackPlugin } from '@rspack/plugin-react-refresh'; import plumeria from '@plumeria/unplugin'; const isDev = process.env.NODE_ENV === 'development'; export default { entry: './src/index.tsx', output: { filename: 'bundle.js', clean: true, }, resolve: { extensions: ['.ts', '.tsx', '.js'], }, module: { rules: [ { test: /\.tsx?$/, use: { loader: 'builtin:swc-loader', options: { jsc: { parser: { syntax: 'typescript', tsx: true }, transform: { react: { runtime: 'automatic', development: isDev, refresh: isDev, }, }, }, }, }, }, ], }, plugins: [ plumeria.rspack(), new rspack.HtmlRspackPlugin({ template: './src/index.html' }), isDev && new ReactRefreshRspackPlugin(), ].filter(Boolean), devServer: { hot: true, port: 3000, }, }; ``` -------------------------------- ### Test style compilation with @plumeria/unplugin transform Source: https://plumeria.dev/docs/ai.md For projects using @plumeria/unplugin, call the transform directly to test what a style compiles to. It returns the rewritten code and the stylesheet, without a component, DOM, or bundler. The example extracts the CSS ID from the rewritten code and loads the stylesheet. ```js const { unpluginFactory } = require('@plumeria/unplugin/factory'); const plugin = unpluginFactory(); const { code } = await plugin.transform(source, id); const cssId = code.match(/import "(.+\.zero\.css)"/)[1]; const css = plugin.load(cssId); ``` -------------------------------- ### Custom cross-fade with viewTransition (TypeScript and CSS) Source: https://plumeria.dev/docs/api-reference/javascript/viewTransition.md This example shows how to use viewTransition with custom keyframes for a long cross-fade. The TypeScript code defines fadeIn and fadeOut animations and passes them to viewTransition, then creates a CSS rule with the returned view-transition-name. The CSS output shows the generated keyframes and view-transition rules. ```ts import * as css from '@plumeria/core'; const fadeIn = css.keyframes({ from: { opacity: 0 }, to: { opacity: 1 }, }); const fadeOut = css.keyframes({ from: { opacity: 1 }, to: { opacity: 0 }, }); const longCrossFade = css.viewTransition({ old: { animationName: fadeOut, animationDuration: '1.2s', }, new: { animationName: fadeIn, animationDuration: '1.2s', }, }); export const transition = css.create({ name: { viewTransitionName: longCrossFade, }, }); ``` ```css @keyframes kf-x34h9adh { from { opacity: 0; } to { opacity: 1; } } @keyframes kf-xmzotw7h { from { opacity: 1; } to { opacity: 0; } } ::view-transition-old(vt-xsq18f68) { animation-name: kf-xmzotw7h; animation-duration: 1.2s; } ::view-transition-new(vt-xsq18f68) { animation-name: kf-x34h9adh; animation-duration: 1.2s; } .xa6j6hgv { view-transition-name: vt-xjp967de; } ``` -------------------------------- ### Migrating Tailwind Variants to Plumeria css.create Source: https://plumeria.dev/docs/ai.md Comparison showing the transition from a dynamic tv() configuration to a static css.create() implementation. Note that external overrides are handled via the classStyle array rather than twMerge. ```tsx // --- Before --- const button = tv({ base: 'inline-flex rounded font-medium', variants: { size: { sm: 'h-8 px-3 text-sm', lg: 'h-12 px-6 text-lg' }, tone: { primary: 'bg-blue-500 text-white', danger: 'bg-red-500 text-white' }, }, compoundVariants: [{ size: 'lg', tone: 'primary', class: 'shadow-lg' }], defaultVariants: { size: 'sm', tone: 'primary' }, });