ywana-core8 0.2.5 → 0.2.8

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.
@@ -7,7 +7,7 @@ import { defaultAppManager } from './AppManager.js'
7
7
  */
8
8
  export const BasicDesktop = () => (
9
9
  <div style={{ height: '600px', width: '100%', position: 'relative', overflow: 'hidden' }}>
10
- <Desktop>
10
+ <Desktop desktopSize={{ width: 1200, height: 600 }}>
11
11
  <div style={{
12
12
  position: 'absolute',
13
13
  top: '50%',
@@ -61,7 +61,7 @@ export const CustomSizeDesktop = () => (
61
61
  */
62
62
  export const DarkDesktop = () => (
63
63
  <div style={{ height: '600px', width: '100%', position: 'relative', overflow: 'hidden' }}>
64
- <Desktop className="desktop--dark">
64
+ <Desktop className="desktop--dark" desktopSize={{ width: 1200, height: 600 }}>
65
65
  <div style={{
66
66
  position: 'absolute',
67
67
  top: '50%',
@@ -88,7 +88,7 @@ export const DarkDesktop = () => (
88
88
  */
89
89
  export const LightDesktop = () => (
90
90
  <div style={{ height: '600px', width: '100%', position: 'relative', overflow: 'hidden' }}>
91
- <Desktop className="desktop--light">
91
+ <Desktop className="desktop--light" desktopSize={{ width: 1200, height: 600 }}>
92
92
  <div style={{
93
93
  position: 'absolute',
94
94
  top: '50%',
@@ -238,18 +238,263 @@ export const ApplicationMenuBasic = () => (
238
238
  boxShadow: '0 2px 10px rgba(0,0,0,0.1)',
239
239
  maxWidth: '400px'
240
240
  }}>
241
- <h3 style={{ margin: '0 0 15px 0' }}>🚀 Application Menu Demo</h3>
241
+ <h3 style={{ margin: '0 0 15px 0' }}>🚀 New Layout: Workspace + Menu</h3>
242
242
  <p style={{ margin: '0 0 15px 0', lineHeight: '1.5' }}>
243
- Click the <strong>"Start"</strong> button in the taskbar to open the Application Menu.
244
- Browse applications by category and launch them to create windows.
243
+ Click <strong>"Start"</strong> to open the Application Menu.
244
+ The new architecture has a <strong>dedicated Workspace</strong> that contains windows,
245
+ and the <strong>ApplicationMenu overlays only the workspace</strong> (never the taskbar).
246
+ </p>
247
+ <div style={{ fontSize: '14px', color: '#666' }}>
248
+ <p><strong>New Architecture:</strong></p>
249
+ <ul style={{ margin: '5px 0', paddingLeft: '20px' }}>
250
+ <li>✅ <strong>Workspace container</strong> with proper boundaries</li>
251
+ <li>✅ <strong>Windows constrained</strong> to workspace area</li>
252
+ <li>✅ <strong>ApplicationMenu over workspace</strong> only</li>
253
+ <li>✅ <strong>Taskbar always accessible</strong> and separate</li>
254
+ <li>✅ Categories sidebar with independent scrolling</li>
255
+ <li>✅ Responsive grid layout</li>
256
+ </ul>
257
+ </div>
258
+ </div>
259
+ </Desktop>
260
+ </div>
261
+ )
262
+
263
+ /**
264
+ * Windows Theme Desktop
265
+ */
266
+ export const WindowsTheme = () => (
267
+ <div style={{ height: '600px', width: '100%', position: 'relative', overflow: 'hidden' }}>
268
+ <Desktop theme="windows" desktopSize={{ width: 1200, height: 600 }}>
269
+ <div style={{
270
+ position: 'absolute',
271
+ top: '20px',
272
+ left: '20px',
273
+ background: 'rgba(255,255,255,0.9)',
274
+ padding: '20px',
275
+ borderRadius: '8px',
276
+ boxShadow: '0 2px 10px rgba(0,0,0,0.1)',
277
+ maxWidth: '400px'
278
+ }}>
279
+ <h3 style={{ margin: '0 0 15px 0' }}>🪟 Windows Theme</h3>
280
+ <p style={{ margin: '0 0 15px 0', lineHeight: '1.5' }}>
281
+ Windows-inspired desktop theme with Segoe UI font, blue gradient background,
282
+ and Windows-style window controls and taskbar.
245
283
  </p>
246
284
  <div style={{ fontSize: '14px', color: '#666' }}>
247
285
  <p><strong>Features:</strong></p>
248
286
  <ul style={{ margin: '5px 0', paddingLeft: '20px' }}>
249
- <li>Browse apps by category</li>
250
- <li>Search functionality</li>
251
- <li>Launch applications as windows</li>
252
- <li>Full-screen overlay menu</li>
287
+ <li>Windows 11 inspired design</li>
288
+ <li>Segoe UI font family</li>
289
+ <li>Blue gradient background</li>
290
+ <li>Windows-style window controls</li>
291
+ </ul>
292
+ </div>
293
+ </div>
294
+ </Desktop>
295
+ </div>
296
+ )
297
+
298
+ /**
299
+ * macOS Theme Desktop
300
+ */
301
+ export const MacOSTheme = () => (
302
+ <div style={{ height: '600px', width: '100%', position: 'relative', overflow: 'hidden' }}>
303
+ <Desktop theme="macos" desktopSize={{ width: 1200, height: 600 }}>
304
+ <div style={{
305
+ position: 'absolute',
306
+ top: '20px',
307
+ left: '20px',
308
+ background: 'rgba(255,255,255,0.9)',
309
+ padding: '20px',
310
+ borderRadius: '16px',
311
+ boxShadow: '0 8px 25px rgba(0,0,0,0.15)',
312
+ maxWidth: '400px',
313
+ backdropFilter: 'blur(20px)'
314
+ }}>
315
+ <h3 style={{ margin: '0 0 15px 0' }}>🍎 macOS Theme</h3>
316
+ <p style={{ margin: '0 0 15px 0', lineHeight: '1.5' }}>
317
+ macOS-inspired desktop theme with SF Pro Display font, purple gradient background,
318
+ and signature traffic light window controls.
319
+ </p>
320
+ <div style={{ fontSize: '14px', color: '#666' }}>
321
+ <p><strong>Features:</strong></p>
322
+ <ul style={{ margin: '5px 0', paddingLeft: '20px' }}>
323
+ <li>macOS Big Sur/Monterey design</li>
324
+ <li>SF Pro Display font family</li>
325
+ <li>Purple gradient background</li>
326
+ <li>Traffic light window controls</li>
327
+ </ul>
328
+ </div>
329
+ </div>
330
+ </Desktop>
331
+ </div>
332
+ )
333
+
334
+ /**
335
+ * Linux Theme Desktop
336
+ */
337
+ export const LinuxTheme = () => (
338
+ <div style={{ height: '600px', width: '100%', position: 'relative', overflow: 'hidden' }}>
339
+ <Desktop theme="linux" desktopSize={{ width: 1200, height: 600 }}>
340
+ <div style={{
341
+ position: 'absolute',
342
+ top: '20px',
343
+ left: '20px',
344
+ background: 'rgba(255,255,255,0.9)',
345
+ padding: '20px',
346
+ borderRadius: '12px',
347
+ boxShadow: '0 4px 16px rgba(0,0,0,0.3)',
348
+ maxWidth: '400px'
349
+ }}>
350
+ <h3 style={{ margin: '0 0 15px 0' }}>🐧 Linux Theme</h3>
351
+ <p style={{ margin: '0 0 15px 0', lineHeight: '1.5' }}>
352
+ Linux GNOME-inspired desktop theme with Ubuntu font, dark gradient background,
353
+ and colorful circular window controls.
354
+ </p>
355
+ <div style={{ fontSize: '14px', color: '#666' }}>
356
+ <p><strong>Features:</strong></p>
357
+ <ul style={{ margin: '5px 0', paddingLeft: '20px' }}>
358
+ <li>GNOME/Ubuntu inspired design</li>
359
+ <li>Ubuntu/Cantarell font family</li>
360
+ <li>Dark gradient background</li>
361
+ <li>Colorful circular controls</li>
362
+ </ul>
363
+ </div>
364
+ </div>
365
+ </Desktop>
366
+ </div>
367
+ )
368
+
369
+ /**
370
+ * Theme Comparison - All three themes side by side
371
+ */
372
+ export const ThemeComparison = () => (
373
+ <div style={{
374
+ display: 'grid',
375
+ gridTemplateColumns: 'repeat(3, 1fr)',
376
+ gap: '20px',
377
+ padding: '20px',
378
+ height: '600px'
379
+ }}>
380
+ <div style={{ position: 'relative', overflow: 'hidden', border: '2px solid #ccc', borderRadius: '8px' }}>
381
+ <div style={{
382
+ position: 'absolute',
383
+ top: '5px',
384
+ left: '5px',
385
+ background: 'rgba(0,0,0,0.7)',
386
+ color: 'white',
387
+ padding: '4px 8px',
388
+ borderRadius: '4px',
389
+ fontSize: '12px',
390
+ zIndex: 1000
391
+ }}>
392
+ Windows
393
+ </div>
394
+ <Desktop theme="windows" desktopSize={{ width: 400, height: 560 }} />
395
+ </div>
396
+
397
+ <div style={{ position: 'relative', overflow: 'hidden', border: '2px solid #ccc', borderRadius: '8px' }}>
398
+ <div style={{
399
+ position: 'absolute',
400
+ top: '5px',
401
+ left: '5px',
402
+ background: 'rgba(0,0,0,0.7)',
403
+ color: 'white',
404
+ padding: '4px 8px',
405
+ borderRadius: '4px',
406
+ fontSize: '12px',
407
+ zIndex: 1000
408
+ }}>
409
+ macOS
410
+ </div>
411
+ <Desktop theme="macos" desktopSize={{ width: 400, height: 560 }} />
412
+ </div>
413
+
414
+ <div style={{ position: 'relative', overflow: 'hidden', border: '2px solid #ccc', borderRadius: '8px' }}>
415
+ <div style={{
416
+ position: 'absolute',
417
+ top: '5px',
418
+ left: '5px',
419
+ background: 'rgba(0,0,0,0.7)',
420
+ color: 'white',
421
+ padding: '4px 8px',
422
+ borderRadius: '4px',
423
+ fontSize: '12px',
424
+ zIndex: 1000
425
+ }}>
426
+ Linux
427
+ </div>
428
+ <Desktop theme="linux" desktopSize={{ width: 400, height: 560 }} />
429
+ </div>
430
+ </div>
431
+ )
432
+
433
+ /**
434
+ * Resizable Windows Demo
435
+ */
436
+ export const ResizableWindows = () => (
437
+ <div style={{ height: '600px', width: '100%', position: 'relative', overflow: 'hidden' }}>
438
+ <Desktop desktopSize={{ width: 1200, height: 600 }}>
439
+ <div style={{
440
+ position: 'absolute',
441
+ top: '20px',
442
+ left: '20px',
443
+ background: 'rgba(255,255,255,0.9)',
444
+ padding: '20px',
445
+ borderRadius: '8px',
446
+ boxShadow: '0 2px 10px rgba(0,0,0,0.1)',
447
+ maxWidth: '400px'
448
+ }}>
449
+ <h3 style={{ margin: '0 0 15px 0' }}>🔄 Resizable Windows</h3>
450
+ <p style={{ margin: '0 0 15px 0', lineHeight: '1.5' }}>
451
+ Create windows and try resizing them by dragging the edges and corners.
452
+ The WindowManager gets notified of size changes when you finish resizing.
453
+ </p>
454
+ <div style={{ fontSize: '14px', color: '#666' }}>
455
+ <p><strong>Resize Features:</strong></p>
456
+ <ul style={{ margin: '5px 0', paddingLeft: '20px' }}>
457
+ <li>Drag edges to resize horizontally/vertically</li>
458
+ <li>Drag corners to resize diagonally</li>
459
+ <li>Minimum size constraints (200x150)</li>
460
+ <li>WindowManager updates on resize end</li>
461
+ <li>Visual feedback with hover effects</li>
462
+ </ul>
463
+ </div>
464
+ </div>
465
+ </Desktop>
466
+ </div>
467
+ )
468
+
469
+ /**
470
+ * Resizable Windows with macOS Theme
471
+ */
472
+ export const ResizableWindowsMacOS = () => (
473
+ <div style={{ height: '600px', width: '100%', position: 'relative', overflow: 'hidden' }}>
474
+ <Desktop theme="macos" desktopSize={{ width: 1200, height: 600 }}>
475
+ <div style={{
476
+ position: 'absolute',
477
+ top: '20px',
478
+ left: '20px',
479
+ background: 'rgba(255,255,255,0.9)',
480
+ padding: '20px',
481
+ borderRadius: '16px',
482
+ boxShadow: '0 8px 25px rgba(0,0,0,0.15)',
483
+ maxWidth: '400px',
484
+ backdropFilter: 'blur(20px)'
485
+ }}>
486
+ <h3 style={{ margin: '0 0 15px 0' }}>🍎 macOS Resizable Windows</h3>
487
+ <p style={{ margin: '0 0 15px 0', lineHeight: '1.5' }}>
488
+ Experience window resizing with the beautiful macOS theme.
489
+ Notice the traffic light controls and smooth animations.
490
+ </p>
491
+ <div style={{ fontSize: '14px', color: '#666' }}>
492
+ <p><strong>macOS Features:</strong></p>
493
+ <ul style={{ margin: '5px 0', paddingLeft: '20px' }}>
494
+ <li>Traffic light window controls</li>
495
+ <li>Smooth resize animations</li>
496
+ <li>macOS-style blur effects</li>
497
+ <li>SF Pro Display typography</li>
253
498
  </ul>
254
499
  </div>
255
500
  </div>
@@ -258,7 +503,7 @@ export const ApplicationMenuBasic = () => (
258
503
  )
259
504
 
260
505
  /**
261
- * Desktop with ApplicationMenu - Advanced with controls
506
+ * Desktop with ApplicationMenu - Workspace Boundaries Demo
262
507
  */
263
508
  export const ApplicationMenuAdvanced = () => {
264
509
  // Setup custom apps
@@ -44,9 +44,12 @@ export const WindowProvider = ({ children, desktopSize }) => {
44
44
 
45
45
  // Don't render until WindowManager is initialized
46
46
  if (!state || !windowManagerRef.current) {
47
+ console.log('WindowProvider not ready - state:', state, 'windowManager:', windowManagerRef.current)
47
48
  return null
48
49
  }
49
50
 
51
+ console.log('WindowProvider ready - providing context')
52
+
50
53
  const value = {
51
54
  // Current state
52
55
  windows: state.windows,
@@ -63,6 +66,7 @@ export const WindowProvider = ({ children, desktopSize }) => {
63
66
  minimizeWindow: (id, minimize) => windowManagerRef.current.minimizeWindow(id, minimize),
64
67
  maximizeWindow: (id, maximize) => windowManagerRef.current.maximizeWindow(id, maximize),
65
68
  updateWindowPosition: (id, position) => windowManagerRef.current.updateWindowPosition(id, position),
69
+ updateWindowSize: (id, size) => windowManagerRef.current.updateWindowSize(id, size),
66
70
 
67
71
  // Window queries
68
72
  getWindow: (id) => windowManagerRef.current.getWindow(id),
@@ -6,6 +6,7 @@ export class WindowManager {
6
6
  this.windows = new Map()
7
7
  this.activeWindowId = null
8
8
  this.nextZIndex = 1000
9
+ this.maxZIndex = 9999 // Maximum z-index for windows (ApplicationMenu is 10000)
9
10
  this.listeners = new Set()
10
11
  this.desktopSize = desktopSize
11
12
  }
@@ -77,7 +78,7 @@ export class WindowManager {
77
78
  size: size,
78
79
  minimized: false,
79
80
  maximized: false,
80
- zIndex: this.nextZIndex++,
81
+ zIndex: Math.min(this.nextZIndex++, this.maxZIndex),
81
82
  ...config
82
83
  }
83
84
 
@@ -101,9 +102,9 @@ export class WindowManager {
101
102
  let x = baseX + (existingWindows.length * offsetStep)
102
103
  let y = baseY + (existingWindows.length * offsetStep)
103
104
 
104
- // Check if it goes out of desktop bounds
105
+ // Check if it goes out of workspace bounds
105
106
  const maxX = this.desktopSize.width - windowSize.width - 20
106
- const maxY = this.desktopSize.height - windowSize.height - 100 // Space for taskbar
107
+ const maxY = this.desktopSize.height - windowSize.height - 20 // Workspace boundaries
107
108
 
108
109
  // If out of bounds, restart cascade
109
110
  if (x > maxX || y > maxY) {
@@ -152,8 +153,11 @@ export class WindowManager {
152
153
  window.minimized = false
153
154
  }
154
155
 
155
- // Bring to front
156
- window.zIndex = this.nextZIndex++
156
+ // Bring to front (but never above ApplicationMenu)
157
+ if (this.nextZIndex >= this.maxZIndex) {
158
+ this.resetZIndexes()
159
+ }
160
+ window.zIndex = Math.min(this.nextZIndex++, this.maxZIndex)
157
161
  this.activeWindowId = windowId
158
162
 
159
163
  this.notifyListeners()
@@ -210,6 +214,29 @@ export class WindowManager {
210
214
  return true
211
215
  }
212
216
 
217
+ /**
218
+ * Update window size
219
+ */
220
+ updateWindowSize(windowId, size) {
221
+ const window = this.windows.get(windowId)
222
+ if (!window) return false
223
+
224
+ // Ensure minimum size constraints
225
+ const minWidth = 200
226
+ const minHeight = 150
227
+ const maxWidth = this.desktopSize.width
228
+ const maxHeight = this.desktopSize.height // Workspace boundaries
229
+
230
+ const constrainedSize = {
231
+ width: Math.max(minWidth, Math.min(size.width || window.size.width, maxWidth)),
232
+ height: Math.max(minHeight, Math.min(size.height || window.size.height, maxHeight))
233
+ }
234
+
235
+ window.size = { ...window.size, ...constrainedSize }
236
+ this.notifyListeners()
237
+ return true
238
+ }
239
+
213
240
  /**
214
241
  * Get all windows
215
242
  */
@@ -241,7 +268,7 @@ export class WindowManager {
241
268
  if (window.maximized) return // Maximized windows don't need repositioning
242
269
 
243
270
  const maxX = this.desktopSize.width - window.size.width
244
- const maxY = this.desktopSize.height - window.size.height - 50 // Space for taskbar
271
+ const maxY = this.desktopSize.height - window.size.height // Workspace boundaries
245
272
 
246
273
  // Adjust position if out of bounds
247
274
  if (window.position.x > maxX) {
@@ -283,7 +310,7 @@ export class WindowManager {
283
310
  const cols = Math.ceil(Math.sqrt(visibleWindows.length))
284
311
  const rows = Math.ceil(visibleWindows.length / cols)
285
312
  const windowWidth = Math.floor(this.desktopSize.width / cols)
286
- const windowHeight = Math.floor((this.desktopSize.height - 80) / rows) // Space for taskbar
313
+ const windowHeight = Math.floor(this.desktopSize.height / rows) // Workspace boundaries
287
314
 
288
315
  visibleWindows.forEach((window, index) => {
289
316
  const col = index % cols
@@ -312,7 +339,7 @@ export class WindowManager {
312
339
 
313
340
  window.position = {
314
341
  x: (this.desktopSize.width - window.size.width) / 2,
315
- y: (this.desktopSize.height - window.size.height - 50) / 2 // Space for taskbar
342
+ y: (this.desktopSize.height - window.size.height) / 2 // Workspace center
316
343
  }
317
344
 
318
345
  this.notifyListeners()
@@ -328,7 +355,7 @@ export class WindowManager {
328
355
 
329
356
  visibleWindows.forEach((window, index) => {
330
357
  const baseX = (this.desktopSize.width - window.size.width) / 2
331
- const baseY = (this.desktopSize.height - window.size.height - 50) / 2
358
+ const baseY = (this.desktopSize.height - window.size.height) / 2
332
359
 
333
360
  window.position = {
334
361
  x: baseX + (index * offsetStep),
@@ -352,4 +379,22 @@ export class WindowManager {
352
379
  desktopSize: this.desktopSize
353
380
  }
354
381
  }
382
+
383
+ /**
384
+ * Reset z-indexes when they reach the maximum
385
+ */
386
+ resetZIndexes() {
387
+ const windows = Array.from(this.windows.values())
388
+ // Sort windows by current z-index
389
+ windows.sort((a, b) => a.zIndex - b.zIndex)
390
+
391
+ // Reassign z-indexes starting from 1000
392
+ this.nextZIndex = 1000
393
+ windows.forEach((window, index) => {
394
+ window.zIndex = this.nextZIndex + index
395
+ })
396
+ this.nextZIndex = 1000 + windows.length
397
+
398
+ this.notifyListeners()
399
+ }
355
400
  }