chore: Housekeeping items in List and Entity Item ADS (#38537)
This commit is contained in:
parent
e0e76d69b4
commit
8efce1dd8d
|
|
@ -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<HTMLDivElement>(null);
|
||||
const [disableTooltip, setDisableTooltip] = useState(true);
|
||||
|
||||
const isEllipsisActive = () => {
|
||||
let active = false;
|
||||
const handleShowFullText = useEventCallback(
|
||||
(e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
let isInEllipsis = false;
|
||||
const text_node = e.target;
|
||||
|
||||
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;
|
||||
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 (
|
||||
<Tooltip content={props.children} isDisabled={disableTooltip}>
|
||||
<TooltipTextWrapper ref={ref}>
|
||||
<TooltipTextWrapper onMouseOver={handleShowFullText}>
|
||||
<Text
|
||||
{...props}
|
||||
className={clsx(ListItemTextOverflowClassName, props.className)}
|
||||
|
|
@ -92,21 +84,25 @@ function ListItem(props: ListItemProps) {
|
|||
const isBlockDescription = descriptionType === "block" && description;
|
||||
const isInlineDescription = descriptionType === "inline" && description;
|
||||
|
||||
const handleOnClick = () => {
|
||||
if (!props.isDisabled && props.onClick) {
|
||||
props.onClick();
|
||||
}
|
||||
};
|
||||
const handleOnClick = useEventCallback((e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
|
||||
if (!props.isDisabled && 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 (
|
||||
<StyledListItem
|
||||
|
|
@ -114,6 +110,7 @@ function ListItem(props: ListItemProps) {
|
|||
data-disabled={props.isDisabled || false}
|
||||
data-rightcontrolvisibility={rightControlVisibility}
|
||||
data-selected={props.isSelected}
|
||||
id={props.id}
|
||||
onClick={handleOnClick}
|
||||
onDoubleClick={handleDoubleClick}
|
||||
role="listitem"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { Sizes } from "../__config__/types";
|
||||
import type { ReactNode } from "react";
|
||||
import type { MouseEvent, ReactNode } from "react";
|
||||
|
||||
export type ListSizes = Extract<Sizes, "md" | "lg">;
|
||||
|
||||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ describe("useEditableText", () => {
|
|||
act(() => {
|
||||
handleKeyUp({
|
||||
key: "Enter",
|
||||
stopPropagation: jest.fn(),
|
||||
} as unknown as React.KeyboardEvent<HTMLInputElement>);
|
||||
});
|
||||
|
||||
|
|
@ -113,6 +114,7 @@ describe("useEditableText", () => {
|
|||
act(() => {
|
||||
handleKeyUp({
|
||||
key: "Enter",
|
||||
stopPropagation: jest.fn(),
|
||||
} as unknown as React.KeyboardEvent<HTMLInputElement>);
|
||||
});
|
||||
|
||||
|
|
@ -134,7 +136,10 @@ describe("useEditableText", () => {
|
|||
const [, , , handleKeyUp] = result.current;
|
||||
|
||||
act(() => {
|
||||
handleKeyUp({ key: "Escape" } as React.KeyboardEvent<HTMLInputElement>);
|
||||
handleKeyUp({
|
||||
key: "Escape",
|
||||
stopPropagation: jest.fn(),
|
||||
} as unknown as React.KeyboardEvent<HTMLInputElement>);
|
||||
});
|
||||
|
||||
expect(mockExitEditing).toHaveBeenCalled();
|
||||
|
|
@ -155,7 +160,10 @@ describe("useEditableText", () => {
|
|||
const [, , , handleKeyUp] = result.current;
|
||||
|
||||
act(() => {
|
||||
handleKeyUp({ key: "Enter" } as React.KeyboardEvent<HTMLInputElement>);
|
||||
handleKeyUp({
|
||||
key: "Enter",
|
||||
stopPropagation: jest.fn(),
|
||||
} as unknown as React.KeyboardEvent<HTMLInputElement>);
|
||||
});
|
||||
|
||||
expect(mockExitEditing).toHaveBeenCalled();
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ export function useEditableText(
|
|||
]);
|
||||
|
||||
const handleKeyUp = useEventCallback((e: KeyboardEvent<HTMLInputElement>) => {
|
||||
e.stopPropagation();
|
||||
|
||||
if (e.key === "Enter") {
|
||||
attemptSave();
|
||||
} else if (e.key === "Escape") {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ const Template = (props: EntityItemProps) => {
|
|||
<ExplorerContainer borderRight="STANDARD" height="500px" width="255px">
|
||||
<Flex flexDirection="column" gap="spaces-2" p="spaces-3">
|
||||
<EntityItem
|
||||
id="storyItem"
|
||||
onDoubleClick={() => {
|
||||
setIsEditing(true);
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<ListItem
|
||||
{...props}
|
||||
className={clx("t--entity-item", props.className)}
|
||||
customTitleComponent={customTitle}
|
||||
data-testid={`t--entity-item-${props.title}`}
|
||||
id={"entity-" + props.id}
|
||||
startIcon={startIcon}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user