@deepseek-ai/dsh-client-ui-dockkit 0.1.6-alpha.2 → 0.1.7-alpha.2

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.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { Children, Fragment as Fragment$1, useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
3
3
  import clsx from "clsx";
4
- import { IconCloseFill14, IconCloseOutline16, IconPanelLeftOutline16, IconPlusOutline16, Tooltip } from "@deepseek-ai/dsh-client-ui-primitives";
4
+ import { IconCloseFillRegular, IconCloseOutlineRegular, IconPanelLeftOutlineRegular, IconPlusOutlineRegular, Tooltip } from "@deepseek-ai/dsh-client-ui-primitives";
5
5
  import { createPortal } from "react-dom";
6
6
  import css from "./components/dockkit.module.css";
7
7
  //#region lib/types/engine/tree.js
@@ -2163,6 +2163,10 @@ function followPointer(element, pointerId, followers) {
2163
2163
  capturePointer(element, pointerId);
2164
2164
  const controller = new AbortController();
2165
2165
  const { signal } = controller;
2166
+ element.dataset.dockkitPointer = String(pointerId);
2167
+ signal.addEventListener("abort", () => {
2168
+ if (element.dataset.dockkitPointer === String(pointerId)) delete element.dataset.dockkitPointer;
2169
+ }, { once: true });
2166
2170
  const own = (event) => event.pointerId === pointerId;
2167
2171
  window.addEventListener("pointermove", (event) => {
2168
2172
  if (own(event)) followers.move(event);
@@ -2368,20 +2372,21 @@ function TabTitle({ children }) {
2368
2372
  * inside it so they read as siblings of the panel controls beside them.
2369
2373
  */
2370
2374
  const PANEL_FRAME = "M9.67272 0.522841C10.8339 0.522841 11.76 0.522714 12.4963 0.602493C13.2453 0.683657 13.8789 0.854248 14.4264 1.25197C14.7504 1.48739 15.0355 1.77247 15.2709 2.0965C15.6686 2.64394 15.8392 3.27758 15.9204 4.02655C16.0002 4.7629 16 5.68895 16 6.85014V9.14986C16 10.3111 16.0002 11.2371 15.9204 11.9735C15.8392 12.7224 15.6686 13.3561 15.2709 13.9035C15.0355 14.2275 14.7504 14.5126 14.4264 14.748C13.8789 15.1458 13.2453 15.3163 12.4963 15.3975C11.76 15.4773 10.8339 15.4772 9.67272 15.4772H6.3273C5.16611 15.4772 4.24006 15.4773 3.50371 15.3975C2.75474 15.3163 2.1211 15.1458 1.57366 14.748C1.24963 14.5126 0.964549 14.2275 0.729131 13.9035C0.331407 13.3561 0.160817 12.7224 0.0796529 11.9735C-0.000126137 11.2371 1.25338e-09 10.3111 1.25338e-09 9.14986V6.85014C1.25329e-09 5.68895 -0.000126137 4.7629 0.0796529 4.02655C0.160817 3.27758 0.331407 2.64394 0.729131 2.0965C0.964549 1.77247 1.24963 1.48739 1.57366 1.25197C2.1211 0.854248 2.75474 0.683657 3.50371 0.602493C4.24006 0.522714 5.16611 0.522841 6.3273 0.522841H9.67272ZM4.1828 14.0873L5.54303 14.1118C5.78636 14.1128 6.04709 14.1169 6.3273 14.1169H9.67272C10.8639 14.1169 11.7032 14.1164 12.3493 14.0465C12.9824 13.9779 13.3497 13.8494 13.6268 13.6482C13.8354 13.4966 14.0195 13.3125 14.1711 13.1039C14.3723 12.8268 14.5007 12.4595 14.5693 11.8264C14.6393 11.1803 14.6398 10.341 14.6398 9.14986V6.85014C14.6398 5.65896 14.6393 4.81967 14.5693 4.1736C14.5007 3.54048 14.3723 3.17318 14.1711 2.89609C14.0195 2.68747 13.8354 2.50337 13.6268 2.35179C13.3497 2.1506 12.9824 2.02212 12.3493 1.95353C11.7032 1.88358 10.8639 1.88307 9.67272 1.88307H6.3273C6.04709 1.88307 5.78636 1.8862 5.54303 1.88715L4.1828 1.91166C3.99125 1.9216 3.8148 1.93577 3.65076 1.95353C3.01764 2.02212 2.65034 2.1506 2.37325 2.35179C2.16463 2.50337 1.98052 2.68747 1.82895 2.89609C1.62776 3.17318 1.49928 3.54048 1.43069 4.1736C1.36074 4.81967 1.36023 5.65896 1.36023 6.85014V9.14986C1.36023 10.341 1.36074 11.1803 1.43069 11.8264C1.49928 12.4595 1.62776 12.8268 1.82895 13.1039C1.98052 13.3125 2.16463 13.4966 2.37325 13.6482C2.65034 13.8494 3.01764 13.9779 3.65076 14.0465C3.81478 14.0642 3.99127 14.0774 4.1828 14.0873Z";
2371
- /** The split control's glyph: the panel frame with its divider moved to the centre. */
2375
+ /** The split control's glyph from the shared product artwork. */
2372
2376
  function SplitGlyph() {
2373
- return jsx("svg", {
2377
+ return jsxs("svg", {
2374
2378
  width: "16",
2375
2379
  height: "16",
2376
2380
  viewBox: "0 0 16 16",
2377
2381
  fill: "none",
2378
2382
  "aria-hidden": "true",
2379
- children: jsx("path", {
2380
- fillRule: "evenodd",
2381
- clipRule: "evenodd",
2382
- d: `${PANEL_FRAME}M7.31989 1.88307H8.68012V14.1169H7.31989V1.88307Z`,
2383
- fill: "currentColor"
2384
- })
2383
+ children: [jsx("path", {
2384
+ d: "M13.5 1.5H2.5C1.94772 1.5 1.5 1.94772 1.5 2.5V13.5C1.5 14.0523 1.94772 14.5 2.5 14.5H13.5C14.0523 14.5 14.5 14.0523 14.5 13.5V2.5C14.5 1.94772 14.0523 1.5 13.5 1.5Z",
2385
+ stroke: "currentColor"
2386
+ }), jsx("path", {
2387
+ d: "M8 1.5V14.5",
2388
+ stroke: "currentColor"
2389
+ })]
2385
2390
  });
2386
2391
  }
2387
2392
  /**
@@ -2535,18 +2540,16 @@ function splitBlockedTitle(labels, block) {
2535
2540
  case "width": return labels.splitPaneNarrow;
2536
2541
  }
2537
2542
  }
2538
- /** The pane's tab strip, split control, and body. */
2539
- function TabPanel({ state, pane, callbacks }) {
2543
+ /** @param props - pane state and gestures. @returns its tab strip without a content container. */
2544
+ function TabStrip({ state, pane, callbacks }) {
2540
2545
  const [menu, setMenu] = useState(void 0);
2541
2546
  const [chips] = useState(() => /* @__PURE__ */ new Map());
2542
2547
  const stripTabs = useRef(null);
2543
2548
  useStripScrollFades(stripTabs, pane.tabs);
2544
2549
  useActiveChipInView(stripTabs, chips, pane.tabs, pane.activeTabId);
2545
- const active = pane.activeTabId === void 0 ? void 0 : getTab(state, pane.activeTabId);
2546
2550
  const block = callbacks.splitBlock(pane.id);
2547
2551
  const target = callbacks.dropTarget;
2548
2552
  const stripIndex = target !== void 0 && target.kind === "strip" && target.paneId === pane.id ? target.index : void 0;
2549
- const zone = target !== void 0 && target.kind === "zone" && target.paneId === pane.id ? target.zone : void 0;
2550
2553
  /** Select a tab from a click or a key, unless it is the active pane's selected tab already: that changes nothing. */
2551
2554
  const activate = (tabId) => {
2552
2555
  if (state.activePaneId === pane.id && pane.activeTabId === tabId) return;
@@ -2558,179 +2561,197 @@ function TabPanel({ state, pane, callbacks }) {
2558
2561
  if (chip === void 0) return;
2559
2562
  chip.focus();
2560
2563
  };
2561
- return jsxs("section", {
2562
- className: css.pane,
2563
- "data-dockkit-pane": pane.id,
2564
- "data-dockkit-pane-active": state.activePaneId === pane.id || void 0,
2565
- onClick: () => {
2566
- if (state.activePaneId === pane.id) return;
2567
- callbacks.onFocusPane(pane.id);
2568
- },
2569
- children: [jsxs("div", {
2570
- className: css.tabStrip,
2571
- role: "tablist",
2572
- "data-dockkit-strip": pane.id,
2573
- children: [
2574
- jsxs("div", {
2575
- ref: stripTabs,
2576
- className: css.stripTabs,
2577
- role: "presentation",
2578
- "data-dockkit-strip-tabs": pane.id,
2579
- children: [pane.tabs.map((tabId, index) => {
2580
- const tab = getTab(state, tabId);
2581
- const selected = tabId === pane.activeTabId;
2582
- const closable = callbacks.canCloseTab(tabId);
2583
- const quiet = !closable && pane.tabs.length === 1;
2584
- return jsxs(Fragment$1, { children: [(index > 0 || stripIndex === index) && jsx("div", {
2585
- className: clsx(css.slot, stripIndex === index && css.slotCaret),
2586
- "data-dockkit-caret": stripIndex === index ? index : void 0
2587
- }), jsxs("div", {
2588
- role: "tab",
2589
- "aria-selected": selected,
2590
- tabIndex: selected ? 0 : -1,
2591
- className: clsx(css.tab, selected && css.tabActive, quiet && css.tabQuiet, callbacks.draggingTabId === tabId && css.tabDragging),
2592
- "data-dockkit-tab": tabId,
2593
- "data-dockkit-tab-quiet": quiet || void 0,
2594
- ref: (element) => {
2595
- if (element === null) chips.delete(tabId);
2596
- else chips.set(tabId, element);
2597
- },
2598
- onPointerDown: (event) => {
2599
- if (event.button === 2) return;
2600
- callbacks.onTabPressed(tabId, event);
2601
- },
2602
- onClick: (event) => {
2603
- event.stopPropagation();
2604
- activate(tabId);
2605
- },
2606
- onKeyDown: (event) => {
2607
- if (event.target !== event.currentTarget) return;
2608
- const next = chipToFocus(event.key, pane.tabs, tabId);
2609
- if (next !== void 0) {
2610
- event.preventDefault();
2611
- focusChip(next);
2612
- return;
2613
- }
2614
- if (selects(event.key)) {
2615
- event.preventDefault();
2616
- activate(tabId);
2617
- }
2618
- },
2619
- onContextMenu: (event) => {
2620
- event.preventDefault();
2621
- const anchor = event.currentTarget;
2622
- setMenu((current) => current?.tabId === tabId ? void 0 : {
2623
- tabId,
2624
- anchor
2625
- });
2626
- },
2627
- children: [
2628
- jsx(TabTitle, { children: callbacks.renderTabTitle?.(tab) ?? tab.title }),
2629
- closable && jsx("button", {
2630
- type: "button",
2631
- className: css.tabClose,
2632
- "aria-label": callbacks.labels.closeTab,
2633
- "data-dockkit-tab-close": tabId,
2634
- onPointerDown: (event) => {
2635
- event.stopPropagation();
2636
- },
2637
- onClick: (event) => {
2638
- event.stopPropagation();
2639
- callbacks.onCloseTab(tabId);
2640
- },
2641
- children: jsx(IconCloseFill14, { size: 14 })
2642
- }),
2643
- menu?.tabId === tabId && jsx(TabMenu, {
2644
- labels: callbacks.labels,
2645
- anchor: menu.anchor,
2646
- onClose: closable ? () => {
2647
- setMenu(void 0);
2648
- callbacks.onCloseTab(tabId);
2649
- } : void 0,
2650
- onDismiss: () => {
2651
- setMenu(void 0);
2652
- },
2653
- extras: callbacks.renderTabMenuItems?.(tab, () => {
2654
- setMenu(void 0);
2655
- })
2656
- })
2657
- ]
2658
- })] }, tabId);
2659
- }), stripIndex === pane.tabs.length && jsx("div", {
2660
- className: clsx(css.slot, css.slotCaret),
2661
- "data-dockkit-caret": stripIndex
2662
- })]
2663
- }),
2664
- callbacks.canAddTab(pane.id) && jsx(Tooltip, {
2665
- label: callbacks.labels.addTab,
2666
- side: "bottom",
2667
- delayMs: 500,
2668
- children: jsx("button", {
2669
- type: "button",
2670
- className: css.addTab,
2671
- "aria-label": callbacks.labels.addTab,
2672
- "data-dockkit-add-tab": pane.id,
2673
- onClick: (event) => {
2674
- event.stopPropagation();
2675
- callbacks.onAddTab(pane.id);
2564
+ return jsxs("div", {
2565
+ className: css.tabStrip,
2566
+ role: "tablist",
2567
+ "data-dockkit-strip": pane.id,
2568
+ children: [
2569
+ jsxs("div", {
2570
+ ref: stripTabs,
2571
+ className: css.stripTabs,
2572
+ role: "presentation",
2573
+ "data-dockkit-strip-tabs": pane.id,
2574
+ children: [pane.tabs.map((tabId, index) => {
2575
+ const tab = getTab(state, tabId);
2576
+ const selected = tabId === pane.activeTabId;
2577
+ const closable = callbacks.canCloseTab(tabId);
2578
+ const quiet = !closable && pane.tabs.length === 1;
2579
+ return jsxs(Fragment$1, { children: [(index > 0 || stripIndex === index) && jsx("div", {
2580
+ className: clsx(css.slot, stripIndex === index && css.slotCaret),
2581
+ "data-dockkit-caret": stripIndex === index ? index : void 0
2582
+ }), jsxs("div", {
2583
+ role: "tab",
2584
+ "aria-selected": selected,
2585
+ tabIndex: selected ? 0 : -1,
2586
+ className: clsx(css.tab, selected && css.tabActive, quiet && css.tabQuiet, callbacks.draggingTabId === tabId && css.tabDragging),
2587
+ "data-dockkit-tab": tabId,
2588
+ "data-dockkit-tab-quiet": quiet || void 0,
2589
+ ref: (element) => {
2590
+ if (element === null) chips.delete(tabId);
2591
+ else chips.set(tabId, element);
2592
+ },
2593
+ onPointerDown: (event) => {
2594
+ if (event.button === 2) return;
2595
+ callbacks.onTabPressed(tabId, event);
2676
2596
  },
2677
- children: jsx(IconPlusOutline16, { size: 14 })
2678
- })
2679
- }),
2680
- jsx("div", {
2681
- className: css.stripFill,
2682
- "data-dockkit-strip-fill": true
2683
- }),
2684
- !(callbacks.hideSplitWhenBlocked && block !== void 0) && jsx(Tooltip, {
2685
- label: callbacks.labels.splitPane,
2686
- side: "bottom",
2687
- delayMs: 500,
2688
- disabled: block !== void 0,
2689
- children: jsx("button", {
2690
- type: "button",
2691
- className: css.iconButton,
2692
- "aria-label": callbacks.labels.splitPane,
2693
- title: block === void 0 ? void 0 : splitBlockedTitle(callbacks.labels, block),
2694
- disabled: block !== void 0,
2695
- "data-dockkit-split-button": pane.id,
2696
- "data-dockkit-split-blocked": block,
2697
2597
  onClick: (event) => {
2698
2598
  event.stopPropagation();
2699
- callbacks.onSplitPane(pane.id);
2599
+ activate(tabId);
2700
2600
  },
2701
- children: jsx(SplitGlyph, {})
2702
- })
2703
- }),
2704
- pane.id === callbacks.chromePaneId && callbacks.chrome !== void 0 && jsx("div", {
2705
- className: css.stripChrome,
2706
- "data-dockkit-strip-chrome": true,
2601
+ onKeyDown: (event) => {
2602
+ if (event.target !== event.currentTarget) return;
2603
+ const next = chipToFocus(event.key, pane.tabs, tabId);
2604
+ if (next !== void 0) {
2605
+ event.preventDefault();
2606
+ focusChip(next);
2607
+ return;
2608
+ }
2609
+ if (selects(event.key)) {
2610
+ event.preventDefault();
2611
+ activate(tabId);
2612
+ }
2613
+ },
2614
+ onContextMenu: (event) => {
2615
+ event.preventDefault();
2616
+ const anchor = event.currentTarget;
2617
+ setMenu((current) => current?.tabId === tabId ? void 0 : {
2618
+ tabId,
2619
+ anchor
2620
+ });
2621
+ },
2622
+ children: [
2623
+ jsx(TabTitle, { children: callbacks.renderTabTitle?.(tab) ?? tab.title }),
2624
+ closable && jsx("button", {
2625
+ type: "button",
2626
+ className: css.tabClose,
2627
+ "aria-label": callbacks.labels.closeTab,
2628
+ "data-dockkit-tab-close": tabId,
2629
+ onPointerDown: (event) => {
2630
+ event.stopPropagation();
2631
+ },
2632
+ onClick: (event) => {
2633
+ event.stopPropagation();
2634
+ callbacks.onCloseTab(tabId);
2635
+ },
2636
+ children: jsx(IconCloseFillRegular, { size: 14 })
2637
+ }),
2638
+ menu?.tabId === tabId && jsx(TabMenu, {
2639
+ labels: callbacks.labels,
2640
+ anchor: menu.anchor,
2641
+ onClose: closable ? () => {
2642
+ setMenu(void 0);
2643
+ callbacks.onCloseTab(tabId);
2644
+ } : void 0,
2645
+ onDismiss: () => {
2646
+ setMenu(void 0);
2647
+ },
2648
+ extras: callbacks.renderTabMenuItems?.(tab, () => {
2649
+ setMenu(void 0);
2650
+ })
2651
+ })
2652
+ ]
2653
+ })] }, tabId);
2654
+ }), stripIndex === pane.tabs.length && jsx("div", {
2655
+ className: clsx(css.slot, css.slotCaret),
2656
+ "data-dockkit-caret": stripIndex
2657
+ })]
2658
+ }),
2659
+ callbacks.canAddTab(pane.id) && jsx(Tooltip, {
2660
+ label: callbacks.labels.addTab,
2661
+ side: "bottom",
2662
+ delayMs: 500,
2663
+ children: jsx("button", {
2664
+ type: "button",
2665
+ className: css.addTab,
2666
+ "aria-label": callbacks.labels.addTab,
2667
+ "data-dockkit-add-tab": pane.id,
2707
2668
  onClick: (event) => {
2708
2669
  event.stopPropagation();
2670
+ callbacks.onAddTab(pane.id);
2709
2671
  },
2710
- children: callbacks.chrome
2672
+ children: jsx(IconPlusOutlineRegular, { size: 14 })
2711
2673
  })
2712
- ]
2674
+ }),
2675
+ jsx("div", {
2676
+ className: css.stripFill,
2677
+ "data-dockkit-strip-fill": true
2678
+ }),
2679
+ !(callbacks.hideSplitWhenBlocked && block !== void 0) && jsx(Tooltip, {
2680
+ label: callbacks.labels.splitPane,
2681
+ side: "bottom",
2682
+ delayMs: 500,
2683
+ disabled: block !== void 0,
2684
+ children: jsx("button", {
2685
+ type: "button",
2686
+ className: css.iconButton,
2687
+ "aria-label": callbacks.labels.splitPane,
2688
+ title: block === void 0 ? void 0 : splitBlockedTitle(callbacks.labels, block),
2689
+ disabled: block !== void 0,
2690
+ "data-dockkit-split-button": pane.id,
2691
+ "data-dockkit-split-blocked": block,
2692
+ onClick: (event) => {
2693
+ event.stopPropagation();
2694
+ callbacks.onSplitPane(pane.id);
2695
+ },
2696
+ children: jsx(SplitGlyph, {})
2697
+ })
2698
+ }),
2699
+ pane.id === callbacks.chromePaneId && callbacks.chrome !== void 0 && jsx("div", {
2700
+ className: css.stripChrome,
2701
+ "data-dockkit-strip-chrome": true,
2702
+ onClick: (event) => {
2703
+ event.stopPropagation();
2704
+ },
2705
+ children: callbacks.chrome
2706
+ })
2707
+ ]
2708
+ });
2709
+ }
2710
+ /** @param props - target pane and drag preview. @returns body-local drop feedback, or nothing. */
2711
+ function PaneDropHints({ pane, callbacks }) {
2712
+ const target = callbacks.dropTarget;
2713
+ const zone = target?.kind === "zone" && target.paneId === pane.id ? target.zone : void 0;
2714
+ if (zone === void 0) return null;
2715
+ return jsxs(Fragment, { children: [jsx("div", {
2716
+ className: css.dockScrim,
2717
+ "data-dockkit-dock-scrim": true
2718
+ }), callbacks.horizontalDrops && zone !== "center" ? jsxs(Fragment, { children: [jsx(DockHint, {
2719
+ zone: "left",
2720
+ active: zone === "left",
2721
+ labels: callbacks.labels
2722
+ }), jsx(DockHint, {
2723
+ zone: "right",
2724
+ active: zone === "right",
2725
+ labels: callbacks.labels
2726
+ })] }) : jsx(DockHint, {
2727
+ zone,
2728
+ active: true,
2729
+ labels: callbacks.labels
2730
+ })] });
2731
+ }
2732
+ /** @param props - pane state and gestures. @returns one pane in the recursive, visibility-mounted layout. */
2733
+ function TabPanel({ state, pane, callbacks }) {
2734
+ const active = pane.activeTabId === void 0 ? void 0 : getTab(state, pane.activeTabId);
2735
+ return jsxs("section", {
2736
+ className: css.pane,
2737
+ "data-dockkit-pane": pane.id,
2738
+ "data-dockkit-pane-active": state.activePaneId === pane.id || void 0,
2739
+ onClick: () => {
2740
+ if (state.activePaneId !== pane.id) callbacks.onFocusPane(pane.id);
2741
+ },
2742
+ children: [jsx(TabStrip, {
2743
+ state,
2744
+ pane,
2745
+ callbacks
2713
2746
  }), jsxs("div", {
2714
2747
  className: css.paneBody,
2715
2748
  children: [active === void 0 ? jsx("p", {
2716
2749
  className: css.empty,
2717
2750
  children: callbacks.labels.emptyPane
2718
- }) : callbacks.renderTab(active), zone !== void 0 && jsxs(Fragment, { children: [jsx("div", {
2719
- className: css.dockScrim,
2720
- "data-dockkit-dock-scrim": true
2721
- }), callbacks.horizontalDrops && zone !== "center" ? jsxs(Fragment, { children: [jsx(DockHint, {
2722
- zone: "left",
2723
- active: zone === "left",
2724
- labels: callbacks.labels
2725
- }), jsx(DockHint, {
2726
- zone: "right",
2727
- active: zone === "right",
2728
- labels: callbacks.labels
2729
- })] }) : jsx(DockHint, {
2730
- zone,
2731
- active: true,
2732
- labels: callbacks.labels
2733
- })] })]
2751
+ }) : callbacks.renderTab(active), jsx(PaneDropHints, {
2752
+ pane,
2753
+ callbacks
2754
+ })]
2734
2755
  })]
2735
2756
  });
2736
2757
  }
@@ -2774,6 +2795,375 @@ function PaneTree({ state, nodeId, callbacks, preview }) {
2774
2795
  });
2775
2796
  }
2776
2797
  //#endregion
2798
+ //#region lib/types/components/FloatLayer.js
2799
+ /**
2800
+ * The floating layer: one overlay panel per floating pane, bottom-to-top in the
2801
+ * model's z order. A floating pane hosts exactly one tab; its header is the
2802
+ * strip's row holding that tab's chip, never selectable or closable from the
2803
+ * chip, and the send-back and close controls. Pressing a panel's body raises it. Its grip
2804
+ * and corner report through their gesture instead: a press released in place is
2805
+ * a click and raises the panel; a drag records the move or resize, and that
2806
+ * operation raises the panel itself, so one gesture is one intent. Raising a
2807
+ * panel that is active and on top already changes nothing and reports nothing.
2808
+ *
2809
+ * The layer owns its own drag and resize gestures, so where it mounts is not
2810
+ * part of its contract: panels are positioned in viewport coordinates and read
2811
+ * only `state` and the outward contracts. An embedder may portal it anywhere,
2812
+ * and nothing here assumes the docked tree is an ancestor or even present.
2813
+ */
2814
+ /** The rectangle a gesture has reached. */
2815
+ function draggedRect(drag, x, y) {
2816
+ const dx = x - drag.originX;
2817
+ const dy = y - drag.originY;
2818
+ return drag.mode === "move" ? movedRect(drag.rect, dx, dy) : resizedRect(drag.rect, dx, dy, FLOAT_MIN_SIZE);
2819
+ }
2820
+ /** Whether two rectangles agree in every coordinate. */
2821
+ function sameRect(a, b) {
2822
+ return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
2823
+ }
2824
+ /** Whether a floating pane is already where a raise would put it: focused and on top. */
2825
+ function raised(state, paneId) {
2826
+ return state.activePaneId === paneId && state.floats.at(-1) === paneId;
2827
+ }
2828
+ /**
2829
+ * Shared move/resize gestures; changing layout mode never owns the content DOM.
2830
+ * @param state - committed layout and float stacking order.
2831
+ * @param intents - gesture settlements.
2832
+ * @returns the current preview and focus/gesture callbacks.
2833
+ */
2834
+ function useFloatGestures(state, intents) {
2835
+ const [preview, setPreview] = useState(void 0);
2836
+ const begin = useGesture(() => {
2837
+ setPreview(void 0);
2838
+ });
2839
+ /** Focus and raise a panel from a press or click on it, unless it is raised already. */
2840
+ const raise = (paneId) => {
2841
+ if (raised(state, paneId)) return;
2842
+ intents.focusPane(paneId);
2843
+ };
2844
+ /** Start a move or resize from a press on the panel's grip or corner; a release that moved nothing is a click. */
2845
+ const drag = (mode, paneId, event) => {
2846
+ event.stopPropagation();
2847
+ const start = {
2848
+ mode,
2849
+ originX: event.clientX,
2850
+ originY: event.clientY,
2851
+ rect: floatRect(getPane(state, paneId))
2852
+ };
2853
+ begin(event.currentTarget, event.pointerId, {
2854
+ move: (moved) => {
2855
+ setPreview({
2856
+ paneId,
2857
+ rect: draggedRect(start, moved.clientX, moved.clientY)
2858
+ });
2859
+ },
2860
+ up: (released) => {
2861
+ const rect = draggedRect(start, released.clientX, released.clientY);
2862
+ if (sameRect(rect, start.rect)) raise(paneId);
2863
+ else if (mode === "move") intents.moveFloat(paneId, rect.x, rect.y);
2864
+ else intents.resizeFloat(paneId, rect);
2865
+ }
2866
+ });
2867
+ };
2868
+ return {
2869
+ preview,
2870
+ raise,
2871
+ drag
2872
+ };
2873
+ }
2874
+ /**
2875
+ * Header-only controls, usable above either retained or visibility-mounted bodies.
2876
+ * @param props - owning pane/tab, localized labels and gesture callbacks.
2877
+ * @returns the float header without a content container.
2878
+ */
2879
+ function FloatHeader({ paneId, tab, labels, intents, renderTabTitle, canCloseTab, drag }) {
2880
+ return jsxs("header", {
2881
+ className: clsx(css.tabStrip, css.floatHeader),
2882
+ "data-dockkit-float-grip": paneId,
2883
+ onPointerDown: (event) => {
2884
+ drag("move", paneId, event);
2885
+ },
2886
+ children: [
2887
+ jsx("div", {
2888
+ className: clsx(css.tab, css.floatTitle),
2889
+ "data-dockkit-float-title": true,
2890
+ children: jsx(TabTitle, { children: renderTabTitle?.(tab) ?? tab.title })
2891
+ }),
2892
+ jsx("div", { className: css.stripFill }),
2893
+ jsx(Tooltip, {
2894
+ label: labels.dockFloat,
2895
+ side: "bottom",
2896
+ delayMs: 500,
2897
+ children: jsx("button", {
2898
+ type: "button",
2899
+ className: css.iconButton,
2900
+ "aria-label": labels.dockFloat,
2901
+ "data-dockkit-float-dock": paneId,
2902
+ onPointerDown: (event) => {
2903
+ event.stopPropagation();
2904
+ },
2905
+ onClick: () => {
2906
+ intents.unfloatPane(paneId);
2907
+ },
2908
+ children: jsx(IconPanelLeftOutlineRegular, { className: css.dockGlyph })
2909
+ })
2910
+ }),
2911
+ (canCloseTab?.(tab.id) ?? true) && jsx(Tooltip, {
2912
+ label: labels.closeFloat,
2913
+ side: "bottom",
2914
+ delayMs: 500,
2915
+ children: jsx("button", {
2916
+ type: "button",
2917
+ className: css.iconButton,
2918
+ "aria-label": labels.closeFloat,
2919
+ "data-dockkit-float-close": paneId,
2920
+ onPointerDown: (event) => {
2921
+ event.stopPropagation();
2922
+ },
2923
+ onClick: () => {
2924
+ intents.closeTab(tab.id);
2925
+ },
2926
+ children: jsx(IconCloseOutlineRegular, {})
2927
+ })
2928
+ })
2929
+ ]
2930
+ });
2931
+ }
2932
+ /** Every floating panel, in z order. */
2933
+ function FloatLayer({ state, intents, labels, renderTab, renderTabTitle, canCloseTab }) {
2934
+ const { preview, raise, drag } = useFloatGestures(state, intents);
2935
+ return jsx(Fragment, { children: state.floats.map((paneId, depth) => {
2936
+ const pane = getPane(state, paneId);
2937
+ const tab = getTab(state, onlyTabId(pane));
2938
+ const lifted = preview?.paneId === paneId ? preview.rect : void 0;
2939
+ const live = lifted ?? floatRect(pane);
2940
+ return jsxs("div", {
2941
+ className: css.float,
2942
+ "data-dockkit-float": paneId,
2943
+ "data-dockkit-float-active": state.activePaneId === paneId || void 0,
2944
+ style: {
2945
+ left: live.x,
2946
+ top: live.y,
2947
+ width: live.width,
2948
+ height: live.height,
2949
+ zIndex: lifted === void 0 ? depth + 1 : state.floats.length + 1
2950
+ },
2951
+ onPointerDown: () => {
2952
+ raise(paneId);
2953
+ },
2954
+ children: [
2955
+ jsx(FloatHeader, {
2956
+ paneId,
2957
+ tab,
2958
+ labels,
2959
+ intents,
2960
+ renderTabTitle,
2961
+ canCloseTab,
2962
+ drag
2963
+ }),
2964
+ jsx("div", {
2965
+ className: css.floatBody,
2966
+ children: renderTab(tab)
2967
+ }),
2968
+ jsx("div", {
2969
+ className: css.floatResize,
2970
+ "data-dockkit-float-resize": paneId,
2971
+ onPointerDown: (event) => {
2972
+ drag("resize", paneId, event);
2973
+ }
2974
+ })
2975
+ ]
2976
+ }, paneId);
2977
+ }) });
2978
+ }
2979
+ //#endregion
2980
+ //#region lib/types/components/TabLayout.js
2981
+ /** Stable tab siblings in one horizontal Grid, including viewport-positioned floats. */
2982
+ /** A tab's ancestors stay identical across selection, pane moves and floating. */
2983
+ function TabHost({ state, callbacks, intents, tab, pane, column, floats, focusRequest, keepMounted, active = true }) {
2984
+ const floating = pane.host === "float";
2985
+ const selected = floating || pane.activeTabId === tab.id;
2986
+ const visible = active && selected && (floating || state.expanded);
2987
+ const retained = keepMounted?.(tab) ?? false;
2988
+ const [visited, setVisited] = useState(visible);
2989
+ if (visible && !visited) setVisited(true);
2990
+ const host = useRef(null);
2991
+ const body = useRef(null);
2992
+ useLayoutEffect(() => {
2993
+ const section = host.current;
2994
+ section.inert = !visible;
2995
+ const focused = document.activeElement;
2996
+ if (!visible && focused instanceof HTMLElement && section.contains(focused)) focused.blur();
2997
+ const request = focusRequest.current;
2998
+ if (!visible || request?.tabId !== tab.id) return;
2999
+ focusRequest.current = void 0;
3000
+ if (focused !== null && focused !== document.body && focused !== document.documentElement && focused !== request.origin) return;
3001
+ [...section.querySelector("[data-dockkit-strip]")?.querySelectorAll("[data-dockkit-tab]") ?? []].find((element) => element.dataset.dockkitTab === tab.id)?.focus({ preventScroll: true });
3002
+ }, [
3003
+ visible,
3004
+ tab.id,
3005
+ focusRequest
3006
+ ]);
3007
+ useEffect(() => {
3008
+ const element = body.current;
3009
+ const focus = () => {
3010
+ if (!visible) return;
3011
+ if (floating) floats.raise(pane.id);
3012
+ else if (state.activePaneId !== pane.id) callbacks.onFocusPane(pane.id);
3013
+ };
3014
+ element.addEventListener("focus", focus, true);
3015
+ return () => {
3016
+ element.removeEventListener("focus", focus, true);
3017
+ };
3018
+ }, [
3019
+ visible,
3020
+ floating,
3021
+ floats,
3022
+ pane.id,
3023
+ state.activePaneId,
3024
+ callbacks
3025
+ ]);
3026
+ const lifted = floating && floats.preview?.paneId === pane.id ? floats.preview.rect : void 0;
3027
+ const rect = floating ? lifted ?? floatRect(pane) : void 0;
3028
+ const depth = lifted === void 0 ? state.floats.indexOf(pane.id) + 1 : state.floats.length + 1;
3029
+ return jsx("div", {
3030
+ className: clsx(css.tabCell, floating && css.floatingCell),
3031
+ hidden: !selected,
3032
+ "data-dockkit-host": floating ? "float" : "dock",
3033
+ "data-dockkit-column": floating ? void 0 : column,
3034
+ style: {
3035
+ gridColumn: floating ? 1 : column * 2 + 1,
3036
+ gridRow: 1,
3037
+ order: floating ? depth : 0
3038
+ },
3039
+ children: jsxs("section", {
3040
+ ref: host,
3041
+ className: clsx(css.tabHost, floating ? css.float : css.pane),
3042
+ "aria-hidden": !visible || void 0,
3043
+ "data-dockkit-content": tab.id,
3044
+ "data-dockkit-pane": !floating && selected ? pane.id : void 0,
3045
+ "data-dockkit-pane-active": !floating && state.activePaneId === pane.id || void 0,
3046
+ "data-dockkit-float": floating ? pane.id : void 0,
3047
+ "data-dockkit-float-active": floating && state.activePaneId === pane.id || void 0,
3048
+ "data-dockkit-column": !floating ? column : void 0,
3049
+ style: rect === void 0 ? void 0 : {
3050
+ left: rect.x,
3051
+ top: rect.y,
3052
+ width: rect.width,
3053
+ height: rect.height
3054
+ },
3055
+ onPointerDown: () => {
3056
+ if (floating) floats.raise(pane.id);
3057
+ },
3058
+ onClick: () => {
3059
+ if (!floating && state.activePaneId !== pane.id) callbacks.onFocusPane(pane.id);
3060
+ },
3061
+ children: [
3062
+ jsx("div", {
3063
+ className: css.tabHostHeader,
3064
+ children: selected && (floating ? jsx(FloatHeader, {
3065
+ paneId: pane.id,
3066
+ tab,
3067
+ labels: callbacks.labels,
3068
+ intents,
3069
+ renderTabTitle: callbacks.renderTabTitle,
3070
+ canCloseTab: callbacks.canCloseTab,
3071
+ drag: floats.drag
3072
+ }) : jsx(TabStrip, {
3073
+ state,
3074
+ pane,
3075
+ callbacks
3076
+ }))
3077
+ }),
3078
+ jsxs("div", {
3079
+ ref: body,
3080
+ className: clsx(css.tabHostBody, floating ? css.floatBody : css.paneBody),
3081
+ children: [visited && (retained || active && selected) ? callbacks.renderTab(tab) : null, !floating && jsx(PaneDropHints, {
3082
+ pane,
3083
+ callbacks
3084
+ })]
3085
+ }),
3086
+ floating && jsx("div", {
3087
+ className: css.floatResize,
3088
+ "data-dockkit-float-resize": pane.id,
3089
+ onPointerDown: (event) => {
3090
+ floats.drag("resize", pane.id, event);
3091
+ }
3092
+ })
3093
+ ]
3094
+ })
3095
+ });
3096
+ }
3097
+ /**
3098
+ * One or two horizontal panes; CSS resolves content sizes from track fractions.
3099
+ * @param props - committed layout, gesture preview and body retention policy.
3100
+ * @returns stable tab containers, including floating tabs.
3101
+ * @throws if the docked tree is not one pane or two horizontal panes.
3102
+ */
3103
+ function TabLayout(props) {
3104
+ const { state, callbacks, preview } = props;
3105
+ const focusRequest = useRef();
3106
+ const tabCallbacks = {
3107
+ ...callbacks,
3108
+ onFocusTab: (tabId) => {
3109
+ focusRequest.current = findTabPane(state, tabId).activeTabId === tabId ? void 0 : {
3110
+ tabId,
3111
+ origin: document.activeElement
3112
+ };
3113
+ callbacks.onFocusTab(tabId);
3114
+ }
3115
+ };
3116
+ const root = getNode(state, state.rootId);
3117
+ if (root.kind === "split" && (root.axis !== "row" || root.children.length !== 2)) throw new Error("DockLayout requires one pane or two horizontally split panes");
3118
+ const panes = root.kind === "pane" ? [root] : root.children.map((id) => getPane(state, id));
3119
+ const sizes = root.kind === "split" ? preview?.splitId === root.id ? preview.sizes : root.sizes : [1];
3120
+ const floats = useFloatGestures(state, props.intents);
3121
+ const columns = sizes.map((size) => `minmax(0, ${size}fr)`).join(" 0px ");
3122
+ return jsxs("div", {
3123
+ className: css.tabLayout,
3124
+ "data-dockkit-split": root.kind === "split" ? root.id : void 0,
3125
+ style: { gridTemplateColumns: columns },
3126
+ children: [
3127
+ Object.values(state.tabs).sort((a, b) => a.id.localeCompare(b.id)).map((tab) => {
3128
+ const pane = findTabPane(state, tab.id);
3129
+ return jsx(TabHost, {
3130
+ ...props,
3131
+ callbacks: tabCallbacks,
3132
+ tab,
3133
+ pane,
3134
+ column: panes.findIndex((candidate) => candidate.id === pane.id),
3135
+ floats,
3136
+ focusRequest
3137
+ }, tab.id);
3138
+ }),
3139
+ panes.filter((pane) => pane.tabs.length === 0).map((pane) => jsx("div", {
3140
+ className: css.emptyTabHost,
3141
+ "data-dockkit-empty": true,
3142
+ style: {
3143
+ gridColumn: panes.indexOf(pane) * 2 + 1,
3144
+ gridRow: 1
3145
+ },
3146
+ children: jsx(TabPanel, {
3147
+ state,
3148
+ pane,
3149
+ callbacks
3150
+ })
3151
+ }, pane.id)),
3152
+ root.kind === "split" && jsx("div", {
3153
+ className: clsx(css.divider, css.tabLayoutDivider),
3154
+ "data-dockkit-divider": `${root.id}:0`,
3155
+ style: {
3156
+ gridColumn: 2,
3157
+ gridRow: 1
3158
+ },
3159
+ onPointerDown: (event) => {
3160
+ callbacks.onDividerPressed(root.id, 0, event);
3161
+ }
3162
+ })
3163
+ ]
3164
+ });
3165
+ }
3166
+ //#endregion
2777
3167
  //#region lib/types/components/DockSurface.js
2778
3168
  /**
2779
3169
  * The docked surface: the split tree plus the tab and divider gestures over it.
@@ -2838,7 +3228,7 @@ function sameSizes(a, b) {
2838
3228
  });
2839
3229
  }
2840
3230
  /** The split tree and the gestures over it. */
2841
- function DockSurface({ state, canSplit, canAddTab, canCloseTab, intents, labels, renderTab, renderTabTitle, renderTabMenuItems, chrome, onRoom, dropZones = "edges", minPaneFraction = MIN_PANE_FRACTION, hideSplitWhenBlocked = false }) {
3231
+ function Surface({ state, canSplit, canAddTab, canCloseTab, intents, labels, renderTab, renderTabTitle, renderTabMenuItems, chrome, onRoom, draw, dropZones = "edges", minPaneFraction = MIN_PANE_FRACTION, hideSplitWhenBlocked = false }) {
2842
3232
  const surface = useRef(null);
2843
3233
  const [preview, setPreview] = useState(NO_PREVIEW);
2844
3234
  const [fits, setFits] = useState(NO_FITS);
@@ -2967,167 +3357,37 @@ function DockSurface({ state, canSplit, canAddTab, canCloseTab, intents, labels,
2967
3357
  ref: surface,
2968
3358
  "data-dockkit-surface": true,
2969
3359
  "data-dockkit-drop-zones": dropZones,
2970
- children: jsx(PaneTree, {
2971
- state,
2972
- nodeId: state.rootId,
3360
+ children: draw(callbacks, preview.sizes)
3361
+ });
3362
+ }
3363
+ /** Recursive docked layout; floating content is rendered separately by FloatLayer. */
3364
+ function DockSurface(props) {
3365
+ return jsx(Surface, {
3366
+ ...props,
3367
+ draw: (callbacks, preview) => jsx(PaneTree, {
3368
+ state: props.state,
3369
+ nodeId: props.state.rootId,
2973
3370
  callbacks,
2974
- preview: preview.sizes
3371
+ preview
2975
3372
  })
2976
3373
  });
2977
3374
  }
2978
- //#endregion
2979
- //#region lib/types/components/FloatLayer.js
2980
3375
  /**
2981
- * The floating layer: one overlay panel per floating pane, bottom-to-top in the
2982
- * model's z order. A floating pane hosts exactly one tab; its header is the
2983
- * strip's row holding that tab's chip, never selectable or closable from the
2984
- * chip, and the send-back and close controls. Pressing a panel's body raises it. Its grip
2985
- * and corner report through their gesture instead: a press released in place is
2986
- * a click and raises the panel; a drag records the move or resize, and that
2987
- * operation raises the panel itself, so one gesture is one intent. Raising a
2988
- * panel that is active and on top already changes nothing and reports nothing.
2989
- *
2990
- * The layer owns its own drag and resize gestures, so where it mounts is not
2991
- * part of its contract: panels are positioned in viewport coordinates and read
2992
- * only `state` and the outward contracts. An embedder may portal it anywhere,
2993
- * and nothing here assumes the docked tree is an ancestor or even present.
3376
+ * Render one pane or two horizontal panes, and their floats, in one stable content tree.
3377
+ * @param props - layout, gestures and lazy body-retention policy.
3378
+ * @returns the layout; the containing ancestors must not clip or establish a fixed-position containing block.
2994
3379
  */
2995
- /** The rectangle a gesture has reached. */
2996
- function draggedRect(drag, x, y) {
2997
- const dx = x - drag.originX;
2998
- const dy = y - drag.originY;
2999
- return drag.mode === "move" ? movedRect(drag.rect, dx, dy) : resizedRect(drag.rect, dx, dy, FLOAT_MIN_SIZE);
3000
- }
3001
- /** Whether two rectangles agree in every coordinate. */
3002
- function sameRect(a, b) {
3003
- return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
3004
- }
3005
- /** Whether a floating pane is already where a raise would put it: focused and on top. */
3006
- function raised(state, paneId) {
3007
- return state.activePaneId === paneId && state.floats.at(-1) === paneId;
3008
- }
3009
- /** Every floating panel, in z order. */
3010
- function FloatLayer({ state, intents, labels, renderTab, renderTabTitle, canCloseTab }) {
3011
- const [preview, setPreview] = useState(void 0);
3012
- const begin = useGesture(() => {
3013
- setPreview(void 0);
3380
+ function DockLayout(props) {
3381
+ return jsx(Surface, {
3382
+ ...props,
3383
+ draw: (callbacks, preview) => jsx(TabLayout, {
3384
+ ...props,
3385
+ callbacks,
3386
+ preview
3387
+ })
3014
3388
  });
3015
- /** Focus and raise a panel from a press or click on it, unless it is raised already. */
3016
- const raise = (paneId) => {
3017
- if (raised(state, paneId)) return;
3018
- intents.focusPane(paneId);
3019
- };
3020
- /** Start a move or resize from a press on the panel's grip or corner; a release that moved nothing is a click. */
3021
- const drag = (mode, paneId, event) => {
3022
- event.stopPropagation();
3023
- const start = {
3024
- mode,
3025
- originX: event.clientX,
3026
- originY: event.clientY,
3027
- rect: floatRect(getPane(state, paneId))
3028
- };
3029
- begin(event.currentTarget, event.pointerId, {
3030
- move: (moved) => {
3031
- setPreview({
3032
- paneId,
3033
- rect: draggedRect(start, moved.clientX, moved.clientY)
3034
- });
3035
- },
3036
- up: (released) => {
3037
- const rect = draggedRect(start, released.clientX, released.clientY);
3038
- if (sameRect(rect, start.rect)) raise(paneId);
3039
- else if (mode === "move") intents.moveFloat(paneId, rect.x, rect.y);
3040
- else intents.resizeFloat(paneId, rect);
3041
- }
3042
- });
3043
- };
3044
- return jsx(Fragment, { children: state.floats.map((paneId, depth) => {
3045
- const pane = getPane(state, paneId);
3046
- const tab = getTab(state, onlyTabId(pane));
3047
- const lifted = preview?.paneId === paneId ? preview.rect : void 0;
3048
- const live = lifted ?? floatRect(pane);
3049
- return jsxs("div", {
3050
- className: css.float,
3051
- "data-dockkit-float": paneId,
3052
- "data-dockkit-float-active": state.activePaneId === paneId || void 0,
3053
- style: {
3054
- left: live.x,
3055
- top: live.y,
3056
- width: live.width,
3057
- height: live.height,
3058
- zIndex: lifted === void 0 ? depth + 1 : state.floats.length + 1
3059
- },
3060
- onPointerDown: () => {
3061
- raise(paneId);
3062
- },
3063
- children: [
3064
- jsxs("header", {
3065
- className: clsx(css.tabStrip, css.floatHeader),
3066
- "data-dockkit-float-grip": paneId,
3067
- onPointerDown: (event) => {
3068
- drag("move", paneId, event);
3069
- },
3070
- children: [
3071
- jsx("div", {
3072
- className: clsx(css.tab, css.floatTitle),
3073
- "data-dockkit-float-title": true,
3074
- children: jsx(TabTitle, { children: renderTabTitle?.(tab) ?? tab.title })
3075
- }),
3076
- jsx("div", { className: css.stripFill }),
3077
- jsx(Tooltip, {
3078
- label: labels.dockFloat,
3079
- side: "bottom",
3080
- delayMs: 500,
3081
- children: jsx("button", {
3082
- type: "button",
3083
- className: css.iconButton,
3084
- "aria-label": labels.dockFloat,
3085
- "data-dockkit-float-dock": paneId,
3086
- onPointerDown: (event) => {
3087
- event.stopPropagation();
3088
- },
3089
- onClick: () => {
3090
- intents.unfloatPane(paneId);
3091
- },
3092
- children: jsx(IconPanelLeftOutline16, { className: css.dockGlyph })
3093
- })
3094
- }),
3095
- (canCloseTab?.(tab.id) ?? true) && jsx(Tooltip, {
3096
- label: labels.closeFloat,
3097
- side: "bottom",
3098
- delayMs: 500,
3099
- children: jsx("button", {
3100
- type: "button",
3101
- className: css.iconButton,
3102
- "aria-label": labels.closeFloat,
3103
- "data-dockkit-float-close": paneId,
3104
- onPointerDown: (event) => {
3105
- event.stopPropagation();
3106
- },
3107
- onClick: () => {
3108
- intents.closeTab(tab.id);
3109
- },
3110
- children: jsx(IconCloseOutline16, {})
3111
- })
3112
- })
3113
- ]
3114
- }),
3115
- jsx("div", {
3116
- className: css.floatBody,
3117
- children: renderTab(tab)
3118
- }),
3119
- jsx("div", {
3120
- className: css.floatResize,
3121
- "data-dockkit-float-resize": paneId,
3122
- onPointerDown: (event) => {
3123
- drag("resize", paneId, event);
3124
- }
3125
- })
3126
- ]
3127
- }, paneId);
3128
- }) });
3129
3389
  }
3130
3390
  //#endregion
3131
- export { DOCK_EDGE_FRACTION, DOCK_ZONES, DRAG_THRESHOLD, DockController, DockSurface, EMPTY_HISTORY, FLOAT_DEFAULT_SIZE, FLOAT_MIN_SIZE, FloatLayer, MAX_DOCK_PANES, MIN_PANE_FRACTION, SPLIT_MINIMUMS, Sequencer, activeDockPaneId, applyOp, canSplit, canStepBack, canStepForward, clampSizes, containsPoint, createIdMinter, createInitialState, dividerSizes, dockPaneCount, dockPaneIds, findContentTab, findPaneContentTab, findParent, findTabPane, floatRectAt, getNode, getPane, getSplit, getTab, halvesFit, insertionIndex, isFocusOp, movedRect, passedThreshold, planAddTab, planDropTab, planDuplicateTab, planFloatTab, planOpenContent, planPlaceTab, planResizeSplit, planSetExpanded, planSetMode, planSettle, planSplitPane, planUnfloatPane, record, recordedOps, replay, resizedRect, stepBack, stepForward, topRightPaneId, zoneAt, zoneInRect, zoneSplit };
3391
+ export { DOCK_EDGE_FRACTION, DOCK_ZONES, DRAG_THRESHOLD, DockController, DockLayout, DockSurface, EMPTY_HISTORY, FLOAT_DEFAULT_SIZE, FLOAT_MIN_SIZE, FloatLayer, MAX_DOCK_PANES, MIN_PANE_FRACTION, SPLIT_MINIMUMS, Sequencer, activeDockPaneId, applyOp, canSplit, canStepBack, canStepForward, clampSizes, containsPoint, createIdMinter, createInitialState, dividerSizes, dockPaneCount, dockPaneIds, findContentTab, findPaneContentTab, findParent, findTabPane, floatRectAt, getNode, getPane, getSplit, getTab, halvesFit, insertionIndex, isFocusOp, movedRect, passedThreshold, planAddTab, planDropTab, planDuplicateTab, planFloatTab, planOpenContent, planPlaceTab, planResizeSplit, planSetExpanded, planSetMode, planSettle, planSplitPane, planUnfloatPane, record, recordedOps, replay, resizedRect, stepBack, stepForward, topRightPaneId, zoneAt, zoneInRect, zoneSplit };
3132
3392
 
3133
3393
  //# sourceMappingURL=index.js.map