@tachui/viewport 0.8.0-alpha
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/LICENSE +363 -0
- package/README.md +394 -0
- package/dist/index.js +2823 -0
- package/dist/index.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
# @tachui/viewport
|
|
2
|
+
|
|
3
|
+
> Viewport management and device detection for tachUI framework
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@tachui/viewport)
|
|
6
|
+
[](https://opensource.org/licenses/MPL-2.0)
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
The tachUI viewport package provides comprehensive viewport and window management capabilities inspired by SwiftUI's window system. It handles multi-window applications, device detection, platform adaptation, and provides a unified API across web, desktop, and mobile platforms.
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- 🪟 **Multi-Window Management** - Create and manage multiple windows/modals/portals
|
|
15
|
+
- 🖥️ **Platform Detection** - Comprehensive device and browser capability detection
|
|
16
|
+
- 📱 **Mobile Adaptation** - Handle safe areas, orientation, and mobile-specific patterns
|
|
17
|
+
- ⚡ **Performance Optimized** - Window pooling and efficient state management
|
|
18
|
+
- 🎨 **SwiftUI-inspired API** - Familiar patterns for iOS/macOS developers
|
|
19
|
+
- 🔧 **TypeScript-first** - Complete type safety with comprehensive interfaces
|
|
20
|
+
- 🌐 **Cross-Platform** - Works consistently across web, Electron, and mobile browsers
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @tachui/core@0.8.0-alpha @tachui/viewport@0.8.0-alpha
|
|
26
|
+
# or
|
|
27
|
+
pnpm add @tachui/core@0.8.0-alpha @tachui/viewport@0.8.0-alpha
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
### Basic Window Management
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import {
|
|
36
|
+
initializeViewportSystem,
|
|
37
|
+
useOpenWindow,
|
|
38
|
+
useDismissWindow,
|
|
39
|
+
} from '@tachui/viewport'
|
|
40
|
+
import { VStack, Button, Text } from '@tachui/primitives'
|
|
41
|
+
|
|
42
|
+
// Initialize the viewport system
|
|
43
|
+
const viewportManager = initializeViewportSystem()
|
|
44
|
+
|
|
45
|
+
const MyApp = () => {
|
|
46
|
+
const openWindow = useOpenWindow()
|
|
47
|
+
const dismissWindow = useDismissWindow()
|
|
48
|
+
|
|
49
|
+
const openSettings = async () => {
|
|
50
|
+
await openWindow(
|
|
51
|
+
'settings',
|
|
52
|
+
VStack({
|
|
53
|
+
children: [
|
|
54
|
+
Text('Settings Window'),
|
|
55
|
+
Button('Close', () => dismissWindow('settings')),
|
|
56
|
+
],
|
|
57
|
+
})
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return VStack({
|
|
62
|
+
children: [Text('Main Application'), Button('Open Settings', openSettings)],
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Platform Detection
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { PlatformUtils, detectViewportEnvironment } from '@tachui/viewport'
|
|
71
|
+
|
|
72
|
+
const MyComponent = () => {
|
|
73
|
+
const environment = detectViewportEnvironment()
|
|
74
|
+
|
|
75
|
+
if (PlatformUtils.isMobile()) {
|
|
76
|
+
return MobileLayout()
|
|
77
|
+
} else if (PlatformUtils.isElectron()) {
|
|
78
|
+
return DesktopLayout()
|
|
79
|
+
} else {
|
|
80
|
+
return WebLayout()
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Window Groups for Data-Driven Windows
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { WindowGroup } from '@tachui/viewport'
|
|
89
|
+
|
|
90
|
+
// Create a document-based window group
|
|
91
|
+
const DocumentGroup = WindowGroup.create('document', 'Document')
|
|
92
|
+
|
|
93
|
+
const MyApp = () => {
|
|
94
|
+
const openDocument = async documentData => {
|
|
95
|
+
await DocumentGroup.openWindow(documentData, doc =>
|
|
96
|
+
VStack({
|
|
97
|
+
children: [
|
|
98
|
+
Text(`Editing: ${doc.name}`),
|
|
99
|
+
// Document editing UI
|
|
100
|
+
],
|
|
101
|
+
})
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return VStack({
|
|
106
|
+
children: [
|
|
107
|
+
Button('New Document', () => openDocument({ name: 'Untitled' })),
|
|
108
|
+
],
|
|
109
|
+
})
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Core Concepts
|
|
114
|
+
|
|
115
|
+
### Viewport Types
|
|
116
|
+
|
|
117
|
+
The package supports different viewport types depending on platform capabilities:
|
|
118
|
+
|
|
119
|
+
- **Window**: Native OS windows (Electron, desktop browsers)
|
|
120
|
+
- **Modal**: Overlay modals for web browsers
|
|
121
|
+
- **Portal**: DOM portals for complex layouts
|
|
122
|
+
- **Sheet**: Bottom sheets for mobile interfaces
|
|
123
|
+
- **Popover**: Contextual popovers and tooltips
|
|
124
|
+
|
|
125
|
+
### Platform Adaptation
|
|
126
|
+
|
|
127
|
+
The system automatically chooses the best viewport type based on platform capabilities:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { getViewportManager } from '@tachui/viewport'
|
|
131
|
+
|
|
132
|
+
const manager = getViewportManager()
|
|
133
|
+
const optimalType = manager.getOptimalWindowType({
|
|
134
|
+
preferNativeWindow: true,
|
|
135
|
+
})
|
|
136
|
+
// Returns 'window' on Electron, 'modal' on web, 'sheet' on mobile
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Window Lifecycle
|
|
140
|
+
|
|
141
|
+
Windows follow a complete lifecycle with events and cleanup:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
const windowInstance = await openWindow('my-window', content)
|
|
145
|
+
|
|
146
|
+
// Listen to window events
|
|
147
|
+
windowInstance.onShow(() => console.log('Window shown'))
|
|
148
|
+
windowInstance.onHide(() => console.log('Window hidden'))
|
|
149
|
+
windowInstance.onClose(() => console.log('Window closed'))
|
|
150
|
+
|
|
151
|
+
// Window operations
|
|
152
|
+
await windowInstance.show()
|
|
153
|
+
await windowInstance.focus()
|
|
154
|
+
await windowInstance.minimize()
|
|
155
|
+
await windowInstance.close()
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Advanced Features
|
|
159
|
+
|
|
160
|
+
### Window Pooling
|
|
161
|
+
|
|
162
|
+
For better performance, windows can be pooled and reused:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { WindowGroup } from '@tachui/viewport'
|
|
166
|
+
|
|
167
|
+
const group = WindowGroup.create('pooled-windows')
|
|
168
|
+
|
|
169
|
+
// Configure window pooling
|
|
170
|
+
group.configurePool({
|
|
171
|
+
enabled: true,
|
|
172
|
+
maxPoolSize: 5,
|
|
173
|
+
reuseThreshold: 100, // ms
|
|
174
|
+
keepAliveTime: 30000, // 30 seconds
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
// Windows are automatically pooled and reused
|
|
178
|
+
await group.openWindow(data, renderFunction)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### State Synchronization
|
|
182
|
+
|
|
183
|
+
Share state across windows in a group:
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const group = WindowGroup.create('synchronized-windows')
|
|
187
|
+
|
|
188
|
+
// Enable state synchronization
|
|
189
|
+
group.enableStateSync('group') // 'none' | 'group' | 'global'
|
|
190
|
+
|
|
191
|
+
// Sync state across all windows in group
|
|
192
|
+
group.syncState('selectedItem', currentItem)
|
|
193
|
+
|
|
194
|
+
// Listen for state changes
|
|
195
|
+
group.onStateChange('selectedItem', item => {
|
|
196
|
+
console.log('Selection changed:', item)
|
|
197
|
+
})
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Window Grouping Strategies
|
|
201
|
+
|
|
202
|
+
Organize multiple windows with different strategies:
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
const group = WindowGroup.create('tabbed-windows')
|
|
206
|
+
|
|
207
|
+
// Configure tabbing
|
|
208
|
+
group.configureTabbing({
|
|
209
|
+
enabled: true,
|
|
210
|
+
maxTabs: 10,
|
|
211
|
+
tabPosition: 'top',
|
|
212
|
+
allowDetach: true,
|
|
213
|
+
allowReorder: true,
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
// Set grouping strategy
|
|
217
|
+
group.setGroupingStrategy('tabs') // 'tabs' | 'stack' | 'cascade' | 'tile'
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Environment Integration
|
|
221
|
+
|
|
222
|
+
### SwiftUI-Style Environment
|
|
223
|
+
|
|
224
|
+
Access viewport functionality through environment values:
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
import {
|
|
228
|
+
ViewportEnvironmentProvider,
|
|
229
|
+
useViewportEnvironment,
|
|
230
|
+
useCurrentWindow,
|
|
231
|
+
} from '@tachui/viewport'
|
|
232
|
+
|
|
233
|
+
const App = () => {
|
|
234
|
+
return ViewportEnvironmentProvider().children([AppContent()])
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const AppContent = () => {
|
|
238
|
+
const environment = useViewportEnvironment()
|
|
239
|
+
const currentWindow = useCurrentWindow()
|
|
240
|
+
|
|
241
|
+
const openNewWindow = () => {
|
|
242
|
+
environment.openWindow('new-window', content)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return Button('New Window', openNewWindow)
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Cross-Window Communication
|
|
250
|
+
|
|
251
|
+
Communicate between windows with message passing:
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
const window1 = await openWindow('window-1', content)
|
|
255
|
+
const window2 = await openWindow('window-2', content)
|
|
256
|
+
|
|
257
|
+
// Send message from window1 to window2
|
|
258
|
+
window1.postMessage({ type: 'data-update', payload: newData })
|
|
259
|
+
|
|
260
|
+
// Listen for messages in window2
|
|
261
|
+
window2.onMessage(message => {
|
|
262
|
+
if (message.type === 'data-update') {
|
|
263
|
+
updateLocalData(message.payload)
|
|
264
|
+
}
|
|
265
|
+
})
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Platform-Specific Features
|
|
269
|
+
|
|
270
|
+
### Web Browser Support
|
|
271
|
+
|
|
272
|
+
- Modal overlays with backdrop blur
|
|
273
|
+
- DOM portals for complex layouts
|
|
274
|
+
- Popup windows when available
|
|
275
|
+
- Responsive modal sizing
|
|
276
|
+
|
|
277
|
+
### Electron Integration
|
|
278
|
+
|
|
279
|
+
- Native OS windows with full controls
|
|
280
|
+
- Window positioning and sizing
|
|
281
|
+
- Menu bar integration
|
|
282
|
+
- Inter-process communication
|
|
283
|
+
|
|
284
|
+
### Mobile Browser Support
|
|
285
|
+
|
|
286
|
+
- Bottom sheet presentations
|
|
287
|
+
- Safe area handling
|
|
288
|
+
- Orientation-aware layouts
|
|
289
|
+
- Touch-optimized interactions
|
|
290
|
+
|
|
291
|
+
## API Reference
|
|
292
|
+
|
|
293
|
+
### Core Functions
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
// Initialization
|
|
297
|
+
initializeViewportSystem(options?: ViewportOptions): ViewportManager
|
|
298
|
+
|
|
299
|
+
// Environment hooks
|
|
300
|
+
useOpenWindow(): (id: string, component: Component, options?: WindowOptions) => Promise<ViewportInstance>
|
|
301
|
+
useDismissWindow(): (id: string) => Promise<void>
|
|
302
|
+
useViewportInfo(): ViewportEnvironment
|
|
303
|
+
useCurrentWindow(): ViewportInstance | null
|
|
304
|
+
|
|
305
|
+
// Platform utilities
|
|
306
|
+
PlatformUtils.isElectron(): boolean
|
|
307
|
+
PlatformUtils.isMobile(): boolean
|
|
308
|
+
PlatformUtils.supportsMultiWindow(): boolean
|
|
309
|
+
PlatformUtils.supportsNativeWindows(): boolean
|
|
310
|
+
|
|
311
|
+
// Detection functions
|
|
312
|
+
detectViewportEnvironment(): ViewportEnvironment
|
|
313
|
+
createCapabilityChecker(): CapabilityChecker
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Components
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
// Window components
|
|
320
|
+
App(scenes: AppScene[]): AppComponent
|
|
321
|
+
Window(id: string, content: Component): WindowComponent
|
|
322
|
+
WindowGroup<T>(id: string, dataType: string): WindowGroupComponent<T>
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Types
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
interface ViewportEnvironment {
|
|
329
|
+
platform: 'web' | 'electron' | 'mobile' | 'embedded'
|
|
330
|
+
capabilities: ViewportCapabilities
|
|
331
|
+
userAgent: string
|
|
332
|
+
screenSize: { width: number; height: number }
|
|
333
|
+
isTouch: boolean
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
interface WindowOptions {
|
|
337
|
+
title?: string
|
|
338
|
+
width?: number
|
|
339
|
+
height?: number
|
|
340
|
+
resizable?: boolean
|
|
341
|
+
modal?: boolean
|
|
342
|
+
preferNativeWindow?: boolean
|
|
343
|
+
// ... more options
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Browser Compatibility
|
|
348
|
+
|
|
349
|
+
- **Modern browsers** (Chrome, Firefox, Safari, Edge)
|
|
350
|
+
- **Electron** applications
|
|
351
|
+
- **Mobile browsers** (iOS Safari, Chrome Mobile)
|
|
352
|
+
- **Progressive Web Apps** with manifest support
|
|
353
|
+
|
|
354
|
+
## Performance Considerations
|
|
355
|
+
|
|
356
|
+
### Window Pooling Benefits
|
|
357
|
+
|
|
358
|
+
- Reduces window creation overhead
|
|
359
|
+
- Faster window reuse for repeated operations
|
|
360
|
+
- Memory-efficient window management
|
|
361
|
+
- Configurable pool size and retention
|
|
362
|
+
|
|
363
|
+
### Bundle Size
|
|
364
|
+
|
|
365
|
+
The @tachui/viewport package is approximately **15KB** minified and gzipped, making it suitable for both web and desktop applications.
|
|
366
|
+
|
|
367
|
+
### Memory Management
|
|
368
|
+
|
|
369
|
+
- Automatic cleanup of event listeners
|
|
370
|
+
- Window pooling to reduce garbage collection
|
|
371
|
+
- Efficient state synchronization
|
|
372
|
+
- Lazy loading of platform-specific features
|
|
373
|
+
|
|
374
|
+
## Migration from @tachui/core
|
|
375
|
+
|
|
376
|
+
If you were previously using viewport functionality from @tachui/core, here's how to migrate:
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
// Old (from @tachui/core)
|
|
380
|
+
import { Viewport, initializeViewportSystem } from '@tachui/core'
|
|
381
|
+
|
|
382
|
+
// New (from @tachui/viewport)
|
|
383
|
+
import { Viewport, initializeViewportSystem } from '@tachui/viewport'
|
|
384
|
+
|
|
385
|
+
// The APIs remain the same, just import from the new package
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
## Contributing
|
|
389
|
+
|
|
390
|
+
See the main [Contributing Guide](https://github.com/tach-UI/tachUI/blob/main/CONTRIBUTING.md) for information on contributing to tachUI viewport functionality.
|
|
391
|
+
|
|
392
|
+
## License
|
|
393
|
+
|
|
394
|
+
Mozilla Public License 2.0 - see [LICENSE](https://github.com/tach-UI/tachUI/blob/main/LICENSE) for details.
|