@griffel/postcss-syntax
v1.3.15
Published
postcss syntax for Griffel
Keywords
Readme
PostCSS syntax for Griffel
A PostCSS custom syntax that exposes the CSS generated by Griffel to CSS tooling, most notably stylelint.
Griffel compiles makeStyles() and makeResetStyles() calls to atomic CSS ahead of time, so that CSS
never exists as a .css file and a CSS linter has nothing to read. This package closes that gap: it
runs the Griffel transform over a JavaScript/TypeScript file and returns a PostCSS AST of the
generated CSS, with source locations that point back to the original JavaScript.
Install
yarn add --dev @griffel/postcss-syntax
# or
npm install --save-dev @griffel/postcss-syntax⚠️ This package is ESM only. If your project is CommonJS, use
stylelint.config.mjsrather than.stylelintrc.js, as the latter is loaded withrequire().
Usage with stylelint
Stylelint calls a PostCSS syntax a custom syntax.
Point customSyntax at this package:
{
"customSyntax": "@griffel/postcss-syntax",
"rules": {
"selector-anb-no-unmatchable": true
}
}Then lint your style files:
npx stylelint "src/**/*.styles.ts"For example, this file:
import { makeStyles } from '@griffel/react';
export const useStyles = makeStyles({
root: {
':nth-child(0)': { color: 'red' },
},
});...generates .fwey13v:nth-child(0){color:red;}, which makes stylelint report
selector-anb-no-unmatchable. The reported location points at the root slot in example.styles.ts,
not at the generated CSS.
Disabling rules
stylelint-disable comments cannot be placed in generated CSS, so use a griffel-csslint-disable
comment directive instead. For makeStyles() place it above a slot:
export const useStyles = makeStyles({
// griffel-csslint-disable selector-anb-no-unmatchable
root: {
':nth-child(0)': { color: 'red' },
},
});For makeResetStyles() place it above the declaration:
// griffel-csslint-disable selector-anb-no-unmatchable
export const useResetStyles = makeResetStyles({
':nth-child(0)': { color: 'red' },
});A directive must be a line comment (//) and disables exactly one rule. To disable several rules, use
several comments:
export const useStyles = makeStyles({
// griffel-csslint-disable selector-anb-no-unmatchable
// griffel-csslint-disable declaration-property-value-no-unknown
root: {/* ... */},
});Linting custom wrappers
By default only makeStyles()/makeResetStyles() imported from @griffel/core, @griffel/react or
@fluentui/react-components are processed. If your project re-exports them from its own package, use
createSyntax() to build a configured syntax:
import { createSyntax } from '@griffel/postcss-syntax';
export default {
customSyntax: createSyntax({
importsToTransform: ['@griffel/react', '@myScope/griffel'],
}),
rules: {
'selector-anb-no-unmatchable': true,
},
};createSyntax() accepts:
| Option | Type | Default | Description |
| ---------------------- | ---------- | ------------------------------------------------------------------- | ------------------------------------------------------------- |
| importsToTransform | string[] | ['@griffel/core', '@griffel/react', '@fluentui/react-components'] | Modules whose Griffel imports should be processed. |
| functionsToTransform | string[] | ['makeStyles', 'makeResetStyles', 'makeStaticStyles'] | Function names that should be treated as Griffel style calls. |
⚠️ Both options replace their defaults rather than extend them. Keep
@griffel/reactin the list if you also import from it directly.
API
parse(css, options?)— parses a JavaScript/TypeScript source and returns a PostCSS AST of the generated CSS. Supportsfrom,silenceParseErrors,importsToTransformandfunctionsToTransform.stringify(node, builder)— the matching stringifier.createSyntax(options)— returns a{ parse, stringify }syntax configured with the options above.
When a file cannot be parsed, parse() emits a /* Failed to parse griffel styles: <file> */ comment
and logs the error. Pass silenceParseErrors: true to suppress the log.
Limitations
- Only
makeStyles()andmakeResetStyles()produce CSS, and both must be statically evaluable, see limitations of the build time transform. - The stringifier only works on an AST produced by this syntax, as Griffel's ahead of time compilation
cannot map generated CSS back to the original JavaScript accurately enough for arbitrary input. For
the same reason stylelint's
--fixis not supported.
