diff --git a/packages/react/package.json b/packages/react/package.json index 89c37ee6b..7add3a356 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -14,6 +14,10 @@ "./dist/index.css": { "import": "./dist/index.css", "require": "./dist/index.css" + }, + "./dist/layered.css": { + "import": "./dist/layered.css", + "require": "./dist/layered.css" } }, "types": "./dist/index.d.ts", diff --git a/packages/react/tsup.config.ts b/packages/react/tsup.config.ts index 392246d80..42a8c90fb 100644 --- a/packages/react/tsup.config.ts +++ b/packages/react/tsup.config.ts @@ -1,5 +1,8 @@ import { defineConfig } from 'tsup' import { styledComponentsPlugin } from '@charcoal-ui/esbuild-plugin-styled-components' +import postcss from 'postcss' +import fs from 'node:fs/promises' +import path from 'node:path' export default defineConfig({ entry: ['src/index.ts'], @@ -11,5 +14,59 @@ export default defineConfig({ }, target: 'esnext', sourcemap: true, - esbuildPlugins: [styledComponentsPlugin], + esbuildPlugins: [ + styledComponentsPlugin, + { + name: 'at-layer-charcoal', + setup(build) { + // NOTE: this will be called twice for esm and cjs. + build.onEnd(async (result) => { + const originalCssOutput = result.outputFiles?.find((file) => + file.path.endsWith('css') + ) + if (!originalCssOutput) { + throw new Error('[at-layer-charcoal]: expect original css output') + } + + const layeredCssFilePath = originalCssOutput.path.replace( + 'index.css', + 'layered.css' + ) + const layeredCssOutput = await postcss({ + postcssPlugin: 'at-layer-charcoal', + Once(_, { AtRule, result }) { + const atLayerNode = new AtRule({ + name: 'layer', + params: 'charcoal', + nodes: result.root.nodes, + }) + result.root.nodes = [atLayerNode] + }, + }).process(originalCssOutput.text, { + from: originalCssOutput.path, + to: layeredCssFilePath, + map: { + inline: false, + }, + }) + + // https://github.com/evanw/esbuild/issues/2999 + // this will be called before dist is created + await fs.mkdir(path.dirname(layeredCssFilePath), { recursive: true }) + await Promise.all([ + fs.writeFile(layeredCssFilePath, layeredCssOutput.content), + fs.writeFile( + `${layeredCssFilePath}.map`, + layeredCssOutput.map.toString() + ), + ]) + + // eslint-disable-next-line no-console + console.log( + `${build.initialOptions.format?.toUpperCase()} dist/layered.css` + ) + }) + }, + }, + ], })