@mieweb/ui 0.10.0-dev.3 → 0.10.0-dev.4

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/dist/index.cjs CHANGED
@@ -40688,86 +40688,149 @@ function SidebarNavGroup({
40688
40688
  children,
40689
40689
  defaultExpanded = false,
40690
40690
  groupId,
40691
- className
40691
+ className,
40692
+ forceMount
40692
40693
  }) {
40693
40694
  const { isCollapsed, isMobileViewport, expandedGroup, toggleGroup } = useSidebar();
40694
40695
  const showCollapsed = !isMobileViewport && isCollapsed;
40696
+ const prefersReducedMotion = chunk6HFFWEM3_cjs.usePrefersReducedMotion();
40697
+ const contentId = React13.useId();
40698
+ const groupRef = React13.useRef(null);
40699
+ const triggerRef = React13.useRef(null);
40695
40700
  const isExpanded = groupId ? expandedGroup === groupId : defaultExpanded;
40696
40701
  const [localExpanded, setLocalExpanded] = React13.useState(defaultExpanded);
40697
40702
  const effectiveExpanded = groupId ? isExpanded : localExpanded;
40703
+ const itemsVisible = !showCollapsed && effectiveExpanded;
40704
+ const focusWasInsideRef = React13.useRef(false);
40705
+ const captureFocusInside = React13.useCallback(() => {
40706
+ const active = document.activeElement;
40707
+ focusWasInsideRef.current = active !== triggerRef.current && groupRef.current?.contains(active) === true;
40708
+ }, []);
40709
+ React13.useEffect(() => {
40710
+ if (!itemsVisible) return;
40711
+ function trackFocus(event) {
40712
+ const target = event.target;
40713
+ focusWasInsideRef.current = target !== triggerRef.current && groupRef.current?.contains(target) === true;
40714
+ }
40715
+ document.addEventListener("focusin", trackFocus);
40716
+ return () => document.removeEventListener("focusin", trackFocus);
40717
+ }, [itemsVisible]);
40718
+ React13.useEffect(() => {
40719
+ if (itemsVisible) return;
40720
+ if (focusWasInsideRef.current) {
40721
+ focusWasInsideRef.current = false;
40722
+ triggerRef.current?.focus();
40723
+ }
40724
+ }, [itemsVisible]);
40698
40725
  const handleToggle = React13.useCallback(() => {
40726
+ captureFocusInside();
40699
40727
  if (groupId) {
40700
40728
  toggleGroup(groupId);
40701
40729
  } else {
40702
40730
  setLocalExpanded((prev) => !prev);
40703
40731
  }
40704
- }, [groupId, toggleGroup]);
40705
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "sidebar-nav-group", className: chunkS5RVSXDV_cjs.cn("mb-2", className), children: [
40706
- /* @__PURE__ */ jsxRuntime.jsxs(
40707
- "button",
40708
- {
40709
- "data-slot": "sidebar-nav-group-button",
40710
- onClick: handleToggle,
40711
- className: chunkS5RVSXDV_cjs.cn(
40712
- "flex w-full items-center rounded-lg px-3 py-2 text-sm font-semibold",
40713
- "text-neutral-700 dark:text-neutral-300",
40714
- "transition-colors hover:bg-neutral-100 dark:hover:bg-neutral-800",
40715
- showCollapsed && "justify-center"
40716
- ),
40717
- title: showCollapsed ? label : void 0,
40718
- "aria-label": showCollapsed ? label : void 0,
40719
- children: [
40720
- icon && /* @__PURE__ */ jsxRuntime.jsx(
40721
- "span",
40722
- {
40723
- className: chunkS5RVSXDV_cjs.cn(
40724
- "text-muted-foreground h-5 w-5 flex-shrink-0",
40725
- !showCollapsed && "me-3"
40726
- ),
40727
- children: icon
40728
- }
40729
- ),
40730
- /* @__PURE__ */ jsxRuntime.jsxs(chunkNV2CWBI2_cjs.AnimatedPresence, { initial: false, children: [
40731
- !showCollapsed && /* @__PURE__ */ jsxRuntime.jsx(
40732
- chunkNV2CWBI2_cjs.Animated,
40733
- {
40734
- as: "span",
40735
- preset: "sidebarLabel",
40736
- mode: "presence",
40737
- className: "flex-1 truncate text-start",
40738
- children: label
40739
- },
40740
- "label"
40732
+ }, [captureFocusInside, groupId, toggleGroup]);
40733
+ const items = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 ps-2", children });
40734
+ const panelInDom = forceMount || itemsVisible;
40735
+ return /* @__PURE__ */ jsxRuntime.jsxs(
40736
+ "div",
40737
+ {
40738
+ ref: groupRef,
40739
+ "data-slot": "sidebar-nav-group",
40740
+ className: chunkS5RVSXDV_cjs.cn("mb-2", className),
40741
+ children: [
40742
+ /* @__PURE__ */ jsxRuntime.jsxs(
40743
+ "button",
40744
+ {
40745
+ ref: triggerRef,
40746
+ "data-slot": "sidebar-nav-group-button",
40747
+ onClick: handleToggle,
40748
+ "aria-expanded": itemsVisible,
40749
+ "aria-controls": panelInDom ? contentId : void 0,
40750
+ className: chunkS5RVSXDV_cjs.cn(
40751
+ "flex w-full items-center rounded-lg px-3 py-2 text-sm font-semibold",
40752
+ "text-neutral-700 dark:text-neutral-300",
40753
+ "transition-colors hover:bg-neutral-100 dark:hover:bg-neutral-800",
40754
+ showCollapsed && "justify-center"
40741
40755
  ),
40742
- !showCollapsed && /* @__PURE__ */ jsxRuntime.jsx(
40743
- chunkNV2CWBI2_cjs.Animated,
40744
- {
40745
- as: "span",
40746
- preset: "sidebarLabel",
40747
- mode: "presence",
40748
- className: chunkS5RVSXDV_cjs.cn(
40749
- "ms-2 flex-shrink-0 transition-transform duration-200",
40750
- effectiveExpanded && "rotate-180"
40756
+ title: showCollapsed ? label : void 0,
40757
+ "aria-label": showCollapsed ? label : void 0,
40758
+ children: [
40759
+ icon && /* @__PURE__ */ jsxRuntime.jsx(
40760
+ "span",
40761
+ {
40762
+ className: chunkS5RVSXDV_cjs.cn(
40763
+ "text-muted-foreground h-5 w-5 flex-shrink-0",
40764
+ !showCollapsed && "me-3"
40765
+ ),
40766
+ children: icon
40767
+ }
40768
+ ),
40769
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkNV2CWBI2_cjs.AnimatedPresence, { initial: false, children: [
40770
+ !showCollapsed && /* @__PURE__ */ jsxRuntime.jsx(
40771
+ chunkNV2CWBI2_cjs.Animated,
40772
+ {
40773
+ as: "span",
40774
+ preset: "sidebarLabel",
40775
+ mode: "presence",
40776
+ className: "flex-1 truncate text-start",
40777
+ children: label
40778
+ },
40779
+ "label"
40751
40780
  ),
40752
- children: /* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon4, {})
40753
- },
40754
- "chevron"
40755
- )
40756
- ] })
40757
- ]
40758
- }
40759
- ),
40760
- !showCollapsed && /* @__PURE__ */ jsxRuntime.jsx(
40761
- "div",
40762
- {
40763
- className: chunkS5RVSXDV_cjs.cn(
40764
- "overflow-hidden transition-all duration-300",
40765
- effectiveExpanded ? "mt-1 max-h-[1000px] opacity-100" : "max-h-0 opacity-0"
40781
+ !showCollapsed && /* @__PURE__ */ jsxRuntime.jsx(
40782
+ chunkNV2CWBI2_cjs.Animated,
40783
+ {
40784
+ as: "span",
40785
+ preset: "sidebarLabel",
40786
+ mode: "presence",
40787
+ className: chunkS5RVSXDV_cjs.cn(
40788
+ "ms-2 flex-shrink-0 transition-transform duration-200",
40789
+ effectiveExpanded && "rotate-180"
40790
+ ),
40791
+ children: /* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon4, {})
40792
+ },
40793
+ "chevron"
40794
+ )
40795
+ ] })
40796
+ ]
40797
+ }
40766
40798
  ),
40767
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ps-2", children })
40768
- }
40769
- )
40770
- ] });
40799
+ forceMount ? (
40800
+ /*
40801
+ * Deliberately outside the rail-collapsed gate. Gating it there would
40802
+ * unmount the items whenever the sidebar collapsed, destroying exactly
40803
+ * the state this prop exists to preserve — the prop would hold its
40804
+ * promise for the group's own toggle and quietly break it for the
40805
+ * rail's, which is worse than not offering it.
40806
+ */
40807
+ /* @__PURE__ */ jsxRuntime.jsx(
40808
+ "div",
40809
+ {
40810
+ id: contentId,
40811
+ "data-slot": "sidebar-nav-group-items",
40812
+ "data-state": itemsVisible ? "open" : "closed",
40813
+ hidden: !itemsVisible,
40814
+ children: items
40815
+ }
40816
+ )
40817
+ ) : !showCollapsed && /* @__PURE__ */ jsxRuntime.jsx(chunkNV2CWBI2_cjs.AnimatedPresence, { initial: false, children: effectiveExpanded && /* @__PURE__ */ jsxRuntime.jsx(
40818
+ chunkNV2CWBI2_cjs.Animated,
40819
+ {
40820
+ id: contentId,
40821
+ "data-slot": "sidebar-nav-group-items",
40822
+ "data-state": "open",
40823
+ preset: "collapse",
40824
+ mode: "presence",
40825
+ enabled: !prefersReducedMotion,
40826
+ className: "overflow-hidden",
40827
+ children: items
40828
+ },
40829
+ "items"
40830
+ ) })
40831
+ ]
40832
+ }
40833
+ );
40771
40834
  }
40772
40835
  function SidebarNavItem({
40773
40836
  label,