Skip to content
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

[eslint plugin] Update polaris-no-bare-stack-item and polaris-prefer-sectioned-prop #371

Merged
merged 5 commits into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/brave-masks-march.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/eslint-plugin': patch
---

Updated component URLs for polaris.shopify.com and updated `polaris-no-bare-stack-item` to use `LegacyStack` and `polaris-prefer-sectioned-prop` to use `LegacyCard`'
4 changes: 2 additions & 2 deletions packages/eslint-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ This plugin also provides the following tool-specific configurations, which can
```

- [react](lib/config/react.js): Use this for React projects.
- [polaris](lib/config/polaris.js): Use this for projects that use [Shopify’s React Polaris components](https://polaris.shopify.com/components/get-started).
- [polaris](lib/config/polaris.js): Use this for projects that use [Shopify’s React Polaris components](https://polaris.shopify.com/components).
- [prettier](lib/config/prettier.js): Use [prettier](https://github.com/prettier/prettier) for consistent formatting. Extending this Shopify's prettier config will [override](https://github.com/prettier/eslint-config-prettier/blob/master/index.js) the default Shopify eslint rules in favor of prettier formatting. Prettier must be installed within your project, as @shopify/eslint-plugin does not provide the dependency itself.
- [webpack](lib/config/webpack.js): Use this for projects built by [webpack](https://webpack.js.org/).

Expand Down Expand Up @@ -132,7 +132,7 @@ This plugin provides the following custom rules, which are included as appropria
- [jsx-prefer-fragment-wrappers](docs/rules/jsx-prefer-fragment-wrappers.md): Disallow useless wrapping elements in favour of fragment shorthand in JSX.
- [no-namespace-imports](docs/rules/no-namespace-imports.md): Prevent namespace import declarations.
- [no-useless-computed-properties](docs/rules/no-useless-computed-properties.md): Prevent the usage of unnecessary computed properties.
- [polaris-no-bare-stack-item](docs/rules/polaris-no-bare-stack-item.md): Disallow the use of Polaris’s `Stack.Item` without any custom props.
- [polaris-no-bare-stack-item](docs/rules/polaris-no-bare-stack-item.md): Disallow the use of Polaris’s `LegacyStack.Item` without any custom props.
- [polaris-prefer-sectioned-prop](docs/rules/polaris-prefer-sectioned-prop.md): Prefer the use of the `sectioned` props in Polaris components instead of wrapping all contents in a `Section` component.
- [prefer-class-properties](docs/rules/prefer-class-properties.md): Prefer class properties to assignment of literals in constructors.
- [prefer-early-return](docs/rules/prefer-early-return.md): Prefer early returns over full-body conditional wrapping in function declarations.
Expand Down
20 changes: 10 additions & 10 deletions packages/eslint-plugin/docs/rules/polaris-no-bare-stack-item.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Disallow the use of Polaris’s `Stack.Item` without any custom props. (polaris-no-bare-stack-item)
# Disallow the use of Polaris’s `LegacyStack.Item` without any custom props. (polaris-no-bare-stack-item)

The Polaris [`Stack` component](https://polaris.shopify.com/components/structure/stack) has an `Item` subcomponent that is automatically wrapped around all children. As such, it is useless to wrap any content in a `Stack.Item` unless a non-default prop value is provided. This rule prevents creating such items.
The Polaris [`LegacyStack` component](https://polaris.shopify.com/components/layout-and-structure/legacy-stack) has an `Item` subcomponent that is automatically wrapped around all children. As such, it is useless to wrap any content in a `LegacyStack.Item` unless a non-default prop value is provided. This rule prevents creating such items.

Note that this rule will only work if the Stack component was explicitly imported using a named, default, or namespace import, and not when using dynamic imports (`import('@shopify/polaris')`).

Expand All @@ -10,20 +10,20 @@ The following patterns are considered warnings:

```js
import * as Polaris from '@shopify/polaris';
import {Stack} from '@shopify/polaris';
import {Stack as PolarisStack} from '@shopify/polaris';
import {LegacyStack} from '@shopify/polaris';
import {LegacyStack as PolarisLegacyStack} from '@shopify/polaris';

<Stack><Stack.Item>Content</Stack.Item></Stack>
<Polaris.Stack.Item>Content</Polaris.Stack.Item>
<PolarisStack.Item>Content</PolarisStack.Item>
<LegacyStack><LegacyStack.Item>Content</LegacyStack.Item></LegacyStack>
<Polaris.LegacyStack.Item>Content</Polaris.LegacyStack.Item>
<PolarisLegacyStack.Item>Content</PolarisLegacyStack.Item>
```

The following patterns are not warnings:

```js
import {Stack} from '@shopify/polaris';
import {LegacyStack} from '@shopify/polaris';

<Stack.Item fill><span>Content</span></Stack.Item>
<Stack><span>No wrapping item</span></Stack>
<LegacyStack.Item fill><span>Content</span></LegacyStack.Item>
<LegacyStack><span>No wrapping item</span></LegacyStack>
```

Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,32 @@ Polaris provides a convenience `sectioned` prop for some components that wraps t

This rule currently Require the use of the `sectioned` prop over the `Section` subcomponent for the following components:

* [`Card`](https://polaris.shopify.com/components/structure/card)
* [`LegacyCard`](https://polaris.shopify.com/components/layout-and-structure/legacy-card)
* [`Popover`](https://polaris.shopify.com/components/overlays/popover)
* [`Layout`](https://polaris.shopify.com/components/structure/layout)
* [`Layout`](https://polaris.shopify.com/components/layout-and-structure/layout)

This rule only takes effect when the `Section` subcomponent is the only top-level child of the components specified above, and when the `Section` component has no props.

The following patterns are considered warnings:

```js
import {Card, Popover, Layout} from '@shopify/polaris';
import {LegacyCard, Popover, Layout} from '@shopify/polaris';

<Card><Card.Section>Contents</Card.Section></Card>
<LegacyCard><LegacyCard.Section>Contents</LegacyCard.Section></LegacyCard>
<Popover><Popover.Section>Contents</Popover.Section></Popover>
<Layout><Layout.Section>Contents</Layout.Section></Layout>
```

The following patterns are not warnings:

```js
import {Card, Layout, Popover} from '@shopify/polaris';
import {LegacyCard, Layout, Popover} from '@shopify/polaris';

<Card sectioned>Contents</Card>
<LegacyCard sectioned>Contents</LegacyCard>

<Card>
<Card.Section subdued>Contents</Card.Section>
</Card>
<LegacyCard>
<LegacyCard.Section subdued>Contents</LegacyCard.Section>
</LegacyCard>

<Layout>
<Layout.AnnotatedSection></Layout.AnnotatedSection>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module.exports = {
meta: {
docs: {
description:
'Disallow the use of Polaris’s `Stack.Item` without any custom props.',
'Disallow the use of Polaris’s `LegacyStack.Item` without any custom props.',
category: 'Best Practices',
recommended: true,
uri: docsUrl('polaris-no-bare-stack-item'),
Expand All @@ -17,13 +17,13 @@ module.exports = {
JSXElement(node) {
const component = polarisComponentFromJSX(node, context);
if (
component === 'Stack.Item' &&
component === 'LegacyStack.Item' &&
node.openingElement.attributes.length === 0
) {
context.report({
node,
message:
'You don’t need to wrap content in a Stack.Item unless you need to customize one of its props.',
'You don’t need to wrap content in a LegacyStack.Item unless you need to customize one of its props.',
});
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const {polarisComponentFromJSX, docsUrl} = require('../utilities');

const COMPONENTS_WITH_SECTIONED_PROP = ['Popover', 'Card', 'Layout'];
const COMPONENTS_WITH_SECTIONED_PROP = ['Popover', 'LegacyCard', 'Layout'];

module.exports = {
meta: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,40 @@ const errors = [
{
type: 'JSXElement',
message:
'You don’t need to wrap content in a Stack.Item unless you need to customize one of its props.',
'You don’t need to wrap content in a LegacyStack.Item unless you need to customize one of its props.',
},
];

ruleTester.run('polaris-no-bare-stack-item', rule, {
valid: [
{
code: `
import {Stack} from '@shopify/polaris';
<Stack>Content</Stack>;
import {LegacyStack} from '@shopify/polaris';
<LegacyStack>Content</LegacyStack>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
},
{
code: `
import {Stack} from '@shopify/polaris';
<Stack>Content<Stack.Item fill>More content</Stack.Item></Stack>;
import {LegacyStack} from '@shopify/polaris';
<LegacyStack>Content<LegacyStack.Item fill>More content</LegacyStack.Item></LegacyStack>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
},
{
code: `
import {Stack} from 'other-module';
<Stack><Stack.Item>Content</Stack.Item></Stack>;
import {LegacyStack} from 'other-module';
<LegacyStack><LegacyStack.Item>Content</LegacyStack.Item></LegacyStack>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
},
{
code: `
import {Stack} from '@shopify/polaris';
<Stack.Item fill>Content</Stack.Item>;
import {LegacyStack} from '@shopify/polaris';
<LegacyStack.Item fill>Content</LegacyStack.Item>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
Expand All @@ -56,17 +56,17 @@ ruleTester.run('polaris-no-bare-stack-item', rule, {
invalid: [
{
code: `
import {Stack} from '@shopify/polaris';
<Stack><Stack.Item>Content</Stack.Item></Stack>;
import {LegacyStack} from '@shopify/polaris';
<LegacyStack><LegacyStack.Item>Content</LegacyStack.Item></LegacyStack>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
errors,
},
{
code: `
import {Stack} from '@shopify/polaris';
<Stack.Item>Content</Stack.Item>;
import {LegacyStack} from '@shopify/polaris';
<LegacyStack.Item>Content</LegacyStack.Item>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
Expand All @@ -75,7 +75,7 @@ ruleTester.run('polaris-no-bare-stack-item', rule, {
{
code: `
import * as P from '@shopify/polaris';
<P.Stack.Item>Content</P.Stack.Item>;
<P.LegacyStack.Item>Content</P.LegacyStack.Item>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ ruleTester.run('polaris-prefer-sectioned-prop', rule, {
valid: [
{
code: `
import {Card} from '@shopify/other';
<Card><Card.Section /></Card>;
import {LegacyCard} from '@shopify/other';
<LegacyCard><LegacyCard.Section /></LegacyCard>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
Expand All @@ -39,48 +39,48 @@ ruleTester.run('polaris-prefer-sectioned-prop', rule, {
},
{
code: `
import {Card} from '@shopify/polaris';
<Card />;
import {LegacyCard} from '@shopify/polaris';
<LegacyCard />;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
},
{
code: `
import {Card} from '@shopify/polaris';
<Card>Content</Card>;
import {LegacyCard} from '@shopify/polaris';
<LegacyCard>Content</LegacyCard>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
},
{
code: `
import {Card} from '@shopify/polaris';
<Card><Card.Section subdued /></Card>;
import {LegacyCard} from '@shopify/polaris';
<LegacyCard><LegacyCard.Section subdued /></LegacyCard>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
},
{
code: `
import {Card} from '@shopify/polaris';
<Card><Card.Section {...props} /></Card>;
import {LegacyCard} from '@shopify/polaris';
<LegacyCard><LegacyCard.Section {...props} /></LegacyCard>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
},
{
code: `
import {Card} from '@shopify/polaris';
<Card><Card.Other /></Card>;
import {LegacyCard} from '@shopify/polaris';
<LegacyCard><LegacyCard.Other /></LegacyCard>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
},
{
code: `
import {Card} from '@shopify/polaris';
<Card><Card.Section /><Card.Section /></Card>;
import {LegacyCard} from '@shopify/polaris';
<LegacyCard><LegacyCard.Section /><LegacyCard.Section /></LegacyCard>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
Expand All @@ -97,12 +97,12 @@ ruleTester.run('polaris-prefer-sectioned-prop', rule, {
invalid: [
{
code: `
import {Card} from '@shopify/polaris';
<Card><Card.Section /></Card>;
import {LegacyCard} from '@shopify/polaris';
<LegacyCard><LegacyCard.Section /></LegacyCard>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
errors: errorsFor('Card'),
errors: errorsFor('LegacyCard'),
},
{
code: `
Expand All @@ -125,20 +125,20 @@ ruleTester.run('polaris-prefer-sectioned-prop', rule, {
{
code: `
import * as Polaris from '@shopify/polaris';
<Polaris.Card><Polaris.Card.Section /></Polaris.Card>;
<Polaris.LegacyCard><Polaris.LegacyCard.Section /></Polaris.LegacyCard>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
errors: errorsFor('Card'),
errors: errorsFor('LegacyCard'),
},
{
code: `
import Polaris from '@shopify/polaris';
<Polaris.Card><Polaris.Card.Section /></Polaris.Card>;
<Polaris.LegacyCard><Polaris.LegacyCard.Section /></Polaris.LegacyCard>;
`,
filename: fixtureFile('polaris-app/index.js'),
parserOptions,
errors: errorsFor('Card'),
errors: errorsFor('LegacyCard'),
},
],
});