mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 03:01:21 -04:00
## Summary Adds support for wrapping elements. | Code | Turns into | |--------|--------| | <img width="764" alt="Screenshot 2025-04-01 at 09 25 09" src="https://github.com/user-attachments/assets/9b5d2743-3b61-4d21-b726-0a0be9539d99" /> | <img width="827" alt="Screenshot 2025-04-01 at 09 25 20" src="https://github.com/user-attachments/assets/9879d1cb-e22f-4c80-a666-001b273d6d7d" /> | <img width="744" alt="Screenshot 2025-04-01 at 09 25 54" src="https://github.com/user-attachments/assets/c4320ff8-baa2-4fcc-9b3c-f7ab86c1cb23" /> | <img width="838" alt="Screenshot 2025-04-01 at 09 26 07" src="https://github.com/user-attachments/assets/d81a1232-a643-4775-ac83-a1a97bcbc528" /> | **Message** <img width="804" alt="Screenshot 2025-03-25 at 13 59 36" src="https://github.com/user-attachments/assets/8eaa2f54-aee6-4828-b1d5-15d4d2bfb4c0" /> **Exceptions** If elements have a `aria-label`, `aria-labelledby` or `label`, they are not flagged. **Autofix suggestion** - autofixes are translated with `i18n.translate` - if `i18n` is not imported yet, an import statement is added - If a `placeholder` prop is found, it uses that as the `i18n.translate` default message for `aria-label` - If the element has children, it uses the text value of the children as the default message for the `i18n.translate` default message for `aria-label` --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Milosz Marcinkowski <38698566+miloszmarcinkowski@users.noreply.github.com>
77 lines
2.7 KiB
TypeScript
77 lines
2.7 KiB
TypeScript
/*
|
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
* or more contributor license agreements. Licensed under the "Elastic License
|
|
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
|
* Public License v 1"; you may not use this file except in compliance with, at
|
|
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
|
* License v3.0 only", or the "Server Side Public License, v 1".
|
|
*/
|
|
|
|
import * as EsLint from 'eslint';
|
|
import * as TypescriptEsTree from '@typescript-eslint/typescript-estree';
|
|
|
|
export function getPropValues({
|
|
jsxOpeningElement,
|
|
propNames,
|
|
sourceCode,
|
|
}: {
|
|
jsxOpeningElement: TypescriptEsTree.TSESTree.JSXOpeningElement;
|
|
propNames: string[];
|
|
sourceCode: EsLint.SourceCode;
|
|
}): Record<
|
|
(typeof propNames)[number],
|
|
TypescriptEsTree.TSESTree.Literal | TypescriptEsTree.TSESTree.JSXExpression
|
|
> {
|
|
const scope = sourceCode.getScope(jsxOpeningElement as any);
|
|
|
|
if (!scope) return {};
|
|
|
|
// Loop over the input propNames array
|
|
return propNames.reduce((acc, propName) => {
|
|
// Loop over the attributes of the input JSXOpeningElement
|
|
for (const prop of jsxOpeningElement.attributes) {
|
|
if (
|
|
prop.type === TypescriptEsTree.AST_NODE_TYPES.JSXAttribute &&
|
|
propName === prop.name.name &&
|
|
prop.value
|
|
) {
|
|
acc[propName] = prop.value; // can be a string or an function
|
|
}
|
|
|
|
// If the prop is a JSXSpreadAttribute, get the value of the spreaded variable
|
|
if (prop.type === TypescriptEsTree.AST_NODE_TYPES.JSXSpreadAttribute) {
|
|
// If the spreaded variable is an Expression, break
|
|
if (!('argument' in prop) || !('name' in prop.argument)) {
|
|
break;
|
|
}
|
|
|
|
// The name of the variable which is spreaded on the node
|
|
// i.e.
|
|
// const args = { foo: 'bar' };
|
|
// <Foo {...args} />
|
|
const { name } = prop.argument;
|
|
|
|
// the variable definition of the spreaded variable
|
|
const variable = scope.variables.find((v) => v.name === name);
|
|
|
|
// Get the value of the propName from the spreaded variable
|
|
const value =
|
|
variable && variable.defs.length > 0
|
|
? variable.defs[0].node.init?.properties?.find(
|
|
(property: TypescriptEsTree.TSESTree.Property) => {
|
|
if ('value' in property.key && property.key.value) {
|
|
return property.key.value;
|
|
}
|
|
return undefined;
|
|
}
|
|
)
|
|
: undefined;
|
|
|
|
if (value) {
|
|
acc[propName] = value;
|
|
}
|
|
}
|
|
}
|
|
return acc;
|
|
}, {} as Record<(typeof propNames)[number], TypescriptEsTree.TSESTree.Literal | TypescriptEsTree.TSESTree.JSXExpression>);
|
|
}
|