Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0358d86
Add `theme` package
mirka Oct 13, 2025
0010125
Remove ts extensions
mirka Oct 13, 2025
22f281c
Handle CSS modules
mirka Oct 14, 2025
4741fc1
Update package lock
mirka Oct 14, 2025
0568c63
Allow public documentation
mirka Oct 15, 2025
24da932
Merge branch 'trunk' into theme-package
mirka Oct 15, 2025
97b0dfd
Add content to readme
mirka Oct 15, 2025
71d1f63
Lock private APIs
mirka Oct 15, 2025
fe9e740
Fix missing React error in test file
mirka Oct 15, 2025
d377c0c
Remove test for now (requires jest 30)
mirka Oct 15, 2025
d0d0242
Remove Storybook for now (punt to follow-up)
mirka Oct 15, 2025
91c4376
Remove build scripts to bin
mirka Oct 15, 2025
c144b61
Merge branch 'trunk' into theme-package
mirka Oct 16, 2025
a1c0e40
Move to prebuild folder
mirka Oct 16, 2025
67abb89
Lint all prebuild files
mirka Oct 16, 2025
54a4cb0
Move `design-tokens.ts` file to prebuild folder
mirka Oct 16, 2025
e4519e5
Fixup
mirka Oct 16, 2025
c43da33
Prebuild as part of root build process
mirka Oct 16, 2025
a89b0de
Try resolving floating point differences
mirka Oct 16, 2025
2f6f56b
Update readme
mirka Oct 17, 2025
97aa621
Remove layers from stylesheet
mirka Oct 17, 2025
a1c7b23
Merge branch 'trunk' into theme-package
mirka Oct 17, 2025
98ab6ed
Reduce color ramp tests
mirka Oct 17, 2025
2dfcd14
Move prebuild files into src (fixes types)
mirka Oct 17, 2025
815798b
Allow theme package to participate in private APIs
mirka Oct 17, 2025
ddfa586
Output combined stylesheet
mirka Oct 20, 2025
6aa7e5c
Rename prebuild to prebuilt
mirka Oct 21, 2025
cd1192c
Merge branch 'trunk' into theme-package
mirka Oct 21, 2025
d86bdeb
Merge branch 'trunk' into theme-package
mirka Oct 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const developmentFiles = [
'**/@(__mocks__|__tests__|test)/**/*.[tj]s?(x)',
'**/@(storybook|stories)/**/*.[tj]s?(x)',
'packages/babel-preset-default/bin/**/*.js',
'packages/theme/bin/**/*.[tj]s?(x)',
'packages/theme/terrazzo.config.ts',
];

// All files from packages that have types provided with TypeScript.
Expand Down Expand Up @@ -430,7 +432,12 @@ module.exports = {
},
},
{
files: [ 'bin/**/*.js', 'bin/**/*.mjs', 'packages/env/**' ],
files: [
'bin/**/*.js',
'bin/**/*.mjs',
'packages/env/**',
'packages/theme/bin/**/*.[tj]s?(x)',
],
rules: {
'no-console': 'off',
},
Expand Down
85 changes: 77 additions & 8 deletions bin/packages/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import chokidar from 'chokidar';
import browserslistToEsbuild from 'browserslist-to-esbuild';
import { sassPlugin } from 'esbuild-sass-plugin';
import postcss from 'postcss';
import postcssModulesPlugin from 'postcss-modules';
import autoprefixer from 'autoprefixer';
import rtlcss from 'rtlcss';
import cssnano from 'cssnano';
Expand Down Expand Up @@ -870,8 +871,10 @@ async function transpilePackage( packageName ) {

/**
* Compile styles for a single package.
* Discovers and compiles SCSS entry points based on package configuration.
* Supports wpStyleEntryPoints in package.json for custom entry point patterns.
*
* Discovers and compiles SCSS entry points based on package configuration
* (supporting wpStyleEntryPoints in package.json for custom entry point patterns),
* and all .module.css files in src/ directory.
*
* @param {string} packageName Package name.
* @return {Promise<number|null>} Build time in milliseconds, or null if no styles.
Expand All @@ -881,27 +884,93 @@ async function compileStyles( packageName ) {
const packageJsonPath = path.join( packageDir, 'package.json' );
const packageJson = JSON.parse( await readFile( packageJsonPath, 'utf8' ) );

// Get entry point patterns from package.json, default to root-level only
const entryPointPatterns = packageJson.wpStyleEntryPoints || [
// Get SCSS entry point patterns from package.json, default to root-level only
const scssEntryPointPatterns = packageJson.wpStyleEntryPoints || [
'src/*.scss',
];

const styleEntries = await glob(
entryPointPatterns.map( ( pattern ) =>
// Find all matching SCSS files
const scssEntries = await glob(
scssEntryPointPatterns.map( ( pattern ) =>
normalizePath( path.join( packageDir, pattern ) )
)
);

if ( styleEntries.length === 0 ) {
// Get CSS modules from anywhere in src/
const cssModuleEntries = await glob(
normalizePath( path.join( packageDir, 'src/**/*.module.css' ) ),
{ ignore: IGNORE_PATTERNS }
);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I set up a separate process for CSS modules. It's currently "opinionatedly modern", in that we don't support RTL transformation or Sass.


if ( scssEntries.length === 0 && cssModuleEntries.length === 0 ) {
return null;
}

const startTime = Date.now();
const buildStyleDir = path.join( packageDir, 'build-style' );
const srcDir = path.join( packageDir, 'src' );

// Process .module.css files and generate JS modules
const cssResults = await Promise.all(
cssModuleEntries.map( async ( styleEntryPath ) => {
const buildDir = path.join( packageDir, 'build' );
const buildModuleDir = path.join( packageDir, 'build-module' );

const cssContent = await readFile( styleEntryPath, 'utf8' );
const relativePath = path.relative( srcDir, styleEntryPath );

let mappings = {};
const result = await postcss( [
postcssModulesPlugin( {
getJSON: ( _, json ) => ( mappings = json ),
} ),
] ).process( cssContent, { from: styleEntryPath } );

// Write processed CSS to build-style (preserving directory structure)
const cssOutPath = path.join(
buildStyleDir,
relativePath.replace( '.module.css', '.css' )
);
await mkdir( path.dirname( cssOutPath ), { recursive: true } );
await writeFile( cssOutPath, result.css );

// Generate JS modules with class name mappings (preserving directory structure)
const jsExport = JSON.stringify( mappings );
const jsPath = `${ relativePath }.js`;
await Promise.all( [
mkdir( path.dirname( path.join( buildDir, jsPath ) ), {
recursive: true,
} ),
mkdir( path.dirname( path.join( buildModuleDir, jsPath ) ), {
recursive: true,
} ),
] );
await Promise.all( [
writeFile(
path.join( buildDir, jsPath ),
`"use strict";\nmodule.exports = ${ jsExport };\n`
),
writeFile(
path.join( buildModuleDir, jsPath ),
`export default ${ jsExport };\n`
),
] );

// Return the processed CSS for combining
return result.css;
} )
);

// Generate combined stylesheet from all CSS modules
if ( cssResults.length > 0 ) {
const combinedCss = cssResults.join( '\n' );
await mkdir( buildStyleDir, { recursive: true } );
await writeFile( path.join( buildStyleDir, 'style.css' ), combinedCss );
}
Comment on lines +964 to +969
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This "combine step" isn't necessary for this theme package that only has one stylesheet, but it will be necessary for the UI components package which will have separate stylesheets for every component.

The idea is that most consumers can just import the single combined stylesheet for convenience, while size-sensitive consumers can opt to import the separate component-specific stylesheets if they want.


// Process SCSS files
await Promise.all(
styleEntries.map( async ( styleEntryPath ) => {
scssEntries.map( async ( styleEntryPath ) => {
// Calculate relative path from src/ to preserve directory structure
const relativePath = path.relative( srcDir, styleEntryPath );
const relativeDir = path.dirname( relativePath );
Expand Down
6 changes: 6 additions & 0 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1985,6 +1985,12 @@
"markdown_source": "../packages/sync/README.md",
"parent": "packages"
},
{
"title": "@wordpress/theme",
"slug": "packages-theme",
"markdown_source": "../packages/theme/README.md",
"parent": "packages"
},
{
"title": "@wordpress/token-list",
"slug": "packages-token-list",
Expand Down
Loading
Loading