@aiquants/resize-panels 1.9.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +129 -22
- package/dist/GlobalDebugOverlay-Cf3GOn2A.cjs +1 -0
- package/dist/{GlobalDebugOverlay-Do70T2l6.js → GlobalDebugOverlay-DQtUdNeF.js} +28 -28
- package/dist/GlobalDebugOverlay.d.ts +1 -18
- package/dist/Panel.d.ts +13 -7
- package/dist/PanelDebugInfo.d.ts +6 -10
- package/dist/PanelGroup.d.ts +1 -6
- package/dist/PanelResizeHandle.d.ts +2 -7
- package/dist/allocateLayout.d.ts +12 -0
- package/dist/context.d.ts +2 -11
- package/dist/debugOverlayStore-D7FT6zPE.js +135 -0
- package/dist/debugOverlayStore-DY09saU8.cjs +1 -0
- package/dist/debugOverlayStore.d.ts +7 -36
- package/dist/hooks.d.ts +12 -24
- package/dist/index-DZ0itiBD.js +1299 -0
- package/dist/index-DqATP_BA.cjs +2 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +10 -26
- package/dist/index.js +25 -13
- package/dist/reducer.d.ts +7 -38
- package/dist/roundHalfToEven.d.ts +0 -9
- package/dist/styles/resize-panels.standalone.css +1 -1
- package/dist/types.d.ts +67 -261
- package/dist/utils/simple-logger.d.ts +0 -74
- package/dist/utils.d.ts +10 -55
- package/package.json +2 -3
- package/dist/GlobalDebugOverlay-sEQN6exo.cjs +0 -1
- package/dist/GlobalDebugOverlay.d.ts.map +0 -1
- package/dist/Panel.d.ts.map +0 -1
- package/dist/PanelDebugInfo.d.ts.map +0 -1
- package/dist/PanelGroup.d.ts.map +0 -1
- package/dist/PanelResizeHandle.d.ts.map +0 -1
- package/dist/context.d.ts.map +0 -1
- package/dist/debugOverlayStore-Cntyxboe.js +0 -141
- package/dist/debugOverlayStore-Dkl-fHoa.cjs +0 -1
- package/dist/debugOverlayStore.d.ts.map +0 -1
- package/dist/hooks.d.ts.map +0 -1
- package/dist/index-B6YGX2DH.js +0 -2009
- package/dist/index-DssZUxGw.cjs +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/reducer.d.ts.map +0 -1
- package/dist/roundHalfToEven.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/utils/simple-logger.d.ts.map +0 -1
- package/dist/utils.d.ts.map +0 -1
- package/src/GlobalDebugOverlay.tsx +0 -284
- package/src/Panel.tsx +0 -635
- package/src/PanelDebugInfo.tsx +0 -148
- package/src/PanelGroup.tsx +0 -260
- package/src/PanelResizeHandle.tsx +0 -797
- package/src/context.ts +0 -25
- package/src/debugOverlayStore.ts +0 -351
- package/src/hooks.ts +0 -968
- package/src/index.ts +0 -84
- package/src/reducer.ts +0 -1234
- package/src/roundHalfToEven.ts +0 -40
- package/src/styles/components.entry.css +0 -10
- package/src/styles/resize-panels.css +0 -1
- package/src/styles/standalone.entry.css +0 -12
- package/src/types.ts +0 -419
- package/src/utils/simple-logger.ts +0 -186
- package/src/utils.ts +0 -279
package/src/utils.ts
DELETED
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Utility functions for custom resizable panels
|
|
3
|
-
* カスタムリサイズ可能パネルのためのユーティリティ関数
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { roundHalfToEven } from "./roundHalfToEven"
|
|
7
|
-
import { type ContainerAxisMeasurement, type FlexibleSize, PANEL_COLLAPSE_THRESHOLD_MAX, PANEL_COLLAPSE_THRESHOLD_RATIO, PANEL_MIN_SNAP_THRESHOLD, PANEL_SNAP_THRESHOLD, type PanelDirection, type PanelLayoutData, type SizeConfig, type SizeUnit } from "./types"
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Number of significant fractional digits to preserve when rounding percentage-based sizes.
|
|
11
|
-
* パーセンテージサイズの丸めで保持する有効小数桁数。
|
|
12
|
-
*/
|
|
13
|
-
export const PERCENTAGE_DIGITS = 6
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Convert a pixel measurement to a percentage of the container using banker’s rounding.
|
|
17
|
-
* ピクセル寸法をバンカーズラウンディングでコンテナ比率のパーセンテージへ変換する。
|
|
18
|
-
*/
|
|
19
|
-
export const toRoundedPercentage = (size: number, base: number): number => {
|
|
20
|
-
if (base <= 0) {
|
|
21
|
-
return 0
|
|
22
|
-
}
|
|
23
|
-
const percentage = roundHalfToEven((size / base) * 100, PERCENTAGE_DIGITS)
|
|
24
|
-
return percentage
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Translate a percentage-based size back into pixels relative to the container.
|
|
29
|
-
* パーセンテージ指定のサイズをコンテナ基準のピクセル値へ変換する。
|
|
30
|
-
*/
|
|
31
|
-
export const percentageToPixels = (percentage: number | undefined, base: number): number => {
|
|
32
|
-
if (!percentage || base <= 0) {
|
|
33
|
-
return 0
|
|
34
|
-
}
|
|
35
|
-
return (percentage / 100) * base
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Normalize a flexible size into a size configuration object.
|
|
40
|
-
* 柔軟なサイズ指定をサイズ設定オブジェクトへ正規化する。
|
|
41
|
-
*/
|
|
42
|
-
export const normalizeSizeConfig = (size: FlexibleSize | undefined, defaultUnit: SizeUnit = "percentage"): SizeConfig | undefined => {
|
|
43
|
-
if (size === undefined) return undefined
|
|
44
|
-
if (typeof size === "number") {
|
|
45
|
-
return { value: size, unit: defaultUnit }
|
|
46
|
-
}
|
|
47
|
-
return size
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Convert flexible size constraints into pixel values based on container size.
|
|
52
|
-
* 柔軟サイズ制約をコンテナサイズ基準のピクセル値へ変換する。
|
|
53
|
-
*/
|
|
54
|
-
export const getConstraintInPixels = (size: FlexibleSize | undefined, defaultValue: number, containerSize: number): number => {
|
|
55
|
-
if (!size) return defaultValue
|
|
56
|
-
if (typeof size === "number") {
|
|
57
|
-
return (size / 100) * containerSize
|
|
58
|
-
}
|
|
59
|
-
if (size.unit === "pixels") {
|
|
60
|
-
return size.value
|
|
61
|
-
}
|
|
62
|
-
return (size.value / 100) * containerSize
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Clamp a numeric value between the provided bounds.
|
|
67
|
-
* 数値を指定した範囲に収めるためのクリッピング処理。
|
|
68
|
-
*/
|
|
69
|
-
export const clamp = (value: number, min: number, max: number): number => {
|
|
70
|
-
return Math.min(Math.max(value, min), max)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Derive a snap-to-zero threshold from the container axis length using shared heuristics.
|
|
75
|
-
* 共通ヒューリスティクスに基づきコンテナ軸長からゼロスナップ閾値を算出する。
|
|
76
|
-
*/
|
|
77
|
-
export const calculateSnapThreshold = (axisSize: number): number => {
|
|
78
|
-
if (!Number.isFinite(axisSize) || axisSize <= 0) {
|
|
79
|
-
return PANEL_MIN_SNAP_THRESHOLD
|
|
80
|
-
}
|
|
81
|
-
const thresholdFromRatio = axisSize * PANEL_COLLAPSE_THRESHOLD_RATIO
|
|
82
|
-
const cappedThreshold = Math.min(PANEL_SNAP_THRESHOLD, PANEL_COLLAPSE_THRESHOLD_MAX, thresholdFromRatio)
|
|
83
|
-
return Math.max(PANEL_MIN_SNAP_THRESHOLD, cappedThreshold)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Adjust pixel-based panels in priority order to absorb remaining space.
|
|
88
|
-
* 残余スペースを吸収するためにピクセル基準パネルを優先度順に調整する。
|
|
89
|
-
*/
|
|
90
|
-
type AdjustPixelOptions = {
|
|
91
|
-
enforceAutoMinSize?: boolean
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export const adjustPixelPanelsByPriority = (panels: PanelLayoutData[], sizeDiff: number, containerSize: number, options: AdjustPixelOptions = {}): number => {
|
|
95
|
-
if (Math.abs(sizeDiff) <= 0) {
|
|
96
|
-
return sizeDiff
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const enforceAutoMinSize = options.enforceAutoMinSize ?? false
|
|
100
|
-
|
|
101
|
-
// ピクセル指定パネルを抽出してインデックスを保持
|
|
102
|
-
const pixelPanels = panels.map((panel, index) => ({ panel, index })).filter(({ panel }) => !panel.collapsed && (panel.sizeUnit === "pixels" || panel.originalPixelSize !== undefined))
|
|
103
|
-
|
|
104
|
-
if (pixelPanels.length === 0) {
|
|
105
|
-
return sizeDiff
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// 優先度順にソート (優先度が同じ場合はインデックス順)
|
|
109
|
-
const isGrowing = sizeDiff > 0
|
|
110
|
-
const sortedPanels = [...pixelPanels].sort((a, b) => {
|
|
111
|
-
const priorityA = a.panel.pixelAdjustPriority ?? a.index + 1
|
|
112
|
-
const priorityB = b.panel.pixelAdjustPriority ?? b.index + 1
|
|
113
|
-
if (priorityA === priorityB) {
|
|
114
|
-
return isGrowing ? b.index - a.index : a.index - b.index
|
|
115
|
-
}
|
|
116
|
-
return isGrowing ? priorityB - priorityA : priorityA - priorityB
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
let remaining = sizeDiff
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Execute a single adjustment pass for pixel panels.
|
|
123
|
-
* ピクセルパネル調整処理
|
|
124
|
-
*/
|
|
125
|
-
const adjustPass = (respectPreferred: boolean) => {
|
|
126
|
-
for (const { index } of sortedPanels) {
|
|
127
|
-
if (Math.abs(remaining) <= 0) {
|
|
128
|
-
break
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const panel = panels[index]
|
|
132
|
-
if (!panel || panel.collapsed) {
|
|
133
|
-
continue
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// パネルの最小・最大サイズをピクセル値へ変換
|
|
137
|
-
// bare number は他の全経路 (getConstraintInPixels) と同じくパーセンテージとして解釈する
|
|
138
|
-
const minSizeFromConstraint = getConstraintInPixels(panel.minSize, 0, containerSize)
|
|
139
|
-
const maxSize = getConstraintInPixels(panel.maxSize, containerSize, containerSize)
|
|
140
|
-
const autoMinSize = enforceAutoMinSize ? getConstraintInPixels(panel.autoMinSize, 0, containerSize) : 0
|
|
141
|
-
const minSize = Math.max(minSizeFromConstraint, autoMinSize)
|
|
142
|
-
const preferredPixel = panel.preferredPixelSize !== undefined ? clamp(panel.preferredPixelSize, minSize, maxSize) : panel.size
|
|
143
|
-
|
|
144
|
-
const panelIsCollapsible = panel.collapseFromStart || panel.collapseFromEnd
|
|
145
|
-
if (remaining > 0) {
|
|
146
|
-
// パネルサイズがゼロかどうかを判定
|
|
147
|
-
const isZero = Math.abs(panel.size) <= 0 && (panel.percentageSize ?? 0) <= 0
|
|
148
|
-
// ゼロのパネルはスキップ
|
|
149
|
-
if (isZero) {
|
|
150
|
-
continue
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const targetSize = Math.max(panel.size, preferredPixel)
|
|
154
|
-
const effectiveMax = respectPreferred ? Math.min(maxSize, targetSize) : maxSize
|
|
155
|
-
const expansionCapacity = Math.max(0, effectiveMax - panel.size)
|
|
156
|
-
if (expansionCapacity <= 0) {
|
|
157
|
-
continue
|
|
158
|
-
}
|
|
159
|
-
const applied = Math.min(expansionCapacity, remaining)
|
|
160
|
-
if (applied <= 0) {
|
|
161
|
-
continue
|
|
162
|
-
}
|
|
163
|
-
const nextSize = panel.size + applied
|
|
164
|
-
const nextPercentage = toRoundedPercentage(nextSize, containerSize)
|
|
165
|
-
const nextSizeBeforeCollapse = panelIsCollapsible ? nextSize : panel.sizeBeforeCollapse
|
|
166
|
-
const nextMeasuredPixelBeforeCollapse = panelIsCollapsible ? (panel.measuredPixelSizeBeforeCollapse ?? panel.measuredPixelSize ?? nextSize) : panel.measuredPixelSizeBeforeCollapse
|
|
167
|
-
panels[index] = {
|
|
168
|
-
...panel,
|
|
169
|
-
size: nextSize,
|
|
170
|
-
percentageSize: nextPercentage,
|
|
171
|
-
sizeBeforeCollapse: nextSizeBeforeCollapse,
|
|
172
|
-
measuredPixelSizeBeforeCollapse: nextMeasuredPixelBeforeCollapse,
|
|
173
|
-
measuredPixelSize: undefined,
|
|
174
|
-
measuredPercentageSize: undefined,
|
|
175
|
-
}
|
|
176
|
-
remaining -= applied
|
|
177
|
-
} else {
|
|
178
|
-
const shrinkFloor = respectPreferred ? preferredPixel : minSize
|
|
179
|
-
const reductionCapacity = Math.max(0, panel.size - shrinkFloor)
|
|
180
|
-
if (reductionCapacity <= 0) {
|
|
181
|
-
continue
|
|
182
|
-
}
|
|
183
|
-
const applied = Math.min(reductionCapacity, Math.abs(remaining))
|
|
184
|
-
if (applied <= 0) {
|
|
185
|
-
continue
|
|
186
|
-
}
|
|
187
|
-
const nextSize = panel.size - applied
|
|
188
|
-
const nextPercentage = toRoundedPercentage(nextSize, containerSize)
|
|
189
|
-
const nextSizeBeforeCollapse = panelIsCollapsible ? nextSize : panel.sizeBeforeCollapse
|
|
190
|
-
const nextMeasuredPixelBeforeCollapse = panelIsCollapsible ? (panel.measuredPixelSizeBeforeCollapse ?? panel.measuredPixelSize ?? nextSize) : panel.measuredPixelSizeBeforeCollapse
|
|
191
|
-
panels[index] = {
|
|
192
|
-
...panel,
|
|
193
|
-
size: nextSize,
|
|
194
|
-
percentageSize: nextPercentage,
|
|
195
|
-
sizeBeforeCollapse: nextSizeBeforeCollapse,
|
|
196
|
-
measuredPixelSizeBeforeCollapse: nextMeasuredPixelBeforeCollapse,
|
|
197
|
-
measuredPixelSize: undefined,
|
|
198
|
-
measuredPercentageSize: undefined,
|
|
199
|
-
}
|
|
200
|
-
remaining += applied
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
adjustPass(true)
|
|
206
|
-
|
|
207
|
-
if ((isGrowing && remaining > 0) || (!isGrowing && remaining < 0)) {
|
|
208
|
-
adjustPass(false)
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return remaining
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Parse a CSS pixel string and return the numeric portion.
|
|
216
|
-
* CSS ピクセル表現から数値を抽出する処理。
|
|
217
|
-
*/
|
|
218
|
-
const parsePixelValue = (value: string | null): number => {
|
|
219
|
-
if (!value) {
|
|
220
|
-
return 0
|
|
221
|
-
}
|
|
222
|
-
const parsed = parseFloat(value)
|
|
223
|
-
return Number.isFinite(parsed) ? parsed : 0
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Measure container size in a given direction, returning inner (borderless) and outer dimensions.
|
|
228
|
-
* 指定方向で枠線控除後と控除前の両方の寸法を測定して返す。
|
|
229
|
-
*/
|
|
230
|
-
export const getContainerSize = (element: HTMLElement, direction: PanelDirection): ContainerAxisMeasurement => {
|
|
231
|
-
const rect = element.getBoundingClientRect()
|
|
232
|
-
const styles = typeof window !== "undefined" ? window.getComputedStyle(element) : null
|
|
233
|
-
const horizontalBorder = styles ? parsePixelValue(styles.borderLeftWidth) + parsePixelValue(styles.borderRightWidth) : 0
|
|
234
|
-
const verticalBorder = styles ? parsePixelValue(styles.borderTopWidth) + parsePixelValue(styles.borderBottomWidth) : 0
|
|
235
|
-
if (direction === "horizontal") {
|
|
236
|
-
const rectWidth = rect.width > 0 ? rect.width : element.offsetWidth
|
|
237
|
-
const innerWidth = rect.width > 0 ? Math.max(0, rect.width - horizontalBorder) : element.clientWidth
|
|
238
|
-
const outerWidthFallback = element.offsetWidth > 0 ? element.offsetWidth : element.clientWidth + horizontalBorder
|
|
239
|
-
// 枠線の厚みを控除した実効幅と控除前の幅をそれぞれ算出
|
|
240
|
-
return {
|
|
241
|
-
inner: innerWidth > 0 ? innerWidth : Math.max(0, element.clientWidth),
|
|
242
|
-
outer: rectWidth > 0 ? rectWidth : Math.max(0, outerWidthFallback),
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
const rectHeight = rect.height > 0 ? rect.height : element.offsetHeight
|
|
246
|
-
const innerHeight = rect.height > 0 ? Math.max(0, rect.height - verticalBorder) : element.clientHeight
|
|
247
|
-
const outerHeightFallback = element.offsetHeight > 0 ? element.offsetHeight : element.clientHeight + verticalBorder
|
|
248
|
-
// 枠線控除後の高さと控除前の高さを併せて返却
|
|
249
|
-
return {
|
|
250
|
-
inner: innerHeight > 0 ? innerHeight : Math.max(0, element.clientHeight),
|
|
251
|
-
outer: rectHeight > 0 ? rectHeight : Math.max(0, outerHeightFallback),
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Persist panel layout sizes to local storage.
|
|
257
|
-
* パネルレイアウトのサイズをローカルストレージへ保存する。
|
|
258
|
-
*/
|
|
259
|
-
export const saveLayout = (id: string, sizes: number[]): void => {
|
|
260
|
-
try {
|
|
261
|
-
localStorage.setItem(`panel-layout-${id}`, JSON.stringify(sizes))
|
|
262
|
-
} catch (error) {
|
|
263
|
-
console.warn("Failed to save panel layout:", error)
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Restore panel layout sizes from local storage.
|
|
269
|
-
* パネルレイアウトのサイズをローカルストレージから復元する。
|
|
270
|
-
*/
|
|
271
|
-
export const loadLayout = (id: string): number[] | null => {
|
|
272
|
-
try {
|
|
273
|
-
const saved = localStorage.getItem(`panel-layout-${id}`)
|
|
274
|
-
return saved ? JSON.parse(saved) : null
|
|
275
|
-
} catch (error) {
|
|
276
|
-
console.warn("Failed to load panel layout:", error)
|
|
277
|
-
return null
|
|
278
|
-
}
|
|
279
|
-
}
|