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
7 changes: 6 additions & 1 deletion .github/workflows/static-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,12 @@ jobs:

- name: Lint Styles
if: ${{ matrix.annotations }}
run: npm run lint:css -- --formatter compact
# Stylelint has no separate prune flag. Run lint first so new violations fail,
# then `--suppress` to prune stale suppressions (same outcome as ESLint's
# `--prune-suppressions` + check-local-changes).
run: |
npm run lint:css -- --formatter compact
npm run lint:css:update-suppressions

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The stylelint suppress command will both add and prune suppressions in the same pass. This means that on CI, we need a first pass to flag violations (and fail the job), and then a second pass to prune stale suppressions.

This second pass is estimated to add about 15 secs on CI (not completely negligible in absolute terms, but negligible in the context of the entire static checks job).


- name: Type checking
run: npm run build
Expand Down
4 changes: 3 additions & 1 deletion lint-staged.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ module.exports = {
() => 'npm run prelint:js',
'node ./tools/eslint/lint-js.cjs --config eslint.config.strict.cjs',
],
'*.{scss,module.css}': [ 'wp-scripts lint-style' ],
'*.{scss,module.css}': [
'wp-scripts lint-style --suppress-location=tools/stylelint/stylelint-suppressions.json',
],
'package-lock.json': [ 'npm run lint:lockfile' ],
'packages/*/package.json': [ 'wp-scripts lint-pkg-json' ],
'{docs/toc.json,tools/docs/*.cjs,packages/{*/README.md,components/src/*/**/README.md,block-library/src/*/README.md}}':
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,9 @@
"format:php": "wp-env run --env-cwd='wp-content/plugins/gutenberg' cli composer run-script format",
"prelint:js": "npm run --if-present --workspaces prelint:js",
"lint": "concurrently \"npm run lint:lockfile\" \"npm run lint:tsconfig\" \"npm run lint:js\" \"npm run lint:pkg-json\" \"npm run lint:deps\" \"npm run lint:css\"",
"lint:css": "wp-scripts lint-style \"**/*.scss\" \"**/*.module.css\"",
"lint:css": "wp-scripts lint-style --suppress-location=tools/stylelint/stylelint-suppressions.json \"**/*.scss\" \"**/*.module.css\"",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What about non-module css files, such as packages/media-editor/src/image-editor/stories/style.css and packages/image-cropper/src/stories/style.css ?

I think that wp-scripts lint-style defaults to **/*.{css,pcss,scss}, maybe we can follow those extensions too?

If we make changes here, we may need to also reflect them to #79918?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

When I considered this, it seemed to me that this repo generally does not treat plain .css files as a normal authoring format. The bulk of them are test fixtures and build artifacts. So while it's not necessarily wrong to start setting up stylelintignores for all the paths that should be exempt from linting, a simpler strategy at this point may be to switch the files you want to be linted to either of the two "official" formats.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I actually just tried linting everything right now, and the diff actually seems simpler than I expected. I'll see if the switch is feasible.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Addressed in #79957. Thanks for prompting, both @ciampo and @aduth!

"lint:css:fix": "npm run lint:css -- --fix",
"lint:css:update-suppressions": "npm run lint:css -- --suppress && wp-scripts format tools/stylelint/stylelint-suppressions.json",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Unlike the eslint version, stylelint doesn't have separate "add suppressions" and "prune suppressions" commands. So the command name reflects that, rather than keep parity with the eslint version where it's called lint:js:prune-suppressions.

"lint:deps": "syncpack lint",
"lint:deps:fix": "syncpack fix",
"lint:js": "node ./tools/eslint/lint-js.cjs --concurrency=auto",
Expand Down
2 changes: 2 additions & 0 deletions packages/block-library/src/image/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ figure.wp-block-image:not(.wp-block) {
width: 100%;
overflow: hidden;

// stylelint-disable selector-class-pattern -- react-easy-crop library class names.
.reactEasyCrop_Container {
// The linked Image block has `pointer-events: none` applied. Override it
// here to enable the crop action.
Expand All @@ -143,6 +144,7 @@ figure.wp-block-image:not(.wp-block) {
border-radius: 0; // Prevent's theme.json radius bleeding into cropper.
}
}
// stylelint-enable selector-class-pattern
}

.wp-block-image__crop-icon {
Expand Down
1 change: 1 addition & 0 deletions packages/block-library/src/media-text/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
}
}

// stylelint-disable-next-line selector-class-pattern -- re-resizable library class name.
.wp-block-media-text .__resizable_base__ {
grid-column: 1 / span 2;
grid-row: 2;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@use "@wordpress/base-styles/z-index" as *;

// stylelint-disable selector-class-pattern -- WordPress Customizer control class names use underscores by convention.
.customize-control-sidebar_block_editor .block-editor-block-list__block-popover {
// FloatingUI library used in Popover component forces us to have an "absolute" inline style.
// We need to override this in the customizer.
Expand All @@ -13,3 +14,4 @@
// We need to override this in the customizer.
position: fixed !important;
}
// stylelint-enable selector-class-pattern
2 changes: 2 additions & 0 deletions packages/customize-widgets/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
}

// Include reset CSS for the customizer.
// stylelint-disable selector-class-pattern -- WordPress Customizer control class names use underscores by convention.
.customize-control-sidebar_block_editor,
.customize-widgets-layout__inspector {
@include reset;
}
// stylelint-enable selector-class-pattern
2 changes: 2 additions & 0 deletions packages/edit-site/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
display: block;
}

// stylelint-disable selector-class-pattern -- WordPress admin body classes use underscores by convention.
body.js #wpbody {
padding-top: 0;
}
Expand All @@ -64,6 +65,7 @@ body.js.site-editor-php {
}
}
}
// stylelint-enable selector-class-pattern

.edit-site {
@include reset;
Expand Down
2 changes: 2 additions & 0 deletions packages/edit-widgets/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
@use "./components/widget-areas-block-editor-content/style.scss" as *;
@use "./components/secondary-sidebar/style.scss" as *;

// stylelint-disable selector-class-pattern -- WordPress admin body classes use underscores by convention.
body.js.appearance_page_gutenberg-widgets,
body.js.widgets-php {
@include wp-admin-reset( ".blocks-widgets-container" );
}
// stylelint-enable selector-class-pattern

.blocks-widgets-container {
@include reset;
Expand Down
26 changes: 7 additions & 19 deletions tools/stylelint/config.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
// CSS Baseline 2024 stepped-value functions not yet recognized by Stylelint.
const CSS_BASELINE_2024_FUNCTIONS = [ 'round', 'rem', 'mod' ];

const SELECTOR_CLASS_PATTERN = [
'^[a-z][a-z0-9]*(?:(?:__|--|-)[a-z0-9]+)*$',
{
message:
'Selector should use lowercase class segments separated with hyphens, double hyphens, or double underscores (selector-class-pattern)',
},
];

/** @type {import('stylelint').Config} */
module.exports = {
extends: '@wordpress/stylelint-config/scss-stylistic',
Expand Down Expand Up @@ -55,7 +47,13 @@ module.exports = {
},
],
'rule-empty-line-before': null,
'selector-class-pattern': null,
'selector-class-pattern': [
'^[a-z][a-z0-9]*(?:(?:__|--|-)[a-z0-9]+)*$',
{
message:
'Selector should use lowercase class segments separated with hyphens, double hyphens, or double underscores (selector-class-pattern)',
},
],
'value-keyword-case': null,
'scss/operator-no-unspaced': null,
'scss/selector-no-redundant-nesting-selector': null,
Expand Down Expand Up @@ -155,16 +153,6 @@ module.exports = {
],
},
},
{
files: [
'packages/components/src/**/*.module.{css,scss}',
'packages/theme/src/**/*.module.{css,scss}',
'packages/ui/src/**/*.module.{css,scss}',
],
rules: {
'selector-class-pattern': SELECTOR_CLASS_PATTERN,
},
},
],
reportDescriptionlessDisables: true,
};
152 changes: 152 additions & 0 deletions tools/stylelint/stylelint-suppressions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
{
"widgets/events/style.module.css": {
"selector-class-pattern": {
"count": 3
}
},
"widgets/quick-draft/style.module.css": {
"selector-class-pattern": {
"count": 6
}
},
"widgets/site-preview/style.module.css": {
"selector-class-pattern": {
"count": 8
}
},
"packages/grid/src/dashboard-grid/grid.module.css": {
"selector-class-pattern": {
"count": 6
}
},
"packages/grid/src/dashboard-lanes/lanes.module.css": {
"selector-class-pattern": {
"count": 6
}
},
"widgets/news/components/news-list/news-list.module.css": {
"selector-class-pattern": {
"count": 2
}
},
"widgets/events/components/events-list/events-list.module.css": {
"selector-class-pattern": {
"count": 5
}
},
"widgets/events/components/location-picker/location-picker.module.css": {
"selector-class-pattern": {
"count": 1
}
},
"widgets/quick-draft/components/drafts-list/drafts-list.module.css": {
"selector-class-pattern": {
"count": 5
}
},
"widgets/quick-draft/components/saved-post/saved-post.module.css": {
"selector-class-pattern": {
"count": 1
}
},
"widgets/welcome/components/banner/banner.module.css": {
"selector-class-pattern": {
"count": 2
}
},
"widgets/welcome/components/feature-highlight/feature-highlight.module.css": {
"selector-class-pattern": {
"count": 1
}
},
"packages/widget-dashboard/src/components/actions/actions.module.css": {
"selector-class-pattern": {
"count": 7
}
},
"packages/widget-dashboard/src/components/widget-chrome/widget-chrome.module.css": {
"selector-class-pattern": {
"count": 3
}
},
"packages/widget-dashboard/src/components/widget-frame/widget-frame.module.css": {
"selector-class-pattern": {
"count": 1
}
},
"packages/widget-dashboard/src/components/widget-header/widget-header.module.css": {
"selector-class-pattern": {
"count": 2
}
},
"packages/widget-dashboard/src/components/widget-toolbar/widget-toolbar.module.css": {
"selector-class-pattern": {
"count": 1
}
},
"packages/widget-dashboard/src/components/widgets/widget-resize-handle.module.css": {
"selector-class-pattern": {
"count": 21
}
},
"packages/widget-dashboard/src/components/widgets/widgets.module.css": {
"selector-class-pattern": {
"count": 4
}
},
"packages/widget-dashboard/src/components/layout-settings/layout-model-edit-field/style.module.css": {
"selector-class-pattern": {
"count": 3
}
},
"routes/template-list/add-new-template/style.scss": {
"selector-class-pattern": {
"count": 1
}
},
"packages/block-library/src/image/editor.scss": {
"selector-class-pattern": {
"count": 2
}
},
"packages/block-library/src/navigation/style.scss": {
"selector-class-pattern": {
"count": 1
}
},
"packages/block-library/src/social-link/editor.scss": {
"selector-class-pattern": {
"count": 1
}
},
"packages/global-styles-ui/src/font-library/style.scss": {
"selector-class-pattern": {
"count": 2
}
},
"packages/global-styles-ui/src/variations/style.scss": {
"selector-class-pattern": {
"count": 6
}
},
"packages/block-editor/src/components/link-control/style.scss": {
"selector-class-pattern": {
"count": 1
}
},
"packages/dataviews/src/components/dataviews-filters/style.scss": {
"selector-class-pattern": {
"count": 1
}
},
"packages/edit-site/src/components/add-new-template/style.scss": {
"selector-class-pattern": {
"count": 1
}
},
"packages/edit-site/src/components/sidebar-navigation-screen/style.scss": {
"selector-class-pattern": {
"count": 5
}
}
}
1 change: 1 addition & 0 deletions tools/validation/check-local-changes.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ SimpleGit()

- npm install
- npm run lint:js:prune-suppressions
- npm run lint:css:update-suppressions
- npm run docs:build
- npm run --workspace @wordpress/theme build

Expand Down
Loading