@homecode/ui 5.12.0 → 5.14.1

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.
@@ -1,9 +1,9 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
2
  import cn from 'classnames';
3
3
  import { useState, useRef, useId, useEffect } from 'react';
4
- import { createPortal } from 'react-dom';
5
4
  import { Card, CardHeader, CardContent, CardFooter } from '../Card/Card.js';
6
5
  import { Icon } from '../Icon/Icon.js';
6
+ import { Portal } from '../Portal/Portal.js';
7
7
  import { isBrowser } from '../../tools/env.js';
8
8
  import S from './Dialogue.styl.js';
9
9
 
@@ -99,11 +99,7 @@ function Dialogue({ open, onOpenChange, disabled, trigger, title, subtitle, icon
99
99
  ? `min(${String(maxHeight)}, calc(100% - var(--p-5)))`
100
100
  : undefined,
101
101
  }, children: [(title || subtitle || icon) && (jsx(CardHeader, { icon: icon, title: title, description: subtitle, titleId: titleId, descriptionId: descriptionId })), jsx("button", { className: S.dialogClose, onClick: handleCloseClick, "aria-label": "Close dialog", type: "button", children: jsx(Icon, { type: "close", size: "m" }) }), content && (jsx(CardContent, { className: contentClassName, noScroll: noScroll, autoScrollBottom: autoScrollBottom, children: content })), footer && (jsx(CardFooter, { className: FOOTER_ALIGN_CLASS[footerAlignment], children: footer }))] })] }));
102
- return (jsxs(Fragment, { children: [trigger && jsx("div", { onClick: onTriggerClick, children: trigger }), open &&
103
- !disabled &&
104
- isMounted &&
105
- isBrowser &&
106
- createPortal(dialogueContent, document.body)] }));
102
+ return (jsxs(Fragment, { children: [trigger && jsx("div", { onClick: onTriggerClick, children: trigger }), open && !disabled && isMounted && isBrowser && (jsx(Portal, { children: dialogueContent }))] }));
107
103
  }
108
104
 
109
105
  export { Dialogue, S as DialogueStyles };
@@ -1,6 +1,6 @@
1
1
  import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
2
2
 
3
- var css_248z = ".Dialogue_dialogOverlay__jjBIa{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);background-color:var(--decent-color-alpha-900);inset:0;opacity:0;position:fixed;transition:opacity .2s ease-out;z-index:50}.Dialogue_dialogOverlay__jjBIa.Dialogue_isOpen__gISMb{animation-duration:.2s;animation-fill-mode:forwards;animation-name:Dialogue_fadeIn__RSEB2;animation-timing-function:ease-out;opacity:1}.Dialogue_dialogContent__-Lxde{border-radius:var(--border-radius-l);box-shadow:0 10px 20px rgba(0,0,0,.3),0 0 0 2px var(--decent-color-alpha-800);display:flex;flex-direction:column;left:50%;max-height:calc(100% - var(--p-5));opacity:0;position:fixed;top:50%;transform:translateX(-50%) translateY(-50%) scale(.95);transition:opacity .2s ease-out,transform .2s ease-out;width:-moz-fit-content;width:fit-content;z-index:50}.Dialogue_dialogContent__-Lxde.Dialogue_isOpen__gISMb{animation-duration:.2s;animation-fill-mode:forwards;animation-name:Dialogue_dialogueIn__M0tLL;animation-timing-function:ease-out;opacity:1;transform:translateX(-50%) translateY(-50%) scale(1)}.Dialogue_dialogContent__-Lxde.Dialogue_isClosed__lHYyZ{animation-duration:.2s;animation-fill-mode:forwards;animation-name:Dialogue_dialogueOut__6bLTY;animation-timing-function:ease-in;opacity:0;pointer-events:none;transform:translateX(-50%) translateY(-50%) scale(.95)}@media (max-width:700px){.Dialogue_dialogContent__-Lxde{max-width:calc(100% - var(--p-5));width:calc(100% - var(--p-5))}}.Dialogue_dialogContent__-Lxde:has(.Dialogue_dialogClose__5q12n) [data-slot=card-header]{padding-right:calc(2rem + var(--p-3))}.Dialogue_size-default__X1sdB{max-width:40rem}.Dialogue_size-login__GyixB{max-width:24rem}.Dialogue_size-wide__HQbiX{max-width:calc(100% - var(--p-5))}@media (min-width:700px){.Dialogue_size-wide__HQbiX{max-width:80rem}}.Dialogue_dialogClose__5q12n{align-items:center;background-color:transparent;border:none;border-radius:var(--border-radius-s);box-shadow:inset 0 0 0 2px none;color:var(--accent-color);cursor:pointer;display:flex;height:2rem;justify-content:center;opacity:.3;position:absolute;right:var(--p-3);top:var(--p-3);transform-origin:center;transition:opacity .2s ease,transform .2s ease;width:2rem;z-index:10}.Dialogue_dialogClose__5q12n:focus-visible,.Dialogue_dialogClose__5q12n:hover{opacity:1;transform:scale(1.1)}.Dialogue_dialogClose__5q12n:focus-visible{box-shadow:0 0 0 2px var(--active-color)}.Dialogue_dialogClose__5q12n:disabled{pointer-events:none}.Dialogue_footerAlignLeft__xQUD8{justify-content:flex-start}.Dialogue_footerAlignCenter__yq9Mu{justify-content:center}.Dialogue_footerAlignRight__Yo7hG{justify-content:flex-end}@keyframes Dialogue_fadeIn__RSEB2{0%{opacity:0}to{opacity:1}}@keyframes Dialogue_dialogueIn__M0tLL{0%{opacity:0;transform:translateX(-50%) translateY(-50%) scale(.95)}to{opacity:1;transform:translateX(-50%) translateY(-50%) scale(1)}}@keyframes Dialogue_dialogueOut__6bLTY{0%{opacity:1;transform:translateX(-50%) translateY(-50%) scale(1)}to{opacity:0;transform:translateX(-50%) translateY(-50%) scale(.95)}}";
3
+ var css_248z = ".Dialogue_dialogOverlay__jjBIa{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);background-color:var(--decent-color-alpha-900);inset:0;opacity:0;position:fixed;transition:opacity .2s ease-out;z-index:10}.Dialogue_dialogOverlay__jjBIa.Dialogue_isOpen__gISMb{animation-duration:.2s;animation-fill-mode:forwards;animation-name:Dialogue_fadeIn__RSEB2;animation-timing-function:ease-out;opacity:1}.Dialogue_dialogContent__-Lxde{border-radius:var(--border-radius-l);box-shadow:0 10px 20px rgba(0,0,0,.3),0 0 0 2px var(--decent-color-alpha-800);display:flex;flex-direction:column;left:50%;max-height:calc(100% - var(--p-5));opacity:0;position:fixed;top:50%;transform:translateX(-50%) translateY(-50%) scale(.95);transition:opacity .2s ease-out,transform .2s ease-out;width:-moz-fit-content;width:fit-content;z-index:10}.Dialogue_dialogContent__-Lxde.Dialogue_isOpen__gISMb{animation-duration:.2s;animation-fill-mode:forwards;animation-name:Dialogue_dialogueIn__M0tLL;animation-timing-function:ease-out;opacity:1;transform:translateX(-50%) translateY(-50%) scale(1)}.Dialogue_dialogContent__-Lxde.Dialogue_isClosed__lHYyZ{animation-duration:.2s;animation-fill-mode:forwards;animation-name:Dialogue_dialogueOut__6bLTY;animation-timing-function:ease-in;opacity:0;pointer-events:none;transform:translateX(-50%) translateY(-50%) scale(.95)}@media (max-width:700px){.Dialogue_dialogContent__-Lxde{max-width:calc(100% - var(--p-5));width:calc(100% - var(--p-5))}}.Dialogue_dialogContent__-Lxde:has(.Dialogue_dialogClose__5q12n) [data-slot=card-header]{padding-right:calc(2rem + var(--p-3))}.Dialogue_size-default__X1sdB{max-width:40rem}.Dialogue_size-login__GyixB{max-width:24rem}.Dialogue_size-wide__HQbiX{max-width:calc(100% - var(--p-5))}@media (min-width:700px){.Dialogue_size-wide__HQbiX{max-width:80rem}}.Dialogue_dialogClose__5q12n{align-items:center;background-color:transparent;border:none;border-radius:var(--border-radius-s);box-shadow:inset 0 0 0 2px none;color:var(--accent-color);cursor:pointer;display:flex;height:2rem;justify-content:center;opacity:.3;position:absolute;right:var(--p-3);top:var(--p-3);transform-origin:center;transition:opacity .2s ease,transform .2s ease;width:2rem;z-index:10}.Dialogue_dialogClose__5q12n:focus-visible,.Dialogue_dialogClose__5q12n:hover{opacity:1;transform:scale(1.1)}.Dialogue_dialogClose__5q12n:focus-visible{box-shadow:0 0 0 2px var(--active-color)}.Dialogue_dialogClose__5q12n:disabled{pointer-events:none}.Dialogue_footerAlignLeft__xQUD8{justify-content:flex-start}.Dialogue_footerAlignCenter__yq9Mu{justify-content:center}.Dialogue_footerAlignRight__Yo7hG{justify-content:flex-end}@keyframes Dialogue_fadeIn__RSEB2{0%{opacity:0}to{opacity:1}}@keyframes Dialogue_dialogueIn__M0tLL{0%{opacity:0;transform:translateX(-50%) translateY(-50%) scale(.95)}to{opacity:1;transform:translateX(-50%) translateY(-50%) scale(1)}}@keyframes Dialogue_dialogueOut__6bLTY{0%{opacity:1;transform:translateX(-50%) translateY(-50%) scale(1)}to{opacity:0;transform:translateX(-50%) translateY(-50%) scale(.95)}}";
4
4
  var S = {"dialogOverlay":"Dialogue_dialogOverlay__jjBIa","isOpen":"Dialogue_isOpen__gISMb","fadeIn":"Dialogue_fadeIn__RSEB2","dialogContent":"Dialogue_dialogContent__-Lxde","dialogueIn":"Dialogue_dialogueIn__M0tLL","isClosed":"Dialogue_isClosed__lHYyZ","dialogueOut":"Dialogue_dialogueOut__6bLTY","dialogClose":"Dialogue_dialogClose__5q12n","size-default":"Dialogue_size-default__X1sdB","size-login":"Dialogue_size-login__GyixB","size-wide":"Dialogue_size-wide__HQbiX","footerAlignLeft":"Dialogue_footerAlignLeft__xQUD8","footerAlignCenter":"Dialogue_footerAlignCenter__yq9Mu","footerAlignRight":"Dialogue_footerAlignRight__Yo7hG"};
5
5
  styleInject(css_248z);
6
6
 
@@ -1,11 +1,13 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import cn from 'classnames';
3
- import { useRef, useState, useEffect, useLayoutEffect } from 'react';
3
+ import { useState, useEffect } from 'react';
4
4
  import { Icon } from '../Icon/Icon.js';
5
+ import { Popup } from '../Popup/Popup.js';
5
6
  import S from './NestedMenu.styl.js';
6
7
 
7
8
  const MOBILE_MQ = '(max-width: 720px)';
8
9
  const HOVER_MQ = '(hover: hover) and (pointer: fine)';
10
+ const ICON_SIZE = { xs: 'xs', s: 'xs', m: 'xs', l: 's', xl: 'm' };
9
11
  function useMedia(query) {
10
12
  const [matches, setMatches] = useState(() => typeof window !== 'undefined' && window.matchMedia(query).matches);
11
13
  useEffect(() => {
@@ -27,14 +29,13 @@ function NestedMenuItemRow({ children, className, danger, disabled, href, target
27
29
  }
28
30
  return (jsx("button", { type: "button", className: classes, disabled: disabled, onClick: onClick, children: children }));
29
31
  }
30
- function NestedMenuComponent({ trigger, items, open, onOpenChange, align = 'end', className, }) {
31
- const rootRef = useRef(null);
32
+ function NestedMenuComponent({ trigger, items, open, onOpenChange, align = 'end', size = 'm', className, popupProps, }) {
32
33
  const [activeId, setActiveId] = useState(null);
33
- const [flipLeft, setFlipLeft] = useState(false);
34
- const hoverTimer = useRef(0);
35
34
  const stacked = useMedia(MOBILE_MQ);
36
35
  const canHover = useMedia(HOVER_MQ);
37
36
  const active = items.find(item => item.id === activeId);
37
+ const iconSize = ICON_SIZE[size];
38
+ const contentClass = cn(S.content, S[`size-${size}`]);
38
39
  function close() {
39
40
  onOpenChange(false);
40
41
  setActiveId(null);
@@ -54,40 +55,9 @@ function NestedMenuComponent({ trigger, items, open, onOpenChange, align = 'end'
54
55
  if (e.key === 'Escape')
55
56
  close();
56
57
  };
57
- const onPointer = (e) => {
58
- if (!rootRef.current?.contains(e.target))
59
- close();
60
- };
61
58
  document.addEventListener('keydown', onKey);
62
- document.addEventListener('pointerdown', onPointer);
63
- return () => {
64
- document.removeEventListener('keydown', onKey);
65
- document.removeEventListener('pointerdown', onPointer);
66
- };
59
+ return () => document.removeEventListener('keydown', onKey);
67
60
  }, [open]);
68
- useLayoutEffect(() => {
69
- if (!open || !rootRef.current)
70
- return;
71
- const rect = rootRef.current.getBoundingClientRect();
72
- setFlipLeft(window.innerWidth - rect.right < 280);
73
- }, [open, activeId]);
74
- useEffect(() => () => window.clearTimeout(hoverTimer.current), []);
75
- function onItemEnter(id) {
76
- if (!canHover || stacked)
77
- return;
78
- window.clearTimeout(hoverTimer.current);
79
- const item = items.find(entry => entry.id === id);
80
- if (item?.disabled || !item?.submenu) {
81
- setActiveId(null);
82
- return;
83
- }
84
- openSub(id, false);
85
- }
86
- function onItemLeave() {
87
- if (!canHover || stacked)
88
- return;
89
- hoverTimer.current = window.setTimeout(() => setActiveId(null), 160);
90
- }
91
61
  function onItemClick(id) {
92
62
  const item = items.find(entry => entry.id === id);
93
63
  if (!item || item.disabled)
@@ -97,18 +67,47 @@ function NestedMenuComponent({ trigger, items, open, onOpenChange, align = 'end'
97
67
  close();
98
68
  return;
99
69
  }
100
- if (activeId === id && !stacked) {
70
+ if (!item.submenu)
71
+ return;
72
+ if (activeId === id && !stacked && !canHover) {
101
73
  setActiveId(null);
102
74
  return;
103
75
  }
104
76
  openSub(id, true);
105
77
  }
78
+ function renderItemButton(item) {
79
+ return (jsxs("button", { type: "button", className: cn(S.item, activeId === item.id && S.itemActive, item.danger && S.itemDanger, item.disabled && S.itemDisabled, item.wrap && S.multiline, item.className), role: "menuitem", disabled: item.disabled, "aria-haspopup": item.submenu ? 'menu' : undefined, "aria-expanded": item.submenu ? activeId === item.id : undefined, onClick: () => onItemClick(item.id), children: [item.icon && (jsx("span", { className: S.icon, "aria-hidden": true, children: item.icon })), jsx("span", { className: S.label, children: item.label }), item.hint != null && item.hint !== '' && (jsx("span", { className: S.hint, children: item.hint })), item.submenu && (jsx(Icon, { className: S.chevron, type: "chevronRight", size: iconSize }))] }));
80
+ }
106
81
  function renderItems() {
107
- return items.map(item => (jsxs("div", { className: S.itemWrap, onMouseEnter: () => onItemEnter(item.id), onMouseLeave: onItemLeave, children: [jsxs("button", { type: "button", className: cn(S.item, activeId === item.id && S.itemActive, item.danger && S.itemDanger, item.disabled && S.itemDisabled, item.wrap && S.multiline, item.className), role: "menuitem", disabled: item.disabled, "aria-haspopup": item.submenu ? 'menu' : undefined, "aria-expanded": item.submenu ? activeId === item.id : undefined, onClick: () => onItemClick(item.id), children: [item.icon && (jsx("span", { className: S.icon, "aria-hidden": true, children: item.icon })), jsx("span", { className: S.label, children: item.label }), item.hint != null && item.hint !== '' && (jsx("span", { className: S.hint, children: item.hint })), item.submenu && (jsx(Icon, { className: S.chevron, type: "chevronRight", size: "xs" }))] }), !stacked && activeId === item.id && item.submenu && (jsx("div", { className: cn(S.submenu, flipLeft && S.submenuLeft), role: "menu", onMouseEnter: () => {
108
- window.clearTimeout(hoverTimer.current);
109
- }, children: item.submenu }))] }, item.id)));
82
+ return items.map(item => {
83
+ if (item.submenu && !stacked) {
84
+ return (jsx(Popup, { ...popupProps, className: cn(S.itemPopup, popupProps?.className), size: size, hoverControl: canHover, isOpen: activeId === item.id, onOpen: () => openSub(item.id, true), onClose: () => {
85
+ setActiveId(current => (current === item.id ? null : current));
86
+ }, direction: align === 'end' ? 'left-top' : 'right-top', trigger: renderItemButton(item), triggerProps: {
87
+ ...popupProps?.triggerProps,
88
+ className: cn(S.itemTrigger, popupProps?.triggerProps?.className),
89
+ }, contentProps: {
90
+ ...popupProps?.contentProps,
91
+ className: cn(contentClass, popupProps?.contentProps?.className),
92
+ }, content: jsx("div", { className: S.list, role: "menu", children: item.submenu }) }, item.id));
93
+ }
94
+ return (jsx("div", { className: S.itemWrap, onPointerEnter: () => {
95
+ if (canHover && !stacked)
96
+ setActiveId(null);
97
+ }, children: renderItemButton(item) }, item.id));
98
+ });
110
99
  }
111
- return (jsxs("div", { ref: rootRef, className: cn(S.root, className), children: [jsx("div", { className: S.trigger, onClick: () => onOpenChange(!open), children: trigger }), open && (jsxs("div", { className: cn(S.popup, align === 'end' && S.alignEnd), role: "menu", children: [stacked && active && (jsxs("div", { className: S.stacked, children: [jsxs("button", { type: "button", className: S.back, onClick: () => setActiveId(null), children: [jsx(Icon, { type: "chevronLeft", size: "xs" }), jsx("span", { className: S.label, children: active.label })] }), jsx("div", { className: S.stackedBody, children: active.submenu })] })), (!stacked || !active) && renderItems()] }))] }));
100
+ return (jsx(Popup, { ...popupProps, className: cn(S.root, className, popupProps?.className), size: size, isOpen: open, onOpen: () => onOpenChange(true), onClose: () => {
101
+ onOpenChange(false);
102
+ setActiveId(null);
103
+ }, direction: align === 'end' ? 'bottom-left' : 'bottom-right', trigger: trigger, triggerProps: {
104
+ ...popupProps?.triggerProps,
105
+ className: cn(S.trigger, popupProps?.triggerProps?.className),
106
+ onClick: () => onOpenChange(!open),
107
+ }, contentProps: {
108
+ ...popupProps?.contentProps,
109
+ className: cn(contentClass, popupProps?.contentProps?.className),
110
+ }, content: jsx("div", { className: S.list, role: "menu", children: stacked && active ? (jsxs("div", { className: S.stacked, children: [jsxs("button", { type: "button", className: S.back, onClick: () => setActiveId(null), children: [jsx(Icon, { type: "chevronLeft", size: iconSize }), jsx("span", { className: S.label, children: active.label })] }), jsx("div", { className: S.stackedBody, children: active.submenu })] })) : (renderItems()) }) }));
112
111
  }
113
112
  const NestedMenu = Object.assign(NestedMenuComponent, {
114
113
  Item: NestedMenuItemRow,
@@ -1,7 +1,7 @@
1
1
  import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
2
2
 
3
- var css_248z = ".NestedMenu_root__ybyGA{display:inline-flex;position:relative}.NestedMenu_trigger__zBeNI{display:inline-flex}.NestedMenu_popup__q0uYO{background:var(--decent-color);border:1px solid var(--accent-color-alpha-200);border-radius:10px;box-shadow:0 8px 28px rgba(0,0,0,.45);display:flex;flex-direction:column;gap:1px;left:0;max-width:280px;min-width:200px;padding:4px;position:absolute;top:calc(100% + 6px);z-index:20}.NestedMenu_alignEnd__L4AZi{left:auto;right:0}.NestedMenu_itemWrap__Qmc0B{position:relative}.NestedMenu_back__dNsDV,.NestedMenu_item__tgbZm,.NestedMenu_row__48g5c{align-items:center;background:none;border:none;border-radius:6px;color:inherit;cursor:pointer;display:flex;font:inherit;font-size:13px;font-weight:500;gap:8px;letter-spacing:.01em;line-height:1.3;padding:6px 10px;text-align:left;text-decoration:none;width:100%}.NestedMenu_back__dNsDV:hover,.NestedMenu_item__tgbZm:hover,.NestedMenu_row__48g5c:hover{background:var(--accent-color-alpha-50)}.NestedMenu_back__dNsDV.NestedMenu_itemActive__RfPZH,.NestedMenu_item__tgbZm.NestedMenu_itemActive__RfPZH,.NestedMenu_row__48g5c.NestedMenu_itemActive__RfPZH{background:var(--accent-color-alpha-100)}.NestedMenu_back__dNsDV.NestedMenu_itemDisabled__evVk1,.NestedMenu_back__dNsDV:disabled,.NestedMenu_item__tgbZm.NestedMenu_itemDisabled__evVk1,.NestedMenu_item__tgbZm:disabled,.NestedMenu_row__48g5c.NestedMenu_itemDisabled__evVk1,.NestedMenu_row__48g5c:disabled{cursor:default;opacity:.55;pointer-events:none}.NestedMenu_itemDanger__oAJbP{color:var(--active-color)}.NestedMenu_itemDanger__oAJbP .NestedMenu_icon__4g2Yp{color:inherit;opacity:1}.NestedMenu_icon__4g2Yp{display:inline-flex;flex-shrink:0;opacity:.55}.NestedMenu_icon__4g2Yp svg{display:block}.NestedMenu_label__Jnm6l{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.NestedMenu_hint__hotNP{flex-shrink:0;font-weight:400;opacity:.5}.NestedMenu_multiline__MDdk-{grid-row-gap:2px;align-items:start;display:grid;grid-template-columns:auto minmax(0,1fr);min-width:252px;row-gap:2px}.NestedMenu_multiline__MDdk- .NestedMenu_label__Jnm6l{overflow:visible;text-overflow:clip}.NestedMenu_multiline__MDdk- .NestedMenu_hint__hotNP{grid-column:2;min-width:0;white-space:normal}.NestedMenu_chevron__8i-Po{flex-shrink:0;opacity:.45}.NestedMenu_row__48g5c svg{color:var(--active-color);flex-shrink:0}.NestedMenu_submenu__Tx1Ll{background:var(--decent-color);border:1px solid var(--accent-color-alpha-200);border-radius:10px;box-shadow:0 8px 28px rgba(0,0,0,.45);left:calc(100% + 6px);max-height:min(360px,calc(100vh - 24px));max-width:280px;min-width:220px;overflow-x:hidden;overflow-y:auto;padding:4px;position:absolute;top:-4px;z-index:21}.NestedMenu_submenu__Tx1Ll:before{bottom:0;content:\"\";left:-6px;position:absolute;top:0;width:6px}.NestedMenu_submenuLeft__y18Nb{left:auto;right:calc(100% + 6px)}.NestedMenu_submenuLeft__y18Nb:before{left:auto;right:-6px}.NestedMenu_stacked__rMiOi{display:flex;flex-direction:column;max-height:min(360px,calc(100vh - 24px));overflow-y:auto}.NestedMenu_back__dNsDV{font-weight:650;margin-bottom:2px}.NestedMenu_stackedBody__Fbkma{min-width:0}";
4
- var S = {"root":"NestedMenu_root__ybyGA","trigger":"NestedMenu_trigger__zBeNI","popup":"NestedMenu_popup__q0uYO","alignEnd":"NestedMenu_alignEnd__L4AZi","itemWrap":"NestedMenu_itemWrap__Qmc0B","item":"NestedMenu_item__tgbZm","row":"NestedMenu_row__48g5c","back":"NestedMenu_back__dNsDV","itemActive":"NestedMenu_itemActive__RfPZH","itemDisabled":"NestedMenu_itemDisabled__evVk1","itemDanger":"NestedMenu_itemDanger__oAJbP","icon":"NestedMenu_icon__4g2Yp","label":"NestedMenu_label__Jnm6l","hint":"NestedMenu_hint__hotNP","multiline":"NestedMenu_multiline__MDdk-","chevron":"NestedMenu_chevron__8i-Po","submenu":"NestedMenu_submenu__Tx1Ll","submenuLeft":"NestedMenu_submenuLeft__y18Nb","stacked":"NestedMenu_stacked__rMiOi","stackedBody":"NestedMenu_stackedBody__Fbkma"};
3
+ var css_248z = ".NestedMenu_root__ybyGA,.NestedMenu_trigger__zBeNI{display:inline-flex}.NestedMenu_content__OyLXN{box-sizing:border-box;max-width:280px;min-width:200px;padding:4px}.NestedMenu_list__Q55Aa{display:flex;flex-direction:column;gap:1px}.NestedMenu_itemPopup__kMaxU{display:block;width:100%}.NestedMenu_itemTrigger__a7XHw{cursor:inherit;display:block;width:100%}.NestedMenu_itemWrap__Qmc0B{position:relative}.NestedMenu_back__dNsDV,.NestedMenu_item__tgbZm,.NestedMenu_row__48g5c{align-items:center;background:none;border:none;border-radius:6px;color:inherit;cursor:pointer;display:flex;font:inherit;font-weight:500;gap:8px;letter-spacing:.01em;line-height:1.3;text-align:left;text-decoration:none;width:100%}.NestedMenu_back__dNsDV:hover,.NestedMenu_item__tgbZm:hover,.NestedMenu_row__48g5c:hover{background:var(--accent-color-alpha-50)}.NestedMenu_back__dNsDV.NestedMenu_itemActive__RfPZH,.NestedMenu_item__tgbZm.NestedMenu_itemActive__RfPZH,.NestedMenu_row__48g5c.NestedMenu_itemActive__RfPZH{background:var(--accent-color-alpha-100)}.NestedMenu_back__dNsDV.NestedMenu_itemDisabled__evVk1,.NestedMenu_back__dNsDV:disabled,.NestedMenu_item__tgbZm.NestedMenu_itemDisabled__evVk1,.NestedMenu_item__tgbZm:disabled,.NestedMenu_row__48g5c.NestedMenu_itemDisabled__evVk1,.NestedMenu_row__48g5c:disabled{cursor:default;opacity:.55;pointer-events:none}.NestedMenu_itemDanger__oAJbP{color:var(--active-color)}.NestedMenu_itemDanger__oAJbP .NestedMenu_icon__4g2Yp{color:inherit;opacity:1}.NestedMenu_icon__4g2Yp{display:inline-flex;flex-shrink:0;opacity:.55}.NestedMenu_icon__4g2Yp svg{display:block}.NestedMenu_label__Jnm6l{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.NestedMenu_hint__hotNP{flex-shrink:0;font-weight:400;opacity:.5}.NestedMenu_multiline__MDdk-{grid-row-gap:2px;align-items:start;display:grid;grid-template-columns:auto minmax(0,1fr);min-width:252px;row-gap:2px}.NestedMenu_multiline__MDdk- .NestedMenu_label__Jnm6l{overflow:visible;text-overflow:clip}.NestedMenu_multiline__MDdk- .NestedMenu_hint__hotNP{grid-column:2;min-width:0;white-space:normal}.NestedMenu_chevron__8i-Po{flex-shrink:0;opacity:.45}.NestedMenu_row__48g5c svg{color:var(--active-color);flex-shrink:0}.NestedMenu_stacked__rMiOi{display:flex;flex-direction:column;max-height:min(360px,calc(100vh - 24px));overflow-y:auto}.NestedMenu_back__dNsDV{font-weight:650;margin-bottom:2px}.NestedMenu_stackedBody__Fbkma{min-width:0}.NestedMenu_size-s__2n2te .NestedMenu_back__dNsDV,.NestedMenu_size-s__2n2te .NestedMenu_item__tgbZm,.NestedMenu_size-s__2n2te .NestedMenu_row__48g5c,.NestedMenu_size-xs__yUJ0q .NestedMenu_back__dNsDV,.NestedMenu_size-xs__yUJ0q .NestedMenu_item__tgbZm,.NestedMenu_size-xs__yUJ0q .NestedMenu_row__48g5c{font-size:12px;gap:6px;padding:4px 8px}.NestedMenu_size-s__2n2te.NestedMenu_content__OyLXN,.NestedMenu_size-xs__yUJ0q.NestedMenu_content__OyLXN{min-width:176px;padding:3px}.NestedMenu_size-s__2n2te .NestedMenu_back__dNsDV svg,.NestedMenu_size-s__2n2te .NestedMenu_chevron__8i-Po,.NestedMenu_size-s__2n2te .NestedMenu_icon__4g2Yp svg,.NestedMenu_size-s__2n2te .NestedMenu_row__48g5c svg,.NestedMenu_size-xs__yUJ0q .NestedMenu_back__dNsDV svg,.NestedMenu_size-xs__yUJ0q .NestedMenu_chevron__8i-Po,.NestedMenu_size-xs__yUJ0q .NestedMenu_icon__4g2Yp svg,.NestedMenu_size-xs__yUJ0q .NestedMenu_row__48g5c svg{height:10px;width:10px}.NestedMenu_size-m__B8zm5 .NestedMenu_back__dNsDV,.NestedMenu_size-m__B8zm5 .NestedMenu_item__tgbZm,.NestedMenu_size-m__B8zm5 .NestedMenu_row__48g5c{font-size:13px;padding:6px 10px}.NestedMenu_size-l__1FrvQ .NestedMenu_back__dNsDV,.NestedMenu_size-l__1FrvQ .NestedMenu_item__tgbZm,.NestedMenu_size-l__1FrvQ .NestedMenu_row__48g5c{font-size:16px;gap:10px;padding:10px 14px}.NestedMenu_size-l__1FrvQ.NestedMenu_content__OyLXN{max-width:320px;min-width:240px;padding:6px}.NestedMenu_size-l__1FrvQ .NestedMenu_back__dNsDV svg,.NestedMenu_size-l__1FrvQ .NestedMenu_chevron__8i-Po,.NestedMenu_size-l__1FrvQ .NestedMenu_icon__4g2Yp svg,.NestedMenu_size-l__1FrvQ .NestedMenu_row__48g5c svg{height:18px;width:18px}.NestedMenu_size-xl__jiXmT .NestedMenu_back__dNsDV,.NestedMenu_size-xl__jiXmT .NestedMenu_item__tgbZm,.NestedMenu_size-xl__jiXmT .NestedMenu_row__48g5c{font-size:18px;gap:12px;padding:12px 16px}.NestedMenu_size-xl__jiXmT.NestedMenu_content__OyLXN{max-width:360px;min-width:260px;padding:8px}.NestedMenu_size-xl__jiXmT .NestedMenu_back__dNsDV svg,.NestedMenu_size-xl__jiXmT .NestedMenu_chevron__8i-Po,.NestedMenu_size-xl__jiXmT .NestedMenu_icon__4g2Yp svg,.NestedMenu_size-xl__jiXmT .NestedMenu_row__48g5c svg{height:22px;width:22px}";
4
+ var S = {"root":"NestedMenu_root__ybyGA","trigger":"NestedMenu_trigger__zBeNI","content":"NestedMenu_content__OyLXN","list":"NestedMenu_list__Q55Aa","itemPopup":"NestedMenu_itemPopup__kMaxU","itemTrigger":"NestedMenu_itemTrigger__a7XHw","itemWrap":"NestedMenu_itemWrap__Qmc0B","item":"NestedMenu_item__tgbZm","row":"NestedMenu_row__48g5c","back":"NestedMenu_back__dNsDV","itemActive":"NestedMenu_itemActive__RfPZH","itemDisabled":"NestedMenu_itemDisabled__evVk1","itemDanger":"NestedMenu_itemDanger__oAJbP","icon":"NestedMenu_icon__4g2Yp","label":"NestedMenu_label__Jnm6l","hint":"NestedMenu_hint__hotNP","multiline":"NestedMenu_multiline__MDdk-","chevron":"NestedMenu_chevron__8i-Po","stacked":"NestedMenu_stacked__rMiOi","stackedBody":"NestedMenu_stackedBody__Fbkma","size-xs":"NestedMenu_size-xs__yUJ0q","size-s":"NestedMenu_size-s__2n2te","size-m":"NestedMenu_size-m__B8zm5","size-l":"NestedMenu_size-l__1FrvQ","size-xl":"NestedMenu_size-xl__jiXmT"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { S as default };
@@ -118,10 +118,6 @@ const getPopupId = (elem, attr = 'data-popup-id') => {
118
118
  const id = elem.getAttribute(attr);
119
119
  return id ? parseInt(id, 10) : null;
120
120
  };
121
- function isLastChild(rootId, id) {
122
- const ids = childs[rootId];
123
- return ids && ids[ids.length - 1] === id;
124
- }
125
121
  function setChild(rootId, id) {
126
122
  if (!childs[rootId])
127
123
  childs[rootId] = [];
@@ -133,4 +129,4 @@ function unsetChild(rootId, id) {
133
129
  delete childs[rootId];
134
130
  }
135
131
 
136
- export { ZERO_BOUNDARY_FIT, childs, constrainAxisShift, domRectToEdges, edgesWidth, fitRectToBoundary, getId, getPopupId, intersectEdges, isEditable, isLastChild, popupBoundaryEdges, popupBoundaryPadding, setChild, shiftMarginsIntoBounds, shrinkEdgesUniform, unsetChild, viewportClientRectEdges };
132
+ export { ZERO_BOUNDARY_FIT, childs, constrainAxisShift, domRectToEdges, edgesWidth, fitRectToBoundary, getId, getPopupId, intersectEdges, isEditable, popupBoundaryEdges, popupBoundaryPadding, setChild, shiftMarginsIntoBounds, shrinkEdgesUniform, unsetChild, viewportClientRectEdges };
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { ZERO_BOUNDARY_FIT, getId, getPopupId, popupBoundaryEdges, popupBoundaryPadding, edgesWidth, fitRectToBoundary, isLastChild, unsetChild, childs, isEditable, setChild } from './Popup.helpers.js';
2
+ import { ZERO_BOUNDARY_FIT, getId, getPopupId, popupBoundaryEdges, popupBoundaryPadding, edgesWidth, fitRectToBoundary, childs, isEditable, setChild, unsetChild } from './Popup.helpers.js';
3
3
  import { observe, unobserve } from '../../tools/resizeObserver.js';
4
4
  import { Component, createRef } from 'react';
5
5
  import { Paranja } from '../Paranja/Paranja.js';
@@ -8,7 +8,6 @@ import { config } from '../../tools/config.js';
8
8
  import S from './Popup.styl.js';
9
9
  import Time from 'timen';
10
10
  import cn from 'classnames';
11
- import debounce from '../../tools/debounce.js';
12
11
  import { getCoords } from '../../tools/dom.js';
13
12
  import { isBrowser } from '../../tools/env.js';
14
13
  import throttle from '../../tools/throttle.js';
@@ -16,6 +15,7 @@ import throttle from '../../tools/throttle.js';
16
15
  const ANIMATION_DURATION = 100;
17
16
  const OFFSET_GAP = 10;
18
17
  const BOUNDARY_FIT_EPSILON = 1;
18
+ const HOVER_CLOSE_DELAY = 160;
19
19
  class Popup extends Component {
20
20
  rootElem = createRef();
21
21
  triggerElem = createRef();
@@ -33,11 +33,12 @@ class Popup extends Component {
33
33
  };
34
34
  focused = false;
35
35
  isOpening = false;
36
+ openedByHover = false;
36
37
  pointerPressed = false;
37
- subscribedHoverControl = false;
38
38
  subscribedSizeChange = false;
39
39
  pointerDownTarget = null;
40
40
  isPointerPressedInside = false;
41
+ hoverCloseUnsub = null;
41
42
  id;
42
43
  parentPopupContent;
43
44
  timers = Time.create();
@@ -63,7 +64,7 @@ class Popup extends Component {
63
64
  this.id = getId();
64
65
  }
65
66
  componentDidMount() {
66
- const { hoverControl, focusControl } = this.props;
67
+ const { focusControl } = this.props;
67
68
  const vv = isBrowser ? window.visualViewport : null;
68
69
  if (vv) {
69
70
  vv.addEventListener('resize', this.onBoundaryGeometryChange);
@@ -81,8 +82,6 @@ class Popup extends Component {
81
82
  document.addEventListener('keydown', this.onDocKeyDown, true);
82
83
  document.addEventListener('keyup', this.onDocKeyUp);
83
84
  }
84
- if (hoverControl)
85
- this.subscribeHoverControl();
86
85
  this.subscribeScroll();
87
86
  if (this.state.isOpen &&
88
87
  this.state.isContentVisible &&
@@ -95,15 +94,11 @@ class Popup extends Component {
95
94
  this.scheduleComputeShift();
96
95
  }, 100);
97
96
  componentDidUpdate(prevProps, prevState) {
98
- const { isOpen, disabled, hoverControl } = this.props;
97
+ const { isOpen, disabled } = this.props;
99
98
  if (disabled !== prevProps.disabled) {
100
99
  this.setState({ isOpen: false }); // close when receive disabled=true
101
100
  return;
102
101
  }
103
- if (!prevProps.hoverControl && hoverControl)
104
- this.subscribeHoverControl();
105
- if (prevProps.hoverControl && !hoverControl)
106
- this.unsubscribeHoverControl();
107
102
  if (typeof isOpen === 'boolean' && isOpen !== prevProps.isOpen) {
108
103
  isOpen ? this.open() : this.close();
109
104
  }
@@ -138,7 +133,7 @@ class Popup extends Component {
138
133
  if (this.scrollParent) {
139
134
  this.scrollParent.removeEventListener('scroll', this.close);
140
135
  }
141
- this.unsubscribeHoverControl();
136
+ this.cancelHoverClose();
142
137
  this.unsubscribeSizeChange();
143
138
  this.unsubscribeScroll();
144
139
  }
@@ -162,20 +157,6 @@ class Popup extends Component {
162
157
  unobserve(this.triggerElem.current);
163
158
  unobserve(this.containerElem);
164
159
  }
165
- subscribeHoverControl() {
166
- if (this.subscribedHoverControl)
167
- return;
168
- this.subscribedHoverControl = true;
169
- document.addEventListener('pointermove', this.checkHover);
170
- document.addEventListener('pointerup', this.checkHover);
171
- }
172
- unsubscribeHoverControl() {
173
- if (!this.subscribedHoverControl)
174
- return;
175
- this.subscribedHoverControl = false;
176
- document.removeEventListener('pointermove', this.checkHover);
177
- document.removeEventListener('pointerup', this.checkHover);
178
- }
179
160
  updateBounds() {
180
161
  if (!this.containerElem)
181
162
  return;
@@ -268,33 +249,6 @@ class Popup extends Component {
268
249
  this.setState({ boundaryFit });
269
250
  }
270
251
  }
271
- checkHover = debounce((e) => {
272
- if (this.isPointerPressedInside)
273
- return;
274
- const { isOpen, rootPopupId } = this.state;
275
- const overTrigger = this.isPointerOver(e.target, S.trigger);
276
- const overContent = this.isPointerOver(e.target, S.content);
277
- if (!isOpen) {
278
- if (overTrigger)
279
- this.open();
280
- return;
281
- }
282
- // isOpen
283
- if (overTrigger || overContent)
284
- return;
285
- if (typeof rootPopupId === 'number') {
286
- if (isLastChild(rootPopupId, this.id)) {
287
- this.close();
288
- unsetChild(rootPopupId, this.id);
289
- }
290
- }
291
- else {
292
- const isOverAnyPopupContent = e.target.closest(`.${S.content}`);
293
- if (!isOverAnyPopupContent || !childs[this.id]?.length) {
294
- this.close();
295
- }
296
- }
297
- }, 100);
298
252
  isControllable = () => typeof this.props.isOpen === 'boolean';
299
253
  isLastClickInside = () => this.pointerDownTarget &&
300
254
  (this.pointerDownTarget.closest(`.${S.trigger}`) ||
@@ -305,12 +259,81 @@ class Popup extends Component {
305
259
  this.timers.after(100, () => (this.pointerDownTarget = null));
306
260
  };
307
261
  onDocPointerUp = (e) => {
308
- if (!this.isPointerPressedInside)
309
- this.close();
262
+ const pressedInside = this.isPointerPressedInside;
310
263
  this.isPointerPressedInside = false;
264
+ if (!this.state.isOpen || pressedInside)
265
+ return;
266
+ if (this.isHoverInside(e.target))
267
+ return;
268
+ this.close();
311
269
  };
312
270
  isPointerOver(target, elem) {
313
- return target.closest(`.${elem}[data-popup-id="${this.id}"]`);
271
+ return (target instanceof Element &&
272
+ target.closest(`.${elem}[data-popup-id="${this.id}"]`));
273
+ }
274
+ isHoverInside(target) {
275
+ return (this.isPointerOver(target, S.trigger) ||
276
+ this.isPointerOver(target, S.content));
277
+ }
278
+ isRelatedHover(target) {
279
+ if (!(target instanceof Element))
280
+ return false;
281
+ if (this.isHoverInside(target))
282
+ return true;
283
+ const popupEl = target.closest('[data-popup-id]');
284
+ if (!popupEl)
285
+ return false;
286
+ const id = getPopupId(popupEl);
287
+ if (id == null || id === this.id)
288
+ return false;
289
+ if (childs[this.id]?.includes(id))
290
+ return true;
291
+ const { rootPopupId } = this.state;
292
+ return rootPopupId != null && childs[rootPopupId]?.includes(id);
293
+ }
294
+ cancelHoverClose() {
295
+ this.hoverCloseUnsub?.();
296
+ this.hoverCloseUnsub = null;
297
+ }
298
+ scheduleHoverClose() {
299
+ this.cancelHoverClose();
300
+ this.hoverCloseUnsub = Time.after(HOVER_CLOSE_DELAY, () => {
301
+ this.hoverCloseUnsub = null;
302
+ this.close();
303
+ });
304
+ }
305
+ onHoverEnter = () => {
306
+ if (!this.props.hoverControl)
307
+ return;
308
+ this.cancelHoverClose();
309
+ if (!this.state.isOpen) {
310
+ this.openedByHover = true;
311
+ this.open();
312
+ }
313
+ };
314
+ onHoverLeave = (e) => {
315
+ if (!this.props.hoverControl)
316
+ return;
317
+ if (this.isRelatedHover(e.relatedTarget)) {
318
+ this.cancelHoverClose();
319
+ return;
320
+ }
321
+ this.scheduleHoverClose();
322
+ };
323
+ bindHoverHandlers(props = {}) {
324
+ const enter = props.onPointerEnter;
325
+ const leave = props.onPointerLeave;
326
+ return {
327
+ ...props,
328
+ onPointerEnter: (e) => {
329
+ this.onHoverEnter();
330
+ enter?.(e);
331
+ },
332
+ onPointerLeave: (e) => {
333
+ this.onHoverLeave(e);
334
+ leave?.(e);
335
+ },
336
+ };
314
337
  }
315
338
  onScroll = throttle(e => {
316
339
  if (!this.state.isOpen) {
@@ -347,8 +370,12 @@ class Popup extends Component {
347
370
  };
348
371
  onTriggerPointerUp = e => {
349
372
  this.pointerPressed = false;
350
- if (e.traget === this.pointerDownTarget)
351
- this.toggle();
373
+ if (e.target !== this.pointerDownTarget)
374
+ return;
375
+ // Hover already opened — don't toggle shut on the same pointer.
376
+ if (this.state.isOpen && this.openedByHover)
377
+ return;
378
+ this.toggle();
352
379
  };
353
380
  onFocus = e => {
354
381
  this.focused = true;
@@ -393,8 +420,13 @@ class Popup extends Component {
393
420
  };
394
421
  close = () => {
395
422
  this.isOpening = false;
423
+ this.openedByHover = false;
424
+ this.cancelHoverClose();
396
425
  if (!this.state.isOpen)
397
426
  return;
427
+ const { rootPopupId } = this.state;
428
+ if (rootPopupId)
429
+ unsetChild(rootPopupId, this.id);
398
430
  this.unsubscribeSizeChange();
399
431
  this.changeState(false, this.afterClose);
400
432
  };
@@ -438,9 +470,17 @@ class Popup extends Component {
438
470
  if (!disableTrigger) {
439
471
  triggerProps.role = 'button';
440
472
  if (hoverControl) {
441
- Object.assign(triggerProps, {
442
- onPointerDown: this.onTriggerPointerDown,
443
- onPointerUp: this.onTriggerPointerUp,
473
+ const userDown = triggerProps.onPointerDown;
474
+ const userUp = triggerProps.onPointerUp;
475
+ Object.assign(triggerProps, this.bindHoverHandlers(triggerProps), {
476
+ onPointerDown: e => {
477
+ this.onTriggerPointerDown(e);
478
+ userDown?.(e);
479
+ },
480
+ onPointerUp: e => {
481
+ this.onTriggerPointerUp(e);
482
+ userUp?.(e);
483
+ },
444
484
  });
445
485
  }
446
486
  if (focusControl) {
@@ -453,7 +493,10 @@ class Popup extends Component {
453
493
  return (jsx("div", { className: classesTrigger, ...triggerProps, suppressHydrationWarning: true, "data-popup-id": this.id, ref: this.triggerElem, children: trigger }));
454
494
  }
455
495
  renderContent() {
456
- const { content, contentProps = {}, wrapperProps = {}, size, disabled, inline, outlined, animated, paranja, blur, round, elevation, } = this.props;
496
+ const { content, wrapperProps = {}, size, disabled, inline, outlined, animated, paranja, blur, round, elevation, hoverControl, } = this.props;
497
+ const contentProps = hoverControl
498
+ ? this.bindHoverHandlers(this.props.contentProps ?? {})
499
+ : (this.props.contentProps ?? {});
457
500
  const { isOpen, isContentVisible, animating, direction, triggerBounds, rootPopupId, boundaryFit, } = this.state;
458
501
  if (disabled)
459
502
  return null;
@@ -471,6 +514,15 @@ class Popup extends Component {
471
514
  ...(shiftTf ? { transform: shiftTf } : {}),
472
515
  };
473
516
  }
517
+ // Nested popups portal as siblings of the parent wrapper. A transform on
518
+ // the parent creates a stacking context, so the child needs a higher
519
+ // z-index or it paints under the parent (looks like it never opened).
520
+ if (rootPopupId) {
521
+ wrapperProps.style = {
522
+ ...wrapperProps.style,
523
+ zIndex: 12,
524
+ };
525
+ }
474
526
  const contentNode = (jsx("div", { ...wrapperProps, className: wrapperClasses, children: jsxs("div", { ...contentProps, ref: this.onContainerElemRef, className: classes, suppressHydrationWarning: true, "data-popup-id": this.id, "data-root-popup-id": rootPopupId, style: {
475
527
  ...(contentProps.style ?? {}),
476
528
  ...(boundaryFit.maxWidth !== null && boundaryFit.maxWidth > 0
@@ -1,6 +1,6 @@
1
1
  import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
2
2
 
3
- var css_248z = ".Popup_root__uQ-fP{display:inline-block;position:relative}.Popup_contentWrapper__2yi-2{opacity:0;pointer-events:none;position:absolute}.Popup_contentWrapper__2yi-2.Popup_animating__kR0qF{transition:opacity .1s ease-out}.Popup_contentWrapper__2yi-2.Popup_isOpen__BRIdP{opacity:1;pointer-events:all}.Popup_contentWrapper__2yi-2.Popup_inline__1-l1S.Popup_isOpen__BRIdP{position:relative}.Popup_contentWrapper__2yi-2:not(.Popup_inline__1-l1S),.Popup_contentWrapper__2yi-2:not(.Popup_inline__1-l1S)>.Popup_content__e8Qyu{position:absolute}.Popup_trigger__jQNaQ{cursor:pointer}.Popup_trigger__jQNaQ.Popup_isOpen__BRIdP{position:relative;z-index:11}.Popup_trigger__jQNaQ.Popup_disabled__DlE9y{opacity:.4;pointer-events:none}.Popup_content__e8Qyu{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--decent-color);box-shadow:inset 0 0 0 1px var(--accent-color-alpha-50);box-sizing:border-box;max-width:min(min(560px,70vw),calc(100svw - 16px));min-width:100%;overflow:hidden;position:relative;transform-origin:top center;z-index:11}.Popup_content__e8Qyu:before{background-color:var(--accent-color-alpha-50);bottom:0;content:\"\";left:0;pointer-events:none;position:absolute;right:0;top:0}.Popup_content__e8Qyu.Popup_blur__1hfU8{-webkit-backdrop-filter:blur(50px);backdrop-filter:blur(50px);background-color:var(--decent-color-alpha-500)}.Popup_content__e8Qyu.Popup_size-xs__7QR-d{border-radius:4px}.Popup_content__e8Qyu.Popup_size-xs__7QR-d.Popup_round__7rD1m{border-radius:12px}.Popup_content__e8Qyu.Popup_size-s__UmixP{border-radius:4px}.Popup_content__e8Qyu.Popup_size-s__UmixP.Popup_round__7rD1m{border-radius:16px}.Popup_content__e8Qyu.Popup_size-m__FYpTL{border-radius:6px}.Popup_content__e8Qyu.Popup_size-m__FYpTL.Popup_round__7rD1m{border-radius:20px}.Popup_content__e8Qyu.Popup_size-l__BTS57{border-radius:8px}.Popup_content__e8Qyu.Popup_size-l__BTS57.Popup_round__7rD1m{border-radius:24px}.Popup_content__e8Qyu.Popup_size-xl__fSfCc{border-radius:10px}.Popup_content__e8Qyu.Popup_size-xl__fSfCc.Popup_round__7rD1m{border-radius:28px}.Popup_content__e8Qyu.Popup_elevation-1__vmP3e{box-shadow:inset 0 0 0 1px var(--accent-color-alpha-50),0 0 var(--p-3) 2px var(--decent-color-alpha-500)}.Popup_content__e8Qyu.Popup_elevation-2__Ci4sI{box-shadow:inset 0 0 0 1px var(--accent-color-alpha-50),0 0 var(--p-5) 2px var(--decent-color-alpha-500)}.Popup_content__e8Qyu.Popup_outlined__g3cJV:after{border-radius:inherit;bottom:0;content:\"\";left:0;pointer-events:none;position:absolute;right:0;top:0}.Popup_isOpen__BRIdP .Popup_content__e8Qyu{opacity:1;pointer-events:all;transform:scaleX(1)}.Popup_animating__kR0qF{transition:70ms ease-out;transition-property:transform,opacity,margin}.Popup_axis-top__BaLgG{bottom:100%}.Popup_axis-bottom__hZwwr{top:100%}.Popup_axis-right__LMYVy{left:100%}.Popup_axis-left__SFKm-{right:100%}.Popup_float-top__8SQAu{bottom:0}.Popup_float-right__mdm-3{left:0}.Popup_float-bottom__7flve{top:0}.Popup_float-left__tz7fX{right:0}.Popup_axis-bottom__hZwwr,.Popup_axis-top__BaLgG{transform:scaleY(.5)}.Popup_axis-bottom__hZwwr.Popup_float-middle__Dmnn1,.Popup_axis-top__BaLgG.Popup_float-middle__Dmnn1{left:50%;transform:translateX(-50%) scaleY(.5)}.Popup_isOpen__BRIdP .Popup_axis-bottom__hZwwr.Popup_float-middle__Dmnn1,.Popup_isOpen__BRIdP .Popup_axis-top__BaLgG.Popup_float-middle__Dmnn1{transform:translateX(-50%) scaleX(1)}.Popup_axis-left__SFKm-,.Popup_axis-right__LMYVy{transform:scaleX(.5)}.Popup_axis-left__SFKm-.Popup_float-middle__Dmnn1,.Popup_axis-right__LMYVy.Popup_float-middle__Dmnn1{top:50%;transform:translateY(-50%) scaleX(.5)}.Popup_isOpen__BRIdP .Popup_axis-left__SFKm-.Popup_float-middle__Dmnn1,.Popup_isOpen__BRIdP .Popup_axis-right__LMYVy.Popup_float-middle__Dmnn1{transform:translateY(-50%) scaleX(1)}.Popup_axis-top__BaLgG.Popup_float-middle__Dmnn1{transform-origin:bottom center}.Popup_axis-top__BaLgG.Popup_float-right__mdm-3{transform-origin:bottom left}.Popup_axis-top__BaLgG.Popup_float-left__tz7fX{transform-origin:bottom right}.Popup_axis-bottom__hZwwr.Popup_float-middle__Dmnn1{transform-origin:top center}.Popup_axis-bottom__hZwwr.Popup_float-right__mdm-3{transform-origin:top left}.Popup_axis-bottom__hZwwr.Popup_float-left__tz7fX{transform-origin:top right}.Popup_axis-right__LMYVy.Popup_float-middle__Dmnn1{transform-origin:center left}.Popup_axis-right__LMYVy.Popup_float-top__8SQAu{transform-origin:bottom left}.Popup_axis-right__LMYVy.Popup_float-bottom__7flve{transform-origin:top left}.Popup_axis-left__SFKm-.Popup_float-middle__Dmnn1{transform-origin:center right}.Popup_axis-left__SFKm-.Popup_float-top__8SQAu{transform-origin:bottom right}.Popup_axis-left__SFKm-.Popup_float-bottom__7flve{transform-origin:top right}";
3
+ var css_248z = ".Popup_root__uQ-fP{display:inline-block;position:relative}.Popup_contentWrapper__2yi-2{opacity:0;pointer-events:none;position:absolute}.Popup_contentWrapper__2yi-2.Popup_animating__kR0qF{transition:opacity .1s ease-out}.Popup_contentWrapper__2yi-2.Popup_isOpen__BRIdP{opacity:1;z-index:11}.Popup_contentWrapper__2yi-2.Popup_inline__1-l1S.Popup_isOpen__BRIdP{position:relative}.Popup_contentWrapper__2yi-2:not(.Popup_inline__1-l1S),.Popup_contentWrapper__2yi-2:not(.Popup_inline__1-l1S)>.Popup_content__e8Qyu{position:absolute}.Popup_trigger__jQNaQ{cursor:pointer}.Popup_trigger__jQNaQ.Popup_isOpen__BRIdP{position:relative;z-index:11}.Popup_trigger__jQNaQ.Popup_disabled__DlE9y{opacity:.4;pointer-events:none}.Popup_content__e8Qyu{-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:var(--decent-color);box-shadow:inset 0 0 0 1px var(--accent-color-alpha-50);box-sizing:border-box;max-width:min(min(560px,70vw),calc(100svw - 16px));min-width:100%;overflow:hidden;position:relative;transform-origin:top center;z-index:11}.Popup_content__e8Qyu:before{background-color:var(--accent-color-alpha-50);bottom:0;content:\"\";left:0;pointer-events:none;position:absolute;right:0;top:0}.Popup_content__e8Qyu.Popup_blur__1hfU8{-webkit-backdrop-filter:blur(50px);backdrop-filter:blur(50px);background-color:var(--decent-color-alpha-500)}.Popup_content__e8Qyu.Popup_size-xs__7QR-d{border-radius:4px}.Popup_content__e8Qyu.Popup_size-xs__7QR-d.Popup_round__7rD1m{border-radius:12px}.Popup_content__e8Qyu.Popup_size-s__UmixP{border-radius:4px}.Popup_content__e8Qyu.Popup_size-s__UmixP.Popup_round__7rD1m{border-radius:16px}.Popup_content__e8Qyu.Popup_size-m__FYpTL{border-radius:6px}.Popup_content__e8Qyu.Popup_size-m__FYpTL.Popup_round__7rD1m{border-radius:20px}.Popup_content__e8Qyu.Popup_size-l__BTS57{border-radius:8px}.Popup_content__e8Qyu.Popup_size-l__BTS57.Popup_round__7rD1m{border-radius:24px}.Popup_content__e8Qyu.Popup_size-xl__fSfCc{border-radius:10px}.Popup_content__e8Qyu.Popup_size-xl__fSfCc.Popup_round__7rD1m{border-radius:28px}.Popup_content__e8Qyu.Popup_elevation-1__vmP3e{box-shadow:inset 0 0 0 1px var(--accent-color-alpha-50),0 0 var(--p-3) 2px var(--decent-color-alpha-500)}.Popup_content__e8Qyu.Popup_elevation-2__Ci4sI{box-shadow:inset 0 0 0 1px var(--accent-color-alpha-50),0 0 var(--p-5) 2px var(--decent-color-alpha-500)}.Popup_content__e8Qyu.Popup_outlined__g3cJV:after{border-radius:inherit;bottom:0;content:\"\";left:0;pointer-events:none;position:absolute;right:0;top:0}.Popup_isOpen__BRIdP .Popup_content__e8Qyu{opacity:1;pointer-events:all;transform:scaleX(1)}.Popup_animating__kR0qF{transition:70ms ease-out;transition-property:transform,opacity,margin}.Popup_axis-top__BaLgG{bottom:100%}.Popup_axis-bottom__hZwwr{top:100%}.Popup_axis-right__LMYVy{left:100%}.Popup_axis-left__SFKm-{right:100%}.Popup_float-top__8SQAu{bottom:0}.Popup_float-right__mdm-3{left:0}.Popup_float-bottom__7flve{top:0}.Popup_float-left__tz7fX{right:0}.Popup_axis-bottom__hZwwr,.Popup_axis-top__BaLgG{transform:scaleY(.5)}.Popup_axis-bottom__hZwwr.Popup_float-middle__Dmnn1,.Popup_axis-top__BaLgG.Popup_float-middle__Dmnn1{left:50%;transform:translateX(-50%) scaleY(.5)}.Popup_isOpen__BRIdP .Popup_axis-bottom__hZwwr.Popup_float-middle__Dmnn1,.Popup_isOpen__BRIdP .Popup_axis-top__BaLgG.Popup_float-middle__Dmnn1{transform:translateX(-50%) scaleX(1)}.Popup_axis-left__SFKm-,.Popup_axis-right__LMYVy{transform:scaleX(.5)}.Popup_axis-left__SFKm-.Popup_float-middle__Dmnn1,.Popup_axis-right__LMYVy.Popup_float-middle__Dmnn1{top:50%;transform:translateY(-50%) scaleX(.5)}.Popup_isOpen__BRIdP .Popup_axis-left__SFKm-.Popup_float-middle__Dmnn1,.Popup_isOpen__BRIdP .Popup_axis-right__LMYVy.Popup_float-middle__Dmnn1{transform:translateY(-50%) scaleX(1)}.Popup_axis-top__BaLgG.Popup_float-middle__Dmnn1{transform-origin:bottom center}.Popup_axis-top__BaLgG.Popup_float-right__mdm-3{transform-origin:bottom left}.Popup_axis-top__BaLgG.Popup_float-left__tz7fX{transform-origin:bottom right}.Popup_axis-bottom__hZwwr.Popup_float-middle__Dmnn1{transform-origin:top center}.Popup_axis-bottom__hZwwr.Popup_float-right__mdm-3{transform-origin:top left}.Popup_axis-bottom__hZwwr.Popup_float-left__tz7fX{transform-origin:top right}.Popup_axis-right__LMYVy.Popup_float-middle__Dmnn1{transform-origin:center left}.Popup_axis-right__LMYVy.Popup_float-top__8SQAu{transform-origin:bottom left}.Popup_axis-right__LMYVy.Popup_float-bottom__7flve{transform-origin:top left}.Popup_axis-left__SFKm-.Popup_float-middle__Dmnn1{transform-origin:center right}.Popup_axis-left__SFKm-.Popup_float-top__8SQAu{transform-origin:bottom right}.Popup_axis-left__SFKm-.Popup_float-bottom__7flve{transform-origin:top right}";
4
4
  var S = {"root":"Popup_root__uQ-fP","contentWrapper":"Popup_contentWrapper__2yi-2","animating":"Popup_animating__kR0qF","isOpen":"Popup_isOpen__BRIdP","inline":"Popup_inline__1-l1S","content":"Popup_content__e8Qyu","trigger":"Popup_trigger__jQNaQ","disabled":"Popup_disabled__DlE9y","blur":"Popup_blur__1hfU8","size-xs":"Popup_size-xs__7QR-d","round":"Popup_round__7rD1m","size-s":"Popup_size-s__UmixP","size-m":"Popup_size-m__FYpTL","size-l":"Popup_size-l__BTS57","size-xl":"Popup_size-xl__fSfCc","elevation-1":"Popup_elevation-1__vmP3e","elevation-2":"Popup_elevation-2__Ci4sI","outlined":"Popup_outlined__g3cJV","axis-top":"Popup_axis-top__BaLgG","axis-bottom":"Popup_axis-bottom__hZwwr","axis-right":"Popup_axis-right__LMYVy","axis-left":"Popup_axis-left__SFKm-","float-top":"Popup_float-top__8SQAu","float-right":"Popup_float-right__mdm-3","float-bottom":"Popup_float-bottom__7flve","float-left":"Popup_float-left__tz7fX","float-middle":"Popup_float-middle__Dmnn1"};
5
5
  styleInject(css_248z);
6
6
 
@@ -1,14 +1,14 @@
1
1
  import { useState, useEffect, useCallback, createElement } from 'react';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
- import cn from 'classnames';
4
- import { Scroll } from '../Scroll/Scroll.js';
5
3
  import { Button } from '../Button/Button.js';
6
4
  import { ButtonGroup } from '../ButtonGroup/ButtonGroup.js';
7
5
  import S from './Tabs.styl.js';
6
+ import { Scroll } from '../Scroll/Scroll.js';
7
+ import cn from 'classnames';
8
8
 
9
9
  const isId = id => ['string', 'number'].includes(typeof id);
10
10
  function Tabs(props) {
11
- const { size = 'm', className, tabsWrapperClassName, tabsClassName, contentClassName, items, hideTabsIfSingle = false, allowEmpty = false, onChange, renderAll, activeId: initialId, children, ...rest } = props;
11
+ const { size = 'm', variant = 'default', className, tabsWrapperClassName, tabsInnerClassName, tabsClassName, contentClassName, items, hideTabsIfSingle = false, allowEmpty = false, onChange, renderAll, activeId: initialId, children, ...rest } = props;
12
12
  const [activeId, setActiveId] = useState(isId(initialId) ? initialId : allowEmpty ? null : items[0].id);
13
13
  useEffect(() => {
14
14
  if (isId(initialId)) {
@@ -35,9 +35,9 @@ function Tabs(props) {
35
35
  if (renderAll || forceRender || isActive) {
36
36
  tabsContent.push(jsx("div", { className: cn(contentClassName, currContentClassName, !isActive && S.inactive), children: tabContent }, id));
37
37
  }
38
- return (createElement(Button, { ...rest, className: cn(S.tab, rest.className), size: size, key: id, onClick: e => onTabClick(e, params), checked: isActive }, label));
38
+ return (createElement(Button, { ...rest, className: cn(S.tab, isActive && S.active, rest.className), size: size, key: id, onClick: e => onTabClick(e, params), checked: isActive }, label));
39
39
  });
40
- const tabs = tabsButtons.length === 1 && hideTabsIfSingle ? null : (jsx(Scroll, { x: true, offset: { x: { before: 10, after: 10 } }, className: tabsWrapperClassName, innerClassName: cn(S.tabsScroll, S[`size-${size}`]), autoHide: true, fadeSize: size, size: size, children: jsx(ButtonGroup, { className: tabsClassName, ...rest, children: tabsButtons }) }));
40
+ const tabs = tabsButtons.length === 1 && hideTabsIfSingle ? null : (jsx(Scroll, { x: true, offset: { x: { before: 10, after: 10 } }, className: tabsWrapperClassName, innerClassName: cn(S.tabsScroll, S[`size-${size}`], tabsInnerClassName), autoHide: true, fadeSize: size, size: size, children: jsx(ButtonGroup, { className: cn(variant === 'links' && S['variant-links'], tabsClassName), ...rest, children: tabsButtons }) }));
41
41
  if (typeof children === 'function') {
42
42
  return children({
43
43
  tabs,
@@ -1,7 +1,7 @@
1
1
  import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
2
2
 
3
- var css_248z = "div .Tabs_inactive__H0mPh{display:none}.Tabs_tabsScroll__7Dj0S{padding-bottom:var(--p-5)}.Tabs_size-xs__J0-xo.Tabs_tabsScroll__7Dj0S{padding-bottom:var(--p-3)}.Tabs_size-s__bz7NO.Tabs_tabsScroll__7Dj0S{padding-bottom:var(--p-4)}.Tabs_size-l__emJzX.Tabs_tabsScroll__7Dj0S{padding-bottom:calc(var(--p-5)*1.2)}.Tabs_size-xl__Kqzt-.Tabs_tabsScroll__7Dj0S{padding-bottom:calc(var(--p-5)*1.35)}.Tabs_tab__-oN-g{flex-shrink:0;white-space:nowrap}";
4
- var S = {"inactive":"Tabs_inactive__H0mPh","tabsScroll":"Tabs_tabsScroll__7Dj0S","size-xs":"Tabs_size-xs__J0-xo","size-s":"Tabs_size-s__bz7NO","size-l":"Tabs_size-l__emJzX","size-xl":"Tabs_size-xl__Kqzt-","tab":"Tabs_tab__-oN-g"};
3
+ var css_248z = "div .Tabs_inactive__H0mPh{display:none}.Tabs_tabsScroll__7Dj0S{padding-bottom:var(--p-5)}.Tabs_size-xs__J0-xo.Tabs_tabsScroll__7Dj0S{padding-bottom:var(--p-3)}.Tabs_size-s__bz7NO.Tabs_tabsScroll__7Dj0S{padding-bottom:var(--p-4)}.Tabs_size-l__emJzX.Tabs_tabsScroll__7Dj0S{padding-bottom:calc(var(--p-5)*1.2)}.Tabs_size-xl__Kqzt-.Tabs_tabsScroll__7Dj0S{padding-bottom:calc(var(--p-5)*1.35)}.Tabs_tab__-oN-g{flex-shrink:0;white-space:nowrap}.Tabs_variant-links__-N1Ym>button:not(:first-child){border-radius:inherit;margin-left:0}.Tabs_variant-links__-N1Ym>button:not(:last-child){border-radius:inherit}.Tabs_variant-links__-N1Ym .Tabs_tab__-oN-g{background-color:transparent!important;box-shadow:none;padding:var(--p-3) var(--p-5)}.Tabs_variant-links__-N1Ym .Tabs_tab__-oN-g:focus,.Tabs_variant-links__-N1Ym .Tabs_tab__-oN-g:hover{background-color:transparent!important;box-shadow:0 2px 0 0 var(--active-color-alpha-100)}.Tabs_variant-links__-N1Ym .Tabs_tab__-oN-g.Tabs_active__nOA5N,.Tabs_variant-links__-N1Ym .Tabs_tab__-oN-g.Tabs_active__nOA5N:focus,.Tabs_variant-links__-N1Ym .Tabs_tab__-oN-g.Tabs_active__nOA5N:hover{background-color:transparent!important;box-shadow:0 2px 0 0 var(--active-color);color:inherit}";
4
+ var S = {"inactive":"Tabs_inactive__H0mPh","tabsScroll":"Tabs_tabsScroll__7Dj0S","size-xs":"Tabs_size-xs__J0-xo","size-s":"Tabs_size-s__bz7NO","size-l":"Tabs_size-l__emJzX","size-xl":"Tabs_size-xl__Kqzt-","tab":"Tabs_tab__-oN-g","variant-links":"Tabs_variant-links__-N1Ym","active":"Tabs_active__nOA5N"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { S as default };
@@ -8,12 +8,11 @@ function TextShimmerComponent({ children, as: Component = 'p', className, durati
8
8
  const raw = Math.min(48, 3.5 + Math.max(0, Math.min(1, spread / 10)) * 100.5);
9
9
  // Wide blend stops “vertical knife” artefacts when the ramp only spans few pixels inside the glyph mask.
10
10
  const ridgeHalf = Math.min(49, Math.max(36, raw + 17));
11
- const baseColor = inverted
12
- ? 'var(--txt-sh-highlight)'
13
- : 'var(--txt-sh-fill)';
14
- const bandColor = inverted
15
- ? 'var(--txt-sh-fill)'
16
- : 'var(--txt-sh-highlight)';
11
+ // Resolve on the gradient so ancestor --txt-sh-* inherit. --decent-color is the surface.
12
+ const fill = 'var(--txt-sh-fill, var(--text-shimmer-decent-tone, var(--accent-color)))';
13
+ const highlight = 'var(--txt-sh-highlight, var(--text-shimmer-accent-tone, var(--active-color)))';
14
+ const baseColor = inverted ? highlight : fill;
15
+ const bandColor = inverted ? fill : highlight;
17
16
  const backgroundGradient = `linear-gradient(90deg, ${baseColor} calc(50% - ${ridgeHalf}%), ${bandColor} 50%, ${baseColor} calc(50% + ${ridgeHalf}%))`;
18
17
  return { backgroundGradient };
19
18
  }, [spread, inverted]);
@@ -1,6 +1,6 @@
1
1
  import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
2
2
 
3
- var css_248z = ".TextShimmer_root__cnKtV{-webkit-text-fill-color:transparent;-webkit-font-smoothing:antialiased;--txt-sh-fill:var(--text-shimmer-decent-tone,var(--accent-color));--txt-sh-highlight:var(--text-shimmer-accent-tone,var(--decent-color));animation:TextShimmer_textShimmer__w7rQj 1s linear infinite;animation:TextShimmer_textShimmer__w7rQj var(--text-shimmer-duration,1s) linear infinite;-webkit-background-clip:text;background-clip:text;background-repeat:repeat-x;background-size:200% 100%;color:transparent!important;display:inline-block;position:relative}@keyframes TextShimmer_textShimmer__w7rQj{0%{background-position:100%}to{background-position:-100%}}";
3
+ var css_248z = ".TextShimmer_root__cnKtV{-webkit-text-fill-color:transparent;-webkit-font-smoothing:antialiased;animation:TextShimmer_textShimmer__w7rQj 1s linear infinite;animation:TextShimmer_textShimmer__w7rQj var(--text-shimmer-duration,1s) linear infinite;-webkit-background-clip:text;background-clip:text;background-repeat:repeat-x;background-size:200% 100%;color:transparent!important;display:inline-block;position:relative}@keyframes TextShimmer_textShimmer__w7rQj{0%{background-position:100%}to{background-position:-100%}}";
4
4
  var S = {"root":"TextShimmer_root__cnKtV","textShimmer":"TextShimmer_textShimmer__w7rQj"};
5
5
  styleInject(css_248z);
6
6
 
@@ -1,7 +1,7 @@
1
1
  import * as T from './NestedMenu.types';
2
2
  export declare function NestedMenuLabel({ children, className, }: T.NestedMenuLabelProps): import("react").JSX.Element;
3
3
  export declare function NestedMenuItemRow({ children, className, danger, disabled, href, target, rel, onClick, }: T.NestedMenuRowProps): import("react").JSX.Element;
4
- declare function NestedMenuComponent({ trigger, items, open, onOpenChange, align, className, }: T.Props): import("react").JSX.Element;
4
+ declare function NestedMenuComponent({ trigger, items, open, onOpenChange, align, size, className, popupProps, }: T.Props): import("react").JSX.Element;
5
5
  export declare const NestedMenu: typeof NestedMenuComponent & {
6
6
  Item: typeof NestedMenuItemRow;
7
7
  Label: typeof NestedMenuLabel;
@@ -1,4 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
+ import { Props as PopupProps } from 'uilib/components/Popup/Popup.types';
3
+ import { Size } from 'uilib/types';
2
4
  export type NestedMenuItem = {
3
5
  id: string;
4
6
  label: ReactNode;
@@ -19,7 +21,9 @@ export type Props = {
19
21
  open: boolean;
20
22
  onOpenChange: (open: boolean) => void;
21
23
  align?: 'start' | 'end';
24
+ size?: Size;
22
25
  className?: string;
26
+ popupProps?: Partial<PopupProps>;
23
27
  };
24
28
  export type NestedMenuProps = Props;
25
29
  export type NestedMenuRowProps = {
@@ -10,11 +10,12 @@ export declare class Popup extends Component<T.Props, T.State> {
10
10
  onContainerElemRef: (elem: any) => void;
11
11
  focused: boolean;
12
12
  isOpening: boolean;
13
+ openedByHover: boolean;
13
14
  pointerPressed: boolean;
14
- subscribedHoverControl: boolean;
15
15
  subscribedSizeChange: boolean;
16
16
  pointerDownTarget: any;
17
17
  isPointerPressedInside: boolean;
18
+ hoverCloseUnsub: (() => void) | null;
18
19
  id: any;
19
20
  parentPopupContent: any;
20
21
  timers: any;
@@ -36,8 +37,6 @@ export declare class Popup extends Component<T.Props, T.State> {
36
37
  subscribeScroll(): void;
37
38
  unsubscribeScroll(): void;
38
39
  unsubscribeSizeChange(): void;
39
- subscribeHoverControl(): void;
40
- unsubscribeHoverControl(): void;
41
40
  updateBounds(): void;
42
41
  updateBoundsThrottled: any;
43
42
  scheduleComputeShift(): void;
@@ -47,12 +46,21 @@ export declare class Popup extends Component<T.Props, T.State> {
47
46
  maxWidth: number | null;
48
47
  };
49
48
  setBoundaryFit(boundaryFit: H.BoundaryFit): void;
50
- checkHover: any;
51
49
  isControllable: () => boolean;
52
50
  isLastClickInside: () => any;
53
51
  onDocPointerDown: (e: PointerEvent) => void;
54
52
  onDocPointerUp: (e: PointerEvent) => void;
55
- isPointerOver(target: any, elem: any): any;
53
+ isPointerOver(target: any, elem: any): Element;
54
+ isHoverInside(target: any): Element;
55
+ isRelatedHover(target: any): boolean;
56
+ cancelHoverClose(): void;
57
+ scheduleHoverClose(): void;
58
+ onHoverEnter: () => void;
59
+ onHoverLeave: (e: PointerEvent) => void;
60
+ bindHoverHandlers(props?: Record<string, unknown>): {
61
+ onPointerEnter: (e: PointerEvent) => void;
62
+ onPointerLeave: (e: PointerEvent) => void;
63
+ };
56
64
  onScroll: any;
57
65
  onDocKeyDown: (e: KeyboardEvent) => void;
58
66
  onDocKeyUp: (e: KeyboardEvent) => void;
@@ -1,6 +1,6 @@
1
- import { Size } from 'uilib/types';
2
1
  import { ButtonProps } from '../Button/Button';
3
2
  import { ReactNode } from 'react';
3
+ import { Size } from 'uilib/types';
4
4
  type ID = string | number;
5
5
  export type Item = Omit<ButtonProps, 'children'> & {
6
6
  id: ID;
@@ -17,8 +17,10 @@ export type RenderProps = {
17
17
  };
18
18
  export type Props = {
19
19
  size?: Size;
20
+ variant?: 'default' | 'links';
20
21
  className?: string;
21
22
  tabsWrapperClassName?: string;
23
+ tabsInnerClassName?: string;
22
24
  tabsClassName?: string;
23
25
  contentClassName?: string;
24
26
  items: Item[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homecode/ui",
3
- "version": "5.12.0",
3
+ "version": "5.14.1",
4
4
  "description": "React UI components library",
5
5
  "scripts": {
6
6
  "tests": "jest",