UNPKG

kedao

Version:

Rich Text Editor Based On Draft.js

79 lines (78 loc) 4.17 kB
import { classNameParser } from '../../utils/style'; import React, { useState, useEffect, useRef, forwardRef, useImperativeHandle, useCallback } from 'react'; import mergeClassNames from 'merge-class-names'; import styles from "./style.module.css"; import { useClickOutside, usePrevious, useSyncedRef, useWindowSize } from '@react-hookz/web'; import ChevronDownIcon from 'tabler-icons-react/dist/icons/chevron-down'; import { tablerIconProps } from '../../constants'; const cls = classNameParser(styles); const DropDown = forwardRef(({ disabled, autoHide, getContainerNode, caption, htmlCaption, title, showArrow = true, arrowActive, isActive, onActiveChage, className, children }, ref) => { const latestIsActive = useSyncedRef(isActive); const [activeState, setActive] = useState(false); const active = latestIsActive.current === undefined ? activeState : latestIsActive.current; // 兼容受控与非受控 const [offset, setOffset] = useState(0); const dropDownHandlerElement = useRef(null); const dropDownContentElement = useRef(null); const size = useWindowSize(); const fixDropDownPosition = () => { var _a, _b; const viewRect = getContainerNode().getBoundingClientRect(); const handlerRect = (_a = dropDownHandlerElement.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect(); const contentRect = (_b = dropDownContentElement.current) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect(); let newOffset = 0; let right = handlerRect.right - handlerRect.width / 2 + contentRect.width / 2; let left = handlerRect.left + handlerRect.width / 2 - contentRect.width / 2; right = viewRect.right - right; left -= viewRect.left; if (right < 10) { newOffset = right - 10; } else if (left < 10) { newOffset = left * -1 + 10; } if (newOffset !== offset) { setOffset(newOffset); } }; useEffect(fixDropDownPosition, [size]); useEffect(() => { if (disabled) { hide(); } }, [disabled]); const previousActive = usePrevious(active); useEffect(() => { if (active && active !== previousActive) { fixDropDownPosition(); } }, [active]); const autoHideHandler = useCallback(() => { if (autoHide && active) { hide(); } }, [autoHide, active]); useClickOutside(dropDownContentElement, autoHideHandler); const toggle = () => { onActiveChage === null || onActiveChage === void 0 ? void 0 : onActiveChage(!active); setActive((active) => !active); }; const hide = () => { onActiveChage === null || onActiveChage === void 0 ? void 0 : onActiveChage(false); setActive(false); }; useImperativeHandle(ref, () => { return { hide, toggle }; }, [hide, toggle]); return (React.createElement("div", { className: cls(mergeClassNames('kedao-dropdown', !disabled && active && 'active', disabled && 'disabled', className)) }, htmlCaption ? (React.createElement("button", { type: "button", className: cls('dropdown-handler'), "data-title": title, "aria-label": "Button", onClick: toggle, dangerouslySetInnerHTML: htmlCaption ? { __html: htmlCaption } : null, ref: dropDownHandlerElement })) : (React.createElement("button", { type: "button", className: cls('dropdown-handler'), "data-title": title, onClick: toggle, ref: dropDownHandlerElement }, React.createElement("span", null, caption), showArrow ? React.createElement(ChevronDownIcon, Object.assign({}, tablerIconProps, { size: 16 })) : null)), React.createElement("div", { className: cls('dropdown-content'), style: { marginLeft: offset }, ref: dropDownContentElement }, React.createElement("i", { style: { marginLeft: offset * -1 }, className: cls(mergeClassNames('dropdown-arrow', arrowActive && 'active')) }), React.createElement("div", { className: cls('dropdown-content-inner') }, children)))); }); export default DropDown;