react-panel-layout 0.5.0 → 0.5.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.
Files changed (63) hide show
  1. package/dist/FloatingPanelFrame-D9Cp2al1.cjs +2 -0
  2. package/dist/FloatingPanelFrame-D9Cp2al1.cjs.map +1 -0
  3. package/dist/FloatingPanelFrame-lLg-Lpg7.js +95 -0
  4. package/dist/FloatingPanelFrame-lLg-Lpg7.js.map +1 -0
  5. package/dist/GridLayout-BQQ63eA1.cjs +2 -0
  6. package/dist/GridLayout-BQQ63eA1.cjs.map +1 -0
  7. package/dist/{GridLayout-tpSM0iM-.js → GridLayout-CJTKq7Mp.js} +465 -460
  8. package/dist/GridLayout-CJTKq7Mp.js.map +1 -0
  9. package/dist/PanelSystemContext.d.ts +9 -0
  10. package/dist/components/grid/GridLayerList.d.ts +3 -0
  11. package/dist/components/paneling/FloatingPanelFrame.d.ts +4 -0
  12. package/dist/config.cjs +1 -1
  13. package/dist/config.js +1 -1
  14. package/dist/constants/styles.d.ts +3 -1
  15. package/dist/floating.cjs +1 -1
  16. package/dist/floating.js +1 -1
  17. package/dist/hooks/ContentCacheContext.d.ts +59 -0
  18. package/dist/hooks/useContainerScroll.d.ts +23 -0
  19. package/dist/hooks/useContentCache.d.ts +67 -0
  20. package/dist/hooks/useDocumentScroll.d.ts +13 -0
  21. package/dist/hooks/useScrollContainer.d.ts +21 -0
  22. package/dist/index.cjs +2 -2
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.js +442 -440
  25. package/dist/index.js.map +1 -1
  26. package/dist/modules/pivot/types.d.ts +6 -0
  27. package/dist/pivot.cjs +1 -1
  28. package/dist/pivot.js +1 -1
  29. package/dist/sticky-header/StickyHeader.d.ts +53 -0
  30. package/dist/sticky-header/index.d.ts +7 -0
  31. package/dist/sticky-header/types.d.ts +50 -0
  32. package/dist/sticky-header.cjs +2 -0
  33. package/dist/sticky-header.cjs.map +1 -0
  34. package/dist/sticky-header.js +198 -0
  35. package/dist/sticky-header.js.map +1 -0
  36. package/dist/styles-CA2_zLZt.js +52 -0
  37. package/dist/{styles-DcG3aIFx.cjs.map → styles-CA2_zLZt.js.map} +1 -1
  38. package/dist/styles-PsqGOEJP.cjs +2 -0
  39. package/dist/styles-PsqGOEJP.cjs.map +1 -0
  40. package/dist/types.d.ts +12 -0
  41. package/dist/useIsomorphicLayoutEffect-DGRNF4Lf.cjs +2 -0
  42. package/dist/useIsomorphicLayoutEffect-DGRNF4Lf.cjs.map +1 -0
  43. package/dist/useIsomorphicLayoutEffect-DhmEnmZ_.js +6 -0
  44. package/dist/useIsomorphicLayoutEffect-DhmEnmZ_.js.map +1 -0
  45. package/dist/usePivot-7ctin_P_.cjs +2 -0
  46. package/dist/usePivot-7ctin_P_.cjs.map +1 -0
  47. package/dist/usePivot-CgQxB8rc.js +124 -0
  48. package/dist/usePivot-CgQxB8rc.js.map +1 -0
  49. package/package.json +6 -1
  50. package/dist/FloatingPanelFrame-DDT6aING.js +0 -66
  51. package/dist/FloatingPanelFrame-DDT6aING.js.map +0 -1
  52. package/dist/FloatingPanelFrame-DrYwgI9f.cjs +0 -2
  53. package/dist/FloatingPanelFrame-DrYwgI9f.cjs.map +0 -1
  54. package/dist/GridLayout-DC7fCmcI.cjs +0 -2
  55. package/dist/GridLayout-DC7fCmcI.cjs.map +0 -1
  56. package/dist/GridLayout-tpSM0iM-.js.map +0 -1
  57. package/dist/styles-DcG3aIFx.cjs +0 -2
  58. package/dist/styles-w0ZixggV.js +0 -51
  59. package/dist/styles-w0ZixggV.js.map +0 -1
  60. package/dist/usePivot-C8q0pMgW.cjs +0 -2
  61. package/dist/usePivot-C8q0pMgW.cjs.map +0 -1
  62. package/dist/usePivot-z9gumDf-.js +0 -97
  63. package/dist/usePivot-z9gumDf-.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles-PsqGOEJP.cjs","sources":["../src/constants/styles.ts"],"sourcesContent":["/**\n * @file Style constants for library components\n *\n * These constants reference CSS variables defined in variables.css.\n * This allows users to override theme values via CSS while maintaining\n * type-safe constants in TypeScript.\n *\n * All CSS variables use the unified prefix: --rpl- (react-panel-layout)\n * Users can override these via CSS variables (--rpl-*)\n *\n * @example\n * // In your CSS:\n * :root {\n * --rpl-color-primary: #ff0000;\n * }\n */\n\n// ========================================\n// CSS VARIABLE PREFIX\n// ========================================\n\n/**\n * Unified CSS variable prefix for all react-panel-layout variables\n * All theme variables use this prefix: --rpl-*\n */\nexport const CSS_VAR_PREFIX = \"rpl\";\n\n// ========================================\n// COLORS\n// ========================================\n\n/**\n * Tab colors - used in TabBar component\n */\nexport const COLOR_TAB_FG = \"var(--rpl-color-tab-fg, #d5d7de)\";\nexport const COLOR_TAB_ACTIVE_BG = \"var(--rpl-color-tab-active-bg, #2b2d35)\";\nexport const COLOR_TABBAR_BG = \"var(--rpl-color-tabbar-bg, #1e1f24)\";\n\n/**\n * Panel colors - used in panel layouts\n */\nexport const COLOR_PANEL_BORDER = \"var(--rpl-color-panel-border, rgba(0, 0, 0, 0.3))\";\nexport const COLOR_PANEL_BG = \"var(--rpl-color-panel-bg, #0b0b0c)\";\n\n/**\n * Primary color - used for resize handles, highlights\n */\nexport const COLOR_PRIMARY = \"var(--rpl-color-primary, #2196f3)\";\nexport const COLOR_RESIZE_HANDLE_IDLE = \"var(--rpl-color-resize-handle-idle, rgba(255, 255, 255, 0.0))\";\nexport const COLOR_RESIZE_HANDLE_HOVER = \"var(--rpl-color-resize-handle-hover, rgba(33, 150, 243, 0.35))\";\nexport const COLOR_RESIZE_HANDLE_ACTIVE = \"var(--rpl-color-resize-handle-active, rgba(33, 150, 243, 0.55))\";\n\n/**\n * Drop suggestion overlay colors\n */\nexport const COLOR_DROP_SUGGEST_BORDER = \"var(--rpl-color-drop-suggest-border, rgba(90, 150, 255, 0.9))\";\nexport const COLOR_DROP_SUGGEST_BG = \"var(--rpl-color-drop-suggest-bg, rgba(90, 150, 255, 0.15))\";\n\n/**\n * Tab drag overlay colors\n */\nexport const COLOR_TABDRAG_BG = \"var(--rpl-color-tabdrag-bg, rgba(34, 36, 42, 0.95))\";\nexport const COLOR_TABDRAG_FG = \"var(--rpl-color-tabdrag-fg, #e9ebf0)\";\nexport const COLOR_TABDRAG_BORDER = \"var(--rpl-color-tabdrag-border, rgba(120, 160, 255, 0.6))\";\nexport const COLOR_TABDRAG_SHADOW = \"var(--rpl-color-tabdrag-shadow, 0 6px 20px rgba(0, 0, 0, 0.35))\";\n\n/**\n * Insert guide colors\n */\nexport const COLOR_INSERT_GUIDE = \"var(--rpl-color-insert-guide, rgba(120, 160, 255, 0.95))\";\nexport const COLOR_INSERT_GUIDE_SHADOW = \"var(--rpl-color-insert-guide-shadow, 0 0 0 2px rgba(120, 160, 255, 0.2))\";\n\n/**\n * Node editor / floating panel colors\n * These are used by Drawer and FloatingPanelFrame components\n */\nexport const COLOR_NODE_EDITOR_SURFACE = \"var(--rpl-color-surface, #fff)\";\nexport const COLOR_NODE_EDITOR_SURFACE_2 = \"var(--rpl-color-surface-2, #fafafa)\";\nexport const COLOR_NODE_EDITOR_BORDER = \"var(--rpl-color-border, #e5e7eb)\";\nexport const COLOR_NODE_EDITOR_MUTED_FG = \"var(--rpl-color-muted-fg, #6b7280)\";\nexport const COLOR_NODE_EDITOR_CARD_SHADOW = \"var(--rpl-shadow-card, 0 2px 10px rgba(0, 0, 0, 0.08))\";\nexport const COLOR_DRAWER_BACKDROP = \"var(--rpl-color-drawer-backdrop, rgba(0, 0, 0, 0.5))\";\n\n/**\n * Drawer transitions\n */\nexport const DRAWER_TRANSITION_DURATION = \"var(--rpl-drawer-transition-duration, 220ms)\";\nexport const DRAWER_TRANSITION_EASING = \"var(--rpl-drawer-transition-easing, cubic-bezier(0.22, 1, 0.36, 1))\";\n\n/**\n * Pivot animations\n * User defines @keyframes in their CSS and references via these tokens.\n * - Enter: Applied when content becomes active\n * - Leave: Applied when content becomes inactive\n */\nexport const PIVOT_ANIMATION_ENTER = \"var(--rpl-pivot-animation-enter, none)\";\nexport const PIVOT_ANIMATION_LEAVE = \"var(--rpl-pivot-animation-leave, none)\";\n\n// ========================================\n// SIZING & SPACING\n// ========================================\n\n/**\n * Tab sizing\n */\nexport const SIZE_TAB_FONT = \"var(--rpl-size-tab-font, 12px)\";\nexport const SPACE_TAB_PADDING_Y = \"var(--rpl-space-tab-padding-y, 4px)\";\nexport const SPACE_TAB_PADDING_X = \"var(--rpl-space-tab-padding-x, 8px)\";\n\n/**\n * Tabbar spacing\n */\nexport const SPACE_TABBAR_GAP = \"var(--rpl-space-tabbar-gap, 6px)\";\nexport const SPACE_TABBAR_PADDING_Y = \"var(--rpl-space-tabbar-padding-y, 4px)\";\nexport const SPACE_TABBAR_PADDING_X = \"var(--rpl-space-tabbar-padding-x, 6px)\";\n\n/**\n * Border radius (decorative, using CSS variables)\n */\nexport const RADIUS_TAB = \"var(--rpl-radius-tab, 4px)\";\nexport const RADIUS_SUGGEST = \"var(--rpl-radius-suggest, 6px)\";\n\n/**\n * Border widths\n */\nexport const SIZE_SUGGEST_BORDER = \"var(--rpl-size-suggest-border, 2px)\";\n\n/**\n * Handle thicknesses\n * Note: SIZE_GRID_HANDLE_THICKNESS is kept as number for JavaScript calculations\n */\nexport const SIZE_GRID_HANDLE_THICKNESS = 4; // Used in GridTrackResizeHandle.tsx for offset calculation\nexport const SIZE_RESIZE_HANDLE_THICKNESS = \"var(--rpl-size-resize-handle-thickness, 4px)\";\nexport const SIZE_SPLIT_HANDLE_THICKNESS = \"var(--rpl-size-split-handle-thickness, 6px)\";\n\n/**\n * Drop suggest padding\n */\nexport const SPACE_DROP_SUGGEST_PADDING = \"var(--rpl-space-drop-suggest-padding, 6px)\";\n\n// ========================================\n// Z-INDEXES\n// ========================================\n\nexport const Z_OVERLAY = \"var(--rpl-z-overlay, 9998)\";\nexport const Z_TABDRAG_OVERLAY = \"var(--rpl-z-tabdrag-overlay, 9999)\";\nexport const Z_DIALOG_OVERLAY = \"var(--rpl-z-dialog-overlay, 10000)\";\n\n// ========================================\n// COMPONENT-SPECIFIC CONSTANTS\n// ========================================\n\n/**\n * Resize Handle\n */\nexport const RESIZE_HANDLE_THICKNESS = SIZE_RESIZE_HANDLE_THICKNESS;\nexport const RESIZE_HANDLE_Z_INDEX = \"var(--rpl-z-resize-handle, 1000)\";\n\n/**\n * Grid Track Resize Handle\n */\nexport const GRID_HANDLE_THICKNESS = SIZE_GRID_HANDLE_THICKNESS;\n\n/**\n * Grid Layer Resize Handles\n */\nexport const GRID_LAYER_CORNER_HIT_SIZE = \"var(--rpl-size-grid-layer-corner-hit, 14px)\";\nexport const GRID_LAYER_EDGE_HIT_THICKNESS = \"var(--rpl-size-grid-layer-edge-hit-thickness, 12px)\";\n\n/**\n * Drop Suggest Overlay\n */\nexport const DROP_SUGGEST_Z_INDEX = Z_OVERLAY;\nexport const DROP_SUGGEST_BORDER_WIDTH = SIZE_SUGGEST_BORDER;\nexport const DROP_SUGGEST_BORDER_RADIUS = RADIUS_SUGGEST;\nexport const DROP_SUGGEST_BORDER_COLOR = COLOR_DROP_SUGGEST_BORDER;\nexport const DROP_SUGGEST_BG_COLOR = COLOR_DROP_SUGGEST_BG;\nexport const DROP_SUGGEST_PADDING = SPACE_DROP_SUGGEST_PADDING;\nexport const DROP_SUGGEST_PADDING_PX = 6;\n\n/**\n * Tab Drag Overlay\n */\nexport const TAB_DRAG_OVERLAY_Z_INDEX = Z_TABDRAG_OVERLAY;\nexport const TAB_DRAG_PREVIEW_OFFSET_X = \"var(--rpl-space-tab-drag-preview-offset-x, 12px)\";\nexport const TAB_DRAG_PREVIEW_OFFSET_Y = \"var(--rpl-space-tab-drag-preview-offset-y, 12px)\";\nexport const TAB_DRAG_PREVIEW_BORDER_RADIUS = \"var(--rpl-radius-tab-drag-preview, 6px)\";\nexport const TAB_DRAG_PREVIEW_PADDING_Y = \"var(--rpl-space-tab-drag-preview-padding-y, 4px)\";\nexport const TAB_DRAG_PREVIEW_PADDING_X = \"var(--rpl-space-tab-drag-preview-padding-x, 8px)\";\nexport const TAB_DRAG_PREVIEW_FONT_SIZE = \"var(--rpl-size-tab-drag-preview-font, 12px)\";\nexport const TAB_DRAG_INSERT_GUIDE_WIDTH = \"var(--rpl-size-tab-drag-insert-guide-width, 2px)\";\nexport const TAB_DRAG_INSERT_GUIDE_BORDER_RADIUS = \"var(--rpl-radius-tab-drag-insert-guide, 1px)\";\nexport const TAB_DRAG_PREVIEW_BG_COLOR = COLOR_TABDRAG_BG;\nexport const TAB_DRAG_PREVIEW_FG_COLOR = COLOR_TABDRAG_FG;\nexport const TAB_DRAG_PREVIEW_BORDER_COLOR = COLOR_TABDRAG_BORDER;\nexport const TAB_DRAG_PREVIEW_SHADOW = COLOR_TABDRAG_SHADOW;\nexport const TAB_DRAG_INSERT_GUIDE_COLOR = COLOR_INSERT_GUIDE;\nexport const TAB_DRAG_INSERT_GUIDE_SHADOW = COLOR_INSERT_GUIDE_SHADOW;\n\n/**\n * Dialog Overlay\n */\nexport const DIALOG_OVERLAY_Z_INDEX = Z_DIALOG_OVERLAY;\n\n/**\n * Floating Panel Frame\n */\nexport const FLOATING_PANEL_BORDER_RADIUS = \"var(--rpl-radius-floating-panel, 8px)\";\nexport const FLOATING_PANEL_GAP = \"var(--rpl-space-floating-panel-gap, 8px)\";\nexport const FLOATING_PANEL_HEADER_PADDING_Y = \"var(--rpl-space-floating-panel-header-padding-y, 8px)\";\nexport const FLOATING_PANEL_HEADER_PADDING_X = \"var(--rpl-space-floating-panel-header-padding-x, 12px)\";\nexport const FLOATING_PANEL_CONTENT_PADDING = \"var(--rpl-space-floating-panel-content-padding, 12px)\";\nexport const FLOATING_PANEL_META_FONT_SIZE = \"var(--rpl-size-floating-panel-meta-font, 12px)\";\nexport const FLOATING_PANEL_CONTROLS_GAP = \"var(--rpl-space-floating-panel-controls-gap, 6px)\";\nexport const FLOATING_PANEL_CLOSE_BUTTON_FONT_SIZE = \"var(--rpl-size-floating-panel-close-button-font, 1.25rem)\";\nexport const FLOATING_PANEL_CLOSE_BUTTON_PADDING =\n \"var(--rpl-space-floating-panel-close-button-padding, 0.25rem 0.5rem)\";\nexport const FLOATING_PANEL_SURFACE_COLOR = COLOR_NODE_EDITOR_SURFACE;\nexport const FLOATING_PANEL_SURFACE_2_COLOR = COLOR_NODE_EDITOR_SURFACE_2;\nexport const FLOATING_PANEL_BORDER_COLOR = COLOR_NODE_EDITOR_BORDER;\nexport const FLOATING_PANEL_MUTED_FG_COLOR = COLOR_NODE_EDITOR_MUTED_FG;\nexport const FLOATING_PANEL_SHADOW = COLOR_NODE_EDITOR_CARD_SHADOW;\n\n/**\n * Drawer\n */\nexport const DRAWER_HEADER_PADDING_Y = \"var(--rpl-space-drawer-header-padding-y, 10px)\";\nexport const DRAWER_HEADER_PADDING_X = \"var(--rpl-space-drawer-header-padding-x, 12px)\";\nexport const DRAWER_HEADER_GAP = \"var(--rpl-space-drawer-header-gap, 8px)\";\nexport const DRAWER_CONTENT_PADDING = \"var(--rpl-space-drawer-content-padding, 12px)\";\nexport const DRAWER_CLOSE_BUTTON_FONT_SIZE = \"var(--rpl-size-drawer-close-button-font, 18px)\";\nexport const DRAWER_SURFACE_COLOR = COLOR_NODE_EDITOR_SURFACE;\nexport const DRAWER_BORDER_COLOR = COLOR_NODE_EDITOR_BORDER;\nexport const DRAWER_SHADOW = COLOR_NODE_EDITOR_CARD_SHADOW;\n\n/**\n * Split Handles\n */\nexport const SPLIT_HANDLE_THICKNESS = SIZE_SPLIT_HANDLE_THICKNESS;\n\n/**\n * HorizontalDivider\n */\nexport const HORIZONTAL_DIVIDER_WIDTH = \"var(--rpl-size-horizontal-divider-width, 4px)\";\nexport const HORIZONTAL_DIVIDER_HIT_AREA_OFFSET = \"var(--rpl-space-horizontal-divider-hit-area-offset, 4px)\";\n"],"names":["COLOR_RESIZE_HANDLE_IDLE","COLOR_RESIZE_HANDLE_HOVER","COLOR_RESIZE_HANDLE_ACTIVE","COLOR_DROP_SUGGEST_BORDER","COLOR_DROP_SUGGEST_BG","COLOR_INSERT_GUIDE","COLOR_INSERT_GUIDE_SHADOW","COLOR_NODE_EDITOR_SURFACE","COLOR_NODE_EDITOR_SURFACE_2","COLOR_NODE_EDITOR_BORDER","COLOR_NODE_EDITOR_MUTED_FG","COLOR_NODE_EDITOR_CARD_SHADOW","COLOR_DRAWER_BACKDROP","DRAWER_TRANSITION_DURATION","DRAWER_TRANSITION_EASING","PIVOT_ANIMATION_ENTER","PIVOT_ANIMATION_LEAVE","RADIUS_SUGGEST","SIZE_SUGGEST_BORDER","SIZE_RESIZE_HANDLE_THICKNESS","SIZE_SPLIT_HANDLE_THICKNESS","Z_OVERLAY","Z_TABDRAG_OVERLAY","RESIZE_HANDLE_THICKNESS","RESIZE_HANDLE_Z_INDEX","GRID_HANDLE_THICKNESS","GRID_LAYER_CORNER_HIT_SIZE","GRID_LAYER_EDGE_HIT_THICKNESS","DROP_SUGGEST_Z_INDEX","DROP_SUGGEST_BORDER_WIDTH","DROP_SUGGEST_BORDER_RADIUS","DROP_SUGGEST_BORDER_COLOR","DROP_SUGGEST_BG_COLOR","DROP_SUGGEST_PADDING_PX","TAB_DRAG_OVERLAY_Z_INDEX","TAB_DRAG_PREVIEW_OFFSET_X","TAB_DRAG_PREVIEW_OFFSET_Y","TAB_DRAG_INSERT_GUIDE_WIDTH","TAB_DRAG_INSERT_GUIDE_BORDER_RADIUS","TAB_DRAG_INSERT_GUIDE_COLOR","TAB_DRAG_INSERT_GUIDE_SHADOW","FLOATING_PANEL_BORDER_RADIUS","FLOATING_PANEL_GAP","FLOATING_PANEL_HEADER_PADDING_Y","FLOATING_PANEL_HEADER_PADDING_X","FLOATING_PANEL_CONTENT_PADDING","FLOATING_PANEL_META_FONT_SIZE","FLOATING_PANEL_CONTROLS_GAP","FLOATING_PANEL_CLOSE_BUTTON_FONT_SIZE","FLOATING_PANEL_CLOSE_BUTTON_PADDING","FLOATING_PANEL_SURFACE_COLOR","FLOATING_PANEL_SURFACE_2_COLOR","FLOATING_PANEL_BORDER_COLOR","FLOATING_PANEL_MUTED_FG_COLOR","FLOATING_PANEL_SHADOW","DRAWER_HEADER_PADDING_Y","DRAWER_HEADER_PADDING_X","DRAWER_HEADER_GAP","DRAWER_CONTENT_PADDING","SPLIT_HANDLE_THICKNESS","HORIZONTAL_DIVIDER_WIDTH"],"mappings":"aAgDO,MAAMA,EAA2B,gEAC3BC,EAA4B,iEAC5BC,EAA6B,kEAK7BC,EAA4B,gEAC5BC,EAAwB,6DAaxBC,EAAqB,2DACrBC,EAA4B,2EAM5BC,EAA4B,iCAC5BC,EAA8B,sCAC9BC,EAA2B,mCAC3BC,EAA6B,qCAC7BC,EAAgC,yDAChCC,EAAwB,uDAKxBC,EAA6B,+CAC7BC,EAA2B,sEAQ3BC,EAAwB,yCACxBC,EAAwB,yCAwBxBC,EAAiB,iCAKjBC,EAAsB,sCAO5B,MAAMC,EAA+B,+CAC/BC,EAA8B,8CAW9BC,EAAY,6BACZC,EAAoB,qCAUpBC,EAA0BJ,EAC1BK,EAAwB,mCAKxBC,EAAwB,EAKxBC,EAA6B,8CAC7BC,EAAgC,sDAKhCC,EAAuBP,EACvBQ,EAA4BX,EAC5BY,EAA6Bb,EAC7Bc,EAA4B5B,EAC5B6B,EAAwB5B,EAExB6B,EAA0B,EAK1BC,EAA2BZ,EAC3Ba,EAA4B,mDAC5BC,EAA4B,mDAK5BC,EAA8B,mDAC9BC,EAAsC,+CAKtCC,EAA8BlC,EAC9BmC,EAA+BlC,EAU/BmC,EAA+B,wCAC/BC,EAAqB,2CACrBC,EAAkC,wDAClCC,EAAkC,yDAClCC,EAAiC,wDACjCC,EAAgC,iDAChCC,EAA8B,oDAC9BC,EAAwC,4DACxCC,EACX,uEACWC,EAA+B3C,EAC/B4C,EAAiC3C,EACjC4C,EAA8B3C,EAC9B4C,EAAgC3C,EAChC4C,GAAwB3C,EAKxB4C,GAA0B,iDAC1BC,GAA0B,iDAC1BC,GAAoB,0CACpBC,GAAyB,gDASzBC,GAAyBvC,EAKzBwC,GAA2B"}
package/dist/types.d.ts CHANGED
@@ -115,6 +115,12 @@ export type PivotBehaviorItem = {
115
115
  content: React.ReactNode;
116
116
  /** Whether this item can be selected */
117
117
  disabled?: boolean;
118
+ /**
119
+ * Enable content caching to preserve React component state across re-renders.
120
+ * When disabled (default), content is re-created on each render.
121
+ * @default false
122
+ */
123
+ cache?: boolean;
118
124
  };
119
125
  export type PivotBehavior = {
120
126
  /** Array of content items to switch between */
@@ -230,6 +236,12 @@ export type LayerDefinition = {
230
236
  * When false or omitted, content overflow is hidden (default behavior).
231
237
  */
232
238
  scrollable?: boolean;
239
+ /**
240
+ * Enable content caching to preserve React component state across re-renders.
241
+ * When disabled (default), content is re-created on each render.
242
+ * @default false
243
+ */
244
+ cache?: boolean;
233
245
  };
234
246
  export type PanelLayoutProps = {
235
247
  config: PanelLayoutConfig;
@@ -0,0 +1,2 @@
1
+ "use strict";const r=require("react");function u(e){const o=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const t in e)if(t!=="default"){const c=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(o,t,c.get?c:{enumerable:!0,get:()=>e[t]})}}return o.default=e,Object.freeze(o)}const n=u(r),f=typeof window<"u"&&typeof window.document<"u",s=f?n.useLayoutEffect:n.useEffect;exports.useIsomorphicLayoutEffect=s;
2
+ //# sourceMappingURL=useIsomorphicLayoutEffect-DGRNF4Lf.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIsomorphicLayoutEffect-DGRNF4Lf.cjs","sources":["../src/hooks/useIsomorphicLayoutEffect.ts"],"sourcesContent":["/**\n * @file useIsomorphicLayoutEffect - SSR-safe version of useLayoutEffect\n *\n * Uses useLayoutEffect on the client and useEffect on the server to avoid warnings\n * during server-side rendering (e.g., with Next.js)\n */\nimport * as React from \"react\";\n\n/**\n * Check if we're running in a browser environment\n */\nconst isBrowser = typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\n\n/**\n * SSR-safe version of useLayoutEffect\n *\n * - Client: Uses useLayoutEffect for synchronous layout updates\n * - Server: Uses useEffect to avoid SSR warnings\n *\n * @example\n * ```tsx\n * useIsomorphicLayoutEffect(() => {\n * // This runs synchronously after DOM mutations on the client\n * // but safely falls back to useEffect on the server\n * measureElement();\n * }, [deps]);\n * ```\n */\nexport const useIsomorphicLayoutEffect = isBrowser ? React.useLayoutEffect : React.useEffect;\n"],"names":["isBrowser","useIsomorphicLayoutEffect","React"],"mappings":"gUAWMA,EAAY,OAAO,OAAW,KAAe,OAAO,OAAO,SAAa,IAiBjEC,EAA4BD,EAAYE,EAAM,gBAAkBA,EAAM"}
@@ -0,0 +1,6 @@
1
+ import * as e from "react";
2
+ const o = typeof window < "u" && typeof window.document < "u", t = o ? e.useLayoutEffect : e.useEffect;
3
+ export {
4
+ t as u
5
+ };
6
+ //# sourceMappingURL=useIsomorphicLayoutEffect-DhmEnmZ_.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIsomorphicLayoutEffect-DhmEnmZ_.js","sources":["../src/hooks/useIsomorphicLayoutEffect.ts"],"sourcesContent":["/**\n * @file useIsomorphicLayoutEffect - SSR-safe version of useLayoutEffect\n *\n * Uses useLayoutEffect on the client and useEffect on the server to avoid warnings\n * during server-side rendering (e.g., with Next.js)\n */\nimport * as React from \"react\";\n\n/**\n * Check if we're running in a browser environment\n */\nconst isBrowser = typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\n\n/**\n * SSR-safe version of useLayoutEffect\n *\n * - Client: Uses useLayoutEffect for synchronous layout updates\n * - Server: Uses useEffect to avoid SSR warnings\n *\n * @example\n * ```tsx\n * useIsomorphicLayoutEffect(() => {\n * // This runs synchronously after DOM mutations on the client\n * // but safely falls back to useEffect on the server\n * measureElement();\n * }, [deps]);\n * ```\n */\nexport const useIsomorphicLayoutEffect = isBrowser ? React.useLayoutEffect : React.useEffect;\n"],"names":["isBrowser","useIsomorphicLayoutEffect","React"],"mappings":";AAWA,MAAMA,IAAY,OAAO,SAAW,OAAe,OAAO,OAAO,WAAa,KAiBjEC,IAA4BD,IAAYE,EAAM,kBAAkBA,EAAM;"}
@@ -0,0 +1,2 @@
1
+ "use strict";const d=require("react/jsx-runtime"),S=require("react"),R=require("./styles-PsqGOEJP.cjs"),N=require("./useIsomorphicLayoutEffect-DGRNF4Lf.cjs");function _(c){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(c){for(const o in c)if(o!=="default"){const u=Object.getOwnPropertyDescriptor(c,o);Object.defineProperty(e,o,u.get?u:{enumerable:!0,get:()=>c[o]})}}return e.default=c,Object.freeze(e)}const t=_(S);function y(c){const{resolveContent:e,validIds:o}=c,u=t.useRef(new Map),i=t.useRef(e);i.current=e;const s=t.useCallback(l=>{const a=u.current.get(l);if(a!==void 0)return a;const r=i.current(l);return u.current.set(l,r),r},[]),f=t.useCallback(()=>{u.current.clear()},[]);return t.useEffect(()=>{const l=new Set(o);u.current.forEach((a,r)=>{l.has(r)||u.current.delete(r)})},[o]),{getCachedContent:s,clearCache:f}}const k={position:"absolute",inset:0,width:"100%",height:"100%"},A=t.memo(({id:c,isActive:e,transitionMode:o,children:u})=>{const i=t.useRef(null),s=t.useRef(e);N.useIsomorphicLayoutEffect(()=>{if(o!=="css"||!i.current)return;const a=i.current,r=s.current;s.current=e,r!==e&&(a.style.animation="none",a.offsetHeight,a.style.animation="")},[e,o]);const f=t.useMemo(()=>{const a={...k,pointerEvents:e?"auto":"none",opacity:e?1:0};return o==="css"&&(a.animation=e?R.PIVOT_ANIMATION_ENTER:R.PIVOT_ANIMATION_LEAVE),a},[e,o]),l=d.jsx("div",{ref:i,"data-pivot-content":c,"data-active":e?"true":"false",style:f,children:u});return o==="none"?d.jsx(t.Activity,{mode:e?"visible":"hidden",children:l}):l}),E=t.createContext(null),M=t.memo(()=>{const c=t.useContext(E);if(!c)throw new Error("PivotOutlet must be used within usePivot");const[,e]=t.useReducer(s=>s+1,0);t.useEffect(()=>c.subscribe(e),[c]);const{items:o,activeId:u,transitionMode:i}=c.getState();return d.jsx(d.Fragment,{children:o.map(s=>d.jsx(A,{id:s.id,isActive:s.id===u,transitionMode:i,children:s.cache?c.getCachedContent(s.id):s.content},s.id))})});function T(c){const{items:e,activeId:o,defaultActiveId:u,onActiveChange:i,transitionMode:s="css"}=c,f=o!==void 0,[l,a]=t.useState(()=>{if(u!==void 0)return u;const n=e.find(v=>v.disabled!==!0);if(!n)throw new Error("usePivot: No enabled items provided");return n.id}),r=f?o:l,h=t.useCallback(n=>{const v=e.find(b=>b.id===n);v&&(v.disabled||(f||a(n),i?.(n)))},[e,f,i]),O=t.useCallback(n=>n===r,[r]),P=t.useCallback(n=>({"data-pivot-item":n,"data-active":n===r?"true":"false","aria-selected":n===r,tabIndex:n===r?0:-1,onClick:()=>{h(n)}}),[r,h]),p=t.useMemo(()=>({position:"relative",width:"100%",height:"100%"}),[]),m=t.useRef({items:e,activeId:r,transitionMode:s});m.current={items:e,activeId:r,transitionMode:s};const C=t.useRef(new Set);t.useEffect(()=>{C.current.forEach(n=>n())},[r,s]);const x=t.useCallback(n=>m.current.items.find(b=>b.id===n)?.content??null,[]),j=t.useMemo(()=>e.map(n=>n.id),[e]),{getCachedContent:I}=y({resolveContent:x,validIds:j}),g=t.useMemo(()=>({getState:()=>m.current,subscribe:n=>(C.current.add(n),()=>C.current.delete(n)),getCachedContent:I}),[I]),w=t.useMemo(()=>{const n=()=>d.jsx(E.Provider,{value:g,children:d.jsx("div",{style:p,"data-pivot-container":!0,children:d.jsx(M,{})})});return n.displayName="PivotOutlet",n},[g,p]);return{activeId:r,setActiveId:h,isActive:O,getItemProps:P,Outlet:w}}exports.useContentCache=y;exports.usePivot=T;
2
+ //# sourceMappingURL=usePivot-7ctin_P_.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePivot-7ctin_P_.cjs","sources":["../src/hooks/useContentCache.tsx","../src/modules/pivot/PivotContent.tsx","../src/modules/pivot/usePivot.tsx"],"sourcesContent":["/**\n * @file Shared content caching hook for preserving React component state.\n *\n * This hook provides a common pattern for caching ReactNode content by ID,\n * ensuring the same reference is returned for the same ID across re-renders.\n * This prevents component remounting when parent components re-create content arrays.\n *\n * Used by:\n * - PanelSystemContext (GridLayout layer content)\n * - usePivot (Pivot item content)\n * - ContentRegistry (Panel content)\n */\nimport * as React from \"react\";\n\n/**\n * Function type for resolving content by ID.\n * Called only when content is not already cached.\n */\nexport type ContentResolver<TId extends string = string> = (id: TId) => React.ReactNode | null;\n\n/**\n * Options for useContentCache hook.\n */\nexport type UseContentCacheOptions<TId extends string = string> = {\n /**\n * Function to resolve content by ID.\n * Called only when content is not already in cache.\n */\n resolveContent: ContentResolver<TId>;\n /**\n * Current valid IDs. Used to clean up stale cache entries.\n * When an ID is removed from this array, its cached content is deleted.\n */\n validIds: readonly TId[];\n};\n\n/**\n * Result from useContentCache hook.\n */\nexport type UseContentCacheResult<TId extends string = string> = {\n /**\n * Get cached content for an ID.\n * Returns the same ReactNode reference for the same ID.\n */\n getCachedContent: (id: TId) => React.ReactNode | null;\n /**\n * Clear all cached content.\n * Use when you need to force re-creation of all content.\n */\n clearCache: () => void;\n};\n\n/**\n * Hook for caching ReactNode content by ID.\n *\n * Ensures the same ReactNode reference is returned for the same ID,\n * preventing unnecessary component remounting when parent re-renders.\n *\n * @example\n * ```tsx\n * const { getCachedContent } = useContentCache({\n * resolveContent: (id) => items.find(i => i.id === id)?.content ?? null,\n * validIds: items.map(i => i.id),\n * });\n *\n * return items.map(item => (\n * <div key={item.id}>{getCachedContent(item.id)}</div>\n * ));\n * ```\n */\nexport function useContentCache<TId extends string = string>(\n options: UseContentCacheOptions<TId>,\n): UseContentCacheResult<TId> {\n const { resolveContent, validIds } = options;\n\n /**\n * Cache storage. Key: ID, Value: cached ReactNode.\n * Uses ref to persist across re-renders without triggering updates.\n */\n const cacheRef = React.useRef<Map<string, React.ReactNode>>(new Map());\n\n /**\n * Store resolveContent in a ref for stable getCachedContent function.\n * This allows getCachedContent to always use the latest resolver\n * without needing to be recreated.\n */\n const resolveContentRef = React.useRef(resolveContent);\n resolveContentRef.current = resolveContent;\n\n /**\n * Get or create cached content for an ID.\n * On first access, calls resolveContent and caches the result.\n * On subsequent accesses, returns the cached reference.\n */\n const getCachedContent = React.useCallback((id: TId): React.ReactNode | null => {\n const cached = cacheRef.current.get(id);\n if (cached !== undefined) {\n return cached;\n }\n\n const content = resolveContentRef.current(id);\n cacheRef.current.set(id, content);\n return content;\n }, []);\n\n /**\n * Clear all cached content.\n */\n const clearCache = React.useCallback((): void => {\n cacheRef.current.clear();\n }, []);\n\n /**\n * Clean up stale cache entries when validIds changes.\n * Removes entries for IDs that are no longer valid.\n */\n React.useEffect(() => {\n const currentValidIds = new Set<string>(validIds);\n cacheRef.current.forEach((_, id) => {\n if (!currentValidIds.has(id)) {\n cacheRef.current.delete(id);\n }\n });\n }, [validIds]);\n\n return { getCachedContent, clearCache };\n}\n","/**\n * @file PivotContent component for rendering pivot items with CSS animations.\n *\n * Override via CSS custom properties:\n * - --rpl-pivot-animation-enter: Animation when becoming active\n * - --rpl-pivot-animation-leave: Animation when becoming inactive\n *\n * User defines @keyframes in their CSS and references via these tokens.\n * Example:\n * @keyframes pivotEnter {\n * from { opacity: 0; }\n * to { opacity: 1; }\n * }\n * :root { --rpl-pivot-animation-enter: pivotEnter 150ms ease-out forwards; }\n */\nimport * as React from \"react\";\nimport { PIVOT_ANIMATION_ENTER, PIVOT_ANIMATION_LEAVE } from \"../../constants/styles\";\nimport { useIsomorphicLayoutEffect } from \"../../hooks/useIsomorphicLayoutEffect\";\n\nexport type PivotContentProps = {\n id: string;\n isActive: boolean;\n transitionMode: \"css\" | \"none\";\n children: React.ReactNode;\n};\n\nconst baseStyle: React.CSSProperties = {\n position: \"absolute\",\n inset: 0,\n width: \"100%\",\n height: \"100%\",\n};\n\n/**\n * Renders pivot content with CSS animation support.\n *\n * When transitionMode=\"css\": Applies enter/leave animations.\n * When transitionMode=\"none\": Uses React.Activity for memory optimization.\n */\nexport const PivotContent: React.FC<PivotContentProps> = React.memo(({ id, isActive, transitionMode, children }) => {\n const ref = React.useRef<HTMLDivElement>(null);\n const prevActiveRef = React.useRef(isActive);\n\n // Restart animation on state change by removing and re-adding animation\n useIsomorphicLayoutEffect(() => {\n if (transitionMode !== \"css\" || !ref.current) {\n return;\n }\n\n const el = ref.current;\n const wasActive = prevActiveRef.current;\n prevActiveRef.current = isActive;\n\n // Only restart if state actually changed\n if (wasActive === isActive) {\n return;\n }\n\n // Force animation restart: remove animation, trigger reflow, re-add\n el.style.animation = \"none\";\n void el.offsetHeight; // Force reflow\n el.style.animation = \"\";\n }, [isActive, transitionMode]);\n\n const style = React.useMemo<React.CSSProperties>(() => {\n const s: React.CSSProperties = {\n ...baseStyle,\n pointerEvents: isActive ? \"auto\" : \"none\",\n opacity: isActive ? 1 : 0,\n };\n\n if (transitionMode === \"css\") {\n s.animation = isActive ? PIVOT_ANIMATION_ENTER : PIVOT_ANIMATION_LEAVE;\n }\n\n return s;\n }, [isActive, transitionMode]);\n\n const content = (\n <div ref={ref} data-pivot-content={id} data-active={isActive ? \"true\" : \"false\"} style={style}>\n {children}\n </div>\n );\n\n if (transitionMode === \"none\") {\n return <React.Activity mode={isActive ? \"visible\" : \"hidden\"}>{content}</React.Activity>;\n }\n\n return content;\n});\n","/**\n * @file Headless hook for managing Pivot (content switching) behavior.\n *\n * Includes content caching to preserve React component state across re-renders.\n * This is essential for maintaining internal state when parent components\n * re-create the items array.\n */\nimport * as React from \"react\";\nimport type { UsePivotOptions, UsePivotResult, PivotItemProps, PivotItem } from \"./types\";\nimport { PivotContent } from \"./PivotContent\";\nimport { useContentCache } from \"../../hooks/useContentCache\";\n\n/**\n * Context for sharing pivot state with Outlet component.\n * Uses a ref-based approach to avoid re-creating the Outlet component.\n * Includes content cache to preserve component state.\n */\ntype PivotOutletContextValue = {\n getState: () => {\n items: ReadonlyArray<PivotItem>;\n activeId: string;\n transitionMode: \"css\" | \"none\";\n };\n subscribe: (callback: () => void) => () => void;\n /**\n * Get cached content for an item. Returns the same ReactNode reference\n * for the same item ID to prevent remounting on parent re-renders.\n */\n getCachedContent: (itemId: string) => React.ReactNode | null;\n};\n\nconst PivotOutletContext = React.createContext<PivotOutletContextValue | null>(null);\n\n/**\n * Stable Outlet component that subscribes to state changes.\n * This prevents remounting when activeId changes.\n * Uses cached content only when item.cache is true.\n */\nconst PivotOutletInner: React.FC = React.memo(() => {\n const ctx = React.useContext(PivotOutletContext);\n if (!ctx) {\n throw new Error(\"PivotOutlet must be used within usePivot\");\n }\n\n const [, forceUpdate] = React.useReducer((x) => x + 1, 0);\n\n React.useEffect(() => {\n return ctx.subscribe(forceUpdate);\n }, [ctx]);\n\n const { items, activeId, transitionMode } = ctx.getState();\n\n return (\n <>\n {items.map((item) => (\n <PivotContent key={item.id} id={item.id} isActive={item.id === activeId} transitionMode={transitionMode}>\n {item.cache ? ctx.getCachedContent(item.id) : item.content}\n </PivotContent>\n ))}\n </>\n );\n});\n\n/**\n * Headless hook for managing content switching within a scope.\n * Provides behavior only - UI is fully customizable.\n *\n * @example\n * ```tsx\n * const { activeId, getItemProps, Outlet } = usePivot({\n * items: [\n * { id: 'home', label: 'Home', content: <HomePage /> },\n * { id: 'settings', label: 'Settings', content: <SettingsPage /> }\n * ],\n * defaultActiveId: 'home'\n * });\n *\n * return (\n * <div>\n * <nav>\n * {items.map((item) => (\n * <button key={item.id} {...getItemProps(item.id)}>{item.label}</button>\n * ))}\n * </nav>\n * <Outlet />\n * </div>\n * );\n * ```\n */\nexport function usePivot<TId extends string = string>(options: UsePivotOptions<TId>): UsePivotResult<TId> {\n const { items, activeId: controlledActiveId, defaultActiveId, onActiveChange, transitionMode = \"css\" } = options;\n\n const isControlled = controlledActiveId !== undefined;\n\n const [uncontrolledActiveId, setUncontrolledActiveId] = React.useState<TId>(() => {\n if (defaultActiveId !== undefined) {\n return defaultActiveId;\n }\n const firstEnabled = items.find((item) => item.disabled !== true);\n if (!firstEnabled) {\n throw new Error(\"usePivot: No enabled items provided\");\n }\n return firstEnabled.id;\n });\n\n const activeId = isControlled ? controlledActiveId : uncontrolledActiveId;\n\n const setActiveId = React.useCallback(\n (id: TId) => {\n const target = items.find((item) => item.id === id);\n if (!target) {\n return;\n }\n if (target.disabled) {\n return;\n }\n if (!isControlled) {\n setUncontrolledActiveId(id);\n }\n onActiveChange?.(id);\n },\n [items, isControlled, onActiveChange],\n );\n\n const isActive = React.useCallback((id: TId): boolean => id === activeId, [activeId]);\n\n const getItemProps = React.useCallback(\n (id: TId): PivotItemProps => ({\n \"data-pivot-item\": id,\n \"data-active\": (id === activeId ? \"true\" : \"false\") as \"true\" | \"false\",\n \"aria-selected\": id === activeId,\n tabIndex: id === activeId ? 0 : -1,\n onClick: () => {\n setActiveId(id);\n },\n }),\n [activeId, setActiveId],\n );\n\n const containerStyle: React.CSSProperties = React.useMemo(\n () => ({\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n }),\n [],\n );\n\n // Store state in a ref for stable getState function\n const stateRef = React.useRef({\n items,\n activeId,\n transitionMode,\n });\n\n // Update ref when state changes\n stateRef.current = {\n items,\n activeId,\n transitionMode,\n };\n\n // Subscribers for state changes\n const subscribersRef = React.useRef(new Set<() => void>());\n\n // Notify subscribers when activeId changes\n React.useEffect(() => {\n subscribersRef.current.forEach((callback) => callback());\n }, [activeId, transitionMode]);\n\n // Content resolver for useContentCache\n const resolveContent = React.useCallback(\n (itemId: string): React.ReactNode | null => {\n const item = stateRef.current.items.find((i) => i.id === itemId);\n return item?.content ?? null;\n },\n [],\n );\n\n // Valid IDs for cache cleanup (cast to string[] for useContentCache compatibility)\n const validIds = React.useMemo((): readonly string[] => items.map((i) => i.id), [items]);\n\n // Use shared content cache hook\n const { getCachedContent } = useContentCache({\n resolveContent,\n validIds,\n });\n\n // Stable context value (never changes)\n const contextValue = React.useMemo<PivotOutletContextValue>(\n () => ({\n getState: () => stateRef.current,\n subscribe: (callback) => {\n subscribersRef.current.add(callback);\n return () => subscribersRef.current.delete(callback);\n },\n getCachedContent,\n }),\n [getCachedContent],\n );\n\n // Stable Outlet component (reference never changes)\n const Outlet = React.useMemo(() => {\n const OutletComponent: React.FC = () => (\n <PivotOutletContext.Provider value={contextValue}>\n <div style={containerStyle} data-pivot-container>\n <PivotOutletInner />\n </div>\n </PivotOutletContext.Provider>\n );\n OutletComponent.displayName = \"PivotOutlet\";\n return OutletComponent;\n }, [contextValue, containerStyle]);\n\n return { activeId, setActiveId, isActive, getItemProps, Outlet };\n}\n"],"names":["useContentCache","options","resolveContent","validIds","cacheRef","React","resolveContentRef","getCachedContent","id","cached","content","clearCache","currentValidIds","_","baseStyle","PivotContent","isActive","transitionMode","children","ref","prevActiveRef","useIsomorphicLayoutEffect","el","wasActive","style","s","PIVOT_ANIMATION_ENTER","PIVOT_ANIMATION_LEAVE","jsx","PivotOutletContext","PivotOutletInner","ctx","forceUpdate","x","items","activeId","Fragment","item","usePivot","controlledActiveId","defaultActiveId","onActiveChange","isControlled","uncontrolledActiveId","setUncontrolledActiveId","firstEnabled","setActiveId","target","getItemProps","containerStyle","stateRef","subscribersRef","callback","itemId","i","contextValue","Outlet","OutletComponent"],"mappings":"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"}
@@ -0,0 +1,124 @@
1
+ import { jsx as f, Fragment as x } from "react/jsx-runtime";
2
+ import * as e from "react";
3
+ import { P as A, n as N } from "./styles-CA2_zLZt.js";
4
+ import { u as S } from "./useIsomorphicLayoutEffect-DhmEnmZ_.js";
5
+ function k(a) {
6
+ const { resolveContent: n, validIds: c } = a, s = e.useRef(/* @__PURE__ */ new Map()), i = e.useRef(n);
7
+ i.current = n;
8
+ const r = e.useCallback((l) => {
9
+ const u = s.current.get(l);
10
+ if (u !== void 0)
11
+ return u;
12
+ const o = i.current(l);
13
+ return s.current.set(l, o), o;
14
+ }, []), d = e.useCallback(() => {
15
+ s.current.clear();
16
+ }, []);
17
+ return e.useEffect(() => {
18
+ const l = new Set(c);
19
+ s.current.forEach((u, o) => {
20
+ l.has(o) || s.current.delete(o);
21
+ });
22
+ }, [c]), { getCachedContent: r, clearCache: d };
23
+ }
24
+ const M = {
25
+ position: "absolute",
26
+ inset: 0,
27
+ width: "100%",
28
+ height: "100%"
29
+ }, T = e.memo(({ id: a, isActive: n, transitionMode: c, children: s }) => {
30
+ const i = e.useRef(null), r = e.useRef(n);
31
+ S(() => {
32
+ if (c !== "css" || !i.current)
33
+ return;
34
+ const u = i.current, o = r.current;
35
+ r.current = n, o !== n && (u.style.animation = "none", u.offsetHeight, u.style.animation = "");
36
+ }, [n, c]);
37
+ const d = e.useMemo(() => {
38
+ const u = {
39
+ ...M,
40
+ pointerEvents: n ? "auto" : "none",
41
+ opacity: n ? 1 : 0
42
+ };
43
+ return c === "css" && (u.animation = n ? A : N), u;
44
+ }, [n, c]), l = /* @__PURE__ */ f("div", { ref: i, "data-pivot-content": a, "data-active": n ? "true" : "false", style: d, children: s });
45
+ return c === "none" ? /* @__PURE__ */ f(e.Activity, { mode: n ? "visible" : "hidden", children: l }) : l;
46
+ }), R = e.createContext(null), V = e.memo(() => {
47
+ const a = e.useContext(R);
48
+ if (!a)
49
+ throw new Error("PivotOutlet must be used within usePivot");
50
+ const [, n] = e.useReducer((r) => r + 1, 0);
51
+ e.useEffect(() => a.subscribe(n), [a]);
52
+ const { items: c, activeId: s, transitionMode: i } = a.getState();
53
+ return /* @__PURE__ */ f(x, { children: c.map((r) => /* @__PURE__ */ f(T, { id: r.id, isActive: r.id === s, transitionMode: i, children: r.cache ? a.getCachedContent(r.id) : r.content }, r.id)) });
54
+ });
55
+ function j(a) {
56
+ const { items: n, activeId: c, defaultActiveId: s, onActiveChange: i, transitionMode: r = "css" } = a, d = c !== void 0, [l, u] = e.useState(() => {
57
+ if (s !== void 0)
58
+ return s;
59
+ const t = n.find((v) => v.disabled !== !0);
60
+ if (!t)
61
+ throw new Error("usePivot: No enabled items provided");
62
+ return t.id;
63
+ }), o = d ? c : l, m = e.useCallback(
64
+ (t) => {
65
+ const v = n.find((p) => p.id === t);
66
+ v && (v.disabled || (d || u(t), i?.(t)));
67
+ },
68
+ [n, d, i]
69
+ ), g = e.useCallback((t) => t === o, [o]), P = e.useCallback(
70
+ (t) => ({
71
+ "data-pivot-item": t,
72
+ "data-active": t === o ? "true" : "false",
73
+ "aria-selected": t === o,
74
+ tabIndex: t === o ? 0 : -1,
75
+ onClick: () => {
76
+ m(t);
77
+ }
78
+ }),
79
+ [o, m]
80
+ ), I = e.useMemo(
81
+ () => ({
82
+ position: "relative",
83
+ width: "100%",
84
+ height: "100%"
85
+ }),
86
+ []
87
+ ), h = e.useRef({
88
+ items: n,
89
+ activeId: o,
90
+ transitionMode: r
91
+ });
92
+ h.current = {
93
+ items: n,
94
+ activeId: o,
95
+ transitionMode: r
96
+ };
97
+ const C = e.useRef(/* @__PURE__ */ new Set());
98
+ e.useEffect(() => {
99
+ C.current.forEach((t) => t());
100
+ }, [o, r]);
101
+ const w = e.useCallback(
102
+ (t) => h.current.items.find((p) => p.id === t)?.content ?? null,
103
+ []
104
+ ), y = e.useMemo(() => n.map((t) => t.id), [n]), { getCachedContent: b } = k({
105
+ resolveContent: w,
106
+ validIds: y
107
+ }), E = e.useMemo(
108
+ () => ({
109
+ getState: () => h.current,
110
+ subscribe: (t) => (C.current.add(t), () => C.current.delete(t)),
111
+ getCachedContent: b
112
+ }),
113
+ [b]
114
+ ), O = e.useMemo(() => {
115
+ const t = () => /* @__PURE__ */ f(R.Provider, { value: E, children: /* @__PURE__ */ f("div", { style: I, "data-pivot-container": !0, children: /* @__PURE__ */ f(V, {}) }) });
116
+ return t.displayName = "PivotOutlet", t;
117
+ }, [E, I]);
118
+ return { activeId: o, setActiveId: m, isActive: g, getItemProps: P, Outlet: O };
119
+ }
120
+ export {
121
+ k as a,
122
+ j as u
123
+ };
124
+ //# sourceMappingURL=usePivot-CgQxB8rc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePivot-CgQxB8rc.js","sources":["../src/hooks/useContentCache.tsx","../src/modules/pivot/PivotContent.tsx","../src/modules/pivot/usePivot.tsx"],"sourcesContent":["/**\n * @file Shared content caching hook for preserving React component state.\n *\n * This hook provides a common pattern for caching ReactNode content by ID,\n * ensuring the same reference is returned for the same ID across re-renders.\n * This prevents component remounting when parent components re-create content arrays.\n *\n * Used by:\n * - PanelSystemContext (GridLayout layer content)\n * - usePivot (Pivot item content)\n * - ContentRegistry (Panel content)\n */\nimport * as React from \"react\";\n\n/**\n * Function type for resolving content by ID.\n * Called only when content is not already cached.\n */\nexport type ContentResolver<TId extends string = string> = (id: TId) => React.ReactNode | null;\n\n/**\n * Options for useContentCache hook.\n */\nexport type UseContentCacheOptions<TId extends string = string> = {\n /**\n * Function to resolve content by ID.\n * Called only when content is not already in cache.\n */\n resolveContent: ContentResolver<TId>;\n /**\n * Current valid IDs. Used to clean up stale cache entries.\n * When an ID is removed from this array, its cached content is deleted.\n */\n validIds: readonly TId[];\n};\n\n/**\n * Result from useContentCache hook.\n */\nexport type UseContentCacheResult<TId extends string = string> = {\n /**\n * Get cached content for an ID.\n * Returns the same ReactNode reference for the same ID.\n */\n getCachedContent: (id: TId) => React.ReactNode | null;\n /**\n * Clear all cached content.\n * Use when you need to force re-creation of all content.\n */\n clearCache: () => void;\n};\n\n/**\n * Hook for caching ReactNode content by ID.\n *\n * Ensures the same ReactNode reference is returned for the same ID,\n * preventing unnecessary component remounting when parent re-renders.\n *\n * @example\n * ```tsx\n * const { getCachedContent } = useContentCache({\n * resolveContent: (id) => items.find(i => i.id === id)?.content ?? null,\n * validIds: items.map(i => i.id),\n * });\n *\n * return items.map(item => (\n * <div key={item.id}>{getCachedContent(item.id)}</div>\n * ));\n * ```\n */\nexport function useContentCache<TId extends string = string>(\n options: UseContentCacheOptions<TId>,\n): UseContentCacheResult<TId> {\n const { resolveContent, validIds } = options;\n\n /**\n * Cache storage. Key: ID, Value: cached ReactNode.\n * Uses ref to persist across re-renders without triggering updates.\n */\n const cacheRef = React.useRef<Map<string, React.ReactNode>>(new Map());\n\n /**\n * Store resolveContent in a ref for stable getCachedContent function.\n * This allows getCachedContent to always use the latest resolver\n * without needing to be recreated.\n */\n const resolveContentRef = React.useRef(resolveContent);\n resolveContentRef.current = resolveContent;\n\n /**\n * Get or create cached content for an ID.\n * On first access, calls resolveContent and caches the result.\n * On subsequent accesses, returns the cached reference.\n */\n const getCachedContent = React.useCallback((id: TId): React.ReactNode | null => {\n const cached = cacheRef.current.get(id);\n if (cached !== undefined) {\n return cached;\n }\n\n const content = resolveContentRef.current(id);\n cacheRef.current.set(id, content);\n return content;\n }, []);\n\n /**\n * Clear all cached content.\n */\n const clearCache = React.useCallback((): void => {\n cacheRef.current.clear();\n }, []);\n\n /**\n * Clean up stale cache entries when validIds changes.\n * Removes entries for IDs that are no longer valid.\n */\n React.useEffect(() => {\n const currentValidIds = new Set<string>(validIds);\n cacheRef.current.forEach((_, id) => {\n if (!currentValidIds.has(id)) {\n cacheRef.current.delete(id);\n }\n });\n }, [validIds]);\n\n return { getCachedContent, clearCache };\n}\n","/**\n * @file PivotContent component for rendering pivot items with CSS animations.\n *\n * Override via CSS custom properties:\n * - --rpl-pivot-animation-enter: Animation when becoming active\n * - --rpl-pivot-animation-leave: Animation when becoming inactive\n *\n * User defines @keyframes in their CSS and references via these tokens.\n * Example:\n * @keyframes pivotEnter {\n * from { opacity: 0; }\n * to { opacity: 1; }\n * }\n * :root { --rpl-pivot-animation-enter: pivotEnter 150ms ease-out forwards; }\n */\nimport * as React from \"react\";\nimport { PIVOT_ANIMATION_ENTER, PIVOT_ANIMATION_LEAVE } from \"../../constants/styles\";\nimport { useIsomorphicLayoutEffect } from \"../../hooks/useIsomorphicLayoutEffect\";\n\nexport type PivotContentProps = {\n id: string;\n isActive: boolean;\n transitionMode: \"css\" | \"none\";\n children: React.ReactNode;\n};\n\nconst baseStyle: React.CSSProperties = {\n position: \"absolute\",\n inset: 0,\n width: \"100%\",\n height: \"100%\",\n};\n\n/**\n * Renders pivot content with CSS animation support.\n *\n * When transitionMode=\"css\": Applies enter/leave animations.\n * When transitionMode=\"none\": Uses React.Activity for memory optimization.\n */\nexport const PivotContent: React.FC<PivotContentProps> = React.memo(({ id, isActive, transitionMode, children }) => {\n const ref = React.useRef<HTMLDivElement>(null);\n const prevActiveRef = React.useRef(isActive);\n\n // Restart animation on state change by removing and re-adding animation\n useIsomorphicLayoutEffect(() => {\n if (transitionMode !== \"css\" || !ref.current) {\n return;\n }\n\n const el = ref.current;\n const wasActive = prevActiveRef.current;\n prevActiveRef.current = isActive;\n\n // Only restart if state actually changed\n if (wasActive === isActive) {\n return;\n }\n\n // Force animation restart: remove animation, trigger reflow, re-add\n el.style.animation = \"none\";\n void el.offsetHeight; // Force reflow\n el.style.animation = \"\";\n }, [isActive, transitionMode]);\n\n const style = React.useMemo<React.CSSProperties>(() => {\n const s: React.CSSProperties = {\n ...baseStyle,\n pointerEvents: isActive ? \"auto\" : \"none\",\n opacity: isActive ? 1 : 0,\n };\n\n if (transitionMode === \"css\") {\n s.animation = isActive ? PIVOT_ANIMATION_ENTER : PIVOT_ANIMATION_LEAVE;\n }\n\n return s;\n }, [isActive, transitionMode]);\n\n const content = (\n <div ref={ref} data-pivot-content={id} data-active={isActive ? \"true\" : \"false\"} style={style}>\n {children}\n </div>\n );\n\n if (transitionMode === \"none\") {\n return <React.Activity mode={isActive ? \"visible\" : \"hidden\"}>{content}</React.Activity>;\n }\n\n return content;\n});\n","/**\n * @file Headless hook for managing Pivot (content switching) behavior.\n *\n * Includes content caching to preserve React component state across re-renders.\n * This is essential for maintaining internal state when parent components\n * re-create the items array.\n */\nimport * as React from \"react\";\nimport type { UsePivotOptions, UsePivotResult, PivotItemProps, PivotItem } from \"./types\";\nimport { PivotContent } from \"./PivotContent\";\nimport { useContentCache } from \"../../hooks/useContentCache\";\n\n/**\n * Context for sharing pivot state with Outlet component.\n * Uses a ref-based approach to avoid re-creating the Outlet component.\n * Includes content cache to preserve component state.\n */\ntype PivotOutletContextValue = {\n getState: () => {\n items: ReadonlyArray<PivotItem>;\n activeId: string;\n transitionMode: \"css\" | \"none\";\n };\n subscribe: (callback: () => void) => () => void;\n /**\n * Get cached content for an item. Returns the same ReactNode reference\n * for the same item ID to prevent remounting on parent re-renders.\n */\n getCachedContent: (itemId: string) => React.ReactNode | null;\n};\n\nconst PivotOutletContext = React.createContext<PivotOutletContextValue | null>(null);\n\n/**\n * Stable Outlet component that subscribes to state changes.\n * This prevents remounting when activeId changes.\n * Uses cached content only when item.cache is true.\n */\nconst PivotOutletInner: React.FC = React.memo(() => {\n const ctx = React.useContext(PivotOutletContext);\n if (!ctx) {\n throw new Error(\"PivotOutlet must be used within usePivot\");\n }\n\n const [, forceUpdate] = React.useReducer((x) => x + 1, 0);\n\n React.useEffect(() => {\n return ctx.subscribe(forceUpdate);\n }, [ctx]);\n\n const { items, activeId, transitionMode } = ctx.getState();\n\n return (\n <>\n {items.map((item) => (\n <PivotContent key={item.id} id={item.id} isActive={item.id === activeId} transitionMode={transitionMode}>\n {item.cache ? ctx.getCachedContent(item.id) : item.content}\n </PivotContent>\n ))}\n </>\n );\n});\n\n/**\n * Headless hook for managing content switching within a scope.\n * Provides behavior only - UI is fully customizable.\n *\n * @example\n * ```tsx\n * const { activeId, getItemProps, Outlet } = usePivot({\n * items: [\n * { id: 'home', label: 'Home', content: <HomePage /> },\n * { id: 'settings', label: 'Settings', content: <SettingsPage /> }\n * ],\n * defaultActiveId: 'home'\n * });\n *\n * return (\n * <div>\n * <nav>\n * {items.map((item) => (\n * <button key={item.id} {...getItemProps(item.id)}>{item.label}</button>\n * ))}\n * </nav>\n * <Outlet />\n * </div>\n * );\n * ```\n */\nexport function usePivot<TId extends string = string>(options: UsePivotOptions<TId>): UsePivotResult<TId> {\n const { items, activeId: controlledActiveId, defaultActiveId, onActiveChange, transitionMode = \"css\" } = options;\n\n const isControlled = controlledActiveId !== undefined;\n\n const [uncontrolledActiveId, setUncontrolledActiveId] = React.useState<TId>(() => {\n if (defaultActiveId !== undefined) {\n return defaultActiveId;\n }\n const firstEnabled = items.find((item) => item.disabled !== true);\n if (!firstEnabled) {\n throw new Error(\"usePivot: No enabled items provided\");\n }\n return firstEnabled.id;\n });\n\n const activeId = isControlled ? controlledActiveId : uncontrolledActiveId;\n\n const setActiveId = React.useCallback(\n (id: TId) => {\n const target = items.find((item) => item.id === id);\n if (!target) {\n return;\n }\n if (target.disabled) {\n return;\n }\n if (!isControlled) {\n setUncontrolledActiveId(id);\n }\n onActiveChange?.(id);\n },\n [items, isControlled, onActiveChange],\n );\n\n const isActive = React.useCallback((id: TId): boolean => id === activeId, [activeId]);\n\n const getItemProps = React.useCallback(\n (id: TId): PivotItemProps => ({\n \"data-pivot-item\": id,\n \"data-active\": (id === activeId ? \"true\" : \"false\") as \"true\" | \"false\",\n \"aria-selected\": id === activeId,\n tabIndex: id === activeId ? 0 : -1,\n onClick: () => {\n setActiveId(id);\n },\n }),\n [activeId, setActiveId],\n );\n\n const containerStyle: React.CSSProperties = React.useMemo(\n () => ({\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n }),\n [],\n );\n\n // Store state in a ref for stable getState function\n const stateRef = React.useRef({\n items,\n activeId,\n transitionMode,\n });\n\n // Update ref when state changes\n stateRef.current = {\n items,\n activeId,\n transitionMode,\n };\n\n // Subscribers for state changes\n const subscribersRef = React.useRef(new Set<() => void>());\n\n // Notify subscribers when activeId changes\n React.useEffect(() => {\n subscribersRef.current.forEach((callback) => callback());\n }, [activeId, transitionMode]);\n\n // Content resolver for useContentCache\n const resolveContent = React.useCallback(\n (itemId: string): React.ReactNode | null => {\n const item = stateRef.current.items.find((i) => i.id === itemId);\n return item?.content ?? null;\n },\n [],\n );\n\n // Valid IDs for cache cleanup (cast to string[] for useContentCache compatibility)\n const validIds = React.useMemo((): readonly string[] => items.map((i) => i.id), [items]);\n\n // Use shared content cache hook\n const { getCachedContent } = useContentCache({\n resolveContent,\n validIds,\n });\n\n // Stable context value (never changes)\n const contextValue = React.useMemo<PivotOutletContextValue>(\n () => ({\n getState: () => stateRef.current,\n subscribe: (callback) => {\n subscribersRef.current.add(callback);\n return () => subscribersRef.current.delete(callback);\n },\n getCachedContent,\n }),\n [getCachedContent],\n );\n\n // Stable Outlet component (reference never changes)\n const Outlet = React.useMemo(() => {\n const OutletComponent: React.FC = () => (\n <PivotOutletContext.Provider value={contextValue}>\n <div style={containerStyle} data-pivot-container>\n <PivotOutletInner />\n </div>\n </PivotOutletContext.Provider>\n );\n OutletComponent.displayName = \"PivotOutlet\";\n return OutletComponent;\n }, [contextValue, containerStyle]);\n\n return { activeId, setActiveId, isActive, getItemProps, Outlet };\n}\n"],"names":["useContentCache","options","resolveContent","validIds","cacheRef","React","resolveContentRef","getCachedContent","id","cached","content","clearCache","currentValidIds","_","baseStyle","PivotContent","isActive","transitionMode","children","ref","prevActiveRef","useIsomorphicLayoutEffect","el","wasActive","style","s","PIVOT_ANIMATION_ENTER","PIVOT_ANIMATION_LEAVE","jsx","PivotOutletContext","PivotOutletInner","ctx","forceUpdate","x","items","activeId","Fragment","item","usePivot","controlledActiveId","defaultActiveId","onActiveChange","isControlled","uncontrolledActiveId","setUncontrolledActiveId","firstEnabled","setActiveId","target","getItemProps","containerStyle","stateRef","subscribersRef","callback","itemId","i","contextValue","Outlet","OutletComponent"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-panel-layout",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "license": "Unlicense",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -35,6 +35,11 @@
35
35
  "import": "./dist/pivot.js",
36
36
  "require": "./dist/pivot.cjs"
37
37
  },
38
+ "./sticky-header": {
39
+ "types": "./dist/sticky-header/index.d.ts",
40
+ "import": "./dist/sticky-header.js",
41
+ "require": "./dist/sticky-header.cjs"
42
+ },
38
43
  "./package.json": "./package.json"
39
44
  },
40
45
  "files": [
@@ -1,66 +0,0 @@
1
- import { jsx as o } from "react/jsx-runtime";
2
- import * as n from "react";
3
- import { F as r, a as d, b as i, c as _, d as c, e as N, f as A, g as F, h as m, i as P, j as L, k as y } from "./styles-w0ZixggV.js";
4
- const O = {
5
- display: "flex",
6
- flexDirection: "column",
7
- borderRadius: _,
8
- border: `1px solid ${i}`,
9
- background: d,
10
- boxShadow: r
11
- }, g = {
12
- display: "flex",
13
- alignItems: "center",
14
- gap: F,
15
- padding: `${N} ${A}`,
16
- borderBottom: `1px solid ${i}`,
17
- background: c
18
- }, E = {
19
- fontWeight: 600
20
- }, u = {
21
- marginLeft: "auto",
22
- color: P,
23
- fontSize: m
24
- }, T = {
25
- display: "flex",
26
- alignItems: "center",
27
- gap: L
28
- }, f = {
29
- padding: y,
30
- overflow: "auto"
31
- }, I = n.forwardRef(function({ style: t, ...a }, s) {
32
- const l = n.useMemo(() => ({ ...O, ...t }), [t]);
33
- return /* @__PURE__ */ o("div", { ref: s, style: l, ...a });
34
- }), G = ({ style: e, ...t }) => {
35
- const a = n.useMemo(() => ({ ...g, ...e }), [e]);
36
- return /* @__PURE__ */ o("div", { style: a, ...t });
37
- }, R = ({ style: e, ...t }) => {
38
- const a = n.useMemo(() => ({ ...E, ...e }), [e]);
39
- return /* @__PURE__ */ o("span", { style: a, ...t });
40
- }, b = ({ style: e, ...t }) => {
41
- const a = n.useMemo(() => ({ ...u, ...e }), [e]);
42
- return /* @__PURE__ */ o("span", { style: a, ...t });
43
- }, D = ({ style: e, ...t }) => {
44
- const a = n.useMemo(() => ({ ...T, ...e }), [e]);
45
- return /* @__PURE__ */ o("div", { style: a, ...t });
46
- }, S = n.forwardRef(
47
- function({ style: t, ...a }, s) {
48
- const l = n.useMemo(() => ({ ...f, ...t }), [t]);
49
- return /* @__PURE__ */ o("div", { ref: s, style: l, ...a });
50
- }
51
- );
52
- I.displayName = "FloatingPanelFrame";
53
- G.displayName = "FloatingPanelHeader";
54
- R.displayName = "FloatingPanelTitle";
55
- b.displayName = "FloatingPanelMeta";
56
- D.displayName = "FloatingPanelControls";
57
- S.displayName = "FloatingPanelContent";
58
- export {
59
- I as F,
60
- G as a,
61
- R as b,
62
- b as c,
63
- D as d,
64
- S as e
65
- };
66
- //# sourceMappingURL=FloatingPanelFrame-DDT6aING.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FloatingPanelFrame-DDT6aING.js","sources":["../src/components/paneling/FloatingPanelFrame.tsx"],"sourcesContent":["/**\n * @file Shared floating panel frame components for reusable overlay styling\n */\nimport * as React from \"react\";\nimport {\n FLOATING_PANEL_BORDER_RADIUS,\n FLOATING_PANEL_GAP,\n FLOATING_PANEL_HEADER_PADDING_Y,\n FLOATING_PANEL_HEADER_PADDING_X,\n FLOATING_PANEL_CONTENT_PADDING,\n FLOATING_PANEL_META_FONT_SIZE,\n FLOATING_PANEL_CONTROLS_GAP,\n FLOATING_PANEL_SURFACE_COLOR,\n FLOATING_PANEL_SURFACE_2_COLOR,\n FLOATING_PANEL_BORDER_COLOR,\n FLOATING_PANEL_MUTED_FG_COLOR,\n FLOATING_PANEL_SHADOW,\n} from \"../../constants/styles\";\n\nconst frameStyle: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n borderRadius: FLOATING_PANEL_BORDER_RADIUS,\n border: `1px solid ${FLOATING_PANEL_BORDER_COLOR}`,\n background: FLOATING_PANEL_SURFACE_COLOR,\n boxShadow: FLOATING_PANEL_SHADOW,\n};\n\nconst headerStyle: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n gap: FLOATING_PANEL_GAP,\n padding: `${FLOATING_PANEL_HEADER_PADDING_Y} ${FLOATING_PANEL_HEADER_PADDING_X}`,\n borderBottom: `1px solid ${FLOATING_PANEL_BORDER_COLOR}`,\n background: FLOATING_PANEL_SURFACE_2_COLOR,\n};\n\nconst titleStyle: React.CSSProperties = {\n fontWeight: 600,\n};\n\nconst metaStyle: React.CSSProperties = {\n marginLeft: \"auto\",\n color: FLOATING_PANEL_MUTED_FG_COLOR,\n fontSize: FLOATING_PANEL_META_FONT_SIZE,\n};\n\nconst controlsStyle: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n gap: FLOATING_PANEL_CONTROLS_GAP,\n};\n\nconst contentStyle: React.CSSProperties = {\n padding: FLOATING_PANEL_CONTENT_PADDING,\n overflow: \"auto\",\n};\n\nexport type FloatingPanelFrameProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"className\" | \"style\"> & {\n style?: React.CSSProperties;\n};\n\nexport const FloatingPanelFrame = React.forwardRef<HTMLDivElement, FloatingPanelFrameProps>(function FloatingPanelFrame(\n { style: propStyle, ...props },\n ref,\n) {\n const combinedStyle = React.useMemo(() => ({ ...frameStyle, ...propStyle }), [propStyle]);\n return <div ref={ref} style={combinedStyle} {...props} />;\n});\n\nexport type FloatingPanelHeaderProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"className\" | \"style\"> & {\n style?: React.CSSProperties;\n};\n\nexport const FloatingPanelHeader: React.FC<FloatingPanelHeaderProps> = ({ style: propStyle, ...props }) => {\n const combinedStyle = React.useMemo(() => ({ ...headerStyle, ...propStyle }), [propStyle]);\n return <div style={combinedStyle} {...props} />;\n};\n\nexport type FloatingPanelTitleProps = Omit<React.HTMLAttributes<HTMLSpanElement>, \"className\" | \"style\"> & {\n style?: React.CSSProperties;\n};\n\nexport const FloatingPanelTitle: React.FC<FloatingPanelTitleProps> = ({ style: propStyle, ...props }) => {\n const combinedStyle = React.useMemo(() => ({ ...titleStyle, ...propStyle }), [propStyle]);\n return <span style={combinedStyle} {...props} />;\n};\n\nexport type FloatingPanelMetaProps = Omit<React.HTMLAttributes<HTMLSpanElement>, \"className\" | \"style\"> & {\n style?: React.CSSProperties;\n};\n\nexport const FloatingPanelMeta: React.FC<FloatingPanelMetaProps> = ({ style: propStyle, ...props }) => {\n const combinedStyle = React.useMemo(() => ({ ...metaStyle, ...propStyle }), [propStyle]);\n return <span style={combinedStyle} {...props} />;\n};\n\nexport type FloatingPanelControlsProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"className\" | \"style\"> & {\n style?: React.CSSProperties;\n};\n\nexport const FloatingPanelControls: React.FC<FloatingPanelControlsProps> = ({ style: propStyle, ...props }) => {\n const combinedStyle = React.useMemo(() => ({ ...controlsStyle, ...propStyle }), [propStyle]);\n return <div style={combinedStyle} {...props} />;\n};\n\nexport type FloatingPanelContentProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"className\" | \"style\"> & {\n style?: React.CSSProperties;\n};\n\nexport const FloatingPanelContent = React.forwardRef<HTMLDivElement, FloatingPanelContentProps>(\n function FloatingPanelContent({ style: propStyle, ...props }, ref) {\n const combinedStyle = React.useMemo(() => ({ ...contentStyle, ...propStyle }), [propStyle]);\n return <div ref={ref} style={combinedStyle} {...props} />;\n },\n);\n\nFloatingPanelFrame.displayName = \"FloatingPanelFrame\";\nFloatingPanelHeader.displayName = \"FloatingPanelHeader\";\nFloatingPanelTitle.displayName = \"FloatingPanelTitle\";\nFloatingPanelMeta.displayName = \"FloatingPanelMeta\";\nFloatingPanelControls.displayName = \"FloatingPanelControls\";\nFloatingPanelContent.displayName = \"FloatingPanelContent\";\n"],"names":["frameStyle","FLOATING_PANEL_BORDER_RADIUS","FLOATING_PANEL_BORDER_COLOR","FLOATING_PANEL_SURFACE_COLOR","FLOATING_PANEL_SHADOW","headerStyle","FLOATING_PANEL_GAP","FLOATING_PANEL_HEADER_PADDING_Y","FLOATING_PANEL_HEADER_PADDING_X","FLOATING_PANEL_SURFACE_2_COLOR","titleStyle","metaStyle","FLOATING_PANEL_MUTED_FG_COLOR","FLOATING_PANEL_META_FONT_SIZE","controlsStyle","FLOATING_PANEL_CONTROLS_GAP","contentStyle","FLOATING_PANEL_CONTENT_PADDING","FloatingPanelFrame","React","propStyle","props","ref","combinedStyle","FloatingPanelHeader","jsx","FloatingPanelTitle","FloatingPanelMeta","FloatingPanelControls","FloatingPanelContent"],"mappings":";;;AAmBA,MAAMA,IAAkC;AAAA,EACtC,SAAS;AAAA,EACT,eAAe;AAAA,EACf,cAAcC;AAAA,EACd,QAAQ,aAAaC,CAA2B;AAAA,EAChD,YAAYC;AAAA,EACZ,WAAWC;AACb,GAEMC,IAAmC;AAAA,EACvC,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,KAAKC;AAAA,EACL,SAAS,GAAGC,CAA+B,IAAIC,CAA+B;AAAA,EAC9E,cAAc,aAAaN,CAA2B;AAAA,EACtD,YAAYO;AACd,GAEMC,IAAkC;AAAA,EACtC,YAAY;AACd,GAEMC,IAAiC;AAAA,EACrC,YAAY;AAAA,EACZ,OAAOC;AAAA,EACP,UAAUC;AACZ,GAEMC,IAAqC;AAAA,EACzC,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,KAAKC;AACP,GAEMC,IAAoC;AAAA,EACxC,SAASC;AAAA,EACT,UAAU;AACZ,GAMaC,IAAqBC,EAAM,WAAoD,SAC1F,EAAE,OAAOC,GAAW,GAAGC,EAAA,GACvBC,GACA;AACA,QAAMC,IAAgBJ,EAAM,QAAQ,OAAO,EAAE,GAAGnB,GAAY,GAAGoB,EAAA,IAAc,CAACA,CAAS,CAAC;AACxF,2BAAQ,OAAA,EAAI,KAAAE,GAAU,OAAOC,GAAgB,GAAGF,GAAO;AACzD,CAAC,GAMYG,IAA0D,CAAC,EAAE,OAAOJ,GAAW,GAAGC,QAAY;AACzG,QAAME,IAAgBJ,EAAM,QAAQ,OAAO,EAAE,GAAGd,GAAa,GAAGe,EAAA,IAAc,CAACA,CAAS,CAAC;AACzF,SAAO,gBAAAK,EAAC,OAAA,EAAI,OAAOF,GAAgB,GAAGF,GAAO;AAC/C,GAMaK,IAAwD,CAAC,EAAE,OAAON,GAAW,GAAGC,QAAY;AACvG,QAAME,IAAgBJ,EAAM,QAAQ,OAAO,EAAE,GAAGT,GAAY,GAAGU,EAAA,IAAc,CAACA,CAAS,CAAC;AACxF,SAAO,gBAAAK,EAAC,QAAA,EAAK,OAAOF,GAAgB,GAAGF,GAAO;AAChD,GAMaM,IAAsD,CAAC,EAAE,OAAOP,GAAW,GAAGC,QAAY;AACrG,QAAME,IAAgBJ,EAAM,QAAQ,OAAO,EAAE,GAAGR,GAAW,GAAGS,EAAA,IAAc,CAACA,CAAS,CAAC;AACvF,SAAO,gBAAAK,EAAC,QAAA,EAAK,OAAOF,GAAgB,GAAGF,GAAO;AAChD,GAMaO,IAA8D,CAAC,EAAE,OAAOR,GAAW,GAAGC,QAAY;AAC7G,QAAME,IAAgBJ,EAAM,QAAQ,OAAO,EAAE,GAAGL,GAAe,GAAGM,EAAA,IAAc,CAACA,CAAS,CAAC;AAC3F,SAAO,gBAAAK,EAAC,OAAA,EAAI,OAAOF,GAAgB,GAAGF,GAAO;AAC/C,GAMaQ,IAAuBV,EAAM;AAAA,EACxC,SAA8B,EAAE,OAAOC,GAAW,GAAGC,EAAA,GAASC,GAAK;AACjE,UAAMC,IAAgBJ,EAAM,QAAQ,OAAO,EAAE,GAAGH,GAAc,GAAGI,EAAA,IAAc,CAACA,CAAS,CAAC;AAC1F,6BAAQ,OAAA,EAAI,KAAAE,GAAU,OAAOC,GAAgB,GAAGF,GAAO;AAAA,EACzD;AACF;AAEAH,EAAmB,cAAc;AACjCM,EAAoB,cAAc;AAClCE,EAAmB,cAAc;AACjCC,EAAkB,cAAc;AAChCC,EAAsB,cAAc;AACpCC,EAAqB,cAAc;"}
@@ -1,2 +0,0 @@
1
- "use strict";const s=require("react/jsx-runtime"),P=require("react"),a=require("./styles-DcG3aIFx.cjs");function A(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const l=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,l.get?l:{enumerable:!0,get:()=>e[n]})}}return t.default=e,Object.freeze(t)}const o=A(P),O={display:"flex",flexDirection:"column",borderRadius:a.FLOATING_PANEL_BORDER_RADIUS,border:`1px solid ${a.FLOATING_PANEL_BORDER_COLOR}`,background:a.FLOATING_PANEL_SURFACE_COLOR,boxShadow:a.FLOATING_PANEL_SHADOW},g={display:"flex",alignItems:"center",gap:a.FLOATING_PANEL_GAP,padding:`${a.FLOATING_PANEL_HEADER_PADDING_Y} ${a.FLOATING_PANEL_HEADER_PADDING_X}`,borderBottom:`1px solid ${a.FLOATING_PANEL_BORDER_COLOR}`,background:a.FLOATING_PANEL_SURFACE_2_COLOR},u={fontWeight:600},m={marginLeft:"auto",color:a.FLOATING_PANEL_MUTED_FG_COLOR,fontSize:a.FLOATING_PANEL_META_FONT_SIZE},L={display:"flex",alignItems:"center",gap:a.FLOATING_PANEL_CONTROLS_GAP},y={padding:a.FLOATING_PANEL_CONTENT_PADDING,overflow:"auto"},r=o.forwardRef(function({style:t,...n},l){const i=o.useMemo(()=>({...O,...t}),[t]);return s.jsx("div",{ref:l,style:i,...n})}),c=({style:e,...t})=>{const n=o.useMemo(()=>({...g,...e}),[e]);return s.jsx("div",{style:n,...t})},_=({style:e,...t})=>{const n=o.useMemo(()=>({...u,...e}),[e]);return s.jsx("span",{style:n,...t})},d=({style:e,...t})=>{const n=o.useMemo(()=>({...m,...e}),[e]);return s.jsx("span",{style:n,...t})},F=({style:e,...t})=>{const n=o.useMemo(()=>({...L,...e}),[e]);return s.jsx("div",{style:n,...t})},N=o.forwardRef(function({style:t,...n},l){const i=o.useMemo(()=>({...y,...t}),[t]);return s.jsx("div",{ref:l,style:i,...n})});r.displayName="FloatingPanelFrame";c.displayName="FloatingPanelHeader";_.displayName="FloatingPanelTitle";d.displayName="FloatingPanelMeta";F.displayName="FloatingPanelControls";N.displayName="FloatingPanelContent";exports.FloatingPanelContent=N;exports.FloatingPanelControls=F;exports.FloatingPanelFrame=r;exports.FloatingPanelHeader=c;exports.FloatingPanelMeta=d;exports.FloatingPanelTitle=_;
2
- //# sourceMappingURL=FloatingPanelFrame-DrYwgI9f.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FloatingPanelFrame-DrYwgI9f.cjs","sources":["../src/components/paneling/FloatingPanelFrame.tsx"],"sourcesContent":["/**\n * @file Shared floating panel frame components for reusable overlay styling\n */\nimport * as React from \"react\";\nimport {\n FLOATING_PANEL_BORDER_RADIUS,\n FLOATING_PANEL_GAP,\n FLOATING_PANEL_HEADER_PADDING_Y,\n FLOATING_PANEL_HEADER_PADDING_X,\n FLOATING_PANEL_CONTENT_PADDING,\n FLOATING_PANEL_META_FONT_SIZE,\n FLOATING_PANEL_CONTROLS_GAP,\n FLOATING_PANEL_SURFACE_COLOR,\n FLOATING_PANEL_SURFACE_2_COLOR,\n FLOATING_PANEL_BORDER_COLOR,\n FLOATING_PANEL_MUTED_FG_COLOR,\n FLOATING_PANEL_SHADOW,\n} from \"../../constants/styles\";\n\nconst frameStyle: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n borderRadius: FLOATING_PANEL_BORDER_RADIUS,\n border: `1px solid ${FLOATING_PANEL_BORDER_COLOR}`,\n background: FLOATING_PANEL_SURFACE_COLOR,\n boxShadow: FLOATING_PANEL_SHADOW,\n};\n\nconst headerStyle: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n gap: FLOATING_PANEL_GAP,\n padding: `${FLOATING_PANEL_HEADER_PADDING_Y} ${FLOATING_PANEL_HEADER_PADDING_X}`,\n borderBottom: `1px solid ${FLOATING_PANEL_BORDER_COLOR}`,\n background: FLOATING_PANEL_SURFACE_2_COLOR,\n};\n\nconst titleStyle: React.CSSProperties = {\n fontWeight: 600,\n};\n\nconst metaStyle: React.CSSProperties = {\n marginLeft: \"auto\",\n color: FLOATING_PANEL_MUTED_FG_COLOR,\n fontSize: FLOATING_PANEL_META_FONT_SIZE,\n};\n\nconst controlsStyle: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n gap: FLOATING_PANEL_CONTROLS_GAP,\n};\n\nconst contentStyle: React.CSSProperties = {\n padding: FLOATING_PANEL_CONTENT_PADDING,\n overflow: \"auto\",\n};\n\nexport type FloatingPanelFrameProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"className\" | \"style\"> & {\n style?: React.CSSProperties;\n};\n\nexport const FloatingPanelFrame = React.forwardRef<HTMLDivElement, FloatingPanelFrameProps>(function FloatingPanelFrame(\n { style: propStyle, ...props },\n ref,\n) {\n const combinedStyle = React.useMemo(() => ({ ...frameStyle, ...propStyle }), [propStyle]);\n return <div ref={ref} style={combinedStyle} {...props} />;\n});\n\nexport type FloatingPanelHeaderProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"className\" | \"style\"> & {\n style?: React.CSSProperties;\n};\n\nexport const FloatingPanelHeader: React.FC<FloatingPanelHeaderProps> = ({ style: propStyle, ...props }) => {\n const combinedStyle = React.useMemo(() => ({ ...headerStyle, ...propStyle }), [propStyle]);\n return <div style={combinedStyle} {...props} />;\n};\n\nexport type FloatingPanelTitleProps = Omit<React.HTMLAttributes<HTMLSpanElement>, \"className\" | \"style\"> & {\n style?: React.CSSProperties;\n};\n\nexport const FloatingPanelTitle: React.FC<FloatingPanelTitleProps> = ({ style: propStyle, ...props }) => {\n const combinedStyle = React.useMemo(() => ({ ...titleStyle, ...propStyle }), [propStyle]);\n return <span style={combinedStyle} {...props} />;\n};\n\nexport type FloatingPanelMetaProps = Omit<React.HTMLAttributes<HTMLSpanElement>, \"className\" | \"style\"> & {\n style?: React.CSSProperties;\n};\n\nexport const FloatingPanelMeta: React.FC<FloatingPanelMetaProps> = ({ style: propStyle, ...props }) => {\n const combinedStyle = React.useMemo(() => ({ ...metaStyle, ...propStyle }), [propStyle]);\n return <span style={combinedStyle} {...props} />;\n};\n\nexport type FloatingPanelControlsProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"className\" | \"style\"> & {\n style?: React.CSSProperties;\n};\n\nexport const FloatingPanelControls: React.FC<FloatingPanelControlsProps> = ({ style: propStyle, ...props }) => {\n const combinedStyle = React.useMemo(() => ({ ...controlsStyle, ...propStyle }), [propStyle]);\n return <div style={combinedStyle} {...props} />;\n};\n\nexport type FloatingPanelContentProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"className\" | \"style\"> & {\n style?: React.CSSProperties;\n};\n\nexport const FloatingPanelContent = React.forwardRef<HTMLDivElement, FloatingPanelContentProps>(\n function FloatingPanelContent({ style: propStyle, ...props }, ref) {\n const combinedStyle = React.useMemo(() => ({ ...contentStyle, ...propStyle }), [propStyle]);\n return <div ref={ref} style={combinedStyle} {...props} />;\n },\n);\n\nFloatingPanelFrame.displayName = \"FloatingPanelFrame\";\nFloatingPanelHeader.displayName = \"FloatingPanelHeader\";\nFloatingPanelTitle.displayName = \"FloatingPanelTitle\";\nFloatingPanelMeta.displayName = \"FloatingPanelMeta\";\nFloatingPanelControls.displayName = \"FloatingPanelControls\";\nFloatingPanelContent.displayName = \"FloatingPanelContent\";\n"],"names":["frameStyle","FLOATING_PANEL_BORDER_RADIUS","FLOATING_PANEL_BORDER_COLOR","FLOATING_PANEL_SURFACE_COLOR","FLOATING_PANEL_SHADOW","headerStyle","FLOATING_PANEL_GAP","FLOATING_PANEL_HEADER_PADDING_Y","FLOATING_PANEL_HEADER_PADDING_X","FLOATING_PANEL_SURFACE_2_COLOR","titleStyle","metaStyle","FLOATING_PANEL_MUTED_FG_COLOR","FLOATING_PANEL_META_FONT_SIZE","controlsStyle","FLOATING_PANEL_CONTROLS_GAP","contentStyle","FLOATING_PANEL_CONTENT_PADDING","FloatingPanelFrame","React","propStyle","props","ref","combinedStyle","FloatingPanelHeader","jsx","FloatingPanelTitle","FloatingPanelMeta","FloatingPanelControls","FloatingPanelContent"],"mappings":"kYAmBMA,EAAkC,CACtC,QAAS,OACT,cAAe,SACf,aAAcC,EAAAA,6BACd,OAAQ,aAAaC,EAAAA,2BAA2B,GAChD,WAAYC,EAAAA,6BACZ,UAAWC,EAAAA,qBACb,EAEMC,EAAmC,CACvC,QAAS,OACT,WAAY,SACZ,IAAKC,EAAAA,mBACL,QAAS,GAAGC,EAAAA,+BAA+B,IAAIC,EAAAA,+BAA+B,GAC9E,aAAc,aAAaN,EAAAA,2BAA2B,GACtD,WAAYO,EAAAA,8BACd,EAEMC,EAAkC,CACtC,WAAY,GACd,EAEMC,EAAiC,CACrC,WAAY,OACZ,MAAOC,EAAAA,8BACP,SAAUC,EAAAA,6BACZ,EAEMC,EAAqC,CACzC,QAAS,OACT,WAAY,SACZ,IAAKC,EAAAA,2BACP,EAEMC,EAAoC,CACxC,QAASC,EAAAA,+BACT,SAAU,MACZ,EAMaC,EAAqBC,EAAM,WAAoD,SAC1F,CAAE,MAAOC,EAAW,GAAGC,CAAA,EACvBC,EACA,CACA,MAAMC,EAAgBJ,EAAM,QAAQ,KAAO,CAAE,GAAGnB,EAAY,GAAGoB,CAAA,GAAc,CAACA,CAAS,CAAC,EACxF,aAAQ,MAAA,CAAI,IAAAE,EAAU,MAAOC,EAAgB,GAAGF,EAAO,CACzD,CAAC,EAMYG,EAA0D,CAAC,CAAE,MAAOJ,EAAW,GAAGC,KAAY,CACzG,MAAME,EAAgBJ,EAAM,QAAQ,KAAO,CAAE,GAAGd,EAAa,GAAGe,CAAA,GAAc,CAACA,CAAS,CAAC,EACzF,OAAOK,EAAAA,IAAC,MAAA,CAAI,MAAOF,EAAgB,GAAGF,EAAO,CAC/C,EAMaK,EAAwD,CAAC,CAAE,MAAON,EAAW,GAAGC,KAAY,CACvG,MAAME,EAAgBJ,EAAM,QAAQ,KAAO,CAAE,GAAGT,EAAY,GAAGU,CAAA,GAAc,CAACA,CAAS,CAAC,EACxF,OAAOK,EAAAA,IAAC,OAAA,CAAK,MAAOF,EAAgB,GAAGF,EAAO,CAChD,EAMaM,EAAsD,CAAC,CAAE,MAAOP,EAAW,GAAGC,KAAY,CACrG,MAAME,EAAgBJ,EAAM,QAAQ,KAAO,CAAE,GAAGR,EAAW,GAAGS,CAAA,GAAc,CAACA,CAAS,CAAC,EACvF,OAAOK,EAAAA,IAAC,OAAA,CAAK,MAAOF,EAAgB,GAAGF,EAAO,CAChD,EAMaO,EAA8D,CAAC,CAAE,MAAOR,EAAW,GAAGC,KAAY,CAC7G,MAAME,EAAgBJ,EAAM,QAAQ,KAAO,CAAE,GAAGL,EAAe,GAAGM,CAAA,GAAc,CAACA,CAAS,CAAC,EAC3F,OAAOK,EAAAA,IAAC,MAAA,CAAI,MAAOF,EAAgB,GAAGF,EAAO,CAC/C,EAMaQ,EAAuBV,EAAM,WACxC,SAA8B,CAAE,MAAOC,EAAW,GAAGC,CAAA,EAASC,EAAK,CACjE,MAAMC,EAAgBJ,EAAM,QAAQ,KAAO,CAAE,GAAGH,EAAc,GAAGI,CAAA,GAAc,CAACA,CAAS,CAAC,EAC1F,aAAQ,MAAA,CAAI,IAAAE,EAAU,MAAOC,EAAgB,GAAGF,EAAO,CACzD,CACF,EAEAH,EAAmB,YAAc,qBACjCM,EAAoB,YAAc,sBAClCE,EAAmB,YAAc,qBACjCC,EAAkB,YAAc,oBAChCC,EAAsB,YAAc,wBACpCC,EAAqB,YAAc"}
@@ -1,2 +0,0 @@
1
- "use strict";const g=require("react/jsx-runtime"),$t=require("react"),H=require("./FloatingPanelFrame-DrYwgI9f.cjs"),v=require("./styles-DcG3aIFx.cjs"),Wt=require("react-dom"),Q=require("./usePivot-C8q0pMgW.cjs");function Yt(t){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const n in t)if(n!=="default"){const o=Object.getOwnPropertyDescriptor(t,n);Object.defineProperty(e,n,o.get?o:{enumerable:!0,get:()=>t[n]})}}return e.default=t,Object.freeze(e)}const i=Yt($t),Bt=()=>{const t=new Map;return e=>{if(!e)return;const n=t.get(e);if(n!==void 0)return n;const o=t.size;return t.set(e,o),o}},Xt=Bt(),K=new Map,Vt=t=>{const e=`ovs-threshold:${t.threshold}-rootMargin:${t.rootMargin}-root:${Xt(t.root)}`;if(K.has(e))return K.get(e);const n=new class{#t=new Map;#e=new IntersectionObserver(o=>{o.forEach(r=>{const s=this.#t.get(r.target);s&&s(r)})},t);observe(o,r){return this.#t.set(o,r),this.#e.observe(o),()=>{this.#t.delete(o),this.#e.unobserve(o)}}};return K.set(e,n),n},dt=Object.freeze({x:0,y:0,width:0,height:0,top:0,right:0,bottom:0,left:0});function Zt(t,{threshold:e=0,rootMargin:n="0px",root:o=null}){const[r,s]=i.useState(null);return i.useEffect(()=>{const c=t.current;return c?Vt({threshold:e,rootMargin:n,root:o}).observe(c,a=>{s({isIntersecting:a.isIntersecting,boundingClientRect:a.boundingClientRect,intersectionRatio:a.intersectionRatio,intersectionRect:a.intersectionRect,rootBounds:a.rootBounds,target:a.target,time:a.time})}):void 0},[t,e,n,o]),i.useMemo(()=>({isIntersecting:r?.isIntersecting??!1,boundingClientRect:r?.boundingClientRect??dt,intersectionRatio:r?.intersectionRatio??0,intersectionRect:r?.intersectionRect??dt,rootBounds:r?.rootBounds??null,target:r?.target??t.current,time:r?.time??0}),[r,t])}const ft={position:"fixed",inset:0,background:v.COLOR_DRAWER_BACKDROP},Ut={willChange:"transform"},gt={left:{top:0,bottom:0,left:0,transform:"translateX(-100%)"},right:{top:0,bottom:0,right:0,transform:"translateX(100%)"},top:{top:0,left:0,right:0,transform:"translateY(-100%)"},bottom:{bottom:0,left:0,right:0,transform:"translateY(100%)"}},Kt=(t,e,n)=>{if(t==="none")return;const o=e??v.DRAWER_TRANSITION_DURATION,r=n??v.DRAWER_TRANSITION_EASING;return`transform ${o} ${r}`},qt=(t,e)=>t?e:!1,Jt={marginLeft:"auto",border:"none",background:"transparent",cursor:"pointer",fontSize:v.DRAWER_CLOSE_BUTTON_FONT_SIZE},Qt=({header:t,dismissible:e,onClose:n})=>{if(!t)return null;const o=t.showCloseButton??!0,r=qt(e,o);return g.jsx(i.Activity,{mode:t?"visible":"hidden",children:g.jsxs(H.FloatingPanelHeader,{style:{padding:`${v.DRAWER_HEADER_PADDING_Y} ${v.DRAWER_HEADER_PADDING_X}`,gap:v.DRAWER_HEADER_GAP},children:[g.jsx(i.Activity,{mode:t?"visible":"hidden",children:g.jsx(H.FloatingPanelTitle,{children:t.title})}),g.jsx(i.Activity,{mode:r?"visible":"hidden",children:g.jsx("button",{style:Jt,onClick:n,"aria-label":"Close drawer",type:"button",children:"×"})})]})})},te=({header:t,dismissible:e,onClose:n,chrome:o,children:r})=>o?g.jsxs(H.FloatingPanelFrame,{style:{height:"100%",borderRadius:0},children:[g.jsx(Qt,{header:t,dismissible:e,onClose:n}),g.jsx(H.FloatingPanelContent,{style:{padding:v.DRAWER_CONTENT_PADDING,flex:1,display:"flex",flexDirection:"column"},children:r})]}):g.jsx(g.Fragment,{children:r}),It=({id:t,config:e,isOpen:n,onClose:o,children:r,zIndex:s,width:c,height:u,position:a})=>{const{dismissible:l=!0,header:p,chrome:f=!0,inline:m=!1,transitionMode:b="css",transitionDuration:C,transitionEasing:R}=e,P=i.useCallback((D,L)=>D||(L?L.left!==void 0?"left":L.right!==void 0?"right":L.top!==void 0?"top":L.bottom!==void 0?"bottom":"right":"right"),[])(e.anchor,a),_={left:"translateX(0)",right:"translateX(0)",top:"translateY(0)",bottom:"translateY(0)"},N=i.useMemo(()=>{const D=Kt(b,C,R),L={...Ut,...m?{position:"absolute"}:{position:"fixed"},...gt[P],transform:n?_[P]:gt[P].transform,transition:D};return s!==void 0&&(L.zIndex=s),c!==void 0&&(L.width=typeof c=="number"?`${c}px`:c),u!==void 0&&(L.height=typeof u=="number"?`${u}px`:u),L},[u,m,n,P,C,R,b,c,s]),y=p?.title??e.ariaLabel??"Drawer",T=i.useMemo(()=>{const D=m?{...ft,position:"absolute"}:ft,L=b==="none"?void 0:`opacity ${C??"220ms"} ease`;return{...D,opacity:n?1:0,pointerEvents:n?"auto":"none",transition:L,zIndex:s!==void 0?s-1:void 0}},[m,n,C,b,s]);return g.jsxs(g.Fragment,{children:[g.jsx("div",{style:T,onClick:l?o:void 0}),g.jsx("div",{"data-layer-id":t,"data-placement":P,style:N,role:"dialog","aria-modal":l?!0:void 0,"aria-hidden":n?void 0:!0,"aria-label":y,children:g.jsx(te,{header:p,dismissible:l,onClose:o,chrome:f,children:r})})]})},ee=(t,e)=>new Promise(n=>{let o=!1;const r=()=>{o||(o=!0,t.removeEventListener("transitionend",s),n())},s=c=>{c.target===t&&r()};t.addEventListener("transitionend",s),setTimeout(r,e+50)}),tt=async(t,e,n,o)=>{switch(e){case"none":t();return;case"css":t(),n&&await ee(n,o);return}},ne=t=>{const[e,n]=i.useState({}),o=i.useRef(t);o.current=t;const r=i.useCallback(async(a,l,p)=>{const{mode:f="none",element:m,duration:b=300}=p??{};await tt(()=>{n(I=>I[a]===l?I:{...I,[a]:l})},f,m?.current,b);const R=o.current;l?R?.onOpen?.(a):R?.onClose?.(a),R?.onTransitionEnd?.(a,l)},[]),s=i.useCallback(a=>e[a]??!1,[e]),c=i.useCallback((a,l)=>r(a,!0,l),[r]),u=i.useCallback((a,l)=>r(a,!1,l),[r]);return{state:s,open:c,close:u}},oe=t=>{if(!t)return 300;const e=t.match(/(\d+)/);return e?parseInt(e[1],10):300},re=t=>{const[e,n]=i.useState(()=>{const a={};return t.forEach(l=>{l.drawer&&(a[l.id]=l.drawer.defaultOpen??!1)}),a}),o=i.useMemo(()=>{const a=new Map;return t.forEach(l=>a.set(l.id,l)),a},[t]),r=i.useCallback(async(a,l,p)=>{const f=o.get(a);if(!f?.drawer)return;const m=p?.mode??f.drawer.transitionMode??"css",b=p?.duration??oe(f.drawer.transitionDuration),C=p?.element?.current;await tt(()=>{f.drawer?.open===void 0&&n(I=>I[a]===l?I:{...I,[a]:l}),f.drawer?.onStateChange?.(l)},m,C,b)},[o]),s=i.useCallback(a=>{const l=o.get(a);return l?.drawer?.open!==void 0?l.drawer.open:e[a]??!1},[o,e]),c=i.useCallback((a,l)=>r(a,!0,l),[r]),u=i.useCallback((a,l)=>r(a,!1,l),[r]);return{state:s,open:c,close:u}},Lt=({layers:t})=>{const e=re(t),n=i.useMemo(()=>t.filter(r=>r.drawer),[t]),o=i.useMemo(()=>{const r=new Map;return n.forEach(s=>{r.set(s.id,()=>e.close(s.id))}),r},[n,e.close]);return g.jsx(g.Fragment,{children:n.map(r=>{if(!r.drawer)return null;const s=e.state(r.id),c=o.get(r.id);return c?g.jsx(It,{id:r.id,config:r.drawer,isOpen:s,onClose:c,zIndex:r.zIndex,width:r.width,height:r.height,position:r.position,children:r.component},r.id):null})})},Pt=i.createContext(null),se=({value:t,children:e})=>g.jsx(Pt.Provider,{value:t,children:e}),et=()=>{const t=i.useContext(Pt);if(!t)throw new Error("useGridLayoutContext must be used within a GridLayoutProvider.");return t},Dt=i.createContext(null),ie=()=>{const t=i.useContext(Dt);if(!t)throw new Error("usePanelSystem must be used within a PanelSystemProvider.");return t},ae=({config:t,layers:e,style:n,children:o})=>{const r=i.useMemo(()=>{const c=new Map;return e.forEach(u=>{c.set(u.id,u)}),c},[e]),s=i.useMemo(()=>({config:t,style:n,layers:{defs:e,layerById:r}}),[t,n,e,r]);return g.jsx(Dt.Provider,{value:s,children:o})},yt=i.createContext(null),Tt=({layerId:t,children:e})=>{const n=i.useMemo(()=>({layerId:t}),[t]);return g.jsx(yt.Provider,{value:n,children:e})},ce=()=>{const t=i.useContext(yt);if(!t)throw new Error("useLayerInstance must be used within a LayerInstanceProvider.");return t},pt=(t,e,n)=>{if(typeof t=="number"&&Number.isFinite(t))return t;throw new Error(`Popup layer "${n}" requires a numeric "${e}" value.`)},_t=(t,e)=>{if(!t)throw new Error(`Popup layer "${e}" must define position (left/top).`);return{left:pt(t.left,"left",e),top:pt(t.top,"top",e)}},$=t=>`${Math.round(t)}`,G=t=>{if(t!==void 0)return t?"yes":"no"},ue=(t,e,n,o,r)=>{const s={},c=_t(e,t);if(typeof n!="number"||typeof o!="number")throw new Error(`Popup layer "${t}" requires numeric width/height.`);s.width=$(n),s.height=$(o),s.left=$(c.left),s.top=$(c.top);const u=r?.features;if(u){const a=G(u.toolbar),l=G(u.menubar),p=G(u.location),f=G(u.status),m=G(u.resizable),b=G(u.scrollbars);a!==void 0&&(s.toolbar=a),l!==void 0&&(s.menubar=l),p!==void 0&&(s.location=p),f!==void 0&&(s.status=f),m!==void 0&&(s.resizable=m),b!==void 0&&(s.scrollbars=b)}return Object.entries(s).map(([a,l])=>`${a}=${l}`).join(",")},ht=(t,e,n,o,r)=>{const s=_t(n,e);if(typeof o!="number"||typeof r!="number")throw new Error(`Popup layer "${e}" requires numeric width/height.`);t.moveTo(Math.round(s.left),Math.round(s.top)),t.resizeTo(Math.round(o),Math.round(r))},le=({layer:t})=>{const e=t.floating;if(!e)throw new Error(`Layer "${t.id}" is missing floating configuration required for popup mode.`);if((e.mode??"embedded")!=="popup")throw new Error(`PopupLayerPortal received layer "${t.id}" that is not configured for popup mode.`);const o=i.useRef(null),r=i.useRef(null),[s,c]=i.useState(!1);return i.useEffect(()=>{if(typeof window>"u")return;const u=ue(t.id,t.position,t.width,t.height,e.popup),a=e.popup?.name??t.id,l=de(a,u,{position:t.position,size:{width:t.width,height:t.height}},e.popup);if(!l)throw new Error(`Failed to open popup window for layer "${t.id}".`);const p=l;r.current=p,e.popup?.focus!==!1&&p.focus(),p.document.title||(p.document.title=t.id),p.document.body.innerHTML="";const f=p.document.createElement("div");f.dataset.layerId=t.id,p.document.body.appendChild(f),o.current=f,c(!0),ht(p,t.id,t.position,t.width,t.height);const m=()=>{r.current=null,o.current=null,c(!1)};return p.addEventListener("beforeunload",m),()=>{p.removeEventListener("beforeunload",m),e.popup?.closeOnUnmount!==!1&&p.close(),r.current=null,o.current=null,c(!1)}},[e.popup?.closeOnUnmount,e.popup?.features?.location,e.popup?.features?.menubar,e.popup?.features?.resizable,e.popup?.features?.scrollbars,e.popup?.features?.status,e.popup?.features?.toolbar,e.popup?.focus,e.popup?.name,t.id]),i.useEffect(()=>{const u=r.current;u&&ht(u,t.id,t.position,t.width,t.height)},[t.position?.left,t.position?.top,t.height,t.width,t.id]),!s||!o.current?null:Wt.createPortal(g.jsx(Tt,{layerId:t.id,children:t.component}),o.current)},de=(t,e,n,o)=>{const r=o?.createWindow;return r?r({name:t,features:e,bounds:n}):window.open("",t,e)},fe={marginLeft:"auto",border:"none",background:"transparent",cursor:"pointer",fontSize:"1.25rem",padding:"0.25rem 0.5rem",lineHeight:1},ge=({onClick:t})=>g.jsx(H.FloatingPanelControls,{children:g.jsx("button",{style:fe,onClick:t,"aria-label":"Close window",type:"button","data-drag-ignore":"true",children:"×"})}),pe=({header:t,draggable:e,onClose:n})=>{if(!t)return null;const o=t.showCloseButton??!1,r=e?{"data-drag-handle":"true"}:{},s=e?"grab":void 0;return g.jsxs(H.FloatingPanelHeader,{...r,style:{cursor:s},children:[t.title?g.jsx(H.FloatingPanelTitle,{children:t.title}):null,o?g.jsx(ge,{onClick:n}):null]})},he=({header:t,draggable:e,chrome:n,onClose:o,children:r})=>n?g.jsxs(H.FloatingPanelFrame,{style:{height:"100%",width:"100%"},children:[g.jsx(pe,{header:t,draggable:e,onClose:o}),g.jsx(H.FloatingPanelContent,{style:{flex:1,display:"flex",flexDirection:"column"},children:r})]}):g.jsx(g.Fragment,{children:r}),nt=({id:t,config:e,onClose:n,children:o})=>{const r=e.chrome??!1,s=e.draggable??!1,c=e.header?.title??e.ariaLabel??"Floating window";return g.jsx("div",{"data-floating-window":t,role:"dialog","aria-label":c,style:{height:"100%",width:"100%"},children:g.jsx(he,{header:e.header,draggable:s,chrome:r,onClose:n,children:o})})};nt.displayName="FloatingWindow";const Mt={position:"absolute",pointerEvents:"auto",boxSizing:"border-box",background:"transparent",border:"none"},me={...Mt,width:v.GRID_LAYER_CORNER_HIT_SIZE,height:v.GRID_LAYER_CORNER_HIT_SIZE,zIndex:2},be={...Mt,zIndex:1},we={"top-left":{top:0,left:0,transform:"translate(-50%, -50%)",cursor:"nwse-resize"},"top-right":{top:0,right:0,transform:"translate(50%, -50%)",cursor:"nesw-resize"},"bottom-left":{bottom:0,left:0,transform:"translate(-50%, 50%)",cursor:"nesw-resize"},"bottom-right":{bottom:0,right:0,transform:"translate(50%, 50%)",cursor:"nwse-resize"}},Ee={left:{top:v.GRID_LAYER_CORNER_HIT_SIZE,bottom:v.GRID_LAYER_CORNER_HIT_SIZE,left:0,width:v.GRID_LAYER_EDGE_HIT_THICKNESS,transform:"translateX(-50%)",cursor:"ew-resize"},right:{top:v.GRID_LAYER_CORNER_HIT_SIZE,bottom:v.GRID_LAYER_CORNER_HIT_SIZE,right:0,width:v.GRID_LAYER_EDGE_HIT_THICKNESS,transform:"translateX(50%)",cursor:"ew-resize"},top:{left:v.GRID_LAYER_CORNER_HIT_SIZE,right:v.GRID_LAYER_CORNER_HIT_SIZE,top:0,height:v.GRID_LAYER_EDGE_HIT_THICKNESS,transform:"translateY(-50%)",cursor:"ns-resize"},bottom:{left:v.GRID_LAYER_CORNER_HIT_SIZE,right:v.GRID_LAYER_CORNER_HIT_SIZE,bottom:0,height:v.GRID_LAYER_EDGE_HIT_THICKNESS,transform:"translateY(50%)",cursor:"ns-resize"}},ve=[{key:"top-left",variant:"corner",horizontal:"left",vertical:"top"},{key:"top-right",variant:"corner",horizontal:"right",vertical:"top"},{key:"bottom-left",variant:"corner",horizontal:"left",vertical:"bottom"},{key:"bottom-right",variant:"corner",horizontal:"right",vertical:"bottom"},{key:"left",variant:"edge",horizontal:"left"},{key:"right",variant:"edge",horizontal:"right"},{key:"top",variant:"edge",vertical:"top"},{key:"bottom",variant:"edge",vertical:"bottom"}],Se=({layerId:t,onPointerDown:e})=>g.jsx(g.Fragment,{children:ve.map(n=>{const o=n.variant==="corner"?me:be,r=n.variant==="corner"?we[n.key]:Ee[n.key],s={...o,...r},c=n.variant==="corner"?{"data-resize-corner":n.key}:{"data-resize-edge":n.key};return g.jsx("div",{role:"presentation","aria-hidden":"true",style:s,...c,"data-layer-id":t,onPointerDown:u=>e(n,u)},n.key)})}),Ce=({pivot:t})=>{const{Outlet:e}=Q.usePivot({items:t.items,activeId:t.activeId,defaultActiveId:t.defaultActiveId,onActiveChange:t.onActiveChange,transitionMode:t.transitionMode});return g.jsx(e,{})},Ht=i.memo(({layer:t,onClose:e})=>{const n=t.pivot?g.jsx(Ce,{pivot:t.pivot}):g.jsx(g.Fragment,{children:t.component});return t.floating?.chrome?g.jsx(nt,{id:t.id,config:t.floating,onClose:e,children:n}):n});Ht.displayName="LayerContentRenderer";const Nt=i.memo(({layerId:t,isResizable:e,onPointerDown:n})=>e?g.jsx(Se,{layerId:t,onPointerDown:n}):null);Nt.displayName="LayerResizeHandles";const Re=t=>t?"auto":"hidden",At=i.memo(({layer:t,handleLayerPointerDown:e})=>{const{getLayerRenderState:n}=et(),{style:o,isResizable:r,isResizing:s,onResizeHandlePointerDown:c}=n(t),u=i.useMemo(()=>{const p={};return t.gridArea&&(p.gridArea=t.gridArea),t.gridRow&&(p.gridRow=t.gridRow),t.gridColumn&&(p.gridColumn=t.gridColumn),p},[t.gridArea,t.gridRow,t.gridColumn]),a=i.useMemo(()=>{const p=Re(t.scrollable),f={...o,...u,minWidth:0,minHeight:0,overflow:p};return r?{...f,position:"relative"}:f},[o,u,r,t.scrollable]),l=i.useCallback(()=>{t.floating?.onClose?.()},[t.floating]);return g.jsxs("div",{"data-layer-id":t.id,"data-draggable":!!t.floating?.draggable,"data-resizable":r,"data-resizing":s,style:a,onPointerDown:e,children:[g.jsx(Tt,{layerId:t.id,children:g.jsx(Ht,{layer:t,onClose:l})}),g.jsx(Nt,{layerId:t.id,isResizable:r,onPointerDown:c})]})});At.displayName="EmbeddedLayer";const ze=({layers:t})=>{const{handleLayerPointerDown:e}=et();return g.jsx(g.Fragment,{children:t.map(n=>{const o=n.floating?.mode??"embedded";return n.floating&&o==="popup"?g.jsx(le,{layer:n},n.id):g.jsx(At,{layer:n,handleLayerPointerDown:e},n.id)})})};function k(t){const e=i.useRef(t);return e.current=t,i.useCallback((...n)=>{const o=e.current;if(o)return o(...n)},[])}function q(t,e){const n=k(e.onMove),o=k(e.onUp),r=k(e.onCancel);i.useEffect(()=>{if(t)return e.onMove&&document.addEventListener("pointermove",n,{passive:!1}),e.onUp&&document.addEventListener("pointerup",o),e.onCancel&&document.addEventListener("pointercancel",r),()=>{e.onMove&&document.removeEventListener("pointermove",n),e.onUp&&document.removeEventListener("pointerup",o),e.onCancel&&document.removeEventListener("pointercancel",r)}},[t,e.onMove,e.onUp,e.onCancel,n,o,r])}function xe(t,e,n){i.useEffect(()=>{const o=t.current;if(!(!e||!o||n===void 0))return o.setPointerCapture(n),()=>{o.hasPointerCapture&&o.hasPointerCapture(n)&&o.releasePointerCapture(n)}},[t,e,n])}function Ie(t,e,n=["pointerdown","pointermove","pointerup"]){i.useEffect(()=>{const o=t.current;if(!e||!o)return;const r=s=>{s.preventDefault()};return n.forEach(s=>{o.addEventListener(s,r,{passive:!1})}),()=>{n.forEach(s=>{o.removeEventListener(s,r)})}},[t,e,n])}function Le(t,e,n){const{onMove:o,onUp:r,onCancel:s,pointerId:c,capturePointer:u=!0,preventDefaults:a=!0}=n;q(e,{onMove:o,onUp:r,onCancel:s}),xe(t,e?u:!1,c),Ie(t,e?a:!1)}const kt=t=>{const e=i.useRef(null),n=i.useRef(null),o=i.useRef(0),[r,s]=i.useState(!1),c=k(f=>{t.onResize?.(f)}),u=i.useCallback(f=>t.axis==="x"?f.clientX:f.clientY,[t.axis]),a=i.useCallback(f=>{f.preventDefault(),e.current=f.currentTarget,n.current=f.pointerId,o.current=u(f),s(!0)},[u]),l=i.useCallback(f=>{const m=u(f),b=m-o.current;b!==0&&(o.current=m,c(b))},[u,c]),p=i.useCallback(()=>{s(!1),n.current=null},[]);return Le(e,r,{onMove:l,onUp:p,pointerId:n.current??void 0,capturePointer:!0,preventDefaults:!1}),{ref:e,onPointerDown:a,isDragging:r}},Pe=({element:t,component:e})=>i.forwardRef(({children:n,...o},r)=>t?i.cloneElement(t,{...o,ref:r},n??t.props.children):e?g.jsx(e,{...o,ref:r,children:n}):g.jsx("div",{...o,ref:r,children:n}));function jt({element:t,component:e}){return i.useMemo(()=>Pe({element:t,component:e}),[e,t])}const De={position:"absolute",zIndex:v.RESIZE_HANDLE_Z_INDEX},ye={vertical:{width:v.RESIZE_HANDLE_THICKNESS,height:"100%",top:0,cursor:"col-resize"},horizontal:{width:"100%",height:v.RESIZE_HANDLE_THICKNESS,left:0,cursor:"row-resize"}},Te={idle:v.COLOR_RESIZE_HANDLE_IDLE,hovered:v.COLOR_RESIZE_HANDLE_HOVER,dragging:v.COLOR_RESIZE_HANDLE_ACTIVE},Gt=({direction:t,onResize:e,component:n,element:o,children:r})=>{const s=t==="vertical"?"x":"y",{ref:c,isDragging:u,onPointerDown:a}=kt({axis:s,onResize:e}),[l,p]=i.useState(!1),f=i.useCallback(()=>{p(!0)},[]),m=i.useCallback(()=>{p(!1)},[]),b=jt({element:o,component:n}),C=i.useMemo(()=>u?"dragging":l?"hovered":"idle",[u,l]),R=i.useMemo(()=>({...De,...ye[t],backgroundColor:Te[C],touchAction:"none"}),[t,C]);return g.jsx(b,{ref:c,style:R,role:"separator","aria-orientation":t,"aria-hidden":void 0,"data-resize-handle":"true","data-direction":t,"data-is-dragging":u?"true":void 0,onPointerDown:a,onPointerEnter:f,onPointerLeave:m,children:r})},mt={position:"absolute",pointerEvents:"auto"},bt=({direction:t,trackIndex:e,align:n,gap:o,span:r,onResize:s})=>{const c=t==="col"?"vertical":"horizontal",u=i.useCallback(p=>{const f=n==="start"?-p:p;s(t,e,f)},[n,t,e,s]),a=i.useMemo(()=>t==="col"?{gridColumn:`${e+1} / ${e+2}`,gridRow:`${r.start} / ${r.end}`}:{gridRow:`${e+1} / ${e+2}`,gridColumn:`${r.start} / ${r.end}`},[t,e,r]),l=i.useMemo(()=>{const f=Math.max(0,o)/2+v.GRID_HANDLE_THICKNESS/2;return t==="col"?{...mt,width:v.GRID_HANDLE_THICKNESS,height:"100%",top:0,bottom:0,...n==="start"?{left:-f}:{right:-f}}:{...mt,width:"100%",height:v.GRID_HANDLE_THICKNESS,left:0,right:0,...n==="start"?{top:-f}:{bottom:-f}}},[n,t,o]);return g.jsx("div",{"data-resizable":"true",style:{...a,position:"relative",pointerEvents:"none"},children:g.jsx("div",{"data-direction":c,"data-align":n,"data-handle":"true",style:l,children:g.jsx(Gt,{direction:c,onResize:u})})})},_e=t=>{const e=new Map;t.forEach((o,r)=>{o.forEach((s,c)=>{if(!s||s===".")return;const u=e.get(s);if(u){const l={rowStart:Math.min(u.rowStart,r),rowEnd:Math.max(u.rowEnd,r),colStart:Math.min(u.colStart,c),colEnd:Math.max(u.colEnd,c)};e.set(s,l);return}const a={rowStart:r,rowEnd:r,colStart:c,colEnd:c};e.set(s,a)})});const n=new Map;return e.forEach((o,r)=>{const s=o.rowStart+1,c=o.rowEnd+2,u=o.colStart+1,a=o.colEnd+2,l={gridArea:r,gridRow:`${s} / ${c}`,gridColumn:`${u} / ${a}`};n.set(r,l)}),n},Me=(t,e)=>{if((t.positionMode??"grid")!=="grid")return t;const o=t.gridArea??t.id,r=e.get(o);if(!r)return t;const s=!t.gridArea,c=!t.gridRow,u=!t.gridColumn;return!s&&!c&&!u?t:{...t,gridArea:s?r.gridArea:t.gridArea,gridRow:c?r.gridRow:t.gridRow,gridColumn:u?r.gridColumn:t.gridColumn}},He=(t,e)=>{const n=i.useMemo(()=>_e(t.areas),[t.areas]),o=i.useMemo(()=>e.map(u=>Me(u,n)),[e,n]),r=i.useMemo(()=>o.filter(u=>u.visible!==!1),[o]),s=i.useMemo(()=>r.filter(u=>!u.drawer),[r]),c=i.useMemo(()=>{const u=new Map;return o.forEach(a=>{u.set(a.id,a)}),u},[o]);return{normalizedLayers:o,visibleLayers:r,regularLayers:s,layerById:c}},Ne=t=>{if(!t)return{rowGap:0,columnGap:0};const e=t.split(/\s+/).map(o=>o.trim()).filter(Boolean),n=o=>{const r=o.match(/^(-?\d+(?:\.\d+)?)px$/);return r?Number.parseFloat(r[1]):0};if(e.length===1){const o=n(e[0]);return{rowGap:o,columnGap:o}}return{rowGap:n(e[0]),columnGap:n(e[1])}},Ae=(t,e)=>{if(!t)return[];const n=getComputedStyle(t);return(e==="col"?n.gridTemplateColumns:n.gridTemplateRows).split(/\s+/).map(r=>parseFloat(r)).filter(r=>!Number.isNaN(r))},ot=(t,e=Number.NEGATIVE_INFINITY,n=Number.POSITIVE_INFINITY)=>Math.min(Math.max(t,e),n),ke=(t,e)=>typeof t!="number"||!Number.isFinite(t)?e:t,X=(t,e)=>`${t}-${e}`,je=(t,e,n,o)=>{const r=X(n,o),s=e[r];return s!==void 0?`minmax(${t.minSize??0}px, ${s}px)`:t.size},wt=(t,e,n)=>t.map((o,r)=>je(o,e,n,r)).join(" "),W=(t,e)=>t.reduce((n,o,r)=>(o.resizable&&o.size.endsWith("px")&&(n[X(e,r)]=parseInt(o.size,10)),n),{}),Ge=({trackSizes:t,track:e,direction:n,trackIndex:o,containerRef:r})=>{const s=X(n,o),c=t[s];if(c!==void 0)return c;const a=Ae(r?.current??null,n)[o];return a!==void 0&&a>0?a:e.size.endsWith("px")?Number.parseInt(e.size,10):300},Fe=(t,e)=>t.reduce((n,o,r)=>r===e?n:o.size.includes("fr")?n+100:n+(o.minSize??50),0),Oe=({track:t,tracks:e,trackIndex:n,direction:o,containerRef:r,gapSizes:s})=>{if(!r?.current)return t.maxSize;const c=o==="col"?r.current.offsetWidth:r.current.offsetHeight,u=Fe(e,n),a=e.length-1,l=o==="col"?s.columnGap:s.rowGap,p=a*l,f=c-u-p;return t.maxSize!==void 0?Math.min(t.maxSize,f):f},$e=(t,e,n)=>ot(t,e??Number.NEGATIVE_INFINITY,n??Number.POSITIVE_INFINITY),Et=(t,e)=>{const n=t.length,o=[];for(let c=0;c<n;c++){const u=t[c],a=u[e],l=u[e+1];a!==l&&o.push(c)}if(o.length===0)return{start:1,end:n+1};const r=Math.min(...o),s=Math.max(...o);return{start:r+1,end:s+2}},vt=(t,e)=>{const n=t[e],o=t[e+1],r=n?.length??0,s=[];for(let a=0;a<r;a++){const l=n?.[a],p=o?.[a];l!==p&&s.push(a)}if(s.length===0)return{start:1,end:r+1};const c=Math.min(...s),u=Math.max(...s);return{start:c+1,end:u+2}},We=(t,e)=>{if(t.length===0)return[];const n=e.length;if(t.length===1)return t[0]?.resizable?[{trackIndex:0,align:"end",span:{start:1,end:n+1}}]:[];const o=[];return Array.from({length:t.length-1},(s,c)=>c).forEach(s=>{const c=t[s];if(t[s+1]?.resizable){const a=Et(e,s);o.push({trackIndex:s+1,align:"start",span:a});return}if(c?.resizable){const a=Et(e,s);o.push({trackIndex:s,align:"end",span:a})}}),o},Ye=(t,e)=>{if(t.length===0)return[];const n=e[0]?.length??0;if(t.length===1)return t[0]?.resizable?[{trackIndex:0,align:"end",span:{start:1,end:n+1}}]:[];const o=[];return Array.from({length:t.length-1},(s,c)=>c).forEach(s=>{const c=t[s];if(t[s+1]?.resizable){const a=vt(e,s);o.push({trackIndex:s+1,align:"start",span:a});return}if(c?.resizable){const a=vt(e,s);o.push({trackIndex:s,align:"end",span:a})}}),o},Be=t=>t!==void 0?{gap:t}:{},Xe=(t,e)=>{const n=Object.keys(e),o={};for(const p of n)o[p]=t[p]??e[p];const r=Object.keys(t),s=r.length!==n.length,c=r.some(p=>!Object.prototype.hasOwnProperty.call(o,p)),u=s?!0:c,a=n.some(p=>t[p]!==o[p]);return(u?!0:a)?o:null},Ve=(t,e,n)=>{const[o,r]=i.useState(()=>({...W(t.columns,"col"),...W(t.rows,"row")}));Q.useIsomorphicLayoutEffect(()=>{const f={...W(t.columns,"col"),...W(t.rows,"row")};r(m=>Xe(m,f)??m)},[t.columns,t.rows]);const s=i.useMemo(()=>t.areas.map(f=>`"${f.join(" ")}"`).join(" "),[t.areas]),c=i.useMemo(()=>Ne(t.gap),[t.gap]),u=i.useMemo(()=>We(t.columns,t.areas),[t.columns,t.areas]),a=i.useMemo(()=>Ye(t.rows,t.areas),[t.rows,t.areas]),l=i.useMemo(()=>({...t.style,...e,gridTemplateAreas:s,gridTemplateRows:wt(t.rows,o,"row"),gridTemplateColumns:wt(t.columns,o,"col"),...Be(t.gap)}),[s,t.columns,t.gap,t.rows,t.style,e,o]),p=i.useCallback((f,m,b)=>{const C=f==="row"?t.rows:t.columns,R=C[m];if(!R||!R.resizable)return;const I=Ge({trackSizes:o,track:R,direction:f,trackIndex:m,containerRef:n}),P=Oe({track:R,tracks:C,trackIndex:m,direction:f,containerRef:n,gapSizes:c}),_=X(f,m);r(N=>{const y=I+b,T=$e(y,R.minSize,P);return{...N,[_]:T}})},[t.columns,t.rows,o,n,c]);return{columnHandles:u,rowHandles:a,gapSizes:c,gridStyle:l,handleResize:p}},Ze=t=>t.positionMode?t.positionMode:t.floating?(t.floating.mode??"embedded")==="embedded"?"absolute":"relative":"grid",Ue=t=>({position:t==="grid"?"relative":t}),Ke=(t,e)=>e!=="grid"?{}:{gridArea:t.gridArea,gridRow:t.gridRow,gridColumn:t.gridColumn},qe=t=>t?{top:t.top,right:t.right,bottom:t.bottom,left:t.left}:{},Je=t=>t!==void 0?{zIndex:t}:{},Qe=(t,e)=>({width:t,height:e}),tn=(t,e)=>t.pointerEvents!==void 0?typeof t.pointerEvents=="boolean"?{pointerEvents:t.pointerEvents?"auto":"none"}:{pointerEvents:t.pointerEvents}:e==="absolute"||e==="fixed"?{pointerEvents:"auto"}:{},en=t=>t.floating?t.floating.position??t.floating.defaultPosition??t.position:t.position,nn=t=>{if(t.floating){const e=t.floating.size??t.floating.defaultSize;if(e)return{width:e.width,height:e.height}}return{width:t.width,height:t.height}},on=t=>t.floating?.zIndex!==void 0?t.floating.zIndex:t.zIndex,rn=t=>{const e=Ze(t),n=en(t),o=nn(t),r=on(t);return{...t.style,...Ue(e),...Ke(t,e),...qe(n),...Je(r),...Qe(o.width,o.height),...tn(t,e)}},sn=t=>{const e=t.floating;return e?e.mode??"embedded":null},j=t=>sn(t)!=="embedded"?null:t.floating??null,St=t=>t instanceof HTMLElement?["INPUT","TEXTAREA","SELECT","BUTTON"].includes(t.tagName):!1,Ct=(t,e,n)=>{const o=e??Number.NEGATIVE_INFINITY,r=n??Number.POSITIVE_INFINITY;return ot(t,o,r)},Rt=(t,e,n)=>{if(typeof t=="number"&&Number.isFinite(t))return t;throw new Error(`Floating layer "${n}" must provide a numeric "${e}" value when draggable mode is enabled.`)},zt=t=>{const e=j(t);if(!e)throw new Error(`Floating layer "${t.id}" is missing floating configuration required for dragging.`);const n=e.position??e.defaultPosition??t.position;if(!n)throw new Error(`Floating layer "${t.id}" must define position with left and top values.`);return{left:Rt(n.left,"left",t.id),top:Rt(n.top,"top",t.id)}},an=t=>{const e=j(t);return e?e.constraints??{}:{}},cn=(t,e,n)=>t?t==="left"?e-n:e+n:e,un=(t,e,n)=>t?t==="top"?e-n:e+n:e,ln=(t,e,n)=>!t||t==="right"?e:e+n,dn=(t,e,n)=>!t||t==="bottom"?e:e+n,J=(t,e)=>t?t.dataset.layerId===e?t:J(t.parentElement,e):null,rt=(t,e,n)=>!t||n?.(t)?null:e(t)?t:rt(t.parentElement,e,n),fn=t=>t instanceof HTMLElement?rt(t,e=>e.dataset.dragHandle==="true",e=>e.dataset.dragIgnore==="true"):null,xt=t=>t instanceof HTMLElement?rt(t,e=>e.dataset.resizeCorner!==void 0||e.dataset.resizeEdge!==void 0)!==null:!1,Y=t=>{const e=j(t);return e?e.resizable===!0:!1},B=t=>{if(!j(t))return null;const n=hn(t);if(!n)throw new Error(`Floating layer "${t.id}" must define width and height when resizable or draggable.`);return{width:n.width,height:n.height}},gn=(t,e,n)=>{const o=t.filter(Y).reduce((f,m)=>{if(n===m.id){const C=e[m.id];if(C)return f[m.id]=C,f}const b=B(m);return b&&(f[m.id]=b),f},{}),r=Object.keys(e),s=Object.keys(o),c=r.length!==s.length,u=r.some(f=>!Object.prototype.hasOwnProperty.call(o,f)),a=c?!0:u,l=s.some(f=>{const m=e[f],b=o[f];return!m||!b?!0:m.width!==b.width||m.height!==b.height});return{sizes:o,changed:a?!0:l}},pn=({layers:t,layerById:e,isRootLevel:n})=>{const[o,r]=i.useState(null),[s,c]=i.useState(null),[u,a]=i.useState({}),[l,p]=i.useState({}),f=i.useRef(null),m=i.useRef(null),b=k((h,d)=>{e.get(h)?.floating?.onMove?.(d)}),C=k((h,d)=>{e.get(h)?.floating?.onResize?.(d)});Q.useIsomorphicLayoutEffect(()=>{const{sizes:h,changed:d}=gn(t,l,s);d&&p(h)},[t,s]);const R=i.useCallback((h,d,w,E)=>{const S=zt(d),x=u[h]??{x:0,y:0},z={pointerStartX:E.clientX,pointerStartY:E.clientY,initialTranslationX:x.x,initialTranslationY:x.y,baseLeft:S.left,baseTop:S.top,layerId:h,pointerId:E.pointerId,target:w};if(z.target.setPointerCapture)try{z.target.setPointerCapture(z.pointerId)}catch{}f.current=z,r(h)},[u]),I=i.useCallback(h=>{const d=h.target,w=fn(d);if(!w)return;const E=w.closest("[data-layer-id]")?.getAttribute("data-layer-id");if(!E)return;const S=e.get(E);if(!S)return;const x=j(S);if(!(!x||x.draggable!==!0)&&!St(h.target)&&!xt(h.target)&&w){const z=J(w,E);if(!z)return;R(E,S,z,h);return}},[R,e]),P=i.useCallback((h,d)=>{const w=e.get(h),E=w?j(w):null;if(!w||!E||E.draggable!==!0||St(d.target)||xt(d.target))return;const S=J(d.currentTarget,h);S&&R(h,w,S,d)},[R,e]),_=i.useCallback((h,d,w)=>{const E=e.get(h);if(!E||!Y(E))return;const S=l[h]??B(E);if(!S)return;const x=zt(E),z=an(E),M=u[h]??{x:0,y:0};if(w.stopPropagation(),w.preventDefault(),w.currentTarget.setPointerCapture)try{w.currentTarget.setPointerCapture(w.pointerId)}catch{}m.current={layerId:h,pointerId:w.pointerId,horizontalEdge:d.horizontal,verticalEdge:d.vertical,startX:w.clientX,startY:w.clientY,startWidth:S.width,startHeight:S.height,startPosition:M,baseLeft:x.left,baseTop:x.top,minWidth:z.minWidth,maxWidth:z.maxWidth,minHeight:z.minHeight,maxHeight:z.maxHeight,target:w.currentTarget},c(h)},[e,u,l]),N=i.useCallback(h=>{const d=f.current;if(!d)return;const w=h.clientX-d.pointerStartX,E=h.clientY-d.pointerStartY,S={x:d.initialTranslationX+w,y:d.initialTranslationY+E};a(x=>({...x,[d.layerId]:S})),b(d.layerId,{left:d.baseLeft+S.x,top:d.baseTop+S.y})},[b]),y=i.useCallback(h=>{const d=m.current;if(!d||d.pointerId!==h.pointerId||!e.get(d.layerId))return;const E=h.clientX-d.startX,S=h.clientY-d.startY,x=cn(d.horizontalEdge,d.startWidth,E),z=un(d.verticalEdge,d.startHeight,S),M=Ct(x,d.minWidth,d.maxWidth),A=Ct(z,d.minHeight,d.maxHeight),F=d.startWidth-M,V=d.startHeight-A,ct=ln(d.horizontalEdge,d.startPosition.x,F),Ot=dn(d.verticalEdge,d.startPosition.y,V),Z=l[d.layerId],ut={width:M,height:A};(!Z||Z.width!==M||Z.height!==A)&&(p(U=>({...U,[d.layerId]:ut})),C(d.layerId,ut));const lt=u[d.layerId]??{x:0,y:0},O={x:ct,y:Ot};(lt.x!==O.x||lt.y!==O.y)&&(a(U=>({...U,[d.layerId]:O})),b(d.layerId,{left:d.baseLeft+O.x,top:d.baseTop+O.y}))},[e,u,l,b,C]),T=i.useCallback(h=>{const d=f.current;if(d){if(d.pointerId===h.pointerId&&d.target.releasePointerCapture)try{d.target.releasePointerCapture(d.pointerId)}catch{}f.current=null}r(null)},[]),D=i.useCallback(h=>{const d=m.current;if(d){if(d.pointerId===h.pointerId&&d.target.releasePointerCapture)try{d.target.releasePointerCapture(d.pointerId)}catch{}m.current=null}c(null)},[]);q(o!==null,{onMove:N,onUp:T,onCancel:T}),q(s!==null,{onMove:y,onUp:D,onCancel:D});const L=i.useCallback(h=>{const d=rn(h),w=j(h);if(!w||w.draggable!==!0)return d;const E=u[h.id],S=o===h.id,x=s===h.id,z=E?{transform:`translate(${E.x}px, ${E.y}px)`}:{},M=l[h.id],A=Y(h)?B(h):null,F=M??A,V=F?{width:`${F.width}px`,height:`${F.height}px`}:{};return{...d,...V,...z,...S||x?{cursor:"grabbing"}:{}}},[o,u,l,s]),st=i.useCallback(h=>{if(!Y(h))return{isResizable:!1};const w=l[h.id],E=B(h);return(w??E)!==null?{isResizable:!0,onPointerDown:(M,A)=>{_(h.id,M,A)}}:{isResizable:!1}},[_,l]),it=i.useCallback(h=>{const{isResizable:d,onPointerDown:w}=st(h),E=L(h),S=s===h.id;return{style:E,isResizable:d,isResizing:S,onResizeHandlePointerDown:(x,z)=>{w&&w(x,z)}}},[L,st,s]),at=i.useCallback(h=>({"data-drag-handle":"true",role:"button","aria-roledescription":"Drag handle","aria-label":"Drag layer",onPointerDown:d=>{P(h,d)}}),[P]);return{providerValue:i.useMemo(()=>({handleLayerPointerDown:I,getLayerRenderState:it,getLayerHandleProps:at,isRootLevel:n}),[at,it,I,n]),draggingLayerId:o,resizingLayerId:s}},hn=t=>{if(t.floating){const e=t.floating.size??t.floating.defaultSize;if(e)return{width:e.width,height:e.height}}if(typeof t.width=="number"&&typeof t.height=="number")return{width:t.width,height:t.height}},Ft={display:"grid",width:"100%",height:"100%",overflow:"hidden"},mn={touchAction:"none",WebkitTouchCallout:"none",WebkitUserSelect:"none",userSelect:"none"},bn={...Ft,height:"auto",minHeight:"100%"},wn=t=>t?bn:Ft,En=({config:t,layers:e,style:n,root:o=!1})=>{const r=i.useRef(null),{isIntersecting:s}=Zt(r,{threshold:0});return g.jsx(ae,{config:t,layers:e,style:n,children:g.jsx(vn,{gridRef:r,isIntersecting:s,isRoot:o})})},vn=({gridRef:t,isIntersecting:e,isRoot:n})=>{const{config:o,style:r,layers:s}=ie(),{normalizedLayers:c,visibleLayers:u,regularLayers:a,layerById:l}=He(o,s.defs),{columnHandles:p,rowHandles:f,gapSizes:m,gridStyle:b,handleResize:C}=Ve(o,r,t),{providerValue:R,draggingLayerId:I,resizingLayerId:P}=pn({layers:c,layerById:l,isRootLevel:n}),_=I?!0:!!P,N=i.useMemo(()=>({...wn(n),...b,..._?mn:{}}),[b,_,n]);return g.jsxs(g.Fragment,{children:[g.jsxs("div",{ref:t,style:N,"data-dragging":!!I,"data-resizing":!!P,"data-visible":e,children:[g.jsx(se,{value:R,children:g.jsx(ze,{layers:a})}),p.map(({trackIndex:y,align:T,span:D})=>g.jsx(bt,{direction:"col",trackIndex:y,align:T,gap:m.columnGap,span:D,onResize:C},`col-${y}:${T}`)),f.map(({trackIndex:y,align:T,span:D})=>g.jsx(bt,{direction:"row",trackIndex:y,align:T,gap:m.rowGap,span:D,onResize:C},`row-${y}:${T}`))]}),g.jsx(Lt,{layers:u})]})};exports.Drawer=It;exports.DrawerLayers=Lt;exports.FloatingWindow=nt;exports.GridLayout=En;exports.ResizeHandle=Gt;exports.clampNumber=ot;exports.runTransition=tt;exports.toFiniteNumberOr=ke;exports.useEffectEvent=k;exports.useElementComponentWrapper=jt;exports.useGridLayoutContext=et;exports.useLayerInstance=ce;exports.useResizeDrag=kt;exports.useTransitionState=ne;
2
- //# sourceMappingURL=GridLayout-DC7fCmcI.cjs.map