diff --git a/packages/react-core/src/components/DatePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap b/packages/react-core/src/components/DatePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap index a7876dbb096..c76fb6110b5 100644 --- a/packages/react-core/src/components/DatePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap +++ b/packages/react-core/src/components/DatePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap @@ -789,4 +789,4 @@ exports[`disabled date picker 1`] = ` -`; +`; \ No newline at end of file diff --git a/packages/react-table/src/components/Table/SortColumn.tsx b/packages/react-table/src/components/Table/SortColumn.tsx index 93f0a16a417..1526a533aee 100644 --- a/packages/react-table/src/components/Table/SortColumn.tsx +++ b/packages/react-table/src/components/Table/SortColumn.tsx @@ -29,6 +29,7 @@ export const SortColumn: React.FunctionComponent = ({ ...props }: SortColumnProps) => { let SortedByIcon; + const [focused, setFocused] = React.useState(false); if (isSortedBy) { SortedByIcon = sortDirection === SortByDirection.asc ? LongArrowAltUpIcon : LongArrowAltDownIcon; } else { @@ -39,10 +40,12 @@ export const SortColumn: React.FunctionComponent = ({ {...props} type={type} className={css(className, styles.tableButton)} - onClick={event => onSort && onSort(event)} + onClick={(event) => onSort && onSort(event)} + onFocus={() => setFocused(true)} + onBlur={() => setFocused(false)} >
- {children} + {children} diff --git a/packages/react-table/src/components/Table/TableText.tsx b/packages/react-table/src/components/Table/TableText.tsx index f00a4e1b2ad..0a967eb72aa 100644 --- a/packages/react-table/src/components/Table/TableText.tsx +++ b/packages/react-table/src/components/Table/TableText.tsx @@ -31,6 +31,8 @@ export interface TableTextProps extends React.HTMLProps { tooltipProps?: Omit; /** callback used to create the tooltip if text is truncated */ onMouseEnter?: (event: any) => void; + /** Determines if the TableText is focused by parent component */ + focused?: boolean; } export const TableText: React.FunctionComponent = ({ @@ -41,10 +43,11 @@ export const TableText: React.FunctionComponent = ({ tooltip: tooltipProp = '', tooltipProps = {}, onMouseEnter: onMouseEnterProp = () => {}, + focused = false, ...props }: TableTextProps) => { const Component: TableTextVariant | 'span' | 'div' = variant; - const textRef = React.createRef(); + const textRef = React.createRef(); const [tooltip, setTooltip] = React.useState(''); const onMouseEnter = (event: any) => { @@ -56,9 +59,17 @@ export const TableText: React.FunctionComponent = ({ onMouseEnterProp(event); }; + const onFocus = (element: HTMLElement) => { + if (element.offsetWidth < element.scrollWidth) { + setTooltip(tooltipProp || element.innerText); + } else { + setTooltip(''); + } + }; + const text = ( } onMouseEnter={onMouseEnter} className={css(className, wrapModifier && styles.modifiers[wrapModifier], styles.tableText)} {...props} @@ -67,6 +78,14 @@ export const TableText: React.FunctionComponent = ({ ); + React.useEffect(() => { + if (focused) { + onFocus(textRef.current); + } else { + setTooltip(''); + } + }, [focused]); + return tooltip !== '' ? ( {text} diff --git a/packages/react-table/src/components/Table/Td.tsx b/packages/react-table/src/components/Table/Td.tsx index c174fd161b4..bd5188287c8 100644 --- a/packages/react-table/src/components/Table/Td.tsx +++ b/packages/react-table/src/components/Table/Td.tsx @@ -105,14 +105,15 @@ const TdBase: React.FunctionComponent = ({ ...props }: TdProps) => { const [showTooltip, setShowTooltip] = React.useState(false); + const [truncated, setTruncated] = React.useState(false); const cellRef = innerRef ? innerRef : React.createRef(); - const onMouseEnter = (event: any) => { if (event.target.offsetWidth < event.target.scrollWidth) { !showTooltip && setShowTooltip(true); } else { showTooltip && setShowTooltip(false); } + onMouseEnterProp(event); }; @@ -255,9 +256,19 @@ const TdBase: React.FunctionComponent = ({ (className && className.includes('pf-c-table__tree-view-title-cell')) || (mergedClassName && mergedClassName.includes('pf-c-table__tree-view-title-cell')); + React.useEffect(() => { + setTruncated( + (cellRef as React.RefObject).current.offsetWidth < + (cellRef as React.RefObject).current.scrollWidth + ); + }, [cellRef]); + const cell = ( setShowTooltip(false)} onMouseEnter={tooltip !== null ? onMouseEnter : onMouseEnterProp} className={css( className, @@ -289,9 +300,14 @@ const TdBase: React.FunctionComponent = ({ const canMakeDefaultTooltip = tooltip === '' ? typeof children === 'string' : true; return tooltip !== null && canMakeDefaultTooltip && showTooltip ? ( - } content={tooltip || (tooltip === '' && children)} isVisible> + <> {cell} - + } + content={tooltip || (tooltip === '' && children)} + isVisible + /> + ) : ( cell ); diff --git a/packages/react-table/src/components/Table/Th.tsx b/packages/react-table/src/components/Table/Th.tsx index ac4e3842b10..c22c7645524 100644 --- a/packages/react-table/src/components/Table/Th.tsx +++ b/packages/react-table/src/components/Table/Th.tsx @@ -80,6 +80,7 @@ const ThBase: React.FunctionComponent = ({ ...props }: ThProps) => { const [showTooltip, setShowTooltip] = React.useState(false); + const [truncated, setTruncated] = React.useState(false); const cellRef = innerRef ? innerRef : React.createRef(); const onMouseEnter = (event: any) => { if (event.target.offsetWidth < event.target.scrollWidth) { @@ -161,8 +162,18 @@ const ThBase: React.FunctionComponent = ({ ...mergedProps } = merged; + React.useEffect(() => { + setTruncated( + (cellRef as React.RefObject).current.offsetWidth < + (cellRef as React.RefObject).current.scrollWidth + ); + }, [cellRef]); + const cell = ( setShowTooltip(false)} data-label={dataLabel} onMouseEnter={tooltip !== null ? onMouseEnter : onMouseEnterProp} scope={component === 'th' && children ? scope : null} @@ -194,9 +205,14 @@ const ThBase: React.FunctionComponent = ({ const canMakeDefaultTooltip = tooltip === '' ? typeof transformedChildren === 'string' : true; return tooltip !== null && canMakeDefaultTooltip && showTooltip ? ( - } content={tooltip || (tooltip === '' && children)} isVisible> + <> {cell} - + } + content={tooltip || (tooltip === '' && children)} + isVisible + /> + ) : ( cell ); diff --git a/packages/react-table/src/components/Table/examples/Table.md b/packages/react-table/src/components/Table/examples/Table.md index 589c4129f73..4e923b754a8 100644 --- a/packages/react-table/src/components/Table/examples/Table.md +++ b/packages/react-table/src/components/Table/examples/Table.md @@ -233,6 +233,8 @@ export type OnExpand = ( ### Modifiers with table text +If the "wrapModifier" property is set to "truncate", it's needed to ensure that the corresponding tooltip can be opened using both keyboard and screen reader. Since this particular Td element is generic and doesn't have any predefined decorators, the focus management required to trigger the tooltip needs to be handled manually by defining and manipulating the requisite props. + ```ts file="TableTextModifiers.tsx" ``` diff --git a/packages/react-table/src/components/Table/examples/TableTextModifiers.tsx b/packages/react-table/src/components/Table/examples/TableTextModifiers.tsx index 50eb6da30ed..974ed99931d 100644 --- a/packages/react-table/src/components/Table/examples/TableTextModifiers.tsx +++ b/packages/react-table/src/components/Table/examples/TableTextModifiers.tsx @@ -9,25 +9,36 @@ const columnNames = { wrap: 'Wrapping table header text. This th text will wrap instead of truncate.' }; -export const TableTextModifiers: React.FunctionComponent = () => ( - - - - - - - - - - - - - -
{columnNames.truncate}{columnNames.wrap}
- This text will truncate instead of wrap. - - - This is a link that needs to be on one line and fully readable. - -
-); +export const TableTextModifiers: React.FunctionComponent = () => { + const [focused, setFocused] = React.useState(false); + + return ( + + + + + + + + + + + + + +
{columnNames.truncate}{columnNames.wrap}
setFocused(true)} + onBlur={() => setFocused(false)} + tabIndex={0} + dataLabel={columnNames.truncate} + > + + This text will truncate instead of wrap. + + + + This is a link that needs to be on one line and fully readable. + +
+ ); +}; diff --git a/packages/react-table/src/deprecated/components/Table/__tests__/__snapshots__/Table.test.tsx.snap b/packages/react-table/src/deprecated/components/Table/__tests__/__snapshots__/Table.test.tsx.snap index e9900d038ac..8d48d13d144 100644 --- a/packages/react-table/src/deprecated/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +++ b/packages/react-table/src/deprecated/components/Table/__tests__/__snapshots__/Table.test.tsx.snap @@ -25,6 +25,7 @@ exports[`Table Actions table 1`] = ` data-key="0" data-label="Header cell" scope="col" + tabindex="-1" >