@zauru-sdk/components 6.15.0 → 6.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [6.16.0](https://github.com/intuitiva/zauru-typescript-sdk/compare/@zauru-sdk/components@6.15.1...@zauru-sdk/components@6.16.0) (2026-10-29)
7
+
8
+
9
+ ### Features
10
+
11
+ * rehacer el NavBar mobile y heredar el color de la app ([f1ab276](https://github.com/intuitiva/zauru-typescript-sdk/commit/f1ab276b6717e7a82e36ad71285b164d43ce243f))
12
+
13
+
14
+
15
+
16
+
17
+ ## [6.15.1](https://github.com/intuitiva/zauru-typescript-sdk/compare/@zauru-sdk/components@6.15.0...@zauru-sdk/components@6.15.1) (2026-10-28)
18
+
19
+ **Note:** Version bump only for package @zauru-sdk/components
20
+
21
+
22
+
23
+
24
+
6
25
  # [6.15.0](https://github.com/intuitiva/zauru-typescript-sdk/compare/@zauru-sdk/components@6.14.2...@zauru-sdk/components@6.15.0) (2026-10-28)
7
26
 
8
27
 
@@ -1,41 +1,100 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import React, { useState, useEffect, useMemo } from "react";
3
- import { DropDownArrowSvgIcon, LogoutDropDownSvgIcon, MenuAlt4Svg, OpcionButtonSvgIcon, } from "@zauru-sdk/icons";
2
+ import { useEffect, useId, useMemo, useRef, useState, } from "react";
3
+ import { DropDownArrowSvgIcon, ExitSvg, LogoutDropDownSvgIcon, MenuAlt4Svg, OpcionButtonSvgIcon, } from "@zauru-sdk/icons";
4
4
  import { COLORS } from "./NavBar.utils.js";
5
- import { Link, useNavigate, useLocation } from "@remix-run/react";
5
+ import { Link, useLocation, useNavigate } from "@remix-run/react";
6
6
  import { useAppSelector } from "@zauru-sdk/redux";
7
- const OptionsDropDownButton = ({ color, options, name, ariaLabel, }) => {
8
- const [showOptionsMenu, setShowOptionsMenu] = useState(true);
9
- return (_jsx("div", { className: "nav-item ml-auto", children: _jsx("div", { className: "flex justify-center", children: _jsxs("div", { className: "relative inline-block", children: [_jsxs("button", { type: "button", "aria-label": ariaLabel ?? (typeof name === "string" ? name : "Menú"), "aria-haspopup": "menu", "aria-expanded": !showOptionsMenu, onClick: () => setShowOptionsMenu(!showOptionsMenu), className: `relative flex cursor-pointer items-center p-2 text-xs text-white ${color.bg700} active:${color.bg900} border border-transparent rounded-full uppercase focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2`, children: [name ?? _jsx(OpcionButtonSvgIcon, {}), _jsx(DropDownArrowSvgIcon, {})] }), _jsx("div", { className: "absolute right-0 z-20 w-56 py-2 mt-2 overflow-hidden bg-white rounded-md shadow-xl dark:bg-gray-800", hidden: showOptionsMenu, onMouseLeave: () => setShowOptionsMenu(true), children: options.map((option, index) => (_jsx(React.Fragment, { children: option }, index))) })] }) }) }));
7
+ const itemColor = (item, fallback) => item.selectedColor ? COLORS[item.selectedColor] : fallback;
8
+ const visibleChildrenOf = (item) => (item.childrens ?? []).filter((child) => child.hide !== true);
9
+ const pathMatches = (pathname, link) => {
10
+ if (!link)
11
+ return false;
12
+ return pathname === link || pathname.startsWith(`${link}/`);
10
13
  };
11
- const NavItem = ({ name, link, icon, selectedColor, childrens = [], reduxNotificationBadge, }) => {
12
- const location = useLocation();
13
- const isActive = location.pathname === link;
14
- const specialColor = selectedColor
15
- ? COLORS[selectedColor]
16
- : COLORS["slate"];
17
- // Selecciona solo la parte del estado relevante
18
- const relevantState = useAppSelector((state) => reduxNotificationBadge ? reduxNotificationBadge(state) : undefined);
14
+ const focusRing = "focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-transparent";
15
+ const desktopTriggerClass = (color, isActive) => `inline-flex min-h-11 cursor-pointer items-center gap-1 rounded-full px-4 text-xs font-medium uppercase leading-none text-white transition-opacity duration-150 motion-reduce:transition-none ${isActive ? color.bg900 : color.bg700} hover:opacity-90 ${focusRing}`;
16
+ const mobileRowClass = (isActive) => `flex min-h-11 w-full cursor-pointer items-center gap-2 rounded-lg px-3 text-left text-sm font-medium text-white transition-colors duration-150 motion-reduce:transition-none hover:bg-white/10 ${focusRing} ${isActive ? "bg-white/15" : ""}`;
17
+ const dropdownItemClass = (danger) => `flex min-h-11 w-full cursor-pointer items-center gap-2 px-4 text-sm transition-colors duration-150 motion-reduce:transition-none ${danger
18
+ ? "text-red-700 hover:bg-red-50"
19
+ : "text-gray-700 hover:bg-gray-100"}`;
20
+ const NotificationBadge = ({ value }) => (_jsx("span", { className: "absolute -top-1.5 -right-1.5 flex h-5 min-w-5 items-center justify-center rounded-full bg-red-500 px-1 text-xs font-bold text-white", children: value }));
21
+ const useNotificationBadge = (item) => {
22
+ const relevantState = useAppSelector((state) => item.reduxNotificationBadge
23
+ ? item.reduxNotificationBadge(state)
24
+ : undefined);
19
25
  const [notificationBadge, setNotificationBadge] = useState();
20
26
  useEffect(() => {
21
27
  setNotificationBadge(relevantState);
22
28
  }, [relevantState]);
23
- // Si este NavItem tiene elementos hijos, renderiza el botón desplegable:
24
- if (childrens.length > 0) {
25
- return (_jsx(OptionsDropDownButton, { name: name, color: specialColor, options: childrens.map((x, index) => (_jsx(Link, { to: x.link, className: `block px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-red-100 dark:hover:bg-gray-700 dark:hover:text-white`, children: x.name }, index))) }));
29
+ return notificationBadge;
30
+ };
31
+ const Chevron = ({ open }) => (_jsx("span", { className: `inline-flex shrink-0 transition-transform duration-150 motion-reduce:transition-none ${open ? "rotate-180" : ""}`, "aria-hidden": "true", children: _jsx(DropDownArrowSvgIcon, {}) }));
32
+ const NavLinkItem = ({ item, color, layout, onNavigate, }) => {
33
+ const location = useLocation();
34
+ const isActive = pathMatches(location.pathname, item.link);
35
+ const notificationBadge = useNotificationBadge(item);
36
+ const palette = itemColor(item, color);
37
+ if (layout === "mobile") {
38
+ return (_jsx("li", { children: _jsxs(Link, { to: item.link, "aria-current": isActive ? "page" : undefined, onClick: onNavigate, className: `${mobileRowClass(isActive)} relative`, children: [item.icon, _jsx("span", { className: "flex-1", children: item.name }), notificationBadge !== undefined && (_jsx(NotificationBadge, { value: notificationBadge }))] }) }));
39
+ }
40
+ return (_jsx("li", { className: "relative", children: _jsxs(Link, { to: item.link, "aria-current": isActive ? "page" : undefined, className: `${desktopTriggerClass(palette, isActive)} relative`, children: [item.icon, _jsx("span", { children: item.name }), notificationBadge !== undefined && (_jsx(NotificationBadge, { value: notificationBadge }))] }) }));
41
+ };
42
+ const NavItemGroup = ({ item, color, layout, open, onToggle, onNavigate, }) => {
43
+ const location = useLocation();
44
+ const children = visibleChildrenOf(item);
45
+ const childActive = children.some((child) => pathMatches(location.pathname, child.link));
46
+ const palette = itemColor(item, color);
47
+ const menuId = useId();
48
+ if (children.length === 0) {
49
+ return null;
26
50
  }
27
- // Si NO tiene elementos hijos, se renderiza como un ítem simple:
28
- return (_jsx("li", { className: "nav-item relative", children: _jsx("div", {
29
- // Si está activo, usamos color de fondo más oscuro (bg900)
30
- // De lo contrario, usamos el color normal (bg700)
31
- className: `${isActive ? specialColor.bg900 : specialColor.bg700} container text-white w-full sm:w-auto h-10 text-sm py-1 uppercase shadow hover:shadow-lg outline-none rounded-full focus:outline-none my-auto sm:my-0 sm:mr-1 mb-1 ease-linear transition-all duration-150`, children: _jsxs(Link, { className: "px-3 flex items-center text-xs leading-snug text-white uppercase hover:opacity-75 relative", to: link, children: [_jsxs("div", { className: "mx-auto pt-2", children: [icon, _jsx("span", { children: name })] }), notificationBadge !== undefined && (_jsx("span", { className: "absolute -top-2 -right-2 bg-red-500 text-white text-xs font-bold rounded-full flex items-center justify-center w-5 h-5", children: notificationBadge }))] }) }) }));
51
+ if (layout === "mobile") {
52
+ return (_jsxs("li", { children: [_jsxs("button", { type: "button", "aria-expanded": open, "aria-controls": menuId, onClick: onToggle, className: mobileRowClass(childActive), children: [item.icon, _jsx("span", { className: "flex-1", children: item.name }), _jsx(Chevron, { open: open })] }), _jsx("ul", { id: menuId, hidden: !open, className: "mt-1 ml-3 space-y-1 border-l border-white/20 pl-2", children: children.map((child) => {
53
+ const isActive = pathMatches(location.pathname, child.link);
54
+ return (_jsx("li", { children: _jsxs(Link, { to: child.link, "aria-current": isActive ? "page" : undefined, onClick: onNavigate, className: mobileRowClass(isActive), children: [child.icon, _jsx("span", { children: child.name })] }) }, child.link));
55
+ }) })] }));
56
+ }
57
+ return (_jsxs("li", { className: "relative", children: [_jsxs("button", { type: "button", "aria-haspopup": "menu", "aria-expanded": open, "aria-controls": menuId, onClick: onToggle, className: desktopTriggerClass(palette, childActive), children: [item.icon, _jsx("span", { children: item.name }), _jsx(Chevron, { open: open })] }), _jsx("div", { id: menuId, role: "menu", hidden: !open, className: "absolute left-0 z-30 mt-2 min-w-[14rem] overflow-hidden rounded-md bg-white py-1 shadow-lg ring-1 ring-black/5", children: children.map((child) => (_jsxs(Link, { role: "menuitem", to: child.link, onClick: onNavigate, className: dropdownItemClass(), children: [child.icon, _jsx("span", { children: child.name })] }, child.link))) })] }));
58
+ };
59
+ const UserMenu = ({ color, layout, open, onToggle, onNavigate, entries, }) => {
60
+ const menuId = useId();
61
+ if (entries.length === 0) {
62
+ return null;
63
+ }
64
+ if (layout === "mobile") {
65
+ return (_jsxs("div", { className: "mt-4 border-t border-white/20 pt-4", children: [_jsx("p", { className: "px-3 pb-2 text-xs font-semibold uppercase tracking-wide text-white/70", children: "Cuenta" }), _jsx("ul", { className: "space-y-1", children: entries.map((entry) => (_jsx("li", { children: entry.to ? (_jsxs(Link, { to: entry.to, onClick: onNavigate, className: `${mobileRowClass(false)} [&_svg]:!text-current ${entry.danger ? "text-red-100 hover:bg-red-500/20" : ""}`, children: [entry.icon, _jsx("span", { children: entry.label })] })) : (_jsxs("button", { type: "button", onClick: () => {
66
+ entry.onClick?.();
67
+ onNavigate?.();
68
+ }, className: `${mobileRowClass(false)} [&_svg]:!text-current`, children: [entry.icon, _jsx("span", { children: entry.label })] })) }, entry.key))) })] }));
69
+ }
70
+ return (_jsxs("div", { className: "relative ml-auto", children: [_jsxs("button", { type: "button", "aria-label": "Men\u00FA de usuario", "aria-haspopup": "menu", "aria-expanded": open, "aria-controls": menuId, onClick: onToggle, className: `${desktopTriggerClass(color, open)} p-0 px-3`, children: [_jsx(OpcionButtonSvgIcon, {}), _jsx(Chevron, { open: open })] }), _jsx("div", { id: menuId, role: "menu", hidden: !open, className: "absolute right-0 z-30 mt-2 w-56 overflow-hidden rounded-md bg-white py-1 shadow-lg ring-1 ring-black/5", children: entries.map((entry) => entry.to ? (_jsxs(Link, { role: "menuitem", to: entry.to, onClick: onNavigate, className: dropdownItemClass(entry.danger), children: [entry.icon, _jsx("span", { children: entry.label })] }, entry.key)) : (_jsxs("button", { type: "button", role: "menuitem", onClick: () => {
71
+ entry.onClick?.();
72
+ onNavigate?.();
73
+ }, className: dropdownItemClass(entry.danger), children: [entry.icon, _jsx("span", { children: entry.label })] }, entry.key))) })] }));
32
74
  };
75
+ const NavItems = ({ items, color, layout, openMenuId, setOpenMenuId, onNavigate, }) => (_jsx("ul", { className: layout === "mobile"
76
+ ? "flex flex-col gap-1"
77
+ : "flex flex-wrap items-center gap-1", children: items.map((item, index) => {
78
+ const children = visibleChildrenOf(item);
79
+ const menuKey = `${item.name}-${index}`;
80
+ if (children.length > 0) {
81
+ return (_jsx(NavItemGroup, { item: item, color: color, layout: layout, open: openMenuId === menuKey, onToggle: () => setOpenMenuId(openMenuId === menuKey ? null : menuKey), onNavigate: onNavigate }, menuKey));
82
+ }
83
+ return (_jsx(NavLinkItem, { item: item, color: color, layout: layout, onNavigate: onNavigate }, menuKey));
84
+ }) }));
33
85
  export const NavBar = ({ title, loggedIn, items, selectedColor, version, reloadCatalogsOption, settingsOption, showDarkModeToggle = false, }) => {
34
86
  const color = COLORS[selectedColor];
35
- const [NavBarOpen, setNavBarOpen] = useState(false);
87
+ const [navOpen, setNavOpen] = useState(false);
88
+ const [openMenuId, setOpenMenuId] = useState(null);
36
89
  const [currentVersion, setCurrentVersion] = useState(version);
37
90
  const [isDarkMode, setIsDarkMode] = useState(false);
38
91
  const navigate = useNavigate();
92
+ const location = useLocation();
93
+ const desktopMenuRef = useRef(null);
94
+ const mobileDrawerRef = useRef(null);
95
+ const wasNavOpen = useRef(false);
96
+ const mobileNavId = useId();
97
+ const visibleItems = useMemo(() => items.filter((item) => item.loggedIn === loggedIn && item.hide !== true), [items, loggedIn]);
39
98
  useEffect(() => {
40
99
  document.documentElement.classList.toggle("dark", isDarkMode);
41
100
  }, [isDarkMode]);
@@ -44,24 +103,107 @@ export const NavBar = ({ title, loggedIn, items, selectedColor, version, reloadC
44
103
  setCurrentVersion(version);
45
104
  }
46
105
  }, [version, currentVersion]);
47
- const refreshPage = () => {
48
- navigate(0);
106
+ useEffect(() => {
107
+ setNavOpen(false);
108
+ setOpenMenuId(null);
109
+ }, [location.pathname]);
110
+ useEffect(() => {
111
+ if (!navOpen)
112
+ return;
113
+ const previousOverflow = document.body.style.overflow;
114
+ document.body.style.overflow = "hidden";
115
+ return () => {
116
+ document.body.style.overflow = previousOverflow;
117
+ };
118
+ }, [navOpen]);
119
+ useEffect(() => {
120
+ const drawer = mobileDrawerRef.current;
121
+ if (!drawer)
122
+ return;
123
+ if (navOpen) {
124
+ drawer.removeAttribute("inert");
125
+ }
126
+ else {
127
+ drawer.setAttribute("inert", "");
128
+ }
129
+ }, [navOpen]);
130
+ useEffect(() => {
131
+ const onKeyDown = (event) => {
132
+ if (event.key !== "Escape")
133
+ return;
134
+ setNavOpen(false);
135
+ setOpenMenuId(null);
136
+ };
137
+ document.addEventListener("keydown", onKeyDown);
138
+ return () => document.removeEventListener("keydown", onKeyDown);
139
+ }, []);
140
+ useEffect(() => {
141
+ const onPointerDown = (event) => {
142
+ if (desktopMenuRef.current &&
143
+ !desktopMenuRef.current.contains(event.target)) {
144
+ setOpenMenuId(null);
145
+ }
146
+ };
147
+ document.addEventListener("mousedown", onPointerDown);
148
+ return () => document.removeEventListener("mousedown", onPointerDown);
149
+ }, []);
150
+ const closeMenus = () => {
151
+ setNavOpen(false);
152
+ setOpenMenuId(null);
49
153
  };
50
- const renderNavItems = (items) => (_jsx("div", { className: "flex flex-col lg:flex-row w-full", children: items.map((item, index) => {
51
- return (_jsx(NavItem, { name: item.name, link: item.link, icon: item.icon, selectedColor: item.selectedColor, color: color, loggedIn: item.loggedIn, reduxNotificationBadge: item.reduxNotificationBadge, childrens: item.childrens?.map((x) => {
52
- return { ...x };
53
- }) }, index));
54
- }) }));
55
- const hiddenItemsChange = useMemo(() => items.filter((item) => item.hide === true), [items]);
56
- const options = useMemo(() => {
57
- return (_jsxs(_Fragment, { children: [_jsx("ul", { className: "w-full lg:flex lg:items-center", children: renderNavItems(items
58
- .filter((item) => item.loggedIn === loggedIn)
59
- .filter((item) => item.hide !== true)) }), _jsx("ul", { className: "sm:flex sm:flex-col lg:flex-row ml-auto", children: loggedIn && (_jsx(OptionsDropDownButton, { color: color, ariaLabel: "Men\u00FA de usuario", options: [
60
- settingsOption && (_jsx(Link, { className: "block cursor-pointer px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 dark:hover:text-white", to: "/configuracion", children: _jsxs("div", { className: "mx-auto pt-2", children: [_jsxs("svg", { className: "h-5 w-5 mr-1", width: "24", height: "24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", viewBox: "0 0 24 24", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [_jsx("path", { d: "M12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Z" }), _jsx("path", { d: "M19.4 13a7.7 7.7 0 0 0 .06-2l2.1-1.64-2-3.46-2.55 1a7.7 7.7 0 0 0-1.73-1L14.7 2H9.3l-.58 2.9a7.7 7.7 0 0 0-1.73 1l-2.55-1-2 3.46L4.54 11a7.7 7.7 0 0 0 0 2l-2.1 1.64 2 3.46 2.55-1a7.7 7.7 0 0 0 1.73 1L9.3 22h5.4l.58-2.9a7.7 7.7 0 0 0 1.73-1l2.55 1 2-3.46Z" })] }), _jsx("span", { children: "Configuraci\u00F3n" })] }) }, "configuracion")),
61
- reloadCatalogsOption && (_jsx(Link, { className: `block px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-red-100 dark:hover:bg-gray-700 dark:hover:text-white`, to: "/reload-catalogs", children: _jsxs("div", { className: "mx-auto pt-2", children: [_jsxs("svg", { className: `h-5 w-5 mr-1`, width: "24", height: "24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", viewBox: "0 0 24 24", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", children: [_jsx("path", { d: "M20.5 8c-1.392-3.179-4.823-5-8.522-5C7.299 3 3.453 6.552 3 11.1" }), _jsx("path", { d: "M16.489 8.4h3.97A.54.54 0 0 0 21 7.86V3.9M3.5 16c1.392 3.179 4.823 5 8.522 5 4.679 0 8.525-3.552 8.978-8.1" }), _jsx("path", { d: "M7.511 15.6h-3.97a.54.54 0 0 0-.541.54v3.96" })] }), _jsx("span", { children: "Recargar cat\u00E1logos" })] }) }, "recargar-catalogos")),
62
- showDarkModeToggle && (_jsx("button", { type: "button", className: "block w-full cursor-pointer text-left px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 dark:hover:text-white", onClick: () => setIsDarkMode((value) => !value), children: _jsx("div", { className: "mx-auto pt-2", children: _jsx("span", { children: isDarkMode ? "Modo claro" : "Modo oscuro" }) }) }, "dark-mode-toggle")),
63
- _jsx(Link, { className: `block px-4 py-3 text-sm text-gray-600 capitalize transition-colors duration-200 transform dark:text-gray-300 hover:bg-red-100 dark:hover:bg-gray-700 dark:hover:text-white`, to: "/logout", children: _jsxs("div", { className: "mx-auto pt-2", children: [_jsx(LogoutDropDownSvgIcon, {}), _jsx("span", { children: "Cerrar sesi\u00F3n" })] }) }, "cerrar-sesion"),
64
- ] })) })] }));
65
- }, [items, loggedIn, hiddenItemsChange, reloadCatalogsOption, settingsOption, showDarkModeToggle, isDarkMode]);
66
- return (_jsx("nav", { className: `py-3 ${color.bg600}`, children: _jsxs("div", { className: "flex items-center justify-between ml-5 mr-5", children: [_jsxs("div", { className: "flex justify-between items-center w-full lg:w-auto", children: [_jsxs(Link, { className: "text-sm font-bold leading-relaxed inline-block mr-4 py-2 whitespace-nowrap uppercase text-white", to: "/home", children: [_jsx("div", { className: "inline-block mr-2 mb-2 align-middle", children: _jsx("img", { className: "w-auto h-7", src: "/logo.png", alt: "logo-zauru" }) }), title] }), version !== currentVersion && (_jsx("button", { className: `ml-2 px-2 py-1 text-xs text-white ${color.bg700} rounded-full hover:${color.bg900} transition-colors duration-200`, onClick: refreshPage, children: "\uD83D\uDD04 Actualizar versi\u00F3n" })), _jsx("button", { className: `rounded lg:hidden focus:outline-none focus:ring focus:${color.ring600} focus:ring-opacity-50`, "aria-label": "Toggle mobile menu", type: "button", onClick: () => setNavBarOpen(!NavBarOpen), children: _jsx(MenuAlt4Svg, { open: NavBarOpen }) })] }), _jsx("div", { className: `lg:hidden fixed top-0 left-0 z-50 w-64 h-full ${color.bg700} dark:bg-gray-900 shadow-lg transform ${NavBarOpen ? "translate-x-0" : "-translate-x-full"} transition-transform duration-300 ease-in-out overflow-y-auto`, children: _jsx("div", { className: "p-4", children: options }) }), _jsx("div", { className: "hidden lg:flex lg:items-center w-full lg:w-auto", children: options })] }) }));
154
+ const userEntries = useMemo(() => {
155
+ if (!loggedIn)
156
+ return [];
157
+ const entries = [];
158
+ if (settingsOption) {
159
+ entries.push({
160
+ key: "configuracion",
161
+ label: "Configuración",
162
+ to: "/configuracion",
163
+ icon: (_jsxs("svg", { className: "h-5 w-5 shrink-0", width: "24", height: "24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", viewBox: "0 0 24 24", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [_jsx("path", { d: "M12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Z" }), _jsx("path", { d: "M19.4 13a7.7 7.7 0 0 0 .06-2l2.1-1.64-2-3.46-2.55 1a7.7 7.7 0 0 0-1.73-1L14.7 2H9.3l-.58 2.9a7.7 7.7 0 0 0-1.73 1l-2.55-1-2 3.46L4.54 11a7.7 7.7 0 0 0 0 2l-2.1 1.64 2 3.46 2.55-1a7.7 7.7 0 0 0 1.73 1L9.3 22h5.4l.58-2.9a7.7 7.7 0 0 0 1.73-1l2.55 1 2-3.46Z" })] })),
164
+ });
165
+ }
166
+ if (reloadCatalogsOption) {
167
+ entries.push({
168
+ key: "recargar-catalogos",
169
+ label: "Recargar catálogos",
170
+ to: "/reload-catalogs",
171
+ icon: (_jsxs("svg", { className: "h-5 w-5 shrink-0", width: "24", height: "24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", viewBox: "0 0 24 24", strokeLinecap: "round", strokeLinejoin: "round", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [_jsx("path", { d: "M20.5 8c-1.392-3.179-4.823-5-8.522-5C7.299 3 3.453 6.552 3 11.1" }), _jsx("path", { d: "M16.489 8.4h3.97A.54.54 0 0 0 21 7.86V3.9M3.5 16c1.392 3.179 4.823 5 8.522 5 4.679 0 8.525-3.552 8.978-8.1" }), _jsx("path", { d: "M7.511 15.6h-3.97a.54.54 0 0 0-.541.54v3.96" })] })),
172
+ });
173
+ }
174
+ if (showDarkModeToggle) {
175
+ entries.push({
176
+ key: "dark-mode-toggle",
177
+ label: isDarkMode ? "Modo claro" : "Modo oscuro",
178
+ onClick: () => setIsDarkMode((value) => !value),
179
+ });
180
+ }
181
+ entries.push({
182
+ key: "cerrar-sesion",
183
+ label: "Cerrar sesión",
184
+ to: "/logout",
185
+ icon: _jsx(LogoutDropDownSvgIcon, {}),
186
+ danger: true,
187
+ });
188
+ return entries;
189
+ }, [
190
+ loggedIn,
191
+ settingsOption,
192
+ reloadCatalogsOption,
193
+ showDarkModeToggle,
194
+ isDarkMode,
195
+ ]);
196
+ useEffect(() => {
197
+ const justOpened = navOpen && !wasNavOpen.current;
198
+ wasNavOpen.current = navOpen;
199
+ if (!justOpened)
200
+ return;
201
+ const activeGroup = visibleItems.find((item) => visibleChildrenOf(item).some((child) => pathMatches(location.pathname, child.link)));
202
+ if (!activeGroup)
203
+ return;
204
+ const index = visibleItems.indexOf(activeGroup);
205
+ setOpenMenuId(`${activeGroup.name}-${index}`);
206
+ }, [navOpen, visibleItems, location.pathname]);
207
+ const renderCluster = (layout) => (_jsxs(_Fragment, { children: [_jsx(NavItems, { items: visibleItems, color: color, layout: layout, openMenuId: openMenuId, setOpenMenuId: setOpenMenuId, onNavigate: closeMenus }), _jsx(UserMenu, { color: color, layout: layout, open: openMenuId === "user", onToggle: () => setOpenMenuId(openMenuId === "user" ? null : "user"), onNavigate: closeMenus, entries: userEntries })] }));
208
+ return (_jsx("nav", { className: `py-2 ${color.bg600}`, "aria-label": "Principal", children: _jsxs("div", { className: "flex items-center justify-between gap-3 px-4 sm:px-5", children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center justify-between gap-2 lg:w-auto lg:flex-none", children: [_jsxs(Link, { className: `inline-flex min-h-11 min-w-0 cursor-pointer items-center gap-2 truncate text-sm font-bold uppercase text-white ${focusRing}`, to: "/home", children: [_jsx("img", { className: "h-7 w-auto shrink-0", src: "/logo.png", alt: "" }), _jsx("span", { className: "truncate", children: title })] }), version !== currentVersion && (_jsx("button", { type: "button", className: `shrink-0 cursor-pointer rounded-full px-3 py-2 text-xs text-white ${color.bg700} hover:opacity-90 ${focusRing}`, onClick: () => navigate(0), children: "Actualizar versi\u00F3n" })), _jsx("button", { type: "button", className: `inline-flex min-h-11 min-w-11 cursor-pointer items-center justify-center rounded-md text-white lg:hidden ${focusRing} ${navOpen ? "pointer-events-none invisible" : ""}`, "aria-label": "Abrir men\u00FA", "aria-expanded": navOpen, "aria-controls": mobileNavId, "aria-hidden": navOpen, tabIndex: navOpen ? -1 : undefined, onClick: () => setNavOpen(true), children: _jsx(MenuAlt4Svg, { open: false }) })] }), navOpen && (_jsx("button", { type: "button", "aria-label": "Cerrar men\u00FA", className: "fixed inset-0 z-40 cursor-pointer bg-black/40 lg:hidden", onClick: closeMenus })), _jsxs("div", { ref: mobileDrawerRef, id: mobileNavId, "aria-hidden": !navOpen, className: `fixed inset-y-0 left-0 z-50 flex w-[min(20rem,86vw)] flex-col ${color.bg700} shadow-lg transition-transform duration-200 ease-out motion-reduce:transition-none lg:hidden ${navOpen ? "translate-x-0" : "pointer-events-none -translate-x-full"}`, children: [_jsxs("div", { className: "flex items-center justify-between gap-2 border-b border-white/15 px-4 py-3", children: [_jsx("p", { className: "truncate text-sm font-bold uppercase text-white", children: title }), _jsx("button", { type: "button", className: `inline-flex min-h-11 min-w-11 cursor-pointer items-center justify-center rounded-md text-white ${focusRing}`, "aria-label": "Cerrar men\u00FA", onClick: closeMenus, children: _jsx(ExitSvg, {}) })] }), _jsx("div", { className: "flex-1 overflow-y-auto overscroll-contain p-3", children: renderCluster("mobile") })] }), _jsx("div", { ref: desktopMenuRef, className: "hidden min-w-0 flex-1 items-center gap-2 lg:flex", children: renderCluster("desktop") })] }) }));
67
209
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zauru-sdk/components",
3
- "version": "6.15.0",
3
+ "version": "6.16.0",
4
4
  "description": "Componentes reutilizables en las WebApps de Zauru.",
5
5
  "main": "./dist/esm/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -45,9 +45,9 @@
45
45
  "@remix-run/node": "^2.8.1",
46
46
  "@remix-run/react": "^2.8.1",
47
47
  "@zauru-sdk/common": "^6.12.0",
48
- "@zauru-sdk/hooks": "^6.4.0",
48
+ "@zauru-sdk/hooks": "^6.4.1",
49
49
  "@zauru-sdk/icons": "^6.2.0",
50
- "@zauru-sdk/redux": "^6.8.1",
50
+ "@zauru-sdk/redux": "^6.8.2",
51
51
  "@zauru-sdk/types": "^6.28.0",
52
52
  "@zauru-sdk/utils": "^6.27.0",
53
53
  "browser-image-compression": "^2.0.2",
@@ -62,5 +62,5 @@
62
62
  "styled-components": "^5.3.5",
63
63
  "zod": "^3.23.8"
64
64
  },
65
- "gitHead": "322f29f8eff1085aba8924ca290f3a04aa54d477"
65
+ "gitHead": "5a47bf012ebb44d51bc409fb3828b2512befb8dd"
66
66
  }