habarico 7.3.0-beta.5 → 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,