Skip to content

Commit

Permalink
Added more OUIA props into Dropdown component (patternfly#4754)
Browse files Browse the repository at this point in the history
* Added more OUIA props into Dropdown component

* Better OUIA default ids for DropdownToggleCheckbox

* getOUIAProps is replaced by useOUIAProps
  • Loading branch information
Dmitrii Misharov authored Sep 22, 2020
1 parent fb697a5 commit 9548ea3
Show file tree
Hide file tree
Showing 12 changed files with 856 additions and 49 deletions.

Large diffs are not rendered by default.

70 changes: 39 additions & 31 deletions packages/react-core/src/components/Dropdown/DropdownItem.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as React from 'react';
import { InternalDropdownItemProps, InternalDropdownItem } from './InternalDropdownItem';
import { DropdownArrowContext } from './dropdownConstants';
import { useOUIAProps, OUIAProps } from '../../helpers';

export interface DropdownItemProps extends InternalDropdownItemProps {
export interface DropdownItemProps extends InternalDropdownItemProps, OUIAProps {
/** Anything which can be rendered as dropdown item */
children?: React.ReactNode;
/** Classes applied to root element of dropdown item */
Expand Down Expand Up @@ -65,35 +66,42 @@ export const DropdownItem: React.FunctionComponent<DropdownItemProps> = ({
autoFocus,
description = null,
styleChildren,
ouiaId,
ouiaSafe,
...props
}: DropdownItemProps) => (
<DropdownArrowContext.Consumer>
{context => (
<InternalDropdownItem
context={context}
role="menuitem"
tabIndex={tabIndex}
className={className}
component={component}
isDisabled={isDisabled}
isPlainText={isPlainText}
isHovered={isHovered}
href={href}
tooltip={tooltip}
tooltipProps={tooltipProps}
listItemClassName={listItemClassName}
onClick={onClick}
additionalChild={additionalChild}
customChild={customChild}
icon={icon}
autoFocus={autoFocus}
styleChildren={styleChildren}
description={description}
{...props}
>
{children}
</InternalDropdownItem>
)}
</DropdownArrowContext.Consumer>
);
}: DropdownItemProps) => {
const ouiaProps = useOUIAProps(DropdownItem.displayName, ouiaId, ouiaSafe);
return (
<DropdownArrowContext.Consumer>
{context => (
<InternalDropdownItem
context={context}
role="menuitem"
tabIndex={tabIndex}
className={className}
component={component}
isDisabled={isDisabled}
isPlainText={isPlainText}
isHovered={isHovered}
href={href}
tooltip={tooltip}
tooltipProps={tooltipProps}
listItemClassName={listItemClassName}
onClick={onClick}
additionalChild={additionalChild}
customChild={customChild}
icon={icon}
autoFocus={autoFocus}
styleChildren={styleChildren}
description={description}
{...ouiaProps}
{...props}
>
{children}
</InternalDropdownItem>
)}
</DropdownArrowContext.Consumer>
);
};

DropdownItem.displayName = 'DropdownItem';
35 changes: 21 additions & 14 deletions packages/react-core/src/components/Dropdown/DropdownSeparator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as React from 'react';
import { DropdownArrowContext } from './dropdownConstants';
import { InternalDropdownItem } from './InternalDropdownItem';
import { Divider, DividerVariant } from '../Divider';
import { useOUIAProps, OUIAProps } from '../../helpers';

export interface SeparatorProps extends React.HTMLProps<HTMLAnchorElement> {
export interface SeparatorProps extends React.HTMLProps<HTMLAnchorElement>, OUIAProps {
/** Classes applied to root element of dropdown item */
className?: string;
/** Click event to pass to InternalDropdownItem */
Expand All @@ -14,18 +15,24 @@ export const DropdownSeparator: React.FunctionComponent<SeparatorProps> = ({
className = '',
// eslint-disable-next-line @typescript-eslint/no-unused-vars
ref, // Types of Ref are different for React.FC vs React.Component
ouiaId,
ouiaSafe,
...props
}: SeparatorProps) => (
<DropdownArrowContext.Consumer>
{context => (
<InternalDropdownItem
{...props}
context={context}
component={<Divider component={DividerVariant.div} />}
className={className}
role="separator"
/>
)}
</DropdownArrowContext.Consumer>
);
}: SeparatorProps) => {
const ouiaProps = useOUIAProps(DropdownSeparator.displayName, ouiaId, ouiaSafe);
return (
<DropdownArrowContext.Consumer>
{context => (
<InternalDropdownItem
{...props}
context={context}
component={<Divider component={DividerVariant.div} />}
className={className}
role="separator"
{...ouiaProps}
/>
)}
</DropdownArrowContext.Consumer>
);
};
DropdownSeparator.displayName = 'DropdownSeparator';
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import { Toggle } from './Toggle';
import styles from '@patternfly/react-styles/css/components/Dropdown/dropdown';
import { DropdownContext } from './dropdownConstants';
import { css } from '@patternfly/react-styles';
import { useOUIAProps, OUIAProps } from '../../helpers';

export interface DropdownToggleProps extends React.HTMLProps<HTMLButtonElement> {
export interface DropdownToggleProps extends React.HTMLProps<HTMLButtonElement>, OUIAProps {
/** HTML ID of dropdown toggle */
id?: string;
/** Anything which can be rendered as dropdown toggle button */
Expand Down Expand Up @@ -65,10 +66,13 @@ export const DropdownToggle: React.FunctionComponent<DropdownToggleProps> = ({
splitButtonItems,
splitButtonVariant = 'checkbox',
'aria-haspopup': ariaHasPopup,
ouiaId,
ouiaSafe,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
ref, // Types of Ref are different for React.FC vs React.Component
...props
}: DropdownToggleProps) => {
const ouiaProps = useOUIAProps(DropdownToggle.displayName, ouiaId, ouiaSafe);
const toggle = (
<DropdownContext.Consumer>
{({ toggleTextClass, toggleIndicatorClass, toggleIconClass }) => (
Expand All @@ -85,6 +89,7 @@ export const DropdownToggle: React.FunctionComponent<DropdownToggleProps> = ({
isPrimary={isPrimary}
onToggle={onToggle}
aria-haspopup={ariaHasPopup}
{...ouiaProps}
{...(splitButtonItems && { isSplitButton: true, 'aria-label': props['aria-label'] || 'Select' })}
>
{icon && <span className={css(toggleIconClass)}>{icon}</span>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import * as React from 'react';
import styles from '@patternfly/react-styles/css/components/Dropdown/dropdown';
import { css } from '@patternfly/react-styles';
import { PickOptional } from '../../helpers/typeUtils';
import { getOUIAProps, OUIAProps, getDefaultOUIAId } from '../../helpers';

export interface DropdownToggleCheckboxProps
extends Omit<React.HTMLProps<HTMLInputElement>, 'type' | 'onChange' | 'disabled' | 'checked'> {
extends Omit<React.HTMLProps<HTMLInputElement>, 'type' | 'onChange' | 'disabled' | 'checked'>,
OUIAProps {
/** Additional classes added to the DropdownToggleCheckbox */
className?: string;
/** Flag to show if the checkbox selection is valid or invalid */
Expand All @@ -25,7 +27,7 @@ export interface DropdownToggleCheckboxProps
'aria-label': string;
}

export class DropdownToggleCheckbox extends React.Component<DropdownToggleCheckboxProps> {
export class DropdownToggleCheckbox extends React.Component<DropdownToggleCheckboxProps, { ouiaStateId: string }> {
static displayName = 'DropdownToggleCheckbox';
static defaultProps: PickOptional<DropdownToggleCheckboxProps> = {
className: '',
Expand All @@ -34,6 +36,13 @@ export class DropdownToggleCheckbox extends React.Component<DropdownToggleCheckb
onChange: () => undefined as any
};

constructor(props: DropdownToggleCheckboxProps) {
super(props);
this.state = {
ouiaStateId: getDefaultOUIAId(DropdownToggleCheckbox.displayName)
};
}

handleChange = (event: React.FormEvent<HTMLInputElement>) => {
this.props.onChange((event.target as HTMLInputElement).checked, event);
};
Expand All @@ -51,7 +60,18 @@ export class DropdownToggleCheckbox extends React.Component<DropdownToggleCheckb

render() {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { className, onChange, isValid, isDisabled, isChecked, checked, children, ...props } = this.props;
const {
className,
onChange,
isValid,
isDisabled,
isChecked,
checked,
children,
ouiaId,
ouiaSafe,
...props
} = this.props;
const text = children && (
<span className={css(styles.dropdownToggleText, className)} aria-hidden="true" id={`${props.id}-text`}>
{children}
Expand All @@ -67,6 +87,11 @@ export class DropdownToggleCheckbox extends React.Component<DropdownToggleCheckb
aria-invalid={!isValid}
disabled={isDisabled}
checked={this.calculateChecked()}
{...getOUIAProps(
DropdownToggleCheckbox.displayName,
ouiaId !== undefined ? ouiaId : this.state.ouiaStateId,
ouiaSafe
)}
/>
{text}
</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ exports[`DropdownToggleCheckbox should match snapshot (auto-generated) 1`] = `
aria-invalid={false}
aria-label="string"
checked={true}
data-ouia-component-id="OUIA-Generated-DropdownToggleCheckbox-1"
data-ouia-component-type="PF4/DropdownToggleCheckbox"
data-ouia-safe={true}
disabled={false}
id="string"
onChange={[Function]}
Expand Down
Loading

0 comments on commit 9548ea3

Please sign in to comment.