Skip to content

Commit

Permalink
fix(Table): make tooltip prop consistent (#9803)
Browse files Browse the repository at this point in the history
* fix(Table): make tooltip prop consistent

* make tooltip ReactNode and add tooltipProps to Th

* add prop to useEffect

* fix logic for keyboard focus

* fix useeffect
  • Loading branch information
kmcfaul authored Dec 6, 2023
1 parent 046ee9e commit eb9693f
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 26 deletions.
35 changes: 27 additions & 8 deletions packages/react-table/src/components/Table/SelectColumn.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { Tooltip, TooltipProps } from '@patternfly/react-core/dist/esm/components/Tooltip';

export enum RowSelectVariant {
radio = 'radio',
Expand All @@ -11,6 +12,10 @@ export interface SelectColumnProps {
className?: string;
onSelect?: (event: React.FormEvent<HTMLInputElement>) => void;
selectVariant?: RowSelectVariant;
/** text to display on the tooltip */
tooltip?: React.ReactNode;
/** other props to pass to the tooltip */
tooltipProps?: Omit<TooltipProps, 'content'>;
}

export const SelectColumn: React.FunctionComponent<SelectColumnProps> = ({
Expand All @@ -19,13 +24,27 @@ export const SelectColumn: React.FunctionComponent<SelectColumnProps> = ({
className,
onSelect = null as (event: React.FormEvent<HTMLInputElement>) => void,
selectVariant,
tooltip,
tooltipProps,
...props
}: SelectColumnProps) => (
<React.Fragment>
<label>
<input {...props} type={selectVariant} onChange={onSelect} />
</label>
{children}
</React.Fragment>
);
}: SelectColumnProps) => {
const inputRef = React.createRef<HTMLInputElement>();

const content = (
<React.Fragment>
<label>
<input {...props} ref={inputRef} type={selectVariant} onChange={onSelect} />
</label>
{children}
</React.Fragment>
);

return tooltip ? (
<Tooltip triggerRef={inputRef} content={tooltip} {...tooltipProps}>
{content}
</Tooltip>
) : (
content
);
};
SelectColumn.displayName = 'SelectColumn';
16 changes: 15 additions & 1 deletion packages/react-table/src/components/Table/SortColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ArrowsAltVIcon from '@patternfly/react-icons/dist/esm/icons/arrows-alt-v-
import { css } from '@patternfly/react-styles';
import styles from '@patternfly/react-styles/css/components/Table/table';
import { TableText } from './TableText';
import { TooltipProps } from '@patternfly/react-core/dist/esm/components/Tooltip';

export enum SortByDirection {
asc = 'asc',
Expand All @@ -17,6 +18,9 @@ export interface SortColumnProps extends React.ButtonHTMLAttributes<HTMLButtonEl
isSortedBy?: boolean;
onSort?: Function;
sortDirection?: string;
tooltip?: React.ReactNode;
tooltipProps?: Omit<TooltipProps, 'content'>;
tooltipHasDefaultBehavior?: boolean;
}

export const SortColumn: React.FunctionComponent<SortColumnProps> = ({
Expand All @@ -26,6 +30,9 @@ export const SortColumn: React.FunctionComponent<SortColumnProps> = ({
onSort = null,
sortDirection = '',
type = 'button',
tooltip,
tooltipProps,
tooltipHasDefaultBehavior,
...props
}: SortColumnProps) => {
let SortedByIcon;
Expand All @@ -45,7 +52,14 @@ export const SortColumn: React.FunctionComponent<SortColumnProps> = ({
onBlur={() => setFocused(false)}
>
<div className={css(className, styles.tableButtonContent)}>
<TableText focused={focused}>{children}</TableText>
<TableText
tooltip={tooltip}
tooltipProps={tooltipProps}
tooltipHasDefaultBehavior={tooltipHasDefaultBehavior}
focused={focused}
>
{children}
</TableText>
<span className={css(styles.tableSortIndicator)}>
<SortedByIcon />
</span>
Expand Down
28 changes: 19 additions & 9 deletions packages/react-table/src/components/Table/TableText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ export interface TableTextProps extends React.HTMLProps<HTMLDivElement> {
/** Determines which wrapping modifier to apply to the table text */
wrapModifier?: WrapModifier | 'wrap' | 'nowrap' | 'truncate' | 'breakWord' | 'fitContent';
/** text to display on the tooltip */
tooltip?: string;
tooltip?: React.ReactNode;
/** other props to pass to the tooltip */
tooltipProps?: Omit<TooltipProps, 'content'>;
/** 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;
/** Determines if tooltip should have normal visbility behavior. If false, the tooltip will only be shown when children is not entirely visible */
tooltipHasDefaultBehavior?: boolean;
}

export const TableText: React.FunctionComponent<TableTextProps> = ({
Expand All @@ -44,12 +46,13 @@ export const TableText: React.FunctionComponent<TableTextProps> = ({
tooltipProps = {},
onMouseEnter: onMouseEnterProp = () => {},
focused = false,
tooltipHasDefaultBehavior = false,
...props
}: TableTextProps) => {
const Component: TableTextVariant | 'span' | 'div' = variant;
const textRef = React.createRef<HTMLElement>();

const [tooltip, setTooltip] = React.useState('');
const [tooltip, setTooltip] = React.useState(tooltipProp);
const onMouseEnter = (event: any) => {
if (event.target.offsetWidth < event.target.scrollWidth) {
setTooltip(tooltipProp || event.target.innerText);
Expand All @@ -70,7 +73,7 @@ export const TableText: React.FunctionComponent<TableTextProps> = ({
const text = (
<Component
ref={textRef as React.Ref<HTMLDivElement>}
onMouseEnter={onMouseEnter}
onMouseEnter={!tooltipHasDefaultBehavior ? onMouseEnter : undefined}
className={css(className, wrapModifier && styles.modifiers[wrapModifier], styles.tableText)}
{...props}
>
Expand All @@ -79,15 +82,22 @@ export const TableText: React.FunctionComponent<TableTextProps> = ({
);

React.useEffect(() => {
if (focused) {
onFocus(textRef.current);
} else {
setTooltip('');
if (!tooltipHasDefaultBehavior) {
if (focused) {
onFocus(textRef.current);
} else {
setTooltip('');
}
}
}, [focused]);
}, [focused, tooltipHasDefaultBehavior]);

return tooltip !== '' ? (
<Tooltip triggerRef={textRef} content={tooltip} isVisible {...tooltipProps}>
<Tooltip
triggerRef={textRef}
content={tooltip}
{...(!tooltipHasDefaultBehavior && { isVisible: true })}
{...tooltipProps}
>
{text}
</Tooltip>
) : (
Expand Down
3 changes: 3 additions & 0 deletions packages/react-table/src/components/Table/TableTypes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ export interface IExtra extends IExtraData {
rowData?: IRowData;
className?: string;
ariaLabel?: string;
tooltip?: React.ReactNode;
tooltipProps?: Omit<TooltipProps, 'content'>;
tooltipHasDefaultBehavior?: boolean;
}

export type IFormatterValueType = formatterValueType & {
Expand Down
21 changes: 16 additions & 5 deletions packages/react-table/src/components/Table/Th.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { info, sortable, sortableFavorites, selectable, collapsible, cellWidth,
import { ThInfoType, ThSelectType, ThExpandType, ThSortType, formatterValueType } from './base/types';
import { mergeProps } from './base/merge-props';
import { IVisibility } from './utils/decorators/classNames';
import { Tooltip } from '@patternfly/react-core/dist/esm/components/Tooltip/Tooltip';
import { Tooltip, TooltipProps } from '@patternfly/react-core/dist/esm/components/Tooltip';
import { BaseCellProps } from './Table';
import { IFormatterValueType, IColumn } from './TableTypes';
import cssStickyCellMinWidth from '@patternfly/react-tokens/dist/esm/c_table__sticky_cell_MinWidth';
Expand Down Expand Up @@ -34,6 +34,8 @@ export interface ThProps
* To disable it completely you can set it to null.
*/
tooltip?: React.ReactNode;
/** other props to pass to the tooltip */
tooltipProps?: Omit<TooltipProps, 'content'>;
/** Callback on mouse enter */
onMouseEnter?: (event: any) => void;
/** Adds tooltip/popover info button */
Expand Down Expand Up @@ -68,6 +70,7 @@ const ThBase: React.FunctionComponent<ThProps> = ({
select = null,
expand: collapse = null,
tooltip = '',
tooltipProps,
onMouseEnter: onMouseEnterProp = () => {},
width,
visibility,
Expand Down Expand Up @@ -99,7 +102,9 @@ const ThBase: React.FunctionComponent<ThProps> = ({
sortParams = sortableFavorites({
onSort: sort?.onSort,
columnIndex: sort.columnIndex,
sortBy: sort.sortBy
sortBy: sort.sortBy,
tooltip: tooltip as string,
tooltipProps
})();
} else {
sortParams = sortable(children as IFormatterValueType, {
Expand All @@ -109,7 +114,9 @@ const ThBase: React.FunctionComponent<ThProps> = ({
sortBy: sort.sortBy,
onSort: sort?.onSort
}
} as IColumn
} as IColumn,
tooltip: tooltip as string,
tooltipProps
});
}
}
Expand All @@ -127,7 +134,9 @@ const ThBase: React.FunctionComponent<ThProps> = ({
allRowsSelected: select.isSelected,
isHeaderSelectDisabled: !!select.isHeaderSelectDisabled
}
}
},
tooltip: tooltip as string,
tooltipProps
})
: null;
const collapseParams = collapse
Expand Down Expand Up @@ -208,13 +217,15 @@ const ThBase: React.FunctionComponent<ThProps> = ({
);

const canMakeDefaultTooltip = tooltip === '' ? typeof transformedChildren === 'string' : true;
return tooltip !== null && canMakeDefaultTooltip && showTooltip ? (
const childControlsTooltip = sortParams || selectParams;
return tooltip !== null && canMakeDefaultTooltip && !childControlsTooltip && showTooltip ? (
<>
{cell}
<Tooltip
triggerRef={cellRef as React.RefObject<any>}
content={tooltip || (tooltip === '' && children)}
isVisible
{...tooltipProps}
/>
</>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import checkStyles from '@patternfly/react-styles/css/components/Check/check';

export const selectable: ITransform = (
label: IFormatterValueType,
{ rowIndex, columnIndex, rowData, column, property }: IExtra
{ rowIndex, columnIndex, rowData, column, property, tooltip }: IExtra
) => {
const {
extraParams: { onSelect, selectVariant, allRowsSelected, isHeaderSelectDisabled }
Expand Down Expand Up @@ -69,6 +69,7 @@ export const selectable: ITransform = (
selectVariant={selectVariant as RowSelectVariant}
onSelect={selectClick}
name={selectName}
tooltip={tooltip}
>
{label as React.ReactNode}
</SelectColumn>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ export const sortableFavorites = (sort: any) => () =>
sortBy: sort.sortBy,
onSort: sort?.onSort
}
}
},
tooltip: sort.tooltip,
tooltipProps: sort.tooltipProps,
tooltipHasDefaultBehavior: true
});

export const sortable: ITransform = (
label: IFormatterValueType,
{ columnIndex, column, property, className, ariaLabel }: IExtra
{ columnIndex, column, property, className, ariaLabel, tooltip, tooltipProps, tooltipHasDefaultBehavior }: IExtra
) => {
const {
extraParams: { sortBy, onSort }
Expand Down Expand Up @@ -56,6 +59,9 @@ export const sortable: ITransform = (
sortDirection={isSortedBy ? sortBy.direction : ''}
onSort={sortClicked}
aria-label={ariaLabel}
tooltip={tooltip}
tooltipProps={tooltipProps}
tooltipHasDefaultBehavior={tooltipHasDefaultBehavior}
>
{label as React.ReactNode}
</SortColumn>
Expand Down

0 comments on commit eb9693f

Please sign in to comment.