-
Notifications
You must be signed in to change notification settings - Fork 60
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
feat: Implement griffel stylelint config #437
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "patch", | ||
"comment": "fix: entrypoint and preset config fixes", | ||
"packageName": "@griffel/postcss-syntax", | ||
"email": "lingfan.gao@microsoft.com", | ||
"dependentChangeType": "patch" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "major", | ||
"comment": "Initial release", | ||
"packageName": "@griffel/stylelint-config", | ||
"email": "lingfan.gao@microsoft.com", | ||
"dependentChangeType": "patch" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,6 @@ import { GRIFFEL_SRC_RAW } from './constants'; | |
export const stringify: postcss.Stringifier = root => { | ||
const originalSource = root.raw(GRIFFEL_SRC_RAW); | ||
if (originalSource) { | ||
console.log(originalSource); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oopsie |
||
return originalSource; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"presets": [["@nrwl/web/babel", { "useBuiltIns": "usage" }]] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"extends": ["../../.eslintrc.json"], | ||
"ignorePatterns": ["!**/*"], | ||
"overrides": [ | ||
{ | ||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.ts", "*.tsx"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.js", "*.jsx"], | ||
"rules": {} | ||
} | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Standard Stylelint config for Griffel | ||
|
||
This is a a standard [stylelint](https://stylelint.io/) that can be used to lint Griffel CSS in JS. | ||
It uses the [Griffel postcss syntax](https://github.com/microsoft/griffel/tree/main/packages/postcss-syntax) as | ||
a base config for any stylelint integration. | ||
|
||
## Usage | ||
|
||
Simply extend this configuration in your stylelint config | ||
|
||
```json | ||
{ | ||
"extends": "@griffe/stylelint-config", | ||
"rules": { | ||
"alpha-value-notation": "number" | ||
} | ||
} | ||
``` | ||
|
||
## Different module source or imports | ||
|
||
If you are using a different module source or import name like the below example: | ||
|
||
```ts | ||
import { foo /* makeStyles */ } from '@foo/foo'; /* @griffel/react */ | ||
|
||
export const useStyles = foo({ | ||
root: { | ||
color: 'red', | ||
}, | ||
}); | ||
``` | ||
|
||
There is no way to customize postcss custom syntaxes, so the only way to make linting these CSS in JS files | ||
possible is to create the griffel postcss custom syntax from a factory that can be configured. For this to work | ||
you'll need to use a javascript stylelint config `.stylelintrc.js` | ||
|
||
```js | ||
module.exports { | ||
customSyntax: require('@griffel/postcss-syntax').createSyntax({ modules: [{ moduleSource: '@foo/foo', importName: 'foo' }] }), | ||
rules: { | ||
"alpha-value-notation": "number" | ||
} | ||
} | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* eslint-disable */ | ||
export default { | ||
displayName: 'eslint-plugin', | ||
preset: '../../jest.preset.js', | ||
globals: { | ||
'ts-jest': { | ||
tsconfig: '<rootDir>/tsconfig.spec.json', | ||
}, | ||
}, | ||
testEnvironment: 'node', | ||
transform: { | ||
'^.+\\.[tj]sx?$': 'ts-jest', | ||
}, | ||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'], | ||
coverageDirectory: '../../coverage/packages/eslint-plugin', | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"name": "@griffel/stylelint-config", | ||
"version": "0.0.0", | ||
"description": "A default stylelint config for Griffel", | ||
"license": "MIT", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/microsoft/griffel" | ||
}, | ||
"dependencies": { | ||
"@griffel/postcss-syntax": "^1.0.0" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
{ | ||
"name": "@griffel/stylelint-config", | ||
"$schema": "../../node_modules/nx/schemas/project-schema.json", | ||
"sourceRoot": "packages/stylelint-config/src", | ||
"projectType": "library", | ||
"targets": { | ||
"lint": { | ||
"executor": "@nrwl/linter:eslint", | ||
"outputs": ["{options.outputFile}"], | ||
"options": { | ||
"lintFilePatterns": ["packages/stylelint-config/**/*.ts"] | ||
} | ||
}, | ||
"test": { | ||
"executor": "@nrwl/jest:jest", | ||
"outputs": ["{workspaceRoot}/coverage/packages/stylelint-config"], | ||
"options": { | ||
"jestConfig": "packages/stylelint-config/jest.config.ts", | ||
"passWithNoTests": true | ||
} | ||
}, | ||
"build": { | ||
"executor": "@nrwl/js:tsc", | ||
"outputs": ["{options.outputPath}"], | ||
"options": { | ||
"outputPath": "dist/packages/stylelint-config", | ||
"tsConfig": "packages/stylelint-config/tsconfig.lib.json", | ||
"packageJson": "packages/stylelint-config/package.json", | ||
"main": "packages/stylelint-config/src/index.ts", | ||
"updateBuildableProjectDepsInPackageJson": false, | ||
"assets": [ | ||
"packages/stylelint-config/README.md", | ||
{ | ||
"glob": "LICENSE.md", | ||
"input": ".", | ||
"output": "." | ||
} | ||
] | ||
} | ||
}, | ||
"type-check": { | ||
"executor": "nx:run-commands", | ||
"options": { | ||
"cwd": "packages/babel-preset", | ||
"commands": [ | ||
{ | ||
"command": "tsc -b --pretty" | ||
} | ||
], | ||
"outputPath": [] | ||
} | ||
} | ||
}, | ||
"tags": [] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import griffelSyntax from '@griffel/postcss-syntax'; | ||
|
||
export default { | ||
customSyntax: griffelSyntax, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import * as stylelint from 'stylelint'; | ||
import griffelStylelintConfig from './index'; | ||
import { createSyntax } from '@griffel/postcss-syntax'; | ||
|
||
describe('stylelint', () => { | ||
it('should lint makeStyles with standard config', async () => { | ||
expect.assertions(1); | ||
const config = { | ||
...griffelStylelintConfig, | ||
rules: { | ||
'selector-anb-no-unmatchable': [true], | ||
}, | ||
}; | ||
|
||
const code = ` | ||
import { makeStyles } from '@griffel/react'; | ||
|
||
const useStyles = makeStyles({ | ||
root: { | ||
':nth-child(0)': { | ||
color: 'red', | ||
} | ||
} | ||
}) | ||
`; | ||
|
||
const { results } = await stylelint.lint({ code, config }); | ||
const warnings = results.map(result => result.warnings).flat(); | ||
expect(warnings).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"column": 11, | ||
"endColumn": 24, | ||
"endLine": 5, | ||
"line": 5, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The starting line is always correct, however the rest of the locations are wrong because most of the stylelint default rules calculate additional offsets internally for better reporting when linting real CSS files. This doesn't work too well with the griffel postcss syntax since we lose the mapping to the entire style slot. Example: That rule even uses a third party parser for the selector and doesn't really use postcss at all |
||
"rule": "selector-anb-no-unmatchable", | ||
"severity": "error", | ||
"text": "Unexpected unmatchable An+B selector \\":nth-child\\" (selector-anb-no-unmatchable)", | ||
}, | ||
] | ||
`); | ||
}); | ||
|
||
it('should lint makeStyles with different module source', async () => { | ||
expect.assertions(1); | ||
const config = { | ||
customSyntax: createSyntax({ modules: [{ moduleSource: '@foo/foo', importName: 'foo' }] }), | ||
rules: { | ||
'selector-anb-no-unmatchable': [true], | ||
}, | ||
}; | ||
|
||
const code = ` | ||
import { foo } from '@foo/foo'; | ||
|
||
const useStyles = foo({ | ||
root: { | ||
':nth-child(0)': { | ||
color: 'red', | ||
} | ||
} | ||
}) | ||
`; | ||
|
||
const { results } = await stylelint.lint({ code, config }); | ||
const warnings = results.map(result => result.warnings).flat(); | ||
expect(warnings).toMatchInlineSnapshot(` | ||
Array [ | ||
Object { | ||
"column": 11, | ||
"endColumn": 24, | ||
"endLine": 5, | ||
"line": 5, | ||
"rule": "selector-anb-no-unmatchable", | ||
"severity": "error", | ||
"text": "Unexpected unmatchable An+B selector \\":nth-child\\" (selector-anb-no-unmatchable)", | ||
}, | ||
] | ||
`); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"extends": "../../tsconfig.base.json", | ||
"compilerOptions": { | ||
"allowJs": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"strict": true, | ||
"noImplicitOverride": true, | ||
"noPropertyAccessFromIndexSignature": true, | ||
"noImplicitReturns": true, | ||
"noFallthroughCasesInSwitch": true | ||
}, | ||
"files": [], | ||
"include": [], | ||
"references": [ | ||
{ | ||
"path": "./tsconfig.lib.json" | ||
}, | ||
{ | ||
"path": "./tsconfig.spec.json" | ||
} | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"extends": "./tsconfig.json", | ||
"compilerOptions": { | ||
"module": "commonjs", | ||
"outDir": "../../dist/out-tsc", | ||
"declaration": true, | ||
"types": ["node", "environment"] | ||
}, | ||
"exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"], | ||
"include": ["**/*.ts"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"extends": "./tsconfig.json", | ||
"compilerOptions": { | ||
"outDir": "../../dist/out-tsc", | ||
"module": "commonjs", | ||
"types": ["jest", "node", "environment"] | ||
}, | ||
"include": [ | ||
"**/*.test.ts", | ||
"**/*.spec.ts", | ||
"**/*.test.tsx", | ||
"**/*.spec.tsx", | ||
"**/*.test.js", | ||
"**/*.spec.js", | ||
"**/*.test.jsx", | ||
"**/*.spec.jsx", | ||
"**/*.d.ts", | ||
"jest.config.ts" | ||
] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
postcss passes some untyped properties here - it will fail the griffel config validator, so I've put it all the preset configuration in a separate property