diff --git a/docs/rules/sort-objects.md b/docs/rules/sort-objects.md index a308e72a..867e1b20 100644 --- a/docs/rules/sort-objects.md +++ b/docs/rules/sort-objects.md @@ -85,6 +85,7 @@ interface Options { 'ignore-case'?: boolean groups?: (string | string[])[] 'custom-groups': { [key: string]: string[] | string } + 'styled-components': boolean 'partition-by-comment': string[] | string | boolean } ``` @@ -132,6 +133,12 @@ Example: } ``` +### styled-components + +(default: `true`) + +When `false`, this rule will be disabled for the styled-components like libraries. + ### partition-by-comment (default: `false`) diff --git a/rules/sort-objects.ts b/rules/sort-objects.ts index 55ad7663..4af2214d 100644 --- a/rules/sort-objects.ts +++ b/rules/sort-objects.ts @@ -35,6 +35,7 @@ type Options = [ 'custom-groups': { [key: string]: string[] | string } 'partition-by-comment': PartitionComment groups: (string[] | string)[] + 'styled-components': boolean 'ignore-case': boolean order: SortOrder type: SortType @@ -63,6 +64,10 @@ export default createEslintRule({ type: ['boolean', 'string', 'array'], default: false, }, + 'styled-components': { + type: 'boolean', + default: true, + }, type: { enum: [ SortType.alphabetical, @@ -105,12 +110,35 @@ export default createEslintRule({ let options = complete(context.options.at(0), { 'partition-by-comment': false, type: SortType.alphabetical, + 'styled-components': true, 'ignore-case': false, order: SortOrder.asc, 'custom-groups': {}, groups: [], }) + let isStyledCallExpression = (identifier: TSESTree.Expression) => + identifier.type === 'Identifier' && identifier.name === 'styled' + + let isStyledComponents = ( + styledNode: TSESTree.Node | undefined, + ): boolean => + styledNode !== undefined && + styledNode.type === 'CallExpression' && + ((styledNode.callee.type === 'MemberExpression' && + isStyledCallExpression(styledNode.callee.object)) || + (styledNode.callee.type === 'CallExpression' && + isStyledCallExpression(styledNode.callee.callee))) + + if ( + !options['styled-components'] && + (isStyledComponents(node.parent) || + (node.parent?.type === 'ArrowFunctionExpression' && + isStyledComponents(node.parent.parent))) + ) { + return + } + let source = context.getSourceCode() let formatProperties = ( diff --git a/test/sort-objects.test.ts b/test/sort-objects.test.ts index da4a4f83..bbb59b88 100644 --- a/test/sort-objects.test.ts +++ b/test/sort-objects.test.ts @@ -2465,5 +2465,56 @@ describe(RULE_NAME, () => { ], }) }) + + it(`${RULE_NAME}: allow to disable rule for styled-components`, () => { + ruleTester.run(RULE_NAME, rule, { + valid: [ + { + code: dedent` + const Box = styled.div({ + background: "palevioletred", + width: "50px", + height: "50px", + }) + `, + options: [ + { + 'styled-components': false, + }, + ], + }, + { + code: dedent` + const PropsBox = styled.div((props) => ({ + background: props.background, + height: "50px", + width: "50px", + })) + `, + options: [ + { + 'styled-components': false, + }, + ], + }, + { + code: dedent` + export default styled('div')(() => ({ + borderRadius: 0, + borderWidth: 0, + border: 0, + borderBottom: hasBorder && \`1px solid \${theme.palette.divider}\`, + })) + `, + options: [ + { + 'styled-components': false, + }, + ], + }, + ], + invalid: [], + }) + }) }) })