2022-06-09 08:56:31 +00:00
|
|
|
import React, { useCallback, useRef } from "react";
|
2022-06-09 08:38:08 +00:00
|
|
|
import { getMainCanvas } from "./WidgetUtils";
|
|
|
|
|
import styled from "styled-components";
|
|
|
|
|
import Select from "rc-select";
|
|
|
|
|
import { LabelValueType } from "rc-select/lib/interface/generator";
|
|
|
|
|
import { RenderMode, RenderModes } from "constants/WidgetConstants";
|
|
|
|
|
|
|
|
|
|
const BackDropContainer = styled.div`
|
|
|
|
|
position: fixed;
|
|
|
|
|
width: 100vw;
|
|
|
|
|
height: 100vh;
|
|
|
|
|
background: transparent;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
type useDropdownProps = {
|
|
|
|
|
inputRef: React.RefObject<HTMLInputElement>;
|
|
|
|
|
renderMode?: RenderMode;
|
|
|
|
|
};
|
|
|
|
|
const FOCUS_TIMEOUT = 500;
|
|
|
|
|
|
|
|
|
|
// TODO: Refactor More functionalities in MultiSelect, MultiTreeSelect and TreeSelect Components
|
2022-06-09 09:31:02 +00:00
|
|
|
const useDropdown = ({ inputRef, renderMode }: useDropdownProps) => {
|
2022-06-09 08:56:31 +00:00
|
|
|
const popupContainer = useRef<HTMLElement>(getMainCanvas());
|
2022-06-09 09:31:02 +00:00
|
|
|
const selectRef = useRef<Select<LabelValueType[]> | null>(null);
|
2022-06-09 08:38:08 +00:00
|
|
|
|
|
|
|
|
const closeBackDrop = useCallback(() => {
|
|
|
|
|
if (selectRef.current) {
|
|
|
|
|
selectRef.current.blur();
|
|
|
|
|
}
|
|
|
|
|
}, []);
|
|
|
|
|
|
2022-06-22 00:11:29 +00:00
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2022-06-09 08:38:08 +00:00
|
|
|
// Avoid scrolls when Popup is opened
|
|
|
|
|
function BackDrop() {
|
|
|
|
|
return <BackDropContainer onClick={closeBackDrop} />;
|
|
|
|
|
}
|
2022-06-09 08:56:31 +00:00
|
|
|
// Get PopupContainer on main Canvas
|
|
|
|
|
const getPopupContainer = useCallback(() => popupContainer.current, []);
|
2022-06-09 08:38:08 +00:00
|
|
|
|
|
|
|
|
// When Dropdown is opened disable scrolling within the app except the list of options
|
2022-06-09 09:31:02 +00:00
|
|
|
const onOpen = useCallback(
|
|
|
|
|
(open: boolean) => {
|
|
|
|
|
if (open) {
|
|
|
|
|
setTimeout(() => inputRef.current?.focus(), FOCUS_TIMEOUT);
|
2022-06-09 12:50:17 +00:00
|
|
|
// for more context, the Element we attach to in view mode doesn't have an overflow style, so this only applies to edit mode.
|
2022-06-09 09:31:02 +00:00
|
|
|
if (popupContainer.current && renderMode === RenderModes.CANVAS) {
|
|
|
|
|
popupContainer.current.style.overflowY = "hidden";
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (popupContainer.current && renderMode === RenderModes.CANVAS) {
|
|
|
|
|
popupContainer.current.style.overflowY = "auto";
|
|
|
|
|
}
|
2022-06-09 08:38:08 +00:00
|
|
|
}
|
2022-06-09 09:31:02 +00:00
|
|
|
},
|
|
|
|
|
[renderMode],
|
|
|
|
|
);
|
2022-06-09 08:38:08 +00:00
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
BackDrop,
|
|
|
|
|
getPopupContainer,
|
|
|
|
|
onOpen,
|
2022-06-09 09:31:02 +00:00
|
|
|
selectRef,
|
2022-06-22 00:11:29 +00:00
|
|
|
onKeyDown,
|
2022-06-09 08:38:08 +00:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default useDropdown;
|