From 13ce14ec873aeb956cefcb33bad5e06fa5df9d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Pet=C5=99=C3=ADk?= Date: Tue, 28 Feb 2023 16:11:16 +0100 Subject: [PATCH 1/5] fix(Table) TableText tooltips not triggered via keyboard --- .../src/components/Table/SortColumn.tsx | 7 ++++-- .../src/components/Table/TableText.tsx | 23 +++++++++++++++++-- .../react-table/src/components/Table/Td.tsx | 22 +++++++++++++++--- .../react-table/src/components/Table/Th.tsx | 23 +++++++++++++++++-- .../components/Table/HeaderCell.tsx | 1 + 5 files changed, 67 insertions(+), 9 deletions(-) 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..d68dcda4538 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; + + 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..71d31b7348c 100644 --- a/packages/react-table/src/components/Table/Th.tsx +++ b/packages/react-table/src/components/Table/Th.tsx @@ -51,6 +51,8 @@ export interface ThProps stickyRightOffset?: string; /** Indicates the is part of a subheader of a nested header */ isSubheader?: boolean; + + focusable?: boolean; } const ThBase: React.FunctionComponent = ({ @@ -77,9 +79,11 @@ const ThBase: React.FunctionComponent = ({ stickyLeftOffset, stickyRightOffset, isSubheader = false, + focusable = true, ...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 +165,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 +208,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/deprecated/components/Table/HeaderCell.tsx b/packages/react-table/src/deprecated/components/Table/HeaderCell.tsx index 1bc946f35a2..26dcb5384e3 100644 --- a/packages/react-table/src/deprecated/components/Table/HeaderCell.tsx +++ b/packages/react-table/src/deprecated/components/Table/HeaderCell.tsx @@ -33,6 +33,7 @@ export const HeaderCell: React.FunctionComponent = ({ scope={scope} tooltip={tooltip} onMouseEnter={onMouseEnter} + focusable={false} textCenter={textCenter} component={component} className={className} From 2ef241eaa42995534e913e0f5948f75afd772985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Pet=C5=99=C3=ADk?= Date: Tue, 28 Feb 2023 16:57:35 +0100 Subject: [PATCH 2/5] fix tests --- .../Table/__tests__/__snapshots__/Table.test.tsx.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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..30323eef912 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 @@ -11998,4 +11998,4 @@ exports[`Table simple header 1`] = ` -`; +`; \ No newline at end of file From caf089525f10f2fa75b1987651e59b80350f9b13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Pet=C5=99=C3=ADk?= Date: Thu, 23 Mar 2023 12:05:26 +0100 Subject: [PATCH 3/5] update snapshosts --- .../DatePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 12e7c44bdb9b2787fffd290d62a190cbebb9f727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Pet=C5=99=C3=ADk?= Date: Tue, 18 Apr 2023 16:27:23 +0200 Subject: [PATCH 4/5] edit example --- .../src/components/Table/examples/Table.md | 2 + .../Table/examples/TableTextModifiers.tsx | 55 +- .../__snapshots__/Table.test.tsx.snap | 1147 ++++++++++++++++- 3 files changed, 1181 insertions(+), 23 deletions(-) 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 30323eef912..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" >