diff --git a/Source/package.json b/Source/package.json index 88648f9..6eebf37 100644 --- a/Source/package.json +++ b/Source/package.json @@ -83,7 +83,8 @@ "types": "./dist/esm/Toolbar/index.d.ts", "require": "./dist/cjs/Toolbar/index.js", "import": "./dist/esm/Toolbar/index.js" - } + }, + "./styles": "./dist/styles.css" }, "scripts": { "prepare": "yarn g:build", diff --git a/Source/scripts/copy-css.sh b/Source/scripts/copy-css.sh index 7acfa41..ec24933 100755 --- a/Source/scripts/copy-css.sh +++ b/Source/scripts/copy-css.sh @@ -8,7 +8,8 @@ find . -name '*.css' \ -not -path './node_modules/*' \ -not -path './dist/*' \ - -not -path './.storybook/*' | while read -r file; do + -not -path './.storybook/*' \ + -not -name 'tailwind.css' | while read -r file; do # Remove the leading './' relative_path="${file#./}" diff --git a/Source/tailwind.css b/Source/tailwind.css new file mode 100644 index 0000000..c31c9eb --- /dev/null +++ b/Source/tailwind.css @@ -0,0 +1,13 @@ +/* Copyright (c) Cratis. All rights reserved. */ +/* Licensed under the MIT license. See LICENSE file in the project root for full license information. */ + +/* + * Tailwind utility classes compiled at build time. + * This stylesheet is generated during the package build and contains only + * the utility classes that are actually used across all components. + * It intentionally excludes preflight/base resets — those are the consumer app's responsibility. + * + * Usage in your app: + * import '@cratis/components/styles'; + */ +@import "tailwindcss"; diff --git a/rollup.config.mjs b/rollup.config.mjs index 69da35a..f870b3c 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -4,8 +4,46 @@ import typescript2 from 'rollup-plugin-typescript2'; import commonjs from 'rollup-plugin-commonjs'; import peerDepsExternal from 'rollup-plugin-peer-deps-external'; -import { writeFileSync, mkdirSync } from 'fs'; -import { dirname, join } from 'path'; +import { readFileSync, writeFileSync, mkdirSync } from 'fs'; +import { dirname, join, resolve } from 'path'; + +/** + * Rollup plugin that compiles the Tailwind entry CSS through PostCSS after the + * bundle is written, producing a self-contained dist/styles.css that consumers + * can import once to get all utility classes used by the components. + * + * Without this step the utility classes (e.g. p-2, gap-1, w-10 …) only exist + * in the package's source JSX and would never be generated by the consuming + * app's own Tailwind build, because node_modules is typically excluded from + * content scanning. + */ +function compileTailwind(sourceDir, distDir) { + let hasRun = false; + return { + name: 'compile-tailwind', + async closeBundle() { + if (hasRun) return; + hasRun = true; + + const inputFile = resolve(sourceDir, 'tailwind.css'); + const outputFile = resolve(distDir, 'styles.css'); + + const { default: postcss } = await import('postcss'); + const { default: tailwindcss } = await import('@tailwindcss/postcss'); + const { default: autoprefixer } = await import('autoprefixer'); + + const css = readFileSync(inputFile, 'utf8'); + const result = await postcss([tailwindcss({ base: sourceDir }), autoprefixer]).process(css, { + from: inputFile, + to: outputFile, + }); + + mkdirSync(dirname(outputFile), { recursive: true }); + writeFileSync(outputFile, result.css); + console.log('✓ Compiled Tailwind utilities → dist/styles.css'); + }, + }; +} /** * Rollup plugin to generate package.json files in output directories @@ -39,6 +77,8 @@ function generatePackageJson(cjsPath, esmPath) { } export function rollup(cjsPath, esmPath, tsconfigPath, pkg) { + const sourceDir = dirname(tsconfigPath); + const distDir = resolve(sourceDir, 'dist'); return { input: "index.ts", @@ -89,7 +129,8 @@ export function rollup(cjsPath, esmPath, tsconfigPath, pkg) { exclude: ["node_modules", "../node_modules", "for_*/**/*"] } }), - generatePackageJson(cjsPath, esmPath) + generatePackageJson(cjsPath, esmPath), + compileTailwind(sourceDir, distDir), ] }; }