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

eslint-plugin-smarthr

Package Overview
Dependencies
Maintainers
24
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.4.1 to 0.4.2

rules/best-practice-for-button-element/index.js

12

CHANGELOG.md

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

### [0.4.2](https://github.com/kufu/eslint-plugin-smarthr/compare/v0.4.1...v0.4.2) (2024-03-03)
### Features
* best-practice-for-button-elementを追加 ([#115](https://github.com/kufu/eslint-plugin-smarthr/issues/115)) ([c19ab10](https://github.com/kufu/eslint-plugin-smarthr/commit/c19ab1062d00aa000cfcf9b86535af21b47a0ead))
### Bug Fixes
* a11y-numbered-text-within-ol でwidthの値が誤検知されてしまう場合に対応する ([#117](https://github.com/kufu/eslint-plugin-smarthr/issues/117)) ([3741d54](https://github.com/kufu/eslint-plugin-smarthr/commit/3741d5412f62ac04286e0626e37d2ca3c57c4f60))
### [0.4.1](https://github.com/kufu/eslint-plugin-smarthr/compare/v0.4.0...v0.4.1) (2024-02-21)

@@ -7,0 +19,0 @@

74

libs/format_styled_components.js

@@ -21,2 +21,40 @@ const STYLED_COMPONENTS_METHOD = 'styled'

const getStyledComponentBaseName = (node) => {
let base = null
if (!node.init) {
return base
}
const tag = node.init.tag || node.init
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
case callee.object?.callee?.name:
const arg = callee.object.arguments[0]
base = arg.name || arg.value
break
}
}
return base
}
const generateTagFormatter = ({ context, EXPECTED_NAMES, UNEXPECTED_NAMES }) => {

@@ -56,36 +94,4 @@ const entriesesTagNames = Object.entries(EXPECTED_NAMES).map(([b, e]) => [ new RegExp(b), new RegExp(e) ])

VariableDeclarator: (node) => {
if (!node.init) {
return
}
const base = getStyledComponentBaseName(node)
const tag = node.init.tag || node.init
let base = null
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
case callee.object?.callee?.name:
const arg = callee.object.arguments[0]
base = arg.name || arg.value
break
}
}
if (base) {

@@ -122,2 +128,2 @@ const extended = node.id.name

module.exports = { generateTagFormatter }
module.exports = { generateTagFormatter, checkImportStyledComponents, getStyledComponentBaseName }
{
"name": "eslint-plugin-smarthr",
"version": "0.4.1",
"version": "0.4.2",
"author": "SmartHR",

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

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

const REGEX_TEXT_COMPONENT = /(Text|Message)$/
const REGEX_JSX_TYPE = /^(JSXText|JSXExpressionContainer)$/
const HIT_TYPES_RECURSICVE_SEARCH = ['JSXText', 'JSXExpressionContainer']
const HIT_TEXT_ATTRS = ['visuallyHiddenText', 'alt']
const HIT_TEXT_ATTR = 'alt'

@@ -72,3 +72,3 @@ const filterFalsyJSXText = (cs) => cs.filter(checkFalsyJSXText)

const recursiveSearch = (c) => {
if (HIT_TYPES_RECURSICVE_SEARCH.includes(c.type)) {
if (REGEX_JSX_TYPE.test(c.type)) {
return true

@@ -102,3 +102,3 @@ }

prev ||
!HIT_TEXT_ATTRS.includes(a.name.name)
HIT_TEXT_ATTR !== a.name.name
) {

@@ -105,0 +105,0 @@ return prev

# smarthr/a11y-clickable-element-has-text
- ButtonやAnchor,Link コンポーネントにテキスト要素が設定されていない場合、アクセシビリティの問題が発生する可能性を防ぐルールです
- ButtonやAnchor,Link コンポーネントにテキスト要素が設定されていない場合、スクリーンリーダーで押したものが何だったのかわからない等の問題が発生する可能性を防ぐルールです
- a要素やbutton要素の中身にtextがあることを担保するルール
- 画像要素の場合は `visuallyHiddenText`や `alt`等代替テキストを設定する
- SVGの場合はrole="img" と aria-labelを設定する
- linkとかanchorのchildrenを含まない要素はチェックしない
- 例) `<YyyAnchor />`

@@ -41,3 +46,3 @@ ## rules

```jsx
<XxxAnchor>>
<XxxAnchor>
<XxxTextYyyy />

@@ -61,3 +66,3 @@ </XxxAnchor>

```jsx
<XxxAnchor>>
<XxxAnchor>
<YyyIcon visuallyHiddenText="hoge" />

@@ -73,7 +78,7 @@ </XxxAnchor>

```jsx
<YyyAnchoor />
<YyyAnchor />
```
```jsx
<XxxAnchor>>
<XxxAnchor>
<XxxText />

@@ -80,0 +85,0 @@ </XxxAnchor>

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

const NUMBERED_TEXT_REGEX = /^[\s\n]*(([1-9])([^1-9]{2})[^\s\n]*)/
const NUMBERED_TEXT_REGEX = /^[\s\n]*(([0-9])([^0-9]{2})[^\s\n]*)/
const ORDERED_LIST_REGEX = /(Ordered(.*)List|^ol)$/
const SELECT_REGEX = /(S|s)elect$/
const IGNORE_ATTRIBUTE_REGEX = /((w|W)idth|(h|H)eight)$/
const AS_ATTRIBUTE_REGEX = /^(as|forwardedAs)$/
const findAsOlAttr = (a) => a.type === 'JSXAttribute' && AS_ATTRIBUTE_REGEX.test(a.name?.name) && a.value?.value === 'ol'
const searchOrderedList = (node) => {

@@ -18,8 +22,11 @@ if (node.type === 'JSXElement' && node.openingElement.name?.name) {

if (name.match(ORDERED_LIST_REGEX)) {
return node.openingElement
} else if (name.match(SELECT_REGEX)) {
if (name.match(SELECT_REGEX)) {
// HINT: select要素の場合、optionのラベルに連番がついている場合がありえるのでignoreする
// 通常と処理を分けるためnullではなく0を返す
return 0
} else if (
name.match(ORDERED_LIST_REGEX) ||
node.openingElement.attributes.find(findAsOlAttr)
) {
return node.openingElement
}

@@ -126,3 +133,3 @@ }

JSXAttribute: (node) => {
if (node.value?.value) {
if (node.value?.value && !IGNORE_ATTRIBUTE_REGEX.test(node.name?.name)) {
checker(node, node.value.value.match(NUMBERED_TEXT_REGEX))

@@ -129,0 +136,0 @@ }

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

{
code: `<a><Icon visuallyHiddenText="ほげ" /></a>`,
},
{
code: `<a><AnyComponent><Icon visuallyHiddenText="ほげ" /></AnyComponent></a>`,
},
{
code: `<a>{any}</a>`,

@@ -199,6 +193,2 @@ },

{
code: `<a><AnyComponent><Icon visuallyHiddenText="" /></AnyComponent></a>`,
errors: [{ message: defaultErrorMessage }]
},
{
code: `<button><img src="hoge.jpg" /></button>`,

@@ -220,6 +210,2 @@ errors: [{ message: defaultErrorMessage }]

{
code: `<button><AnyComponent><Icon visuallyHiddenText="" /></AnyComponent></button>`,
errors: [{ message: defaultErrorMessage }]
},
{
code: `<button><SmartHRLogoSuffix /></button>`,

@@ -226,0 +212,0 @@ errors: [{ message: defaultErrorMessage }]

@@ -24,3 +24,6 @@ const rule = require('../rules/a11y-numbered-text-within-ol')

{ code: `<OrderedList><li>abc</li><li>def</li></OrderedList>` },
{ code: `<Hoge as="ol"><li>abc</li><li>def</li></Hoge>` },
{ code: `<Hoge forwardedAs="ol"><li>abc</li><li>def</li></Hoge>` },
{ code: `<Select><optgroup><option value="hoge">1. hoge</option><option value="fuga">2. fuga</option></optgroup></Select>` },
{ code: `<><Hoge width="100%" /><Hoge height="200%" /><Hoge maxWidth="30px" /></>` },
],

@@ -27,0 +30,0 @@ invalid: [

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