@orderly.network/layout-split 2.0.4-alpha.0 → 2.0.4-alpha.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.
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import React, { createContext, forwardRef, useMemo, useCallback, useContext, useState, useEffect, useRef } from 'react';
1
+ import React, { createContext, forwardRef, useMemo, useCallback, useContext, useState, useEffect, useRef, useLayoutEffect } from 'react';
2
2
  import { cn, Box, Flex, createInterceptor, Text, CloseIcon, Divider, DropdownMenuRoot, DropdownMenuTrigger, DropdownMenuPortal, DropdownMenuContent } from '@orderly.network/ui';
3
3
  import * as ResizablePrimitive from 'react-resizable-panels';
4
4
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
@@ -25,7 +25,7 @@ function ResizablePanelGroup({
25
25
  {
26
26
  "data-slot": "resizable-panel-group",
27
27
  className: cn(
28
- "aria-[orientation=vertical]:oui-flex-col oui-flex oui-w-full oui-h-full",
28
+ "oui-flex oui-size-full aria-[orientation=vertical]:oui-flex-col",
29
29
  className
30
30
  ),
31
31
  ...props
@@ -55,11 +55,11 @@ function ResizableHandle({
55
55
  {
56
56
  "data-slot": "resizable-handle",
57
57
  className: cn(
58
- "oui-bg-primary focus:oui-ring-0 focus-visible:oui-ring-0 focus-visible:oui-outline-none after:oui-absolute after:oui-inset-y-0 after:oui-left-1/2 after:oui-w-1 after:-oui-translate-x-1/2 aria-[orientation=horizontal]:oui-h-px aria-[orientation=horizontal]:oui-w-full aria-[orientation=horizontal]:after:oui-left-0 aria-[orientation=horizontal]:after:oui-h-1 aria-[orientation=horizontal]:after:oui-w-full aria-[orientation=horizontal]:after:oui-translate-x-0 aria-[orientation=horizontal]:after:-oui-translate-y-1/2 [&[aria-orientation=horizontal]>div]:oui-rotate-90 oui-relative oui-flex oui-w-px oui-items-center oui-justify-center",
58
+ "oui-relative oui-flex oui-w-px oui-items-center oui-justify-center oui-bg-primary after:oui-absolute after:oui-inset-y-0 after:oui-left-1/2 after:oui-w-1 after:-oui-translate-x-1/2 focus:oui-ring-0 focus-visible:oui-outline-none focus-visible:oui-ring-0 aria-[orientation=horizontal]:oui-h-px aria-[orientation=horizontal]:oui-w-full aria-[orientation=horizontal]:after:oui-left-0 aria-[orientation=horizontal]:after:oui-h-1 aria-[orientation=horizontal]:after:oui-w-full aria-[orientation=horizontal]:after:-oui-translate-y-1/2 aria-[orientation=horizontal]:after:oui-translate-x-0 [&[aria-orientation=horizontal]>div]:oui-rotate-90",
59
59
  className
60
60
  ),
61
61
  ...props,
62
- children: withHandle && /* @__PURE__ */ jsx("div", { className: "oui-bg-primary oui-z-10 oui-flex oui-h-6 oui-w-1 oui-shrink-0 oui-rounded-lg" })
62
+ children: withHandle && /* @__PURE__ */ jsx("div", { className: "oui-z-10 oui-flex oui-h-6 oui-w-1 oui-shrink-0 oui-rounded-lg oui-bg-primary" })
63
63
  }
64
64
  );
65
65
  }
@@ -132,7 +132,7 @@ function SplitLayout({
132
132
  });
133
133
  onSizeChange?.(sizesAsStrings);
134
134
  },
135
- [onSizeChange, count]
135
+ [onSizeChange, count, sizes]
136
136
  );
137
137
  if (count === 0) return /* @__PURE__ */ jsx(Fragment, {});
138
138
  const marginPx = gap != null ? gap * 2 : 4;
@@ -1202,9 +1202,9 @@ var LayoutSwitchButton = ({
1202
1202
  {
1203
1203
  justify: position === "right" ? "end" : "start",
1204
1204
  className: cn(
1205
- "oui-w-[148px] oui-h-[100px]",
1206
- "oui-bg-base-10 oui-rounded-[10px]",
1207
- "oui-border-[4px] oui-border-base-5 group-hover:oui-border-primary-light",
1205
+ "oui-h-[100px] oui-w-[148px]",
1206
+ "oui-rounded-[10px] oui-bg-base-10",
1207
+ "oui-border-4 oui-border-base-5 group-hover:oui-border-primary-light",
1208
1208
  layout === position && "!oui-border-primary-light"
1209
1209
  ),
1210
1210
  children: /* @__PURE__ */ jsx(Box, { p: 1, children: /* @__PURE__ */ jsx(OrderEntryIcon, {}) })
@@ -1257,7 +1257,7 @@ var LayoutSwitchButton = ({
1257
1257
  onMouseLeave: () => setHoveredMarket(null),
1258
1258
  className: "oui-group",
1259
1259
  children: [
1260
- /* @__PURE__ */ jsxs(Flex, { justify: "center", className: "oui-w-[148px] oui-h-[100px]", children: [
1260
+ /* @__PURE__ */ jsxs(Flex, { justify: "center", className: "oui-h-[100px] oui-w-[148px]", children: [
1261
1261
  position === "left" && /* @__PURE__ */ jsx(MarketLeftIcon, { isSelected, isHovered }),
1262
1262
  position === "top" && /* @__PURE__ */ jsx(MarketTopIcon, { isSelected, isHovered }),
1263
1263
  position === "bottom" && /* @__PURE__ */ jsx(MarketBottomIcon, { isSelected, isHovered }),
@@ -1411,7 +1411,7 @@ var TRADINGVIEW_MIN_WIDTH = 540;
1411
1411
  var DATA_LIST_MAX_HEIGHT = 800;
1412
1412
  var DATA_LIST_INITIAL_HEIGHT = 350;
1413
1413
  var SPACE = 8;
1414
- var SYMBOL_INFO_BAR_HEIGHT = 54;
1414
+ var SYMBOL_INFO_BAR_HEIGHT = 56;
1415
1415
  var ORDERLY_ORDER_ENTRY_SIDE_MARKETS_LAYOUT = "orderly_order_entry_side_markets_layout";
1416
1416
  var ORDERLY_SIDE_MARKETS_MODE_KEY = "orderly_side_markets_mode";
1417
1417
  var ORDERLY_HORIZONTAL_MARKETS_LAYOUT = "orderly_horizontal_markets_layout";
@@ -1645,8 +1645,7 @@ function useSplitLayout(options = {}) {
1645
1645
  const {
1646
1646
  initialLayout = "right",
1647
1647
  initialMarketLayout = "left",
1648
- canTrade = true,
1649
- isFirstTimeDeposit = false
1648
+ canTrade = true
1650
1649
  } = options;
1651
1650
  const max2XL = useMediaQuery("(max-width: 1279px)");
1652
1651
  const min3XL = useMediaQuery("(min-width: 1440px)");
@@ -1701,30 +1700,6 @@ function useSplitLayout(options = {}) {
1701
1700
  ORDERLY_ORDER_ENTRY_EXTRA_HEIGHT,
1702
1701
  0
1703
1702
  );
1704
- useCallback(
1705
- (preSize, nextSize, boxHeight) => {
1706
- if (!boxHeight) return;
1707
- const splitTradingviewHeight = boxHeight * preSize / 100;
1708
- const splitOrderbookHeight = boxHeight * nextSize / 100;
1709
- const tradingviewHeight = Math.min(
1710
- Math.max(splitTradingviewHeight, TRADINGVIEW_MIN_HEIGHT),
1711
- max2XL ? 1200 : 600
1712
- );
1713
- const orderbookHeight = Math.min(
1714
- Math.max(splitOrderbookHeight, ORDERBOOK_MIN_HEIGHT),
1715
- ORDERBOOK_MAX_HEIGHT
1716
- );
1717
- if (splitOrderbookHeight >= orderbookHeight) {
1718
- const offset = splitOrderbookHeight - orderbookHeight;
1719
- setExtraHeight(Math.max(0, extraHeight - offset));
1720
- } else if (tradingviewHeight + orderbookHeight < (max2XL ? 1200 : 600) + ORDERBOOK_MAX_HEIGHT) {
1721
- const height = tradingviewHeight + orderbookHeight + SPACE + SYMBOL_INFO_BAR_HEIGHT;
1722
- const offset = Math.max(0, height - 0);
1723
- setExtraHeight(extraHeight + offset);
1724
- }
1725
- },
1726
- [max2XL, extraHeight, setExtraHeight]
1727
- );
1728
1703
  const tradingviewMaxHeight = max2XL ? 1200 : 600;
1729
1704
  const dataListHeight = canTrade ? 379 : 277;
1730
1705
  const memoizedPanelSize = useMemo(() => {
@@ -1887,27 +1862,22 @@ var TradingSortablePanel = (props) => {
1887
1862
  );
1888
1863
  };
1889
1864
  var SplitLineBar = (props) => {
1890
- const { onMouseDown, mode = "horizontal", ...rest } = props;
1891
- const disable = useMemo(
1892
- () => props.className?.split(" ").includes("disable"),
1893
- [props.className]
1894
- );
1895
- const filteredCls = useMemo(
1896
- () => props.className?.split(" ").filter((cls) => cls !== "disable"),
1897
- [props.className]
1898
- );
1865
+ const { onMouseDown, mode = "horizontal", className, ...rest } = props;
1866
+ const tokens = className?.split(/\s+/).filter(Boolean) ?? [];
1867
+ const disable = tokens.includes("disable");
1868
+ const filteredCls = tokens.filter((t) => t !== "disable").join(" ");
1899
1869
  return /* @__PURE__ */ jsx(
1900
1870
  "div",
1901
1871
  {
1902
1872
  ...rest,
1903
1873
  className: cn(
1904
- filteredCls,
1874
+ filteredCls || void 0,
1905
1875
  "!oui-transition-none",
1906
- "!oui-shadow-none !oui-bg-transparent",
1876
+ "!oui-bg-transparent !oui-shadow-none",
1907
1877
  "hover:!oui-bg-primary-light hover:!oui-shadow-[0px_0px_4px_0px] hover:!oui-shadow-primary-light/80",
1908
1878
  "active:!oui-bg-primary-light active:!oui-shadow-[0px_0px_4px_0px] active:!oui-shadow-primary-light/80",
1909
1879
  "focus:!oui-bg-primary-light focus:!oui-shadow-[0px_0px_4px_0px] focus:!oui-shadow-primary-light/80",
1910
- mode === "horizontal" ? "!oui-w-[2px] !oui-min-w-[2px] !oui-mx-[3px]" : "!oui-h-[2px] !oui-min-h-[2px] !oui-my-[3px]",
1880
+ mode === "horizontal" ? "!oui-mx-[3px] !oui-w-[2px] !oui-min-w-[2px]" : "!oui-my-[3px] !oui-h-[2px] !oui-min-h-[2px]",
1911
1881
  disable && "oui-pointer-events-none"
1912
1882
  ),
1913
1883
  children: /* @__PURE__ */ jsx(
@@ -1949,6 +1919,18 @@ var DEFAULT_SORTABLE_ITEMS = [
1949
1919
  TRADING_PANEL_IDS.ASSETS,
1950
1920
  TRADING_PANEL_IDS.ORDER_ENTRY
1951
1921
  ];
1922
+ function orderEntrySortablePanelClassName(id) {
1923
+ if (id === TRADING_PANEL_IDS.MARGIN || id === "margin") {
1924
+ return "oui-trading-riskRate-container";
1925
+ }
1926
+ if (id === TRADING_PANEL_IDS.ASSETS || id === "assets") {
1927
+ return "oui-trading-assetsView-container oui-border oui-border-line-12";
1928
+ }
1929
+ if (id === TRADING_PANEL_IDS.ORDER_ENTRY || id === "orderEntry") {
1930
+ return "oui-trading-orderEntry-container";
1931
+ }
1932
+ return void 0;
1933
+ }
1952
1934
  var dropAnimationConfig = {
1953
1935
  keyframes({
1954
1936
  transform
@@ -1990,8 +1972,6 @@ function SplitTradingLayout(props) {
1990
1972
  max2XL,
1991
1973
  max4XL,
1992
1974
  horizontalDraggable,
1993
- panelSize,
1994
- setPanelSize,
1995
1975
  marketsWidth,
1996
1976
  mainSplitSize,
1997
1977
  setMainSplitSize,
@@ -2003,17 +1983,34 @@ function SplitTradingLayout(props) {
2003
1983
  setDataListSplitHeightSM,
2004
1984
  orderBookSplitHeightSM,
2005
1985
  setOrderbookSplitHeightSM,
2006
- tradingviewMaxHeight: tradindviewMaxHeight,
1986
+ tradingviewMaxHeight,
2007
1987
  extraHeight,
2008
1988
  setExtraHeight,
2009
- dataListHeight: dataListMinHeight,
2010
- symbolInfoBarHeight
1989
+ dataListHeight: dataListMinHeight
2011
1990
  } = useSplitLayout();
1991
+ const symbolInfoBarChromeRef = useRef(null);
1992
+ const [symbolBarChromeHeight, setSymbolBarChromeHeight] = useState(
1993
+ SYMBOL_INFO_BAR_HEIGHT
1994
+ );
1995
+ useLayoutEffect(() => {
1996
+ const el = symbolInfoBarChromeRef.current;
1997
+ if (!el) return;
1998
+ const sync = () => {
1999
+ const next = el.getBoundingClientRect().height;
2000
+ if (!(Number.isFinite(next) && next > 0)) return;
2001
+ setSymbolBarChromeHeight(
2002
+ (prev) => Math.round(Math.abs(prev - next)) >= 1 ? Math.round(next) : prev
2003
+ );
2004
+ };
2005
+ sync();
2006
+ const observer = new ResizeObserver(sync);
2007
+ observer.observe(el);
2008
+ return () => observer.disconnect();
2009
+ }, []);
2012
2010
  const [tradingViewFullScreen] = useLocalStorage(
2013
2011
  TradingviewFullscreenKey,
2014
2012
  false
2015
2013
  );
2016
- const [animating, setAnimating] = useState(false);
2017
2014
  const [sortableItems, setSortableItems] = useLocalStorage(
2018
2015
  ORDER_ENTRY_SORT_KEY,
2019
2016
  DEFAULT_SORTABLE_ITEMS
@@ -2061,9 +2058,9 @@ function SplitTradingLayout(props) {
2061
2058
  }
2062
2059
  const onMainSplitSizeChange = (width) => layout === "left" ? setMainSplitSize(`${100 - Math.min(Number(width), 100)}`) : setMainSplitSize(width);
2063
2060
  const minScreenHeight = useMemo(() => {
2064
- return tradingViewFullScreen ? 0 : symbolInfoBarHeight + ORDERBOOK_MAX_HEIGHT + DATA_LIST_INITIAL_HEIGHT + SPACE * 4;
2065
- }, [tradingViewFullScreen, symbolInfoBarHeight]);
2066
- const minScreenHeightSM = TOP_BAR_HEIGHT + BOTTOM_BAR_HEIGHT + symbolInfoBarHeight + TRADINGVIEW_MIN_HEIGHT + ORDERBOOK_MIN_HEIGHT + dataListMinHeight + SPACE * 4;
2061
+ return tradingViewFullScreen ? 0 : symbolBarChromeHeight + ORDERBOOK_MAX_HEIGHT + DATA_LIST_INITIAL_HEIGHT + SPACE * 4;
2062
+ }, [tradingViewFullScreen, symbolBarChromeHeight]);
2063
+ const minScreenHeightSM = TOP_BAR_HEIGHT + BOTTOM_BAR_HEIGHT + symbolBarChromeHeight + TRADINGVIEW_MIN_HEIGHT + ORDERBOOK_MIN_HEIGHT + dataListMinHeight + SPACE * 4;
2067
2064
  const containerPaddingX = useMemo(() => max4XL ? 12 : 8, [max4XL]);
2068
2065
  const getPanel = (id) => panels.get(id)?.node ?? null;
2069
2066
  const horizontalMarketsView = getPanel(TRADING_PANEL_IDS.HORIZONTAL_MARKETS);
@@ -2094,22 +2091,10 @@ function SplitTradingLayout(props) {
2094
2091
  width: marketsWidth,
2095
2092
  style: { minWidth: marketsWidth },
2096
2093
  className: "oui-trading-markets-container oui-transition-all oui-duration-150",
2097
- onTransitionEnd: () => setAnimating(false),
2098
- children: !animating && marketLayout === "left" && marketsWidget
2099
- }
2100
- );
2101
- const symbolInfoBarView = /* @__PURE__ */ jsx(
2102
- Box,
2103
- {
2104
- className: "oui-trading-symbolInfoBar-container",
2105
- intensity: 900,
2106
- r: "2xl",
2107
- px: 3,
2108
- width: "100%",
2109
- style: { minHeight: symbolInfoBarHeight, height: symbolInfoBarHeight },
2110
- children: getPanel(TRADING_PANEL_IDS.SYMBOL_INFO_BAR)
2094
+ children: marketLayout === "left" && marketsWidget
2111
2095
  }
2112
2096
  );
2097
+ const symbolInfoBarView = getPanel(TRADING_PANEL_IDS.SYMBOL_INFO_BAR);
2113
2098
  const tradingviewWidget = getPanel(TRADING_PANEL_IDS.TRADING_VIEW);
2114
2099
  const tradingView = /* @__PURE__ */ jsx(
2115
2100
  Box,
@@ -2168,15 +2153,7 @@ function SplitTradingLayout(props) {
2168
2153
  {
2169
2154
  id,
2170
2155
  showIndicator: showPositionIcon,
2171
- className: cn(
2172
- id === TRADING_PANEL_IDS.MARGIN && "oui-trading-riskRate-container",
2173
- id === TRADING_PANEL_IDS.ASSETS && "oui-trading-assetsView-container oui-border oui-border-line-12",
2174
- id === TRADING_PANEL_IDS.ORDER_ENTRY && "oui-trading-orderEntry-container",
2175
- // Support legacy short-name keys
2176
- id === "margin" && "oui-trading-riskRate-container",
2177
- id === "assets" && "oui-trading-assetsView-container oui-border oui-border-line-12",
2178
- id === "orderEntry" && "oui-trading-orderEntry-container"
2179
- ),
2156
+ className: orderEntrySortablePanelClassName(id),
2180
2157
  children: getPanel(id)
2181
2158
  },
2182
2159
  id
@@ -2233,7 +2210,7 @@ function SplitTradingLayout(props) {
2233
2210
  Flex,
2234
2211
  {
2235
2212
  direction: "column",
2236
- className: "oui-flex-1 oui-overflow-hidden",
2213
+ className: "oui-min-h-0 oui-flex-1 oui-overflow-hidden",
2237
2214
  gap: 2,
2238
2215
  style: {
2239
2216
  minWidth: max4XL ? marketsWidth + TRADINGVIEW_MIN_WIDTH + ORDERBOOK_MIN_WIDTH + SPACE * 2 : TRADINGVIEW_MIN_WIDTH + ORDERBOOK_MIN_WIDTH + SPACE
@@ -2244,9 +2221,12 @@ function SplitTradingLayout(props) {
2244
2221
  TradingSplitLayout,
2245
2222
  {
2246
2223
  style: {
2247
- maxHeight: `calc(100% - ${symbolInfoBarHeight}px - ${SPACE}px)`
2224
+ flex: 1,
2225
+ minHeight: 0,
2226
+ width: "100%",
2227
+ overflow: "hidden"
2248
2228
  },
2249
- className: "oui-w-full",
2229
+ className: "oui-flex oui-min-h-0 oui-w-full oui-flex-1 oui-overflow-hidden",
2250
2230
  mode: "vertical",
2251
2231
  onSizeChange: setDataListSplitSize,
2252
2232
  children: [
@@ -2323,17 +2303,17 @@ function SplitTradingLayout(props) {
2323
2303
  ),
2324
2304
  style: {
2325
2305
  minHeight: Math.max(
2326
- symbolInfoBarHeight + TRADINGVIEW_MIN_HEIGHT + ORDERBOOK_MIN_HEIGHT + SPACE * 2,
2306
+ symbolBarChromeHeight + TRADINGVIEW_MIN_HEIGHT + ORDERBOOK_MIN_HEIGHT + SPACE * 2,
2327
2307
  orderEntryHeight
2328
2308
  ),
2329
- maxHeight: symbolInfoBarHeight + tradindviewMaxHeight + ORDERBOOK_MAX_HEIGHT + SPACE * 2
2309
+ maxHeight: symbolBarChromeHeight + tradingviewMaxHeight + ORDERBOOK_MAX_HEIGHT + SPACE * 2
2330
2310
  },
2331
2311
  children: [
2332
2312
  /* @__PURE__ */ jsxs(
2333
2313
  Flex,
2334
2314
  {
2335
2315
  height: "100%",
2336
- className: "oui-w-[calc(100%_-_280px_-_12px)] oui-flex-1",
2316
+ className: "oui-min-h-0 oui-w-[calc(100%_-_280px_-_12px)] oui-flex-1",
2337
2317
  direction: "column",
2338
2318
  gapY: 2,
2339
2319
  children: [
@@ -2342,15 +2322,15 @@ function SplitTradingLayout(props) {
2342
2322
  Flex,
2343
2323
  {
2344
2324
  width: "100%",
2345
- height: "100%",
2346
2325
  gapX: 2,
2347
2326
  itemAlign: "stretch",
2348
2327
  style: {
2328
+ flex: 1,
2349
2329
  minHeight: TRADINGVIEW_MIN_HEIGHT + ORDERBOOK_MIN_HEIGHT + SPACE,
2350
- maxHeight: tradindviewMaxHeight + ORDERBOOK_MAX_HEIGHT + SPACE
2330
+ maxHeight: tradingviewMaxHeight + ORDERBOOK_MAX_HEIGHT + SPACE
2351
2331
  },
2352
2332
  className: cn(
2353
- "oui-flex-1",
2333
+ "oui-min-h-0 oui-flex-1",
2354
2334
  layout === "left" && "oui-flex-row-reverse"
2355
2335
  ),
2356
2336
  children: [
@@ -2363,7 +2343,7 @@ function SplitTradingLayout(props) {
2363
2343
  width: marketsWidth,
2364
2344
  style: {
2365
2345
  minHeight: TRADINGVIEW_MIN_HEIGHT + ORDERBOOK_MIN_HEIGHT + SPACE,
2366
- maxHeight: tradindviewMaxHeight + ORDERBOOK_MAX_HEIGHT + SPACE
2346
+ maxHeight: tradingviewMaxHeight + ORDERBOOK_MAX_HEIGHT + SPACE
2367
2347
  },
2368
2348
  children: marketsWidget
2369
2349
  }
@@ -2386,7 +2366,7 @@ function SplitTradingLayout(props) {
2386
2366
  r: "2xl",
2387
2367
  style: {
2388
2368
  minHeight: TRADINGVIEW_MIN_HEIGHT,
2389
- maxHeight: tradindviewMaxHeight,
2369
+ maxHeight: tradingviewMaxHeight,
2390
2370
  height: 1200
2391
2371
  },
2392
2372
  children: tradingviewWidget
@@ -2809,7 +2789,7 @@ var CollapsiblePanel = ({
2809
2789
  "div",
2810
2790
  {
2811
2791
  className: cn(
2812
- "oui-flex oui-flex-col oui-gap-y-5 oui-overflow-hidden oui-rounded-2xl oui-bg-base-9 oui-w-full oui-h-full",
2792
+ "oui-flex oui-size-full oui-flex-col oui-gap-y-5 oui-overflow-hidden oui-rounded-2xl oui-bg-base-9",
2813
2793
  className
2814
2794
  ),
2815
2795
  style: computedStyle,
@@ -3135,20 +3115,24 @@ function updateSizeAtPath(node, path, newSizes) {
3135
3115
  }
3136
3116
  return updatedNode;
3137
3117
  }
3138
- function getCollapsiblePanels(node) {
3139
- const collapsible = /* @__PURE__ */ new Map();
3140
- const traverse = (n) => {
3141
- if (n.type === "panel" && n.id) {
3142
- collapsible.set(n.id, n.collapsible ?? false);
3118
+ function collectPanelCollapseState(root) {
3119
+ const collapsiblePanels = /* @__PURE__ */ new Map();
3120
+ const collapsedPanels = /* @__PURE__ */ new Set();
3121
+ const traverse = (node) => {
3122
+ if (node.type === "panel" && node.id) {
3123
+ collapsiblePanels.set(node.id, node.collapsible ?? false);
3124
+ if (node.defaultCollapsed) {
3125
+ collapsedPanels.add(node.id);
3126
+ }
3143
3127
  }
3144
- if (n.type === "split" || n.type === "sort") {
3145
- for (const child of n.children ?? []) {
3128
+ if (node.type === "split" || node.type === "sort") {
3129
+ for (const child of node.children ?? []) {
3146
3130
  traverse(child);
3147
3131
  }
3148
3132
  }
3149
3133
  };
3150
- traverse(node);
3151
- return collapsible;
3134
+ traverse(root);
3135
+ return { collapsiblePanels, collapsedPanels };
3152
3136
  }
3153
3137
  function createUpdatedLayout(rootNode, layout, breakpoint, path, sizes) {
3154
3138
  const updatedRoot = updateSizeAtPath(rootNode, path, sizes);
@@ -3201,36 +3185,24 @@ function SplitRenderer(props) {
3201
3185
  },
3202
3186
  [computeUpdatedLayout, onLayoutPersist]
3203
3187
  );
3204
- const collapsiblePanels = useMemo(
3205
- () => getCollapsiblePanels(rootNode),
3188
+ const { collapsiblePanels, collapsedPanels } = useMemo(
3189
+ () => collectPanelCollapseState(rootNode),
3206
3190
  [rootNode]
3207
3191
  );
3208
- const collapsedPanels = useMemo(() => {
3209
- const collapsed = /* @__PURE__ */ new Set();
3210
- const traverse = (node) => {
3211
- if (node.type === "panel" && node.id && node.defaultCollapsed) {
3212
- collapsed.add(node.id);
3213
- }
3214
- if (node.type === "split" || node.type === "sort") {
3215
- node.children?.forEach(traverse);
3216
- }
3217
- };
3218
- traverse(rootNode);
3219
- return collapsed;
3220
- }, [rootNode]);
3221
3192
  const computeUpdatedLayoutForCollapse = useCallback(
3222
3193
  (panelId, collapsed) => {
3223
- const updatedLayouts = {};
3194
+ const layouts = { ...layout.layouts };
3224
3195
  for (const bp of BREAKPOINT_KEYS) {
3225
- if (layout.layouts[bp]) {
3226
- updatedLayouts[bp] = updateDefaultCollapsedAtPath(
3227
- layout.layouts[bp],
3196
+ const nodeAtBreakpoint = layouts[bp];
3197
+ if (nodeAtBreakpoint) {
3198
+ layouts[bp] = updateDefaultCollapsedAtPath(
3199
+ nodeAtBreakpoint,
3228
3200
  panelId,
3229
3201
  collapsed
3230
3202
  );
3231
3203
  }
3232
3204
  }
3233
- return { ...layout, layouts: updatedLayouts };
3205
+ return { ...layout, layouts };
3234
3206
  },
3235
3207
  [layout]
3236
3208
  );
@@ -3285,7 +3257,7 @@ function SplitRenderer(props) {
3285
3257
  /* @__PURE__ */ jsxs(
3286
3258
  "div",
3287
3259
  {
3288
- className: "oui-fixed oui-right-2 oui-bottom-5 oui-text-lg oui-text-trade-loss oui-flex oui-flex-col oui-items-end",
3260
+ className: "oui-fixed oui-bottom-5 oui-right-2 oui-flex oui-flex-col oui-items-end oui-text-lg oui-text-trade-loss",
3289
3261
  style: { zIndex: 1e3 },
3290
3262
  children: [
3291
3263
  /* @__PURE__ */ jsx("span", { children: breakpoint }),
@@ -3294,7 +3266,7 @@ function SplitRenderer(props) {
3294
3266
  "button",
3295
3267
  {
3296
3268
  onClick: () => ctx?.reset(),
3297
- className: "oui-mt-1 oui-px-2 oui-py-1 oui-text-sm oui-bg-gray-500 oui-text-white oui-rounded",
3269
+ className: "oui-mt-1 oui-rounded oui-bg-gray-500 oui-px-2 oui-py-1 oui-text-sm oui-text-white",
3298
3270
  children: "Reset"
3299
3271
  }
3300
3272
  )