From 1c3dd97e5a7da813023de1e6d584008c59efd7fd Mon Sep 17 00:00:00 2001 From: logonoff Date: Thu, 19 Dec 2024 16:11:18 -0500 Subject: [PATCH] fix: replace react useId with lodash uniqueId (#11351) (#11357) * fix: replace react useId with lodash uniqueId (#11351) * fix: use `GenerateId` instead of lodash.uniqueId --- .../src/components/Card/CardHeader.tsx | 215 +++++++++--------- .../src/components/DataList/DataListCheck.tsx | 29 +-- 2 files changed, 124 insertions(+), 120 deletions(-) diff --git a/packages/react-core/src/components/Card/CardHeader.tsx b/packages/react-core/src/components/Card/CardHeader.tsx index 83308be1e6e..18e61f0ae25 100644 --- a/packages/react-core/src/components/Card/CardHeader.tsx +++ b/packages/react-core/src/components/Card/CardHeader.tsx @@ -9,6 +9,7 @@ import { Button } from '../Button'; import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon'; import { Radio } from '../Radio'; import { Checkbox } from '../Checkbox'; +import { GenerateId } from '../../helpers/GenerateId/GenerateId'; export interface CardHeaderActionsObject { /** Actions of the card header */ @@ -87,122 +88,122 @@ export const CardHeader: React.FunctionComponent = ({ toggleButtonProps, isToggleRightAligned, ...props -}: CardHeaderProps) => { - const uniqueId = React.useId(); - - return ( - - {({ cardId, isClickable, isSelectable, isSelected, isDisabled: isCardDisabled }) => { - const cardHeaderToggle = ( -
-
- ); - - const isClickableOrSelectableOnly = (isClickable && !isSelectable) || (isSelectable && !isClickable); - if (actions?.actions && isClickableOrSelectableOnly) { - // eslint-disable-next-line no-console - console.error( - `Card: ${ - isClickable ? 'Clickable' : 'Selectable' - } only cards should not contain any other actions. If you wish to include additional actions, use a clickable and selectable card.` +}: CardHeaderProps) => ( + + {(randomId) => ( + + {({ cardId, isClickable, isSelectable, isSelected, isDisabled: isCardDisabled }) => { + const cardHeaderToggle = ( +
+
); - } - const isClickableOnlyCard = isClickable && !isSelectable; - if ( - (isClickableOnlyCard || isSelectable) && - !selectableActions?.selectableActionAriaLabel && - !selectableActions?.selectableActionAriaLabelledby - ) { - // eslint-disable-next-line no-console - console.error( - `Card: ${isClickableOnlyCard ? 'Clickable-only cards' : 'Cards with a selectable input'} must have either the selectableActions.selectableActionAriaLabel or selectableActions.selectableActionAriaLabelledby prop passed in order to provide an accessible name to the clickable element.` - ); - } + const isClickableOrSelectableOnly = (isClickable && !isSelectable) || (isSelectable && !isClickable); + if (actions?.actions && isClickableOrSelectableOnly) { + // eslint-disable-next-line no-console + console.error( + `Card: ${ + isClickable ? 'Clickable' : 'Selectable' + } only cards should not contain any other actions. If you wish to include additional actions, use a clickable and selectable card.` + ); + } - const SelectableCardInput = selectableActions?.variant === 'single' ? Radio : Checkbox; - const getSelectableProps = () => ({ - className: css('pf-m-standalone'), - inputClassName: css(selectableActions?.isHidden && 'pf-v6-screen-reader'), - label: <>, - 'aria-label': selectableActions.selectableActionAriaLabel, - 'aria-labelledby': selectableActions.selectableActionAriaLabelledby, - id: selectableActions.selectableActionId ?? `card-selectable-${uniqueId}`, - name: selectableActions.name, - isDisabled: isCardDisabled, - onChange: selectableActions.onChange, - isChecked: selectableActions.isChecked ?? isSelected, - ...selectableActions.selectableActionProps - }); + const isClickableOnlyCard = isClickable && !isSelectable; + if ( + (isClickableOnlyCard || isSelectable) && + !selectableActions?.selectableActionAriaLabel && + !selectableActions?.selectableActionAriaLabelledby + ) { + // eslint-disable-next-line no-console + console.error( + `Card: ${isClickableOnlyCard ? 'Clickable-only cards' : 'Cards with a selectable input'} must have either the selectableActions.selectableActionAriaLabel or selectableActions.selectableActionAriaLabelledby prop passed in order to provide an accessible name to the clickable element.` + ); + } - const isClickableLinkCard = selectableActions?.to !== undefined; - const ClickableCardComponent = isClickableLinkCard ? 'a' : 'button'; - const getClickableProps = () => { - const isDisabledLinkCard = isCardDisabled && isClickableLinkCard; - const baseProps = { - className: css( - 'pf-v6-c-card__clickable-action', - isDisabledLinkCard && styles.modifiers.disabled, - selectableActions?.isHidden && 'pf-v6-screen-reader' - ), - id: selectableActions.selectableActionId, + const SelectableCardInput = selectableActions?.variant === 'single' ? Radio : Checkbox; + const getSelectableProps = () => ({ + className: css('pf-m-standalone'), + inputClassName: css(selectableActions?.isHidden && 'pf-v6-screen-reader'), + label: <>, 'aria-label': selectableActions.selectableActionAriaLabel, 'aria-labelledby': selectableActions.selectableActionAriaLabelledby, + id: selectableActions.selectableActionId ?? `card-selectable-${randomId}`, + name: selectableActions.name, + isDisabled: isCardDisabled, + onChange: selectableActions.onChange, + isChecked: selectableActions.isChecked ?? isSelected, ...selectableActions.selectableActionProps - }; + }); - if (isClickableLinkCard) { - return { - ...baseProps, - href: selectableActions.to, - ...(isCardDisabled && { tabIndex: -1, 'aria-disabled': true }), - ...(selectableActions.isExternalLink && { target: '_blank' }) + const isClickableLinkCard = selectableActions?.to !== undefined; + const ClickableCardComponent = isClickableLinkCard ? 'a' : 'button'; + const getClickableProps = () => { + const isDisabledLinkCard = isCardDisabled && isClickableLinkCard; + const baseProps = { + className: css( + 'pf-v6-c-card__clickable-action', + isDisabledLinkCard && styles.modifiers.disabled, + selectableActions?.isHidden && 'pf-v6-screen-reader' + ), + id: selectableActions.selectableActionId, + 'aria-label': selectableActions.selectableActionAriaLabel, + 'aria-labelledby': selectableActions.selectableActionAriaLabelledby, + ...selectableActions.selectableActionProps }; - } - return { ...baseProps, type: 'button', disabled: isCardDisabled, onClick: selectableActions.onClickAction }; - }; + if (isClickableLinkCard) { + return { + ...baseProps, + href: selectableActions.to, + ...(isCardDisabled && { tabIndex: -1, 'aria-disabled': true }), + ...(selectableActions.isExternalLink && { target: '_blank' }) + }; + } - return ( -
- {onExpand && !isToggleRightAligned && cardHeaderToggle} - {(actions || (selectableActions && (isClickable || isSelectable))) && ( - - {actions?.actions} - {selectableActions && (isClickable || isSelectable) && ( - - {isSelectable && } - {isClickableOnlyCard && } - - )} - - )} - {children && {children}} - {onExpand && isToggleRightAligned && cardHeaderToggle} -
- ); - }} -
- ); -}; + return { ...baseProps, type: 'button', disabled: isCardDisabled, onClick: selectableActions.onClickAction }; + }; + + return ( +
+ {onExpand && !isToggleRightAligned && cardHeaderToggle} + {(actions || (selectableActions && (isClickable || isSelectable))) && ( + + {actions?.actions} + {selectableActions && (isClickable || isSelectable) && ( + + {isSelectable && } + {isClickableOnlyCard && } + + )} + + )} + {children && {children}} + {onExpand && isToggleRightAligned && cardHeaderToggle} +
+ ); + }} +
+ )} + +); CardHeader.displayName = 'CardHeader'; diff --git a/packages/react-core/src/components/DataList/DataListCheck.tsx b/packages/react-core/src/components/DataList/DataListCheck.tsx index a16ff40e588..6a19e058aaf 100644 --- a/packages/react-core/src/components/DataList/DataListCheck.tsx +++ b/packages/react-core/src/components/DataList/DataListCheck.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import { css } from '@patternfly/react-styles'; import styles from '@patternfly/react-styles/css/components/DataList/data-list'; import { Checkbox, CheckboxProps } from '../Checkbox'; +import { GenerateId } from '../../helpers/GenerateId/GenerateId'; export interface DataListCheckProps extends Omit { /** Id of the DataList checkbox. */ @@ -46,21 +47,23 @@ export const DataListCheck: React.FunctionComponent = ({ otherControls = false, ...props }: DataListCheckProps) => { - const uniqueId = React.useId(); - const check = (
- + + {(randomId) => ( + + )} +
); return (