-
Notifications
You must be signed in to change notification settings - Fork 18
add counter badge rule #107
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
Merged
Merged
Changes from 1 commit
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
63ab5d4
add counter badge rule
yonashailug bcc7871
fix comments
yonashailug 5d796fd
resolve conflict
yonashailug d796074
Merge branch 'main' of https://github.com/yonashailug/eslint-plugin-f…
yonashailug be8a8a8
merge conflict
yonashailug d97703b
update counter badge rule
yonashailug c0781cd
fixed readme file lint error
aubreyquinn 9804701
Merge branch 'main' into main
aubreyquinn da4634f
updated readme
aubreyquinn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# @microsoft/fluentui-jsx-a11y/counter-badge-needs-count | ||
|
||
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix). | ||
|
||
<!-- end auto-generated rule header --> | ||
|
||
A counter badge is a badge that displays a numerical count. | ||
|
||
## Rule Details | ||
|
||
Ensure that the `CounterBadge` component is accessible. | ||
|
||
Examples of **incorrect** code for this rule: | ||
|
||
```jsx | ||
<CounterBadge appearance="filled" size="extra-large" /> | ||
``` | ||
|
||
```jsx | ||
<CounterBadge icon={<PasteIcon />} /> | ||
``` | ||
|
||
|
||
Examples of **correct** code for this rule: | ||
|
||
If the badge contains a custom icon, that icon must be given alternative text with aria-label, unless it is purely presentational: | ||
|
||
```jsx | ||
<CounterBadge icon={<PasteIcon aria-label="paste" />} count={5} /> | ||
``` | ||
|
||
```jsx | ||
<CounterBadge dot /> | ||
``` | ||
|
||
## Further Reading | ||
|
||
<https://react.fluentui.dev/?path=/docs/components-badge-badge--docs> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
"use strict"; | ||
|
||
var elementType = require("jsx-ast-utils").elementType; | ||
const { getProp } = require("jsx-ast-utils"); | ||
var hasProp = require("jsx-ast-utils").hasProp; | ||
|
||
//------------------------------------------------------------------------------ | ||
// Rule Definition | ||
//------------------------------------------------------------------------------ | ||
|
||
/** @type {import('eslint').Rule.RuleModule} */ | ||
module.exports = { | ||
meta: { | ||
messages: { | ||
counterBadgeNeedsCount: "CounterBadge: needs numerical count. Add numerical count.", | ||
counterBadgeIconNeedsLabelling: "The icon inside <CounterBadge> must have an aria-label attribute." | ||
}, | ||
type: "problem", // `problem`, `suggestion`, or `layout` | ||
docs: { | ||
description: "", | ||
recommended: false, | ||
url: "https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/img_role" // URL to the documentation page for this rule | ||
}, | ||
fixable: "code", // Or `code` or `whitespace` | ||
schema: [] // Add a schema if the rule has options | ||
}, | ||
|
||
create(context) { | ||
return { | ||
// visitor functions for different types of nodes | ||
JSXElement(node) { | ||
const openingElement = node.openingElement; | ||
|
||
if (elementType(openingElement) !== "CounterBadge") { | ||
return; | ||
} | ||
|
||
const hasDot = hasProp(openingElement.attributes, "dot"); | ||
|
||
if (hasDot) { | ||
return; | ||
} | ||
|
||
const hasIconProp = hasProp(openingElement.attributes, "icon"); | ||
|
||
if (hasIconProp) { | ||
const iconProp = getProp(openingElement.attributes, "icon"); | ||
|
||
if (iconProp) { | ||
const iconElement = iconProp.value.expression; | ||
|
||
const ariaLabelAttr = hasProp(iconElement.openingElement.attributes, "aria-label"); | ||
|
||
if (!ariaLabelAttr) { | ||
context.report({ | ||
node, | ||
messageId: "counterBadgeIconNeedsLabelling", | ||
fix(fixer) { | ||
const ariaLabelFix = fixer.insertTextAfter(iconElement.openingElement.name, ' aria-label=""'); | ||
return ariaLabelFix; | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
|
||
const hasCount = hasProp(openingElement.attributes, "count"); | ||
yonashailug marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if (hasCount) { | ||
return; | ||
} | ||
|
||
context.report({ | ||
node, | ||
messageId: "counterBadgeNeedsCount", | ||
fix(fixer) { | ||
const countFix = fixer.insertTextAfter(openingElement.name, " count={0}"); | ||
return countFix; | ||
} | ||
}); | ||
} | ||
}; | ||
} | ||
}; | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
"use strict"; | ||
|
||
//------------------------------------------------------------------------------ | ||
// Requirements | ||
//------------------------------------------------------------------------------ | ||
|
||
const rule = require("../../../lib/rules/counter-badge-needs-count"), | ||
RuleTester = require("eslint").RuleTester; | ||
|
||
RuleTester.setDefaultConfig({ | ||
parserOptions: { | ||
ecmaVersion: 6, | ||
ecmaFeatures: { | ||
jsx: true | ||
} | ||
} | ||
}); | ||
|
||
//------------------------------------------------------------------------------ | ||
// Tests | ||
//------------------------------------------------------------------------------ | ||
|
||
const ruleTester = new RuleTester(); | ||
ruleTester.run("counter-badge-needs-count", rule, { | ||
valid: [ | ||
`<CounterBadge count={5} appearance="filled" />`, | ||
`<CounterBadge icon={<PasteIcon aria-label="paste" />} count={1} />`, | ||
`<CounterBadge dot />`, | ||
`<div><CounterBadge count={10} appearance="filled" /></div>` | ||
], | ||
|
||
invalid: [ | ||
{ | ||
code: `<CounterBadge appearance="filled" size="extra-large" />`, | ||
errors: [{ messageId: "counterBadgeNeedsCount" }], | ||
output: `<CounterBadge count={0} appearance="filled" size="extra-large" />` | ||
}, | ||
{ | ||
code: `<CounterBadge icon={<PasteIcon />} />`, | ||
errors: [ | ||
{ | ||
messageId: "counterBadgeIconNeedsLabelling" | ||
}, | ||
{ messageId: "counterBadgeNeedsCount" } | ||
], | ||
output: `<CounterBadge count={0} icon={<PasteIcon aria-label="" />} />` | ||
}, | ||
{ | ||
code: `<CounterBadge icon={<PasteIcon />} count={100} />`, | ||
errors: [{ messageId: "counterBadgeIconNeedsLabelling" }], | ||
output: `<CounterBadge icon={<PasteIcon aria-label="" />} count={100} />` | ||
}, | ||
{ | ||
code: `<CounterBadge></CounterBadge>`, | ||
errors: [{ messageId: "counterBadgeNeedsCount" }], | ||
output: `<CounterBadge count={0}></CounterBadge>` | ||
} | ||
] | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.