-
Notifications
You must be signed in to change notification settings - Fork 71
chore(packages) avoid data-lgid
and data-testid
attributes being duplicated in components
#3184
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
base: main
Are you sure you want to change the base?
Changes from all commits
d0a948f
90a296a
5de7102
e09ef7f
b03b742
310c155
5df76b0
56909f1
1577e9e
d950bd1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
--- | ||
'@leafygreen-ui/confirmation-modal': patch | ||
'@leafygreen-ui/password-input': patch | ||
'@leafygreen-ui/progress-bar': patch | ||
'@leafygreen-ui/form-field': patch | ||
'@lg-tools/eslint-plugin': patch | ||
'@leafygreen-ui/checkbox': patch | ||
'@leafygreen-ui/select': patch | ||
'@leafygreen-ui/modal': patch | ||
'@leafygreen-ui/lib': patch | ||
'@lg-tools/lint': patch | ||
--- | ||
|
||
Avoid duplicated data-lgid and data-testid |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -542,8 +542,8 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>( | |||
<div className={labelDescriptionContainerStyle}> | ||||
{label && ( | ||||
<Label | ||||
data-lgid={lgIds.root} | ||||
data-testid={lgIds.root} | ||||
data-lgid={lgIds.label} | ||||
data-testid={lgIds.label} | ||||
htmlFor={menuButtonId} | ||||
id={labelId} | ||||
darkMode={darkMode} | ||||
|
@@ -574,8 +574,8 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>( | |||
|
||||
{description && ( | ||||
<Description | ||||
data-lgid={lgIds.root} | ||||
data-testid={lgIds.root} | ||||
data-lgid={lgIds.description} | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we make this change, then we should update the test utils. Currently, in a few test utils, we are calling the typography getLgIds function with the root, but with this change, we'll no longer need to do that.
|
||||
data-testid={lgIds.description} | ||||
id={descriptionId} | ||||
darkMode={darkMode} | ||||
disabled={disabled} | ||||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,14 @@ | ||
/** | ||
* DO NOT MODIFY THIS FILE | ||
* ANY CHANGES WILL BE REMOVED ON THE NEXT BUILD | ||
* USE THE "create-rule" SCRIPT TO ADD NEW RULES INSTEAD | ||
*/ | ||
import { noDuplicateIdsRule } from './no-duplicate-ids'; | ||
import { noIndirectImportsRule } from './no-indirect-imports'; | ||
import { noRenderHookFromRtlRule } from './no-render-hook-from-rtl'; | ||
|
||
export const rules = { | ||
'no-duplicate-ids': noDuplicateIdsRule, | ||
'no-indirect-imports': noIndirectImportsRule, | ||
'no-render-hook-from-rtl': noRenderHookFromRtlRule, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { TSESTree } from '@typescript-eslint/types'; | ||
|
||
import { createRule } from '../utils/createRule'; | ||
|
||
export const noDuplicateIdsRule = createRule({ | ||
name: 'no-duplicate-ids', | ||
meta: { | ||
type: 'suggestion', | ||
messages: { | ||
'issue:noDuplicateIds': | ||
'Do not reference the same lgid or testid in multiple places within a component', | ||
}, | ||
schema: [], | ||
docs: { | ||
description: | ||
'Prevents duplicate lgid or testid usage within a component file', | ||
}, | ||
}, | ||
defaultOptions: [], | ||
create: context => { | ||
const seen: Record< | ||
'data-lgid' | 'data-testid', | ||
Record<string, TSESTree.JSXAttribute | undefined> | ||
> = { | ||
'data-lgid': {}, | ||
'data-testid': {}, | ||
}; | ||
|
||
return { | ||
JSXAttribute(node) { | ||
if (node.name.type !== 'JSXIdentifier') { | ||
return; | ||
} | ||
|
||
const { name: attributeName } = node.name; | ||
|
||
if (attributeName !== 'data-lgid' && attributeName !== 'data-testid') { | ||
return; | ||
} | ||
|
||
if ( | ||
node.value?.type !== 'JSXExpressionContainer' || | ||
node.value.expression.type !== 'MemberExpression' || | ||
node.value.expression.object.type !== 'Identifier' || | ||
node.value.expression.object.name !== 'lgIds' | ||
) { | ||
return; | ||
} | ||
|
||
const { property } = node.value.expression; | ||
|
||
const name = | ||
property.type === 'Identifier' | ||
? property.name | ||
: property.type === 'Literal' | ||
? property.value | ||
: undefined; | ||
|
||
if (typeof name === 'string') { | ||
const other = seen[attributeName][name]; | ||
|
||
if (other) { | ||
context.report({ | ||
node, | ||
messageId: 'issue:noDuplicateIds', | ||
}); | ||
} else { | ||
seen[attributeName][name] = node; | ||
} | ||
} | ||
}, | ||
}; | ||
}, | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { noDuplicateIdsRule } from '../rules/no-duplicate-ids'; | ||
|
||
import { ruleTester } from './utils/ruleTester.testutils'; | ||
|
||
ruleTester.run('no-duplicate-ids', noDuplicateIdsRule, { | ||
valid: [ | ||
{ | ||
code: `<div data-lgid={lgIds.root}><div data-lgid={lgIds.nested} /></div>`, | ||
languageOptions: { | ||
parserOptions: { | ||
ecmaFeatures: { | ||
jsx: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: `<div data-lgid={lgIds.root}><div data-lgid={lgIds.root} /></div>`, | ||
languageOptions: { | ||
parserOptions: { | ||
ecmaFeatures: { | ||
jsx: true, | ||
}, | ||
}, | ||
}, | ||
errors: [ | ||
{ | ||
messageId: 'issue:noDuplicateIds', | ||
}, | ||
], | ||
}, | ||
], | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the reasons we pass the root to label and description is because
<Label>
and<Description>
already generate their own specific lgids internally.leafygreen-ui/packages/typography/src/Label/Label.tsx
Lines 38 to 39 in 9b2d156
So if you pass
lgids.root
, the root islg-checkbox
and the id generated in<Label>
will belg-checkbox-label
.However, if we pass
lgIds.label
, that will passlg-checkbox-label
to<Label>
, which will generatelg-checkbox-label-label
.The first approach allows us to avoid duplication in the id string
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh I see. Wouldn't it make more sense (and in alignment with the style-guide / BEM-like) for the
Label
component to have its owngetLgIds
function? 🤔 I mean,Label
is not a "child element" of some "typography block".I've pushed a suggestion to work around this in the simplest possible way I could imagine.
leafygreen-ui/packages/typography/src/Description/Description.tsx
Lines 36 to 41 in 148ee52
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a good point. If we take this approach, we'll probably have to update some of our tests. I want to look into this a little deeper. Is this currently blocking you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I noticed this PR #3183 was merged in last week and it looks like some of those changes are duplicated in this PR. Where the changes in #3183 the ones that were blocking you?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I remember, the changes in this PR are not blocking us.
It was indeed stacked on the #3183 branch and I've force-pushed a rebase 👍
Feel free to close this PR if this is not the direction you want to go 👍
I was just pretty sure I found a bug with those duplications 🙂