habarico 7.3.0-beta.4 → 7.3.0-beta.6

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/lib/index.cjs CHANGED
@@ -46011,13 +46011,38 @@ const usePanelContext = () => {
46011
46011
  return context;
46012
46012
  };
46013
46013
 
46014
+ const RESIZE_HANDLE_SX = {
46015
+ corner: {
46016
+ right: 5,
46017
+ bottom: 5,
46018
+ width: 12,
46019
+ height: 12,
46020
+ borderRight: "2px solid",
46021
+ borderBottom: "2px solid",
46022
+ borderColor: "text.disabled",
46023
+ borderBottomRightRadius: "6px",
46024
+ cursor: "nwse-resize"
46025
+ },
46026
+ bottom: {
46027
+ left: "50%",
46028
+ bottom: 5,
46029
+ width: 24,
46030
+ height: 4,
46031
+ ml: "-12px",
46032
+ borderRadius: 2,
46033
+ bgcolor: "text.disabled",
46034
+ cursor: "ns-resize"
46035
+ }
46036
+ };
46037
+ const ResizeHandle = ({ at }) => /* @__PURE__ */ jsxRuntime.jsx(material.Box, { "aria-hidden": true, sx: { position: "absolute", ...RESIZE_HANDLE_SX[at] } });
46014
46038
  const Panel = ({
46015
46039
  variant,
46016
46040
  collapsible = false,
46017
46041
  defaultCollapsed = false,
46018
46042
  collapsed: collapsedProp,
46019
46043
  onCollapsedChange,
46020
- resizeHandle,
46044
+ resizable = false,
46045
+ resizeHandle = "corner",
46021
46046
  fullHeight = false,
46022
46047
  emphasized = false,
46023
46048
  children,
@@ -46068,24 +46093,7 @@ const Panel = ({
46068
46093
  },
46069
46094
  children: [
46070
46095
  /* @__PURE__ */ jsxRuntime.jsx(InsidePanelContextProvider, { value: true, children }),
46071
- resizeHandle && /* @__PURE__ */ jsxRuntime.jsx(
46072
- material.Box,
46073
- {
46074
- "aria-hidden": true,
46075
- sx: {
46076
- position: "absolute",
46077
- right: 5,
46078
- bottom: 5,
46079
- width: 12,
46080
- height: 12,
46081
- borderRight: "2px solid",
46082
- borderBottom: "2px solid",
46083
- borderColor: "text.disabled",
46084
- borderBottomRightRadius: "6px",
46085
- cursor: "nwse-resize"
46086
- }
46087
- }
46088
- )
46096
+ resizable && /* @__PURE__ */ jsxRuntime.jsx(ResizeHandle, { at: resizeHandle })
46089
46097
  ]
46090
46098
  }
46091
46099
  )
@@ -48214,13 +48222,6 @@ function useContainerWidth(options = {}) {
48214
48222
  measureWidth
48215
48223
  };
48216
48224
  }
48217
- var DEFAULT_BREAKPOINTS$1 = {
48218
- lg: 1200,
48219
- md: 996,
48220
- sm: 768,
48221
- xs: 480,
48222
- xxs: 0
48223
- };
48224
48225
 
48225
48226
  var cjs = {exports: {}};
48226
48227
 
@@ -51709,6 +51710,11 @@ function ResponsiveGridLayout(props) {
51709
51710
  var css_248z = ".react-grid-layout {\n position: relative;\n transition: height 200ms ease;\n}\n.react-grid-item {\n transition: all 200ms ease;\n transition-property: left, top, width, height;\n}\n.react-grid-item img {\n pointer-events: none;\n user-select: none;\n}\n.react-grid-item.cssTransforms {\n transition-property: transform, width, height;\n}\n.react-grid-item.resizing {\n transition: none;\n z-index: 1;\n will-change: width, height;\n}\n\n.react-grid-item.react-draggable-dragging {\n transition: none;\n z-index: 3;\n will-change: transform;\n}\n\n.react-grid-item.dropping {\n visibility: hidden;\n}\n\n.react-grid-item.react-grid-placeholder {\n background: red;\n opacity: 0.2;\n transition-duration: 100ms;\n z-index: 2;\n user-select: none;\n}\n\n.react-grid-item.react-grid-placeholder.placeholder-resizing {\n transition: none;\n}\n\n.react-grid-item > .react-resizable-handle {\n position: absolute;\n width: 20px;\n height: 20px;\n opacity: 0;\n}\n\n.react-grid-item:hover > .react-resizable-handle {\n opacity: 1;\n}\n\n.react-grid-item > .react-resizable-handle::after {\n content: \"\";\n position: absolute;\n right: 3px;\n bottom: 3px;\n width: 5px;\n height: 5px;\n border-right: 2px solid rgba(0, 0, 0, 0.4);\n border-bottom: 2px solid rgba(0, 0, 0, 0.4);\n}\n\n.react-resizable-hide > .react-resizable-handle {\n display: none;\n}\n\n.react-grid-item > .react-resizable-handle.react-resizable-handle-sw {\n bottom: 0;\n left: 0;\n cursor: sw-resize;\n transform: rotate(90deg);\n}\n.react-grid-item > .react-resizable-handle.react-resizable-handle-se {\n bottom: 0;\n right: 0;\n cursor: se-resize;\n}\n.react-grid-item > .react-resizable-handle.react-resizable-handle-nw {\n top: 0;\n left: 0;\n cursor: nw-resize;\n transform: rotate(180deg);\n}\n.react-grid-item > .react-resizable-handle.react-resizable-handle-ne {\n top: 0;\n right: 0;\n cursor: ne-resize;\n transform: rotate(270deg);\n}\n.react-grid-item > .react-resizable-handle.react-resizable-handle-w,\n.react-grid-item > .react-resizable-handle.react-resizable-handle-e {\n top: 50%;\n margin-top: -10px;\n cursor: ew-resize;\n}\n.react-grid-item > .react-resizable-handle.react-resizable-handle-w {\n left: 0;\n transform: rotate(135deg);\n}\n.react-grid-item > .react-resizable-handle.react-resizable-handle-e {\n right: 0;\n transform: rotate(315deg);\n}\n.react-grid-item > .react-resizable-handle.react-resizable-handle-n,\n.react-grid-item > .react-resizable-handle.react-resizable-handle-s {\n left: 50%;\n margin-left: -10px;\n cursor: ns-resize;\n}\n.react-grid-item > .react-resizable-handle.react-resizable-handle-n {\n top: 0;\n transform: rotate(225deg);\n}\n.react-grid-item > .react-resizable-handle.react-resizable-handle-s {\n bottom: 0;\n transform: rotate(45deg);\n}\n";
51710
51711
  styleInject(css_248z);
51711
51712
 
51713
+ const GRID_COLS = 12;
51714
+ const NARROW_BREAKPOINT = 996;
51715
+ const GRID_BREAKPOINTS = { lg: NARROW_BREAKPOINT, sm: 0 };
51716
+ const isNarrowWidth = (width) => getBreakpointFromWidth(GRID_BREAKPOINTS, width) === "sm";
51717
+ const SPACER_ID = "__spacer";
51712
51718
  const toLayout = (p) => ({
51713
51719
  i: p.id,
51714
51720
  x: p.layout.x,
@@ -51718,29 +51724,43 @@ const toLayout = (p) => ({
51718
51724
  minW: p.layout.minW,
51719
51725
  minH: p.layout.minH
51720
51726
  });
51721
- const toStackedLayout = (panels) => {
51727
+ const stackedHeight = (p) => p.layout.stackedH ?? p.layout.h;
51728
+ const stackedBottom = (panels) => panels.reduce((sum, p) => sum + stackedHeight(p), 0);
51729
+ const toStackedLayout = (panels, isEditing) => {
51722
51730
  let y = 0;
51723
- return panels.map((p) => {
51724
- const item = { i: p.id, x: 0, y, w: 1, h: p.layout.h, minH: p.layout.minH };
51725
- y += p.layout.h;
51726
- return item;
51731
+ return [...panels].sort((a, b) => a.layout.y - b.layout.y || a.layout.x - b.layout.x).map((p) => {
51732
+ const h = stackedHeight(p);
51733
+ const item = { i: p.id, x: 0, y, w: 1, h, minH: p.layout.minH };
51734
+ y += h;
51735
+ if (!isEditing) return item;
51736
+ return { ...item, minW: 1, maxW: 1, resizeHandles: ["s"], isDraggable: false };
51727
51737
  });
51728
51738
  };
51729
51739
  const buildLayouts = (isEditing, panels, spacerItem) => {
51730
- if (!isEditing) return { lg: panels.map(toLayout), sm: toStackedLayout(panels) };
51731
- const editItems = [...panels.map(toLayout), spacerItem];
51732
- return Object.fromEntries(Object.keys(DEFAULT_BREAKPOINTS$1).map((bp) => [bp, editItems]));
51740
+ const lg = panels.map(toLayout);
51741
+ return {
51742
+ lg: isEditing && spacerItem ? [...lg, spacerItem] : lg,
51743
+ sm: toStackedLayout(panels, isEditing)
51744
+ };
51733
51745
  };
51746
+ const mapLayoutBack = (panels, items, isNarrow) => panels.map((p) => {
51747
+ const item = items.find((l) => l.i === p.id && l.i !== SPACER_ID);
51748
+ if (!item) return { id: p.id, layout: p.layout };
51749
+ if (isNarrow) {
51750
+ if (item.h === stackedHeight(p)) return { id: p.id, layout: p.layout };
51751
+ return { id: p.id, layout: { ...p.layout, stackedH: item.h } };
51752
+ }
51753
+ return { id: p.id, layout: { ...p.layout, x: item.x, y: item.y, w: item.w, h: item.h } };
51754
+ });
51734
51755
 
51735
- const GRID_COLS = 12;
51736
- const COLS_VIEW = { lg: GRID_COLS, md: GRID_COLS, sm: 1, xs: 1, xxs: 1 };
51737
- const COLS_EDIT = { lg: GRID_COLS, md: GRID_COLS, sm: GRID_COLS, xs: GRID_COLS, xxs: GRID_COLS };
51756
+ const COLS = { lg: GRID_COLS, sm: 1 };
51738
51757
  const ROW_HEIGHT = 100;
51739
51758
  const GRID_MARGIN = 10;
51740
- const SPACER_ID = "__spacer";
51741
51759
  const ADD_GHOST_W = 3;
51742
51760
  const ADD_GHOST_FALLBACK_H = 2;
51743
51761
  const DOT_EXTRA_ROWS = 5;
51762
+ const STACKED_RESIZE_HIT_W = 96;
51763
+ const STACKED_RESIZE_HIT_H = 44;
51744
51764
  const noCompactorPreventCollision = { ...noCompactor, preventCollision: true };
51745
51765
  const rectsOverlap = (a, b) => a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;
51746
51766
  const computeAddGhostLayout = (panels, w) => {
@@ -51755,11 +51775,14 @@ const computeAddGhostLayout = (panels, w) => {
51755
51775
  }
51756
51776
  return { x: 0, y: bottom, w, h: ADD_GHOST_FALLBACK_H };
51757
51777
  };
51758
- const mapLayoutBack = (panels, items) => panels.map((p) => {
51759
- const item = items.find((l) => l.i === p.id && l.i !== SPACER_ID);
51760
- if (!item) return { id: p.id, layout: p.layout };
51761
- return { id: p.id, layout: { ...p.layout, x: item.x, y: item.y, w: item.w, h: item.h } };
51762
- });
51778
+ const addGhostLayoutFor = (panels, isNarrow) => isNarrow ? { x: 0, y: stackedBottom(panels), w: 1, h: ADD_GHOST_FALLBACK_H } : computeAddGhostLayout(panels, Math.min(ADD_GHOST_W, GRID_COLS));
51779
+ const gridBottom = (panels, isNarrow, addGhost) => {
51780
+ const rowBottoms = [
51781
+ ...isNarrow ? [stackedBottom(panels)] : panels.map((p) => p.layout.y + p.layout.h),
51782
+ ...addGhost ? [addGhost.y + addGhost.h] : []
51783
+ ];
51784
+ return panels.length > 0 || addGhost ? Math.max(...rowBottoms) : 4;
51785
+ };
51763
51786
  const DotGrid = ({
51764
51787
  cols,
51765
51788
  rows,
@@ -51790,19 +51813,19 @@ const DashboardGrid = ({
51790
51813
  }) => {
51791
51814
  const isEditing = mode === "edit";
51792
51815
  const { width, containerRef } = useContainerWidth();
51816
+ const isNarrow = isNarrowWidth(width);
51817
+ const isNarrowEdit = isEditing && isNarrow;
51818
+ const isWideEdit = isEditing && !isNarrow;
51819
+ const cols = isNarrow ? COLS.sm : COLS.lg;
51793
51820
  const theme = material.useTheme();
51794
51821
  const [isInteracting, setIsInteracting] = React.useState(false);
51795
51822
  const showAddGhost = isEditing && Boolean(addPanel) && panels.length > 0 && !isInteracting;
51796
- const addGhostLayout = showAddGhost ? computeAddGhostLayout(panels, Math.min(ADD_GHOST_W, GRID_COLS)) : null;
51823
+ const addGhostLayout = showAddGhost ? addGhostLayoutFor(panels, isNarrow) : null;
51797
51824
  const gridWidth = width;
51798
- const colWidth = (gridWidth - GRID_MARGIN * (GRID_COLS + 1)) / GRID_COLS;
51825
+ const colWidth = (gridWidth - GRID_MARGIN * (cols + 1)) / cols;
51799
51826
  const cellW = colWidth + GRID_MARGIN;
51800
51827
  const cellH = ROW_HEIGHT + GRID_MARGIN;
51801
- const rowBottoms = [
51802
- ...panels.map((p) => p.layout.y + p.layout.h),
51803
- ...addGhostLayout ? [addGhostLayout.y + addGhostLayout.h] : []
51804
- ];
51805
- const maxGridRow = rowBottoms.length > 0 ? Math.max(...rowBottoms) : 4;
51828
+ const maxGridRow = gridBottom(panels, isNarrow, addGhostLayout);
51806
51829
  const [screenDotRows, setScreenDotRows] = React.useState(null);
51807
51830
  React.useEffect(() => {
51808
51831
  if (!isEditing || !containerRef.current) {
@@ -51823,10 +51846,11 @@ const DashboardGrid = ({
51823
51846
  h: 1,
51824
51847
  static: true
51825
51848
  };
51826
- const layouts = buildLayouts(isEditing, panels, spacerItem);
51849
+ const showSpacer = isWideEdit;
51850
+ const layouts = buildLayouts(isEditing, panels, showSpacer ? spacerItem : void 0);
51827
51851
  const handleLayoutChange = (currentLayout, _all) => {
51828
51852
  if (!isEditing || !currentLayout || !onLayoutChange) return;
51829
- onLayoutChange(mapLayoutBack(panels, currentLayout));
51853
+ onLayoutChange(mapLayoutBack(panels, currentLayout, isNarrow));
51830
51854
  };
51831
51855
  const emptyContent = isEditing && addPanel ? /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { minHeight: ROW_HEIGHT * 2 + GRID_MARGIN }, children: addPanel }) : /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { py: 8, textAlign: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { color: "text.secondary", children: emptyMessage }) });
51832
51856
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -51850,13 +51874,24 @@ const DashboardGrid = ({
51850
51874
  // resize affordance. Keep the handle element itself (the transparent hit area) so resize
51851
51875
  // still works; only our Panel corner is drawn.
51852
51876
  "& .react-grid-item > .react-resizable-handle::after": { display: "none" },
51877
+ // RGL's bottom-edge handle is a 20px square turned 45° — too small a target on a phone,
51878
+ // where the stack is resized. Widen it into an upright touch target centred on the edge
51879
+ // and let it take the touch instead of the page scroll.
51880
+ "& .react-grid-item > .react-resizable-handle.react-resizable-handle-s": {
51881
+ width: STACKED_RESIZE_HIT_W,
51882
+ height: STACKED_RESIZE_HIT_H,
51883
+ bottom: -GRID_MARGIN,
51884
+ ml: `${-STACKED_RESIZE_HIT_W / 2}px`,
51885
+ transform: "none",
51886
+ touchAction: "none"
51887
+ },
51853
51888
  ...sx
51854
51889
  },
51855
51890
  children: panels.length === 0 ? emptyContent : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
51856
51891
  isEditing && /* @__PURE__ */ jsxRuntime.jsx(
51857
51892
  DotGrid,
51858
51893
  {
51859
- cols: GRID_COLS,
51894
+ cols,
51860
51895
  rows: dotRows,
51861
51896
  cellW,
51862
51897
  cellH,
@@ -51871,10 +51906,11 @@ const DashboardGrid = ({
51871
51906
  className: "layout",
51872
51907
  width: gridWidth,
51873
51908
  layouts,
51874
- cols: isEditing ? COLS_EDIT : COLS_VIEW,
51909
+ breakpoints: GRID_BREAKPOINTS,
51910
+ cols: COLS,
51875
51911
  rowHeight: ROW_HEIGHT,
51876
51912
  margin: [GRID_MARGIN, GRID_MARGIN],
51877
- compactor: noCompactorPreventCollision,
51913
+ compactor: isNarrowEdit ? verticalCompactor : noCompactorPreventCollision,
51878
51914
  onLayoutChange: handleLayoutChange,
51879
51915
  dragConfig: { enabled: isEditing, handle: `.${PANEL_DRAG_HANDLE_CLASS}` },
51880
51916
  resizeConfig: { enabled: isEditing },
@@ -51883,35 +51919,43 @@ const DashboardGrid = ({
51883
51919
  onResizeStart: () => setIsInteracting(true),
51884
51920
  onResizeStop: () => setIsInteracting(false),
51885
51921
  children: [
51886
- isEditing && /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { display: "none" } }, SPACER_ID),
51922
+ showSpacer && /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { display: "none" } }, SPACER_ID),
51887
51923
  panels.map((p) => (
51888
51924
  // raise the hovered item so an inner chart tooltip isn't painted over by neighbours
51889
- /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { height: "100%", "&:hover": { zIndex: 5 } }, children: /* @__PURE__ */ jsxRuntime.jsxs(Panel, { resizeHandle: isEditing, sx: { height: "100%" }, children: [
51890
- /* @__PURE__ */ jsxRuntime.jsx(
51891
- PanelHeader,
51892
- {
51893
- label: p.label,
51894
- icon: p.icon,
51895
- iconColor: p.iconColor,
51896
- iconBadge: p.iconBadge,
51897
- help: p.help,
51898
- actions: p.actions,
51899
- dragHandle: isEditing
51900
- }
51901
- ),
51902
- /* @__PURE__ */ jsxRuntime.jsx(
51903
- PanelContent,
51904
- {
51905
- paddingSize: p.contentPaddingSize,
51906
- sx: { flexGrow: 1, minHeight: 0, overflow: "auto" },
51907
- children: p.content
51908
- }
51909
- )
51910
- ] }) }, p.id)
51925
+ /* @__PURE__ */ jsxRuntime.jsx(material.Box, { sx: { height: "100%", "&:hover": { zIndex: 5 } }, children: /* @__PURE__ */ jsxRuntime.jsxs(
51926
+ Panel,
51927
+ {
51928
+ resizable: isEditing,
51929
+ resizeHandle: isNarrow ? "bottom" : "corner",
51930
+ sx: { height: "100%" },
51931
+ children: [
51932
+ /* @__PURE__ */ jsxRuntime.jsx(
51933
+ PanelHeader,
51934
+ {
51935
+ label: p.label,
51936
+ icon: p.icon,
51937
+ iconColor: p.iconColor,
51938
+ iconBadge: p.iconBadge,
51939
+ help: p.help,
51940
+ actions: p.actions,
51941
+ dragHandle: isWideEdit
51942
+ }
51943
+ ),
51944
+ /* @__PURE__ */ jsxRuntime.jsx(
51945
+ PanelContent,
51946
+ {
51947
+ paddingSize: p.contentPaddingSize,
51948
+ sx: { flexGrow: 1, minHeight: 0, overflow: "auto" },
51949
+ children: p.content
51950
+ }
51951
+ )
51952
+ ]
51953
+ }
51954
+ ) }, p.id)
51911
51955
  ))
51912
51956
  ]
51913
51957
  },
51914
- isEditing ? "edit" : "view"
51958
+ isNarrowEdit ? "edit-narrow" : mode
51915
51959
  ),
51916
51960
  addGhostLayout && /* @__PURE__ */ jsxRuntime.jsx(
51917
51961
  material.Box,
@@ -55441,6 +55485,7 @@ const MenuItem = ({
55441
55485
  highlighted,
55442
55486
  sub,
55443
55487
  dropdown,
55488
+ expanded,
55444
55489
  tooltip,
55445
55490
  onMouseEnter,
55446
55491
  onMouseLeave,
@@ -55450,12 +55495,13 @@ const MenuItem = ({
55450
55495
  const isLight = theme.palette.mode === "light";
55451
55496
  const activeText = isLight ? theme.palette.primary.dark : theme.palette.primary.light;
55452
55497
  const activeIcon = isLight ? theme.palette.primary.main : theme.palette.primary.lighter;
55498
+ const isGroup = !!item.items?.length;
55499
+ const linkProps = isGroup ? { "aria-expanded": !!expanded } : { component: RouterLink, href: item.href };
55453
55500
  return /* @__PURE__ */ jsxRuntime.jsx(material.Tooltip, { title: tooltip, placement: "right", children: /* @__PURE__ */ jsxRuntime.jsxs(
55454
55501
  material.ListItemButton,
55455
55502
  {
55456
55503
  disableGutters: true,
55457
- component: RouterLink,
55458
- href: item.href,
55504
+ ...linkProps,
55459
55505
  onMouseEnter,
55460
55506
  onMouseLeave,
55461
55507
  onClick,
@@ -55504,6 +55550,7 @@ const MenuItemWithPopper = ({ children, onClick, ...rest }) => {
55504
55550
  const isOverSubMenuRef = React.useRef(false);
55505
55551
  const openTimeoutRef = React.useRef(void 0);
55506
55552
  const closeTimeoutRef = React.useRef(void 0);
55553
+ const openedByClickRef = React.useRef(false);
55507
55554
  const closeIfNotOver = React.useCallback(() => {
55508
55555
  clearTimeout(closeTimeoutRef.current);
55509
55556
  closeTimeoutRef.current = setTimeout(() => {
@@ -55517,9 +55564,22 @@ const MenuItemWithPopper = ({ children, onClick, ...rest }) => {
55517
55564
  isOverMenuRef.current = true;
55518
55565
  const target = e.currentTarget;
55519
55566
  openTimeoutRef.current = setTimeout(() => {
55567
+ openedByClickRef.current = false;
55520
55568
  setAnchorEl(target);
55521
55569
  }, POPOVER_OPEN_DEBOUNCE);
55522
55570
  }, []);
55571
+ const togglePopper = React.useCallback(
55572
+ (e) => {
55573
+ clearTimeout(openTimeoutRef.current);
55574
+ clearTimeout(closeTimeoutRef.current);
55575
+ const target = e.currentTarget;
55576
+ const close = Boolean(anchorEl) && openedByClickRef.current;
55577
+ openedByClickRef.current = !close;
55578
+ setAnchorEl(close ? null : target);
55579
+ onClick?.(e);
55580
+ },
55581
+ [anchorEl, onClick]
55582
+ );
55523
55583
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
55524
55584
  /* @__PURE__ */ jsxRuntime.jsx(
55525
55585
  MenuItem,
@@ -55531,7 +55591,8 @@ const MenuItemWithPopper = ({ children, onClick, ...rest }) => {
55531
55591
  isOverMenuRef.current = false;
55532
55592
  closeIfNotOver();
55533
55593
  },
55534
- onClick
55594
+ onClick: togglePopper,
55595
+ expanded: Boolean(anchorEl)
55535
55596
  }
55536
55597
  ),
55537
55598
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -55629,8 +55690,39 @@ const MenuListCollapsed = ({ items, level, onItemClick }) => {
55629
55690
  const SUB_INDENT = 40;
55630
55691
  const ELBOW_WIDTH = 16;
55631
55692
  const ELBOW_RADIUS = 10;
55632
- const MenuListFull = ({ items, level, onItemClick }) => {
55693
+ const MenuListFullItem = ({ item, level, onItemClick }) => {
55633
55694
  const { isActive, isExpanded } = useActiveExpanded();
55695
+ const pathname = usePathname();
55696
+ const routeExpanded = isExpanded(item);
55697
+ const [open, setOpen] = React.useState(routeExpanded);
55698
+ const [syncedPathname, setSyncedPathname] = React.useState(pathname);
55699
+ if (syncedPathname !== pathname) {
55700
+ setSyncedPathname(pathname);
55701
+ if (routeExpanded) setOpen(true);
55702
+ }
55703
+ const active = isActive(item);
55704
+ const isGroup = !!item.items?.length;
55705
+ const highlighted = !active && isGroup && open;
55706
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
55707
+ /* @__PURE__ */ jsxRuntime.jsx(
55708
+ MenuItem,
55709
+ {
55710
+ item,
55711
+ active,
55712
+ highlighted,
55713
+ expanded: isGroup ? open : void 0,
55714
+ sub: level >= 1,
55715
+ collapsed: false,
55716
+ onClick: () => {
55717
+ if (isGroup) setOpen((value) => !value);
55718
+ onItemClick?.(item);
55719
+ }
55720
+ }
55721
+ ),
55722
+ isGroup && /* @__PURE__ */ jsxRuntime.jsx(material.Collapse, { in: open, children: /* @__PURE__ */ jsxRuntime.jsx(MenuListFull, { items: item.items, onItemClick, level: level + 1 }) })
55723
+ ] });
55724
+ };
55725
+ const MenuListFull = ({ items, level, onItemClick }) => {
55634
55726
  const theme = material.useTheme();
55635
55727
  const isSub = level >= 1;
55636
55728
  const lineColor = varAlpha(theme.palette.grey["500Channel"], 0.32);
@@ -55651,9 +55743,7 @@ const MenuListFull = ({ items, level, onItemClick }) => {
55651
55743
  position: isSub ? "relative" : void 0
55652
55744
  },
55653
55745
  children: items.map((item, index) => {
55654
- const active = isActive(item);
55655
- const highlighted = !active && !!item.items?.length && isExpanded(item);
55656
- return /* @__PURE__ */ jsxRuntime.jsxs(
55746
+ return /* @__PURE__ */ jsxRuntime.jsx(
55657
55747
  material.ListItem,
55658
55748
  {
55659
55749
  disableGutters: true,
@@ -55684,22 +55774,7 @@ const MenuListFull = ({ items, level, onItemClick }) => {
55684
55774
  }
55685
55775
  }
55686
55776
  },
55687
- children: [
55688
- /* @__PURE__ */ jsxRuntime.jsx(
55689
- MenuItem,
55690
- {
55691
- item,
55692
- active,
55693
- highlighted,
55694
- sub: isSub,
55695
- collapsed: false,
55696
- onClick: () => {
55697
- onItemClick?.(item);
55698
- }
55699
- }
55700
- ),
55701
- item.items && /* @__PURE__ */ jsxRuntime.jsx(material.Collapse, { in: isExpanded(item), children: /* @__PURE__ */ jsxRuntime.jsx(MenuListFull, { items: item.items, onItemClick, level: level + 1 }) })
55702
- ]
55777
+ children: /* @__PURE__ */ jsxRuntime.jsx(MenuListFullItem, { item, level, onItemClick })
55703
55778
  },
55704
55779
  index
55705
55780
  );