Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["docs", "example-*", "codesandbox", "rollup-plugin-import-css"]
"ignore": ["docs", "example-*", "codesandbox"]
}
5 changes: 5 additions & 0 deletions .changeset/dry-trainers-protect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': major
---

Update Primer React to emit *.css files that are imported by emitted *.js files for styling
2 changes: 1 addition & 1 deletion .github/workflows/consumer_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Install dependencies
run: npm ci
- name: Build @primer/react
run: npm run build -w @primer/react
run: npm run build -w rollup-plugin-import-css -w @primer/react
# Output the artifact as a tarball in `consumer-test`. Write the
# information for this package in `consumer-test/pack.json` so we can read
# from it later to install the package
Expand Down
63 changes: 63 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
"name": "primer",
"private": true,
"workspaces": [
"packages/rollup-plugin-import-css",
"packages/*",
"docs",
"examples/*"
],
"scripts": {
"setup": "./script/setup",
"build": "npm run build -w @primer/react",
"build": "npm run build -w rollup-plugin-import-css -w @primer/react",
"clean": "npm run clean -ws --if-present",
"clean:all": "npm run clean && rimraf node_modules docs/node_modules packages/*/node_modules examples/*/node_modules",
"format": "prettier --cache --write '**/*.{js,css,md,mdx,ts,tsx,yml}'",
Expand Down
8 changes: 7 additions & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@
"./lib-esm/internal/*": null
},
"typings": "lib/index.d.ts",
"sideEffects": false,
"sideEffects": [
"lib-esm/**/*.css",
"lib/**/*.css"
],
"scripts": {
"build": "./script/build",
"clean": "rimraf dist lib lib-esm css",
Expand Down Expand Up @@ -199,7 +202,9 @@
"mdast-util-to-string": "4.0.0",
"micromark-extension-frontmatter": "2.0.0",
"micromark-extension-mdxjs": "3.0.0",
"postcss-custom-properties-fallback": "1.0.2",
"postcss-preset-env": "9.5.14",
"postcss-preset-primer": "^0.0.0",
"react": "18.3.1",
"react-dnd": "14.0.4",
"react-dnd-html5-backend": "14.0.2",
Expand All @@ -208,6 +213,7 @@
"recast": "0.23.7",
"rimraf": "5.0.5",
"rollup": "4.9.6",
"rollup-plugin-import-css": "^0.0.0",
"rollup-plugin-postcss": "4.0.2",
"rollup-plugin-visualizer": "5.9.2",
"semver": "7.6.2",
Expand Down
111 changes: 104 additions & 7 deletions packages/react/rollup.config.js → packages/react/rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import fs from 'node:fs'
import path from 'node:path'
import {fileURLToPath} from 'node:url'
import commonjs from '@rollup/plugin-commonjs'
import resolve from '@rollup/plugin-node-resolve'
import babel from '@rollup/plugin-babel'
import replace from '@rollup/plugin-replace'
import terser from '@rollup/plugin-terser'
import glob from 'fast-glob'
import customPropertiesFallback from 'postcss-custom-properties-fallback'
import {visualizer} from 'rollup-plugin-visualizer'
import {importCSS} from 'rollup-plugin-import-css'
import postcss from 'rollup-plugin-postcss'
import postssPresetPrimer from 'postcss-preset-primer'
import MagicString from 'magic-string'
import packageJson from './package.json'
import packageJson from './package.json' assert {type: 'json'}

const __dirname = path.dirname(fileURLToPath(import.meta.url))

const input = new Set([
// "exports"
Expand Down Expand Up @@ -80,6 +88,50 @@ function createPackageRegex(name) {
return new RegExp(`^${name}(/.*)?`)
}

const postcssPlugins = [
postssPresetPrimer(),
customPropertiesFallback({
importFrom: [
() => {
let customProperties = {}
const filePaths = glob.sync(['fallbacks/**/*.json', 'docs/functional/themes/light.json'], {
cwd: path.join(__dirname, '../../node_modules/@primer/primitives/dist/'),
ignore: ['fallbacks/color-fallbacks.json'],
})

for (const filePath of filePaths) {
const fileData = fs.readFileSync(
path.join(__dirname, '../../node_modules/@primer/primitives/dist/', filePath),
'utf8',
)

const jsonData = JSON.parse(fileData)
let result = {}

if (filePath === 'docs/functional/themes/light.json') {
for (const variable of Object.keys(jsonData)) {
result[`--${variable}`] = jsonData[variable].value
}
} else {
result = jsonData
}

customProperties = {
...customProperties,
...result,
}
}

return {customProperties}
},
],
}),
]

const postcssModulesOptions = {
generateScopedName: 'prc-[folder]-[local]-[hash:base64:5]',
}

const baseConfig = {
input: Array.from(input),
plugins: [
Expand Down Expand Up @@ -121,12 +173,12 @@ const baseConfig = {
commonjs({
extensions,
}),
postcss({
extract: 'components.css',
autoModules: false,
modules: {generateScopedName: 'prc_[local]_[hash:base64:5]'},
// plugins are defined in postcss.config.js
importCSS({
modulesRoot: 'src',
postcssPlugins,
postcssModulesOptions,
}),

/**
* This custom rollup plugin allows us to preserve directives in source
* code, such as "use client", in order to support React Server Components.
Expand Down Expand Up @@ -269,7 +321,52 @@ export default [
'process.env.NODE_ENV': JSON.stringify('production'),
preventAssignment: true,
}),
...baseConfig.plugins,
babel({
extensions,
exclude: /node_modules/,
babelHelpers: 'inline',
babelrc: false,
configFile: false,
presets: [
'@babel/preset-typescript',
[
'@babel/preset-react',
{
modules: false,
},
],
],
plugins: [
'macros',
'add-react-displayname',
'dev-expression',
'babel-plugin-styled-components',
'@babel/plugin-proposal-nullish-coalescing-operator',
'@babel/plugin-proposal-optional-chaining',
[
'babel-plugin-transform-replace-expressions',
{
replace: {
__DEV__: "process.env.NODE_ENV !== 'production'",
},
},
],
],
}),
resolve({
extensions,
}),
commonjs({
extensions,
}),
// PostCSS plugins are defined in postcss.config.js
postcss({
extract: 'components.css',
autoModules: false,
modules: {
generateScopedName: 'prc_[local]_[hash:base64:5]',
},
}),
terser(),
visualizer({sourcemap: true}),
],
Expand Down
2 changes: 1 addition & 1 deletion packages/react/script/build
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ npm run clean
npm run build:precompile-color-schemes

# Bundle
npx rollup -c --bundleConfigAsCjs
npx rollup -c

# Type check
npx tsc --project tsconfig.build.json
Expand Down
11 changes: 11 additions & 0 deletions packages/react/script/get-export-sizes.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ async function main() {
commonjs({
include: /node_modules/,
}),
{
name: 'empty-css-modules',
transform(_code, id) {
if (!id.endsWith('.css')) {
return
}
return {
code: `export default {}`,
}
},
},
virtual({
__entrypoint__: `export { ${identifier} } from '${filepath}';`,
}),
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/__tests__/exports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ async function setup(): Promise<Project> {
}

const extension = path.extname(source)
if (extension !== '' && extensions.includes(extension)) {
if (extension !== '' && !extensions.includes(extension)) {
return null
}

Expand Down
17 changes: 12 additions & 5 deletions packages/rollup-plugin-import-css/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,10 @@ export function importCSS(options: ImportCSSOptions): Plugin {
return
}

// If we're working with a css asset that is not a CSS module, assume that
// it has been generated by our plugin and should be marked as external.
if (source.endsWith('.css') && !source.endsWith('.module.css')) {
const moduleInfo = this.getModuleInfo(importer)
if (moduleInfo?.meta['import-css']?.source === source) {
return {
id: path.resolve(path.dirname(importer), source),
id: source,
external: true,
}
}
Expand Down Expand Up @@ -87,9 +86,17 @@ export function importCSS(options: ImportCSSOptions): Plugin {
fileName,
})

const moduleInfo = this.getModuleInfo(id)
const cssSource = `./${path.basename(fileName)}`
if (moduleInfo) {
moduleInfo.meta['import-css'] = {
source: cssSource,
}
}

return {
code: `
import './${path.basename(fileName)}';
import '${cssSource}';
export default ${JSON.stringify(cssModuleClasses)}
`,
}
Expand Down