## Description Added ESLint rule to force blank lines between statements. Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="@tag.All" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!CAUTION] > 🔴 🔴 🔴 Some tests have failed. > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/10924926728> > Commit: 34f57714a1575ee04e94e03cbcaf95e57a96c86c > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10924926728&attempt=1&selectiontype=test&testsstatus=failed&specsstatus=fail" target="_blank">Cypress dashboard</a>. > Tags: @tag.All > Spec: > The following are new failures, please fix them before merging the PR: <ol> > <li>cypress/e2e/Regression/ClientSide/Anvil/AnvilModal_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilButtonWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCheckboxGroupWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilCurrencyInputWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilIconButtonWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInlineButtonWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilInputWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilParagraphWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilPhoneInputWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilStatsWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchGroupWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilSwitchWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilTableWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilToolbarButtonWidgetSnapshot_spec.ts > <li>cypress/e2e/Regression/ClientSide/Anvil/Widgets/AnvilZoneSectionWidgetSnapshot_spec.ts</ol> > <a href="https://internal.appsmith.com/app/cypress-dashboard/identified-flaky-tests-65890b3c81d7400d08fa9ee3?branch=master" target="_blank">List of identified flaky tests</a>. > <hr>Wed, 18 Sep 2024 16:33:36 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No --------- Co-authored-by: Valera Melnikov <valera@appsmith.com>
115 lines
3.1 KiB
TypeScript
115 lines
3.1 KiB
TypeScript
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
import { getMainCanvas } from "./WidgetUtils";
|
|
import styled from "styled-components";
|
|
import type { BaseSelectRef } from "rc-select";
|
|
import type { RenderMode } from "constants/WidgetConstants";
|
|
import { RenderModes } from "constants/WidgetConstants";
|
|
|
|
const BackDropContainer = styled.div`
|
|
position: fixed;
|
|
width: 100vw;
|
|
height: 100vh;
|
|
background: transparent;
|
|
top: 0;
|
|
left: 0;
|
|
display: none;
|
|
`;
|
|
|
|
interface useDropdownProps {
|
|
inputRef: React.RefObject<HTMLInputElement>;
|
|
renderMode?: RenderMode;
|
|
onDropdownOpen?: () => void;
|
|
onDropdownClose?: () => void;
|
|
}
|
|
const FOCUS_TIMEOUT = 500;
|
|
|
|
// TODO: Refactor More functionalities in MultiSelect, MultiTreeSelect and TreeSelect Components
|
|
const useDropdown = ({
|
|
inputRef,
|
|
onDropdownClose,
|
|
onDropdownOpen,
|
|
renderMode,
|
|
}: useDropdownProps) => {
|
|
// This is to make the dropdown controlled
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
const popupContainer = useRef<HTMLElement>(getMainCanvas());
|
|
const selectRef = useRef<BaseSelectRef | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (!popupContainer.current) {
|
|
popupContainer.current = getMainCanvas();
|
|
}
|
|
}, []);
|
|
|
|
const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
|
// Backspace would simultaneously remove an option, so it should only be used within the search input
|
|
if (event.key === "Backspace") {
|
|
event.stopPropagation();
|
|
}
|
|
};
|
|
|
|
// Avoid scrolls when Popup is opened
|
|
function BackDrop() {
|
|
return <BackDropContainer onClick={closeBackDrop} />;
|
|
}
|
|
|
|
// Get PopupContainer on main Canvas
|
|
const getPopupContainer = useCallback(() => popupContainer.current, []);
|
|
|
|
const handleOnDropdownOpen = useCallback(() => {
|
|
if (!isOpen && onDropdownOpen) {
|
|
onDropdownOpen();
|
|
}
|
|
}, [onDropdownOpen, isOpen]);
|
|
|
|
const handleOnDropdownClose = useCallback(() => {
|
|
if (isOpen && onDropdownClose) {
|
|
onDropdownClose();
|
|
}
|
|
}, [onDropdownClose, isOpen]);
|
|
|
|
// When Dropdown is opened disable scrolling within the app except the list of options
|
|
const onOpen = useCallback(
|
|
(open: boolean) => {
|
|
setIsOpen(open);
|
|
|
|
if (open) {
|
|
handleOnDropdownOpen();
|
|
setTimeout(() => inputRef.current?.focus(), FOCUS_TIMEOUT);
|
|
|
|
// for more context, the Element we attach to in view mode doesn't have an overflow style, so this only applies to edit mode.
|
|
if (popupContainer.current && renderMode === RenderModes.CANVAS) {
|
|
popupContainer.current.style.overflowY = "hidden";
|
|
}
|
|
} else {
|
|
handleOnDropdownClose();
|
|
|
|
if (popupContainer.current && renderMode === RenderModes.CANVAS) {
|
|
popupContainer.current.style.overflowY = "auto";
|
|
}
|
|
|
|
selectRef.current?.blur();
|
|
}
|
|
},
|
|
[renderMode, handleOnDropdownOpen, handleOnDropdownOpen],
|
|
);
|
|
|
|
const closeBackDrop = useCallback(() => {
|
|
if (selectRef.current) {
|
|
selectRef.current.blur();
|
|
onOpen(false);
|
|
}
|
|
}, [onOpen]);
|
|
|
|
return {
|
|
BackDrop,
|
|
getPopupContainer,
|
|
onOpen,
|
|
isOpen,
|
|
selectRef,
|
|
onKeyDown,
|
|
};
|
|
};
|
|
|
|
export default useDropdown;
|