Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Stylelint #3736

Merged
merged 7 commits into from
Apr 25, 2023
Merged

Add Stylelint #3736

merged 7 commits into from
Apr 25, 2023

Conversation

julieg18
Copy link
Contributor

@julieg18 julieg18 commented Apr 21, 2023

  • adds stylelint, a css linter, to the project

Demo

Screen.Recording.2023-04-21.at.3.37.25.PM.mov

Fixes #3597

package.json Outdated Show resolved Hide resolved
.stylelintrc.js Outdated
@@ -0,0 +1,10 @@
module.exports = {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Technically, only webview has CSS but I chose to make it global since the VSCode extension for stylelint requires the workspace to have stylelint and config file to be in the root of the workspace. Any reasons not too though?

Copy link
Member

Choose a reason for hiding this comment

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

Can we move as set stylelint.config in the .vscode/settings file? or is there another option?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

I got the hot tip that:

I’d start by extending stylelint-config-sass-guidelines and stylelint-config-prettier

Copy link
Contributor Author

@julieg18 julieg18 Apr 25, 2023

Choose a reason for hiding this comment

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

And do we need to disable the built-in linters as per: https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint#disable-vs-codes-built-in-linters-optional?

Good idea! Disabled now.

I’d start by extending stylelint-config-sass-guidelines and stylelint-config-prettier

On further research stylelint-config-prettier is depreciated and sass-guidelines is indeed in use inside of our current scss plugin!

Can we move as set stylelint.config in the .vscode/settings file? or is there another option?

I managed to move our stylelint config file to be inside of webview but I couldn't figure out a way to move stylelint packages inside of webview.

I tried to install stylelint packages inside of webview via the stylelint.stylelintPath config option, but stylelint kept getting installed inside the root for some reason, even after moving packages inside of webview/package.json, deleting node_modules, and starting out of a fresh install. I even tried to revert yarn.lock to a previous commit and fresh install the packages but stylelint still appeared inside of /node_modules instead of /webview/node_modules. Kept the packages installed in the root for now but can revisit this later

&:hover .copyButton {
opacity: 1;
}
.tooltipColumn {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Almost all changes in the pr were done with the --fix flag and I made three manual changes:

  • no-descending-specificity issue in /ribbon
  • no-descending-specificity issue in /plots
  • at-extend-no-missing-placeholder in /table

@@ -1,11 +1,11 @@
/* stylelint-disable no-descending-specificity */
Copy link
Contributor Author

Choose a reason for hiding this comment

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

table/styles.module.scss had a lot of errors with no-descending-specificity. I disabled this file rule for now since it will take some time to take care of.

dvc-vscode-webview:lint:css: src/experiments/components/table/styles.module.scss
dvc-vscode-webview:lint:css:  222:1  ✖  Expected selector ".experimentsTh" to come before selector ".experimentsTh:first-child"                                                                               no-descending-specificity
dvc-vscode-webview:lint:css:  284:3  ✖  Expected selector ".firstLevelHeaderCell .paramHeaderCell" to come before selector ".headRow:last-child .paramHeaderCell"                                             no-descending-specificity
dvc-vscode-webview:lint:css:  289:3  ✖  Expected selector ".firstLevelHeaderCell .metricHeaderCell" to come before selector ".headRow:last-child .metricHeaderCell"                                           no-descending-specificity
dvc-vscode-webview:lint:css:  294:3  ✖  Expected selector ".firstLevelHeaderCell .depHeaderCell" to come before selector ".headRow:last-child .depHeaderCell"                                                 no-descending-specificity
dvc-vscode-webview:lint:css:  330:3  ✖  Expected selector ".iconMenu ul[role='menu']" to come before selector ".dropTargetHeaderCell .iconMenu ul[role='menu']"                                               no-descending-specificity
dvc-vscode-webview:lint:css:  352:3  ✖  Expected selector ".moveToRight ul[role='menu']" to come before selector ".dropTargetHeaderCell .iconMenu ul[role='menu']"                                            no-descending-specificity
dvc-vscode-webview:lint:css:  507:1  ✖  Expected selector ".experimentsTd" to come before selector ".experimentsTd:first-child"                                                                               no-descending-specificity
dvc-vscode-webview:lint:css:  514:3  ✖  Expected selector ".experimentsTd:not(.experimentCell)::before" to come before selector ".bodyRow:hover .experimentsTd:not(.experimentCell):hover::before"            no-descending-specificity
dvc-vscode-webview:lint:css:  514:3  ✖  Expected selector ".experimentsTd:not(.experimentCell)::before" to come before selector ".bodyRow:hover .experimentsTd:hover + .experimentsTd::before"                no-descending-specificity
dvc-vscode-webview:lint:css:  514:3  ✖  Expected selector ".experimentsTd:not(.experimentCell)::before" to come before selector ".rowSelected:hover .experimentsTd:not(.experimentCell):hover::before"        no-descending-specificity
dvc-vscode-webview:lint:css:  514:3  ✖  Expected selector ".experimentsTd:not(.experimentCell)::before" to come before selector ".rowSelected:hover .experimentsTd:hover + .experimentsTd::before"            no-descending-specificity
dvc-vscode-webview:lint:css:  536:3  ✖  Expected selector ".experimentsTd:first-child" to come before selector ".rowSelected .experimentsTd:not(.experimentCell)"                                             no-descending-specificity
dvc-vscode-webview:lint:css:  536:3  ✖  Expected selector ".experimentsTd:first-child" to come before selector ".bodyRow:not(.rowSelected):hover .experimentsTd"                                              no-descending-specificity
dvc-vscode-webview:lint:css:  536:3  ✖  Expected selector ".experimentsTd:first-child" to come before selector ".bodyRow:not(.rowSelected):hover .experimentsTd:not(.experimentCell)"                         no-descending-specificity
dvc-vscode-webview:lint:css:  542:3  ✖  Expected selector ".experimentsTd:last-child" to come before selector ".rowSelected .experimentsTd:not(.experimentCell)"                                              no-descending-specificity
dvc-vscode-webview:lint:css:  542:3  ✖  Expected selector ".experimentsTd:last-child" to come before selector ".bodyRow:not(.rowSelected):hover .experimentsTd"                                               no-descending-specificity
dvc-vscode-webview:lint:css:  542:3  ✖  Expected selector ".experimentsTd:last-child" to come before selector ".bodyRow:not(.rowSelected):hover .experimentsTd:not(.experimentCell)"                          no-descending-specificity
dvc-vscode-webview:lint:css:  549:1  ✖  Expected selector ".innerCell" to come before selector ".experimentsTd:first-child .innerCell"                                                                        no-descending-specificity
dvc-vscode-webview:lint:css:  549:1  ✖  Expected selector ".innerCell" to come before selector ".experimentsTd:last-child .innerCell"                                                                         no-descending-specificity
dvc-vscode-webview:lint:css:  567:3  ✖  Expected selector ".experimentCell .innerCell" to come before selector ".experimentsTd:first-child .innerCell"                                                        no-descending-specificity
dvc-vscode-webview:lint:css:  567:3  ✖  Expected selector ".experimentCell .innerCell" to come before selector ".experimentsTd:last-child .innerCell"                                                         no-descending-specificity
dvc-vscode-webview:lint:css:  578:1  ✖  Expected selector ".rowActions" to come before selector ".workspaceRowGroup .rowActions"                                                                              no-descending-specificity
dvc-vscode-webview:lint:css:  619:3  ✖  Expected selector ".starSwitch svg" to come before selector ".iconMenu ul[role='menu'] button svg"                                                                    no-descending-specificity
dvc-vscode-webview:lint:css:  622:5  ✖  Expected selector ".rowSelected .starSwitch svg" to come before selector ".iconMenu ul[role='menu'] button svg"                                                       no-descending-specificity
dvc-vscode-webview:lint:css:  627:3  ✖  Expected selector ".starSwitch[aria-checked='true'] svg" to come before selector ".iconMenu ul[role='menu'] button svg"                                               no-descending-specificity
dvc-vscode-webview:lint:css:  748:3  ✖  Expected selector ".experimentCellText > *" to come before selector ".experimentsTable.withExpColumnShadow .experimentsTr > *:first-child"                            no-descending-specificity
dvc-vscode-webview:lint:css:  759:3  ✖  Expected selector ".experimentCellSecondaryName > *" to come before selector ".experimentsTable.withExpColumnShadow .experimentsTr > *:first-child"                   no-descending-specificity
dvc-vscode-webview:lint:css:  763:3  ✖  Expected selector ".experimentCellSecondaryName svg" to come before selector ".iconMenu ul[role='menu'] button svg"                                                   no-descending-specificity
dvc-vscode-webview:lint:css:  763:3  ✖  Expected selector ".experimentCellSecondaryName svg" to come before selector ".rowSelected .starSwitch svg"                                                           no-descending-specificity
dvc-vscode-webview:lint:css:  763:3  ✖  Expected selector ".experimentCellSecondaryName svg" to come before selector ".starSwitch[aria-checked='true'] svg"                                                   no-descending-specificity
dvc-vscode-webview:lint:css:  784:3  ✖  Expected selector ".experimentCellSecondaryNameTooltip *:first-child" to come before selector ".experimentsTable.withExpColumnShadow .experimentsTr > *:first-child"  no-descending-specificity
dvc-vscode-webview:lint:css:  794:5  ✖  Expected selector ".experimentCellSecondaryNameTooltip .sha svg" to come before selector ".iconMenu ul[role='menu'] button svg"                                       no-descending-specificity
dvc-vscode-webview:lint:css:  814:1  ✖  Expected selector ".timestampInnerCell" to come before selector ".workspaceRowGroup .timestampInnerCell"                                                              no-descending-specificity
dvc-vscode-webview:lint:css:  867:3  ✖  Expected selector ".commitsAndBranchesNavButton:disabled" to come before selector ".commitsAndBranchesNavButton:hover:not(:disabled)"                                 no-descending-specificity
dvc-vscode-webview:lint:css: 
dvc-vscode-webview:lint:css: 34 problems (34 errors, 0 warnings)

Personally, I think taking care of these will lower the chance of specificity issues and clean things up more but we could also consider turning off this rule entirely if we think it's too strict to upkeep.

Copy link
Member

Choose a reason for hiding this comment

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

If it is a useful rule we should fix.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be really good to fix these. It might be too big for this PR, but a follow up just for this would be great.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Glad we're all in agreement! Will plan to do this in a followup.

.stylelintrc.js Outdated
@@ -0,0 +1,10 @@
module.exports = {
extends: 'stylelint-config-standard-scss',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here's the config for stylelint-config-standard-scss. There are also other rules available plus plugins that we could consider enabling.

Copy link
Member

Choose a reason for hiding this comment

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

[Q] Any rules that are missing that we should have turned on?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think some of the rules for "Max and min" would be useful for us as most of our current problems originate from that.

max-nesting-depth
selector-max-attribute
selector-max-class
selector-max-combinator
selector-max-type <- wondering if setting this to 0 would work
selector-max-specificity

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added max and min rules!

    'max-nesting-depth': 2,
    'selector-max-attribute': 2,
    'selector-max-class': 2,
    'selector-max-combinators': 3,
    'selector-max-type': 2,

Had multiple accounts of selector-max-class in table so added a disable comment and plan to fix them in a followup!

I think having a max of two for each of these is a good thing to aim for in the future but we could discuss numbers for each in the future!

Copy link
Contributor

Choose a reason for hiding this comment

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

'selector-max-type': 2, it's fine for now, but since we just changed some type selectors to classes, I feel like 1 would be more appropriate (if 0 does not work).

.stylelintrc.js Outdated
module.exports = {
extends: 'stylelint-config-standard-scss',
rules: {
'custom-property-pattern': null,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have a mixture of camelCase and kebab case rules in our styles thanks to our own CSS module classes, targeting 3rd party components like tippy, and VSCode variables using a mixture of both. I disabled pattern rules, but we could also set things for camelCase and disable certain files.

Copy link
Member

Choose a reason for hiding this comment

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

we can't control other packages but I think we use camelCase, right? We should turn on and exclude files/lines where we can't update. It will probably encourage us to wrap external modules in specific places instead of using them all throughout the code.

Copy link
Contributor

Choose a reason for hiding this comment

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

All kebab-case rules should be inside :global(...). Looking at stylelint configure docs, I've stumbled upon this:

{
  "rules": {
    "selector-pseudo-class-no-unknown": [
      true,
      {
        "ignorePseudoClasses": ["global"]
      }
    ]
  }
}

Not sure if it applies in this case, but if we can ignore global we could set the rule correctly to camelCase.

On another note (out of scope), unless it's really specific to the current CSS module (.myModuleBlock :global(.lib-class) {), we should move the :global(....) selector to the shared/style.scss file without using global and probably ignore this whole file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will need to move turning on camelCase rules to a followup. Turns out it involves adjusting quite a few files :)

@julieg18 julieg18 marked this pull request as ready for review April 21, 2023 20:33
Copy link
Member

@mattseddon mattseddon left a comment

Choose a reason for hiding this comment

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

LGTM but please my opinion is less valuable than @sroy3's.

package.json Outdated Show resolved Hide resolved
.stylelintrc.js Outdated
module.exports = {
extends: 'stylelint-config-standard-scss',
rules: {
'custom-property-pattern': null,
Copy link
Member

Choose a reason for hiding this comment

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

we can't control other packages but I think we use camelCase, right? We should turn on and exclude files/lines where we can't update. It will probably encourage us to wrap external modules in specific places instead of using them all throughout the code.

.stylelintrc.js Outdated
@@ -0,0 +1,10 @@
module.exports = {
extends: 'stylelint-config-standard-scss',
Copy link
Member

Choose a reason for hiding this comment

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

[Q] Any rules that are missing that we should have turned on?

.stylelintrc.js Outdated
@@ -0,0 +1,10 @@
module.exports = {
Copy link
Member

Choose a reason for hiding this comment

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

Can we move as set stylelint.config in the .vscode/settings file? or is there another option?

@@ -1,11 +1,11 @@
/* stylelint-disable no-descending-specificity */
Copy link
Member

Choose a reason for hiding this comment

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

If it is a useful rule we should fix.

Copy link
Contributor

@sroy3 sroy3 left a comment

Choose a reason for hiding this comment

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

This is great. Wish it could have solved more of our problems, but that's definitely a great help in consistency.
I love how it removed duplication and useless style (I would have thought there were more of those). Spotting these things would have been a long process manually.

.stylelintrc.js Outdated
module.exports = {
extends: 'stylelint-config-standard-scss',
rules: {
'custom-property-pattern': null,
Copy link
Contributor

Choose a reason for hiding this comment

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

All kebab-case rules should be inside :global(...). Looking at stylelint configure docs, I've stumbled upon this:

{
  "rules": {
    "selector-pseudo-class-no-unknown": [
      true,
      {
        "ignorePseudoClasses": ["global"]
      }
    ]
  }
}

Not sure if it applies in this case, but if we can ignore global we could set the rule correctly to camelCase.

On another note (out of scope), unless it's really specific to the current CSS module (.myModuleBlock :global(.lib-class) {), we should move the :global(....) selector to the shared/style.scss file without using global and probably ignore this whole file.

@@ -1,11 +1,11 @@
/* stylelint-disable no-descending-specificity */
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be really good to fix these. It might be too big for this PR, but a follow up just for this would be great.

webview/src/shared/variables.scss Outdated Show resolved Hide resolved
.stylelintrc.js Outdated
@@ -0,0 +1,10 @@
module.exports = {
extends: 'stylelint-config-standard-scss',
Copy link
Contributor

Choose a reason for hiding this comment

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

I think some of the rules for "Max and min" would be useful for us as most of our current problems originate from that.

max-nesting-depth
selector-max-attribute
selector-max-class
selector-max-combinator
selector-max-type <- wondering if setting this to 0 would work
selector-max-specificity

julieg18 and others added 3 commits April 25, 2023 10:09
@julieg18
Copy link
Contributor Author

julieg18 commented Apr 25, 2023

Resolved some of the comments! What's left:

To do before merging

  • Fix new stylelint errors that popped up when I merged to latest version of main

To do in followups (will create an issue)

I'll wait a bit before merging to make sure no one wants any of the "followup" comments to be taken care of before we merge!

@julieg18 julieg18 enabled auto-merge (squash) April 25, 2023 19:54
@codeclimate
Copy link

codeclimate bot commented Apr 25, 2023

Code Climate has analyzed commit 502acf0 and detected 0 issues on this pull request.

The test coverage on the diff in this pull request is 100.0% (85% is the threshold).

This pull request will bring the total coverage in the repository to 94.7% (0.0% change).

View more on Code Climate.

@julieg18 julieg18 merged commit 16dacc7 into main Apr 25, 2023
@julieg18 julieg18 deleted the add-stylelint branch April 25, 2023 20:08
@julieg18 julieg18 mentioned this pull request Apr 25, 2023
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clean up Experiments Table SCSS
3 participants