npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zohodesk/stylelint-plugin-standards

v0.0.3

Published

Stylelint plugin to enforce custom Zoho Desk CSS standards.

Downloads

96

Readme

@zohodesk/stylelint-plugin-standards

Stylelint plugin to enforce custom CSS standards for Zoho Desk projects.

Installation

npm install @zohodesk/stylelint-plugin-standards --save-dev

Usage

Add the plugin to your Stylelint configuration:

module.exports = {
  plugins: ["@zohodesk/stylelint-plugin-standards"],
  rules: {
    "@zohodesk/use-common-class": [
      "error",
      {
        commonFiles: [
          "node_modules/@dot-system/css-utility/es/utilities.plain.css"
        ],
        commonClassesFrom: "~@dot-system/css-utility/es/utilities.plain.css",
        isCssModules: true,
        match: "subset",
        propertyAliases: {
          "flex-grow": ["flex-positive", "box-flex"],
          "flex-basis": ["flex-preferred-size"],
          "align-items": ["flex-align", "box-align"],
          "justify-content": ["flex-pack", "box-pack"],
          "align-content": ["flex-line-pack"],
          "align-self": ["flex-item-align"],
          order: ["flex-order"]
        },
        valueAliases: {
          display: {
            flex: ["box", "flexbox"],
            "inline-flex": ["inline-flexbox"]
          },
          "align-items": {
            "flex-start": ["start"],
            "flex-end": ["end"]
          },
          "justify-content": {
            "flex-start": ["start"],
            "flex-end": ["end"],
            "space-between": ["justify"],
            "space-around": ["distribute"]
          }
        },
        excludeWhenPresent: {
          "flex-direction": ["box-orient", "box-direction"]
        }
      }
    ]
  }
};

Project structure

Each rule lives in its own folder so new rules can be added independently:

stylelint-plugin-standards/
├── index.js                       # registers every rule (array of plugins)
├── rules/
│   └── use-common-class/
│       ├── use-common-class.js     # rule implementation
│       └── utils/                  # helpers scoped to this rule
└── test/
    └── use-common-class.test.js

Adding a New Rule

  1. Create a new folder in rules/ (e.g. rules/my-new-rule/my-new-rule.js) along with any rule-specific helpers in rules/my-new-rule/utils/.
  2. Export the rule as a Stylelint plugin:
const stylelint = require("stylelint");

const ruleName = "@zohodesk/my-new-rule";
const messages = stylelint.utils.ruleMessages(ruleName, { /* ... */ });

const ruleFunction = (primary, secondary = {}) => (root, result) => {
  /* ... */
};

ruleFunction.ruleName = ruleName;
ruleFunction.messages = messages;

module.exports = stylelint.createPlugin(ruleName, ruleFunction);
  1. Register it in index.js:
const useCommonClass = require("./rules/use-common-class/use-common-class");
const myNewRule = require("./rules/my-new-rule/my-new-rule");

const plugins = [useCommonClass, myNewRule];

module.exports = plugins;

Rules

use-common-class

Scans CSS / CSS Module files and reports declaration blocks that duplicate a class already defined in a shared utilities file (for example utilities.plain.css). Instead of redeclaring the same properties, apply the existing common class directly in your JSX / HTML.

"@zohodesk/use-common-class": [
  "error",
  {
    commonFiles: [
      "node_modules/@dot-system/css-utility/es/utilities.plain.css"
    ],
    commonClassesFrom: "~@dot-system/css-utility/es/utilities.plain.css",
    isCssModules: true,
    match: "subset" // or "exact"
  }
]

Options

| Option | Required | Default | Description | | --- | --- | --- | --- | | commonFiles | Yes | — | Paths to shared utility CSS files used for comparison. | | commonClassesFrom | No | first commonFiles entry | Import path shown in the lint message. | | isCssModules | No | false | When true, only rules whose selectors are all plain single classes (.className) are checked. If any selector is complex (.a:hover, .a.b, .a::after, etc.), the whole block is skipped. | | match | No | "subset" | "subset" flags each utility whose declarations are contained in the rule. "exact" flags only rules that exactly match a utility block. | | propertyAliases | No | {} | Canonical property → old names (after vendor-prefix strip). Read from config; empty means prefix-strip only. | | valueAliases | No | {} | Canonical value → old names, grouped by property. Read from config; empty means prefix-strip only. | | excludeWhenPresent | No | {} | Canonical property → leftover old names to drop when that canonical property is present. Read from config; empty means nothing is dropped. |

@font-face and @keyframes blocks are ignored. You cannot apply / composes a common utility class inside those at-rules.

Vendor prefixes (-webkit-, -ms-, -moz-, -o-) are stripped automatically. Only names that do not become the modern property/value after that strip need an alias.

propertyAliases

Shape: { "<canonical-property>": ["<old-name>", ...] }

Omitted or {} → no property aliases (vendor prefixes are still stripped).

Example: -ms-flex-positive → strip prefix → flex-positive → flex-grow.

propertyAliases: {
  "flex-grow": ["flex-positive", "box-flex"],
  "flex-basis": ["flex-preferred-size"],
  "align-items": ["flex-align", "box-align"],
  "justify-content": ["flex-pack", "box-pack"],
  "align-content": ["flex-line-pack"],
  "align-self": ["flex-item-align"],
  order: ["flex-order"]
}

box-orient and box-direction are not 1:1 aliases (see excludeWhenPresent).

valueAliases

Shape: { "<property>": { "<canonical-value>": ["<old-value>", ...] } }

Omitted or {} → no value aliases (vendor prefixes are still stripped).

Example: display: -ms-flexbox → strip prefix → flexbox → flex.

valueAliases: {
  display: {
    flex: ["box", "flexbox"],
    "inline-flex": ["inline-flexbox"]
  },
  "align-items": {
    "flex-start": ["start"],
    "flex-end": ["end"]
  },
  "justify-content": {
    "flex-start": ["start"],
    "flex-end": ["end"],
    "space-between": ["justify"],
    "space-around": ["distribute"]
  }
}

Do not list values that prefix-strip already handles (-webkit-inline-flex → inline-flex).

excludeWhenPresent

Use this when old names are leftover keys, not 1:1 aliases: two (or more) old properties together mean one modern property. If the canonical property is present after normalize, the leftovers are dropped so subset matching does not require them.

Shape: { "<canonical-property>": ["<leftover-property>", ...] }

Omitted or {} → nothing is dropped.

Example: a common class with flex-direction, -webkit-box-orient, and -webkit-box-direction normalizes to { flex-direction } only. A user rule that declares only flex-direction still matches.

excludeWhenPresent: {
  "flex-direction": ["box-orient", "box-direction"]
}

Example

Before (flagged):

.container {
  box-sizing: border-box;
}

Suggested fix — drop the duplicate CSS and apply the common class directly in your markup:

<div className="d-box-border" />

Error message:

Instead of redeclaring box-sizing: border-box in ".container", apply the common class 'd-box-border' from '~@dot-system/css-utility/es/utilities.plain.css' directly in your JSX/HTML

When a rule mixes common and non-common declarations, only the ones matching a common class are flagged; the rest can stay in your CSS.