fix: Widget name disappear as you hover over it (#32709)

## Description

Moves the Focus widget action into its own hook, and calling it from the
PositionContainer instead from the DraggableContainer. PositionContainer
is the parent of Draggable and hence adds a larger target for the mouse
focus of a widget.



Fixes #32710

## Automation

/ok-to-test tags="@tag.IDE"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/8705394457>
> Commit: bc58f19c7247544117866d89f4f557372f8791ef
> Cypress dashboard url: <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=8705394457&attempt=1"
target="_blank">Click here!</a>

<!-- end of auto-generated comment: Cypress test results  -->



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enhanced widget interaction by implementing hover to focus
functionality in the PositionedContainer.

- **Refactor**
- Simplified the DraggableComponent by removing unused states and event
handlers, focusing on widget selection improvements.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Hetu Nandu 2024-04-17 16:10:35 +05:30 committed by GitHub
parent 263c761f0d
commit 944fa23283
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 60 additions and 28 deletions

View File

@ -21,6 +21,7 @@ import { POSITIONED_WIDGET } from "constants/componentClassNameConstants";
import equal from "fast-deep-equal";
import { widgetTypeClassname } from "widgets/WidgetUtils";
import { checkIsDropTarget } from "WidgetProvider/factory/helpers";
import { useHoverToFocusWidget } from "utils/hooks/useHoverToFocusWidget";
const PositionedWidget = styled.div<{
zIndexOnHover: number;
@ -157,6 +158,11 @@ export function PositionedContainer(
return styles;
}, [style, isReflowEffected, onHoverZIndex, zIndex, reflowedPosition]);
const [handleMouseOver, handleMouseLeave] = useHoverToFocusWidget(
props.widgetId,
props.resizeDisabled,
);
// TODO: Experimental fix for sniping mode. This should be handled with a single event
return (
<PositionedWidget
@ -168,6 +174,8 @@ export function PositionedContainer(
id={props.widgetId}
key={`positioned-container-${props.widgetId}`}
onClickCapture={clickToSelectWidget}
onMouseLeave={handleMouseLeave}
onMouseOver={handleMouseOver}
ref={ref}
//Before you remove: This is used by property pane to reference the element
style={containerStyle}

View File

@ -17,8 +17,6 @@ import {
useWidgetDragResize,
} from "utils/hooks/dragResizeHooks";
import { getShouldAllowDrag } from "selectors/widgetDragSelectors";
import { combinedPreviewModeSelector } from "selectors/editorSelectors";
import { getAnvilSpaceDistributionStatus } from "layoutSystems/anvil/integrations/selectors";
const DraggableWrapper = styled.div<{ draggable: boolean }>`
display: block;
@ -57,8 +55,8 @@ const WidgetBoundaries = styled.div`
`;
function DraggableComponent(props: DraggableComponentProps) {
// Dispatch hook handy to set a widget as focused/selected
const { focusWidget, selectWidget } = useWidgetSelection();
// Dispatch hook handy to set a widget as selected
const { selectWidget } = useWidgetSelection();
const shouldAllowDrag = useSelector(getShouldAllowDrag);
// Dispatch hook handy to set any `DraggableComponent` as dragging/ not dragging
@ -76,9 +74,6 @@ function DraggableComponent(props: DraggableComponentProps) {
(state: AppState) => state.ui.widgetDragResize.isResizing,
);
// This state tells us whether space redistribution is in process
const isDistributingSpace = useSelector(getAnvilSpaceDistributionStatus);
// This state tells us whether a `DraggableComponent` is dragging
const isDragging = useSelector(
(state: AppState) => state.ui.widgetDragResize.isDragging,
@ -89,8 +84,6 @@ function DraggableComponent(props: DraggableComponentProps) {
state.ui.widgetDragResize?.dragDetails?.draggedOn === props.parentId,
);
const isPreviewMode = useSelector(combinedPreviewModeSelector);
// True when any widget is dragging or resizing, including this one
const isResizingOrDragging = !!isResizing || !!isDragging;
const isCurrentWidgetDragging = isDragging && isSelected;
@ -98,23 +91,6 @@ function DraggableComponent(props: DraggableComponentProps) {
const showBoundary =
!props.isFlexChild && (isCurrentWidgetDragging || isDraggingSibling);
// When mouse is over this draggable
const handleMouseOver = (e: React.MouseEvent) => {
focusWidget &&
!isResizingOrDragging &&
!isFocused &&
!isDistributingSpace &&
!props.resizeDisabled &&
!isPreviewMode &&
focusWidget(props.widgetId, e.metaKey);
e.stopPropagation();
};
const handleMouseLeave = () => {
// on leaving a widget, we reset the focused widget
focusWidget && focusWidget();
};
// Display this draggable based on the current drag state
const dragWrapperStyle: CSSProperties = {
display: !props.isFlexChild && isCurrentWidgetDragging ? "none" : "block",
@ -156,8 +132,6 @@ function DraggableComponent(props: DraggableComponentProps) {
data-testid={isSelected ? "t--selected" : ""}
draggable={allowDrag}
onDragStart={onDragStart}
onMouseLeave={handleMouseLeave}
onMouseOver={handleMouseOver}
ref={draggableRef}
style={dragWrapperStyle}
>

View File

@ -0,0 +1,50 @@
import { useWidgetSelection } from "./useWidgetSelection";
import { useSelector } from "react-redux";
import { isCurrentWidgetFocused } from "selectors/widgetSelectors";
import { getAnvilSpaceDistributionStatus } from "layoutSystems/anvil/integrations/selectors";
import { combinedPreviewModeSelector } from "selectors/editorSelectors";
import type { AppState } from "@appsmith/reducers";
import type React from "react";
export const useHoverToFocusWidget = (
widgetId: string,
resizeDisabled?: boolean,
) => {
const { focusWidget } = useWidgetSelection();
// This state tels us which widget is focused
// The value is the widgetId of the focused widget.
const isFocused = useSelector(isCurrentWidgetFocused(widgetId));
// This state tells us whether a `ResizableComponent` is resizing
const isResizing = useSelector(
(state: AppState) => state.ui.widgetDragResize.isResizing,
);
// This state tells us whether a `DraggableComponent` is dragging
const isDragging = useSelector(
(state: AppState) => state.ui.widgetDragResize.isDragging,
);
const isResizingOrDragging = isResizing || isDragging;
// This state tells us whether space redistribution is in process
const isDistributingSpace = useSelector(getAnvilSpaceDistributionStatus);
const isPreviewMode = useSelector(combinedPreviewModeSelector);
// When mouse is over this draggable
const handleMouseOver = (e: React.MouseEvent) => {
focusWidget &&
!isResizingOrDragging &&
!isFocused &&
!isDistributingSpace &&
!resizeDisabled &&
!isPreviewMode &&
focusWidget(widgetId, e.metaKey);
e.stopPropagation();
};
const handleMouseLeave = () => {
// on leaving a widget, we reset the focused widget
focusWidget && focusWidget();
};
return [handleMouseOver, handleMouseLeave];
};