Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix:- added elipsis and tooltip to the button content in table widget component #36865

Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ export const MenuColumnWrapper = styled.div<{ selected: boolean }>`

export const ActionWrapper = styled.div<{ disabled: boolean }>`
margin: 0 5px 0 0;
max-width: 100%;
${(props) => (props.disabled ? "cursor: not-allowed;" : null)}
&&&&&& {
.bp3-button {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,45 +36,63 @@ const MAX_WIDTH = 500;
const TOOLTIP_OPEN_DELAY = 500;
const MAX_CHARS_ALLOWED_IN_TOOLTIP = 200;

function useToolTip(children: React.ReactNode, title?: string) {
function isButtonTextTruncated(element: HTMLElement) {
const spanElement = element.querySelector("span");
const offsetWidth = spanElement?.offsetWidth ?? 0;
const scrollWidth = spanElement?.scrollWidth ?? 0;

return scrollWidth > offsetWidth;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check for null spanElement before accessing properties

If spanElement is null, comparison on line 44 will fail.

}

function useToolTip(
children: React.ReactNode,
title?: string,
isButton?: boolean,
) {
const ref = createRef<HTMLDivElement>();
const [requiresTooltip, setRequiresTooltip] = useState(false);

useEffect(() => {
let timeout: ReturnType<typeof setTimeout>;
const currentRef = ref.current;

const mouseEnterHandler = () => {
const element = ref.current?.querySelector("div") as HTMLDivElement;
if (!currentRef) return;

/*
* Using setTimeout to simulate hoverOpenDelay of the tooltip
* during initial render
*/
const mouseEnterHandler = () => {
timeout = setTimeout(() => {
const element = currentRef?.querySelector("div") as HTMLDivElement;

/*
* Using setTimeout to simulate hoverOpenDelay of the tooltip
* during initial render
*/
if (element && element.offsetWidth < element.scrollWidth) {
setRequiresTooltip(true);
} else if (isButton && element && isButtonTextTruncated(element)) {
setRequiresTooltip(true);
} else {
setRequiresTooltip(false);
}

ref.current?.removeEventListener("mouseenter", mouseEnterHandler);
ref.current?.removeEventListener("mouseleave", mouseLeaveHandler);
currentRef?.removeEventListener("mouseenter", mouseEnterHandler);
currentRef?.removeEventListener("mouseleave", mouseLeaveHandler);
}, TOOLTIP_OPEN_DELAY);
};

const mouseLeaveHandler = () => {
setRequiresTooltip(false);
clearTimeout(timeout);
};

ref.current?.addEventListener("mouseenter", mouseEnterHandler);
ref.current?.addEventListener("mouseleave", mouseLeaveHandler);
currentRef?.addEventListener("mouseenter", mouseEnterHandler);
currentRef?.addEventListener("mouseleave", mouseLeaveHandler);

return () => {
ref.current?.removeEventListener("mouseenter", mouseEnterHandler);
ref.current?.removeEventListener("mouseleave", mouseLeaveHandler);
currentRef?.removeEventListener("mouseenter", mouseEnterHandler);
currentRef?.removeEventListener("mouseleave", mouseLeaveHandler);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Include isButton in the useEffect dependency array

Since isButton is used within the useEffect hook, it's important to include it in the dependency array. This ensures the effect updates correctly when isButton changes, preventing potential bugs.

Apply this diff to update the dependency array:

       }, [children]);
+      }, [children, isButton]);

Committable suggestion was skipped due to low confidence.

clearTimeout(timeout);
};
}, [children]);
}, [children,isButton]);

return requiresTooltip && children ? (
<Tooltip
Expand Down Expand Up @@ -165,6 +183,11 @@ function AutoToolTipComponent(props: Props) {
return <LinkWrapper {...props} />;
}

if (props.columnType === ColumnTypes.BUTTON && props.title) {
const buttonContent = useToolTip(props.children, props.title, true);
return buttonContent;
}

return (
<ColumnWrapper className={props.className} textColor={props.textColor}>
<CellWrapper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ import React, { useState } from "react";

import { ActionWrapper } from "../TableStyledWrappers";
import { BaseButton } from "widgets/ButtonWidget/component";
import type { ButtonColumnActions } from "widgets/TableWidgetV2/constants";
import {
ColumnTypes,
type ButtonColumnActions,
} from "widgets/TableWidgetV2/constants";
import styled from "styled-components";
import AutoToolTipComponent from "widgets/TableWidgetV2/component/cellComponents/AutoToolTipComponent";

const StyledButton = styled(BaseButton)<{
compactMode?: string;
Expand Down Expand Up @@ -39,12 +43,16 @@ export function Button(props: ButtonProps) {

return (
<ActionWrapper
disabled={!!props.isDisabled}
onClick={(e) => {
e.stopPropagation();
}}
>
{props.isCellVisible && props.action.isVisible ? (
disabled={!!props.isDisabled}
onClick={(e) => {
e.stopPropagation();
}}
>
{props.isCellVisible && props.action.isVisible && props.action.label ? (
<AutoToolTipComponent
columnType={ColumnTypes.BUTTON}
title={props.action.label}
>
<StyledButton
borderRadius={props.action.borderRadius}
boxShadow={props.action.boxShadow}
Expand All @@ -58,7 +66,9 @@ export function Button(props: ButtonProps) {
onClick={handleClick}
text={props.action.label}
/>
) : null}
</ActionWrapper>
</AutoToolTipComponent>
)
: null}
</ActionWrapper>
);
}