diff options
Diffstat (limited to '@linaria/packages/stylelint')
-rw-r--r-- | @linaria/packages/stylelint/CHANGELOG.md | 40 | ||||
-rw-r--r-- | @linaria/packages/stylelint/README.md | 35 | ||||
-rw-r--r-- | @linaria/packages/stylelint/babel.config.js | 3 | ||||
-rw-r--r-- | @linaria/packages/stylelint/package.json | 42 | ||||
-rw-r--r-- | @linaria/packages/stylelint/src/index.ts | 12 | ||||
-rw-r--r-- | @linaria/packages/stylelint/src/preprocessor.ts | 185 | ||||
-rw-r--r-- | @linaria/packages/stylelint/tsconfig.json | 5 |
7 files changed, 322 insertions, 0 deletions
diff --git a/@linaria/packages/stylelint/CHANGELOG.md b/@linaria/packages/stylelint/CHANGELOG.md new file mode 100644 index 0000000..6be3171 --- /dev/null +++ b/@linaria/packages/stylelint/CHANGELOG.md @@ -0,0 +1,40 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [3.0.0-beta.7](https://github.com/callstack/linaria/compare/v3.0.0-beta.6...v3.0.0-beta.7) (2021-06-24) + +**Note:** Version bump only for package @linaria/stylelint + + + + + +# [3.0.0-beta.5](https://github.com/callstack/linaria/compare/v3.0.0-beta.4...v3.0.0-beta.5) (2021-05-31) + +**Note:** Version bump only for package @linaria/stylelint + + + + + +# [3.0.0-beta.4](https://github.com/callstack/linaria/compare/v3.0.0-beta.3...v3.0.0-beta.4) (2021-05-07) + +**Note:** Version bump only for package @linaria/stylelint + + + + + +# [3.0.0-beta.3](https://github.com/callstack/linaria/compare/v3.0.0-beta.2...v3.0.0-beta.3) (2021-04-20) + +**Note:** Version bump only for package @linaria/stylelint + + + + + +# [3.0.0-beta.2](https://github.com/callstack/linaria/compare/v3.0.0-beta.1...v3.0.0-beta.2) (2021-04-11) + +**Note:** Version bump only for package @linaria/stylelint diff --git a/@linaria/packages/stylelint/README.md b/@linaria/packages/stylelint/README.md new file mode 100644 index 0000000..0d75b37 --- /dev/null +++ b/@linaria/packages/stylelint/README.md @@ -0,0 +1,35 @@ +<p align="center"> + <img alt="Linaria" src="https://raw.githubusercontent.com/callstack/linaria/HEAD/website/assets/linaria-logo@2x.png" width="496"> +</p> + +<p align="center"> +Zero-runtime CSS in JS library. +</p> + +--- + +### 📖 Please refer to the [GitHub](https://github.com/callstack/linaria#readme) for full documentation. + +## Features + +- Write CSS in JS, but with **zero runtime**, CSS is extracted to CSS files during build +- Familiar **CSS syntax** with Sass like nesting +- Use **dynamic prop based styles** with the React bindings, uses CSS variables behind the scenes +- Easily find where the style was defined with **CSS sourcemaps** +- **Lint your CSS** in JS with [stylelint](https://github.com/stylelint/stylelint) +- Use **JavaScript for logic**, no CSS preprocessor needed +- Optionally use any **CSS preprocessor** such as Sass or PostCSS + +**[Why use Linaria](../../docs/BENEFITS.md)** + +## Installation + +```sh +npm install @linaria/core @linaria/react @linaria/babel-preset @linaria/shaker +``` + +or + +```sh +yarn add @linaria/core @linaria/react @linaria/babel-preset @linaria/shaker +``` diff --git a/@linaria/packages/stylelint/babel.config.js b/@linaria/packages/stylelint/babel.config.js new file mode 100644 index 0000000..c9ad680 --- /dev/null +++ b/@linaria/packages/stylelint/babel.config.js @@ -0,0 +1,3 @@ +const config = require('../../babel.config'); + +module.exports = config; diff --git a/@linaria/packages/stylelint/package.json b/@linaria/packages/stylelint/package.json new file mode 100644 index 0000000..1ab8aae --- /dev/null +++ b/@linaria/packages/stylelint/package.json @@ -0,0 +1,42 @@ +{ + "name": "@linaria/stylelint", + "version": "3.0.0-beta.7", + "publishConfig": { + "access": "public" + }, + "description": "Blazing fast zero-runtime CSS in JS library", + "main": "lib/index.js", + "module": "esm/index.js", + "types": "types", + "files": [ + "types/", + "lib/", + "esm/" + ], + "license": "MIT", + "repository": "git@github.com:callstack/linaria.git", + "bugs": { + "url": "https://github.com/callstack/linaria/issues" + }, + "homepage": "https://github.com/callstack/linaria#readme", + "keywords": [ + "react", + "linaria", + "css", + "css-in-js", + "styled-components" + ], + "scripts": { + "build:lib": "cross-env NODE_ENV=legacy babel src --out-dir lib --extensions '.js,.jsx,.ts,.tsx' --source-maps --delete-dir-on-start", + "build:esm": "babel src --out-dir esm --extensions '.js,.jsx,.ts,.tsx' --source-maps --delete-dir-on-start", + "build": "yarn build:lib && yarn build:esm", + "build:declarations": "tsc --emitDeclarationOnly --outDir types", + "prepare": "yarn build && yarn build:declarations", + "typecheck": "tsc --noEmit --composite false", + "watch": "yarn build --watch" + }, + "dependencies": { + "@linaria/babel-preset": "^3.0.0-beta.7", + "strip-ansi": "^5.2.0" + } +} diff --git a/@linaria/packages/stylelint/src/index.ts b/@linaria/packages/stylelint/src/index.ts new file mode 100644 index 0000000..1794dcb --- /dev/null +++ b/@linaria/packages/stylelint/src/index.ts @@ -0,0 +1,12 @@ +export default { + processors: [require.resolve('./preprocessor')], + syntax: 'scss', + rules: { + 'property-no-vendor-prefix': true, + 'string-no-newline': true, + 'value-no-vendor-prefix': true, + 'no-empty-source': null, + 'no-extra-semicolons': null, + 'no-missing-end-of-source-newline': null, + }, +}; diff --git a/@linaria/packages/stylelint/src/preprocessor.ts b/@linaria/packages/stylelint/src/preprocessor.ts new file mode 100644 index 0000000..9e9945c --- /dev/null +++ b/@linaria/packages/stylelint/src/preprocessor.ts @@ -0,0 +1,185 @@ +import stripAnsi from 'strip-ansi'; +import { transform } from '@linaria/babel-preset'; +import type { Replacement } from '@linaria/babel-preset'; + +type Errors = { + [key: string]: + | { + name?: string; + code?: string; + message: string; + pos?: number; + loc?: { + line: number; + column: number; + }; + } + | null + | undefined; +}; + +type Cache = { + [key: string]: Replacement[] | null | undefined; +}; + +type Warning = { + rule?: string; + text: string; + severity: 'error' | 'warning'; + line: number; + column: number; +}; + +type LintResult = { + errored: boolean; + warnings: Warning[]; +}; + +function preprocessor() { + const errors: Errors = {}; + const cache: Cache = {}; + + return { + code(input: string, filename: string) { + let result; + + try { + result = transform(input, { + filename, + }); + + cache[filename] = undefined; + errors[filename] = undefined; + } catch (e) { + cache[filename] = undefined; + errors[filename] = e; + + // Ignore parse errors here + // We handle it separately + return ''; + } + + const { rules, replacements } = result; + + if (!rules) { + return ''; + } + + // Construct a CSS-ish file from the unprocessed style rules + let cssText = ''; + + Object.keys(rules).forEach((selector) => { + const rule = rules[selector]; + + // Append new lines until we get to the start line number + let line = cssText.split('\n').length; + + while (rule.start && line < rule.start.line) { + cssText += '\n'; + line++; + } + + cssText += `.${rule.displayName} {`; + + // Append blank spaces until we get to the start column number + const last = cssText.split('\n').pop(); + + let column = last ? last.length : 0; + + while (rule.start && column < rule.start.column) { + cssText += ' '; + column++; + } + + cssText += `${rule.cssText} }`; + }); + + cache[filename] = replacements; + + return cssText; + }, + result(result: LintResult, filename: string) { + const error = errors[filename]; + const replacements = cache[filename]; + + if (error) { + // Babel adds this to the error message + const prefix = `${filename}: `; + + let message = stripAnsi( + error.message.startsWith(prefix) + ? error.message.replace(prefix, '') + : error.message + ); + + let { loc } = error; + + if (!loc) { + // If the error doesn't have location info, try to find it from the code frame + const line = message.split('\n').find((l) => l.startsWith('>')); + const column = message.split('\n').find((l) => l.includes('^')); + + if (line && column) { + loc = { + line: Number(line.replace(/^> /, '').split('|')[0].trim()), + column: column.replace(/[^|]+\|\s/, '').length, + }; + } + } + + if (loc) { + // Strip the codeframe text if we have location of the error + // It's formatted badly by stylelint, so not very helpful + message = message.replace(/^>?\s+\d?\s\|.*$/gm, '').trim(); + } + + // eslint-disable-next-line no-param-reassign + result.errored = true; + result.warnings.push({ + rule: error.code || error.name, + text: message, + line: loc ? loc.line : 0, + column: loc ? loc.column : 0, + severity: 'error', + }); + } + + if (replacements) { + replacements.forEach(({ original, length }) => { + // If the warnings contain stuff that's been replaced, + // Correct the line and column numbers to what's replaced + result.warnings.forEach((w) => { + /* eslint-disable no-param-reassign */ + + if (w.line === original.start.line) { + // If the error is on the same line where an interpolation started, we need to adjust the line and column numbers + // Because a replacement would have increased or decreased the column numbers + // If it's in the same line where interpolation ended, it would have been adjusted during replacement + if (w.column > original.start.column + length) { + // The error is from an item after the replacements + // So we need to adjust the column + w.column += + original.end.column - original.start.column + 1 - length; + } else if ( + w.column >= original.start.column && + w.column < original.start.column + length + ) { + // The linter will underline the whole word in the editor if column is in inside a word + // Set the column to the end, so it will underline the word inside the interpolation + // e.g. in `${colors.primary}`, `primary` will be underlined + w.column = + original.start.line === original.end.line + ? original.end.column - 1 + : original.start.column; + } + } + }); + }); + } + + return result; + }, + }; +} + +module.exports = preprocessor; diff --git a/@linaria/packages/stylelint/tsconfig.json b/@linaria/packages/stylelint/tsconfig.json new file mode 100644 index 0000000..38139ee --- /dev/null +++ b/@linaria/packages/stylelint/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { "paths": {}, "rootDir": "src/" }, + "references": [{ "path": "../babel" }] +} |