diff --git a/.eslintrc.js b/.eslintrc.js
index 9ac141fd09a04c..0b0c71c39a2664 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -76,6 +76,11 @@ const restrictedImports = [
message:
"edit-widgets is a WordPress top level package that shouldn't be imported into other packages",
},
+ {
+ name: 'classnames',
+ message:
+ "Please use `clsx` instead. It's a lighter and faster drop-in replacement for `classnames`.",
+ },
];
module.exports = {
diff --git a/.github/setup-node/action.yml b/.github/setup-node/action.yml
index af71abd3cd9b24..a17adfe5f50071 100644
--- a/.github/setup-node/action.yml
+++ b/.github/setup-node/action.yml
@@ -32,8 +32,15 @@ runs:
- name: Install npm dependencies
if: ${{ steps.cache-node_modules.outputs.cache-hit != 'true' }}
- run: npm ci
+ run: |
+ npm ci
shell: bash
+ - name: Upload npm logs as an artifact on failure
+ uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
+ if: failure()
+ with:
+ name: npm-logs
+ path: C:\npm\cache\_logs
# On cache hit, we run the post-install script to match the native `npm ci` behavior.
# An example of this is to patch `node_modules` using patch-package.
diff --git a/docs/contributors/code/coding-guidelines.md b/docs/contributors/code/coding-guidelines.md
index 63114073b1b802..06f86715a65a06 100644
--- a/docs/contributors/code/coding-guidelines.md
+++ b/docs/contributors/code/coding-guidelines.md
@@ -39,13 +39,13 @@ Components may be assigned with class names that indicate states (for example, a
**Example:**
-Consider again the Notices example. We may want to apply specific styling for dismissible notices. The [`classnames` package](https://www.npmjs.com/package/classnames) can be a helpful utility for conditionally applying modifier class names.
+Consider again the Notices example. We may want to apply specific styling for dismissible notices. The [`clsx` package](https://www.npmjs.com/package/clsx) can be a helpful utility for conditionally applying modifier class names.
```jsx
-import classnames from 'classnames';
+import clsx from 'clsx';
export default function Notice( { children, onRemove, isDismissible } ) {
- const classes = classnames( 'components-notice', {
+ const classes = clsx( 'components-notice', {
'is-dismissible': isDismissible,
} );
diff --git a/package-lock.json b/package-lock.json
index 2d67d54cf6f634..fdbfc7d286d153 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21876,11 +21876,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/classnames": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
- "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
- },
"node_modules/clean-css": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
@@ -22157,6 +22152,14 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/cmd-shim": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.1.tgz",
@@ -53215,7 +53218,7 @@
"@wordpress/warning": "file:../warning",
"@wordpress/wordcount": "file:../wordcount",
"change-case": "^4.1.2",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"colord": "^2.7.0",
"deepmerge": "^4.3.0",
"diff": "^4.0.2",
@@ -53329,7 +53332,7 @@
"@wordpress/viewport": "file:../viewport",
"@wordpress/wordcount": "file:../wordcount",
"change-case": "^4.1.2",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"colord": "^2.7.0",
"escape-html": "^1.0.3",
"fast-average-color": "^9.1.1",
@@ -53452,7 +53455,7 @@
"@wordpress/icons": "file:../icons",
"@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts",
"@wordpress/private-apis": "file:../private-apis",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"cmdk": "^0.2.0"
},
"engines": {
@@ -53498,7 +53501,7 @@
"@wordpress/rich-text": "file:../rich-text",
"@wordpress/warning": "file:../warning",
"change-case": "^4.1.2",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"colord": "^2.7.0",
"date-fns": "^3.6.0",
"deepmerge": "^4.3.0",
@@ -53730,7 +53733,7 @@
"@wordpress/preferences": "file:../preferences",
"@wordpress/private-apis": "file:../private-apis",
"@wordpress/widgets": "file:../widgets",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"fast-deep-equal": "^3.1.3"
},
"engines": {
@@ -53802,7 +53805,7 @@
"@wordpress/keycodes": "file:../keycodes",
"@wordpress/primitives": "file:../primitives",
"@wordpress/private-apis": "file:../private-apis",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"remove-accents": "^0.5.0"
},
"engines": {
@@ -54048,7 +54051,7 @@
"@wordpress/viewport": "file:../viewport",
"@wordpress/warning": "file:../warning",
"@wordpress/widgets": "file:../widgets",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"memize": "^2.1.0"
},
"engines": {
@@ -54107,8 +54110,8 @@
"@wordpress/widgets": "file:../widgets",
"@wordpress/wordcount": "file:../wordcount",
"change-case": "^4.1.2",
- "classnames": "^2.3.1",
"client-zip": "^2.4.4",
+ "clsx": "^2.1.1",
"colord": "^2.9.2",
"deepmerge": "^4.3.0",
"fast-deep-equal": "^3.1.3",
@@ -54156,7 +54159,7 @@
"@wordpress/reusable-blocks": "file:../reusable-blocks",
"@wordpress/url": "file:../url",
"@wordpress/widgets": "file:../widgets",
- "classnames": "^2.3.1"
+ "clsx": "^2.1.1"
},
"engines": {
"node": ">=12"
@@ -54205,7 +54208,7 @@
"@wordpress/url": "file:../url",
"@wordpress/warning": "file:../warning",
"@wordpress/wordcount": "file:../wordcount",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"date-fns": "^3.6.0",
"memize": "^2.1.0",
"react-autosize-textarea": "^7.1.0",
@@ -54600,7 +54603,7 @@
"@wordpress/preferences": "file:../preferences",
"@wordpress/private-apis": "file:../private-apis",
"@wordpress/viewport": "file:../viewport",
- "classnames": "^2.3.1"
+ "clsx": "^2.1.1"
},
"engines": {
"node": ">=12"
@@ -54900,7 +54903,7 @@
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
"@wordpress/private-apis": "file:../private-apis",
- "classnames": "^2.3.1"
+ "clsx": "^2.1.1"
},
"engines": {
"node": ">=12"
@@ -54941,7 +54944,7 @@
"dependencies": {
"@babel/runtime": "^7.16.0",
"@wordpress/element": "file:../element",
- "classnames": "^2.3.1"
+ "clsx": "^2.1.1"
},
"engines": {
"node": ">=12"
@@ -55800,7 +55803,7 @@
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
"@wordpress/notices": "file:../notices",
- "classnames": "^2.3.1"
+ "clsx": "^2.1.1"
},
"peerDependencies": {
"react": "^18.0.0",
@@ -68565,7 +68568,7 @@
"@wordpress/warning": "file:../warning",
"@wordpress/wordcount": "file:../wordcount",
"change-case": "^4.1.2",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"colord": "^2.7.0",
"deepmerge": "^4.3.0",
"diff": "^4.0.2",
@@ -68648,7 +68651,7 @@
"@wordpress/viewport": "file:../viewport",
"@wordpress/wordcount": "file:../wordcount",
"change-case": "^4.1.2",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"colord": "^2.7.0",
"escape-html": "^1.0.3",
"fast-average-color": "^9.1.1",
@@ -68734,7 +68737,7 @@
"@wordpress/icons": "file:../icons",
"@wordpress/keyboard-shortcuts": "file:../keyboard-shortcuts",
"@wordpress/private-apis": "file:../private-apis",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"cmdk": "^0.2.0"
}
},
@@ -68771,7 +68774,7 @@
"@wordpress/rich-text": "file:../rich-text",
"@wordpress/warning": "file:../warning",
"change-case": "^4.1.2",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"colord": "^2.7.0",
"date-fns": "^3.6.0",
"deepmerge": "^4.3.0",
@@ -68946,7 +68949,7 @@
"@wordpress/preferences": "file:../preferences",
"@wordpress/private-apis": "file:../private-apis",
"@wordpress/widgets": "file:../widgets",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"fast-deep-equal": "^3.1.3"
}
},
@@ -68993,7 +68996,7 @@
"@wordpress/keycodes": "file:../keycodes",
"@wordpress/primitives": "file:../primitives",
"@wordpress/private-apis": "file:../private-apis",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"remove-accents": "^0.5.0"
},
"dependencies": {
@@ -69152,7 +69155,7 @@
"@wordpress/viewport": "file:../viewport",
"@wordpress/warning": "file:../warning",
"@wordpress/widgets": "file:../widgets",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"memize": "^2.1.0"
}
},
@@ -69202,8 +69205,8 @@
"@wordpress/widgets": "file:../widgets",
"@wordpress/wordcount": "file:../wordcount",
"change-case": "^4.1.2",
- "classnames": "^2.3.1",
"client-zip": "^2.4.4",
+ "clsx": "^2.1.1",
"colord": "^2.9.2",
"deepmerge": "^4.3.0",
"fast-deep-equal": "^3.1.3",
@@ -69242,7 +69245,7 @@
"@wordpress/reusable-blocks": "file:../reusable-blocks",
"@wordpress/url": "file:../url",
"@wordpress/widgets": "file:../widgets",
- "classnames": "^2.3.1"
+ "clsx": "^2.1.1"
}
},
"@wordpress/editor": {
@@ -69282,7 +69285,7 @@
"@wordpress/url": "file:../url",
"@wordpress/warning": "file:../warning",
"@wordpress/wordcount": "file:../wordcount",
- "classnames": "^2.3.1",
+ "clsx": "^2.1.1",
"date-fns": "^3.6.0",
"memize": "^2.1.0",
"react-autosize-textarea": "^7.1.0",
@@ -69534,7 +69537,7 @@
"@wordpress/preferences": "file:../preferences",
"@wordpress/private-apis": "file:../private-apis",
"@wordpress/viewport": "file:../viewport",
- "classnames": "^2.3.1"
+ "clsx": "^2.1.1"
}
},
"@wordpress/is-shallow-equal": {
@@ -69691,7 +69694,7 @@
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
"@wordpress/private-apis": "file:../private-apis",
- "classnames": "^2.3.1"
+ "clsx": "^2.1.1"
}
},
"@wordpress/preferences-persistence": {
@@ -69709,7 +69712,7 @@
"requires": {
"@babel/runtime": "^7.16.0",
"@wordpress/element": "file:../element",
- "classnames": "^2.3.1"
+ "clsx": "^2.1.1"
}
},
"@wordpress/priority-queue": {
@@ -70298,7 +70301,7 @@
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
"@wordpress/notices": "file:../notices",
- "classnames": "^2.3.1"
+ "clsx": "^2.1.1"
}
},
"@wordpress/wordcount": {
@@ -73014,11 +73017,6 @@
}
}
},
- "classnames": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
- "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
- },
"clean-css": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
@@ -73234,6 +73232,11 @@
"mimic-response": "^1.0.0"
}
},
+ "clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="
+ },
"cmd-shim": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.1.tgz",
diff --git a/packages/block-editor/CHANGELOG.md b/packages/block-editor/CHANGELOG.md
index 3db126ca2de34b..a8c3cebbe8f1c0 100644
--- a/packages/block-editor/CHANGELOG.md
+++ b/packages/block-editor/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+### Internal
+
+- Replaced `classnames` package with the faster and smaller `clsx` package ([#61138](https://github.com/WordPress/gutenberg/pull/61138)).
+
## 12.25.0 (2024-05-02)
## 12.24.0 (2024-04-19)
@@ -20,7 +24,7 @@
## 12.18.0 (2024-01-24)
-- Deprecated `__experimentalRecursionProvider` and `__experimentalUseHasRecursion` in favor of their new stable counterparts `RecursionProvider` and `useHasRecursion`.
+- Deprecated `__experimentalRecursionProvider` and `__experimentalUseHasRecursion` in favor of their new stable counterparts `RecursionProvider` and `useHasRecursion`.
## 12.17.0 (2024-01-10)
@@ -251,8 +255,8 @@
### Breaking Changes
-- Drop support for Internet Explorer 11 ([#31110](https://github.com/WordPress/gutenberg/pull/31110)). Learn more at https://make.wordpress.org/core/2021/04/22/ie-11-support-phase-out-plan/.
-- Increase the minimum Node.js version to v12 matching Long Term Support releases ([#31270](https://github.com/WordPress/gutenberg/pull/31270)). Learn more at https://nodejs.org/en/about/releases/.
+- Drop support for Internet Explorer 11 ([#31110](https://github.com/WordPress/gutenberg/pull/31110)). Learn more at