diff --git a/libs/format_styled_components.js b/libs/format_styled_components.js
index 0ed68fe..b546724 100644
--- a/libs/format_styled_components.js
+++ b/libs/format_styled_components.js
@@ -1,68 +1,71 @@
-const getExtendedComponentName = (node) => {
- if (!node.parent) {
- return null
- }
+const STYLED_COMPONENTS_METHOD = 'styled'
+const STYLED_COMPONENTS = `${STYLED_COMPONENTS_METHOD}-components`
- return node.parent.id?.name || getExtendedComponentName(node.parent)
-}
-const getBaseComponentName = (node) => {
- if (!node) {
- return null
- }
+const findInvalidImportNameNode = (s) => s.type === 'ImportDefaultSpecifier' && s.local.name !== STYLED_COMPONENTS_METHOD
- if (node.type === 'CallExpression') {
- if (node.callee.name === 'styled') {
- return node.arguments[0].name
- }
- if (node.callee.object?.name === 'styled') {
- return node.callee.property.name
- }
- }
+const generateTagFormatter = ({ context, EXPECTED_NAMES }) => {
+ const entriesesTagNames = Object.entries(EXPECTED_NAMES).map(([b, e]) => [ new RegExp(b), new RegExp(e) ])
- if (node?.object?.name === 'styled') {
- return node.property.name
- }
+ return {
+ ImportDeclaration: (node) => {
+ if (node.source.value !== STYLED_COMPONENTS) {
+ return
+ }
- return getBaseComponentName(node.parent)
-}
+ const invalidNameNode = node.specifiers.find(findInvalidImportNameNode)
-const generateTagFormatter = ({ context, EXPECTED_NAMES }) => ({
- ImportDeclaration: (node) => {
- if (node.source.value !== 'styled-components') {
- return
- }
+ if (invalidNameNode) {
+ context.report({
+ node: invalidNameNode,
+ message: `${STYLED_COMPONENTS} をimportする際は、名称が"${STYLED_COMPONENTS_METHOD}" となるようにしてください。例: "import ${STYLED_COMPONENTS_METHOD} from '${STYLED_COMPONENTS}'"`,
+ });
+ }
+ },
+ VariableDeclarator: (node) => {
+ if (!node.init) {
+ return
+ }
- const invalidNameNode = node.specifiers.find((s) => s.type === 'ImportDefaultSpecifier' && s.local.name !== 'styled')
+ const tag = node.init.tag || node.init
- if (invalidNameNode) {
- context.report({
- node: invalidNameNode,
- message: "styled-components をimportする際は、名称が`styled` となるようにしてください。例: `import styled from 'styled-components'`",
- });
- }
- },
- TaggedTemplateExpression: (node) => {
- const extended = getExtendedComponentName(node)
+ let base = null
- if (extended) {
- const base = getBaseComponentName(node.tag)
+ if (tag.object?.name === STYLED_COMPONENTS_METHOD) {
+ base = tag.property.name
+ } else if (tag.callee) {
+ const callee = tag.callee
+
+ switch (STYLED_COMPONENTS_METHOD) {
+ case callee.name: {
+ const arg = tag.arguments[0]
+ base = arg.name || arg.value
+ break
+ }
+ case callee.callee?.name: {
+ const arg = callee.arguments[0]
+ base = arg.name || arg.value
+ break
+ }
+ case callee.object?.name:
+ base = callee.property.name
+ break
+ }
+ }
if (base) {
- Object.entries(EXPECTED_NAMES).forEach(([b, e]) => {
- if (base.match(new RegExp(b))) {
- const extendedregex = new RegExp(e)
+ const extended = node.id.name
- if (!extended.match(extendedregex)) {
- context.report({
- node: node.parent,
- message: `${extended}を正規表現 "${extendedregex.toString()}" がmatchする名称に変更してください`,
- });
- }
+ entriesesTagNames.forEach(([b, e]) => {
+ if (base.match(b) && !extended.match(e)) {
+ context.report({
+ node,
+ message: `${extended}を正規表現 "${e.toString()}" がmatchする名称に変更してください`,
+ });
}
})
}
- }
- },
-})
+ },
+ }
+}
module.exports = { generateTagFormatter }
diff --git a/test/a11y-clickable-element-has-text.js b/test/a11y-clickable-element-has-text.js
index e440f1e..1e3dd77 100644
--- a/test/a11y-clickable-element-has-text.js
+++ b/test/a11y-clickable-element-has-text.js
@@ -27,6 +27,9 @@ ruleTester.run('a11y-clickable-element-has-text', rule, {
{ code: 'const HogeButton = styled(Button)``' },
{ code: 'const FugaAnchor = styled(HogeAnchor)``' },
{ code: 'const FugaSmartHRLogo = styled(SmartHRLogo)``' },
+ { code: 'const HogeAnchor = styled.a(() => ``)' },
+ { code: 'const HogeAnchor = styled("a")(() => ``)' },
+ { code: 'const HogeAnchor = styled(Anchor)(() => ``)' },
{
code: `ほげ`,
},
@@ -110,7 +113,7 @@ ruleTester.run('a11y-clickable-element-has-text', rule, {
},
],
invalid: [
- { code: `import hoge from 'styled-components'`, errors: [ { message: "styled-components をimportする際は、名称が`styled` となるようにしてください。例: `import styled from 'styled-components'`" } ] },
+ { code: `import hoge from 'styled-components'`, errors: [ { message: `styled-components をimportする際は、名称が"styled" となるようにしてください。例: "import styled from 'styled-components'"` } ] },
{ code: 'const Hoge = styled.a``', errors: [ { message: `Hogeを正規表現 "/(Anchor|Link)$/" がmatchする名称に変更してください` } ] },
{ code: 'const Hoge = styled.button``', errors: [ { message: `Hogeを正規表現 "/Button$/" がmatchする名称に変更してください` } ] },
{ code: 'const Hoge = styled(Anchor)``', errors: [ { message: `Hogeを正規表現 "/Anchor$/" がmatchする名称に変更してください` } ] },
@@ -119,6 +122,10 @@ ruleTester.run('a11y-clickable-element-has-text', rule, {
{ code: 'const Fuga = styled(HogeAnchor)``', errors: [ { message: `Fugaを正規表現 "/Anchor$/" がmatchする名称に変更してください` } ] },
{ code: 'const Fuga = styled(HogeAnchor)``', errors: [ { message: `Fugaを正規表現 "/Anchor$/" がmatchする名称に変更してください` } ] },
{ code: 'const Fuga = styled(SmartHRLogo)``', errors: [ { message: `Fugaを正規表現 "/SmartHRLogo$/" がmatchする名称に変更してください` } ] },
+ { code: 'const Piyo = styled.a(() => ``)', errors: [ { message: `Piyoを正規表現 "/(Anchor|Link)$/" がmatchする名称に変更してください` } ] },
+ { code: 'const Piyo = styled("a")(() => ``)', errors: [ { message: `Piyoを正規表現 "/(Anchor|Link)$/" がmatchする名称に変更してください` } ] },
+ { code: 'const Piyo = styled("a")``', errors: [ { message: `Piyoを正規表現 "/(Anchor|Link)$/" がmatchする名称に変更してください` } ] },
+ { code: 'const Piyo = styled(Anchor)(() => ``)', errors: [ { message: `Piyoを正規表現 "/Anchor$/" がmatchする名称に変更してください` } ] },
{
code: ``,
errors: [{ message: defaultErrorMessage }]
diff --git a/test/a11y-image-has-alt-attribute.js b/test/a11y-image-has-alt-attribute.js
index 05cea08..9d526e6 100644
--- a/test/a11y-image-has-alt-attribute.js
+++ b/test/a11y-image-has-alt-attribute.js
@@ -33,7 +33,7 @@ ruleTester.run('a11y-image-has-alt-attribute', rule, {
{ code: '' },
],
invalid: [
- { code: `import hoge from 'styled-components'`, errors: [ { message: "styled-components をimportする際は、名称が`styled` となるようにしてください。例: `import styled from 'styled-components'`" } ] },
+ { code: `import hoge from 'styled-components'`, errors: [ { message: `styled-components をimportする際は、名称が"styled" となるようにしてください。例: "import styled from 'styled-components'"` } ] },
{ code: 'const Hoge = styled.img``', errors: [ { message: `Hogeを正規表現 "/(Img|Image|Icon)$/" がmatchする名称に変更してください` } ] },
{ code: 'const Hoge = styled.svg``', errors: [ { message: `Hogeを正規表現 "/(Img|Image|Icon)$/" がmatchする名称に変更してください` } ] },
{ code: 'const Hoge = styled(Icon)``', errors: [ { message: `Hogeを正規表現 "/Icon$/" がmatchする名称に変更してください` } ] },
diff --git a/test/a11y-input-has-name-attribute.js b/test/a11y-input-has-name-attribute.js
index a754618..2e2f393 100644
--- a/test/a11y-input-has-name-attribute.js
+++ b/test/a11y-input-has-name-attribute.js
@@ -33,7 +33,7 @@ ruleTester.run('a11y-input-has-name-attribute', rule, {
{ code: '' },
],
invalid: [
- { code: `import hoge from 'styled-components'`, errors: [ { message: "styled-components をimportする際は、名称が`styled` となるようにしてください。例: `import styled from 'styled-components'`" } ] },
+ { code: `import hoge from 'styled-components'`, errors: [ { message: `styled-components をimportする際は、名称が"styled" となるようにしてください。例: "import styled from 'styled-components'"` } ] },
{ code: 'const Hoge = styled.input``', errors: [ { message: `Hogeを正規表現 "/Input$/" がmatchする名称に変更してください` } ] },
{ code: 'const Hoge = styled.Input``', errors: [ { message: `Hogeを正規表現 "/Input$/" がmatchする名称に変更してください` } ] },
{ code: 'const Hoge = styled(RadioButton)``', errors: [ { message: `Hogeを正規表現 "/RadioButton$/" がmatchする名称に変更してください` } ] },
diff --git a/test/a11y-prohhibit-input-placeholder.js b/test/a11y-prohhibit-input-placeholder.js
index f9ad0fa..9bf7e94 100644
--- a/test/a11y-prohhibit-input-placeholder.js
+++ b/test/a11y-prohhibit-input-placeholder.js
@@ -43,14 +43,14 @@ ruleTester.run('a11y-prohibit-input-placeholder', rule, {
{ code: `` },
],
invalid: [
- { code: `import hoge from 'styled-components'`, errors: [ { message: "styled-components をimportする際は、名称が`styled` となるようにしてください。例: `import styled from 'styled-components'`" } ] },
+ { code: `import hoge from 'styled-components'`, errors: [ { message: `styled-components をimportする際は、名称が"styled" となるようにしてください。例: "import styled from 'styled-components'"` } ] },
{ code: 'const Hoge = styled.input``', errors: [ { message: `Hogeを正規表現 "/Input$/" がmatchする名称に変更してください` } ] },
{ code: 'const Hoge = styled(StyledInput)``', errors: [ { message: `Hogeを正規表現 "/Input$/" がmatchする名称に変更してください` } ] },
{ code: 'const Hoge = styled.textarea``', errors: [ { message: `Hogeを正規表現 "/Textarea$/" がmatchする名称に変更してください` } ] },
{ code: 'const Hoge = styled(StyledTextarea)``', errors: [ { message: `Hogeを正規表現 "/Textarea$/" がmatchする名称に変更してください` } ] },
{ code: 'const Hoge = styled(FieldSet)``', errors: [ { message: `Hogeを正規表現 "/FieldSet$/" がmatchする名称に変更してください` } ] },
{ code: 'const Hoge = styled(ComboBox)``', errors: [ { message: `Hogeを正規表現 "/ComboBox$/" がmatchする名称に変更してください` } ] },
- {
+ {
code: 'const Hoge = styled(SearchInput)``',
errors: [
{ message: `Hogeを正規表現 "/Input$/" がmatchする名称に変更してください` },
diff --git a/test/a11y-trigger-has-button.js b/test/a11y-trigger-has-button.js
index 6fddbf8..17b5f78 100644
--- a/test/a11y-trigger-has-button.js
+++ b/test/a11y-trigger-has-button.js
@@ -32,7 +32,7 @@ ruleTester.run('a11y-trigger-has-button', rule, {
{ code: '{hoge}' },
],
invalid: [
- { code: `import hoge from 'styled-components'`, errors: [ { message: "styled-components をimportする際は、名称が`styled` となるようにしてください。例: `import styled from 'styled-components'`" } ] },
+ { code: `import hoge from 'styled-components'`, errors: [ { message: `styled-components をimportする際は、名称が"styled" となるようにしてください。例: "import styled from 'styled-components'"` } ] },
{ code: 'const Hoge = styled.button``', errors: [ { message: `Hogeを正規表現 "/Button$/" がmatchする名称に変更してください` } ] },
{ code: 'const Hoge = styled.a``', errors: [ { message: `Hogeを正規表現 "/(Anchor|Link)$/" がmatchする名称に変更してください` } ] },
{ code: 'const Hoge = styled(Button)``', errors: [ { message: `Hogeを正規表現 "/Button$/" がmatchする名称に変更してください` } ] },