PromucFlow_constructor/app/client/src/utils/hooks/useClickToSelectWidget.tsx
Abhinav Jha 20de52000d
feat: Auto height instant update (#19082)
## Description
This PR adds one of the promised updates to the auto height feature. 
More specifically, we wanted to add was the ability to see the
containers change height as we drag and drop widgets within them instead
of after dropping (when auto height is enabled)
This PR does that.


Co-authored-by: Aishwarya UR <aishwarya@appsmith.com>
2023-02-03 11:17:40 +05:30

133 lines
3.9 KiB
TypeScript

import { AppState } from "@appsmith/reducers";
import equal from "fast-deep-equal/es6";
import React, { ReactNode, useCallback } from "react";
import { useSelector } from "react-redux";
import { getIsPropertyPaneVisible } from "selectors/propertyPaneSelectors";
import {
getFocusedParentToOpen,
isWidgetSelected,
shouldWidgetIgnoreClicksSelector,
} from "selectors/widgetSelectors";
import styled from "styled-components";
import { stopEventPropagation } from "utils/AppsmithUtils";
import { scrollCSS } from "widgets/WidgetUtils";
import { useWidgetSelection } from "./useWidgetSelection";
import { SelectionRequestType } from "sagas/WidgetSelectUtils";
import { Colors } from "constants/Colors";
const ContentWrapper = styled.div<{
backgroundColor?: string;
borderRadius?: string;
}>`
width: 100%;
height: 100%;
background: ${({ backgroundColor }) => `${backgroundColor || Colors.WHITE}`};
border-radius: ${({ borderRadius }) => borderRadius};
${scrollCSS}
`;
const ScrollWrapper = styled.div<{
backgroundColor?: string;
borderRadius?: string;
}>`
width: 100%;
height: 100%;
background: ${({ backgroundColor }) => `${backgroundColor || Colors.WHITE}`};
border-radius: ${({ borderRadius }) => borderRadius};
overflow: hidden;
`;
export function ClickContentToOpenPropPane({
backgroundColor,
borderRadius,
children,
widgetId,
}: {
widgetId: string;
children?: ReactNode;
backgroundColor?: string;
borderRadius?: string;
}) {
const { focusWidget } = useWidgetSelection();
const clickToSelectWidget = useClickToSelectWidget(widgetId);
const focusedWidget = useSelector(
(state: AppState) => state.ui.widgetDragResize.focusedWidget,
);
const isResizing = useSelector(
(state: AppState) => state.ui.widgetDragResize.isResizing,
);
const isDragging = useSelector(
(state: AppState) => state.ui.widgetDragResize.isDragging,
);
const isResizingOrDragging = !!isResizing || !!isDragging;
const handleMouseOver = (e: any) => {
focusWidget &&
!isResizingOrDragging &&
focusedWidget !== widgetId &&
focusWidget(widgetId);
e.stopPropagation();
};
return (
<ScrollWrapper
backgroundColor={backgroundColor}
borderRadius={borderRadius}
>
<ContentWrapper
className="scroll-parent"
onClick={stopEventPropagation}
onMouseDownCapture={clickToSelectWidget}
onMouseOver={handleMouseOver}
>
{children}
</ContentWrapper>
</ScrollWrapper>
);
}
export const useClickToSelectWidget = (widgetId: string) => {
const { focusWidget, selectWidget } = useWidgetSelection();
const isPropPaneVisible = useSelector(getIsPropertyPaneVisible);
const isSelected = useSelector(isWidgetSelected(widgetId));
const parentWidgetToOpen = useSelector(getFocusedParentToOpen, equal);
const shouldIgnoreClicks = useSelector(
shouldWidgetIgnoreClicksSelector(widgetId),
);
const clickToSelectWidget = useCallback(
(e: any) => {
// Ignore click captures
// 1. If the component is resizing or dragging because it is handled internally in draggable component.
// 2. If table filter property pane is open.
if (shouldIgnoreClicks) return;
if ((!isPropPaneVisible && isSelected) || !isSelected) {
let type: SelectionRequestType = SelectionRequestType.One;
if (e.metaKey || e.ctrlKey) {
type = SelectionRequestType.PushPop;
} else if (e.shiftKey) {
type = SelectionRequestType.ShiftSelect;
}
if (parentWidgetToOpen) {
selectWidget(type, [parentWidgetToOpen.widgetId]);
} else {
selectWidget(type, [widgetId]);
focusWidget(widgetId);
}
if (
type === SelectionRequestType.PushPop ||
type === SelectionRequestType.ShiftSelect
) {
e.stopPropagation();
}
}
},
[shouldIgnoreClicks, isPropPaneVisible, isSelected, parentWidgetToOpen],
);
return clickToSelectWidget;
};