Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

eslint-plugin-smarthr

Package Overview
Dependencies
Maintainers
20
Versions
84
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-smarthr - npm Package Compare versions

Comparing version 0.2.8 to 0.2.9

rules/require-declaration/index.js

14

CHANGELOG.md

@@ -5,2 +5,16 @@ # Changelog

### [0.2.9](https://github.com/kufu/eslint-plugin-smarthr/compare/v0.2.8...v0.2.9) (2022-10-19)
### Features
* a11y-prohibit-input-placeholder を SearchInputに対応させる ([#38](https://github.com/kufu/eslint-plugin-smarthr/issues/38)) ([60de76b](https://github.com/kufu/eslint-plugin-smarthr/commit/60de76b58731436fe924a8a99da2242404141381))
* add require-declaration rule ([#34](https://github.com/kufu/eslint-plugin-smarthr/issues/34)) ([5dc6d44](https://github.com/kufu/eslint-plugin-smarthr/commit/5dc6d444e63f452f933bf6937207cfe23787732f))
* placeholder非推奨の対象に FieldSet, ComboBox も含める ([#35](https://github.com/kufu/eslint-plugin-smarthr/issues/35)) ([0e8d1d0](https://github.com/kufu/eslint-plugin-smarthr/commit/0e8d1d03377476fbd58adce17455e96533db69fa))
### Bug Fixes
* a11y-clickable-element-has-textのバグを修正する ([#36](https://github.com/kufu/eslint-plugin-smarthr/issues/36)) ([4efc23d](https://github.com/kufu/eslint-plugin-smarthr/commit/4efc23d33ba6eec2c454b323f561de3f7a678fab))
### [0.2.8](https://github.com/kufu/eslint-plugin-smarthr/compare/v0.2.7...v0.2.8) (2022-10-05)

@@ -7,0 +21,0 @@

2

package.json
{
"name": "eslint-plugin-smarthr",
"version": "0.2.8",
"version": "0.2.9",
"author": "SmartHR",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -16,3 +16,4 @@ # eslint-plugin-smarthr

- [require-barrel-import](https://github.com/kufu/eslint-plugin-smarthr/tree/main/rules/require-barrel-import)
- [require-declaration](https://github.com/kufu/eslint-plugin-smarthr/tree/main/rules/require-declaration)
- [require-export](https://github.com/kufu/eslint-plugin-smarthr/tree/main/rules/require-export)
- [require-import](https://github.com/kufu/eslint-plugin-smarthr/tree/main/rules/require-import)
const { generateTagFormatter } = require('../../libs/format_styled_components')
const SCHEMA = [
{
type: 'object',
properties: {
componentsWithText: { type: 'array', items: { type: 'string' }, default: [] },
},
additionalProperties: false,
}
]
const EXPECTED_NAMES = {

@@ -22,5 +32,8 @@ 'SmartHRLogo$': 'SmartHRLogo$',

},
schema: [],
schema: SCHEMA,
},
create(context) {
const option = context.options[0] || {}
const componentsWithText = option.componentsWithText || []
return {

@@ -45,2 +58,10 @@ ...generateTagFormatter({ context, EXPECTED_NAMES }),

if (c.type === 'JSXFragment') {
if (c.children && filterFalsyJSXText(c.children).some(recursiveSearch)) {
return true
}
return false
}
if (c.type === 'JSXElement') {

@@ -51,10 +72,26 @@ // // HINT: SmartHRLogo コンポーネントは内部でaltを持っているため対象外にする

}
if (c.openingElement.attributes.some((a) => {
if (componentsWithText.includes(c.openingElement.name.name)) {
return true
}
// HINT: role & aria-label を同時に設定されている場合は許可
let existRole = false
let existAriaLabel = false
const result = c.openingElement.attributes.reduce((prev, a) => {
existRole = existRole || (a.name.name === 'role' && a.value.value === 'img')
existAriaLabel = existAriaLabel || a.name.name === 'aria-label'
if (prev) {
return prev
}
if (!['visuallyHiddenText', 'alt'].includes(a.name.name)) {
return false
return prev
}
return (!!a.value.value || a.value.type === 'JSXExpressionContainer')
})) {
return (!!a.value.value || a.value.type === 'JSXExpressionContainer') ? a : prev
}, null)
if (result || (existRole && existAriaLabel)) {
return true

@@ -86,2 +123,2 @@ }

}
module.exports.schema = []
module.exports.schema = SCHEMA

@@ -10,3 +10,8 @@ # smarthr/a11y-clickable-element-has-text

rules: {
'smarthr/a11y-clickable-element-has-text': 'error', // 'warn', 'off'
'smarthr/a11y-clickable-element-has-text': [
'error', // 'warn', 'off'
// {
// componentsWithText: ['AnyComponentName'],
// },
]
},

@@ -63,1 +68,18 @@ }

```
```jsx
/*
rules: {
'smarthr/a11y-clickable-element-has-text': [
'error',
{
componentsWithText: ['AnyComponent'],
},
]
},
*/
<XxxButton>
<AnyComponent />
</XxxButton>
```

@@ -5,3 +5,6 @@ const { generateTagFormatter } = require('../../libs/format_styled_components')

'(i|I)nput$': 'Input$',
'SearchInput$': 'SearchInput$',
'(t|T)extarea$': 'Textarea$',
'FieldSet$': 'FieldSet$',
'ComboBox$': 'ComboBox$',
}

@@ -22,9 +25,9 @@

JSXOpeningElement: (node) => {
if (!node.name.name) {
const name = node.name.name
if (!name) {
return
}
const match = node.name.name.match(/((i|I)nput|(t|T)extarea)$/)
if (!match) {
if (!name.match(/((i|I)nput|(t|T)extarea|FieldSet|ComboBox)$/)) {
return

@@ -36,9 +39,23 @@ }

if (placeholder) {
context.report({
if (name.match(/SearchInput$/)) {
const tooltipMessage = node.attributes.find((a) => a.name?.name === 'tooltipMessage')
if (!tooltipMessage) {
context.report({
node: placeholder,
messageId: 'a11y-prohibit-input-placeholder',
data: {
message: `${name} にはplaceholder属性を単独で利用せず、tooltipMessageオプションのみ、もしくはplaceholderとtooltipMessageの併用を検討してください。 (例: '<${name} tooltipMessage="ヒント" />', '<${name} tooltipMessage={hint} placeholder={hint} />')`,
},
})
}
} else {
context.report({
node: placeholder,
messageId: 'a11y-prohibit-input-placeholder',
data: {
message: 'input, textarea要素のplaceholder属性は設定せず、smarthr-ui/Tooltip や別途ヒント用要素の利用を検討してください (例: `<><Input /><Hint>ヒント</Hint></>`, `<Tooltip message="ヒント"><Textarea/></Tooltip>`)',
message: `${name} にはplaceholder属性は設定せず、別途ヒント用要素の利用を検討してください。(例: '<div><${name} /><Hint>ヒント</Hint></div>')`,
},
})
}
}

@@ -45,0 +62,0 @@ },

@@ -99,2 +99,14 @@ const rule = require('../rules/a11y-clickable-element-has-text')

},
{
code: `<a><>ほげ</></a>`,
},
{
code: `<a><svg role="img" aria-label="hoge" /></a>`,
},
{
code: `<a><AnyComponent /></a>`,
options: [{
componentsWithText: ['AnyComponent']
}],
},
],

@@ -155,3 +167,14 @@ invalid: [

},
{
code: `<a><div role="article" aria-label="hoge" /></a>`,
errors: [{ message: defaultErrorMessage }]
},
{
code: `<a><AnyComponent /></a>`,
options: [{
componentsWithText: ['HogeComponent']
}],
errors: [{ message: defaultErrorMessage }]
},
]
})

@@ -25,6 +25,17 @@ const rule = require('../rules/a11y-prohibit-input-placeholder')

{ code: 'const HogeTextarea = styled(Textarea)``' },
{ code: 'const hoge = styled.fieldset``' },
{ code: 'const HogeFieldSet = styled(FieldSet)``' },
{ code: 'const HogeComboBox = styled(ComboBox)``' },
{ code: 'const HogeSearchInput = styled(SearchInput)``' },
{ code: `<input />` },
{ code: `<textarea />` },
{ code: `<FieldSet />` },
{ code: `<ComboBox />` },
{ code: `<StyledInput />` },
{ code: `<HogeTextarea />` },
{ code: `<FugaFieldSet />` },
{ code: `<CustomComboBox />` },
{ code: `<SearchInput />` },
{ code: `<CustomSearchInput tooltipMessage="hoge" />` },
{ code: `<CustomSearchInput tooltipMessage="hoge" placeholder="fuga" />` },
],

@@ -37,7 +48,19 @@ invalid: [

{ code: 'const Hoge = styled(StyledTextarea)``', errors: [ { message: `Hogeを正規表現 "/Textarea$/" がmatchする名称に変更してください` } ] },
{ code: `<input placeholder />`, errors: [ { message: 'input, textarea要素のplaceholder属性は設定せず、smarthr-ui/Tooltip や別途ヒント用要素の利用を検討してください (例: `<><Input /><Hint>ヒント</Hint></>`, `<Tooltip message="ヒント"><Textarea/></Tooltip>`)' } ] },
{ code: `<textarea placeholder="hoge" />`, errors: [ { message: 'input, textarea要素のplaceholder属性は設定せず、smarthr-ui/Tooltip や別途ヒント用要素の利用を検討してください (例: `<><Input /><Hint>ヒント</Hint></>`, `<Tooltip message="ヒント"><Textarea/></Tooltip>`)' } ] },
{ code: `<StyledInput placeholder={any} />`, errors: [ { message: 'input, textarea要素のplaceholder属性は設定せず、smarthr-ui/Tooltip や別途ヒント用要素の利用を検討してください (例: `<><Input /><Hint>ヒント</Hint></>`, `<Tooltip message="ヒント"><Textarea/></Tooltip>`)' } ] },
{ code: `<HogeTextarea placeholder="any" />`, errors: [ { message: 'input, textarea要素のplaceholder属性は設定せず、smarthr-ui/Tooltip や別途ヒント用要素の利用を検討してください (例: `<><Input /><Hint>ヒント</Hint></>`, `<Tooltip message="ヒント"><Textarea/></Tooltip>`)' } ] },
{ 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する名称に変更してください` },
{ message: `Hogeを正規表現 "/SearchInput$/" がmatchする名称に変更してください` },
],
},
{ code: `<input placeholder />`, errors: [ { message: `input にはplaceholder属性は設定せず、別途ヒント用要素の利用を検討してください。(例: '<div><input /><Hint>ヒント</Hint></div>')` } ] },
{ code: `<textarea placeholder="hoge" />`, errors: [ { message: `textarea にはplaceholder属性は設定せず、別途ヒント用要素の利用を検討してください。(例: '<div><textarea /><Hint>ヒント</Hint></div>')` } ] },
{ code: `<StyledInput placeholder={any} />`, errors: [ { message: `StyledInput にはplaceholder属性は設定せず、別途ヒント用要素の利用を検討してください。(例: '<div><StyledInput /><Hint>ヒント</Hint></div>')` } ] },
{ code: `<HogeTextarea placeholder="any" />`, errors: [ { message: `HogeTextarea にはplaceholder属性は設定せず、別途ヒント用要素の利用を検討してください。(例: '<div><HogeTextarea /><Hint>ヒント</Hint></div>')` } ] },
{ code: `<HogeFieldSet placeholder="any" />`, errors: [ { message: `HogeFieldSet にはplaceholder属性は設定せず、別途ヒント用要素の利用を検討してください。(例: '<div><HogeFieldSet /><Hint>ヒント</Hint></div>')` } ] },
{ code: `<HogeComboBox placeholder="any" />`, errors: [ { message: `HogeComboBox にはplaceholder属性は設定せず、別途ヒント用要素の利用を検討してください。(例: '<div><HogeComboBox /><Hint>ヒント</Hint></div>')` } ] },
{ code: `<SearchInput placeholder="any" />`, errors: [ { message: `SearchInput にはplaceholder属性を単独で利用せず、tooltipMessageオプションのみ、もしくはplaceholderとtooltipMessageの併用を検討してください。 (例: '<SearchInput tooltipMessage="ヒント" />', '<SearchInput tooltipMessage={hint} placeholder={hint} />')` } ] },
]
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc