@aiquants/resize-panels 1.8.1 → 2.0.0

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 (81) hide show
  1. package/README.md +213 -108
  2. package/dist/GlobalDebugOverlay-Cf3GOn2A.cjs +1 -0
  3. package/dist/{GlobalDebugOverlay-DYCR0FIu.js → GlobalDebugOverlay-DQtUdNeF.js} +28 -28
  4. package/dist/debugOverlayStore-D7FT6zPE.js +135 -0
  5. package/dist/debugOverlayStore-DY09saU8.cjs +1 -0
  6. package/dist/index-DZ0itiBD.js +1299 -0
  7. package/dist/index-DqATP_BA.cjs +2 -0
  8. package/dist/index.cjs +1 -1
  9. package/dist/index.d.ts +2 -29
  10. package/dist/index.js +25 -13
  11. package/dist/src/GlobalDebugOverlay.d.ts.map +1 -0
  12. package/dist/src/Panel.d.ts +46 -0
  13. package/dist/src/Panel.d.ts.map +1 -0
  14. package/dist/src/PanelDebugInfo.d.ts +34 -0
  15. package/dist/src/PanelDebugInfo.d.ts.map +1 -0
  16. package/dist/src/PanelGroup.d.ts.map +1 -0
  17. package/dist/{PanelResizeHandle.d.ts → src/PanelResizeHandle.d.ts} +1 -1
  18. package/dist/src/PanelResizeHandle.d.ts.map +1 -0
  19. package/dist/src/allocateLayout.d.ts +60 -0
  20. package/dist/src/allocateLayout.d.ts.map +1 -0
  21. package/dist/src/context.d.ts.map +1 -0
  22. package/dist/{debugOverlayStore.d.ts → src/debugOverlayStore.d.ts} +10 -2
  23. package/dist/src/debugOverlayStore.d.ts.map +1 -0
  24. package/dist/src/hooks.d.ts +48 -0
  25. package/dist/src/hooks.d.ts.map +1 -0
  26. package/dist/src/index.d.ts +32 -0
  27. package/dist/src/index.d.ts.map +1 -0
  28. package/dist/src/reducer.d.ts +49 -0
  29. package/dist/src/reducer.d.ts.map +1 -0
  30. package/dist/src/roundHalfToEven.d.ts.map +1 -0
  31. package/dist/src/types.d.ts +481 -0
  32. package/dist/src/types.d.ts.map +1 -0
  33. package/dist/src/utils/simple-logger.d.ts.map +1 -0
  34. package/dist/src/utils.d.ts +164 -0
  35. package/dist/src/utils.d.ts.map +1 -0
  36. package/dist/styles/resize-panels.standalone.css +1 -1
  37. package/dist/tests/support/dom-harness.d.ts +89 -0
  38. package/dist/tests/support/dom-harness.d.ts.map +1 -0
  39. package/package.json +3 -3
  40. package/src/GlobalDebugOverlay.tsx +3 -3
  41. package/src/Panel.tsx +203 -541
  42. package/src/PanelDebugInfo.tsx +52 -106
  43. package/src/PanelGroup.tsx +27 -42
  44. package/src/PanelResizeHandle.tsx +544 -504
  45. package/src/allocateLayout.ts +412 -0
  46. package/src/debugOverlayStore.ts +19 -15
  47. package/src/hooks.ts +187 -779
  48. package/src/index.ts +37 -6
  49. package/src/reducer.ts +364 -1126
  50. package/src/types.ts +282 -65
  51. package/src/utils.ts +205 -164
  52. package/dist/GlobalDebugOverlay-afs0vF-Q.cjs +0 -1
  53. package/dist/GlobalDebugOverlay.d.ts.map +0 -1
  54. package/dist/Panel.d.ts +0 -7
  55. package/dist/Panel.d.ts.map +0 -1
  56. package/dist/PanelDebugInfo.d.ts +0 -26
  57. package/dist/PanelDebugInfo.d.ts.map +0 -1
  58. package/dist/PanelGroup.d.ts.map +0 -1
  59. package/dist/PanelResizeHandle.d.ts.map +0 -1
  60. package/dist/context.d.ts.map +0 -1
  61. package/dist/debugOverlayStore-Cntyxboe.js +0 -141
  62. package/dist/debugOverlayStore-Dkl-fHoa.cjs +0 -1
  63. package/dist/debugOverlayStore.d.ts.map +0 -1
  64. package/dist/hooks.d.ts +0 -45
  65. package/dist/hooks.d.ts.map +0 -1
  66. package/dist/index-BzgId8aQ.js +0 -1972
  67. package/dist/index-xTV-c0PN.cjs +0 -2
  68. package/dist/index.d.ts.map +0 -1
  69. package/dist/reducer.d.ts +0 -39
  70. package/dist/reducer.d.ts.map +0 -1
  71. package/dist/roundHalfToEven.d.ts.map +0 -1
  72. package/dist/types.d.ts +0 -253
  73. package/dist/types.d.ts.map +0 -1
  74. package/dist/utils/simple-logger.d.ts.map +0 -1
  75. package/dist/utils.d.ts +0 -61
  76. package/dist/utils.d.ts.map +0 -1
  77. /package/dist/{GlobalDebugOverlay.d.ts → src/GlobalDebugOverlay.d.ts} +0 -0
  78. /package/dist/{PanelGroup.d.ts → src/PanelGroup.d.ts} +0 -0
  79. /package/dist/{context.d.ts → src/context.d.ts} +0 -0
  80. /package/dist/{roundHalfToEven.d.ts → src/roundHalfToEven.d.ts} +0 -0
  81. /package/dist/{utils → src/utils}/simple-logger.d.ts +0 -0
@@ -4,145 +4,91 @@
4
4
  */
5
5
 
6
6
  import { type CSSProperties, memo, useMemo } from "react"
7
+ import { resolvePanelBounds } from "./allocateLayout"
7
8
  import type { PanelDirection, PanelLayoutData } from "./types"
9
+ import { toRoundedPercentage } from "./utils"
8
10
 
9
11
  type PanelDebugInfoProps = {
10
12
  panel: PanelLayoutData | undefined
11
- measuredPixelSize: number
12
- measuredPercentageSize: number
13
13
  containerAxisSize: number
14
14
  direction: PanelDirection
15
15
  }
16
16
 
17
17
  type FormatPanelDebugInfoArgs = {
18
18
  panel: PanelLayoutData | undefined
19
- measuredPixelSize: number
20
- measuredPercentageSize: number
21
19
  containerAxisSize: number
22
20
  containerLabel: string
23
21
  }
24
22
 
25
23
  type FormattedPanelDebugInfo = {
26
- stateValueDisplay: string
27
- measuredValueDisplay: string
24
+ sizeDisplay: string
25
+ preferenceDisplay: string
26
+ boundsDisplay: string
28
27
  containerDisplay: string
29
28
  headlineLabel: string
30
29
  titleText: string
31
30
  }
32
31
 
33
- export const formatPanelDebugInfo = ({ panel, measuredPixelSize, measuredPercentageSize, containerAxisSize, containerLabel }: FormatPanelDebugInfoArgs): FormattedPanelDebugInfo => {
34
- const rawStatePixelSize = panel?.size
35
- const statePixelDisplay = typeof rawStatePixelSize === "number" && Number.isFinite(rawStatePixelSize) ? `${rawStatePixelSize.toFixed(3)}px` : "-"
36
- const statePercentageDisplay = panel?.percentageSize !== undefined ? `${panel.percentageSize.toFixed(3)}%` : "-"
37
- const measuredPixelDisplay = Number.isFinite(measuredPixelSize) ? `${measuredPixelSize.toFixed(3)}px` : "-"
38
- const measuredPercentageDisplay = Number.isFinite(measuredPercentageSize) ? `${measuredPercentageSize.toFixed(3)}%` : "-"
39
- const containerDisplay = Number.isFinite(containerAxisSize) ? `${containerAxisSize.toFixed(3)}px` : "-"
40
- const stateValueDisplay = `${statePixelDisplay} / ${statePercentageDisplay}`
41
- const measuredValueDisplay = `${measuredPixelDisplay} / ${measuredPercentageDisplay}`
42
- const headlineLabel = panel?.sizeUnit === "pixels" ? "Fixed" : "Flexible"
43
- const titleLines = [headlineLabel, `${containerLabel}: ${containerDisplay}`, `size (state): ${stateValueDisplay}`, `size (measured): ${measuredValueDisplay}`]
44
- return {
45
- stateValueDisplay,
46
- measuredValueDisplay,
47
- containerDisplay,
48
- headlineLabel,
49
- titleText: titleLines.join("\n"),
32
+ /**
33
+ * Format one panel's allocation for the debug overlay.
34
+ * デバッグ表示用に 1 枚のパネルの配分結果を整形する処理。
35
+ *
36
+ * @param args - Panel, container length and the axis label / パネル・コンテナ長・軸ラベル
37
+ * @returns Display strings for the overlay / オーバーレイ表示用の文字列群
38
+ */
39
+ export const formatPanelDebugInfo = ({ panel, containerAxisSize, containerLabel }: FormatPanelDebugInfoArgs): FormattedPanelDebugInfo => {
40
+ if (!panel) {
41
+ return { sizeDisplay: "-", preferenceDisplay: "-", boundsDisplay: "-", containerDisplay: "-", headlineLabel: "Unregistered", titleText: "Unregistered" }
50
42
  }
43
+
44
+ const isPixel = panel.sizeUnit === "pixels"
45
+ const sizeDisplay = `${panel.size.toFixed(3)}px / ${toRoundedPercentage(panel.size, containerAxisSize).toFixed(3)}%`
46
+ const preferenceDisplay = isPixel ? `${panel.preferredPixelSize.toFixed(3)}px` : `${panel.preferredPercentageSize.toFixed(3)}%`
47
+ const bounds = resolvePanelBounds(panel, containerAxisSize)
48
+ const boundsDisplay = `${bounds.min.toFixed(1)} - ${bounds.max.toFixed(1)}px`
49
+ const containerDisplay = Number.isFinite(containerAxisSize) ? `${containerAxisSize.toFixed(3)}px` : "-"
50
+ const headlineLabel = isPixel ? "Fixed" : "Flexible"
51
+ const titleText = [headlineLabel, `${containerLabel}: ${containerDisplay}`, `size: ${sizeDisplay}`, `preference: ${preferenceDisplay}`, `bounds: ${boundsDisplay}`].join("\n")
52
+
53
+ return { sizeDisplay, preferenceDisplay, boundsDisplay, containerDisplay, headlineLabel, titleText }
51
54
  }
52
55
 
53
- export const PanelDebugInfo = memo(({ panel, measuredPixelSize, measuredPercentageSize, containerAxisSize, direction }: PanelDebugInfoProps) => {
56
+ /**
57
+ * Render the per-panel debug badge inside a panel.
58
+ * パネル内にパネル単位のデバッグバッジを描画するコンポーネント。
59
+ */
60
+ export const PanelDebugInfo = memo(({ panel, containerAxisSize, direction }: PanelDebugInfoProps) => {
54
61
  const containerLabel = direction === "horizontal" ? "container width" : "container height"
55
- const { stateValueDisplay, measuredValueDisplay, containerDisplay, headlineLabel, titleText } = useMemo(
56
- () =>
57
- formatPanelDebugInfo({
58
- panel,
59
- measuredPixelSize,
60
- measuredPercentageSize,
61
- containerAxisSize,
62
- containerLabel,
63
- }),
64
- [panel, measuredPixelSize, measuredPercentageSize, containerAxisSize, containerLabel],
65
- )
62
+ const { sizeDisplay, preferenceDisplay, boundsDisplay, containerDisplay, headlineLabel, titleText } = useMemo(() => formatPanelDebugInfo({ panel, containerAxisSize, containerLabel }), [panel, containerAxisSize, containerLabel])
66
63
 
67
- const containerStyle: CSSProperties = {
64
+ const badgeStyle: CSSProperties = {
68
65
  position: "absolute",
69
- top: "2px",
70
- right: "4px",
71
- backgroundColor: "rgba(30, 41, 59, 0.6)",
72
- color: "#fff",
73
- padding: "4px 8px",
74
- borderRadius: "6px",
75
- fontSize: "11px",
76
- fontFamily: "monospace",
77
- pointerEvents: "auto",
78
- zIndex: 10,
79
- boxShadow: "0 2px 4px rgba(0,0,0,0.3)",
66
+ top: 2,
67
+ left: 2,
68
+ zIndex: 30,
69
+ pointerEvents: "none",
70
+ maxWidth: "calc(100% - 4px)",
71
+ padding: "2px 4px",
72
+ borderRadius: 4,
80
73
  border: "1px solid rgba(255,255,255,0.1)",
81
- maxWidth: "calc(100% - 12px)",
82
- minWidth: "60px",
83
- width: "fit-content",
84
- overflow: "hidden",
85
- }
86
-
87
- const wrapperStyle: CSSProperties = {
88
- display: "flex",
89
- flexDirection: "column",
90
- gap: "1px",
91
- minWidth: "0",
92
- width: "100%",
93
- }
94
-
95
- const headlineStyle: CSSProperties = {
96
- display: "flex",
97
- justifyContent: "flex-start",
98
- alignItems: "center",
99
- gap: "6px",
100
- fontSize: "10px",
101
- color: "#ccc",
102
- whiteSpace: "nowrap",
103
- overflow: "hidden",
104
- textOverflow: "ellipsis",
105
- minWidth: "0",
106
- width: "100%",
107
- }
108
-
109
- const debugLineStyle: CSSProperties = {
110
- display: "flex",
111
- justifyContent: "space-between",
112
- alignItems: "center",
113
- gap: "6px",
114
- whiteSpace: "nowrap",
74
+ backgroundColor: "rgba(15, 23, 42, 0.78)",
75
+ color: "#e2e8f0",
76
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
77
+ fontSize: 10,
78
+ lineHeight: 1.35,
79
+ whiteSpace: "pre",
115
80
  overflow: "hidden",
116
81
  textOverflow: "ellipsis",
117
- minWidth: "0",
118
- width: "100%",
119
- }
120
-
121
- const debugValueStyle: CSSProperties = {
122
- marginLeft: "auto",
123
- fontVariantNumeric: "tabular-nums",
124
- whiteSpace: "nowrap",
125
82
  }
126
83
 
127
84
  return (
128
- <div style={containerStyle} title={titleText}>
129
- <div style={wrapperStyle}>
130
- <div style={headlineStyle}>
131
- <span>{headlineLabel}</span>
132
- </div>
133
- <div style={debugLineStyle}>
134
- <span>{containerLabel}</span>
135
- <span style={debugValueStyle}>{containerDisplay}</span>
136
- </div>
137
- <div style={debugLineStyle}>
138
- <span>size (state)</span>
139
- <span style={debugValueStyle}>{stateValueDisplay}</span>
140
- </div>
141
- <div style={debugLineStyle}>
142
- <span>size (measured)</span>
143
- <span style={debugValueStyle}>{measuredValueDisplay}</span>
144
- </div>
85
+ <div style={badgeStyle} title={titleText} data-panel-debug-info="">
86
+ <div>
87
+ {headlineLabel} · {containerLabel}: {containerDisplay}
145
88
  </div>
89
+ <div>size: {sizeDisplay}</div>
90
+ <div>preference: {preferenceDisplay}</div>
91
+ <div>bounds: {boundsDisplay}</div>
146
92
  </div>
147
93
  )
148
94
  })
@@ -3,11 +3,12 @@
3
3
  * カスタムリサイズ可能パネルのための PanelGroup コンポーネント
4
4
  */
5
5
 
6
- import { type CSSProperties, lazy, Suspense, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"
6
+ import { lazy, Suspense, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"
7
7
  import { twMerge } from "tailwind-merge"
8
8
  import { PanelGroupContext } from "./context"
9
+ import type { DebugPanelSnapshot } from "./debugOverlayStore"
9
10
  import { useResizablePanels } from "./hooks"
10
- import type { PanelGroupProps } from "./types"
11
+ import type { PanelGroupProps, PanelLayoutData } from "./types"
11
12
  import { getContainerSize } from "./utils"
12
13
 
13
14
  // デバッグオーバーレイ (UI とストア) は dynamic import で遅延読み込みする。
@@ -16,6 +17,10 @@ const LazyDebugOverlayGate = lazy(() => import("./GlobalDebugOverlay").then((mod
16
17
 
17
18
  type DebugOverlayStoreModule = typeof import("./debugOverlayStore")
18
19
 
20
+ /** Stable empty collections used while the debug overlay is off. デバッグ表示が無効な間に使う不変の空コレクション。 */
21
+ const EMPTY_PANELS: ReadonlyArray<PanelLayoutData> = []
22
+ const EMPTY_MEASUREMENTS: Record<string, never> = {}
23
+
19
24
  let debugGroupIdCounter = 0
20
25
 
21
26
  /**
@@ -29,7 +34,6 @@ const generateDebugGroupId = () => {
29
34
 
30
35
  type ResizablePanelsContextValue = ReturnType<typeof useResizablePanels>["contextValue"]
31
36
  type LayoutConstraintViolation = NonNullable<ResizablePanelsContextValue["layoutConstraintViolation"]>
32
- type DebugPanel = ResizablePanelsContextValue["panels"][number]
33
37
  type DebugPanelMeasurementMap = ResizablePanelsContextValue["panelMeasurements"]
34
38
 
35
39
  /**
@@ -39,9 +43,7 @@ type DebugPanelMeasurementMap = ResizablePanelsContextValue["panelMeasurements"]
39
43
  const buildConstraintCopy = (violation: LayoutConstraintViolation) => {
40
44
  const isMinimum = violation.reason === "minimum-exceeded"
41
45
  const summary = isMinimum ? "Layout unavailable: minimum panel sizes exceed the container." : "Layout unavailable: panels cannot fill the container with their maximum sizes."
42
- const detail = isMinimum
43
- ? `Min required: ${Math.ceil(violation.totalMinimumSize ?? 0)}px | Available: ${Math.floor(violation.availableContainerSize)}px`
44
- : `Max total: ${Math.floor(violation.totalMaximumSize ?? 0)}px | Needed: ${Math.floor(violation.availableContainerSize)}px`
46
+ const detail = isMinimum ? `Min required: ${Math.ceil(violation.totalMinimumSize)}px | Available: ${Math.floor(violation.availableContainerSize)}px` : `Max total: ${Math.floor(violation.totalMaximumSize)}px | Needed: ${Math.floor(violation.availableContainerSize)}px`
45
47
  return { summary, detail }
46
48
  }
47
49
 
@@ -49,25 +51,14 @@ const buildConstraintCopy = (violation: LayoutConstraintViolation) => {
49
51
  * Synchronizes measured panel dimensions into overlay panel descriptors.
50
52
  * 測定済みパネル寸法をオーバーレイ用パネル情報へ同期。
51
53
  */
52
- const mergePanelMeasurements = (panels: ReadonlyArray<DebugPanel>, measurementMap: DebugPanelMeasurementMap): DebugPanel[] => {
53
- let changed = false
54
- const nextPanels = panels.map((panel) => {
54
+ const mergePanelMeasurements = (panels: ReadonlyArray<PanelLayoutData>, measurementMap: DebugPanelMeasurementMap): DebugPanelSnapshot[] =>
55
+ panels.map((panel) => {
55
56
  const measurement = measurementMap[panel.id]
56
57
  if (!measurement) {
57
58
  return panel
58
59
  }
59
- if (panel.measuredPixelSize === measurement.pixelSize && panel.measuredPercentageSize === measurement.percentageSize) {
60
- return panel
61
- }
62
- changed = true
63
- return {
64
- ...panel,
65
- measuredPixelSize: measurement.pixelSize,
66
- measuredPercentageSize: measurement.percentageSize,
67
- }
60
+ return { ...panel, measuredPixelSize: measurement.pixelSize, measuredPercentageSize: measurement.percentageSize }
68
61
  })
69
- return changed ? nextPanels : (panels as DebugPanel[])
70
- }
71
62
 
72
63
  /**
73
64
  * Measures overlay container dimensions with graceful fallbacks.
@@ -77,8 +68,8 @@ const measureDebugOverlayContainerSize = (element: HTMLElement, fallbackWidth?:
77
68
  const horizontal = getContainerSize(element, "horizontal")
78
69
  const vertical = getContainerSize(element, "vertical")
79
70
  const rect = element.getBoundingClientRect()
80
- const width = horizontal.inner > 0 ? horizontal.inner : (fallbackWidth ?? rect.width)
81
- const height = vertical.inner > 0 ? vertical.inner : (fallbackHeight ?? rect.height)
71
+ const width = horizontal.content > 0 ? horizontal.content : (fallbackWidth ?? rect.width)
72
+ const height = vertical.content > 0 ? vertical.content : (fallbackHeight ?? rect.height)
82
73
  return { width, height }
83
74
  }
84
75
 
@@ -87,7 +78,7 @@ const measureDebugOverlayContainerSize = (element: HTMLElement, fallbackWidth?:
87
78
  * 連動するパネルのためのレイアウトコンテキストとコンテナを提供するコンポーネント。
88
79
  */
89
80
  export const PanelGroup = (props: PanelGroupProps) => {
90
- const { id, className, style, children, direction } = props
81
+ const { id, className, style, children, direction, onLayout, autoSaveId, showDebugInfo, ...elementProps } = props
91
82
  const { groupRef, contextValue, groupStyle } = useResizablePanels(props)
92
83
 
93
84
  const [debugOverlayContainerSize, setDebugOverlayContainerSize] = useState({ width: 0, height: 0 })
@@ -109,13 +100,18 @@ export const PanelGroup = (props: PanelGroupProps) => {
109
100
  )
110
101
  }, [constraintViolation])
111
102
 
112
- const debugGroupIdRef = useRef(id ?? generateDebugGroupId())
103
+ // useRef の引数は毎レンダー評価されるため、そこで採番するとレンダーが純粋でなくなる
104
+ const debugGroupIdRef = useRef<string | null>(null)
105
+ if (debugGroupIdRef.current === null) {
106
+ debugGroupIdRef.current = id ?? generateDebugGroupId()
107
+ }
113
108
  const debugGroupId = debugGroupIdRef.current
114
109
  const debugDisplayName = id ?? debugGroupId
115
110
 
116
111
  const shouldShowDebugOverlay = contextValue.showDebugInfo && contextValue.panels.length > 0
117
- const debugOverlayPanels = shouldShowDebugOverlay ? contextValue.panels : []
118
- const debugOverlayMeasurementMap = shouldShowDebugOverlay ? contextValue.panelMeasurements : {}
112
+ // 無効時に空のリテラルを作ると参照が毎レンダー変わり、下流の useMemo が無駄に再計算される
113
+ const debugOverlayPanels = shouldShowDebugOverlay ? contextValue.panels : EMPTY_PANELS
114
+ const debugOverlayMeasurementMap = shouldShowDebugOverlay ? contextValue.panelMeasurements : EMPTY_MEASUREMENTS
119
115
  const debugOverlayHandles = useMemo(() => {
120
116
  if (!shouldShowDebugOverlay) {
121
117
  return []
@@ -126,9 +122,8 @@ export const PanelGroup = (props: PanelGroupProps) => {
126
122
  }
127
123
  return handles.slice().sort((a, b) => a.id.localeCompare(b.id))
128
124
  }, [contextValue.handleMeasurements, shouldShowDebugOverlay])
129
- const containerSize = contextValue.containerSize
130
- const debugOverlayContainerWidth = debugOverlayContainerSize.width > 0 ? debugOverlayContainerSize.width : containerSize.width
131
- const debugOverlayContainerHeight = debugOverlayContainerSize.height > 0 ? debugOverlayContainerSize.height : containerSize.height
125
+ const debugOverlayContainerWidth = debugOverlayContainerSize.width
126
+ const debugOverlayContainerHeight = debugOverlayContainerSize.height
132
127
 
133
128
  useLayoutEffect(() => {
134
129
  // shouldShowDebugOverlay と groupRef に応じてデバッグオーバーレイ用コンテナ寸法を監視
@@ -217,20 +212,9 @@ export const PanelGroup = (props: PanelGroupProps) => {
217
212
  }
218
213
  }, [shouldShowDebugOverlay, debugGroupId, debugDisplayName, direction, debugOverlayContainerWidth, debugOverlayContainerHeight, debugOverlayPanelsWithMeasurements, debugOverlayHandles])
219
214
 
220
- const mergedStyle = useMemo(() => {
221
- const baseStyle: CSSProperties = {
222
- ...groupStyle,
223
- ...style,
224
- }
225
- if (!baseStyle.position) {
226
- baseStyle.position = "relative"
227
- }
228
- return baseStyle
229
- }, [groupStyle, style])
230
-
231
215
  return (
232
216
  <PanelGroupContext.Provider value={contextValue}>
233
- <div ref={groupRef} className={twMerge("panel-group", direction === "horizontal" ? "flex-row" : "flex-col", className)} style={mergedStyle} data-panel-group-id={id} data-panel-group-direction={direction}>
217
+ <div {...elementProps} ref={groupRef} className={twMerge("panel-group", direction === "horizontal" ? "flex-row" : "flex-col", className)} style={groupStyle} data-panel-group-id={id} data-panel-group-direction={direction}>
234
218
  {children}
235
219
  {shouldRenderPlaceholder && placeholderInner ? (
236
220
  <div
@@ -238,7 +222,8 @@ export const PanelGroup = (props: PanelGroupProps) => {
238
222
  style={{
239
223
  position: "absolute",
240
224
  inset: 0,
241
- zIndex: 40,
225
+ // パネル内部要素 (VirtualScroll のスクロールバー z-50 等) を完全に隠蔽するため zIndex を 60 に設定
226
+ zIndex: 60,
242
227
  display: "flex",
243
228
  flexDirection: "column",
244
229
  alignItems: "center",