diff --git a/app/client/packages/design-system/ads/src/List/List.tsx b/app/client/packages/design-system/ads/src/List/List.tsx index a6d74126c84a..95b905e7e61d 100644 --- a/app/client/packages/design-system/ads/src/List/List.tsx +++ b/app/client/packages/design-system/ads/src/List/List.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useState } from "react"; import clsx from "classnames"; import type { ListItemProps, ListProps } from "./List.types"; @@ -22,6 +22,7 @@ import { ListItemTextOverflowClassName, ListItemTitleClassName, } from "./List.constants"; +import { useEventCallback } from "usehooks-ts"; function List({ className, items, ...rest }: ListProps) { return ( @@ -34,39 +35,30 @@ function List({ className, items, ...rest }: ListProps) { } function TextWithTooltip(props: TextProps & { isMultiline?: boolean }) { - const ref = React.useRef(null); const [disableTooltip, setDisableTooltip] = useState(true); - const isEllipsisActive = () => { - let active = false; - - if (ref.current) { - const text_node = ref.current.children[0]; - - if (props.isMultiline) { - active = text_node && text_node.clientHeight < text_node.scrollHeight; - } else { - active = text_node && text_node.clientWidth < text_node.scrollWidth; + const handleShowFullText = useEventCallback( + (e: React.MouseEvent) => { + let isInEllipsis = false; + const text_node = e.target; + + if (text_node instanceof HTMLElement) { + if (props.isMultiline) { + isInEllipsis = + text_node && text_node.clientHeight < text_node.scrollHeight; + } else { + isInEllipsis = + text_node && text_node.clientWidth < text_node.scrollWidth; + } } - } - setDisableTooltip(!active); - }; - - useEffect(() => { - if (ref.current) { - isEllipsisActive(); - ref.current.addEventListener("mouseover", isEllipsisActive); - - return () => { - ref.current?.removeEventListener("mouseover", isEllipsisActive); - }; - } - }, []); + setDisableTooltip(!isInEllipsis); + }, + ); return ( - + { + const handleOnClick = useEventCallback((e: React.MouseEvent) => { + e.stopPropagation(); + if (!props.isDisabled && props.onClick) { - props.onClick(); + props.onClick(e); } - }; + }); + + const handleDoubleClick = useEventCallback((e: React.MouseEvent) => { + e.stopPropagation(); - const handleDoubleClick = () => { if (!props.isDisabled && props.onDoubleClick) { props.onDoubleClick(); } - }; + }); - const handleRightControlClick = (e: React.MouseEvent) => { + const handleRightControlClick = useEventCallback((e: React.MouseEvent) => { e.stopPropagation(); - }; + }); return ( ; @@ -11,7 +11,7 @@ export interface ListItemProps { /** Control the visibility trigger of right control */ rightControlVisibility?: "hover" | "always"; /** callback for when the list item is clicked */ - onClick: () => void; + onClick: (e: MouseEvent) => void; /** callback for when the list item is double-clicked */ onDoubleClick?: () => void; /** Whether the list item is disabled. */ diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.test.tsx b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.test.tsx index 455c3f8cc612..d314a8e193cb 100644 --- a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.test.tsx +++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.test.tsx @@ -82,6 +82,7 @@ describe("useEditableText", () => { act(() => { handleKeyUp({ key: "Enter", + stopPropagation: jest.fn(), } as unknown as React.KeyboardEvent); }); @@ -113,6 +114,7 @@ describe("useEditableText", () => { act(() => { handleKeyUp({ key: "Enter", + stopPropagation: jest.fn(), } as unknown as React.KeyboardEvent); }); @@ -134,7 +136,10 @@ describe("useEditableText", () => { const [, , , handleKeyUp] = result.current; act(() => { - handleKeyUp({ key: "Escape" } as React.KeyboardEvent); + handleKeyUp({ + key: "Escape", + stopPropagation: jest.fn(), + } as unknown as React.KeyboardEvent); }); expect(mockExitEditing).toHaveBeenCalled(); @@ -155,7 +160,10 @@ describe("useEditableText", () => { const [, , , handleKeyUp] = result.current; act(() => { - handleKeyUp({ key: "Enter" } as React.KeyboardEvent); + handleKeyUp({ + key: "Enter", + stopPropagation: jest.fn(), + } as unknown as React.KeyboardEvent); }); expect(mockExitEditing).toHaveBeenCalled(); diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.ts b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.ts index ac8d6d5e621b..59b3d4e26784 100644 --- a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.ts +++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.ts @@ -74,6 +74,8 @@ export function useEditableText( ]); const handleKeyUp = useEventCallback((e: KeyboardEvent) => { + e.stopPropagation(); + if (e.key === "Enter") { attemptSave(); } else if (e.key === "Escape") { diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.stories.tsx b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.stories.tsx index eb4be22a56b6..7b73e7a8b559 100644 --- a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.stories.tsx +++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.stories.tsx @@ -36,6 +36,7 @@ const Template = (props: EntityItemProps) => { { setIsEditing(true); }} diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.tsx b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.tsx index df92daef4400..dfeb0279eb49 100644 --- a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.tsx +++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.tsx @@ -4,6 +4,7 @@ import { ListItem, Spinner, Tooltip } from "../../.."; import type { EntityItemProps } from "./EntityItem.types"; import { EntityEditableName } from "./EntityItem.styles"; import { useEditableText } from "../Editable"; +import clx from "classnames"; export const EntityItem = (props: EntityItemProps) => { const { @@ -77,7 +78,10 @@ export const EntityItem = (props: EntityItemProps) => { return ( ); diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.types.ts b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.types.ts index 09244c4b3b1f..36873a9f422a 100644 --- a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.types.ts +++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.types.ts @@ -5,6 +5,8 @@ export interface EntityItemProps ListItemProps, "customTitleComponent" | "description" | "descriptionType" > { + /** ID of the entity. Will be added to the markup for identification */ + id: string; /** Control the name editing behaviour */ nameEditorConfig: { // Set editable based on user permissions