Skip to content
Merged
7 changes: 7 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
rules: {
'gamut/prefer-themed': 'error',
'gamut/no-css-standalone': 'error',
'gamut/no-inline-style': 'error',
'gamut/import-paths': 'error',
'import/no-extraneous-dependencies': 'off',
},
Expand Down Expand Up @@ -66,5 +67,11 @@ module.exports = {
'lodash/import-scope': ['error', 'method'],
},
},
{
files: ['packages/gamut-illustrations/**'],
rules: {
'gamut/no-inline-style': 'off',
},
},
],
};
1 change: 1 addition & 0 deletions packages/eslint-plugin-gamut/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module.exports = {
'gamut/prefer-themed': 'error',
'gamut/no-css-standalone': 'error',
'gamut/import-paths': 'error',
'gamut/no-inline-style': 'error',
},
};
```
2 changes: 2 additions & 0 deletions packages/eslint-plugin-gamut/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import gamutImportPaths from './gamut-import-paths';
import noCssStandalone from './no-css-standalone';
import noInlineStyle from './no-inline-style';
import preferThemed from './prefer-themed';
import recommended from './recommended';

const rules = {
'import-paths': gamutImportPaths,
'no-css-standalone': noCssStandalone,
'no-inline-style': noInlineStyle,
'prefer-themed': preferThemed,
};

Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-gamut/src/no-css-standalone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default createRule({
},
messages: {
noCssStandalone:
"Do not create anymore stylesheets, please see Gamut's Notion page for current best practices.",
"Do not create anymore stylesheets, please see Gamut's Storybook documentation for current best practices.",
},
type: 'suggestion',
schema: [],
Expand Down
72 changes: 72 additions & 0 deletions packages/eslint-plugin-gamut/src/no-inline-style.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { ESLintUtils } from '@typescript-eslint/utils';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

love love love these


import rule from './no-inline-style';

const ruleTester = new ESLintUtils.RuleTester({
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
});

ruleTester.run('no-inline-style', rule, {
valid: [
`<div />`,
`<div className="foo" />`,
`<Component className="bar" />`,
`<div styles={styles} />`,
`<Component styleSheet={sheet} />`,
`const style = { padding: 0 };`,
],
invalid: [
{
code: `<div style={{ padding: 0 }} />`,
errors: [
{
messageId: 'noInlineStyle',
},
],
},
{
code: `<Component style={{ margin: '10px' }} />`,
errors: [
{
messageId: 'noInlineStyle',
},
],
},
{
code: `<button style={styles.button} />`,
errors: [
{
messageId: 'noInlineStyle',
},
],
},
{
code: `<div className="foo" style={{ color: 'red' }} />`,
errors: [
{
messageId: 'noInlineStyle',
},
],
},
{
code: `
<Component
style={{
padding: 0,
margin: 0,
}}
/>
`,
errors: [
{
messageId: 'noInlineStyle',
},
],
},
],
});
30 changes: 30 additions & 0 deletions packages/eslint-plugin-gamut/src/no-inline-style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { createRule } from './createRule';

export default createRule({
create(context) {
return {
JSXAttribute(node) {
if (node.name.type === 'JSXIdentifier' && node.name.name === 'style') {
context.report({
messageId: 'noInlineStyle',
node,
});
}
},
};
},
defaultOptions: [],
meta: {
docs: {
description: 'Disallow inline style props on JSX elements.',
recommended: 'error',
},
messages: {
noInlineStyle:
'The use of inline styles is discouraged — consider using styled components, design system utilities, or CSS classes instead.',
},
type: 'suggestion',
schema: [],
},
name: 'no-inline-style',
});
1 change: 1 addition & 0 deletions packages/eslint-plugin-gamut/src/recommended.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export default {
rules: {
'gamut/no-css-standalone': 'error',
'gamut/no-inline-style': 'error',
'gamut/prefer-themed': 'off',
'gamut/gamut-import-paths': 'error',
},
Expand Down
1 change: 1 addition & 0 deletions packages/gamut/src/Animation/ExpandInCollapseOut.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const ExpandInCollapseOut: React.FC<WithChildrenProp> = ({
animate="expanded"
exit="collapsed"
initial="collapsed"
// eslint-disable-next-line gamut/no-inline-style
style={{ overflow: 'hidden' }}
transition={{ duration: timingValues.medium / 1000, ease: 'easeInOut' }}
variants={{
Expand Down
2 changes: 2 additions & 0 deletions packages/gamut/src/Animation/Rotation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const Rotation: React.FC<RotationProps> = ({
children,
...rest
}) => (
/* eslint-disable gamut/no-inline-style */
<motion.div
animate={rotated ? 'rotated' : 'normal'}
style={{
Expand All @@ -52,4 +53,5 @@ export const Rotation: React.FC<RotationProps> = ({
>
{children}
</motion.div>
/* eslint-enable gamut/no-inline-style */
);
1 change: 1 addition & 0 deletions packages/gamut/src/Card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const Card: React.FC<CardProps> = ({
left={shadow === 'patternLeft' ? '-0.5rem' : undefined}
position="absolute"
right={shadow === 'patternRight' ? '-0.5rem' : undefined}
// eslint-disable-next-line gamut/no-inline-style
style={{ borderRadius: 'inherit', color: 'currentcolor' }}
top=".5rem"
/>
Expand Down
1 change: 1 addition & 0 deletions packages/gamut/src/FocusTrap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export const FocusTrap: React.FC<FocusTrapProps> = ({
enabled={active}
noIsolation={allowPageInteraction}
scrollLock={!allowPageInteraction}
// eslint-disable-next-line gamut/no-inline-style
style={focusOnStyles}
onClickOutside={onClickOutside}
onEscapeKey={onEscapeKey}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export const RemoveAllButton = (props: SizedIndicatorProps) => {
tabIndex={0}
{...restInnerProps}
ref={removeAllButtonRef}
// eslint-disable-next-line gamut/no-inline-style
style={style}
onKeyDown={onKeyPress}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export const RemoveAllButton = (props: SizedIndicatorProps) => {
tabIndex={0}
{...restInnerProps}
ref={removeAllButtonRef}
// eslint-disable-next-line gamut/no-inline-style
style={style}
onKeyDown={onKeyPress}
>
Expand Down
1 change: 1 addition & 0 deletions packages/gamut/src/Popover/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ export const Popover: React.FC<PopoverProps> = ({
position={position}
{...(popoverContainerRef ? { ref: popoverContainerRef } : {})}
role={role}
// eslint-disable-next-line gamut/no-inline-style
style={getPopoverPosition()}
tabIndex={-1}
>
Expand Down
1 change: 1 addition & 0 deletions packages/gamut/src/Video/lib/VidstackPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export const VidstackPlayer: React.FC<VidstackPlayerProps> = ({
return (
<VariableProvider
className={className}
// eslint-disable-next-line gamut/no-inline-style
style={{ width, height }}
variables={vdsVariables}
>
Expand Down
9 changes: 8 additions & 1 deletion packages/styleguide/.storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ const preview: Preview = {
order: [
'Gamut',
'Meta',
['About', 'Best Practices', 'Contributing', 'FAQs', 'Stories'],
[
'About',
'Best Practices',
'ESLint rules',
'Contributing',
'FAQs',
'Stories',
],
'Foundations',
'Layouts',
'Typography',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,7 @@ export const SpacingTight: Story = {
render: () => (
<Box as="fieldset" m={0} p={0}>
<legend>Tight Spacing</legend>
<FlexBox
as="ul"
column
style={{ listStyle: 'none', margin: 0, padding: 0 }}
>
<FlexBox as="ul" column listStyle="none" m={0} p={0}>
{[
{ id: 'spacing-1', label: 'a small space', checked: true },
{ id: 'spacing-2', label: 'with three checkboxes', checked: false },
Expand All @@ -128,11 +124,7 @@ export const LabelsAsReactNodes: Story = {
render: () => (
<Box as="fieldset" m={0} p={0}>
<legend>Labels as React Nodes</legend>
<FlexBox
as="ul"
column
style={{ listStyle: 'none', margin: 0, padding: 0 }}
>
<FlexBox as="ul" column listStyle="none" m={0} p={0}>
<Box as="li" mt={4}>
<Checkbox
checked
Expand Down
2 changes: 2 additions & 0 deletions packages/styleguide/src/lib/Meta/About.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { parameters as bestPracticesParameters } from './Best Practices.mdx';
import { parameters as brandParameters } from './Brand.mdx';
import { parameters as contributingParameters } from './Contributing.mdx';
import { parameters as deepControlsParameters } from './Deep Controls Add-On.mdx';
import { parameters as eslintRulesParameters } from './ESLint rules.mdx';
import { parameters as faqsParameters } from './FAQs.mdx';
import { parameters as installationParameters } from './Installation.mdx';
import { parameters as storiesParameters } from './Stories.mdx';
Expand All @@ -31,6 +32,7 @@ export const parameters = {
bestPracticesParameters,
contributingParameters,
deepControlsParameters,
eslintRulesParameters,
faqsParameters,
storiesParameters,
brandParameters,
Expand Down
Loading
Loading