diff --git a/src/components/ActionTooltip/ActionTooltip.tsx b/src/components/ActionTooltip/ActionTooltip.tsx index d53291bf1c..29f8ec2cbb 100644 --- a/src/components/ActionTooltip/ActionTooltip.tsx +++ b/src/components/ActionTooltip/ActionTooltip.tsx @@ -13,7 +13,7 @@ const b = block('action-tooltip'); export interface ActionTooltipProps extends Pick< TooltipProps, - 'children' | 'disabled' | 'placement' | 'openDelay' | 'closeDelay' | 'className' + 'children' | 'disabled' | 'placement' | 'openDelay' | 'closeDelay' | 'className' | 'qa' > { title: string; hotkey?: HotkeyProps['value']; diff --git a/src/components/Alert/Alert.tsx b/src/components/Alert/Alert.tsx index dad0942f33..8e66b3c0ad 100644 --- a/src/components/Alert/Alert.tsx +++ b/src/components/Alert/Alert.tsx @@ -25,6 +25,7 @@ export const Alert = (props: AlertProps) => { style, onClose, align, + qa, } = props; const icon = props.icon || ; @@ -42,6 +43,7 @@ export const Alert = (props: AlertProps) => { className={bAlert({corners}, spacing({py: 4, px: 5}, className))} theme={theme} view={view} + qa={qa} > {icon} diff --git a/src/components/Alert/README.md b/src/components/Alert/README.md index 7a24789571..c6f83df6c4 100644 --- a/src/components/Alert/README.md +++ b/src/components/Alert/README.md @@ -235,3 +235,4 @@ LANDING_BLOCK--> | style | HTML style attribute | `React.CSSProperties` | | | className | Name of alert class | `string` | | | icon | Override default icon | `React.ReactNode` | | +| qa | HTML `data-qa` attribute, used in tests. | `string` | | diff --git a/src/components/Alert/types.ts b/src/components/Alert/types.ts index 237928b844..f4bdc3a4e8 100644 --- a/src/components/Alert/types.ts +++ b/src/components/Alert/types.ts @@ -1,5 +1,7 @@ import type React from 'react'; +import type {QAProps} from '../types'; + export type AlertTheme = | 'normal' | 'info' @@ -11,7 +13,7 @@ export type AlertTheme = export type AlertView = 'filled' | 'outlined'; export type AlertCorners = 'rounded' | 'square'; -export interface AlertProps { +export interface AlertProps extends QAProps { title?: React.ReactNode; message?: React.ReactNode; theme?: AlertTheme; diff --git a/src/components/ArrowToggle/ArrowToggle.tsx b/src/components/ArrowToggle/ArrowToggle.tsx index aaf5b053a5..a13bb4cff1 100644 --- a/src/components/ArrowToggle/ArrowToggle.tsx +++ b/src/components/ArrowToggle/ArrowToggle.tsx @@ -3,11 +3,12 @@ import React from 'react'; import {ChevronDown} from '@gravity-ui/icons'; import {Icon} from '../Icon'; +import type {QAProps} from '../types'; import {block} from '../utils/cn'; import './ArrowToggle.scss'; -export interface ArrowToggleProps { +export interface ArrowToggleProps extends QAProps { size?: number; direction?: 'top' | 'left' | 'bottom' | 'right'; className?: string; @@ -15,9 +16,13 @@ export interface ArrowToggleProps { const b = block('arrow-toggle'); -export function ArrowToggle({size = 16, direction = 'bottom', className}: ArrowToggleProps) { +export function ArrowToggle({size = 16, direction = 'bottom', className, qa}: ArrowToggleProps) { return ( - + ); diff --git a/src/components/ArrowToggle/README.md b/src/components/ArrowToggle/README.md index d5e7ef3e3b..91356d54e7 100644 --- a/src/components/ArrowToggle/README.md +++ b/src/components/ArrowToggle/README.md @@ -120,3 +120,4 @@ return ( | className | HTML `class` attribute | `string` | | | direction | Used to set the direction of arrowToggle | `string` | `"bottom"` | | size | Size of arrowToggle in px | `number` | `16` | +| qa | HTML `data-qa` attribute, used in tests | `string` | | diff --git a/src/components/Breadcrumbs/Breadcrumbs.tsx b/src/components/Breadcrumbs/Breadcrumbs.tsx index cea8f51a3a..4ba7a894aa 100644 --- a/src/components/Breadcrumbs/Breadcrumbs.tsx +++ b/src/components/Breadcrumbs/Breadcrumbs.tsx @@ -3,6 +3,7 @@ import React from 'react'; import _throttle from 'lodash/throttle'; import type {PopupPlacement} from '../Popup'; +import type {QAProps} from '../types'; import {block} from '../utils/cn'; import {BreadcrumbsItem as Item} from './BreadcrumbsItem'; @@ -19,7 +20,7 @@ export interface BreadcrumbsItem { title?: string; } -export interface BreadcrumbsProps { +export interface BreadcrumbsProps extends QAProps { items: T[]; className?: string; renderRootContent?: (item: T, isCurrent: boolean) => React.ReactNode; @@ -114,13 +115,13 @@ export class Breadcrumbs extends Re } render() { - const {className} = this.props; + const {className, qa} = this.props; const {calculated} = this.state; const rootItem = this.renderRootItem(); return ( -
+
{rootItem} {this.renderMoreItem()} diff --git a/src/components/Breadcrumbs/README.md b/src/components/Breadcrumbs/README.md index b4b43931b4..5e3623a0d3 100644 --- a/src/components/Breadcrumbs/README.md +++ b/src/components/Breadcrumbs/README.md @@ -343,6 +343,7 @@ return ( | firstDisplayedItemsCount | Number of items to display before item collapse control | `FirstDisplayedItemsCount.Zero \| FirstDisplayedItemsCount.One` | | | lastDisplayedItemsCount | Number of items to display after item collapse control | `LastDisplayedItemsCount.One \| LastDisplayedItemsCount.Two` | | | popupStyle | Style of collapsed item popup | `"staircase" \| undefined` | | +| qa | HTML `data-qa` attribute, used in tests | `string` | | ### BreadcrumbsItem diff --git a/src/components/Card/README.md b/src/components/Card/README.md index f8ef7f14aa..84b092304d 100644 --- a/src/components/Card/README.md +++ b/src/components/Card/README.md @@ -144,3 +144,4 @@ LANDING_BLOCK--> | onClick | Card click handler. Available for `type`: `"selection"`, `"action"` | `Function` | | | selected | Selected card. Available for type: `"selection"` | `Boolean` | | | disabled | Disabled card. Available for type: `"selection"`, `"action"` | `Boolean` | | +| qa | HTML `data-qa` attribute, used in tests | `string` | | diff --git a/src/components/Label/Label.tsx b/src/components/Label/Label.tsx index d99fbdd2d6..57270addaa 100644 --- a/src/components/Label/Label.tsx +++ b/src/components/Label/Label.tsx @@ -8,6 +8,7 @@ import type {ButtonProps, ButtonSize} from '../Button'; import {ClipboardIcon} from '../ClipboardIcon'; import {CopyToClipboard, CopyToClipboardStatus} from '../CopyToClipboard'; import {Icon} from '../Icon'; +import type {QAProps} from '../types'; import {block} from '../utils/cn'; import './Label.scss'; @@ -30,7 +31,7 @@ const commonActionButtonProps: ButtonProps = { }), }; -interface LabelOwnProps { +interface LabelOwnProps extends QAProps { /** Label icon (at left) */ icon?: React.ReactNode; /** Disabled state */ @@ -85,6 +86,7 @@ export const Label = React.forwardRef(function Label value, onCopy, onClick, + qa, } = props; const actionButtonRef = React.useRef(null); @@ -189,6 +191,7 @@ export const Label = React.forwardRef(function Label }, className, )} + data-qa={qa} > {leftIcon} {content} diff --git a/src/components/Label/README.md b/src/components/Label/README.md index 496d9866d4..00e3cf7390 100644 --- a/src/components/Label/README.md +++ b/src/components/Label/README.md @@ -268,3 +268,4 @@ LANDING_BLOCK--> | theme | Label theme | `string` | `"normal"` | | type | Label type | `"default"` `"copy"` `"close"` | `"default"` | | value | Label value (displayed as "children : value") | `string` | | +| qa | HTML `data-qa` attribute, used in tests | `string` | | diff --git a/src/components/Loader/Loader.tsx b/src/components/Loader/Loader.tsx index b19209b5aa..7b97cb723e 100644 --- a/src/components/Loader/Loader.tsx +++ b/src/components/Loader/Loader.tsx @@ -1,5 +1,6 @@ import React from 'react'; +import type {QAProps} from '../types'; import {block} from '../utils/cn'; import './Loader.scss'; @@ -8,14 +9,14 @@ const b = block('loader'); export type LoaderSize = 's' | 'm' | 'l'; -export interface LoaderProps { +export interface LoaderProps extends QAProps { className?: string; size?: LoaderSize; } -export function Loader({size = 's', className}: LoaderProps) { +export function Loader({size = 's', className, qa}: LoaderProps) { return ( -
+
diff --git a/src/components/Pagination/Pagination.tsx b/src/components/Pagination/Pagination.tsx index 8d4464fb4e..e93b3a6b05 100644 --- a/src/components/Pagination/Pagination.tsx +++ b/src/components/Pagination/Pagination.tsx @@ -28,6 +28,7 @@ export const Pagination = ({ showPages = true, showInput = false, className, + qa, }: PaginationProps) => { const [mobile] = useMobile(); @@ -92,7 +93,7 @@ export const Pagination = ({ .filter(Boolean); return ( -
+
{pagination} {showInput && ( {textView} diff --git a/src/components/Persona/README.md b/src/components/Persona/README.md index 301da35b4e..498dfd31fb 100644 --- a/src/components/Persona/README.md +++ b/src/components/Persona/README.md @@ -117,3 +117,4 @@ LANDING_BLOCK--> | onClose | Handles click on button with cross `(text: string) => void` | `Function` | | | onClick | Handles click on component itself `(text: string) => void` | `Function` | | | className | Custom CSS class for root element | `string` | | +| qa | HTML `data-qa` attribute, used in tests | `string` | | diff --git a/src/components/Persona/types.ts b/src/components/Persona/types.ts index 62c17ef772..9210146ca1 100644 --- a/src/components/Persona/types.ts +++ b/src/components/Persona/types.ts @@ -1,5 +1,7 @@ import type React from 'react'; +import type {QAProps} from '../types'; + export type PersonaText = string | {value: string; content: React.ReactNode}; export type PersonaProps = { @@ -25,4 +27,4 @@ export type PersonaProps = { /** Custom CSS class for root element */ className?: string; style?: React.CSSProperties; -}; +} & QAProps; diff --git a/src/components/PersonaWrap/PersonaWrap.tsx b/src/components/PersonaWrap/PersonaWrap.tsx index 69ae4dada8..0dea4998c4 100644 --- a/src/components/PersonaWrap/PersonaWrap.tsx +++ b/src/components/PersonaWrap/PersonaWrap.tsx @@ -3,13 +3,14 @@ import React from 'react'; import {Xmark} from '@gravity-ui/icons'; import {Icon} from '../Icon'; +import type {QAProps} from '../types'; import {block} from '../utils/cn'; import './PersonaWrap.scss'; const b = block('persona'); -export interface PersonaWrapProps { +export interface PersonaWrapProps extends QAProps { avatar: React.ReactNode; children?: React.ReactNode; isEmpty?: boolean; @@ -33,6 +34,7 @@ export function PersonaWrap({ children, style, closeButtonAriaAttributes, + qa, }: PersonaWrapProps) { const clickable = Boolean(onClick); const closeable = Boolean(onClose); @@ -42,6 +44,7 @@ export function PersonaWrap({
{avatar &&
{avatar}
} diff --git a/src/components/Progress/Progress.tsx b/src/components/Progress/Progress.tsx index dab93b8543..6eee3a163e 100644 --- a/src/components/Progress/Progress.tsx +++ b/src/components/Progress/Progress.tsx @@ -2,6 +2,7 @@ import React from 'react'; import _sumBy from 'lodash/sumBy'; +import type {QAProps} from '../types'; import {block} from '../utils/cn'; import './Progress.scss'; @@ -27,7 +28,7 @@ export interface ProgressColorStops { stop: number; } -interface ProgressGeneralProps { +interface ProgressGeneralProps extends QAProps { /** ClassName of element */ className?: string; } @@ -91,10 +92,10 @@ export class Progress extends React.Component { } render() { - const {size, className} = this.props; + const {size, className, qa} = this.props; return ( -
+
{this.renderText()} {this.renderContent()}
diff --git a/src/components/Progress/README.md b/src/components/Progress/README.md index 4c986649f5..ab525a7c49 100644 --- a/src/components/Progress/README.md +++ b/src/components/Progress/README.md @@ -255,3 +255,4 @@ LANDING_BLOCK--> | title | HTML `title` attribute | `string` | | | theme | Sets the stack element color | `string` | `"default"` | | value | Current progress value. The available range is from 0 to 100. Using the `stack` property value is optional and is used as maxValue. | `number` | | +| qa | HTML `data-qa` attribute, used in tests | `string` | | diff --git a/src/components/Skeleton/README.md b/src/components/Skeleton/README.md index 26d93fc03d..b861d20ba5 100644 --- a/src/components/Skeleton/README.md +++ b/src/components/Skeleton/README.md @@ -12,7 +12,8 @@ The Skeleton component displays a placeholder preview of your content before the ## Properties -| Name | Description | Type | Default | -| :-------- | :------------------------------------- | :-------------------: | :-----: | -| style | Custom CSS properties for root element | `React.CSSProperties` | | -| className | Custom CSS class for root element | `string` | | +| Name | Description | Type | Default | +| :-------- | :-------------------------------------- | :-------------------: | :-----: | +| style | Custom CSS properties for root element | `React.CSSProperties` | | +| className | Custom CSS class for root element | `string` | | +| qa | HTML `data-qa` attribute, used in tests | `string` | | diff --git a/src/components/Skeleton/Skeleton.tsx b/src/components/Skeleton/Skeleton.tsx index 172dc7d0c2..1f5eb0f168 100644 --- a/src/components/Skeleton/Skeleton.tsx +++ b/src/components/Skeleton/Skeleton.tsx @@ -1,5 +1,6 @@ import React from 'react'; +import type {QAProps} from '../types'; import {block} from '../utils/cn'; import './Skeleton.scss'; @@ -7,8 +8,9 @@ import './Skeleton.scss'; const b = block('skeleton'); export interface SkeletonProps - extends Pick, 'className' | 'style'> {} + extends Pick, 'className' | 'style'>, + QAProps {} -export function Skeleton({className, style}: SkeletonProps) { - return
; +export function Skeleton({className, style, qa}: SkeletonProps) { + return
; } diff --git a/src/components/Text/README.md b/src/components/Text/README.md index 42893799ac..db2bab04c9 100644 --- a/src/components/Text/README.md +++ b/src/components/Text/README.md @@ -175,3 +175,4 @@ LANDING_BLOCK--> | wordBreak | The word-break css property | `"break-all"` | | | color | Color of the text | `string` (see values in "Color" section) | | | ref | | `any` | | +| qa | HTML `data-qa` attribute, used in tests | `string` | | diff --git a/src/components/Text/Text.tsx b/src/components/Text/Text.tsx index b07af64c38..dbe290058a 100644 --- a/src/components/Text/Text.tsx +++ b/src/components/Text/Text.tsx @@ -1,11 +1,13 @@ import React from 'react'; +import type {QAProps} from '../types'; + import {colorText} from './colorText/colorText'; import type {ColorTextBaseProps} from './colorText/colorText'; import {text} from './text/text'; import type {TextBaseProps} from './text/text'; -export interface TextProps extends TextBaseProps, ColorTextBaseProps { +export interface TextProps extends TextBaseProps, ColorTextBaseProps, QAProps { /** * Ability to override default html tag */ @@ -57,6 +59,7 @@ export const Text = React.forwardRef( color, whiteSpace, wordBreak, + qa, ...rest }: TextPropsWithoutRef, ref?: TextRef, @@ -70,6 +73,7 @@ export const Text = React.forwardRef( {variant, ellipsis, whiteSpace, wordBreak}, color ? colorText({color}, className) : className, )} + data-qa={qa} {...rest} > {children} diff --git a/src/components/Tooltip/README.md b/src/components/Tooltip/README.md index 5adc632eb2..563463204a 100644 --- a/src/components/Tooltip/README.md +++ b/src/components/Tooltip/README.md @@ -26,3 +26,4 @@ import {Tooltip} from '@gravity-ui/uikit'; | closeDelay | Number of ms to delay hiding the `Tooltip` after the hover ends | `number` | `0` | | openDelay | Number of ms to delay showing the `Tooltip` after the hover begins | `number` | `250` | | placement | `Tooltip` position relative to its anchor | [`PopupPlacement`](../Popup/README.md#placement) | | +| qa | HTML `data-qa` attribute, used in tests | `string` | | diff --git a/src/components/Tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx index 5ad59a95be..ce62e2504b 100644 --- a/src/components/Tooltip/Tooltip.tsx +++ b/src/components/Tooltip/Tooltip.tsx @@ -5,12 +5,12 @@ import {useForkRef} from '../../hooks'; import {useBoolean} from '../../hooks/private'; import {Popup} from '../Popup'; import type {PopupPlacement} from '../Popup'; -import type {DOMProps} from '../types'; +import type {DOMProps, QAProps} from '../types'; import {block} from '../utils/cn'; import './Tooltip.scss'; -export interface TooltipProps extends DOMProps, TooltipDelayProps { +export interface TooltipProps extends QAProps, DOMProps, TooltipDelayProps { id?: string; disabled?: boolean; content?: React.ReactNode; @@ -29,7 +29,7 @@ const b = block('tooltip'); const DEFAULT_PLACEMENT: PopupPlacement = ['bottom', 'top']; export const Tooltip = (props: TooltipProps) => { - const {children, content, disabled, placement = DEFAULT_PLACEMENT} = props; + const {children, content, disabled, placement = DEFAULT_PLACEMENT, qa} = props; const [anchorElement, setAnchorElement] = React.useState(null); const tooltipVisible = useTooltipVisible(anchorElement, props); @@ -47,6 +47,7 @@ export const Tooltip = (props: TooltipProps) => { disableEscapeKeyDown disableOutsideClick disableLayer + qa={qa} >
{content}
diff --git a/src/components/User/README.md b/src/components/User/README.md index 9d7b830100..eb23d1f231 100644 --- a/src/components/User/README.md +++ b/src/components/User/README.md @@ -11,3 +11,4 @@ Display user avatar and his brief info. | name | `string` | | | User name (first line of info) | | description | `string` | | | User additional data (second line of info) | | size | `UserAvatarSize` | | 'm' | Component size. Supported values is: `xs`, `s`, `m`, `l`, `xl`. With a smallest size user info is not rendered. | +| qa | `string` | | | HTML `data-qa` attribute, used in tests | diff --git a/src/components/User/User.tsx b/src/components/User/User.tsx index ed51d17af2..c1be92ce4e 100644 --- a/src/components/User/User.tsx +++ b/src/components/User/User.tsx @@ -2,13 +2,14 @@ import React from 'react'; import {UserAvatar} from '../UserAvatar'; import type {UserAvatarSize} from '../UserAvatar'; +import type {QAProps} from '../types'; import {block} from '../utils/cn'; import './User.scss'; const b = block('user'); -export interface UserProps { +export interface UserProps extends QAProps { name?: string; description?: string; imgUrl?: string; @@ -16,11 +17,11 @@ export interface UserProps { className?: string; } -export function User({name, description, imgUrl, size = 'm', className}: UserProps) { +export function User({name, description, imgUrl, size = 'm', className, qa}: UserProps) { const compact = size === 'xs'; return ( -
+
{imgUrl && } {(name || description) && (
diff --git a/src/components/UserAvatar/README.md b/src/components/UserAvatar/README.md index 17361b72f9..8fac13d836 100644 --- a/src/components/UserAvatar/README.md +++ b/src/components/UserAvatar/README.md @@ -14,3 +14,4 @@ Component for displaying user avatar. | title | `string` | | | Tooltip text on hover | | className | `string` | | | Class name | | loading | `eager \| lazy` | | | The loading attribute specifies whether a browser should load an image immediately or to defer loading. | +| qa | `string` | | | HTML `data-qa` attribute, used in tests | diff --git a/src/components/UserAvatar/UserAvatar.tsx b/src/components/UserAvatar/UserAvatar.tsx index 66ad3303f9..a73f83325a 100644 --- a/src/components/UserAvatar/UserAvatar.tsx +++ b/src/components/UserAvatar/UserAvatar.tsx @@ -1,5 +1,6 @@ import React from 'react'; +import type {QAProps} from '../types'; import {block} from '../utils/cn'; import {SIZES} from './constants'; @@ -7,7 +8,7 @@ import type {UserAvatarSize} from './types'; import './UserAvatar.scss'; -export interface UserAvatarProps { +export interface UserAvatarProps extends QAProps { imgUrl?: string; fallbackImgUrl?: string; size?: UserAvatarSize; @@ -24,7 +25,7 @@ const b = block('user-avatar'); export const UserAvatar = React.forwardRef( ( - {imgUrl, fallbackImgUrl, size = 'm', srcSet, sizes, title, className, loading, onClick}, + {imgUrl, fallbackImgUrl, size = 'm', srcSet, sizes, title, className, loading, onClick, qa}, ref, ) => { const [isErrored, setIsErrored] = React.useState(false); @@ -41,7 +42,13 @@ export const UserAvatar = React.forwardRef( return ( // FIXME OnClick deprecated, will be deleted // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions -
+
{ +export interface ColProps extends MediaPartial, QAProps { className?: string; style?: React.CSSProperties; children?: React.ReactNode; @@ -39,7 +40,7 @@ export interface ColProps extends MediaPartial { * --- * Storybook - https://preview.gravity-ui.com/uikit/?path=/docs/layout--playground#col */ -export const Col = ({children, style, className, ...media}: ColProps) => { +export const Col = ({children, style, className, qa, ...media}: ColProps) => { const mods = Object.entries(media).reduce>((acc, [mod, modSize]) => { acc[`s-${mod}`] = makeCssMod(modSize); @@ -47,7 +48,7 @@ export const Col = ({children, style, className, ...media}: ColProps) => { }, {}); return ( -
+
{children}
); diff --git a/src/components/layout/Container/Container.tsx b/src/components/layout/Container/Container.tsx index 5975e42538..c0eb580bc5 100644 --- a/src/components/layout/Container/Container.tsx +++ b/src/components/layout/Container/Container.tsx @@ -1,6 +1,7 @@ /* eslint-disable valid-jsdoc */ import React from 'react'; +import type {QAProps} from '../../types'; import {block} from '../../utils/cn'; import {sp} from '../spacing/spacing'; import type {MediaPartial, MediaType, Space} from '../types'; @@ -12,7 +13,7 @@ import './Container.scss'; const b = block('container'); -export interface ContainerProps { +export interface ContainerProps extends QAProps { style?: React.CSSProperties; /** * Use function to define different classes in different media queries @@ -68,6 +69,7 @@ export const Container = ({ maxWidth, gutters, spaceRow, + qa, }: ContainerProps) => { const {getClosestMediaProps, containerThemeProps} = useContainerThemeProps(); @@ -100,6 +102,7 @@ export const Container = ({ className, ), )} + data-qa={qa} > {children} diff --git a/src/components/layout/Row/Row.tsx b/src/components/layout/Row/Row.tsx index 2596977344..4ebac152f6 100644 --- a/src/components/layout/Row/Row.tsx +++ b/src/components/layout/Row/Row.tsx @@ -1,6 +1,7 @@ /* eslint-disable valid-jsdoc */ import React from 'react'; +import type {QAProps} from '../../types'; import {block} from '../../utils/cn'; import {useLayoutContext} from '../hooks/useLayoutContext'; import type {MediaPartial, Space} from '../types'; @@ -10,7 +11,7 @@ import './Row.scss'; const b = block('row'); -export interface RowProps { +export interface RowProps extends QAProps { style?: React.CSSProperties; /** * Vertical and horizontal `space` between children `` components. @@ -40,7 +41,7 @@ export interface RowProps { * --- * Storybook - https://preview.gravity-ui.com/uikit/?path=/docs/layout--playground#row */ -export const Row = ({children, style, className, space, spaceRow}: RowProps) => { +export const Row = ({children, style, className, space, spaceRow, qa}: RowProps) => { const {getClosestMediaProps} = useLayoutContext(); let s: string | undefined; @@ -76,6 +77,7 @@ export const Row = ({children, style, className, space, spaceRow}: RowProps) => }, className, )} + data-qa={qa} > {children}