diff --git a/.stylelintrc.json b/.stylelintrc.json new file mode 100644 index 0000000000..998393dd29 --- /dev/null +++ b/.stylelintrc.json @@ -0,0 +1,261 @@ +{ + "rules": { + "at-rule-empty-line-before": [ + "always", + { + "except": [ + "blockless-after-same-name-blockless", + "first-nested" + ], + "ignore": ["after-comment"], + "severity": "warning" + } + ], + "at-rule-name-case": ["lower", { "severity": "warning" }], + "at-rule-name-space-after": [ + "always-single-line", + { "severity": "warning" } + ], + "at-rule-semicolon-newline-after": [ + "always", + { "severity": "warning" } + ], + "block-no-empty": true, + "block-closing-brace-empty-line-before": [ + "never", + { "severity": "warning" } + ], + "block-closing-brace-newline-after": [ + "always", + { "severity": "warning" } + ], + "block-closing-brace-newline-before": [ + "always-multi-line", + { "severity": "warning" } + ], + "block-closing-brace-space-before": [ + "always-single-line", + { "severity": "warning" } + ], + "block-opening-brace-newline-after": [ + "always-multi-line", + { "severity": "warning" } + ], + "block-opening-brace-space-after": [ + "always-single-line", + { "severity": "warning" } + ], + "block-opening-brace-space-before": [ + "always", + { "severity": "warning" } + ], + "color-no-invalid-hex": true, + "color-hex-case": ["lower", { "severity": "warning" }], + "color-hex-length": ["short", { "severity": "warning" }], + "comment-no-empty": true, + "comment-empty-line-before": [ + "always", + { + "except": ["first-nested"], + "ignore": ["stylelint-commands"], + "severity": "warning" + } + ], + "comment-whitespace-inside": ["always", { "severity": "warning" }], + "custom-property-empty-line-before": [ + "always", + { + "except": ["after-custom-property", "first-nested"], + "ignore": ["after-comment", "inside-single-line-block"], + "severity": "warning" + } + ], + "declaration-block-no-duplicate-properties": [ + true, + { "severity": "warning" } + ], + "declaration-block-no-shorthand-property-overrides": true, + "declaration-bang-space-after": ["never", { "severity": "warning" }], + "declaration-bang-space-before": ["always", { "severity": "warning" }], + "declaration-block-semicolon-newline-after": [ + "always-multi-line", + { "severity": "warning" } + ], + "declaration-block-semicolon-space-after": [ + "always-single-line", + { "severity": "warning" } + ], + "declaration-block-semicolon-space-before": [ + "never", + { "severity": "warning" } + ], + "declaration-block-single-line-max-declarations": [ + 1, + { "severity": "warning" } + ], + "declaration-block-trailing-semicolon": [ + "always", + { "severity": "warning" } + ], + "declaration-colon-newline-after": [ + "always-multi-line", + { "severity": "warning" } + ], + "declaration-colon-space-after": [ + "always-single-line", + { "severity": "warning" } + ], + "declaration-colon-space-before": ["never", { "severity": "warning" }], + "declaration-empty-line-before": [ + "always", + { + "except": ["after-declaration", "first-nested"], + "ignore": ["after-comment", "inside-single-line-block"], + "severity": "warning" + } + ], + "font-family-no-duplicate-names": true, + "font-family-no-missing-generic-family-keyword": [ + true, + { "severity": "warning" } + ], + "function-calc-no-unspaced-operator": [true, { "severity": "warning" }], + "function-linear-gradient-no-nonstandard-direction": true, + "function-comma-newline-after": [ + "always-multi-line", + { "severity": "warning" } + ], + "function-comma-space-after": [ + "always-single-line", + { "severity": "warning" } + ], + "function-comma-space-before": ["never", { "severity": "warning" }], + "function-max-empty-lines": [0, { "severity": "warning" }], + "function-name-case": ["lower", { "severity": "warning" }], + "function-parentheses-newline-inside": [ + "always-multi-line", + { "severity": "warning" } + ], + "function-parentheses-space-inside": [ + "never-single-line", + { "severity": "warning" } + ], + "function-whitespace-after": ["always", { "severity": "warning" }], + "keyframe-declaration-no-important": [true, { "severity": "warning" }], + "length-zero-no-unit": [true, { "severity": "warning" }], + "max-empty-lines": [1, { "severity": "warning" }], + "media-feature-name-no-unknown": true, + "media-feature-colon-space-after": [ + "always", + { "severity": "warning" } + ], + "media-feature-colon-space-before": [ + "never", + { "severity": "warning" } + ], + "media-feature-name-case": ["lower", { "severity": "warning" }], + "media-feature-parentheses-space-inside": [ + "never", + { "severity": "warning" } + ], + "media-feature-range-operator-space-after": [ + "always", + { "severity": "warning" } + ], + "media-feature-range-operator-space-before": [ + "always", + { "severity": "warning" } + ], + "media-query-list-comma-newline-after": [ + "always-multi-line", + { "severity": "warning" } + ], + "media-query-list-comma-space-after": [ + "always-single-line", + { "severity": "warning" } + ], + "media-query-list-comma-space-before": [ + "never", + { "severity": "warning" } + ], + "no-duplicate-at-import-rules": true, + "no-duplicate-selectors": [true, { "severity": "warning" }], + "no-empty-source": true, + "no-extra-semicolons": [true, { "severity": "warning" }], + "no-eol-whitespace": [true, { "severity": "warning" }], + "no-missing-end-of-source-newline": [true, { "severity": "warning" }], + "no-invalid-double-slash-comments": [true, { "severity": "warning" }], + "number-leading-zero": ["always", { "severity": "warning" }], + "number-no-trailing-zeros": [true, { "severity": "warning" }], + "property-no-unknown": [true, { "severity": "warning" }], + "property-case": ["lower", { "severity": "warning" }], + "rule-empty-line-before": [ + "always-multi-line", + { + "except": ["first-nested"], + "ignore": ["after-comment"], + "severity": "warning" + } + ], + "selector-pseudo-class-no-unknown": true, + "selector-pseudo-element-no-unknown": true, + "selector-type-no-unknown": true, + "selector-attribute-brackets-space-inside": [ + "never", + { "severity": "warning" } + ], + "selector-attribute-operator-space-after": [ + "never", + { "severity": "warning" } + ], + "selector-attribute-operator-space-before": [ + "never", + { "severity": "warning" } + ], + "selector-combinator-space-after": [ + "always", + { "severity": "warning" } + ], + "selector-combinator-space-before": [ + "always", + { "severity": "warning" } + ], + "selector-descendant-combinator-no-non-space": [ + true, + { "severity": "warning" } + ], + "selector-list-comma-newline-after": [ + "always", + { "severity": "warning" } + ], + "selector-list-comma-space-before": [ + "never", + { "severity": "warning" } + ], + "selector-max-empty-lines": [0, { "severity": "warning" }], + "selector-pseudo-class-case": ["lower", { "severity": "warning" }], + "selector-pseudo-class-parentheses-space-inside": [ + "never", + { "severity": "warning" } + ], + "selector-pseudo-element-case": ["lower", { "severity": "warning" }], + "selector-pseudo-element-colon-notation": [ + "double", + { "severity": "warning" } + ], + "selector-type-case": ["lower", { "severity": "warning" }], + "string-no-newline": [true, { "severity": "warning" }], + "unit-no-unknown": true, + "unit-case": ["lower", { "severity": "warning" }], + "value-list-comma-newline-after": [ + "always-multi-line", + { "severity": "warning" } + ], + "value-list-comma-space-after": [ + "always-single-line", + { "severity": "warning" } + ], + "value-list-comma-space-before": ["never", { "severity": "warning" }], + "value-list-max-empty-lines": [0, { "severity": "warning" }] + } +} diff --git a/jsapp/scss/components/_kobo.collection-asset-list.scss b/jsapp/scss/components/_kobo.collection-asset-list.scss index 0b191f72de..af57f92ac1 100644 --- a/jsapp/scss/components/_kobo.collection-asset-list.scss +++ b/jsapp/scss/components/_kobo.collection-asset-list.scss @@ -143,8 +143,6 @@ position: relative; overflow: visible; - &--visible {} - &--collapsed { max-height: 0px; overflow: hidden; diff --git a/jsapp/scss/components/_kobo.list-view.scss b/jsapp/scss/components/_kobo.list-view.scss index 8a6a42c6ca..3c651f70e1 100644 --- a/jsapp/scss/components/_kobo.list-view.scss +++ b/jsapp/scss/components/_kobo.list-view.scss @@ -6,12 +6,6 @@ $mult: 0.5; float: left; } -.list-view { - // @extend %demo-panel; -} - -.list-view__attr {} - .list-view__attr--name { font-size: larger; } diff --git a/jsapp/scss/components/asset-dashboard.scss b/jsapp/scss/components/asset-dashboard.scss index 3245e3d02a..31a9434dfc 100644 --- a/jsapp/scss/components/asset-dashboard.scss +++ b/jsapp/scss/components/asset-dashboard.scss @@ -47,8 +47,6 @@ $permEditorColor: #999; } } -.k-history {} - .k-history--empty { opacity: 0.4; diff --git a/jsapp/scss/libs/alertify.overrides.scss b/jsapp/scss/libs/alertify.overrides.scss index a65fde2e0e..0d96175c5a 100644 --- a/jsapp/scss/libs/alertify.overrides.scss +++ b/jsapp/scss/libs/alertify.overrides.scss @@ -140,8 +140,8 @@ .ajs-message.ajs-warning {box-shadow: 0 2px 0 0 $cool-orange inset;} .ajs-message .ajs-close { - background-image: none; background: transparent; + background-image: none; right: 15px; top: 50%; margin-top: -10px; diff --git a/jsapp/scss/libs/react-select.overrides.scss b/jsapp/scss/libs/react-select.overrides.scss index 89cadcfc3e..86ae2a2811 100644 --- a/jsapp/scss/libs/react-select.overrides.scss +++ b/jsapp/scss/libs/react-select.overrides.scss @@ -29,8 +29,6 @@ } } - .kobo-select__value-container {} - .kobo-select__input input { // HACK: most of the global styles are removed by react-select itself, but // some we need to remove ourself (until our global input[type="text"] @@ -42,8 +40,6 @@ color: $cool-gray; } - .kobo-select__indicators {} - .kobo-select__indicator-separator { display: none; } diff --git a/package.json b/package.json index 7af994d07a..21d4032570 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,8 @@ "select2": "3.5.2-browserify", "spark-md5": "^3.0.0", "style-loader": "^0.23.0", + "stylelint": "^9.9.0", + "stylelint-webpack-plugin": "^0.10.5", "underscore": "^1.8.3", "webfonts-generator": "^0.4.0", "webpack": "^4.20.2", diff --git a/webpack/dev.server.js b/webpack/dev.server.js index 884cbd5472..b873238874 100644 --- a/webpack/dev.server.js +++ b/webpack/dev.server.js @@ -3,6 +3,7 @@ const path = require('path'); const webpack = require('webpack'); const WebpackCommon = require('./webpack.common'); const BundleTracker = require('webpack-bundle-tracker'); +const StyleLintPlugin = require('stylelint-webpack-plugin'); var isPublicDomainDefined = process.env.KOBOFORM_PUBLIC_SUBDOMAIN && process.env.PUBLIC_DOMAIN_NAME; var publicDomain = isPublicDomainDefined ? process.env.KOBOFORM_PUBLIC_SUBDOMAIN @@ -30,6 +31,12 @@ module.exports = WebpackCommon({ host: '0.0.0.0' }, plugins: [ + new StyleLintPlugin({ + failOnError: false, + emitErrors: true, + syntax: 'scss', + files: './jsapp/**/*.scss' + }), new BundleTracker({path: __dirname, filename: '../webpack-stats.json'}), new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin() diff --git a/webpack/webpack.common.js b/webpack/webpack.common.js index 3fd9352473..51d99b00e4 100644 --- a/webpack/webpack.common.js +++ b/webpack/webpack.common.js @@ -1,6 +1,7 @@ const path = require('path'); const webpack = require('webpack'); const BundleTracker = require('webpack-bundle-tracker'); +const StyleLintPlugin = require('stylelint-webpack-plugin'); var merge = require('lodash.merge'); // HACK: we needed to define this postcss-loader because of a problem with @@ -74,6 +75,12 @@ var defaultOptions = { } }, plugins: [ + new StyleLintPlugin({ + failOnError: false, + emitErrors: true, + syntax: 'scss', + files: './jsapp/**/*.scss' + }), new BundleTracker({path: __dirname, filename: '../webpack-stats.json'}) ] }