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
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .stylelintrc.js
Original file line number Diff line number Diff line change
@@ -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

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).

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 :)

'selector-class-pattern': null,
'scss/percent-placeholder-pattern': null,
'selector-pseudo-class-no-unknown': null,
'scss/percent-placeholder-pattern': null
}
}
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,11 @@
"lint-staged": "13.2.1",
"npm-run-all": "4.1.5",
"nyc": "15.1.0",
"postcss": "^8.4.23",
julieg18 marked this conversation as resolved.
Show resolved Hide resolved
"prettier": "2.8.7",
"prettier-config-standard": "5.0.0",
"stylelint": "^15.5.0",
"stylelint-config-standard-scss": "^8.0.0",
"ts-node": "10.9.1",
"turbo": "1.9.1",
"typescript": "5.0.4"
Expand Down
6 changes: 5 additions & 1 deletion turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@
"dependsOn": ["^lint:prettier"],
"outputs": []
},
"lint:css": {
"dependsOn": ["^lint:css"],
"outputs": []
},
"lint": {
"dependsOn": ["lint:prettier", "lint:eslint", "lint:build"],
"dependsOn": ["lint:prettier", "lint:eslint", "lint:css", "lint:build"],
"outputs": []
},
"dev": {
Expand Down
1 change: 1 addition & 0 deletions webview/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"format": "prettier --write '**/*.{js,json,jsx,md,scss,ts,tsx,yaml,yml}'",
"lint:prettier": "prettier -c '**/*.{js,json,jsx,md,scss,ts,tsx,yaml,yml}'",
"lint:eslint": "eslint --cache '**/*.{js,ts,jsx,tsx}'",
"lint:css": "stylelint **/*.scss",
"lint:build": "webpack --mode development",
"dev": "webpack watch --mode development",
"build": "webpack --mode production",
Expand Down
55 changes: 35 additions & 20 deletions webview/src/experiments/components/table/styles.module.scss
Original file line number Diff line number Diff line change
@@ -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.

// Variables

@import '../../../shared/variables.scss';
@import '../../../shared/mixins.scss';
@import '../../../shared/variables';
@import '../../../shared/mixins';

$nested-row-padding: 1.35rem;
$row-border: 1px solid $border-color;

$edge-padding: 0.8rem;
$cell-padding: 0.5rem;
$workspace-row-edge-margin: $edge-padding - $cell-padding;
Expand Down Expand Up @@ -50,6 +50,7 @@ $badge-size: 0.85rem;
align-items: center;
width: 100%;
height: 100%;

&:hover {
& .copyButton {
display: block;
Expand Down Expand Up @@ -85,6 +86,10 @@ $badge-size: 0.85rem;
text-overflow: ellipsis;
}

%noSelect {
user-select: none;
}

// Concrete selectors

@keyframes spin {
Expand All @@ -93,12 +98,9 @@ $badge-size: 0.85rem;
}
}

.noSelect {
user-select: none;
}

.isColumnResizing {
@extend .noSelect;
@extend %noSelect;

cursor: col-resize;

* {
Expand Down Expand Up @@ -148,7 +150,7 @@ $badge-size: 0.85rem;

.experimentsTable.withExpColumnShadow .experimentsTr > *:first-child {
&::after {
box-shadow: 3px 0px 3px $shadow;
box-shadow: 3px 0 3px $shadow;
}

> div::after {
Expand All @@ -161,13 +163,13 @@ $badge-size: 0.85rem;
position: relative;
border: none;
background: none;
padding: 0;
text-align: center;
padding: 0.25rem;
margin: 0.025rem;
width: 1.5rem;
height: 1.5rem;
cursor: pointer;

svg {
fill: $icon-color;
}
Expand Down Expand Up @@ -220,17 +222,18 @@ $badge-size: 0.85rem;

.experimentsTh {
height: auto;
background-color: $header-bg-color;
font-size: 0.7rem;
background-color: $header-bg-color;

&::before {
@extend %cellBorderLeft;

background-color: $header-border-color;
}

.cellContents {
@extend %truncateLeftChild;

display: block;

span[draggable='true'] {
Expand Down Expand Up @@ -297,9 +300,7 @@ $badge-size: 0.85rem;

.dropTargetHeaderCell {
background: $header-dnd-drop-background;
outline-width: 2px;
outline-style: dashed;
outline-color: $header-dnd-outline;
outline: $header-dnd-outline dashed 2px;
outline-offset: -4px;

.iconMenu ul[role='menu'] {
Expand Down Expand Up @@ -330,14 +331,15 @@ $badge-size: 0.85rem;
ul[role='menu'] {
background-color: $header-bg-color;
padding-left: 2px;
margin: 0px 0px 0px 4px;
margin: 0 0 0 4px;
border: none;

button {
width: 13px;
height: 11px;

svg {
fill: currentColor;
fill: currentcolor;
transform: scale(0.7);
}
}
Expand All @@ -355,6 +357,7 @@ $badge-size: 0.85rem;

.timestampHeader {
@extend %headerCellPadding;

overflow-x: hidden;
text-overflow: ellipsis;
text-align: left;
Expand All @@ -363,6 +366,7 @@ $badge-size: 0.85rem;

.experimentHeader {
@extend %headerCellPadding;

padding-left: $cell-padding;
text-align: left;
direction: ltr;
Expand All @@ -373,8 +377,10 @@ $badge-size: 0.85rem;
.headerCellText {
@extend %truncateLeftParent;
@extend %headerCellPadding;

direction: rtl;
opacity: 0.6;

// to prevent extra dragLeave and dragEnter fired
// should be on parent div, not span to work on text-overflow: ellipsis
pointer-events: none;
Expand Down Expand Up @@ -543,6 +549,7 @@ $badge-size: 0.85rem;

.innerCell {
@extend %baseInnerCell;

justify-content: flex-end;
}

Expand Down Expand Up @@ -596,6 +603,7 @@ $badge-size: 0.85rem;

.indicatorCount {
z-index: 2;

&[title='0'] {
display: none;
}
Expand Down Expand Up @@ -653,7 +661,7 @@ $badge-size: 0.85rem;

.normalExperiment & {
line-height: 0;
background: currentColor;
background: currentcolor;
border-radius: 100%;
}

Expand All @@ -671,8 +679,8 @@ $badge-size: 0.85rem;
vertical-align: middle;
border: 1.5px solid $checkbox-background;
border-radius: 100%;
border-right: 1.5px solid currentColor;
border-top: 1.5px solid currentColor;
border-right: 1.5px solid currentcolor;
border-top: 1.5px solid currentcolor;
animation: spin 1s cubic-bezier(0.53, 0.21, 0.29, 0.67) infinite;
background-color: $checkbox-background;
}
Expand Down Expand Up @@ -704,6 +712,7 @@ $badge-size: 0.85rem;

.expandedRowArrow {
@extend %expandableRowArrow;

transform: rotate(45deg);
right: 1px;
bottom: 2px;
Expand All @@ -715,6 +724,7 @@ $badge-size: 0.85rem;

.contractedRowArrow {
@extend %expandableRowArrow;

transform: rotate(-45deg);
right: 4px;
bottom: 0;
Expand All @@ -729,7 +739,8 @@ $badge-size: 0.85rem;
}

.experimentCellText {
@extend .cellContents;
@extend %cellContentsBase;

display: block;
line-height: normal;
direction: ltr;
Expand Down Expand Up @@ -804,18 +815,21 @@ $badge-size: 0.85rem;
.timestampInnerCell {
@extend %baseInnerCell;
@extend %truncateLeftParent;

line-height: normal;
text-align: left;
height: 32px;
}

.timestampDate {
@extend %truncateLeftChild;

font-size: 0.7em;
}

.timestampTime {
@extend %truncateLeftChild;

font-size: 0.9em;
}

Expand Down Expand Up @@ -858,6 +872,7 @@ $badge-size: 0.85rem;

.buttonAsLink {
@extend %link;

background: none;
border: none;
padding: 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@import '../../../shared/variables.scss';
@import '../../../shared/variables';

$gap: 4px;

.comparisonTableHeader {
position: relative;
z-index: 2;
Expand Down
4 changes: 2 additions & 2 deletions webview/src/plots/components/ribbon/RibbonBlockTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ export const RibbonBlockTooltip: React.FC<{
<ErrorTooltipContent error={errors.join('\n')} />
</div>
)}
<table className={styles.columnsTable}>
<table>
<tbody>
{firstThreeColumns.map(({ path, value, type }) => (
<tr key={path}>
<td className={cx(styles[`${type}Key`])}>
<td className={cx(styles.tooltipColumn, styles[`${type}Key`])}>
<span className={styles.tooltipPathWrapper}>{path}</span>
</td>
<td>
Expand Down
Loading