feat: Add useActiveDoubleClick hook for improved double-click handling (#39474)
This commit is contained in:
parent
635aa0621b
commit
efa90ea1d6
|
|
@ -6,6 +6,7 @@ import { DismissibleTab } from "../../DismissibleTab";
|
|||
import { EditableEntityName } from "../EditableEntityName";
|
||||
|
||||
import type { EditableDismissibleTabProps } from "./EditableDismissibleTab.types";
|
||||
import { useActiveDoubleClick } from "../../__hooks__";
|
||||
|
||||
export const EditableDismissibleTab = (props: EditableDismissibleTabProps) => {
|
||||
const {
|
||||
|
|
@ -33,7 +34,13 @@ export const EditableDismissibleTab = (props: EditableDismissibleTabProps) => {
|
|||
const isEditing = propIsEditing ?? localIsEditing;
|
||||
const handleEnterEditMode = propOnEnterEditMode ?? localOnEnterEditMode;
|
||||
const handleExitEditMode = propOnExitEditMode ?? localOnExitEditMode;
|
||||
const handleDoubleClick = isEditable ? handleEnterEditMode : noop;
|
||||
|
||||
const doubleClickOverride = useActiveDoubleClick(
|
||||
isActive,
|
||||
handleEnterEditMode,
|
||||
);
|
||||
|
||||
const handleDoubleClick = isEditable ? doubleClickOverride : noop;
|
||||
|
||||
return (
|
||||
<DismissibleTab
|
||||
|
|
|
|||
|
|
@ -3,8 +3,16 @@ import { ListItem } from "../../../List";
|
|||
import type { EntityItemProps } from "./EntityItem.types";
|
||||
import clx from "classnames";
|
||||
import { EditableEntityName } from "../../EditableEntityName";
|
||||
import { useActiveDoubleClick } from "../../../__hooks__";
|
||||
|
||||
export const EntityItem = (props: EntityItemProps) => {
|
||||
const { onDoubleClick, startIcon, ...rest } = props;
|
||||
|
||||
const doubleClickOverride = useActiveDoubleClick(
|
||||
props.isSelected || false,
|
||||
onDoubleClick,
|
||||
);
|
||||
|
||||
const {
|
||||
canEdit,
|
||||
isEditing,
|
||||
|
|
@ -14,8 +22,6 @@ export const EntityItem = (props: EntityItemProps) => {
|
|||
validateName,
|
||||
} = props.nameEditorConfig;
|
||||
|
||||
const { startIcon, ...rest } = props;
|
||||
|
||||
const inEditMode = canEdit ? isEditing : false;
|
||||
|
||||
// Use List Item custom title prop to show the editable name
|
||||
|
|
@ -61,6 +67,7 @@ export const EntityItem = (props: EntityItemProps) => {
|
|||
customTitleComponent={customTitle}
|
||||
data-testid={`t--entity-item-${props.title}`}
|
||||
id={"entity-" + props.id}
|
||||
onDoubleClick={doubleClickOverride}
|
||||
rightControl={rightControl}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
export { useDOMRef } from "./useDomRef";
|
||||
export { useEditableText } from "./useEditableText";
|
||||
export { useActiveDoubleClick } from "./useActiveDoubleClick";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
import { noop } from "lodash";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { useBoolean } from "usehooks-ts";
|
||||
|
||||
export function useActiveDoubleClick(
|
||||
isActive: boolean,
|
||||
onDoubleClick?: () => void,
|
||||
) {
|
||||
const {
|
||||
setFalse: setCannotDoubleClick,
|
||||
setTrue: setCanDoubleClick,
|
||||
value: canDoubleClick,
|
||||
} = useBoolean();
|
||||
|
||||
useEffect(
|
||||
function handleDoubleClickEnableBasedOnSelection() {
|
||||
let timeoutId: ReturnType<typeof setTimeout>;
|
||||
|
||||
if (isActive) {
|
||||
timeoutId = setTimeout(() => {
|
||||
setCanDoubleClick();
|
||||
}, 200);
|
||||
} else {
|
||||
setCannotDoubleClick();
|
||||
}
|
||||
|
||||
return () => {
|
||||
clearTimeout(timeoutId);
|
||||
};
|
||||
},
|
||||
[isActive, setCanDoubleClick, setCannotDoubleClick],
|
||||
);
|
||||
|
||||
const handleDoubleClick = useMemo(() => {
|
||||
if (!canDoubleClick || !onDoubleClick) {
|
||||
return noop;
|
||||
}
|
||||
|
||||
return onDoubleClick;
|
||||
}, [canDoubleClick, onDoubleClick]);
|
||||
|
||||
return handleDoubleClick;
|
||||
}
|
||||
|
|
@ -115,22 +115,6 @@ export function useEditableText(
|
|||
[name, previousName, isEditing],
|
||||
);
|
||||
|
||||
// TODO: This is a temporary fix to focus the input after context retention applies focus to its target
|
||||
// this is a nasty hack to re-focus the input after context retention applies focus to its target
|
||||
// this will be addressed in a future task, likely by a focus retention modification
|
||||
useEffect(
|
||||
function recaptureFocusInEventOfFocusRetention() {
|
||||
const input = inputRef.current;
|
||||
|
||||
if (isEditing && input) {
|
||||
setTimeout(() => {
|
||||
input.focus();
|
||||
}, 200);
|
||||
}
|
||||
},
|
||||
[isEditing, inputRef],
|
||||
);
|
||||
|
||||
return [
|
||||
inputRef,
|
||||
editableName,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user