6.2.1 • Published 1 year ago

@haltcase/style v6.2.1

Weekly downloads
-
License
MPL-2.0
Repository
github
Last release
1 year ago

@haltcase/style · npm version license @haltcase/style

Style guide and configurations for tools in the web ecosystem.

This package originated from Vercel's style guide.

installation

Install @haltcase/style with your preferred package manager:

# npm
npm i --save-dev @haltcase/style

# pnpm
pnpm i --save-dev @haltcase/style

# yarn
yarn add --dev @haltcase/style

!NOTE Some scenarios require additional peer dependencies. See the Prettier and ESLint sections.

usage

Prettier

!NOTE Prettier is a peer dependency you'll need to install at the root of your project.

See: https://prettier.io/docs/en/install.html

Add the following in package.json:

{
	"prettier": "@haltcase/style/prettier"
}

ESLint

!NOTE ESLint is a peer dependency you'll need to install at the root of your project.

See: https://eslint.org/docs/user-guide/getting-started#installation-and-usage

Several ESLint configs are available which can be combined.

Start with at least one of these base configs, which should always be first in extends:

  • @haltcase/style/eslint/browser
  • @haltcase/style/eslint/node

!TIP You can scope configs so they only target specific files.

See: Scoped configuration with overrides.

The following additional configs are available:

  • @haltcase/style/eslint/astro (requires eslint-plugin-astro to be installed)
  • @haltcase/style/eslint/cjs
  • @haltcase/style/eslint/jest
  • @haltcase/style/eslint/next (requires @next/eslint-plugin-next to be installed at the same version as next)
  • @haltcase/style/eslint/playwright-test
  • @haltcase/style/eslint/react
  • @haltcase/style/eslint/typescript (requires typescript to be installed and additional configuration)

Be sure to use require.resolve to reference these configs ESLint requires absolute paths (eslint/eslint#9188).

For example, to use the shared ESLint config(s) in a Next.js project, set the following in .eslintrc.js.

module.exports = {
	extends: [
		require.resolve("@haltcase/style/eslint/browser"),
		require.resolve("@haltcase/style/eslint/react"),
		require.resolve("@haltcase/style/eslint/next")
	]
};

Configuring ESLint for TypeScript

Some of the rules enabled in the TypeScript config require additional type information, so you'll need to use project: true and tsconfigRootDir or explicitly supply the path(s) to your tsconfig.json per the typescript-eslint documentation.

For more information, see: https://typescript-eslint.io/linting/typed-linting/

module.exports = {
	root: true,
	extends: [
		require.resolve("@haltcase/style/eslint/node"),
		require.resolve("@haltcase/style/eslint/typescript")
	],
	parserOptions: {
		project: true,
		tsconfigRootDir: __dirname
	},
	settings: {
		"import/resolver": {
			typescript: {
				project
			}
		}
	}
};

Configuring custom components for jsx-a11y

It's common practice for React apps to have shared components like Button that wrap native elements. You can pass this information along to jsx-a11y via the components setting.

The below list is not exhaustive.

module.exports = {
	root: true,
	extends: [require.resolve("@haltcase/style/eslint/react")],
	settings: {
		"jsx-a11y": {
			components: {
				Article: "article",
				Button: "button",
				Image: "img",
				Input: "input",
				Link: "a",
				Video: "video"
			}
		}
	}
};

Scoped configuration with overrides

ESLint configs can be scoped to include/exclude specific paths. This ensures that rules don't "leak" into places where those rules don't apply.

In this example, Jest rules are only being applied to files matching Jest's default test match pattern.

module.exports = {
	extends: [require.resolve("@haltcase/style/eslint/node")],
	overrides: [
		{
			files: ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)"],
			extends: [require.resolve("@haltcase/style/eslint/jest")]
		}
	]
};
A note on file extensions

By default, all TypeScript rules are scoped to files ending with .ts and .tsx.

However, when using overrides, file extensions must be included or ESLint will only include .js files.

module.exports = {
	overrides: [
		{
			files: ["directory/**/*.[jt]s?(x)"],
			rules: {
				"my-rule": "off"
			}
		}
	]
};

TypeScript

Several Typescript configs are available to cover various scenarios:

NameDescription
@haltcase/style/typescript/baseBaseline config, intended to be extended from.
@haltcase/style/typescript/bundlerFor use in bundled projects, most commonly Vite + React.
@haltcase/style/typescript/nextFor use in Next.js projects.
@haltcase/style/typescript/nodeDefault Node config, currently targeting Node 20.
@haltcase/style/typescript/node18For projects targeting Node 18.
@haltcase/style/typescript/node20For projects targeting Node 20.
@haltcase/style/typescript/webFor use in web projects.

Typically, you'll only need to extend from one of these:

{
	"extends": "@haltcase/style/typescript/next"
}

You could also combine them with an extends array in Typescript 5+:

{
	"extends": [
		"@haltcase/style/typescript/node",
		"@haltcase/style/typescript/web"
	]
}

!TIP Run tsc --showConfig to see the result of the combined configs.

Stylelint

To format and check CSS with Stylelint, install the stylelint package and set your configuration to extend from @haltcase/style/stylelint.

!NOTE Stylelint is a peer dependency you'll need to install at the root of your project.

See: https://stylelint.io/user-guide/get-started

Add the following in package.json:

{
	"stylelint": {
		"extends": "@haltcase/style/stylelint"
	}
}

!TIP See the Stylelint documentation for other configuration options.

Stylelint configs

There are several configs you can extend from. The default config does not enforce a specific naming convention for classes, IDs, etc. This is intended to allow flexibility between conventional CSS, where kebab-case is standard, and CSS Modules or CSS-in-JS, where camelCase is more common.

There are alternate entry points if you would like to enforce a specific naming convention: standard for kebab case and modules for camel case.

NameDescription
@haltcase/style/stylelintDo not enforce a naming convention for identifiers.
@haltcase/style/stylelint/modulesEnforce camelCase identifiers.
@haltcase/style/stylelint/standardEnforce conventional kebab-case identifiers.

contributing

Please read our contributing guide before creating a pull request.

6.2.1

1 year ago

6.2.0

1 year ago

6.2.1-canary.1

1 year ago

6.2.0-canary.3

1 year ago

6.2.0-canary.1

1 year ago

6.2.0-canary.2

1 year ago

6.1.0

2 years ago

6.1.0-canary.1

2 years ago

6.0.0

2 years ago

5.1.0-canary.1

2 years ago

6.0.0-canary.1

2 years ago

6.0.0-canary.2

2 years ago

4.1.0-canary.1

2 years ago

5.0.0

2 years ago

3.0.0-canary.1

2 years ago

3.0.1

2 years ago

3.0.1-canary.1

2 years ago

4.1.1-canary.1

2 years ago

5.0.0-canary.1

2 years ago

3.0.0

2 years ago

4.0.0-canary.1

2 years ago

4.1.0

2 years ago

4.0.0

2 years ago

4.1.1

2 years ago

2.1.0

2 years ago

2.1.0-canary.1

2 years ago

2.0.2-canary.1

2 years ago

2.0.1

2 years ago

2.0.1-canary.1

2 years ago

2.0.0

2 years ago

2.0.0-canary.1

2 years ago

1.1.0

2 years ago

1.1.0-canary.1

2 years ago

1.0.0-canary.7

2 years ago

1.0.0-canary.6

2 years ago

1.0.0-canary.5

2 years ago

1.0.0-canary.4

2 years ago

1.0.0-canary.3

2 years ago

1.0.0-canary.2

2 years ago

1.0.0-canary.1

2 years ago

1.0.0

2 years ago