UNPKG

phx-react

Version:

PHX REACT

177 lines 14.8 kB
"use strict"; exports.__esModule = true; exports.PHXDropdown = void 0; var tslib_1 = require("tslib"); var react_1 = require("@headlessui/react"); var solid_1 = require("@heroicons/react/20/solid"); var OutlineIcons = tslib_1.__importStar(require("@heroicons/react/24/outline")); var SolidIcons = tslib_1.__importStar(require("@heroicons/react/24/solid")); var react_2 = tslib_1.__importStar(require("react")); var react_dom_1 = tslib_1.__importDefault(require("react-dom")); var types_1 = require("../types"); var Calendar_1 = tslib_1.__importDefault(require("../DatePicker/components/Calendar")); var Loading_1 = require("../Loading"); var PHXUrlApply_1 = tslib_1.__importDefault(require("../Func/PHXUrlApply/PHXUrlApply")); function PHXDropdown(_a) { var buttonContent = _a.buttonContent, className = _a.className, defaultDate = _a.defaultDate, disabledDate = _a.disabledDate, endDisabled = _a.endDisabled, loading = _a.loading, max = _a.max, min = _a.min, onChangeDate = _a.onChangeDate, optionTitle = _a.optionTitle, options = _a.options, _b = _a.origin, origin = _b === void 0 ? 'left' : _b, _c = _a.soft, soft = _c === void 0 ? false : _c, startDisabled = _a.startDisabled, _d = _a.type, type = _d === void 0 ? 'default' : _d, widthContent = _a.widthContent, _e = _a.isFullContentOption, isFullContentOption = _e === void 0 ? false : _e, _f = _a.disabled, disabled = _f === void 0 ? false : _f, configUrlApply = _a.configUrlApply, _g = _a.onlyResetValueUrl, onlyResetValueUrl = _g === void 0 ? false : _g; var _h = (0, react_2.useState)(null), portalElement = _h[0], setPortalElement = _h[1]; var menuButtonRef = (0, react_2.useRef)(null); var scrollContainerRef = (0, react_2.useRef)(null); var handleCloseRef = (0, react_2.useRef)(); function getDropdownButtonClass(_a) { var type = _a.type, soft = _a.soft, disabled = _a.disabled, open = _a.open, loading = _a.loading; var base = 'w-full group relative isolate flex items-center justify-center overflow-hidden rounded-lg transition duration-300 ease-[cubic-bezier(0.4,0.36,0,1)]'; if (disabled || loading) { return (0, types_1.classNames)(base, 'relative bg-indigo-50 px-2.5 pb-[0.42rem] pt-[0.45rem] text-xs font-normal shadow-sm text-gray-400 cursor-not-allowed'); } if (soft) { return (0, types_1.classNames)(base, 'bg-indigo-50 px-2.5 py-1.5 text-xs font-normal text-gray-700 shadow-sm hover:bg-indigo-100 active:pb-[0.3rem] active:pt-[0.45rem] active:shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]', open && '!bg-indigo-100 shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]'); } switch (type) { case 'icon-only': return (0, types_1.classNames)(base, 'flex items-center rounded-full bg-gray-100 text-gray-600 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 focus:ring-offset-gray-100'); case 'soft-small': return (0, types_1.classNames)(base, 'bg-gray-200 px-2 py-1 text-xs hover:bg-gray-300 active:pb-[0.2rem] active:pt-[0.35rem] active:shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]', open && '!bg-gray-300 shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]'); case 'ellipsis-icon': return (0, types_1.classNames)(base, 'flex items-center'); case 'default': case 'date-picker': default: return (0, types_1.classNames)(base, 'border border-gray-300 bg-white px-2.5 py-1.5 text-xs font-normal text-gray-900 shadow-sm hover:border-gray-400 active:border-b-gray-100 active:bg-gray-100 active:pb-[0.3rem] active:pt-[0.45rem] active:shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]', open && '!border-b-gray-300 !bg-gray-100 !shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]'); case 'primary': return (0, types_1.classNames)(base, 'border border-gray-300 bg-gray-900 px-2.5 py-1.5 text-xs font-normal text-white shadow-sm hover:border-gray-400 active:border-b-gray-100 active:bg-gray-400 active:pb-[0.3rem] active:pt-[0.45rem] active:shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]', open && '!border-b-gray-300 bg-gray-900 !shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]'); case 'danger': return (0, types_1.classNames)(base, 'border border-gray-300 bg-red-700 px-2.5 py-1.5 text-xs font-normal text-white shadow-sm hover:border-gray-400 active:border-b-gray-100 active:bg-red-400 active:pb-[0.3rem] active:pt-[0.45rem] active:shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]', open && '!border-b-gray-300 bg-red-700 !shadow-[0rem_0.125rem_0.1rem_0rem_#0004_inset]'); } } var calculatePosition = function () { if (menuButtonRef.current && portalElement) { var buttonRect = menuButtonRef.current.getBoundingClientRect(); portalElement.style.position = 'absolute'; switch (origin) { case 'left': portalElement.style.top = "".concat(buttonRect.bottom + window.scrollY, "px"); portalElement.style.left = "".concat(buttonRect.left + window.scrollX, "px"); break; case 'right': portalElement.style.top = "".concat(buttonRect.bottom + window.scrollY, "px"); portalElement.style.right = "".concat(window.innerWidth - buttonRect.right, "px"); break; case 'top-left': portalElement.style.top = "".concat(buttonRect.bottom + window.scrollY, "px"); portalElement.style.bottom = "".concat(window.innerHeight - buttonRect.top, "px"); portalElement.style.left = "".concat(buttonRect.left + window.scrollX, "px"); break; default: portalElement.style.top = "".concat(buttonRect.bottom + window.scrollY, "px"); portalElement.style.left = "".concat(buttonRect.left + window.scrollX, "px"); } } }; var handleClick = function (item) { if (item.disabled) return; if (item === null || item === void 0 ? void 0 : item.onClick) { item.onClick(); } (0, PHXUrlApply_1["default"])(item.key, item.id, item.listKeyReset, configUrlApply, onlyResetValueUrl); }; (0, react_2.useEffect)(function () { var element = document.createElement('div'); document.body.appendChild(element); setPortalElement(element); return function () { document.body.removeChild(element); }; }, []); (0, react_2.useEffect)(function () { // Tìm phần tử cha có scroll var findScrollContainer = function (element) { while (element) { var overflowY = window.getComputedStyle(element).overflowY; if (overflowY === 'scroll' || overflowY === 'auto') { return element; } element = element.parentElement; } return null; }; if (menuButtonRef.current) { scrollContainerRef.current = findScrollContainer(menuButtonRef.current); } }, []); (0, react_2.useEffect)(function () { if (portalElement) { calculatePosition(); } }, [portalElement]); (0, react_2.useEffect)(function () { var handleScrollAndResize = function (event) { calculatePosition(); var isScrollInsideDropdown = event.target instanceof Node && (portalElement === null || portalElement === void 0 ? void 0 : portalElement.contains(event.target)); if (!isScrollInsideDropdown && (handleCloseRef === null || handleCloseRef === void 0 ? void 0 : handleCloseRef.current)) { handleCloseRef.current(); } }; window.addEventListener('scroll', handleScrollAndResize, true); window.addEventListener('resize', handleScrollAndResize); if (scrollContainerRef.current) { scrollContainerRef.current.addEventListener('scroll', handleScrollAndResize); } return function () { window.removeEventListener('scroll', handleScrollAndResize, true); window.removeEventListener('resize', handleScrollAndResize); if (scrollContainerRef.current) { scrollContainerRef.current.removeEventListener('scroll', handleScrollAndResize); } }; }, [portalElement]); var Icon = function (_a) { var active = _a.active, icon = _a.icon, iconOutline = _a.iconOutline; // @ts-ignore var Icon = iconOutline ? OutlineIcons[icon] : SolidIcons[icon]; return react_2["default"].createElement(Icon, { className: (0, types_1.classNames)('h-4 w-4', active && 'font-semibold') }); }; var renderMenuItems = function () { return (react_2["default"].createElement(react_1.Transition, { as: react_2.Fragment, enter: 'transition ease-out duration-100', enterFrom: 'transform opacity-0 scale-95', enterTo: 'transform opacity-100 scale-100', leave: 'transition ease-in duration-75', leaveFrom: 'transform opacity-100 scale-100', leaveTo: 'transform opacity-0 scale-95' }, react_2["default"].createElement(react_1.Menu.Items, { className: (0, types_1.classNames)(origin === 'left' && 'left-0 origin-top-left', origin === 'right' && 'right-0 origin-top-right', origin === 'top-left' && 'bottom-8 left-0', type === 'date-picker' ? '' : 'border px-1', 'absolute z-50 mt-1.5 max-h-96 min-w-[7.2rem] overflow-y-auto overscroll-contain whitespace-nowrap rounded-lg bg-white shadow-[0rem_0.25rem_0.375rem_-0.125rem_rgba(26,26,26,.2)] focus:outline-none') }, type === 'date-picker' ? (react_2["default"].createElement(Calendar_1["default"], { defaultDate: defaultDate, disabledDate: disabledDate, endDisabled: endDisabled, max: max, min: min, onChangeDate: onChangeDate, startDisabled: startDisabled })) : (react_2["default"].createElement(react_2["default"].Fragment, null, optionTitle && react_2["default"].createElement("p", { className: 'px-2.5 pb-1 pt-2 text-xs font-semibold' }, optionTitle), react_2["default"].createElement("div", { className: 'py-1' }, options === null || options === void 0 ? void 0 : options.map(function (item) { return (react_2["default"].createElement(react_1.Menu.Item, { key: item.content }, function (_a) { var active = _a.active; return (react_2["default"].createElement("div", { className: (0, types_1.classNames)(item.disabled ? 'cursor-not-allowed !text-gray-400' : 'cursor-pointer', active && !item.disabled ? 'cursor-pointer rounded-lg bg-gray-100 text-gray-900' : 'text-gray-700', 'block px-2.5 py-2 text-xs', item.active && !item.destructive && !item.disabled && 'rounded-lg bg-gray-200 font-semibold text-gray-900', item.destructive && !item.active && !item.disabled && 'text-red-800 hover:bg-red-100', item.destructive && item.active && !item.disabled && 'rounded-lg bg-red-200 font-semibold text-red-800'), onClick: function () { handleClick(item); } }, react_2["default"].createElement("div", { className: (0, types_1.classNames)(item.icon && 'flex items-center gap-x-2') }, item.icon && react_2["default"].createElement(Icon, { active: item.active, icon: item.icon, iconOutline: item.iconOutline }), react_2["default"].createElement("p", { className: "".concat(widthContent, " overflow-ellipsis break-words ").concat(isFullContentOption ? 'whitespace-normal' : '') }, item.content)))); })); }))))))); }; return (react_2["default"].createElement("div", { className: (0, types_1.classNames)('relative max-w-full md:max-w-fit', type === 'ellipsis-icon' && 'flex items-center') }, react_2["default"].createElement(react_1.Menu, { as: 'div', className: (0, types_1.classNames)('relative inline-block w-full text-left', className && "".concat(className), type === 'ellipsis-icon' && 'flex items-center') }, function (_a) { var close = _a.close, open = _a.open; open && calculatePosition(); handleCloseRef.current = close; return (react_2["default"].createElement(react_2["default"].Fragment, null, react_2["default"].createElement("div", null, react_2["default"].createElement(react_1.Menu.Button, { disabled: disabled, ref: menuButtonRef, className: getDropdownButtonClass({ type: type, soft: soft, disabled: disabled, open: open, loading: loading }) }, react_2["default"].createElement("div", { className: (0, types_1.classNames)(['default', 'date-picker', 'soft-small', 'primary', 'danger'].includes(type) && "flex items-center justify-between gap-x-1 md:justify-center", type === 'ellipsis-icon' && 'flex items-center') }, react_2["default"].createElement("p", { className: (0, types_1.classNames)('max-w-[120px] truncate sm:max-w-full', type === 'icon-only' && 'sr-only') }, buttonContent), ['default', 'date-picker', 'soft-small', 'primary', 'danger'].includes(type) && (open && origin === 'top-left' ? (react_2["default"].createElement(solid_1.ChevronUpIcon, { "aria-hidden": 'true', className: 'mt-0.5 h-4 w-4' })) : (react_2["default"].createElement(solid_1.ChevronDownIcon, { "aria-hidden": 'true', className: 'mt-0.5 h-4 w-4' }))), type === 'icon-only' && react_2["default"].createElement(solid_1.EllipsisHorizontalIcon, { "aria-hidden": 'true', className: 'w-4 h-4' }), type === 'ellipsis-icon' && (react_2["default"].createElement("div", { className: "rounded-lg p-1 hover:bg-gray-300 ".concat(open ? 'bg-gray-200' : '') }, react_2["default"].createElement(solid_1.EllipsisHorizontalIcon, { "aria-hidden": 'true', className: 'w-4 h-4' })))))), portalElement ? react_dom_1["default"].createPortal(renderMenuItems(), portalElement) : null)); }), loading && (react_2["default"].createElement("div", { className: 'absolute left-[1px] top-[1px] flex h-[calc(100%-2px)] w-[calc(100%-2px)] items-center justify-center rounded-lg bg-gray-300' }, react_2["default"].createElement(Loading_1.PHXSpinner, { className: 'h-[16px] w-[16px] text-white' }))))); } exports.PHXDropdown = PHXDropdown; //# sourceMappingURL=Dropdown.js.map