@aiquants/resize-panels 1.8.1 → 1.9.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.
package/README.md CHANGED
@@ -1,36 +1,37 @@
1
1
  # @aiquants/resize-panels
2
2
 
3
- React 向けのリサイズ可能なパネルレイアウトコンポーネント集です。`~/components/elements/ResizablePanels` で培ったロジックをパッケージ化し、任意のアプリケーションから再利用できるようにしました。
3
+ Resizable panel layout components for React. Packages the layout management, DOM measurement, and snapping logic previously used in application templates into a reusable library.
4
4
 
5
- ## 主な特徴
5
+ ## Key Features
6
6
 
7
- - `PanelGroup` `Panel` `PanelResizeHandle` を中核に、リデューサーでレイアウトと DOM 計測を同期
8
- - `calculateSnapThreshold` とノイズ除去ロジックでリサイズ時の揺らぎを抑え、意図しない折りたたみを防止
9
- - 方向指定付き `collapsible` 設定と `usePanelControls` により、ドラッグ操作と UI 操作の両方で折りたたみ / 展開を制御
10
- - リサイズハンドルはマウス/タッチのドラッグに加え、**矢印キーによるキーボードリサイズ**にも対応(Shift 併用で 5 倍ステップ)。マルチタッチや `pointercancel` の割込みでもドラッグ状態が壊れない
11
- - `dir="rtl"` **RTL レイアウト**でも、ドラッグ・キーボード・ハンドル位置が視覚方向に一致
12
- - `autoSaveId` を指定するとローカルストレージにパネルサイズを自動保存し、再読み込み時に復元(初期化確定後のサイズのみ保存)
13
- - `showDebugInfo` を使えば `PanelDebugInfo` とグローバルオーバーレイで計測結果や制約違反を可視化(デバッグ UI は遅延読み込みで、未使用時は本番バンドルに含まれない)
7
+ - **Core Components**: `PanelGroup`, `Panel`, and `PanelResizeHandle` synchronized via a central state reducer for layout and DOM measurements.
8
+ - **Snap & Noise Filtering**: Uses `calculateSnapThreshold` and noise filtering to prevent layout jitter and unwanted collapse during resizing.
9
+ - **Directional Collapsible Control**: Declarative `collapsible` settings (`from: 'start' | 'end' | 'both'`) and `usePanelControls` hook support collapsing/expanding via both drag actions and UI controls.
10
+ - **Keyboard & Touch Accessibility**: Handles support mouse/touch dragging as well as **keyboard navigation via arrow keys** (5x step multiplier with Shift). Drag states remain robust under multi-touch or `pointercancel` interruptions.
11
+ - **Full RTL Layout Support**: Under `dir="rtl"`, drag interactions, keyboard shortcuts, and handle positions automatically mirror visual layout directions.
12
+ - **Auto-Persistence**: Set `autoSaveId` to save panel sizes to `localStorage` (debounced after layout stabilization) and restore state on page reloads.
13
+ - **Debug & Visualization**: Enable `showDebugInfo` to inspect panel metrics and constraint violations via `PanelDebugInfo` and a global debug overlay (dynamically lazy-loaded, zero overhead in production bundles).
14
14
 
15
- ## インストール
15
+ ## Installation
16
16
 
17
- ワークスペース内で利用する場合は `pnpm` を利用します。
17
+ Monorepo workspace dependency:
18
18
 
19
- ```bash
20
- pnpm add @aiquants/resize-panels
19
+ ```jsonc
20
+ // consumer package.json
21
+ {
22
+ "dependencies": {
23
+ "@aiquants/resize-panels": "workspace:*"
24
+ }
25
+ }
21
26
  ```
22
27
 
23
- モノレポ内から参照する場合は `package.json` に次のように記載します。
28
+ Standard package manager installation:
24
29
 
25
- ```json
26
- {
27
- "dependencies": {
28
- "@aiquants/resize-panels": "workspace:*"
29
- }
30
- }
30
+ ```bash
31
+ pnpm add @aiquants/resize-panels
31
32
  ```
32
33
 
33
- ## クイックスタート
34
+ ## Quick Start
34
35
 
35
36
  ```tsx
36
37
  import { useId } from "react"
@@ -42,36 +43,36 @@ export const Example = () => {
42
43
  return (
43
44
  <PanelGroup id={`${baseId}-group`} direction="horizontal" className="h-96">
44
45
  <Panel id={`${baseId}-left`} defaultSize={{ value: 200, unit: "pixels" }} className="bg-slate-100">
45
- 左パネル
46
+ Left Panel
46
47
  </Panel>
47
48
  <PanelResizeHandle id={`${baseId}-handle`} />
48
49
  <Panel id={`${baseId}-right`} defaultSize={{ value: 60, unit: "percentage" }} className="bg-slate-50">
49
- 右パネル
50
+ Right Panel
50
51
  </Panel>
51
52
  </PanelGroup>
52
53
  )
53
54
  }
54
55
  ```
55
56
 
56
- ### 折りたたみを有効にする
57
+ ### Enabling Collapsible Panels
57
58
 
58
- `Panel` `collapsible={{ from: "start" }}` `collapsible={{ from: "end" }}` を指定すると、対応する `PanelResizeHandle` を端までドラッグしたタイミングで自動的に折りたたみ・展開が行われます。`defaultCollapsed` を併用すると初期状態を折りたたみ済みに設定できます。方向指定は必須で、各パネルがどちら側から折りたためるかを宣言します。両方向に対応したい場合は `collapsible={{ from: "both" }}` を使用します。
59
+ Specify `collapsible={{ from: "start" }}` or `collapsible={{ from: "end" }}` on a `Panel` to enable automatic collapse/expand when dragging the corresponding handle to container boundaries. Set `defaultCollapsed` to set initial state to collapsed. Use `collapsible={{ from: "both" }}` to allow collapsing from either edge.
59
60
 
60
61
  ```tsx
61
62
  <PanelGroup direction="horizontal" className="h-96">
62
63
  <Panel id="sidebar" defaultSize={{ value: 240, unit: "pixels" }} collapsible={{ from: "end" }}>
63
- サイドバー
64
+ Sidebar
64
65
  </Panel>
65
66
  <PanelResizeHandle id="handle" />
66
67
  <Panel id="main" defaultSize={{ value: 60, unit: "percentage" }}>
67
- メインコンテンツ
68
+ Main Content
68
69
  </Panel>
69
70
  </PanelGroup>
70
71
  ```
71
72
 
72
- ### UI から折りたたみ / 展開を切り替える
73
+ ### Programmatic Controls via Hook
73
74
 
74
- `usePanelControls(panelId)` フックを使うと、任意の UI から対象パネルを折りたたみ・展開・トグルできます。ボタンを配置するコンポーネントは `PanelGroup` の配下(コンテキスト内)に置いてください。折りたたみ後もボタンを表示したい場合は、別パネルやヘッダーなど常に可視な場所に設置します。API は方向を必須パラメーターとして受け取り、パネル構成に応じて呼び出し側で指定します。
75
+ Use `usePanelControls(panelId)` inside any child component of `PanelGroup` to trigger collapse, expand, or toggle actions:
75
76
 
76
77
  ```tsx
77
78
  import { PanelGroup, Panel, PanelResizeHandle, usePanelControls } from "@aiquants/resize-panels"
@@ -84,13 +85,13 @@ const PanelToggleButtons = ({ panelId, label }: { panelId: string; label: string
84
85
  <div className="flex items-center gap-2">
85
86
  <span>{label}</span>
86
87
  <button onClick={() => collapse(direction)} disabled={(!canCollapseFromStart && !canCollapseFromEnd) || isCollapsed}>
87
- 折りたたむ
88
+ Collapse
88
89
  </button>
89
90
  <button onClick={() => expand(direction)} disabled={!isCollapsed || (!canCollapseFromStart && !canCollapseFromEnd)}>
90
- 展開する
91
+ Expand
91
92
  </button>
92
93
  <button onClick={() => toggle(direction)} disabled={!canCollapseFromStart && !canCollapseFromEnd}>
93
- {isCollapsed ? "展開に切り替え" : "折りたたみに切り替え"}
94
+ {isCollapsed ? "Switch to Expand" : "Switch to Collapse"}
94
95
  </button>
95
96
  </div>
96
97
  )
@@ -99,119 +100,116 @@ const PanelToggleButtons = ({ panelId, label }: { panelId: string; label: string
99
100
  export const Example = () => (
100
101
  <PanelGroup direction="horizontal" className="h-96">
101
102
  <Panel id="sidebar" defaultSize={{ value: 240, unit: "pixels" }} collapsible={{ from: "end" }}>
102
- <PanelToggleButtons panelId="sidebar" label="サイドバー" />
103
+ <PanelToggleButtons panelId="sidebar" label="Sidebar" />
103
104
  </Panel>
104
105
  <PanelResizeHandle id="split" />
105
106
  <Panel id="main" defaultSize={{ value: 60, unit: "percentage" }}>
106
- <PanelToggleButtons panelId="details" label="詳細パネル" />
107
+ <PanelToggleButtons panelId="details" label="Details Panel" />
107
108
  </Panel>
108
109
  <PanelResizeHandle id="split-right" />
109
110
  <Panel id="details" defaultSize={{ value: 40, unit: "percentage" }} collapsible={{ from: "start" }}>
110
- 詳細
111
+ Details
111
112
  </Panel>
112
113
  </PanelGroup>
113
114
  )
114
115
  ```
115
116
 
116
- `collapse(direction)` は指定方向からパネルを非表示にし、`expand(direction)` はドラッグ操作と同じロジックで直前のサイズや推奨サイズを復元します。`toggle(direction)` を使うと現在の状態に応じて自動的に切り替わります。
117
-
118
- ## コンポーネント API
117
+ ## Component API
119
118
 
120
- ### PanelGroup の主なプロパティ
119
+ ### PanelGroup Properties
121
120
 
122
- | プロパティ | | 説明 |
121
+ | Property | Type | Description |
123
122
  | --- | --- | --- |
124
- | `id` | `string` | `data-panel-group-id` にも反映される識別子。複数グループを並べる場合は指定を推奨 |
125
- | `direction` | `'horizontal' \| 'vertical'` | パネルの配置方向 |
126
- | `className` / `style` | `string` / `React.CSSProperties` | コンテナの見た目を調整するための追加スタイル |
127
- | `children` | `React.ReactNode` | グループ内の `Panel` `PanelResizeHandle` を並べるための子要素 |
128
- | `showDebugInfo` | `boolean` | `PanelDebugInfo` とグローバルオーバーレイを表示して計測結果と制約違反を可視化 |
129
- | `onLayout` | `(sizes: number[]) => void` | リサイズや初期化のたびに最新のピクセルサイズ配列を通知 |
130
- | `autoSaveId` | `string` | 指定すると `localStorage` にパネルサイズを保存・復元 |
123
+ | `id` | `string` | Group identifier (reflected in `data-panel-group-id`). Recommended when mounting multiple groups |
124
+ | `direction` | `'horizontal' \| 'vertical'` | Panel layout orientation |
125
+ | `className` / `style` | `string` / `React.CSSProperties` | Additional styling for the container |
126
+ | `children` | `React.ReactNode` | `Panel` and `PanelResizeHandle` child elements |
127
+ | `showDebugInfo` | `boolean` | Enables `PanelDebugInfo` and global debug overlay |
128
+ | `onLayout` | `(sizes: number[]) => void` | Callback emitting updated pixel size arrays on resize/init |
129
+ | `autoSaveId` | `string` | Key used to automatically persist and restore panel sizes in `localStorage` |
131
130
 
132
- ### Panel の主なプロパティ
131
+ ### Panel Properties
133
132
 
134
- | プロパティ | | 説明 |
133
+ | Property | Type | Description |
135
134
  | --- | --- | --- |
136
- | `id` | `string` | パネル識別子。省略時はランダム生成だが、SSR との整合のため明示指定を推奨 |
137
- | `defaultSize` | `{ value: number; unit: 'pixels' \| 'percentage' } \| number` | 初期サイズ。数値のみの場合はパーセンテージとして扱う |
138
- | `minSize` / `maxSize` | `FlexibleSize` | パネルの最小・最大サイズ制約。ピクセル・割合で指定可能 |
139
- | `collapsible` | `{ from: 'start' \| 'end' \| 'both' }` | 折りたたみ方向の宣言。ドラッグや API 呼び出しで利用される必須設定 |
140
- | `defaultCollapsed` | `boolean` | 初期状態を折りたたみ済みにするかどうか |
141
- | `pixelAdjustPriority` | `number` | 余白調整時にピクセル基準パネルへ割り当てる優先度 |
142
- | `className` / `style` | `string` / `React.CSSProperties` | パネル本体の見た目をカスタマイズ |
135
+ | `id` | `string` | Panel identifier. Explicit string required for SSR consistency |
136
+ | `defaultSize` | `{ value: number; unit: 'pixels' \| 'percentage' } \| number` | Initial panel size (numbers parsed as percentages) |
137
+ | `minSize` / `maxSize` | `FlexibleSize` | Panel size boundaries (pixels or percentages) |
138
+ | `collapsible` | `{ from: 'start' \| 'end' \| 'both' }` | Declarative collapsible edge configuration |
139
+ | `defaultCollapsed` | `boolean` | Whether the panel starts collapsed |
140
+ | `pixelAdjustPriority` | `number` | Priority for assigning excess space to pixel-based panels |
141
+ | `className` / `style` | `string` / `React.CSSProperties` | Panel container styles |
143
142
 
144
- ### PanelResizeHandle の主なプロパティ
143
+ ### PanelResizeHandle Properties
145
144
 
146
- | プロパティ | | 説明 |
145
+ | Property | Type | Description |
147
146
  | --- | --- | --- |
148
- | `id` | `string` | ハンドル識別子。省略時はランダム生成 |
149
- | `disabled` | `boolean` | `true` にするとドラッグ・キーボード操作を無効化 |
150
- | `onDragging` | `(isDragging: boolean) => void` | ドラッグ開始 / 終了ごとに呼び出されるコールバック(`pointercancel` 等の割込みでも終了時に発火) |
151
- | `className` / `style` | `string` / `React.CSSProperties` | ハンドル見た目を追加カスタマイズ |
152
- | `children` | `React.ReactNode` | 独自のハンドルインジケーターを描画する場合に使用 |
153
-
154
- > ハンドルは `<button>` としてレンダリングされ、フォーカス時に矢印キー(水平なら `←` / `→`、垂直なら `↑` / `↓`)でリサイズできます。`Shift` 併用で 1 押下あたりの移動量が 5 倍になります。`dir="rtl"` のコンテナ内ではドラッグ・キーボードの方向が視覚方向に合わせて反転します。
147
+ | `id` | `string` | Handle identifier (reflected in `data-resize-handle-id`) |
148
+ | `disabled` | `boolean` | Disables mouse dragging and keyboard resizing when `true` |
149
+ | `thickness` | `number` | Primary axis thickness of the handle's interactive area in pixels (`8px` default) |
150
+ | `indicator` | `boolean \| PanelResizeHandleIndicatorConfig` | Toggle indicator visibility or provide custom pill/bar dimensions and CSS classes |
151
+ | `indicatorThickness` | `number` | Shorthand for indicator pill wrapper thickness in pixels (`6px` default) |
152
+ | `indicatorLength` | `number` | Shorthand for indicator pill wrapper length in pixels (`48px` horizontal / `80px` vertical default) |
153
+ | `indicatorBarThickness` | `number` | Shorthand for indicator inner bar thickness in pixels (`2px` default) |
154
+ | `indicatorBarLength` | `number` | Shorthand for indicator inner bar length in pixels (`32px` horizontal / `64px` vertical default) |
155
+ | `title` | `string` | Custom tooltip text for the handle element |
156
+ | `onDragging` | `(isDragging: boolean) => void` | Callback triggered on drag start and end (including `pointercancel`) |
157
+ | `className` / `style` | `string` / `React.CSSProperties` | Additional styling for the resize handle |
158
+ | `children` | `React.ReactNode` | Custom indicator element rendered inside handle (overrides default indicator) |
155
159
 
156
- ## フックとユーティリティ
160
+ > Handles render as `<button>` elements accessible via arrow keys (`←`/`→` for horizontal, `↑`/`↓` for vertical). Holding `Shift` increases step distance 5x. Under `dir="rtl"`, keyboard and drag directions adjust to visual layout. Dimension options snap to integer pixels via `roundHalfToEven` to eliminate subpixel blurring.
157
161
 
158
- - `useResizablePanels`: `PanelGroup` 内部実装でも利用しているフック。カスタムコンテナを作る場合に役立ちます。
159
- - `usePanelGroup`: コンテキストを直接参照し、パネルリストやレイアウト情報を取得できます。
160
- - `usePanelControls`: 特定パネルに対する折りたたみ / 展開操作を提供します。
161
- - `saveLayout` と `loadLayout`: 任意のタイミングでレイアウトを永続化 / 復元できます。
162
- - `getPanelElement`, `getPanelGroupElement`, `getResizeHandleElement`: `data-*` 属性をもとに DOM 要素を取得します。
162
+ ## Hooks & Utilities
163
163
 
164
- ## レイアウト保存と復元
164
+ - `useResizablePanels`: Internal hook used by `PanelGroup`. Useful for building custom panel containers.
165
+ - `usePanelGroup`: Context accessor for panel lists and layout state.
166
+ - `usePanelControls`: Provides `collapse`, `expand`, and `toggle` operations for a specified panel ID.
167
+ - `saveLayout` & `loadLayout`: Programmatically persist or restore layout state.
168
+ - `getPanelElement`, `getPanelGroupElement`, `getResizeHandleElement`: DOM element query helpers via `data-*` attributes.
165
169
 
166
- `PanelGroup` `autoSaveId` を指定すると、`ResizeObserver` が安定した後のパネルサイズを 200ms デバウンス付きで `localStorage` に保存します。ページを再読み込みすると `loadLayout(autoSaveId)` の結果が自動的に反映され、ピクセル基準パネルと割合基準パネルの両方が復元されます。手動で制御したい場合は公開ユーティリティの `saveLayout` / `loadLayout` を直接呼び出してください。
170
+ ## Layout Persistence
167
171
 
168
- ## デバッグと可視化
172
+ When `autoSaveId` is provided to `PanelGroup`, panel dimensions are saved to `localStorage` (debounced by 200ms after `ResizeObserver` stabilization). Re-opening the page automatically applies `loadLayout(autoSaveId)` to restore both pixel- and percentage-based panels.
169
173
 
170
- `PanelGroup` `showDebugInfo` を有効にすると、各 `Panel` に `PanelDebugInfo` が表示され、折りたたみ状態・計測サイズ・保持中の割合が即座に確認できます。同時にグローバルオーバーレイが開き、コンテナの実測サイズ、制約違反の有無、ハンドル厚み(`PANEL_HANDLE_THICKNESS` で定義された 8px)なども一覧できます。
174
+ ## Debugging & Inspection
171
175
 
172
- グローバルオーバーレイとそのストアは `React.lazy` + dynamic import で遅延読み込みされるため、`showDebugInfo` を一度も使わないアプリの本番バンドルにはデバッグ UI もストア購読も含まれません。
176
+ Enabling `showDebugInfo` on `PanelGroup` renders overlay inspection metrics over each `Panel` (showing collapse status, measured dimensions, and percentages) along with a global container inspector listing handle thickness (8px default) and constraint alerts. Debug components are lazily imported (`React.lazy`) and excluded from production builds when unused.
173
177
 
174
- ## スナップとノイズ対策・最終整合の挙動
178
+ ## Styling (CSS)
175
179
 
176
- `PanelResizeHandle` `Panel` の両方で `calculateSnapThreshold` を利用し、コンテナサイズに応じたゼロスナップ閾値を共有しています。`Panel` および `PanelGroup` では、サブピクセル単位の微小なノイズ(0.5px 未満の揺れ)を無視するフィルタリングと、動作停止後に正確な真値を反映する **最終整合メカニズム(デバウンス同期)** を導入しています。これにより、スクロールやリサイズ中のチラつきを抑えつつ、最終的な表示状態と内部状態の完全な一致を保証します。
180
+ The package provides two CSS consumption options:
177
181
 
178
- ## スタイル (CSS)
179
-
180
- 大半のスタイルは JSX ベタ書きの Tailwind ユーティリティで持つため、CSS アーティファクトを **2 種類**配布する。ホストの種類で読み込み方を選ぶ。
181
-
182
- - **Tailwind v4 ホスト**: components-only ビルドを `layer(components)` で読み込み、JSX ユーティリティは自アプリの Tailwind ビルドにパッケージ `src` をスキャンさせて生成する。
182
+ - **Tailwind v4 Host**: Import components-only styles into `layer(components)` and configure Tailwind to scan package source files:
183
183
 
184
184
  ```css
185
185
  /* app tailwind.css */
186
186
  @import "@aiquants/resize-panels/styles/resize-panels.css" layer(components);
187
187
  @source "../node_modules/@aiquants/resize-panels/src/**/*.{ts,tsx}";
188
- /* モノレポ: @source "../../../../packages/resize-panels/src/**/*.{ts,tsx}"; */
188
+ /* monorepo: @source "../../../../packages/resize-panels/src/**/*.{ts,tsx}"; */
189
189
  ```
190
190
 
191
- `resize-panels.css` (Artifact A) は手書きコンポーネントクラスのみで、スタイルの大半が JSX ユーティリティのためほぼ空になる。**preflight・`:root` テーマ変数・Tailwind ユーティリティを含まない**。preflight Tailwind ホストへ流し込むとホストの base 層を破壊するため、Artifact A には同梱しない (preflight は standalone だけが持つ)。standalone ビルドをここで併用してはならない (同名ユーティリティが重複しカスケードが反転する)。
192
-
193
- - **非 Tailwind ホスト**: 自己完結の standalone ビルドを 1 本だけ読み込む。preflight と全ユーティリティを同梱する。
191
+ - **Non-Tailwind Host**: Import the self-contained standalone CSS bundle:
194
192
 
195
193
  ```css
196
194
  @import "@aiquants/resize-panels/styles/resize-panels.standalone.css";
197
195
  ```
198
196
 
199
- ダークは `<html>` `.dark` クラス基準。
197
+ Dark mode activates based on the `.dark` class on `<html>`.
200
198
 
201
- ## デモ
199
+ ## Demo App
202
200
 
203
- モノレポ内に簡易デモアプリを用意しています。
201
+ Run the included workspace demo app:
204
202
 
205
203
  ```bash
206
204
  pnpm --filter '@aiquants/resize-panels-demo' dev
207
205
  ```
208
206
 
209
- `http://localhost:5175` にアクセスすると複数レイアウトを含むデモを確認できます。
207
+ Open `http://localhost:5175` to test interactive layouts.
210
208
 
211
- ## ビルド
209
+ ## Build
212
210
 
213
211
  ```bash
214
212
  pnpm --filter '@aiquants/resize-panels' build
215
213
  ```
216
214
 
217
- 生成物は `dist` に出力されます。
215
+ Outputs built artifacts to `dist/`.
@@ -2,7 +2,7 @@ import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
2
  import { useState as A } from "react";
3
3
  import { createPortal as P } from "react-dom";
4
4
  import { useDebugOverlayOwnerId as R, useDebugOverlaySnapshot as T } from "./debugOverlayStore-Cntyxboe.js";
5
- import { P as Y } from "./index-BzgId8aQ.js";
5
+ import { P as Y } from "./index-B6YGX2DH.js";
6
6
  const a = (s, n) => typeof s != "number" || !Number.isFinite(s) ? "—" : `${(s < 0 ? 0 : s).toFixed(8)}${n}`, w = {
7
7
  position: "fixed",
8
8
  left: "50%",
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),A=require("react"),R=require("react-dom"),x=require("./debugOverlayStore-Dkl-fHoa.cjs"),P=require("./index-xTV-c0PN.cjs"),o=(n,r)=>typeof n!="number"||!Number.isFinite(n)?"—":`${(n<0?0:n).toFixed(8)}${r}`,T={position:"fixed",left:"50%",bottom:"20px",transform:"translate(-50%, 0)",zIndex:100,maxWidth:"min(90vw, 1120px)",width:"100%",borderRadius:"14px",backgroundColor:"rgba(15, 23, 42, 0.72)",color:"#e2e8f0",fontFamily:"monospace",fontSize:"11px",lineHeight:1.6,boxShadow:"0 22px 45px rgba(15,23,42,0.45)",border:"1px solid rgba(148, 163, 184, 0.22)",backdropFilter:"blur(10px)",WebkitBackdropFilter:"blur(10px)",pointerEvents:"auto",overflow:"auto"},Y={display:"flex",justifyContent:"space-between",alignItems:"center",flexWrap:"wrap",gap:"12px"},w={display:"flex",flexDirection:"column",gap:"4px"},D={padding:"6px 10px",borderRadius:"9999px",border:"1px solid rgba(148, 163, 184, 0.35)",color:"#e2e8f0",fontWeight:600,fontSize:"10px",letterSpacing:"0.03em",textTransform:"uppercase",cursor:"pointer",transition:"background-color 0.18s ease, border-color 0.18s ease"},C={padding:"10px 12px",borderRadius:"10px",backgroundColor:"rgba(30, 41, 59, 0.55)",border:"1px solid rgba(148, 163, 184, 0.18)",display:"flex",flexDirection:"column",gap:"10px"},N={padding:"8px 10px",borderRadius:"8px",backgroundColor:"rgba(15, 23, 42, 0.55)",border:"1px solid rgba(148, 163, 184, 0.16)",display:"flex",flexDirection:"column",gap:"4px"},p={display:"flex",justifyContent:"space-between",alignItems:"center",gap:"6px"},k={display:"grid",gridTemplateColumns:"auto 1fr",gap:"2px 10px",color:"#e2e8f0"},G={padding:"2px 6px",borderRadius:"9999px",fontSize:"10px",textTransform:"uppercase"},I=({groupId:n})=>x.useDebugOverlayOwnerId()!==n?null:e.jsx(u,{}),u=()=>{const r=x.useDebugOverlaySnapshot().groups,[t,g]=A.useState(!0);if(r.length===0||typeof document>"u")return null;const b=r.reduce((i,a)=>i+a.panels.length,0),h=r.reduce((i,a)=>i+(a.handles?.length??0),0),m=()=>g(i=>!i),f=e.jsxs("div",{style:{...T,padding:t?"10px 18px":"14px 18px",maxHeight:t?"52px":"min(65vh, 520px)",transition:"max-height 0.24s ease, padding 0.24s ease"},children:[e.jsxs("div",{style:{...Y,marginBottom:t?0:"12px"},children:[e.jsxs("div",{style:w,children:[e.jsx("span",{style:{fontWeight:700,fontSize:"12px",letterSpacing:"0.03em"},children:"Panel Overview"}),e.jsxs("span",{style:{color:"#cbd5f5"},children:["groups: ",r.length," / panels: ",b," / resizers: ",h]})]}),e.jsx("button",{type:"button",onClick:m,style:{...D,backgroundColor:t?"rgba(59, 130, 246, 0.2)":"rgba(71, 85, 105, 0.45)"},title:t?"Panel Overview を開く":"Panel Overview を閉じる",children:t?"開く":"閉じる"})]}),!t&&e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"12px",maxHeight:"45vh",overflowY:"auto",paddingRight:"6px"},children:r.map((i,a)=>{const l=i.direction==="horizontal"?i.containerSize.width:i.containerSize.height;return e.jsxs("div",{style:C,children:[e.jsxs("div",{style:{...p,flexWrap:"wrap",gap:"10px",color:"#dbeafe"},children:[e.jsxs("span",{style:{fontWeight:600,fontSize:"11px",letterSpacing:"0.02em",textTransform:"uppercase"},children:["group ",a+1,": ",i.displayName]}),e.jsxs("span",{children:["direction: ",i.direction," / container: ",o(i.containerSize.width,"px")," × ",o(i.containerSize.height,"px")]})]}),e.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(220px, 1fr))",gap:"10px"},children:i.panels.map((s,y)=>{const d=s.measuredPixelSize??s.size,S=s.size,j=o(S,"px"),v=s.percentageSize??(l>0?s.size/l*100:void 0),O=s.measuredPercentageSize!==void 0?s.measuredPercentageSize:l>0?d/l*100:void 0,c=s.collapsed||d<=P.PANEL_SNAP_THRESHOLD,E=s.collapsed?"collapsed":c?"hidden":"visible",z=o(v,"%"),L=o(O,"%"),_=o(d,"px");return e.jsxs("div",{style:N,children:[e.jsxs("div",{style:p,children:[e.jsx("span",{style:{flex:1,minWidth:0,overflow:"hidden",textOverflow:"ellipsis"},children:s.id}),e.jsx("span",{style:{...G,backgroundColor:s.collapsed?"rgba(251, 113, 133, 0.25)":c?"rgba(250, 204, 21, 0.25)":"rgba(74, 222, 128, 0.25)",color:s.collapsed?"#fecdd3":c?"#fef08a":"#bbf7d0"},children:E})]}),e.jsxs("div",{style:k,children:[e.jsx("span",{children:"size (state):"}),e.jsx("span",{children:j}),e.jsx("span",{children:"size (measured):"}),e.jsx("span",{children:_}),e.jsx("span",{children:"percentage (state):"}),e.jsx("span",{children:z}),e.jsx("span",{children:"percentage (measured):"}),e.jsx("span",{children:L}),e.jsx("span",{children:"unit:"}),e.jsx("span",{children:s.sizeUnit}),e.jsx("span",{children:"min:"}),e.jsx("span",{children:s.minSize!==void 0?JSON.stringify(s.minSize):"—"}),e.jsx("span",{children:"auto min:"}),e.jsx("span",{children:s.autoMinSize!==void 0?JSON.stringify(s.autoMinSize):"—"}),e.jsx("span",{children:"max:"}),e.jsx("span",{children:s.maxSize!==void 0?JSON.stringify(s.maxSize):"—"}),e.jsx("span",{children:"priority:"}),e.jsx("span",{children:s.pixelAdjustPriority??"—"}),e.jsx("span",{children:"flex priority:"}),e.jsx("span",{children:s.flexAdjustPriority??"—"})]})]},s.id||y)})})]},i.groupId)})})]});return R.createPortal(f,document.body)};exports.GlobalDebugOverlay=u;exports.GlobalDebugOverlayGate=I;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),A=require("react"),R=require("react-dom"),x=require("./debugOverlayStore-Dkl-fHoa.cjs"),P=require("./index-DssZUxGw.cjs"),o=(n,r)=>typeof n!="number"||!Number.isFinite(n)?"—":`${(n<0?0:n).toFixed(8)}${r}`,T={position:"fixed",left:"50%",bottom:"20px",transform:"translate(-50%, 0)",zIndex:100,maxWidth:"min(90vw, 1120px)",width:"100%",borderRadius:"14px",backgroundColor:"rgba(15, 23, 42, 0.72)",color:"#e2e8f0",fontFamily:"monospace",fontSize:"11px",lineHeight:1.6,boxShadow:"0 22px 45px rgba(15,23,42,0.45)",border:"1px solid rgba(148, 163, 184, 0.22)",backdropFilter:"blur(10px)",WebkitBackdropFilter:"blur(10px)",pointerEvents:"auto",overflow:"auto"},Y={display:"flex",justifyContent:"space-between",alignItems:"center",flexWrap:"wrap",gap:"12px"},w={display:"flex",flexDirection:"column",gap:"4px"},D={padding:"6px 10px",borderRadius:"9999px",border:"1px solid rgba(148, 163, 184, 0.35)",color:"#e2e8f0",fontWeight:600,fontSize:"10px",letterSpacing:"0.03em",textTransform:"uppercase",cursor:"pointer",transition:"background-color 0.18s ease, border-color 0.18s ease"},C={padding:"10px 12px",borderRadius:"10px",backgroundColor:"rgba(30, 41, 59, 0.55)",border:"1px solid rgba(148, 163, 184, 0.18)",display:"flex",flexDirection:"column",gap:"10px"},N={padding:"8px 10px",borderRadius:"8px",backgroundColor:"rgba(15, 23, 42, 0.55)",border:"1px solid rgba(148, 163, 184, 0.16)",display:"flex",flexDirection:"column",gap:"4px"},p={display:"flex",justifyContent:"space-between",alignItems:"center",gap:"6px"},k={display:"grid",gridTemplateColumns:"auto 1fr",gap:"2px 10px",color:"#e2e8f0"},G={padding:"2px 6px",borderRadius:"9999px",fontSize:"10px",textTransform:"uppercase"},I=({groupId:n})=>x.useDebugOverlayOwnerId()!==n?null:e.jsx(u,{}),u=()=>{const r=x.useDebugOverlaySnapshot().groups,[t,g]=A.useState(!0);if(r.length===0||typeof document>"u")return null;const b=r.reduce((i,a)=>i+a.panels.length,0),h=r.reduce((i,a)=>i+(a.handles?.length??0),0),m=()=>g(i=>!i),f=e.jsxs("div",{style:{...T,padding:t?"10px 18px":"14px 18px",maxHeight:t?"52px":"min(65vh, 520px)",transition:"max-height 0.24s ease, padding 0.24s ease"},children:[e.jsxs("div",{style:{...Y,marginBottom:t?0:"12px"},children:[e.jsxs("div",{style:w,children:[e.jsx("span",{style:{fontWeight:700,fontSize:"12px",letterSpacing:"0.03em"},children:"Panel Overview"}),e.jsxs("span",{style:{color:"#cbd5f5"},children:["groups: ",r.length," / panels: ",b," / resizers: ",h]})]}),e.jsx("button",{type:"button",onClick:m,style:{...D,backgroundColor:t?"rgba(59, 130, 246, 0.2)":"rgba(71, 85, 105, 0.45)"},title:t?"Panel Overview を開く":"Panel Overview を閉じる",children:t?"開く":"閉じる"})]}),!t&&e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"12px",maxHeight:"45vh",overflowY:"auto",paddingRight:"6px"},children:r.map((i,a)=>{const l=i.direction==="horizontal"?i.containerSize.width:i.containerSize.height;return e.jsxs("div",{style:C,children:[e.jsxs("div",{style:{...p,flexWrap:"wrap",gap:"10px",color:"#dbeafe"},children:[e.jsxs("span",{style:{fontWeight:600,fontSize:"11px",letterSpacing:"0.02em",textTransform:"uppercase"},children:["group ",a+1,": ",i.displayName]}),e.jsxs("span",{children:["direction: ",i.direction," / container: ",o(i.containerSize.width,"px")," × ",o(i.containerSize.height,"px")]})]}),e.jsx("div",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(220px, 1fr))",gap:"10px"},children:i.panels.map((s,y)=>{const d=s.measuredPixelSize??s.size,S=s.size,j=o(S,"px"),v=s.percentageSize??(l>0?s.size/l*100:void 0),O=s.measuredPercentageSize!==void 0?s.measuredPercentageSize:l>0?d/l*100:void 0,c=s.collapsed||d<=P.PANEL_SNAP_THRESHOLD,E=s.collapsed?"collapsed":c?"hidden":"visible",z=o(v,"%"),L=o(O,"%"),_=o(d,"px");return e.jsxs("div",{style:N,children:[e.jsxs("div",{style:p,children:[e.jsx("span",{style:{flex:1,minWidth:0,overflow:"hidden",textOverflow:"ellipsis"},children:s.id}),e.jsx("span",{style:{...G,backgroundColor:s.collapsed?"rgba(251, 113, 133, 0.25)":c?"rgba(250, 204, 21, 0.25)":"rgba(74, 222, 128, 0.25)",color:s.collapsed?"#fecdd3":c?"#fef08a":"#bbf7d0"},children:E})]}),e.jsxs("div",{style:k,children:[e.jsx("span",{children:"size (state):"}),e.jsx("span",{children:j}),e.jsx("span",{children:"size (measured):"}),e.jsx("span",{children:_}),e.jsx("span",{children:"percentage (state):"}),e.jsx("span",{children:z}),e.jsx("span",{children:"percentage (measured):"}),e.jsx("span",{children:L}),e.jsx("span",{children:"unit:"}),e.jsx("span",{children:s.sizeUnit}),e.jsx("span",{children:"min:"}),e.jsx("span",{children:s.minSize!==void 0?JSON.stringify(s.minSize):"—"}),e.jsx("span",{children:"auto min:"}),e.jsx("span",{children:s.autoMinSize!==void 0?JSON.stringify(s.autoMinSize):"—"}),e.jsx("span",{children:"max:"}),e.jsx("span",{children:s.maxSize!==void 0?JSON.stringify(s.maxSize):"—"}),e.jsx("span",{children:"priority:"}),e.jsx("span",{children:s.pixelAdjustPriority??"—"}),e.jsx("span",{children:"flex priority:"}),e.jsx("span",{children:s.flexAdjustPriority??"—"})]})]},s.id||y)})})]},i.groupId)})})]});return R.createPortal(f,document.body)};exports.GlobalDebugOverlay=u;exports.GlobalDebugOverlayGate=I;
@@ -3,5 +3,5 @@ import { PanelResizeHandleProps } from './types';
3
3
  * Render an interactive divider that manages adjacent panel resizing gestures.
4
4
  * 隣接パネルのリサイズ操作を管理するインタラクティブなディバイダーを描画するコンポーネント。
5
5
  */
6
- export declare const PanelResizeHandle: import('react').MemoExoticComponent<({ id, disabled, className, style, children, onDragging }: PanelResizeHandleProps) => import("react").JSX.Element>;
6
+ export declare const PanelResizeHandle: import('react').MemoExoticComponent<(props: PanelResizeHandleProps) => import("react").JSX.Element>;
7
7
  //# sourceMappingURL=PanelResizeHandle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PanelResizeHandle.d.ts","sourceRoot":"","sources":["../src/PanelResizeHandle.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAUH,KAAK,sBAAsB,EAE9B,MAAM,SAAS,CAAA;AAGhB;;;GAGG;AACH,eAAO,MAAM,iBAAiB,iGAA2E,sBAAsB,iCAkrB7H,CAAA"}
1
+ {"version":3,"file":"PanelResizeHandle.d.ts","sourceRoot":"","sources":["../src/PanelResizeHandle.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAgBH,KAAK,sBAAsB,EAE9B,MAAM,SAAS,CAAA;AAyChB;;;GAGG;AACH,eAAO,MAAM,iBAAiB,8CAAgB,sBAAsB,iCAotBlE,CAAA"}