This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 2a18a556b09 chore(frontend): lint Emotion CSS-in-JS with Stylelint
(#41871)
2a18a556b09 is described below
commit 2a18a556b09b736e7a241fa85c885933e2d3a683
Author: Evan Rusackas <[email protected]>
AuthorDate: Sun Jul 12 08:45:02 2026 -0700
chore(frontend): lint Emotion CSS-in-JS with Stylelint (#41871)
Co-authored-by: Claude Opus 4.8 <[email protected]>
Co-authored-by: Đỗ Trọng Hải <[email protected]>
---
.pre-commit-config.yaml | 6 +
.rat-excludes | 1 +
scripts/stylelint.sh | 49 ++
superset-frontend/.stylelintignore | 9 +
superset-frontend/package-lock.json | 926 +++++++++++++++++++--
superset-frontend/package.json | 6 +-
.../superset-core/src/theme/GlobalStyles.tsx | 8 +-
.../src/components/AsyncAceEditor/index.tsx | 1 -
.../DropdownContainer/DropdownContainer.tsx | 4 +-
.../src/components/Icons/Icons.stories.tsx | 6 +-
.../src/components/Modal/Modal.tsx | 4 +-
.../src/styles/index.tsx | 1 -
.../src/SqlLab/SqlLabGlobalStyles.tsx | 10 +-
.../src/SqlLab/components/EditorWrapper/index.tsx | 4 +-
.../src/SqlLab/components/ResultSet/index.tsx | 1 -
.../src/components/MessageToasts/Toast.tsx | 2 +-
.../src/components/ResizableSidebar/index.tsx | 2 +-
.../components/AddSliceCard/AddSliceCard.tsx | 2 +-
.../DashboardBuilder/DashboardBuilder.tsx | 4 +-
.../src/dashboard/components/DashboardGrid.tsx | 8 +-
.../dashboard/components/FiltersBadge/Styles.tsx | 1 -
.../src/dashboard/components/Header/index.tsx | 2 +-
.../components/filterscope/FilterScopeSelector.tsx | 2 +-
.../src/dashboard/components/menu/HoverMenu.tsx | 2 +-
.../FilterControls/FilterControlShared.tsx | 4 +-
.../nativeFilters/FilterBar/Vertical.tsx | 2 +-
.../FiltersConfigForm/RemovedFilter.tsx | 2 +-
.../explore/components/ControlPanelsContainer.tsx | 8 +-
.../explore/components/DataTableControl/index.tsx | 2 +-
.../DatasourcePanelDragOption/index.tsx | 2 +-
.../controls/VizTypeControl/VizTypeGallery.tsx | 2 +-
.../components/controls/VizTypeControl/index.tsx | 1 -
.../databases/UploadDataModel/ColumnsPreview.tsx | 4 +-
.../src/features/home/SavedQueries.tsx | 1 -
.../src/visualizations/TimeTable/TimeTable.tsx | 2 +-
superset-frontend/stylelint.config.js | 34 +
36 files changed, 1010 insertions(+), 115 deletions(-)
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index a1f3214ab05..98b34d3dc0a 100755
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -81,6 +81,12 @@ repos:
language: system
pass_filenames: true
files: ^superset-frontend/.*\.(js|jsx|ts|tsx)$
+ - id: stylelint-frontend
+ name: stylelint (frontend css-in-js)
+ entry: ./scripts/stylelint.sh
+ language: system
+ pass_filenames: true
+ files: ^superset-frontend/.*\.(js|jsx|ts|tsx)$
- id: eslint-docs
name: eslint (docs)
entry: bash -c 'cd docs && FILES=$(printf "%s\n" "$@" | sed
"s|^docs/||" | tr "\n" " ") && yarn eslint --fix --quiet $FILES'
diff --git a/.rat-excludes b/.rat-excludes
index 30b1ef1da9d..7b788738f2d 100644
--- a/.rat-excludes
+++ b/.rat-excludes
@@ -7,6 +7,7 @@
.codecov.yml
.eslintrc
.eslintignore
+.stylelintignore
.flake8
.nvmrc
.prettierrc
diff --git a/scripts/stylelint.sh b/scripts/stylelint.sh
new file mode 100755
index 00000000000..82980526ec9
--- /dev/null
+++ b/scripts/stylelint.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+script_dir="$(dirname "$(realpath "$0")")"
+root_dir="$(dirname "$script_dir")"
+frontend_dir=superset-frontend
+
+if [[ ! -d "$root_dir/$frontend_dir" ]]; then
+ echo "Error: $frontend_dir directory not found in $root_dir" >&2
+ exit 1
+fi
+
+cd "$root_dir/$frontend_dir"
+
+# Filter files to only include JS/TS files and remove the frontend dir prefix
+js_ts_files=()
+for file in "$@"; do
+ # Remove superset-frontend/ prefix if present
+ cleaned_file="${file#$frontend_dir/}"
+
+ # Only include JS/TS files (Emotion styles live in these)
+ if [[ "$cleaned_file" =~ \.(js|jsx|ts|tsx)$ ]]; then
+ js_ts_files+=("$cleaned_file")
+ fi
+done
+
+# Only run if we have JS/TS files to lint. --allow-empty-input keeps the hook
+# green when every passed file is covered by .stylelintignore.
+if [ ${#js_ts_files[@]} -gt 0 ]; then
+ npx stylelint --allow-empty-input "${js_ts_files[@]}"
+else
+ echo "No JavaScript/TypeScript files to lint for styles"
+fi
diff --git a/superset-frontend/.stylelintignore
b/superset-frontend/.stylelintignore
new file mode 100644
index 00000000000..9691403a12f
--- /dev/null
+++ b/superset-frontend/.stylelintignore
@@ -0,0 +1,9 @@
+# Files whose Emotion template literals nest a `css` tag inside an
+# interpolation (e.g. styled(X)`${props => css`...`}`) or otherwise use a
+# structure that postcss-styled-syntax cannot parse. Stylelint reports a
+# CssSyntaxError on these rather than a real lint finding, so they are
+# excluded until the syntax gains nested-template support.
+src/components/ListView/Filters/Base.ts
+src/features/databases/DatabaseModal/styles.ts
+src/features/databases/UploadDataModel/styles.ts
+packages/superset-ui-core/src/components/Typography/index.tsx
diff --git a/superset-frontend/package-lock.json
b/superset-frontend/package-lock.json
index 91dc079a63b..20a3638f61e 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -263,6 +263,7 @@
"open-cli": "^9.0.0",
"oxlint": "^1.72.0",
"po2json": "^0.4.5",
+ "postcss-styled-syntax": "^0.7.2",
"prettier": "3.9.4",
"prettier-plugin-packagejson": "^3.0.2",
"process": "^0.11.10",
@@ -275,6 +276,7 @@
"speed-measure-webpack-plugin": "^1.6.0",
"storybook": "10.4.6",
"style-loader": "^4.0.0",
+ "stylelint": "^17.14.0",
"swc-loader": "^0.2.7",
"ts-jest": "^29.4.11",
"tscw-config": "^1.1.2",
@@ -2703,6 +2705,67 @@
"dev": true,
"license": "CC0-1.0"
},
+ "node_modules/@cacheable/memory": {
+ "version": "2.2.0",
+ "resolved":
"https://registry.npmjs.org/@cacheable/memory/-/memory-2.2.0.tgz",
+ "integrity":
"sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cacheable/utils": "^2.5.0",
+ "@keyv/bigmap": "^1.3.1",
+ "hookified": "^1.15.1",
+ "keyv": "^5.6.0"
+ }
+ },
+ "node_modules/@cacheable/memory/node_modules/@keyv/bigmap": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.1.tgz",
+ "integrity":
"sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hashery": "^1.4.0",
+ "hookified": "^1.15.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "keyv": "^5.6.0"
+ }
+ },
+ "node_modules/@cacheable/memory/node_modules/keyv": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz",
+ "integrity":
"sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@keyv/serialize": "^1.1.1"
+ }
+ },
+ "node_modules/@cacheable/utils": {
+ "version": "2.5.0",
+ "resolved":
"https://registry.npmjs.org/@cacheable/utils/-/utils-2.5.0.tgz",
+ "integrity":
"sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hashery": "^1.5.1",
+ "keyv": "^5.6.0"
+ }
+ },
+ "node_modules/@cacheable/utils/node_modules/keyv": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz",
+ "integrity":
"sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@keyv/serialize": "^1.1.1"
+ }
+ },
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved":
"https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
@@ -2840,6 +2903,76 @@
"node": ">=20.19.0"
}
},
+ "node_modules/@csstools/media-query-list-parser": {
+ "version": "5.0.0",
+ "resolved":
"https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-5.0.0.tgz",
+ "integrity":
"sha512-T9lXmZOfnam3eMERPsszjY5NK0jX8RmThmmm99FZ8b7z8yMaFZWKwLWGZuTwdO3ddRY5fy13GmmEYZXB4I98Eg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-tokenizer": "^4.0.0"
+ }
+ },
+ "node_modules/@csstools/selector-resolve-nested": {
+ "version": "4.0.0",
+ "resolved":
"https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-4.0.0.tgz",
+ "integrity":
"sha512-9vAPxmp+Dx3wQBIUwc1v7Mdisw1kbbaGqXUM8QLTgWg7SoPGYtXBsMXvsFs/0Bn5yoFhcktzxNZGNaUt0VjgjA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss-selector-parser": "^7.1.1"
+ }
+ },
+ "node_modules/@csstools/selector-specificity": {
+ "version": "6.0.0",
+ "resolved":
"https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-6.0.0.tgz",
+ "integrity":
"sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "peerDependencies": {
+ "postcss-selector-parser": "^7.1.1"
+ }
+ },
"node_modules/@deck.gl/aggregation-layers": {
"version": "9.2.11",
"resolved":
"https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-9.2.11.tgz",
@@ -5861,6 +5994,13 @@
"tslib": "2"
}
},
+ "node_modules/@keyv/serialize": {
+ "version": "1.1.1",
+ "resolved":
"https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz",
+ "integrity":
"sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@kwsites/file-exists": {
"version": "1.1.1",
"resolved":
"https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz",
@@ -7318,20 +7458,6 @@
"node": "^18.17.0 || >=20.5.0"
}
},
- "node_modules/@npmcli/query/node_modules/postcss-selector-parser": {
- "version": "7.1.1",
- "resolved":
"https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
- "integrity":
"sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/@npmcli/redact": {
"version": "3.2.2",
"resolved":
"https://registry.npmjs.org/@npmcli/redact/-/redact-3.2.2.tgz",
@@ -8444,9 +8570,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -8464,9 +8587,6 @@
"arm64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -8484,9 +8604,6 @@
"ppc64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -8504,9 +8621,6 @@
"riscv64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -8524,9 +8638,6 @@
"riscv64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -8544,9 +8655,6 @@
"s390x"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -8564,9 +8672,6 @@
"x64"
],
"dev": true,
- "libc": [
- "glibc"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -8584,9 +8689,6 @@
"x64"
],
"dev": true,
- "libc": [
- "musl"
- ],
"license": "MIT",
"optional": true,
"os": [
@@ -14239,6 +14341,16 @@
"node": ">=4"
}
},
+ "node_modules/astral-regex": {
+ "version": "2.0.0",
+ "resolved":
"https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+ "integrity":
"sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/async": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
@@ -15270,6 +15382,30 @@
"node": "^20.17.0 || >=22.9.0"
}
},
+ "node_modules/cacheable": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.5.0.tgz",
+ "integrity":
"sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cacheable/memory": "^2.2.0",
+ "@cacheable/utils": "^2.5.0",
+ "hookified": "^1.15.0",
+ "keyv": "^5.6.0",
+ "qified": "^0.10.1"
+ }
+ },
+ "node_modules/cacheable/node_modules/keyv": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz",
+ "integrity":
"sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@keyv/serialize": "^1.1.1"
+ }
+ },
"node_modules/caching-transform": {
"version": "4.0.0",
"resolved":
"https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
@@ -15998,6 +16134,13 @@
"color-support": "bin.js"
}
},
+ "node_modules/colord": {
+ "version": "2.9.3",
+ "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
+ "integrity":
"sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/colorette": {
"version": "2.0.20",
"resolved":
"https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
@@ -16758,6 +16901,16 @@
"integrity":
"sha512-C4aQOpCmQL/Arl68chQatNh7/Nfyty15kbLNZezGudjcKSqHHVoHQEeb9IJcjgQ6CiurrHZoEt47yce891vjGw==",
"license": "BSD-3-Clause"
},
+ "node_modules/css-functions-list": {
+ "version": "3.3.3",
+ "resolved":
"https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.3.3.tgz",
+ "integrity":
"sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/css-line-break": {
"version": "2.1.0",
"resolved":
"https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
@@ -19870,6 +20023,16 @@
"fxparser": "src/cli/cli.js"
}
},
+ "node_modules/fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved":
"https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity":
"sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.9.1"
+ }
+ },
"node_modules/fastq": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz",
@@ -21258,9 +21421,9 @@
}
},
"node_modules/get-east-asian-width": {
- "version": "1.3.0",
- "resolved":
"https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz",
- "integrity":
"sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==",
+ "version": "1.6.0",
+ "resolved":
"https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
+ "integrity":
"sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -21737,6 +21900,57 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/globby": {
+ "version": "16.2.1",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-16.2.1.tgz",
+ "integrity":
"sha512-JmsqJalahxxgW8V2ecSQ2G7UjPlI9cpKdrkG9KoNiXhd/YslXOTEB0cViENWUznuovIuNT+FkMbraDGjr4FCUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sindresorhus/merge-streams": "^4.0.0",
+ "fast-glob": "^3.3.3",
+ "ignore": "^7.0.5",
+ "is-path-inside": "^4.0.0",
+ "slash": "^5.1.0",
+ "unicorn-magic": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity":
"sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/globby/node_modules/slash": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
+ "integrity":
"sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globjoin": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
+ "integrity":
"sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/google-auth-library": {
"version": "10.9.0",
"resolved":
"https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.9.0.tgz",
@@ -21992,6 +22206,19 @@
"node": ">=8"
}
},
+ "node_modules/hashery": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz",
+ "integrity":
"sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hookified": "^1.15.0"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
@@ -22254,6 +22481,13 @@
"node": ">=0.10.0"
}
},
+ "node_modules/hookified": {
+ "version": "1.15.1",
+ "resolved":
"https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz",
+ "integrity":
"sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/hosted-git-info": {
"version": "9.0.3",
"resolved":
"https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz",
@@ -22397,6 +22631,19 @@
"node": ">= 12"
}
},
+ "node_modules/html-tags": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-5.1.0.tgz",
+ "integrity":
"sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/html-url-attributes": {
"version": "3.0.1",
"resolved":
"https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz",
@@ -22914,6 +23161,17 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/import-meta-resolve": {
+ "version": "4.2.0",
+ "resolved":
"https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz",
+ "integrity":
"sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/imports-loader": {
"version": "5.0.0",
"resolved":
"https://registry.npmjs.org/imports-loader/-/imports-loader-5.0.0.tgz",
@@ -23578,6 +23836,19 @@
"node": ">=8"
}
},
+ "node_modules/is-path-inside": {
+ "version": "4.0.0",
+ "resolved":
"https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz",
+ "integrity":
"sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-plain-obj": {
"version": "1.1.0",
"resolved":
"https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
@@ -25892,6 +26163,21 @@
}
}
},
+ "node_modules/jsdom/node_modules/@noble/hashes": {
+ "version": "2.2.0",
+ "resolved":
"https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz",
+ "integrity":
"sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">= 20.19.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/jsdom/node_modules/css-tree": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
@@ -27455,6 +27741,13 @@
"integrity":
"sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==",
"license": "MIT"
},
+ "node_modules/lodash.truncate": {
+ "version": "4.4.2",
+ "resolved":
"https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
+ "integrity":
"sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/loglevel": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz",
@@ -27823,6 +28116,17 @@
"node": ">= 0.4"
}
},
+ "node_modules/mathml-tag-names": {
+ "version": "4.0.0",
+ "resolved":
"https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-4.0.0.tgz",
+ "integrity":
"sha512-aa6AU2Pcx0VP/XWnh8IGL0SYSgQHDT6Ucror2j2mXeFAlN3ahaNs8EZtG1YiticMkSLj3Gt6VPFfZogt7G5iFQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/md5": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
@@ -32176,28 +32480,30 @@
"postcss": "^8.1.0"
}
},
-
"node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser":
{
- "version": "7.1.1",
- "resolved":
"https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
- "integrity":
"sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "node_modules/postcss-modules-scope": {
+ "version": "3.2.1",
+ "resolved":
"https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz",
+ "integrity":
"sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==",
"dev": true,
- "license": "MIT",
+ "license": "ISC",
"dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": ">=4"
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
}
},
- "node_modules/postcss-modules-scope": {
- "version": "3.2.1",
- "resolved":
"https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz",
- "integrity":
"sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==",
+ "node_modules/postcss-modules-values": {
+ "version": "4.0.0",
+ "resolved":
"https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
+ "integrity":
"sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
"dev": true,
"license": "ISC",
"dependencies": {
- "postcss-selector-parser": "^7.0.0"
+ "icss-utils": "^5.0.0"
},
"engines": {
"node": "^10 || ^12 || >= 14"
@@ -32206,10 +32512,37 @@
"postcss": "^8.1.0"
}
},
- "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser":
{
- "version": "7.1.1",
- "resolved":
"https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
- "integrity":
"sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "node_modules/postcss-safe-parser": {
+ "version": "7.0.1",
+ "resolved":
"https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz",
+ "integrity":
"sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.31"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "7.1.4",
+ "resolved":
"https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz",
+ "integrity":
"sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -32220,20 +32553,34 @@
"node": ">=4"
}
},
- "node_modules/postcss-modules-values": {
- "version": "4.0.0",
- "resolved":
"https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
- "integrity":
"sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
+ "node_modules/postcss-styled-syntax": {
+ "version": "0.7.2",
+ "resolved":
"https://registry.npmjs.org/postcss-styled-syntax/-/postcss-styled-syntax-0.7.2.tgz",
+ "integrity":
"sha512-PrxG8BC6yh6pmrHx7NrseYt5TiSN57LbGYZxmreg7co7g+zXe6BwUfsZ6r/gghxbtabde3Z0hinelXj4jlJF4Q==",
"dev": true,
- "license": "ISC",
+ "license": "MIT",
"dependencies": {
- "icss-utils": "^5.0.0"
+ "typescript": "^6.0.3"
},
"engines": {
- "node": "^10 || ^12 || >= 14"
+ "node": ">=14.17"
},
"peerDependencies": {
- "postcss": "^8.1.0"
+ "postcss": "^8.5.1"
+ }
+ },
+ "node_modules/postcss-styled-syntax/node_modules/typescript": {
+ "version": "6.0.3",
+ "resolved":
"https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity":
"sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
}
},
"node_modules/postcss-value-parser": {
@@ -32654,6 +33001,26 @@
"node": ">=16.0.0"
}
},
+ "node_modules/qified": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/qified/-/qified-0.10.1.tgz",
+ "integrity":
"sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hookified": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/qified/node_modules/hookified": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/hookified/-/hookified-2.2.0.tgz",
+ "integrity":
"sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/qs": {
"version": "6.15.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
@@ -36198,6 +36565,24 @@
"node": ">=6"
}
},
+ "node_modules/slice-ansi": {
+ "version": "4.0.0",
+ "resolved":
"https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+ "integrity":
"sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved":
"https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
@@ -37449,6 +37834,334 @@
"inline-style-parser": "0.2.7"
}
},
+ "node_modules/stylelint": {
+ "version": "17.14.0",
+ "resolved":
"https://registry.npmjs.org/stylelint/-/stylelint-17.14.0.tgz",
+ "integrity":
"sha512-8xkHPpdqYryeIsOgfsYTmr6cIeC4nLYWk5S8BPxpodq8mIuepggkMljsHewWfuAjj/+qpRKou2QerhjMH3iasg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/stylelint"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/stylelint"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@csstools/css-calc": "^3.2.1",
+ "@csstools/css-parser-algorithms": "^4.0.0",
+ "@csstools/css-syntax-patches-for-csstree": "^1.1.5",
+ "@csstools/css-tokenizer": "^4.0.0",
+ "@csstools/media-query-list-parser": "^5.0.0",
+ "@csstools/selector-resolve-nested": "^4.0.0",
+ "@csstools/selector-specificity": "^6.0.0",
+ "colord": "^2.9.3",
+ "cosmiconfig": "^9.0.2",
+ "css-functions-list": "^3.3.3",
+ "css-tree": "^3.2.1",
+ "debug": "^4.4.3",
+ "fast-glob": "^3.3.3",
+ "fastest-levenshtein": "^1.0.16",
+ "file-entry-cache": "^11.1.3",
+ "global-modules": "^2.0.0",
+ "globby": "^16.2.0",
+ "globjoin": "^0.1.4",
+ "html-tags": "^5.1.0",
+ "ignore": "^7.0.5",
+ "import-meta-resolve": "^4.2.0",
+ "mathml-tag-names": "^4.0.0",
+ "meow": "^14.1.0",
+ "micromatch": "^4.0.8",
+ "normalize-path": "^3.0.0",
+ "picocolors": "^1.1.1",
+ "postcss": "^8.5.15",
+ "postcss-safe-parser": "^7.0.1",
+ "postcss-selector-parser": "^7.1.4",
+ "postcss-value-parser": "^4.2.0",
+ "string-width": "^8.2.1",
+ "supports-hyperlinks": "^4.4.0",
+ "svg-tags": "^1.0.0",
+ "table": "^6.9.0",
+ "write-file-atomic": "^7.0.1"
+ },
+ "bin": {
+ "stylelint": "bin/stylelint.mjs"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ }
+ },
+
"node_modules/stylelint/node_modules/@csstools/css-syntax-patches-for-csstree":
{
+ "version": "1.1.6",
+ "resolved":
"https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.6.tgz",
+ "integrity":
"sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "peerDependencies": {
+ "css-tree": "^3.2.1"
+ },
+ "peerDependenciesMeta": {
+ "css-tree": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/stylelint/node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved":
"https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity":
"sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/stylelint/node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity":
"sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/stylelint/node_modules/cosmiconfig": {
+ "version": "9.0.2",
+ "resolved":
"https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.2.tgz",
+ "integrity":
"sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "env-paths": "^2.2.1",
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/stylelint/node_modules/css-tree": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
+ "integrity":
"sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mdn-data": "2.27.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+ }
+ },
+ "node_modules/stylelint/node_modules/file-entry-cache": {
+ "version": "11.1.5",
+ "resolved":
"https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.5.tgz",
+ "integrity":
"sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^6.1.23"
+ }
+ },
+ "node_modules/stylelint/node_modules/flat-cache": {
+ "version": "6.1.23",
+ "resolved":
"https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.23.tgz",
+ "integrity":
"sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cacheable": "^2.5.0",
+ "flatted": "^3.4.2",
+ "hookified": "^1.15.0"
+ }
+ },
+ "node_modules/stylelint/node_modules/global-modules": {
+ "version": "2.0.0",
+ "resolved":
"https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+ "integrity":
"sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "global-prefix": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/stylelint/node_modules/global-prefix": {
+ "version": "3.0.0",
+ "resolved":
"https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
+ "integrity":
"sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ini": "^1.3.5",
+ "kind-of": "^6.0.2",
+ "which": "^1.3.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/stylelint/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity":
"sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/stylelint/node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity":
"sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/stylelint/node_modules/js-yaml": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
+ "integrity":
"sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/nodeca"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/stylelint/node_modules/mdn-data": {
+ "version": "2.27.1",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
+ "integrity":
"sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/stylelint/node_modules/meow": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-14.1.0.tgz",
+ "integrity":
"sha512-EDYo6VlmtnumlcBCbh1gLJ//9jvM/ndXHfVXIFrZVr6fGcwTUyCTFNTLCKuY3ffbK8L/+3Mzqnd58RojiZqHVw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/stylelint/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved":
"https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity":
"sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/stylelint/node_modules/string-width": {
+ "version": "8.2.2",
+ "resolved":
"https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz",
+ "integrity":
"sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.5.0",
+ "strip-ansi": "^7.1.2"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/stylelint/node_modules/strip-ansi": {
+ "version": "7.2.0",
+ "resolved":
"https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity":
"sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/stylelint/node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity":
"sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/stylelint/node_modules/write-file-atomic": {
+ "version": "7.0.1",
+ "resolved":
"https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-7.0.1.tgz",
+ "integrity":
"sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ }
+ },
"node_modules/stylis": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
@@ -37476,6 +38189,49 @@
"node": ">=8"
}
},
+ "node_modules/supports-hyperlinks": {
+ "version": "4.5.0",
+ "resolved":
"https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-4.5.0.tgz",
+ "integrity":
"sha512-ZW2OvfeCXrNTbLakPUzjQG922EeGCOteFSVoek5DKStTh898wf7zgtuFlzQN8HfZCxC3Eh02yJVrRW51hADf+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^5.0.1",
+ "supports-color": "^10.2.2"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1"
+ }
+ },
+ "node_modules/supports-hyperlinks/node_modules/has-flag": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz",
+ "integrity":
"sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-hyperlinks/node_modules/supports-color": {
+ "version": "10.2.2",
+ "resolved":
"https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz",
+ "integrity":
"sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved":
"https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
@@ -37505,6 +38261,12 @@
"node": ">=12.0.0"
}
},
+ "node_modules/svg-tags": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
+ "integrity":
"sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
+ "dev": true
+ },
"node_modules/svgo": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.3.tgz",
@@ -37588,6 +38350,23 @@
"url": "https://opencollective.com/synckit"
}
},
+ "node_modules/table": {
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz",
+ "integrity":
"sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "ajv": "^8.0.1",
+ "lodash.truncate": "^4.4.2",
+ "slice-ansi": "^4.0.0",
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/tagged-tag": {
"version": "1.0.0",
"resolved":
"https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz",
@@ -40649,6 +41428,21 @@
}
}
},
+ "node_modules/whatwg-url/node_modules/@noble/hashes": {
+ "version": "2.2.0",
+ "resolved":
"https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz",
+ "integrity":
"sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">= 20.19.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/whatwg-url/node_modules/webidl-conversions": {
"version": "8.0.1",
"resolved":
"https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz",
diff --git a/superset-frontend/package.json b/superset-frontend/package.json
index 8167496c282..230ef6ca3f2 100644
--- a/superset-frontend/package.json
+++ b/superset-frontend/package.json
@@ -57,7 +57,9 @@
"lint:all": "npx oxlint --config oxlint.json && npm run type",
"lint-fix": "npx oxlint --config oxlint.json --fix --quiet",
"lint-fix:all": "npx oxlint --config oxlint.json --fix",
- "lint:full": "npm run lint && npm run check:custom-rules",
+ "lint:full": "npm run lint && npm run check:custom-rules && npm run
stylelint",
+ "stylelint": "stylelint
\"{src,packages/*/src,plugins/*/src}/**/*.{ts,tsx}\"",
+ "stylelint-fix": "stylelint --fix
\"{src,packages/*/src,plugins/*/src}/**/*.{ts,tsx}\"",
"check:custom-rules": "node scripts/check-custom-rules.js",
"check:storybook-coverage": "node scripts/check-storybook-coverage.js",
"ensure-oxc": "echo 'OXC linter is ready' && npx oxlint --version",
@@ -346,6 +348,7 @@
"open-cli": "^9.0.0",
"oxlint": "^1.72.0",
"po2json": "^0.4.5",
+ "postcss-styled-syntax": "^0.7.2",
"prettier": "3.9.4",
"prettier-plugin-packagejson": "^3.0.2",
"process": "^0.11.10",
@@ -358,6 +361,7 @@
"speed-measure-webpack-plugin": "^1.6.0",
"storybook": "10.4.6",
"style-loader": "^4.0.0",
+ "stylelint": "^17.14.0",
"swc-loader": "^0.2.7",
"ts-jest": "^29.4.11",
"tscw-config": "^1.1.2",
diff --git
a/superset-frontend/packages/superset-core/src/theme/GlobalStyles.tsx
b/superset-frontend/packages/superset-core/src/theme/GlobalStyles.tsx
index 75956133675..7b9b34b2b60 100644
--- a/superset-frontend/packages/superset-core/src/theme/GlobalStyles.tsx
+++ b/superset-frontend/packages/superset-core/src/theme/GlobalStyles.tsx
@@ -38,7 +38,7 @@ export const GlobalStyles = () => {
<Global
key={`global-${theme.colorLink}`}
styles={css`
- // SPA
+ /* SPA */
html {
color-scheme: ${isDark ? 'dark' : 'light'};
}
@@ -93,7 +93,7 @@ export const GlobalStyles = () => {
}
}
- // Overriding bootstrap styles
+ /* Overriding bootstrap styles */
#app {
flex: 1 1 auto;
position: relative;
@@ -105,8 +105,8 @@ export const GlobalStyles = () => {
cursor: pointer;
}
- // Override geostyler CSS that hides AntD ColorPicker alpha input
- // See: https://github.com/apache/superset/issues/34721
+ /* Override geostyler CSS that hides AntD ColorPicker alpha input */
+ /* See: https://github.com/apache/superset/issues/34721 */
.ant-color-picker .ant-color-picker-alpha-input {
display: block;
}
diff --git
a/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
b/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
index 5d51b25f5d3..425db253f89 100644
---
a/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
+++
b/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/index.tsx
@@ -444,7 +444,6 @@ export function AsyncAceEditor(
/* Adjust tooltip styles */
.ace_tooltip {
margin-left: ${token.margin}px;
- padding: ${token.sizeUnit * 2}px;
background-color: ${token.colorBgElevated} !important;
color: ${token.colorText} !important;
border: 1px solid ${token.colorBorderSecondary};
diff --git
a/superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.tsx
b/superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.tsx
index 4e7edc904f7..e42d3154826 100644
---
a/superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.tsx
+++
b/superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.tsx
@@ -339,8 +339,8 @@ export const DropdownContainer = forwardRef(
<Global
styles={css`
.ant-popover-inner {
- // Some OS versions only show the scroll when hovering.
- // These settings will make the scroll always visible.
+ /* Some OS versions only show the scroll when hovering. */
+ /* These settings will make the scroll always visible. */
::-webkit-scrollbar {
-webkit-appearance: none;
width: 14px;
diff --git
a/superset-frontend/packages/superset-ui-core/src/components/Icons/Icons.stories.tsx
b/superset-frontend/packages/superset-ui-core/src/components/Icons/Icons.stories.tsx
index db107ef282d..a7a9f601294 100644
---
a/superset-frontend/packages/superset-ui-core/src/components/Icons/Icons.stories.tsx
+++
b/superset-frontend/packages/superset-ui-core/src/components/Icons/Icons.stories.tsx
@@ -63,11 +63,11 @@ const IconBlock = styled.div`
span {
margin-top: ${({ theme }) =>
- 2 * theme.sizeUnit}px; // Add spacing between icon and name
+ 2 * theme.sizeUnit}px; /* Add spacing between icon and name */
font-size: ${({ theme }) =>
- theme.fontSizeSM}; // Optional: adjust font size for elegance
+ theme.fontSizeSM}; /* Optional: adjust font size for elegance */
color: ${({ theme }) =>
- theme.colorText}; // Optional: subtle color for the name
+ theme.colorText}; /* Optional: subtle color for the name */
}
`;
diff --git
a/superset-frontend/packages/superset-ui-core/src/components/Modal/Modal.tsx
b/superset-frontend/packages/superset-ui-core/src/components/Modal/Modal.tsx
index 21216206f5a..f8768f29c35 100644
--- a/superset-frontend/packages/superset-ui-core/src/components/Modal/Modal.tsx
+++ b/superset-frontend/packages/superset-ui-core/src/components/Modal/Modal.tsx
@@ -120,8 +120,8 @@ export const StyledModal =
styled(BaseModal)<StyledModalProps>`
right: 0;
display: flex;
justify-content: center;
- // Keep the close button clickable when modal body content uses
- // position: sticky with elevated z-index (e.g. DatabaseModal header).
+ /* Keep the close button clickable when modal body content uses */
+ /* position: sticky with elevated z-index (e.g. DatabaseModal header).
*/
z-index: ${theme.zIndexPopupBase + 1};
}
diff --git
a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/styles/index.tsx
b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/styles/index.tsx
index 3bb714e03a2..892d571c143 100644
--- a/superset-frontend/plugins/plugin-chart-ag-grid-table/src/styles/index.tsx
+++ b/superset-frontend/plugins/plugin-chart-ag-grid-table/src/styles/index.tsx
@@ -74,7 +74,6 @@ export const FilterIconWrapper = styled.div<{
isFilterActive?: boolean }>`
padding: 3px 4px;
overflow: hidden;
- cursor: pointer;
border-radius: 4px;
${({ isFilterActive }) =>
diff --git a/superset-frontend/src/SqlLab/SqlLabGlobalStyles.tsx
b/superset-frontend/src/SqlLab/SqlLabGlobalStyles.tsx
index a8d33009829..fc84a68df91 100644
--- a/superset-frontend/src/SqlLab/SqlLabGlobalStyles.tsx
+++ b/superset-frontend/src/SqlLab/SqlLabGlobalStyles.tsx
@@ -32,14 +32,14 @@ export const SqlLabGlobalStyles = () => (
min-height: max(
100vh,
${theme.sizeUnit * 125}px
- ); // Set a min height so the gutter is always visible when resizing
+ ); /* Set a min height so the gutter is always visible when resizing */
overflow: hidden;
}
- // The tab label is a flex node (icon menu + title + status icon). antd's
- // overflow dropdown styles each menu item for a plain-text label, so the
- // nested flex defeats its ellipsis and very long names render blank. Cap
- // the item width and let the title truncate inside it.
+ /* The tab label is a flex node (icon menu + title + status icon).
antd's */
+ /* overflow dropdown styles each menu item for a plain-text label, so
the */
+ /* nested flex defeats its ellipsis and very long names render blank.
Cap */
+ /* the item width and let the title truncate inside it. */
.${SQLLAB_TAB_OVERFLOW_POPUP_CLASS} {
.ant-tabs-dropdown-menu-item {
max-width: ${theme.sizeUnit * 80}px;
diff --git a/superset-frontend/src/SqlLab/components/EditorWrapper/index.tsx
b/superset-frontend/src/SqlLab/components/EditorWrapper/index.tsx
index a11158c0942..9307b03ccce 100644
--- a/superset-frontend/src/SqlLab/components/EditorWrapper/index.tsx
+++ b/superset-frontend/src/SqlLab/components/EditorWrapper/index.tsx
@@ -344,8 +344,8 @@ const EditorWrapper = ({
}
.ace_autocomplete {
- // Use !important because Ace Editor applies extra CSS at the last
second
- // when opening the autocomplete.
+ /* Use !important because Ace Editor applies extra CSS at the last
second */
+ /* when opening the autocomplete. */
width: ${theme.sizeUnit * 130}px !important;
}
diff --git a/superset-frontend/src/SqlLab/components/ResultSet/index.tsx
b/superset-frontend/src/SqlLab/components/ResultSet/index.tsx
index 8f8600a5343..50e72efa37b 100644
--- a/superset-frontend/src/SqlLab/components/ResultSet/index.tsx
+++ b/superset-frontend/src/SqlLab/components/ResultSet/index.tsx
@@ -138,7 +138,6 @@ const ResultlessStyles = styled.div`
// but wrapping text too so text doesn't overflow
const MonospaceDiv = styled.div`
font-family: ${({ theme }) => theme.fontFamilyCode};
- white-space: pre;
word-break: break-word;
overflow-x: auto;
white-space: pre-wrap;
diff --git a/superset-frontend/src/components/MessageToasts/Toast.tsx
b/superset-frontend/src/components/MessageToasts/Toast.tsx
index 97205384058..7884b615995 100644
--- a/superset-frontend/src/components/MessageToasts/Toast.tsx
+++ b/superset-frontend/src/components/MessageToasts/Toast.tsx
@@ -35,7 +35,7 @@ const ToastContainer = styled.div`
align-items: flex-start;
gap: ${theme.sizeUnit * 2}px;
- // Content container for icon and text
+ /* Content container for icon and text */
.toast__content {
display: flex;
align-items: flex-start;
diff --git a/superset-frontend/src/components/ResizableSidebar/index.tsx
b/superset-frontend/src/components/ResizableSidebar/index.tsx
index 507d8e7c440..64d229fcc8c 100644
--- a/superset-frontend/src/components/ResizableSidebar/index.tsx
+++ b/superset-frontend/src/components/ResizableSidebar/index.tsx
@@ -30,7 +30,7 @@ const ResizableWrapper = styled.div`
}
.sidebar-resizer {
- // @z-index-above-sticky-header (100) + 1 = 101
+ /* @z-index-above-sticky-header (100) + 1 = 101 */
z-index: 101;
}
diff --git
a/superset-frontend/src/dashboard/components/AddSliceCard/AddSliceCard.tsx
b/superset-frontend/src/dashboard/components/AddSliceCard/AddSliceCard.tsx
index 93992fbf3a1..5e8239c2123 100644
--- a/superset-frontend/src/dashboard/components/AddSliceCard/AddSliceCard.tsx
+++ b/superset-frontend/src/dashboard/components/AddSliceCard/AddSliceCard.tsx
@@ -218,7 +218,7 @@ const AddSliceCard: FC<{
color: ${theme.colorText};
&:hover {
- //background: ${theme.colorFillTertiary};
+ /* background: ${theme.colorFillTertiary}; */
}
opacity: ${isSelected ? 0.4 : 'unset'};
diff --git
a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
index cd7ebc414f0..e569d4099f7 100644
---
a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
+++
b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
@@ -124,7 +124,7 @@ const StyledContent = styled.div<{
}>`
grid-column: 2;
grid-row: 2;
- // @z-index-above-dashboard-header (100) + 1 = 101
+ /* @z-index-above-dashboard-header (100) + 1 = 101 */
${({ fullSizeChartId }) => fullSizeChartId && `z-index: 101;`}
`;
@@ -327,7 +327,7 @@ const StyledDashboardContent = styled.div<{
box-sizing: border-box;
overflow-y: visible;
- // transitionable traits to show filter relevance
+ /* transitionable traits to show filter relevance */
transition:
opacity ${theme.motionDurationMid} ease-in-out,
border-color ${theme.motionDurationMid} ease-in-out,
diff --git a/superset-frontend/src/dashboard/components/DashboardGrid.tsx
b/superset-frontend/src/dashboard/components/DashboardGrid.tsx
index 6cb5f1238ed..58f5eddd51f 100644
--- a/superset-frontend/src/dashboard/components/DashboardGrid.tsx
+++ b/superset-frontend/src/dashboard/components/DashboardGrid.tsx
@@ -28,7 +28,11 @@ import type { LayoutItem } from 'src/dashboard/types';
import type { DropResult } from
'src/dashboard/components/dnd/dragDroppableConfig';
import DashboardComponent from '../containers/DashboardComponent';
import { Droppable } from './dnd/DragDroppable';
-import { GRID_GUTTER_SIZE, GRID_COLUMN_COUNT, BOTTOM_RESIZE_DIRECTION } from
'../util/constants';
+import {
+ GRID_GUTTER_SIZE,
+ GRID_COLUMN_COUNT,
+ BOTTOM_RESIZE_DIRECTION,
+} from '../util/constants';
import { TAB_TYPE } from '../util/componentTypes';
export interface DashboardGridProps {
@@ -113,7 +117,7 @@ const GridContent = styled.div<{ editMode?: boolean }>`
const GridColumnGuide = styled.div`
${({ theme }) => css`
- // /* Editing guides */
+ /* Editing guides */
&.grid-column-guide {
position: absolute;
top: 0;
diff --git a/superset-frontend/src/dashboard/components/FiltersBadge/Styles.tsx
b/superset-frontend/src/dashboard/components/FiltersBadge/Styles.tsx
index 6366d51f9b4..e3fed7b86c0 100644
--- a/superset-frontend/src/dashboard/components/FiltersBadge/Styles.tsx
+++ b/superset-frontend/src/dashboard/components/FiltersBadge/Styles.tsx
@@ -24,7 +24,6 @@ export const Pill = styled.div`
color: ${theme.colorBgBase};
background: ${theme.colorText};
border-radius: 1em;
- vertical-align: text-top;
padding: ${theme.sizeUnit}px ${theme.sizeUnit * 2}px;
font-size: ${theme.fontSize}px;
font-weight: ${theme.fontWeightStrong};
diff --git a/superset-frontend/src/dashboard/components/Header/index.tsx
b/superset-frontend/src/dashboard/components/Header/index.tsx
index 3eb4d39376b..5a57f778cc4 100644
--- a/superset-frontend/src/dashboard/components/Header/index.tsx
+++ b/superset-frontend/src/dashboard/components/Header/index.tsx
@@ -177,7 +177,7 @@ const actionButtonsStyle = (theme: SupersetTheme) => css`
`;
const StyledUndoRedoButton = styled(Button)`
- // TODO: check if we need this
+ /* TODO: check if we need this */
padding: 0;
&:hover {
background: transparent;
diff --git
a/superset-frontend/src/dashboard/components/filterscope/FilterScopeSelector.tsx
b/superset-frontend/src/dashboard/components/filterscope/FilterScopeSelector.tsx
index 9a6942cb38a..683e0b35279 100644
---
a/superset-frontend/src/dashboard/components/filterscope/FilterScopeSelector.tsx
+++
b/superset-frontend/src/dashboard/components/filterscope/FilterScopeSelector.tsx
@@ -313,7 +313,7 @@ const ScopeSelector = styled.div`
display: block;
}
- // disable style from react-checkbox-trees.css
+ /* disable style from react-checkbox-tree.css */
.rct-node-clickable:hover,
.rct-node-clickable:focus,
label:hover,
diff --git a/superset-frontend/src/dashboard/components/menu/HoverMenu.tsx
b/superset-frontend/src/dashboard/components/menu/HoverMenu.tsx
index 783b3323a88..58549b4bea2 100644
--- a/superset-frontend/src/dashboard/components/menu/HoverMenu.tsx
+++ b/superset-frontend/src/dashboard/components/menu/HoverMenu.tsx
@@ -32,7 +32,7 @@ const HoverStyleOverrides = styled.div`
.hover-menu {
opacity: 0;
position: absolute;
- z-index: 11; // one more than DragDroppable
+ z-index: 11; /* one more than DragDroppable */
font-size: ${({ theme }) => theme.fontSize};
}
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControlShared.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControlShared.tsx
index 68e407c4719..0d03c96cf0f 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControlShared.tsx
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControlShared.tsx
@@ -73,8 +73,8 @@ export const HorizontalOverflowFilterControlTitleBox = styled(
`;
export const AllFilterControlContainer = styled(Form)`
- // TODO this is a hack related to having form items inside others which is
not
- // normal antd-expected usage
+ /* TODO this is a hack related to having form items inside others which is
not */
+ /* normal antd-expected usage */
.ant-form-item .ant-form-item {
margin-bottom: 0 !important;
}
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Vertical.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Vertical.tsx
index a835e58fe27..47ecde6fd6b 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Vertical.tsx
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/Vertical.tsx
@@ -60,7 +60,7 @@ const BarWrapper = styled.div<{ width: number }>`
margin: 0;
}
&.open {
- width: ${({ width }) => width}px; // arbitrary...
+ width: ${({ width }) => width}px; /* arbitrary... */
}
`;
diff --git
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/RemovedFilter.tsx
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/RemovedFilter.tsx
index a861d980abc..7e958b68fc4 100644
---
a/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/RemovedFilter.tsx
+++
b/superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/RemovedFilter.tsx
@@ -24,7 +24,7 @@ import { styled } from '@apache-superset/core/theme';
const RemovedContent = styled.div`
display: flex;
flex-direction: column;
- height: 400px; // arbitrary
+ height: 400px; /* arbitrary */
text-align: center;
justify-content: center;
align-items: center;
diff --git
a/superset-frontend/src/explore/components/ControlPanelsContainer.tsx
b/superset-frontend/src/explore/components/ControlPanelsContainer.tsx
index 427c34f67b1..9c8435a69ab 100644
--- a/superset-frontend/src/explore/components/ControlPanelsContainer.tsx
+++ b/superset-frontend/src/explore/components/ControlPanelsContainer.tsx
@@ -152,8 +152,8 @@ const Styles = styled.div`
display: flex;
flex-direction: column;
- // Resizable add overflow-y: auto as a style to this div
- // To override it, we need to use !important
+ /* Resizable adds overflow-y: auto as a style to this div */
+ /* To override it, we need to use !important */
overflow: visible !important;
#controlSections {
@@ -166,7 +166,7 @@ const Styles = styled.div`
flex: 1 1 100%;
}
- // Ensure Ant Design tabs allow content to expand
+ /* Ensure Ant Design tabs allow content to expand */
.ant-tabs-content {
overflow: visible;
height: auto;
@@ -182,7 +182,7 @@ const Styles = styled.div`
height: auto;
}
- // Ensure collapse components can expand
+ /* Ensure collapse components can expand */
.ant-collapse-content {
overflow: visible;
}
diff --git
a/superset-frontend/src/explore/components/DataTableControl/index.tsx
b/superset-frontend/src/explore/components/DataTableControl/index.tsx
index d7c1e507981..ffaa6eb4d78 100755
--- a/superset-frontend/src/explore/components/DataTableControl/index.tsx
+++ b/superset-frontend/src/explore/components/DataTableControl/index.tsx
@@ -35,7 +35,7 @@ export const CellNull = styled('span')`
export const CopyButton = styled(Button)`
font-size: ${({ theme }) => theme.fontSizeSM}px;
- // needed to override button's first-of-type margin: 0
+ /* needed to override button's first-of-type margin: 0 */
&& {
margin: 0 ${({ theme }) => theme.sizeUnit * 2}px;
}
diff --git
a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx
b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx
index 204537c3292..cf8458e453c 100644
---
a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx
+++
b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx
@@ -41,7 +41,7 @@ const DatasourceItemContainer = styled.div<{ isDragging?:
boolean }>`
height: ${theme.sizeUnit * 6}px;
padding: 0 ${theme.sizeUnit}px;
- // hack to make the drag preview image corners rounded
+ /* hack to make the drag preview image corners rounded */
transform: translate(0, 0);
color: ${theme.colorText};
background-color: ${theme.colorBgLayout};
diff --git
a/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeGallery.tsx
b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeGallery.tsx
index 895f8f190c2..e88814129fa 100644
---
a/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeGallery.tsx
+++
b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeGallery.tsx
@@ -214,7 +214,7 @@ const IconsPane = styled.div`
justify-content: space-evenly;
grid-gap: ${({ theme }) => theme.sizeUnit * 2}px;
justify-items: center;
- // for some reason this padding doesn't seem to apply at the bottom of the
container. Why is a mystery.
+ /* for some reason this padding doesn't seem to apply at the bottom of the
container. Why is a mystery. */
padding: ${({ theme }) => theme.sizeUnit * 2}px;
`;
diff --git
a/superset-frontend/src/explore/components/controls/VizTypeControl/index.tsx
b/superset-frontend/src/explore/components/controls/VizTypeControl/index.tsx
index a2e92b1dd75..ad11bd73da9 100644
--- a/superset-frontend/src/explore/components/controls/VizTypeControl/index.tsx
+++ b/superset-frontend/src/explore/components/controls/VizTypeControl/index.tsx
@@ -107,7 +107,6 @@ const VizTypeControl = ({
display: flex;
justify-content: flex-end;
margin-top: ${theme.sizeUnit * 2}px;
- color: ${theme.colorTextSecondary};
text-decoration: underline;
font-size: ${theme.fontSizeSM}px;
color: ${theme.colorTextTertiary};
diff --git
a/superset-frontend/src/features/databases/UploadDataModel/ColumnsPreview.tsx
b/superset-frontend/src/features/databases/UploadDataModel/ColumnsPreview.tsx
index b079d39c525..f3ba17e10bb 100644
---
a/superset-frontend/src/features/databases/UploadDataModel/ColumnsPreview.tsx
+++
b/superset-frontend/src/features/databases/UploadDataModel/ColumnsPreview.tsx
@@ -28,8 +28,8 @@ interface ColumnsPreviewProps {
}
export const StyledDivContainer = styled.div`
- //margin-top: 10px;
- //margin-bottom: 10px;
+ /* margin-top: 10px; */
+ /* margin-bottom: 10px; */
`;
const ColumnsPreview: FC<ColumnsPreviewProps> = ({
diff --git a/superset-frontend/src/features/home/SavedQueries.tsx
b/superset-frontend/src/features/home/SavedQueries.tsx
index 147978f1e60..aaa9eb6d602 100644
--- a/superset-frontend/src/features/home/SavedQueries.tsx
+++ b/superset-frontend/src/features/home/SavedQueries.tsx
@@ -88,7 +88,6 @@ export const CardStyles = styled.div`
display: inline-block;
width: 100%;
height: 179px;
- background-repeat: no-repeat;
vertical-align: middle;
}
`;
diff --git a/superset-frontend/src/visualizations/TimeTable/TimeTable.tsx
b/superset-frontend/src/visualizations/TimeTable/TimeTable.tsx
index 31f4e6e47e4..132a5662979 100644
--- a/superset-frontend/src/visualizations/TimeTable/TimeTable.tsx
+++ b/superset-frontend/src/visualizations/TimeTable/TimeTable.tsx
@@ -30,7 +30,7 @@ const TimeTableStyles = styled.div<{ height?: number }>`
overflow: auto;
th {
- z-index: 11 !important; // to cover sparkline
+ z-index: 11 !important; /* to cover sparkline */
}
`;
diff --git a/superset-frontend/stylelint.config.js
b/superset-frontend/stylelint.config.js
new file mode 100644
index 00000000000..38ae5353ac5
--- /dev/null
+++ b/superset-frontend/stylelint.config.js
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+module.exports = {
+ customSyntax: 'postcss-styled-syntax',
+ rules: {
+ 'property-no-unknown': true,
+ 'unit-no-unknown': true,
+ 'function-no-unknown': true,
+ 'color-no-invalid-hex': true,
+ 'named-grid-areas-no-invalid': true,
+ 'string-no-newline': true,
+ 'no-invalid-double-slash-comments': true,
+ 'declaration-block-no-duplicate-properties': [
+ true,
+ { ignore: ['consecutive-duplicates-with-different-values'] },
+ ],
+ },
+};