UNPKG

analytica-frontend-lib

Version:

Repositório público dos componentes utilizados nas plataformas da Analytica Ensino

402 lines (401 loc) 14.4 kB
"use strict"; "use client"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/components/DropdownMenu/DropdownMenu.tsx var DropdownMenu_exports = {}; __export(DropdownMenu_exports, { DropdownMenuTrigger: () => DropdownMenuTrigger, MenuContent: () => MenuContent, MenuItem: () => MenuItem, MenuLabel: () => MenuLabel, MenuSeparator: () => MenuSeparator, ProfileMenuFooter: () => ProfileMenuFooter, ProfileMenuHeader: () => ProfileMenuHeader, ProfileMenuSection: () => ProfileMenuSection, ProfileMenuTrigger: () => ProfileMenuTrigger, createDropdownStore: () => createDropdownStore, default: () => DropdownMenu_default, useDropdownStore: () => useDropdownStore }); module.exports = __toCommonJS(DropdownMenu_exports); var import_phosphor_react = require("phosphor-react"); var import_react = require("react"); var import_zustand = require("zustand"); var import_jsx_runtime = require("react/jsx-runtime"); function createDropdownStore() { return (0, import_zustand.create)((set) => ({ open: false, setOpen: (open) => set({ open }) })); } var useDropdownStore = (externalStore) => { if (!externalStore) { throw new Error( "Component must be used within a DropdownMenu (store is missing)" ); } return externalStore; }; var injectStore = (children, store) => { return import_react.Children.map(children, (child) => { if ((0, import_react.isValidElement)(child)) { const typedChild = child; const newProps = { store }; if (typedChild.props.children) { newProps.children = injectStore(typedChild.props.children, store); } return (0, import_react.cloneElement)(typedChild, newProps); } return child; }); }; var DropdownMenu = ({ children, open, onOpenChange }) => { const storeRef = (0, import_react.useRef)(null); storeRef.current ??= createDropdownStore(); const store = storeRef.current; const isControlled = open !== void 0; const uncontrolledOpen = (0, import_zustand.useStore)(store, (s) => s.open); const currentOpen = isControlled ? open : uncontrolledOpen; const setOpen = (newOpen) => { onOpenChange?.(newOpen); if (!isControlled) store.setState({ open: newOpen }); }; const menuRef = (0, import_react.useRef)(null); const handleArrowDownOrArrowUp = (event) => { const menuContent = menuRef.current?.querySelector('[role="menu"]'); if (menuContent) { event.preventDefault(); const items = Array.from( menuContent.querySelectorAll( '[role="menuitem"]:not([aria-disabled="true"])' ) ).filter((el) => el instanceof HTMLElement); if (items.length === 0) return; const focusedItem = document.activeElement; const currentIndex = items.findIndex((item) => item === focusedItem); let nextIndex; if (event.key === "ArrowDown") { nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % items.length; } else { nextIndex = currentIndex === -1 ? items.length - 1 : (currentIndex - 1 + items.length) % items.length; } items[nextIndex]?.focus(); } }; const handleDownkey = (event) => { if (event.key === "Escape") { setOpen(false); } else if (event.key === "ArrowDown" || event.key === "ArrowUp") { handleArrowDownOrArrowUp(event); } }; const handleClickOutside = (event) => { if (menuRef.current && !menuRef.current.contains(event.target)) { setOpen(false); } }; (0, import_react.useEffect)(() => { onOpenChange?.(currentOpen); if (currentOpen) { document.addEventListener("mousedown", handleClickOutside); document.addEventListener("keydown", handleDownkey); } return () => { document.removeEventListener("mousedown", handleClickOutside); document.removeEventListener("keydown", handleDownkey); }; }, [currentOpen]); (0, import_react.useEffect)(() => { if (isControlled) { store.setState({ open }); } }, []); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative", ref: menuRef, children: injectStore(children, store) }); }; var DropdownMenuTrigger = (0, import_react.forwardRef)(({ className, children, onClick, store: externalStore, ...props }, ref) => { const store = useDropdownStore(externalStore); const open = (0, import_zustand.useStore)(store, (s) => s.open); const toggleOpen = () => store.setState({ open: !open }); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "button", { ref, className: `border border-border-200 cursor-pointer bg-background-muted hover:bg-background-200 transition-colors px-4 py-2 rounded-sm ${className}`, onClick: (e) => { e.stopPropagation(); toggleOpen(); if (onClick) onClick(e); }, "aria-expanded": open, ...props, children } ); }); DropdownMenuTrigger.displayName = "DropdownMenuTrigger"; var ITEM_SIZE_CLASSES = { small: "text-sm", medium: "text-md" }; var SIDE_CLASSES = { top: "bottom-full", right: "top-full", bottom: "top-full", left: "top-full" }; var ALIGN_CLASSES = { start: "left-0", center: "left-1/2 -translate-x-1/2", end: "right-0" }; var MenuLabel = (0, import_react.forwardRef)(({ className, inset, store: _store, ...props }, ref) => { return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "div", { ref, className: `text-sm w-full ${inset ? "pl-8" : ""} ${className ?? ""}`, ...props } ); }); MenuLabel.displayName = "MenuLabel"; var MenuContent = (0, import_react.forwardRef)( ({ className, align = "start", side = "bottom", sideOffset = 4, children, store: externalStore, ...props }, ref) => { const store = useDropdownStore(externalStore); const open = (0, import_zustand.useStore)(store, (s) => s.open); const [isVisible, setIsVisible] = (0, import_react.useState)(open); (0, import_react.useEffect)(() => { if (open) { setIsVisible(true); } else { const timer = setTimeout(() => setIsVisible(false), 200); return () => clearTimeout(timer); } }, [open]); if (!isVisible) return null; const getPositionClasses = () => { const vertical = SIDE_CLASSES[side]; const horizontal = ALIGN_CLASSES[align]; return `absolute ${vertical} ${horizontal}`; }; return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "div", { ref, role: "menu", className: ` bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md border-border-100 ${open ? "animate-in fade-in-0 zoom-in-95" : "animate-out fade-out-0 zoom-out-95"} ${getPositionClasses()} ${className} `, style: { marginTop: side === "bottom" ? sideOffset : void 0, marginBottom: side === "top" ? sideOffset : void 0, marginLeft: side === "right" ? sideOffset : void 0, marginRight: side === "left" ? sideOffset : void 0 }, ...props, children } ); } ); MenuContent.displayName = "MenuContent"; var MenuItem = (0, import_react.forwardRef)( ({ className, size = "small", children, iconRight, iconLeft, disabled = false, onClick, variant = "menu", store: externalStore, ...props }, ref) => { const store = useDropdownStore(externalStore); const setOpen = (0, import_zustand.useStore)(store, (s) => s.setOpen); const sizeClasses = ITEM_SIZE_CLASSES[size]; const handleClick = (e) => { if (disabled) { e.preventDefault(); e.stopPropagation(); return; } onClick?.(e); setOpen(false); }; const getVariantClasses = () => { if (variant === "profile") { return "relative flex flex-row justify-between select-none items-center gap-2 rounded-sm p-3 text-sm outline-none transition-colors [&>svg]:size-6 [&>svg]:shrink-0"; } return "relative flex select-none items-center gap-2 rounded-sm p-3 text-sm outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0"; }; const getVariantProps = () => { return variant === "profile" ? { "data-variant": "profile" } : {}; }; return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( "div", { ref, role: "menuitem", ...getVariantProps(), "aria-disabled": disabled, className: ` focus-visible:bg-background-50 ${getVariantClasses()} ${sizeClasses} ${className} ${disabled ? "cursor-not-allowed text-text-400" : "cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground"} `, onClick: handleClick, onKeyDown: (e) => { if (e.key === "Enter" || e.key === " ") handleClick(e); }, tabIndex: disabled ? -1 : 0, ...props, children: [ iconLeft, children, iconRight ] } ); } ); MenuItem.displayName = "MenuItem"; var MenuSeparator = (0, import_react.forwardRef)(({ className, store: _store, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "div", { ref, className: `my-1 h-px bg-border-200 ${className}`, ...props } )); MenuSeparator.displayName = "MenuSeparator"; var ProfileMenuTrigger = (0, import_react.forwardRef)(({ className, onClick, store: externalStore, ...props }, ref) => { const store = useDropdownStore(externalStore); const open = (0, import_zustand.useStore)(store, (s) => s.open); const toggleOpen = () => store.setState({ open: !open }); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "button", { ref, className: `rounded-lg size-10 bg-background-50 flex items-center justify-center ${className}`, onClick: (e) => { e.stopPropagation(); toggleOpen(); onClick?.(e); }, "aria-expanded": open, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "size-6 rounded-full bg-background-100 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_phosphor_react.User, { className: "text-background-950", size: 18 }) }) } ); }); ProfileMenuTrigger.displayName = "ProfileMenuTrigger"; var ProfileMenuHeader = (0, import_react.forwardRef)(({ className, name, email, store: _store, ...props }, ref) => { return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( "div", { ref, "data-component": "ProfileMenuHeader", className: ` flex flex-row gap-4 items-center ${className} `, ...props, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "size-16 bg-background-100 rounded-full flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_phosphor_react.User, { size: 34, className: "text-background-950" }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col ", children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xl font-bold text-text-950", children: name }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-md text-text-600", children: email }) ] }) ] } ); }); ProfileMenuHeader.displayName = "ProfileMenuHeader"; var ProfileMenuSection = (0, import_react.forwardRef)(({ className, children, store: _store, ...props }, ref) => { return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "div", { ref, className: ` flex flex-col p-2 ${className} `, ...props, children } ); }); ProfileMenuSection.displayName = "ProfileMenuSection"; var ProfileMenuFooter = (0, import_react.forwardRef)( ({ className, disabled = false, onClick, store: externalStore, ...props }, ref) => { const store = useDropdownStore(externalStore); const setOpen = (0, import_zustand.useStore)(store, (s) => s.setOpen); return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( "button", { ref, className: `inline-flex items-center justify-center rounded-full cursor-pointer font-medium text-md px-5 py-2.5 w-full bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed ${className}`, disabled, onClick: (e) => { setOpen(false); onClick?.(e); }, ...props, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mr-2 flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_phosphor_react.SignOut, {}) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Sair" }) ] } ); } ); ProfileMenuFooter.displayName = "ProfileMenuFooter"; var DropdownMenu_default = DropdownMenu; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { DropdownMenuTrigger, MenuContent, MenuItem, MenuLabel, MenuSeparator, ProfileMenuFooter, ProfileMenuHeader, ProfileMenuSection, ProfileMenuTrigger, createDropdownStore, useDropdownStore }); //# sourceMappingURL=index.js.map