@principal-ade/panel-layouts 0.1.4 → 0.1.6
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 +29 -29
- package/dist/index.css +1 -1
- package/dist/index.d.ts +122 -12
- package/dist/index.esm.js +313 -185
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
> Pre-built panel layout components and workspace management for the Panel Framework
|
|
4
4
|
|
|
5
|
-
This package provides ready-to-use panel layout components, workspace presets, and persistence hooks that work with `@principal-ade/panel-framework-core`. Built on top of `@
|
|
5
|
+
This package provides ready-to-use panel layout components, workspace presets, and persistence hooks that work with `@principal-ade/panel-framework-core`. Built on top of `@principal-ade/panels`, it adds workspace management, persistence, and pre-configured layouts from the electron-app.
|
|
6
6
|
|
|
7
7
|
## 🎯 Purpose
|
|
8
8
|
|
|
9
9
|
While `@principal-ade/panel-framework-core` provides the foundation for how panels *work* (registration, lifecycle, events), this package handles how panels *arrange on screen* (layouts, resizing, workspaces).
|
|
10
10
|
|
|
11
|
-
This package = **@
|
|
11
|
+
This package = **@principal-ade/panels** (layout primitives) + **persistence** + **workspace management** + **preset layouts**
|
|
12
12
|
|
|
13
13
|
## 📦 What This Package Provides
|
|
14
14
|
|
|
15
|
-
### Re-exported Components (from @
|
|
15
|
+
### Re-exported Components (from @principal-ade/panels)
|
|
16
16
|
|
|
17
|
-
We re-export the core layout components from `@
|
|
17
|
+
We re-export the core layout components from `@principal-ade/panels` for convenience:
|
|
18
18
|
|
|
19
19
|
- **`ConfigurablePanelLayout`** - Main layout component supporting 2 or 3 panel configurations
|
|
20
20
|
- **`TabGroup`** - Tab-based panel grouping
|
|
@@ -26,7 +26,7 @@ These components provide:
|
|
|
26
26
|
- Resizable panels with drag handles (powered by `react-resizable-panels`)
|
|
27
27
|
- Collapsible panels with animations
|
|
28
28
|
- Tab groups and tile arrangements
|
|
29
|
-
- Theme integration with `@
|
|
29
|
+
- Theme integration with `@principal-ade/industry-theme`
|
|
30
30
|
- 2-panel and 3-panel layout support
|
|
31
31
|
|
|
32
32
|
### Our Value-Add: Hooks (Extracted from electron-app)
|
|
@@ -90,10 +90,10 @@ Three-panel layout optimized for repository exploration:
|
|
|
90
90
|
|
|
91
91
|
## 📋 Type Definitions
|
|
92
92
|
|
|
93
|
-
### Re-exported from @
|
|
93
|
+
### Re-exported from @principal-ade/panels
|
|
94
94
|
|
|
95
95
|
```typescript
|
|
96
|
-
// Panel Layout Structure (from @
|
|
96
|
+
// Panel Layout Structure (from @principal-ade/panels)
|
|
97
97
|
interface PanelLayout {
|
|
98
98
|
left?: PanelSlot;
|
|
99
99
|
middle?: PanelSlot;
|
|
@@ -246,7 +246,7 @@ WorkspaceLayoutService.createCustomWorkspace({
|
|
|
246
246
|
```
|
|
247
247
|
@principal-ade/panel-layouts/
|
|
248
248
|
├── src/
|
|
249
|
-
│ ├── index.ts # Main entry - re-exports from @
|
|
249
|
+
│ ├── index.ts # Main entry - re-exports from @principal-ade/panels + our code
|
|
250
250
|
│ ├── layouts/
|
|
251
251
|
│ │ ├── FeedViewLayout.tsx # Pre-built feed view
|
|
252
252
|
│ │ ├── ProjectManagementLayout.tsx # Project management preset
|
|
@@ -271,7 +271,7 @@ WorkspaceLayoutService.createCustomWorkspace({
|
|
|
271
271
|
└── LICENSE
|
|
272
272
|
```
|
|
273
273
|
|
|
274
|
-
**Note:** We don't duplicate `ConfigurablePanelLayout`, `TabGroup`, etc. - we re-export them from `@
|
|
274
|
+
**Note:** We don't duplicate `ConfigurablePanelLayout`, `TabGroup`, etc. - we re-export them from `@principal-ade/panels`.
|
|
275
275
|
|
|
276
276
|
## 🔗 Dependencies
|
|
277
277
|
|
|
@@ -283,40 +283,40 @@ WorkspaceLayoutService.createCustomWorkspace({
|
|
|
283
283
|
"react-dom": ">=18.0.0"
|
|
284
284
|
},
|
|
285
285
|
"dependencies": {
|
|
286
|
-
"@
|
|
287
|
-
"@
|
|
286
|
+
"@principal-ade/panels": "^1.0.39",
|
|
287
|
+
"@principal-ade/industry-theme": "^0.1.2",
|
|
288
288
|
"react-resizable-panels": "^3.0.0"
|
|
289
289
|
}
|
|
290
290
|
}
|
|
291
291
|
```
|
|
292
292
|
|
|
293
293
|
**Architecture:**
|
|
294
|
-
- We depend on `@
|
|
295
|
-
- `@
|
|
296
|
-
- We re-export components from `@
|
|
294
|
+
- We depend on `@principal-ade/panels` for layout primitives (ConfigurablePanelLayout, TabGroup, etc.)
|
|
295
|
+
- `@principal-ade/panels` depends on `react-resizable-panels` for resizing functionality
|
|
296
|
+
- We re-export components from `@principal-ade/panels` for convenience
|
|
297
297
|
- We add our own persistence, workspace management, and preset layouts on top
|
|
298
298
|
|
|
299
299
|
## 🎨 Design Principles
|
|
300
300
|
|
|
301
301
|
### 1. Layered Architecture
|
|
302
302
|
- **@principal-ade/panel-framework-core:** Panel registration, lifecycle, events
|
|
303
|
-
- **@
|
|
303
|
+
- **@principal-ade/panels:** Layout primitives, resizing, collapsing, theming
|
|
304
304
|
- **@principal-ade/panel-layouts (this package):** Persistence, workspaces, presets
|
|
305
305
|
|
|
306
306
|
### 2. Reuse Over Rebuild
|
|
307
|
-
We build on top of proven components (`@
|
|
307
|
+
We build on top of proven components (`@principal-ade/panels`) rather than reinventing the wheel. This allows us to:
|
|
308
308
|
- Focus on high-value features (workspaces, persistence)
|
|
309
309
|
- Get resizing, animations, and theming for free
|
|
310
310
|
- Maintain compatibility with existing electron-app code
|
|
311
311
|
|
|
312
312
|
### 3. Optional Dependency
|
|
313
|
-
Users can use `@principal-ade/panel-framework-core` + `@
|
|
313
|
+
Users can use `@principal-ade/panel-framework-core` + `@principal-ade/panels` directly if they don't need workspace management.
|
|
314
314
|
|
|
315
315
|
### 4. Composable
|
|
316
316
|
All components are composable - users can:
|
|
317
317
|
- Use pre-built layouts as-is (`FeedViewLayout`)
|
|
318
318
|
- Use `ConfigurablePanelLayout` with custom configs
|
|
319
|
-
- Use `@
|
|
319
|
+
- Use `@principal-ade/panels` directly for full control
|
|
320
320
|
|
|
321
321
|
### 5. Persistence-Ready
|
|
322
322
|
Built-in support for saving/loading layout state to:
|
|
@@ -328,11 +328,11 @@ Built-in support for saving/loading layout state to:
|
|
|
328
328
|
|
|
329
329
|
### Phase 1: Package Setup and Re-exports
|
|
330
330
|
1. ✅ Set up package structure with TypeScript and Vite
|
|
331
|
-
2. ✅ Install `@
|
|
332
|
-
3. ✅ Create re-export index that exposes components from `@
|
|
331
|
+
2. ✅ Install `@principal-ade/panels` as a dependency
|
|
332
|
+
3. ✅ Create re-export index that exposes components from `@principal-ade/panels`
|
|
333
333
|
4. ✅ Configure build to output ESM/CJS with CSS
|
|
334
334
|
|
|
335
|
-
**What we're doing:** Setting up the foundation and making `@
|
|
335
|
+
**What we're doing:** Setting up the foundation and making `@principal-ade/panels` components available through our package.
|
|
336
336
|
|
|
337
337
|
### Phase 2: Extract Persistence Hook (High Priority)
|
|
338
338
|
1. Extract `usePanelPersistence` from electron-app
|
|
@@ -343,7 +343,7 @@ Built-in support for saving/loading layout state to:
|
|
|
343
343
|
**Source File:**
|
|
344
344
|
- `/Users/griever/Developer/electron-app/src/renderer/hooks/usePanelPersistence.ts`
|
|
345
345
|
|
|
346
|
-
**What we're doing:** Adding the state persistence layer that `@
|
|
346
|
+
**What we're doing:** Adding the state persistence layer that `@principal-ade/panels` doesn't provide.
|
|
347
347
|
|
|
348
348
|
### Phase 3: Extract Workspace Service
|
|
349
349
|
1. Extract `WorkspaceLayoutService` from electron-app
|
|
@@ -380,7 +380,7 @@ Built-in support for saving/loading layout state to:
|
|
|
380
380
|
Once published, the electron-app can replace its current implementation:
|
|
381
381
|
|
|
382
382
|
```diff
|
|
383
|
-
- import { ConfigurablePanelLayout } from '@
|
|
383
|
+
- import { ConfigurablePanelLayout } from '@principal-ade/panels';
|
|
384
384
|
- import { usePanelPersistence } from '../hooks/usePanelPersistence';
|
|
385
385
|
+ import { ConfigurablePanelLayout, usePanelPersistence } from '@principal-ade/panel-layouts';
|
|
386
386
|
```
|
|
@@ -395,8 +395,8 @@ Benefits:
|
|
|
395
395
|
|
|
396
396
|
- **@principal-ade/panel-framework-core** - Core panel system (published)
|
|
397
397
|
- **@principal-ade/panel-layouts** - This package (to be implemented)
|
|
398
|
-
- **@
|
|
399
|
-
- **@
|
|
398
|
+
- **@principal-ade/panels** - Current layout implementation in electron-app
|
|
399
|
+
- **@principal-ade/industry-theme** - Theming system used by layouts
|
|
400
400
|
|
|
401
401
|
## 🤝 Contributing
|
|
402
402
|
|
|
@@ -417,12 +417,12 @@ MIT
|
|
|
417
417
|
|
|
418
418
|
**Status:** 🚧 In Active Development
|
|
419
419
|
|
|
420
|
-
This package is being actively developed with a focus on reusing `@
|
|
420
|
+
This package is being actively developed with a focus on reusing `@principal-ade/panels` and adding workspace/persistence features.
|
|
421
421
|
|
|
422
422
|
### Implementation Progress:
|
|
423
423
|
- ✅ README specification complete
|
|
424
424
|
- ✅ Package setup and build configuration (Vite + TypeScript)
|
|
425
|
-
- ✅ Re-exports from @
|
|
425
|
+
- ✅ Re-exports from @principal-ade/panels (25+ components)
|
|
426
426
|
- ✅ `usePanelPersistence` hook extracted and adapted
|
|
427
427
|
- ✅ `LocalStoragePersistenceAdapter` for web apps
|
|
428
428
|
- ✅ Storybook with interactive component stories
|
|
@@ -434,7 +434,7 @@ This package is being actively developed with a focus on reusing `@a24z/panels`
|
|
|
434
434
|
- ⏳ Publish to npm
|
|
435
435
|
|
|
436
436
|
### Architecture Decision:
|
|
437
|
-
We're **reusing** `@
|
|
437
|
+
We're **reusing** `@principal-ade/panels@1.0.39` as a dependency rather than rebuilding layout components. This allows us to:
|
|
438
438
|
- Focus on high-value features (persistence, workspaces, presets)
|
|
439
439
|
- Leverage proven, tested layout components
|
|
440
440
|
- Maintain compatibility with existing electron-app code
|
|
@@ -455,7 +455,7 @@ npm run build # Build ESM + CJS + types ✅
|
|
|
455
455
|
```
|
|
456
456
|
|
|
457
457
|
### Package Contents:
|
|
458
|
-
- **Re-exported:** All components from @
|
|
458
|
+
- **Re-exported:** All components from @principal-ade/panels
|
|
459
459
|
- **New:** `usePanelPersistence` hook with localStorage adapter
|
|
460
460
|
- **New:** Comprehensive TypeScript types
|
|
461
461
|
- **New:** Interactive Storybook documentation
|
package/dist/index.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.animated-resizable-layout{width:100%;height:100%;position:relative;background-color:var(--panel-background)}.hybrid-panel{overflow:auto;height:100%;background-color:var(--panel-background)}.resize-handle{width:8px;background-color:var(--panel-handle);display:flex;justify-content:center;align-items:center;cursor:col-resize;position:relative;transition:background-color .2s,opacity .3s,width .3s}.resize-handle.collapsed{opacity:0;pointer-events:none}.resize-handle:hover{background-color:var(--panel-handle-hover)}.resize-handle:active{background-color:var(--panel-handle-active)}.handle-bar{height:100%;width:100%;display:flex;align-items:center;justify-content:center;position:relative}.collapse-toggle{position:absolute;background:var(--panel-button-bg);border:1px solid var(--panel-button-border);padding:4px 8px;cursor:pointer;color:var(--panel-button-icon);font-size:14px;outline:none;display:flex;align-items:center;justify-content:center;border-radius:4px;z-index:10;transition:all .2s;box-shadow:0 2px 4px #0000001a}.animated-vertical-layout{width:100%;height:100%;position:relative;background-color:var(--panel-background)}.vertical-panel{overflow:auto;width:100%;background-color:var(--panel-background)}.panel-content-wrapper{width:100%;height:100%;overflow:auto}.vertical-resize-handle{height:8px;background-color:var(--panel-handle);display:flex;justify-content:center;align-items:center;cursor:row-resize;position:relative;transition:background-color .2s,opacity .3s,height .3s}.vertical-resize-handle.collapsed{opacity:0;pointer-events:none}.vertical-resize-handle:hover{background-color:var(--panel-handle-hover)}.vertical-resize-handle:active{background-color:var(--panel-handle-active)}.handle-bar{width:100%;height:100%;display:flex;align-items:center;justify-content:center;gap:8px;position:relative}.collapse-toggle{background:var(--panel-button-bg);border:1px solid var(--panel-button-border);padding:4px 8px;cursor:pointer;color:var(--panel-button-icon);font-size:14px;outline:none;display:flex;align-items:center;justify-content:center;border-radius:4px;z-index:10;transition:all .2s;box-shadow:0 2px 4px #0000001a}.collapse-toggle:hover:not(:disabled){background-color:var(--panel-button-hover);box-shadow:0 2px 6px #00000026}.collapse-toggle:active:not(:disabled){opacity:.8}.three-panel-item.collapsible-panel.collapsed{flex:0!important;min-width:0!important}.panel-content-wrapper{flex:1;overflow:auto;will-change:opacity;box-sizing:border-box}.resize-handle.collapsed{width:0!important}.tab-group{display:flex;height:100%;width:100%;overflow:hidden}.tab-group.tab-position-top,.tab-group.tab-position-bottom{flex-direction:column}.tab-group.tab-position-left,.tab-group.tab-position-right{flex-direction:row}.tab-list{display:flex;background:var(--tab-list-bg, #f5f5f5);border-bottom:1px solid var(--tab-border, #ddd);gap:0;padding:0;flex-shrink:0;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.tab-list::-webkit-scrollbar{display:none}.tab-position-top .tab-list,.tab-position-bottom .tab-list{width:100%}.tab-list.centered{justify-content:flex-start}@media (min-width: 0){.tab-list.centered{justify-content:center}.tab-list.centered:has(.tab-button:nth-child(n)){justify-content:flex-start}}.tab-position-bottom .tab-list{border-bottom:none;border-top:none}.tab-position-left .tab-list,.tab-position-right .tab-list{flex-direction:column;border-bottom:none;border-right:none;width:auto;min-width:120px}.tab-position-top .tab-button,.tab-position-bottom .tab-button{flex:1 1 0;min-width:40px;max-width:100%}.tab-button{background:var(--tab-bg, #fff);border:1px solid var(--tab-border, #ddd);border-radius:0;padding:8px 16px;cursor:pointer;font-size:14px;font-weight:500;color:var(--tab-text, #333);transition:all .2s ease;white-space:nowrap;display:flex;align-items:center;justify-content:center;gap:6px;height:40px;line-height:1;box-sizing:border-box;container-type:inline-size}.tab-position-top .tab-button{border-bottom:none;border-top:none;border-left:none}.tab-position-top .tab-button:last-child{border-right:none}.tab-position-bottom .tab-button{border-top:none;border-bottom:none;border-left:none}.tab-position-bottom .tab-button:last-child{border-right:none}.tab-position-left .tab-button{border-right:none;border-bottom:none}.tab-position-left .tab-button:last-child{border-bottom:1px solid var(--tab-border, #ddd)}.tab-position-right .tab-button{border-left:none;border-bottom:none}.tab-position-right .tab-button:last-child{border-bottom:1px solid var(--tab-border, #ddd)}.tab-icon{display:inline-flex;align-items:center;justify-content:center}.tab-label{display:none}@container (min-width: 250px){.tab-label{display:inline}.tab-icon{display:none}}.tab-button:hover{background:var(--tab-bg-hover, #f9f9f9)}.tab-button.active{background:var(--tab-bg-active, #007bff);color:var(--tab-text-active, #fff);border-color:var(--tab-border-active, #007bff)}.tab-button:focus-visible{outline:2px solid var(--tab-focus, #007bff);outline-offset:2px}.tab-content{flex:1;overflow:auto;background:var(--tab-content-bg, #fff)}.tab-group-empty{display:flex;align-items:center;justify-content:center;height:100%;color:var(--tab-empty-text, #999);font-style:italic}.three-panel-layout{height:100%;width:100%;display:flex;flex-direction:column;position:relative;background-color:var(--panel-background);box-sizing:border-box}.three-panel-item{display:flex;flex-direction:column;overflow:hidden;position:relative;background-color:var(--panel-background);box-sizing:border-box}.three-panel-item[data-edit-mode=true]{background-color:var(--panel-accent-bg);border-radius:12px}.three-panel-item.collapsible-panel{will-change:flex}.three-panel-item.collapsible-panel.animating{pointer-events:none}.three-panel-item.collapsible-panel.collapsed{flex:0!important;min-width:0!important;max-width:0!important;width:0!important;overflow:hidden!important;visibility:hidden}.three-panel-item.middle-panel{flex:1;min-width:200px}.panel-content-wrapper{flex:1;overflow-x:hidden;overflow-y:auto;will-change:opacity;box-sizing:border-box}.resize-handle{position:relative;display:flex;align-items:center;justify-content:center;width:1px!important;cursor:col-resize;background:var(--panel-border);overflow:visible!important}.resize-handle:before{content:"";position:absolute;top:0;right:-10px;bottom:0;left:-10px;background:transparent}.resize-handle:after{content:"";position:absolute;top:0;right:-10px;bottom:0;left:-10px;background:var(--panel-handle);opacity:0;transition:opacity .2s ease;z-index:-1}.resize-handle:hover:after{opacity:1}.resize-handle:hover{background:var(--panel-handle-hover)}.resize-handle:active:after{opacity:1;background:var(--panel-handle-active)}.resize-handle:active{background:var(--panel-handle-active)}.resize-handle.collapsed{width:0!important;visibility:hidden}.resize-handle.left-handle.collapsed{margin-right:-1px}.resize-handle.right-handle.collapsed{margin-left:-1px}.handle-bar{position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center;z-index:2}.collapse-toggle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:20px;height:40px;background:var(--panel-button-bg);border:1px solid var(--panel-button-border);border-radius:4px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:12px;color:var(--panel-button-icon);transition:all .2s ease;z-index:10;padding:0;line-height:1}.collapse-toggle:hover{background:var(--panel-button-hover)}.collapse-toggle:active{opacity:.8}.collapse-toggle:disabled{opacity:.5;cursor:not-allowed}@media (max-width: 768px){.resize-handle:before{left:-8px;right:-8px}.resize-handle:after{left:-8px;right:-8px}.collapse-toggle{width:24px;height:48px;font-size:14px}}@keyframes wiggle{0%{transform:rotate(0)}25%{transform:rotate(1deg)}50%{transform:rotate(0)}75%{transform:rotate(-1deg)}to{transform:rotate(0)}}@keyframes scaleIn{0%{transform:scale(.95);opacity:0}to{transform:scale(1);opacity:1}}@keyframes pulse{0%,to{box-shadow:0 0 #3b82f666}50%{box-shadow:0 0 0 8px #3b82f600}}.editable-panel-layout{position:relative;width:100%;height:100%}.editable-panel-layout.edit-mode-active{background:#0000000d}[data-slot][data-edit-mode=true]{transform:scale(.95);transform-origin:center center;cursor:grab;will-change:transform;transition:transform .3s cubic-bezier(.4,0,.2,1)}[data-slot][data-edit-mode=true]:active{cursor:grabbing}[data-slot][data-dragging=true]{cursor:grabbing!important;transform:scale(.95)!important;transition:none!important}.edit-mode-active [data-slot][data-edit-mode=true]{transform-origin:center center}.slot-with-overlay{position:relative;width:100%;height:100%}.slot-with-overlay.dragging{opacity:0;pointer-events:none}.slot-edit-overlay{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;border:none;pointer-events:auto;cursor:grab;z-index:100;display:flex;flex-direction:column;align-items:center;justify-content:center}.slot-edit-overlay:hover{background:#3b82f608}.slot-edit-overlay:active{cursor:grabbing}.drag-indicator,.slot-position-label{display:none}.edit-mode-toggle{position:absolute;top:16px;right:16px;z-index:1000;padding:8px 16px;border-radius:8px;border:1px solid #e5e7eb;background:#fff;color:#374151;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s ease;box-shadow:0 2px 4px #0000001a}.edit-mode-toggle:hover{background:#f9fafb;box-shadow:0 4px 6px #0000001a}.edit-mode-toggle.active{background:#3b82f6;color:#fff;border-color:#2563eb}.edit-mode-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#0000004d;z-index:998;animation:fadeIn .2s ease}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.edit-mode-configurator{position:relative;z-index:999;padding:20px;animation:scaleIn .3s ease}.panel-slot{position:relative;min-height:120px;border:2px dashed transparent;border-radius:12px;transition:all .3s ease;padding:12px}.panel-slot.edit-mode{border-color:#d1d5db;background:#ffffff80}.panel-slot.drag-over{border-color:#3b82f6;background:#3b82f61a;box-shadow:0 0 0 4px #3b82f61a}.panel-slot.empty{display:flex;align-items:center;justify-content:center;color:#9ca3af;font-size:14px}.draggable-panel{position:relative;padding:12px 16px;margin:8px 0;border-radius:8px;background:#fff;border:1px solid #e5e7eb;cursor:grab;transition:all .2s ease;-webkit-user-select:none;user-select:none}.draggable-panel:hover{border-color:#3b82f6;box-shadow:0 2px 8px #0000001a}.draggable-panel.dragging{opacity:.5;cursor:grabbing}.draggable-panel.edit-mode{animation:wiggle .4s ease-in-out infinite;transform-origin:center}.draggable-panel.edit-mode:nth-child(odd){animation-delay:.1s}.draggable-panel.edit-mode:nth-child(2n){animation-delay:.2s}.remove-button{position:absolute;top:-6px;right:-6px;width:20px;height:20px;border-radius:50%;background:#ef4444;color:#fff;border:2px solid white;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:12px;font-weight:700;opacity:0;transform:scale(0);transition:all .2s ease;z-index:10;box-shadow:0 2px 4px #0003}.draggable-panel.edit-mode .remove-button{opacity:1;transform:scale(1);animation:pulse 2s infinite}.remove-button:hover{background:#dc2626;transform:scale(1.1)}.panel-label{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:500;color:#374151}.panel-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center}.drag-handle{display:none;width:24px;height:24px;opacity:.4;cursor:grab}.edit-mode .drag-handle{display:flex;align-items:center;justify-content:center}.drag-overlay{padding:12px 16px;border-radius:8px;background:#fff;border:2px solid #3b82f6;box-shadow:0 8px 16px #0003;cursor:grabbing;opacity:.9}.panel-group{border:2px solid #e5e7eb;border-radius:12px;padding:8px;background:#fff}.panel-group.edit-mode{animation:wiggle .5s ease-in-out infinite;border-color:#3b82f6}.panel-group-header{display:flex;justify-content:space-between;align-items:center;padding:8px;border-bottom:1px solid #e5e7eb;margin-bottom:8px}.panel-group-title{font-size:12px;font-weight:600;color:#6b7280;text-transform:uppercase}.available-panels{background:#fff;border-radius:12px;padding:16px;box-shadow:0 4px 6px #0000001a}.available-panels-title{font-size:16px;font-weight:600;color:#374151;margin-bottom:12px}.available-panels-list{display:flex;flex-direction:column;gap:8px}.slot-label{font-size:12px;font-weight:600;color:#6b7280;text-transform:uppercase;margin-bottom:8px;display:flex;align-items:center;gap:8px}.slot-indicator{width:8px;height:8px;border-radius:50%;background:#d1d5db}.slot-indicator.active{background:#3b82f6}.action-buttons{position:fixed;bottom:24px;left:50%;transform:translate(-50%);z-index:1001;display:flex;gap:12px;padding:12px 24px;background:#fff;border-radius:12px;box-shadow:0 8px 16px #00000026;animation:scaleIn .3s ease}.action-button{padding:10px 20px;border-radius:8px;border:1px solid #e5e7eb;background:#fff;color:#374151;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s ease}.action-button:hover{background:#f9fafb}.action-button.primary{background:#3b82f6;color:#fff;border-color:#2563eb}.action-button.primary:hover{background:#2563eb}@media (max-width: 768px){.edit-mode-toggle{top:8px;right:8px;padding:6px 12px;font-size:12px}.action-buttons{bottom:16px;padding:10px 16px}.action-button{padding:8px 16px;font-size:13px}}@media (prefers-color-scheme: dark){.edit-mode-toggle{background:#1f2937;color:#f9fafb;border-color:#374151}.edit-mode-toggle:hover{background:#374151}.draggable-panel{background:#1f2937;color:#f9fafb;border-color:#374151}.available-panels{background:#1f2937}.panel-label{color:#f9fafb}.action-buttons{background:#1f2937}.action-button{background:#1f2937;color:#f9fafb;border-color:#374151}.action-button:hover{background:#374151}}.panel-configurator{display:flex;flex-direction:column;gap:2rem;padding:1.5rem;background:var(--configurator-bg);border-radius:8px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.configurator-section{display:flex;flex-direction:column;gap:1rem}.section-title{margin:0;font-size:.875rem;font-weight:600;color:var(--configurator-title);text-transform:uppercase;letter-spacing:.05em;text-align:center}.slots-container{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;width:75%;margin:0 auto;align-items:start}.slot{position:relative;aspect-ratio:1 / 1.3;width:100%;padding:2.5rem 1rem 1rem;background:var(--slot-bg);border:2px solid var(--slot-border);border-radius:6px;cursor:pointer;transition:all .2s ease;display:flex;flex-direction:column;gap:.5rem;overflow:hidden;box-sizing:border-box}.slot:hover{border-color:var(--slot-border-hover);box-shadow:0 2px 4px #0000000d}.slot.selected{border-color:var(--slot-border-selected);background:var(--slot-bg-selected);box-shadow:0 0 0 3px var(--slot-bg-selected)}.slot.empty{border-style:dashed}.slot-label{font-size:.75rem;font-weight:600;color:var(--slot-label);text-transform:capitalize;text-align:left}.slot[data-position=middle] .slot-label,.slot[data-position=middle] .slot-panel-name,.slot[data-position=middle] .slot-empty-state{text-align:center}.slot[data-position=right] .slot-label,.slot[data-position=right] .slot-panel-name,.slot[data-position=right] .slot-empty-state{text-align:right}.slot-content{flex:1;display:flex;flex-direction:column;gap:.5rem;overflow-y:auto;min-height:0}.slot-panel-name{font-weight:600;color:var(--slot-content-text);font-size:.875rem}.slot-preview{flex:1;display:flex;align-items:center;justify-content:center;padding:.5rem;background:var(--slot-preview-bg);border-radius:4px;border:1px solid var(--slot-preview-border);font-size:.75rem;color:var(--slot-preview-text)}.slot-empty-state{flex:1;display:flex;align-items:center;justify-content:center;color:var(--slot-empty-text);font-size:.875rem;font-style:italic;min-height:0}.slot-clear-btn{position:absolute;top:.25rem;right:.25rem;width:24px;height:24px;padding:0;background:var(--clear-btn-bg);color:var(--clear-btn-text);border:none;border-radius:4px;cursor:pointer;font-size:1.25rem;line-height:1;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .2s ease}.slot:hover .slot-clear-btn{opacity:1}.slot-clear-btn:hover{background:var(--clear-btn-hover);transform:scale(1.1)}.available-panels{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:.75rem;width:75%;margin:0 auto}.available-panel{min-height:80px;padding:.75rem;background:var(--panel-bg);border:2px solid var(--panel-border);border-radius:6px;cursor:pointer;transition:all .2s ease;display:flex;flex-direction:column;gap:.5rem}.available-panel:hover{border-color:var(--panel-border-hover);box-shadow:0 2px 4px #0000000d;transform:translateY(-2px)}.available-panel.selected{border-color:var(--panel-border-selected);background:var(--panel-bg-selected);box-shadow:0 0 0 3px var(--panel-bg-selected)}.available-panel.in-use{opacity:.5;border-style:dashed}.available-panel.in-use:hover{transform:translateY(0);opacity:.6}.panel-label{font-weight:600;color:var(--panel-label-text);font-size:.875rem}.panel-preview{flex:1;display:flex;align-items:center;justify-content:center;padding:.5rem;background:var(--panel-preview-bg);border-radius:4px;font-size:.75rem;color:var(--panel-preview-text)}.selection-hint{padding:.75rem 1rem;background:var(--hint-bg);border:1px solid var(--hint-border);border-radius:6px;color:var(--hint-text);font-size:.875rem;text-align:center}.available-panel.multi-selected{border-color:var(--panel-border-selected);background:var(--panel-bg-selected);box-shadow:0 0 0 2px var(--panel-bg-selected)}.multi-select-badge{margin-left:.5rem;padding:.25rem .5rem;background:var(--panel-border-selected);color:#fff;font-size:.75rem;border-radius:12px;font-weight:400}.multi-select-hint{background:var(--panel-bg-selected);border-color:var(--panel-border-selected)}.slot.tab-group{border-style:solid}.group-content{position:relative;overflow-y:auto;min-height:0}.group-badge{font-size:.75rem;font-weight:600;color:var(--panel-border-selected);margin-bottom:.5rem}.group-panels{display:flex;flex-direction:column;gap:.25rem;flex:1;overflow-y:auto;min-height:0}.group-panel-label{font-size:.75rem;color:var(--slot-content-text);padding:.25rem .5rem;background:var(--slot-preview-bg);border-radius:3px;border-left:3px solid var(--panel-border-selected)}.slot-panel-label{font-weight:600;color:var(--slot-content-text);font-size:.875rem;text-align:center}.create-tab-group-btn{margin-top:.5rem;padding:.5rem .75rem;background:var(--panel-border-selected);color:#fff;border:none;border-radius:4px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.create-tab-group-btn:hover{transform:scale(1.05);box-shadow:0 2px 4px #0000001a}.tab-mode-toggle{position:absolute;top:.5rem;left:.5rem;padding:.25rem .5rem;background:var(--slot-bg);border:1px solid var(--slot-border);border-radius:4px;font-size:.85rem;cursor:pointer;transition:all .2s ease;z-index:10;opacity:.7;color:var(--slot-content-text)}.tab-mode-toggle svg{display:block}.tab-mode-toggle:hover{opacity:1;border-color:var(--slot-border-hover);background:var(--slot-preview-bg)}.tab-mode-toggle.active{opacity:1;background:var(--panel-border-selected);color:#fff;border-color:var(--panel-border-selected)}.tab-config-controls{margin-bottom:.5rem}.tab-config-label{display:flex;align-items:center;gap:.5rem;font-size:.75rem;color:var(--slot-label)}.tab-config-label select{padding:.25rem .5rem;border:1px solid var(--slot-border);border-radius:3px;background:var(--slot-bg);color:var(--slot-content-text);font-size:.7rem;cursor:pointer}.group-panel-item{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:.25rem .5rem;background:var(--slot-preview-bg);border-radius:3px;border-left:3px solid var(--panel-border-selected)}.group-panel-label{flex:1;font-size:.75rem;color:var(--slot-content-text);display:flex;align-items:center;gap:.25rem}.default-badge{color:var(--panel-border-selected);font-size:.9em}.remove-from-group-btn{width:18px;height:18px;padding:0;background:var(--clear-btn-bg);color:var(--clear-btn-text);border:none;border-radius:3px;cursor:pointer;font-size:1rem;line-height:1;display:flex;align-items:center;justify-content:center;opacity:.7;transition:all .2s ease}.remove-from-group-btn:hover{opacity:1;transform:scale(1.1)}.usage-hint{padding:.75rem 1rem;background:var(--slot-preview-bg);border:1px solid var(--slot-border);border-radius:6px;color:var(--hint-text);font-size:.875rem;text-align:center}.snap-carousel-container{display:flex;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;scroll-behavior:smooth;gap:var(--snap-carousel-gap, 0px);padding:0;margin:0;width:100%;height:100%;background-color:var(--panel-background);box-sizing:border-box;position:relative;left:0;transform:none;container-type:inline-size;-ms-overflow-style:none;scrollbar-width:none}.snap-carousel-container::-webkit-scrollbar{display:none}.snap-carousel-panel{flex:0 0 auto;scroll-snap-align:start;scroll-snap-stop:always;width:var(--snap-carousel-panel-width, 33.33%);height:100%;box-sizing:border-box;overflow:hidden}@media (max-width: 540px){.snap-carousel-panel{min-width:280px}}
|
|
1
|
+
.animated-resizable-layout{width:100%;height:100%;position:relative;background-color:var(--panel-background)}.hybrid-panel{overflow:auto;height:100%;background-color:var(--panel-background)}.resize-handle{width:8px;background-color:var(--panel-handle);display:flex;justify-content:center;align-items:center;cursor:col-resize;position:relative;transition:background-color .2s,opacity .3s,width .3s}.resize-handle.collapsed{opacity:0;pointer-events:none}.resize-handle:hover{background-color:var(--panel-handle-hover)}.resize-handle:active{background-color:var(--panel-handle-active)}.handle-bar{height:100%;width:100%;display:flex;align-items:center;justify-content:center;position:relative}.collapse-toggle{position:absolute;background:var(--panel-button-bg);border:1px solid var(--panel-button-border);padding:4px 8px;cursor:pointer;color:var(--panel-button-icon);font-size:14px;outline:none;display:flex;align-items:center;justify-content:center;border-radius:4px;z-index:10;transition:all .2s;box-shadow:0 2px 4px #0000001a}.animated-vertical-layout{width:100%;height:100%;position:relative;background-color:var(--panel-background)}.vertical-panel{overflow:auto;width:100%;background-color:var(--panel-background)}.panel-content-wrapper{width:100%;height:100%;overflow:auto}.vertical-resize-handle{height:8px;background-color:var(--panel-handle);display:flex;justify-content:center;align-items:center;cursor:row-resize;position:relative;transition:background-color .2s,opacity .3s,height .3s}.vertical-resize-handle.collapsed{opacity:0;pointer-events:none}.vertical-resize-handle:hover{background-color:var(--panel-handle-hover)}.vertical-resize-handle:active{background-color:var(--panel-handle-active)}.handle-bar{width:100%;height:100%;display:flex;align-items:center;justify-content:center;gap:8px;position:relative}.collapse-toggle{background:var(--panel-button-bg);border:1px solid var(--panel-button-border);padding:4px 8px;cursor:pointer;color:var(--panel-button-icon);font-size:14px;outline:none;display:flex;align-items:center;justify-content:center;border-radius:4px;z-index:10;transition:all .2s;box-shadow:0 2px 4px #0000001a}.collapse-toggle:hover:not(:disabled){background-color:var(--panel-button-hover);box-shadow:0 2px 6px #00000026}.collapse-toggle:active:not(:disabled){opacity:.8}.three-panel-item.collapsible-panel.collapsed{flex:0!important;min-width:0!important}.panel-content-wrapper{flex:1;overflow:auto;will-change:opacity;box-sizing:border-box}.resize-handle.collapsed{width:0!important}.tab-group{display:flex;height:100%;width:100%;overflow:hidden}.tab-group.tab-position-top,.tab-group.tab-position-bottom{flex-direction:column}.tab-group.tab-position-left,.tab-group.tab-position-right{flex-direction:row}.tab-list{display:flex;background:var(--tab-list-bg, #f5f5f5);border-bottom:1px solid var(--tab-border, #ddd);gap:0;padding:0;flex-shrink:0;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.tab-list::-webkit-scrollbar{display:none}.tab-position-top .tab-list,.tab-position-bottom .tab-list{width:100%}.tab-list.centered{justify-content:flex-start}@media (min-width:0){.tab-list.centered{justify-content:center}.tab-list.centered:has(.tab-button:nth-child(n)){justify-content:flex-start}}.tab-position-bottom .tab-list{border-bottom:none;border-top:none}.tab-position-left .tab-list,.tab-position-right .tab-list{flex-direction:column;border-bottom:none;border-right:none;width:auto;min-width:120px}.tab-position-top .tab-button,.tab-position-bottom .tab-button{flex:1 1 0;min-width:40px;max-width:100%}.tab-button{background:var(--tab-bg, #fff);border:1px solid var(--tab-border, #ddd);border-radius:0;padding:8px 16px;cursor:pointer;font-size:14px;font-weight:500;color:var(--tab-text, #333);transition:all .2s ease;white-space:nowrap;display:flex;align-items:center;justify-content:center;gap:6px;height:40px;line-height:1;box-sizing:border-box;container-type:inline-size}.tab-position-top .tab-button{border-bottom:none;border-top:none;border-left:none}.tab-position-top .tab-button:last-child{border-right:none}.tab-position-bottom .tab-button{border-top:none;border-bottom:none;border-left:none}.tab-position-bottom .tab-button:last-child{border-right:none}.tab-position-left .tab-button{border-right:none;border-bottom:none}.tab-position-left .tab-button:last-child{border-bottom:1px solid var(--tab-border, #ddd)}.tab-position-right .tab-button{border-left:none;border-bottom:none}.tab-position-right .tab-button:last-child{border-bottom:1px solid var(--tab-border, #ddd)}.tab-icon{display:inline-flex;align-items:center;justify-content:center}.tab-label{display:none}@container (min-width: 250px){.tab-label{display:inline}.tab-icon{display:none}}.tab-button:hover{background:var(--tab-bg-hover, #f9f9f9)}.tab-button.active{background:var(--tab-bg-active, #007bff);color:var(--tab-text-active, #fff);border-color:var(--tab-border-active, #007bff)}.tab-button:focus-visible{outline:2px solid var(--tab-focus, #007bff);outline-offset:2px}.tab-content{flex:1;overflow:auto;background:var(--tab-content-bg, #fff)}.tab-group-empty{display:flex;align-items:center;justify-content:center;height:100%;color:var(--tab-empty-text, #999);font-style:italic}.three-panel-layout{height:100%;width:100%;display:flex;flex-direction:column;position:relative;background-color:var(--panel-background);box-sizing:border-box}.three-panel-item{display:flex;flex-direction:column;overflow:hidden;position:relative;background-color:var(--panel-background);box-sizing:border-box}.three-panel-item[data-edit-mode=true]{background-color:var(--panel-accent-bg);border-radius:12px}.three-panel-item.collapsible-panel{will-change:flex}.three-panel-item.collapsible-panel.animating{pointer-events:none}.three-panel-item.collapsible-panel.collapsed{flex:0!important;min-width:0!important;max-width:0!important;width:0!important;overflow:hidden!important;visibility:hidden}.three-panel-item.middle-panel{flex:1;min-width:200px}.panel-content-wrapper{flex:1;overflow-x:hidden;overflow-y:auto;will-change:opacity;box-sizing:border-box}.resize-handle{position:relative;display:flex;align-items:center;justify-content:center;width:1px!important;cursor:col-resize;background:var(--panel-border);overflow:visible!important}.resize-handle:before{content:"";position:absolute;top:0;right:-10px;bottom:0;left:-10px;background:transparent}.resize-handle:after{content:"";position:absolute;top:0;right:-10px;bottom:0;left:-10px;background:var(--panel-handle);opacity:0;transition:opacity .2s ease;z-index:-1}.resize-handle:hover:after{opacity:1}.resize-handle:hover{background:var(--panel-handle-hover)}.resize-handle:active:after{opacity:1;background:var(--panel-handle-active)}.resize-handle:active{background:var(--panel-handle-active)}.resize-handle.collapsed{width:0!important;visibility:hidden}.resize-handle.left-handle.collapsed{margin-right:-1px}.resize-handle.right-handle.collapsed{margin-left:-1px}.handle-bar{position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center;z-index:2}.collapse-toggle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:20px;height:40px;background:var(--panel-button-bg);border:1px solid var(--panel-button-border);border-radius:4px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:12px;color:var(--panel-button-icon);transition:all .2s ease;z-index:10;padding:0;line-height:1}.collapse-toggle:hover{background:var(--panel-button-hover)}.collapse-toggle:active{opacity:.8}.collapse-toggle:disabled{opacity:.5;cursor:not-allowed}@media (max-width:768px){.resize-handle:before{left:-8px;right:-8px}.resize-handle:after{left:-8px;right:-8px}.collapse-toggle{width:24px;height:48px;font-size:14px}}.snap-carousel-container{display:flex;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;scroll-behavior:smooth;gap:var(--snap-carousel-gap, 0px);padding:0;margin:0;width:100%;height:100%;background-color:var(--panel-background);box-sizing:border-box;position:relative;left:0;transform:none;container-type:inline-size;-ms-overflow-style:none;scrollbar-width:none}.snap-carousel-container::-webkit-scrollbar{display:none}.snap-carousel-panel{flex:0 0 auto;scroll-snap-align:start;scroll-snap-stop:always;width:var(--snap-carousel-panel-width, 33.33%);height:100%;box-sizing:border-box;overflow:hidden}@media (max-width:540px){.snap-carousel-panel{min-width:280px}}@keyframes wiggle{0%{transform:rotate(0)}25%{transform:rotate(1deg)}50%{transform:rotate(0)}75%{transform:rotate(-1deg)}to{transform:rotate(0)}}@keyframes scaleIn{0%{transform:scale(.95);opacity:0}to{transform:scale(1);opacity:1}}@keyframes pulse{0%,to{box-shadow:0 0 #3b82f666}50%{box-shadow:0 0 0 8px #3b82f600}}.editable-panel-layout{position:relative;width:100%;height:100%}.editable-panel-layout.edit-mode-active{background:#0000000d}[data-slot][data-edit-mode=true]{transform:scale(.95);transform-origin:center center;cursor:grab;will-change:transform;transition:transform .3s cubic-bezier(.4,0,.2,1)}[data-slot][data-edit-mode=true]:active{cursor:grabbing}[data-slot][data-dragging=true]{cursor:grabbing!important;transform:scale(.95)!important;transition:none!important}.edit-mode-active [data-slot][data-edit-mode=true]{transform-origin:center center}.slot-with-overlay{position:relative;width:100%;height:100%}.slot-with-overlay.dragging{opacity:0;pointer-events:none}.slot-edit-overlay{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;border:none;pointer-events:auto;cursor:grab;z-index:100;display:flex;flex-direction:column;align-items:center;justify-content:center}.slot-edit-overlay:hover{background:#3b82f608}.slot-edit-overlay:active{cursor:grabbing}.drag-indicator,.slot-position-label{display:none}.edit-mode-toggle{position:absolute;top:16px;right:16px;z-index:1000;padding:8px 16px;border-radius:8px;border:1px solid #e5e7eb;background:#fff;color:#374151;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s ease;box-shadow:0 2px 4px #0000001a}.edit-mode-toggle:hover{background:#f9fafb;box-shadow:0 4px 6px #0000001a}.edit-mode-toggle.active{background:#3b82f6;color:#fff;border-color:#2563eb}.edit-mode-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#0000004d;z-index:998;animation:fadeIn .2s ease}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.edit-mode-configurator{position:relative;z-index:999;padding:20px;animation:scaleIn .3s ease}.panel-slot{position:relative;min-height:120px;border:2px dashed transparent;border-radius:12px;transition:all .3s ease;padding:12px}.panel-slot.edit-mode{border-color:#d1d5db;background:#ffffff80}.panel-slot.drag-over{border-color:#3b82f6;background:#3b82f61a;box-shadow:0 0 0 4px #3b82f61a}.panel-slot.empty{display:flex;align-items:center;justify-content:center;color:#9ca3af;font-size:14px}.draggable-panel{position:relative;padding:12px 16px;margin:8px 0;border-radius:8px;background:#fff;border:1px solid #e5e7eb;cursor:grab;transition:all .2s ease;-webkit-user-select:none;user-select:none}.draggable-panel:hover{border-color:#3b82f6;box-shadow:0 2px 8px #0000001a}.draggable-panel.dragging{opacity:.5;cursor:grabbing}.draggable-panel.edit-mode{animation:wiggle .4s ease-in-out infinite;transform-origin:center}.draggable-panel.edit-mode:nth-child(odd){animation-delay:.1s}.draggable-panel.edit-mode:nth-child(2n){animation-delay:.2s}.remove-button{position:absolute;top:-6px;right:-6px;width:20px;height:20px;border-radius:50%;background:#ef4444;color:#fff;border:2px solid white;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:12px;font-weight:700;opacity:0;transform:scale(0);transition:all .2s ease;z-index:10;box-shadow:0 2px 4px #0003}.draggable-panel.edit-mode .remove-button{opacity:1;transform:scale(1);animation:pulse 2s infinite}.remove-button:hover{background:#dc2626;transform:scale(1.1)}.panel-label{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:500;color:#374151}.panel-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center}.drag-handle{display:none;width:24px;height:24px;opacity:.4;cursor:grab}.edit-mode .drag-handle{display:flex;align-items:center;justify-content:center}.drag-overlay{padding:12px 16px;border-radius:8px;background:#fff;border:2px solid #3b82f6;box-shadow:0 8px 16px #0003;cursor:grabbing;opacity:.9}.panel-group{border:2px solid #e5e7eb;border-radius:12px;padding:8px;background:#fff}.panel-group.edit-mode{animation:wiggle .5s ease-in-out infinite;border-color:#3b82f6}.panel-group-header{display:flex;justify-content:space-between;align-items:center;padding:8px;border-bottom:1px solid #e5e7eb;margin-bottom:8px}.panel-group-title{font-size:12px;font-weight:600;color:#6b7280;text-transform:uppercase}.available-panels{background:#fff;border-radius:12px;padding:16px;box-shadow:0 4px 6px #0000001a}.available-panels-title{font-size:16px;font-weight:600;color:#374151;margin-bottom:12px}.available-panels-list{display:flex;flex-direction:column;gap:8px}.slot-label{font-size:12px;font-weight:600;color:#6b7280;text-transform:uppercase;margin-bottom:8px;display:flex;align-items:center;gap:8px}.slot-indicator{width:8px;height:8px;border-radius:50%;background:#d1d5db}.slot-indicator.active{background:#3b82f6}.action-buttons{position:fixed;bottom:24px;left:50%;transform:translate(-50%);z-index:1001;display:flex;gap:12px;padding:12px 24px;background:#fff;border-radius:12px;box-shadow:0 8px 16px #00000026;animation:scaleIn .3s ease}.action-button{padding:10px 20px;border-radius:8px;border:1px solid #e5e7eb;background:#fff;color:#374151;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s ease}.action-button:hover{background:#f9fafb}.action-button.primary{background:#3b82f6;color:#fff;border-color:#2563eb}.action-button.primary:hover{background:#2563eb}@media (max-width:768px){.edit-mode-toggle{top:8px;right:8px;padding:6px 12px;font-size:12px}.action-buttons{bottom:16px;padding:10px 16px}.action-button{padding:8px 16px;font-size:13px}}@media (prefers-color-scheme:dark){.edit-mode-toggle{background:#1f2937;color:#f9fafb;border-color:#374151}.edit-mode-toggle:hover{background:#374151}.draggable-panel{background:#1f2937;color:#f9fafb;border-color:#374151}.available-panels{background:#1f2937}.panel-label{color:#f9fafb}.action-buttons{background:#1f2937}.action-button{background:#1f2937;color:#f9fafb;border-color:#374151}.action-button:hover{background:#374151}}.panel-configurator{display:flex;flex-direction:column;gap:2rem;padding:1.5rem;background:var(--configurator-bg);border-radius:8px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.configurator-section{display:flex;flex-direction:column;gap:1rem}.section-title{margin:0;font-size:.875rem;font-weight:600;color:var(--configurator-title);text-transform:uppercase;letter-spacing:.05em;text-align:center}.slots-container{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;width:75%;margin:0 auto;align-items:start}.slot{position:relative;aspect-ratio:1 / 1.3;width:100%;padding:2.5rem 1rem 1rem;background:var(--slot-bg);border:2px solid var(--slot-border);border-radius:6px;cursor:pointer;transition:all .2s ease;display:flex;flex-direction:column;gap:.5rem;overflow:hidden;box-sizing:border-box}.slot:hover{border-color:var(--slot-border-hover);box-shadow:0 2px 4px #0000000d}.slot.selected{border-color:var(--slot-border-selected);background:var(--slot-bg-selected);box-shadow:0 0 0 3px var(--slot-bg-selected)}.slot.empty{border-style:dashed}.slot-label{font-size:.75rem;font-weight:600;color:var(--slot-label);text-transform:capitalize;text-align:left}.slot[data-position=middle] .slot-label,.slot[data-position=middle] .slot-panel-name,.slot[data-position=middle] .slot-empty-state{text-align:center}.slot[data-position=right] .slot-label,.slot[data-position=right] .slot-panel-name,.slot[data-position=right] .slot-empty-state{text-align:right}.slot-content{flex:1;display:flex;flex-direction:column;gap:.5rem;overflow-y:auto;min-height:0}.slot-panel-name{font-weight:600;color:var(--slot-content-text);font-size:.875rem}.slot-preview{flex:1;display:flex;align-items:center;justify-content:center;padding:.5rem;background:var(--slot-preview-bg);border-radius:4px;border:1px solid var(--slot-preview-border);font-size:.75rem;color:var(--slot-preview-text)}.slot-empty-state{flex:1;display:flex;align-items:center;justify-content:center;color:var(--slot-empty-text);font-size:.875rem;font-style:italic;min-height:0}.slot-clear-btn{position:absolute;top:.25rem;right:.25rem;width:24px;height:24px;padding:0;background:var(--clear-btn-bg);color:var(--clear-btn-text);border:none;border-radius:4px;cursor:pointer;font-size:1.25rem;line-height:1;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .2s ease}.slot:hover .slot-clear-btn{opacity:1}.slot-clear-btn:hover{background:var(--clear-btn-hover);transform:scale(1.1)}.available-panels{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:.75rem;width:75%;margin:0 auto}.available-panel{min-height:80px;padding:.75rem;background:var(--panel-bg);border:2px solid var(--panel-border);border-radius:6px;cursor:pointer;transition:all .2s ease;display:flex;flex-direction:column;gap:.5rem}.available-panel:hover{border-color:var(--panel-border-hover);box-shadow:0 2px 4px #0000000d;transform:translateY(-2px)}.available-panel.selected{border-color:var(--panel-border-selected);background:var(--panel-bg-selected);box-shadow:0 0 0 3px var(--panel-bg-selected)}.available-panel.in-use{opacity:.5;border-style:dashed}.available-panel.in-use:hover{transform:translateY(0);opacity:.6}.panel-label{font-weight:600;color:var(--panel-label-text);font-size:.875rem}.panel-preview{flex:1;display:flex;align-items:center;justify-content:center;padding:.5rem;background:var(--panel-preview-bg);border-radius:4px;font-size:.75rem;color:var(--panel-preview-text)}.selection-hint{padding:.75rem 1rem;background:var(--hint-bg);border:1px solid var(--hint-border);border-radius:6px;color:var(--hint-text);font-size:.875rem;text-align:center}.available-panel.multi-selected{border-color:var(--panel-border-selected);background:var(--panel-bg-selected);box-shadow:0 0 0 2px var(--panel-bg-selected)}.multi-select-badge{margin-left:.5rem;padding:.25rem .5rem;background:var(--panel-border-selected);color:#fff;font-size:.75rem;border-radius:12px;font-weight:400}.multi-select-hint{background:var(--panel-bg-selected);border-color:var(--panel-border-selected)}.slot.tab-group{border-style:solid}.group-content{position:relative;overflow-y:auto;min-height:0}.group-badge{font-size:.75rem;font-weight:600;color:var(--panel-border-selected);margin-bottom:.5rem}.group-panels{display:flex;flex-direction:column;gap:.25rem;flex:1;overflow-y:auto;min-height:0}.group-panel-label{font-size:.75rem;color:var(--slot-content-text);padding:.25rem .5rem;background:var(--slot-preview-bg);border-radius:3px;border-left:3px solid var(--panel-border-selected)}.slot-panel-label{font-weight:600;color:var(--slot-content-text);font-size:.875rem;text-align:center}.create-tab-group-btn{margin-top:.5rem;padding:.5rem .75rem;background:var(--panel-border-selected);color:#fff;border:none;border-radius:4px;font-size:.75rem;font-weight:600;cursor:pointer;transition:all .2s ease}.create-tab-group-btn:hover{transform:scale(1.05);box-shadow:0 2px 4px #0000001a}.tab-mode-toggle{position:absolute;top:.5rem;left:.5rem;padding:.25rem .5rem;background:var(--slot-bg);border:1px solid var(--slot-border);border-radius:4px;font-size:.85rem;cursor:pointer;transition:all .2s ease;z-index:10;opacity:.7;color:var(--slot-content-text)}.tab-mode-toggle svg{display:block}.tab-mode-toggle:hover{opacity:1;border-color:var(--slot-border-hover);background:var(--slot-preview-bg)}.tab-mode-toggle.active{opacity:1;background:var(--panel-border-selected);color:#fff;border-color:var(--panel-border-selected)}.tab-config-controls{margin-bottom:.5rem}.tab-config-label{display:flex;align-items:center;gap:.5rem;font-size:.75rem;color:var(--slot-label)}.tab-config-label select{padding:.25rem .5rem;border:1px solid var(--slot-border);border-radius:3px;background:var(--slot-bg);color:var(--slot-content-text);font-size:.7rem;cursor:pointer}.group-panel-item{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding:.25rem .5rem;background:var(--slot-preview-bg);border-radius:3px;border-left:3px solid var(--panel-border-selected)}.group-panel-label{flex:1;font-size:.75rem;color:var(--slot-content-text);display:flex;align-items:center;gap:.25rem}.default-badge{color:var(--panel-border-selected);font-size:.9em}.remove-from-group-btn{width:18px;height:18px;padding:0;background:var(--clear-btn-bg);color:var(--clear-btn-text);border:none;border-radius:3px;cursor:pointer;font-size:1rem;line-height:1;display:flex;align-items:center;justify-content:center;opacity:.7;transition:all .2s ease}.remove-from-group-btn:hover{opacity:1;transform:scale(1.1)}.usage-hint{padding:.75rem 1rem;background:var(--slot-preview-bg);border:1px solid var(--slot-border);border-radius:6px;color:var(--hint-text);font-size:.875rem;text-align:center}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
1
|
+
import { default as default_2 } from 'react';
|
|
2
|
+
import { EditableConfigurablePanelLayout } from '@principal-ade/panels';
|
|
3
|
+
import { EditableConfigurablePanelLayoutProps } from '@principal-ade/panels';
|
|
4
|
+
import { mapThemeToPanelVars } from '@principal-ade/panels';
|
|
5
|
+
import { mapThemeToTabVars } from '@principal-ade/panels';
|
|
6
|
+
import { PanelDefinition } from '@principal-ade/panels';
|
|
7
|
+
import { PanelDefinitionWithContent } from '@principal-ade/panels';
|
|
8
|
+
import { PanelGroup } from '@principal-ade/panels';
|
|
9
|
+
import { PanelLayout } from '@principal-ade/panels';
|
|
10
|
+
import { PanelSlot } from '@principal-ade/panels';
|
|
11
|
+
import { ResponsiveConfigurablePanelLayout } from '@principal-ade/panels';
|
|
12
|
+
import { ResponsiveConfigurablePanelLayoutProps } from '@principal-ade/panels';
|
|
13
|
+
import { TabsConfig } from '@principal-ade/panels';
|
|
14
|
+
import { Theme } from '@principal-ade/panels';
|
|
15
|
+
import { TilesConfig } from '@principal-ade/panels';
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* Built-in workspace IDs
|
|
@@ -38,6 +41,22 @@ export { EditableConfigurablePanelLayout }
|
|
|
38
41
|
|
|
39
42
|
export { EditableConfigurablePanelLayoutProps }
|
|
40
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Visual indicator that highlights the focused panel
|
|
46
|
+
*
|
|
47
|
+
* Renders a subtle border/glow around the focused panel for keyboard navigation feedback
|
|
48
|
+
*/
|
|
49
|
+
export declare const FocusIndicator: default_2.FC<FocusIndicatorProps>;
|
|
50
|
+
|
|
51
|
+
export declare interface FocusIndicatorProps {
|
|
52
|
+
/** Whether this panel is currently focused */
|
|
53
|
+
isFocused: boolean;
|
|
54
|
+
/** Custom class name */
|
|
55
|
+
className?: string;
|
|
56
|
+
/** Custom styles */
|
|
57
|
+
style?: default_2.CSSProperties;
|
|
58
|
+
}
|
|
59
|
+
|
|
41
60
|
/**
|
|
42
61
|
* Default localStorage-based persistence adapter for web applications
|
|
43
62
|
*/
|
|
@@ -90,6 +109,28 @@ export { PanelDefinition }
|
|
|
90
109
|
|
|
91
110
|
export { PanelDefinitionWithContent }
|
|
92
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Actions for managing panel focus
|
|
114
|
+
*/
|
|
115
|
+
export declare interface PanelFocusActions {
|
|
116
|
+
/** Set focus to a specific panel */
|
|
117
|
+
setFocus: (panel: PanelSlotId) => void;
|
|
118
|
+
/** Clear focus from all panels */
|
|
119
|
+
clearFocus: () => void;
|
|
120
|
+
/** Focus the next visible panel */
|
|
121
|
+
focusNext: () => void;
|
|
122
|
+
/** Focus the previous visible panel */
|
|
123
|
+
focusPrevious: () => void;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Focus state for the panel layout
|
|
128
|
+
*/
|
|
129
|
+
export declare interface PanelFocusState {
|
|
130
|
+
/** Currently focused panel, or null if no panel is focused */
|
|
131
|
+
focusedPanel: PanelSlotId | null;
|
|
132
|
+
}
|
|
133
|
+
|
|
93
134
|
export { PanelGroup }
|
|
94
135
|
|
|
95
136
|
export { PanelLayout }
|
|
@@ -114,6 +155,14 @@ export declare interface PanelSizes {
|
|
|
114
155
|
|
|
115
156
|
export { PanelSlot }
|
|
116
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Focus management type definitions for keyboard shortcuts
|
|
160
|
+
*/
|
|
161
|
+
/**
|
|
162
|
+
* Panel identifier for focus tracking
|
|
163
|
+
*/
|
|
164
|
+
export declare type PanelSlotId = 'left' | 'middle' | 'right';
|
|
165
|
+
|
|
117
166
|
/**
|
|
118
167
|
* Storage adapter interface for persisting panel state
|
|
119
168
|
* Implementations can use localStorage, Electron IPC, or remote storage
|
|
@@ -163,6 +212,10 @@ export declare interface RepositoryWorkspaceState {
|
|
|
163
212
|
};
|
|
164
213
|
}
|
|
165
214
|
|
|
215
|
+
export { ResponsiveConfigurablePanelLayout }
|
|
216
|
+
|
|
217
|
+
export { ResponsiveConfigurablePanelLayoutProps }
|
|
218
|
+
|
|
166
219
|
export { TabsConfig }
|
|
167
220
|
|
|
168
221
|
export { Theme }
|
|
@@ -223,6 +276,63 @@ export declare interface UpdateWorkspaceOptions {
|
|
|
223
276
|
};
|
|
224
277
|
}
|
|
225
278
|
|
|
279
|
+
/**
|
|
280
|
+
* Hook for managing panel focus state with keyboard shortcuts
|
|
281
|
+
*/
|
|
282
|
+
export declare function usePanelFocus(options?: UsePanelFocusOptions): UsePanelFocusReturn;
|
|
283
|
+
|
|
284
|
+
export declare interface UsePanelFocusOptions {
|
|
285
|
+
/** Initial focused panel (optional) */
|
|
286
|
+
initialFocus?: PanelSlotId | null;
|
|
287
|
+
/** Collapsed state to determine which panels are visible */
|
|
288
|
+
collapsed?: PanelCollapsed;
|
|
289
|
+
/** Whether this is a two-panel or three-panel layout */
|
|
290
|
+
panelType?: 'two-panel' | 'three-panel';
|
|
291
|
+
/** Callback when focus changes */
|
|
292
|
+
onFocusChange?: (panel: PanelSlotId | null) => void;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export declare interface UsePanelFocusReturn extends PanelFocusState, PanelFocusActions {
|
|
296
|
+
/** Check if a specific panel is focused */
|
|
297
|
+
isFocused: (panel: PanelSlotId) => boolean;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Hook for handling Alt+1/2/3 keyboard shortcuts for panel toggle and focus
|
|
302
|
+
*
|
|
303
|
+
* Behavior:
|
|
304
|
+
* - Alt+1 (Left Panel):
|
|
305
|
+
* 1. If collapsed: expand (no focus change)
|
|
306
|
+
* 2. If expanded but not focused: focus it
|
|
307
|
+
* 3. If focused: collapse and focus middle
|
|
308
|
+
*
|
|
309
|
+
* - Alt+2 (Middle Panel):
|
|
310
|
+
* - Always focus middle (never collapses)
|
|
311
|
+
*
|
|
312
|
+
* - Alt+3 (Right Panel):
|
|
313
|
+
* 1. If collapsed: expand (no focus change)
|
|
314
|
+
* 2. If expanded but not focused: focus it
|
|
315
|
+
* 3. If focused: collapse and focus middle
|
|
316
|
+
*/
|
|
317
|
+
export declare function usePanelKeyboardShortcuts(options: UsePanelKeyboardShortcutsOptions): void;
|
|
318
|
+
|
|
319
|
+
export declare interface UsePanelKeyboardShortcutsOptions {
|
|
320
|
+
/** Whether keyboard shortcuts are enabled */
|
|
321
|
+
enabled?: boolean;
|
|
322
|
+
/** Current focused panel */
|
|
323
|
+
focusedPanel: PanelSlotId | null;
|
|
324
|
+
/** Current collapsed state */
|
|
325
|
+
collapsed: PanelCollapsed;
|
|
326
|
+
/** Panel type (two-panel or three-panel) */
|
|
327
|
+
panelType: 'two-panel' | 'three-panel';
|
|
328
|
+
/** Set focus to a specific panel */
|
|
329
|
+
setFocus: (panel: PanelSlotId) => void;
|
|
330
|
+
/** Callback to expand a panel */
|
|
331
|
+
onExpand: (panel: 'left' | 'right') => void | Promise<void>;
|
|
332
|
+
/** Callback to collapse a panel */
|
|
333
|
+
onCollapse: (panel: 'left' | 'right') => void | Promise<void>;
|
|
334
|
+
}
|
|
335
|
+
|
|
226
336
|
/**
|
|
227
337
|
* Hook for persisting panel layouts across sessions
|
|
228
338
|
*
|