Stylelint Polaris

A configuration of Stylelint rules that promote adoption of the Polaris design system in consuming apps.

npm version

Demo of Stylelint Polaris

Installation

Example
yarn add -D @shopify/stylelint-polaris stylelint

Note: stylelint-polaris requires a peer dependency of stylelint@>=14.15.0

Source code

Usage

Extend @shopify/stylelint-polaris in your Stylelint config. Example in package.json

Example
{
  "stylelint": {
    "extends": ["@shopify/stylelint-polaris"]
  }
}

IMPORTANT: @shopify/stylelint-polaris must be added to the end of the extends array

Run the linter

Example
npx stylelint '**/*.{css,scss}'

Run the linter and autofix failures

Example
npx stylelint --fix '**/*.{css,scss}'

Ignoring existing failures

Enabling the linter could result in a large amount of warnings and errors in existing codebases. It is important to fix as many failures upfront as possible, but that shouldn't block the linter from being added. The styles-insert-stylelint-disable migration inserts ignore comments so that enabling stylelint-polaris can be unblocked.

The migration will insert comments as follows:

Example
+ // stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY
padding: 1rem;

Run the following command substituting <path> with a glob pattern of files to run against:

Example
npx @shopify/polaris-migrator styles-insert-stylelint-disable <path>

Rules

There are over 40 rules configured in Stylelint Polaris to help you avoid errors and follow stylistic and non-stylistic conventions while building for the Shopify admin. These rules help us measure the Polaris design system's coverage in the Shopify admin code base using the following categories:

Development

Add new rules

  1. Navigate to the root stylelint-polaris config
  2. Locate the stylelint-polaris/coverage options
  3. Identify the appropriate category for the new rule
  4. Insert the rule using standard Stylelint rule configurations
  5. Add documentation for the rule with examples of code that will be reported as a problem and code that will fix the problem
  6. The title should be the category + the stylelint rule name, for example ### colors/color-named
Example
module.exports = {
  rules: {
    'polaris/coverage': {
      colors: {...}, // Standard Stylelint rules config
      layout: {...}, // Standard Stylelint rules config
      motion: {
        'new-rule': 'new-rule-options',
      },
    },
  },
};

Build custom rules

  1. Refer to the Writing plugins guide of the Stylelint documentation
  2. Create your rule in the plugins directory
  3. Validate your plugin with tests (reference sibling plugins for examples)
  4. Refer to the Add new rules section to add your custom rule to the stylelint-polaris config

Add custom messages

Custom messages are surfaced in the command line, CI, and supported editors along side the default stylelint rule messages. They are added to the root level config and aim to provide more insight on how to resolve rule violations.

In a majority of cases, the default rule messages are clear and concise. However, they don't always guide developers to a desired outcome. Thus, there are two mechanisms we suggest for improving and providing custom rule messages:

Set a generic custom message on the message property of the secondary options of a given stylelint-polaris/coverage category. This message is appended to the default rule message and we expect will cover most cases.

Example
module.exports = {
  rules: {
    'polaris/coverage': {
      colors: [
        {
          'color-named': 'never'
          'color-no-hex': true,
        },
        {message: 'Please use a Polaris color token: https://polaris.shopify.com/tokens/colors'},
      ],
    },
  },
}

Example failure message:

Example
- Unexpected named color "red" (color-named)
+ Unexpected named color "red" (color-named) Please use a Polaris color token

Set a custom message on the message property in the Stylelint rule config's secondary options if supported. This message is appended to the default rule message instead of the generic category message when provided.

Example
module.exports = {
  rules: {
    'polaris/coverage': {
      layout: [
        {
          'property-disallowed-list': [
            ['position'],
            {message: 'Please use the Polaris "Sticky" component'},
          ],
        },
        {message: 'Please use a Polaris layout component'},
      ],
    },
  },
};

Example failure message:

Example
- Unexpected value "sticky" for property "position" (declaration-property-value-disallowed-list) Please use a Polaris layout component
+ Unexpected value "sticky" for property "position" (declaration-property-value-disallowed-list) Please use the Polaris "Sticky" component

Test stylelint-polaris updates in polaris-react

Open your terminal to the root of the polaris monorepo:

  1. Install and symlink dependencies
Example
yarn install
  1. Build @shopify/polaris dependencies, but not @shopify/polaris itself
Example
yarn build -- --filter=@shopify/polaris^...

Note: Remove the ^ character if you do want to build @shopify/polaris

  1. Run stylelint in polaris-react

All files

Example
yarn turbo run lint:styles --filter=@shopify/polaris

Specific file

Example
yarn run stylelint path/to/component.scss

// yarn run stylelint polaris-react/src/components/TopBar/TopBar.scss