UNPKG

@codeworker.br/govbr-tw-react

Version:

Biblioteca de componentes React usando Tailwind CSS que implementa o Padrão Digital de Governo.

181 lines (180 loc) 9.24 kB
var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { createContext, forwardRef, useContext, useEffect, useImperativeHandle, useLayoutEffect, useRef, } from "react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faXmark } from "@fortawesome/free-solid-svg-icons"; import { Button } from "../Button"; import BASE_CLASSNAMES from "../../config/baseClassNames"; import { cn } from "../../libs/utils"; import { sheetViewportVariants, sheetContentVariants, sheetHeaderVariants, sheetBodyVariants, sheetFooterVariants, } from "./variants"; const TRANSITION_DURATION = 300; const SheetContext = createContext(null); const useSheetContext = () => { const context = useContext(SheetContext); if (!context) { throw new Error("Sheet compound components must be used within Sheet."); } return context; }; const closeButtonVariantByTheme = { default: "ghost", dark: "ghost-dark", }; const overlayFallbackClassByVariant = { default: "backdrop:bg-black/50", dark: "backdrop:bg-govbr-blue-warm-vivid-90/80", // exemplo de overlay customizado usando Tailwind }; const SheetClose = forwardRef((_a, ref) => { var { className, variant, onClick, type } = _a, props = __rest(_a, ["className", "variant", "onClick", "type"]); const { toggleDialog, variant: sheetVariant } = useSheetContext(); return (_jsx(Button, Object.assign({ ref: ref, type: type !== null && type !== void 0 ? type : "button", size: "icon", variant: variant !== null && variant !== void 0 ? variant : closeButtonVariantByTheme[sheetVariant], onClick: (event) => { onClick === null || onClick === void 0 ? void 0 : onClick(event); if (event.defaultPrevented) { return; } toggleDialog(); }, className: cn(BASE_CLASSNAMES.sheet.close, className) }, props, { children: _jsx(FontAwesomeIcon, { icon: faXmark }) }))); }); SheetClose.displayName = "SheetClose"; const SheetForwardRef = forwardRef((_a, ref) => { var { children, toggleDialog, side, variant, padding = true, density, persist, closeOnEsc, showCloseButton = true, containerClassName, className, overlayClassName, closeButtonLabel = "Fechar painel", closeButtonProps } = _a, dialogProps = __rest(_a, ["children", "toggleDialog", "side", "variant", "padding", "density", "persist", "closeOnEsc", "showCloseButton", "containerClassName", "className", "overlayClassName", "closeButtonLabel", "closeButtonProps"]); const resolvedVariant = (variant !== null && variant !== void 0 ? variant : "default"); const resolvedSide = (side !== null && side !== void 0 ? side : "left"); const resolvedDensity = density !== null && density !== void 0 ? density : (padding ? "relaxed" : "none"); const resolvedOverlayClassName = cn("bg-transparent", overlayFallbackClassByVariant[resolvedVariant], overlayClassName); const dialogRef = useRef(null); const panelRef = useRef(null); useImperativeHandle(ref, () => dialogRef.current, []); useEffect(() => { const dialog = dialogRef.current; if (!dialog) { return; } const handleCancel = (event) => { if (closeOnEsc === false) { event.preventDefault(); } }; dialog.addEventListener("cancel", handleCancel); return () => { dialog.removeEventListener("cancel", handleCancel); }; }, [closeOnEsc]); useLayoutEffect(() => { const dialog = dialogRef.current; if (!dialog) { return; } const marker = "__govbr_sheet_patched__"; if (dialog[marker]) { return; } dialog[marker] = true; const originalShowModal = dialog.showModal.bind(dialog); const originalClose = dialog.close.bind(dialog); let closeTimer = null; dialog.showModal = (...args) => { if (closeTimer) { window.clearTimeout(closeTimer); closeTimer = null; } const panel = panelRef.current; if (panel) { panel.dataset.motion = "opening"; void panel.getBoundingClientRect(); } const result = originalShowModal(...args); requestAnimationFrame(() => { const currentPanel = panelRef.current; if (currentPanel) { currentPanel.dataset.motion = "open"; } }); return result; }; dialog.close = (returnValue) => { const panel = panelRef.current; if (!panel) { originalClose(returnValue); return; } if (panel.dataset.motion === "closing") { return; } panel.dataset.motion = "closing"; if (closeTimer) { window.clearTimeout(closeTimer); } closeTimer = window.setTimeout(() => { panel.dataset.motion = "closed"; originalClose(returnValue); closeTimer = null; }, TRANSITION_DURATION); }; return () => { if (closeTimer) { window.clearTimeout(closeTimer); } dialog.showModal = originalShowModal; dialog.close = originalClose; delete dialog[marker]; }; }, []); useLayoutEffect(() => { var _a; const panel = panelRef.current; if (!panel) { return; } if (!panel.dataset.motion) { panel.dataset.motion = "closed"; } if ((_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.open) { panel.dataset.motion = "open"; } }, []); const _b = closeButtonProps !== null && closeButtonProps !== void 0 ? closeButtonProps : {}, { className: closeButtonClassName } = _b, closeButtonRest = __rest(_b, ["className"]); const { onClick: dialogOnClick } = dialogProps, restDialogProps = __rest(dialogProps, ["onClick"]); return (_jsx("dialog", Object.assign({ ref: dialogRef, className: resolvedOverlayClassName, onClick: (event) => { dialogOnClick === null || dialogOnClick === void 0 ? void 0 : dialogOnClick(event); if (event.defaultPrevented) { return; } if (!persist && event.currentTarget === event.target) { toggleDialog(); } } }, restDialogProps, { children: _jsx(SheetContext.Provider, { value: { variant: resolvedVariant, side: resolvedSide, density: resolvedDensity, toggleDialog }, children: _jsx("div", { className: cn(sheetViewportVariants({ side: resolvedSide }), containerClassName, BASE_CLASSNAMES.sheet.root, BASE_CLASSNAMES.sheet.container), children: _jsxs("div", { ref: (node) => { panelRef.current = node; }, className: cn(sheetContentVariants({ side: resolvedSide, variant: resolvedVariant }), className, BASE_CLASSNAMES.sheet.panel), "data-side": resolvedSide, children: [showCloseButton ? (_jsx(SheetClose, Object.assign({ "aria-label": closeButtonLabel, className: cn("absolute right-4 top-4", closeButtonClassName) }, closeButtonRest))) : null, _jsx("div", { className: "flex h-full flex-col", "data-side": resolvedSide, children: children })] }) }) }) }))); }); SheetForwardRef.displayName = "Sheet"; const SheetHeader = forwardRef((_a, ref) => { var { className } = _a, props = __rest(_a, ["className"]); const { variant, density } = useSheetContext(); return (_jsx("header", Object.assign({ ref: ref, className: cn(sheetHeaderVariants({ variant, density }), className, BASE_CLASSNAMES.sheet.header) }, props))); }); SheetHeader.displayName = "SheetHeader"; const SheetMain = forwardRef((_a, ref) => { var { className } = _a, props = __rest(_a, ["className"]); const { density } = useSheetContext(); return (_jsx("main", Object.assign({ ref: ref, className: cn(sheetBodyVariants({ density }), className, BASE_CLASSNAMES.sheet.main) }, props))); }); SheetMain.displayName = "SheetMain"; const SheetFooter = forwardRef((_a, ref) => { var { className } = _a, props = __rest(_a, ["className"]); const { variant, density } = useSheetContext(); return (_jsx("footer", Object.assign({ ref: ref, className: cn(sheetFooterVariants({ variant, density }), className, BASE_CLASSNAMES.sheet.footer) }, props))); }); SheetFooter.displayName = "SheetFooter"; const Sheet = Object.assign(Object.assign({}, SheetForwardRef), { Header: SheetHeader, Main: SheetMain, Footer: SheetFooter, Close: SheetClose }); export default Sheet;