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 { EditableEntityName } from "../EditableEntityName";
|
||||||
|
|
||||||
import type { EditableDismissibleTabProps } from "./EditableDismissibleTab.types";
|
import type { EditableDismissibleTabProps } from "./EditableDismissibleTab.types";
|
||||||
|
import { useActiveDoubleClick } from "../../__hooks__";
|
||||||
|
|
||||||
export const EditableDismissibleTab = (props: EditableDismissibleTabProps) => {
|
export const EditableDismissibleTab = (props: EditableDismissibleTabProps) => {
|
||||||
const {
|
const {
|
||||||
|
|
@ -33,7 +34,13 @@ export const EditableDismissibleTab = (props: EditableDismissibleTabProps) => {
|
||||||
const isEditing = propIsEditing ?? localIsEditing;
|
const isEditing = propIsEditing ?? localIsEditing;
|
||||||
const handleEnterEditMode = propOnEnterEditMode ?? localOnEnterEditMode;
|
const handleEnterEditMode = propOnEnterEditMode ?? localOnEnterEditMode;
|
||||||
const handleExitEditMode = propOnExitEditMode ?? localOnExitEditMode;
|
const handleExitEditMode = propOnExitEditMode ?? localOnExitEditMode;
|
||||||
const handleDoubleClick = isEditable ? handleEnterEditMode : noop;
|
|
||||||
|
const doubleClickOverride = useActiveDoubleClick(
|
||||||
|
isActive,
|
||||||
|
handleEnterEditMode,
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDoubleClick = isEditable ? doubleClickOverride : noop;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DismissibleTab
|
<DismissibleTab
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,16 @@ import { ListItem } from "../../../List";
|
||||||
import type { EntityItemProps } from "./EntityItem.types";
|
import type { EntityItemProps } from "./EntityItem.types";
|
||||||
import clx from "classnames";
|
import clx from "classnames";
|
||||||
import { EditableEntityName } from "../../EditableEntityName";
|
import { EditableEntityName } from "../../EditableEntityName";
|
||||||
|
import { useActiveDoubleClick } from "../../../__hooks__";
|
||||||
|
|
||||||
export const EntityItem = (props: EntityItemProps) => {
|
export const EntityItem = (props: EntityItemProps) => {
|
||||||
|
const { onDoubleClick, startIcon, ...rest } = props;
|
||||||
|
|
||||||
|
const doubleClickOverride = useActiveDoubleClick(
|
||||||
|
props.isSelected || false,
|
||||||
|
onDoubleClick,
|
||||||
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
canEdit,
|
canEdit,
|
||||||
isEditing,
|
isEditing,
|
||||||
|
|
@ -14,8 +22,6 @@ export const EntityItem = (props: EntityItemProps) => {
|
||||||
validateName,
|
validateName,
|
||||||
} = props.nameEditorConfig;
|
} = props.nameEditorConfig;
|
||||||
|
|
||||||
const { startIcon, ...rest } = props;
|
|
||||||
|
|
||||||
const inEditMode = canEdit ? isEditing : false;
|
const inEditMode = canEdit ? isEditing : false;
|
||||||
|
|
||||||
// Use List Item custom title prop to show the editable name
|
// Use List Item custom title prop to show the editable name
|
||||||
|
|
@ -61,6 +67,7 @@ export const EntityItem = (props: EntityItemProps) => {
|
||||||
customTitleComponent={customTitle}
|
customTitleComponent={customTitle}
|
||||||
data-testid={`t--entity-item-${props.title}`}
|
data-testid={`t--entity-item-${props.title}`}
|
||||||
id={"entity-" + props.id}
|
id={"entity-" + props.id}
|
||||||
|
onDoubleClick={doubleClickOverride}
|
||||||
rightControl={rightControl}
|
rightControl={rightControl}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
export { useDOMRef } from "./useDomRef";
|
export { useDOMRef } from "./useDomRef";
|
||||||
export { useEditableText } from "./useEditableText";
|
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],
|
[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 [
|
return [
|
||||||
inputRef,
|
inputRef,
|
||||||
editableName,
|
editableName,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user