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.
- package/dist/index.css +1134 -54
- package/dist/index.js +293 -90
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +293 -90
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +293 -90
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/desktop/ApplicationMenu.css +153 -54
- package/src/desktop/ApplicationMenu.js +75 -69
- package/src/desktop/Desktop.stories.jsx +256 -11
- package/src/desktop/WindowContext.js +4 -0
- package/src/desktop/WindowManager.js +54 -9
- package/src/desktop/desktop-linux.css +287 -0
- package/src/desktop/desktop-macos.css +317 -0
- package/src/desktop/desktop-windows.css +244 -0
- package/src/desktop/desktop.css +30 -0
- package/src/desktop/desktop.js +107 -67
- package/src/desktop/window.css +98 -0
- package/src/desktop/window.js +172 -4
- package/src/html/button.css +5 -0
- package/src/html/button.js +2 -1
package/package.json
CHANGED
@@ -1,18 +1,19 @@
|
|
1
|
-
/* ApplicationMenu -
|
1
|
+
/* ApplicationMenu - Positioned over workspace only */
|
2
2
|
|
3
3
|
.application-menu-overlay {
|
4
|
-
position:
|
4
|
+
position: absolute;
|
5
5
|
top: 0;
|
6
6
|
left: 0;
|
7
7
|
right: 0;
|
8
|
-
bottom: 0;
|
8
|
+
bottom: 0; /* Covers entire workspace container */
|
9
9
|
background: rgba(0, 0, 0, 0.8);
|
10
10
|
backdrop-filter: blur(8px);
|
11
|
-
z-index: 10000;
|
11
|
+
z-index: 10000; /* Always above all windows */
|
12
12
|
display: flex;
|
13
13
|
align-items: center;
|
14
14
|
justify-content: center;
|
15
15
|
animation: fadeIn 0.2s ease-out;
|
16
|
+
pointer-events: auto; /* Ensure menu is clickable */
|
16
17
|
}
|
17
18
|
|
18
19
|
@keyframes fadeIn {
|
@@ -29,11 +30,15 @@
|
|
29
30
|
border-radius: 12px;
|
30
31
|
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
31
32
|
width: 90%;
|
32
|
-
max-width:
|
33
|
-
height:
|
34
|
-
max-height:
|
35
|
-
display:
|
36
|
-
|
33
|
+
max-width: 1000px;
|
34
|
+
height: 90%; /* Use most of workspace height */
|
35
|
+
max-height: 100%; /* Constrained by workspace container */
|
36
|
+
display: grid;
|
37
|
+
grid-template-rows: auto auto 1fr;
|
38
|
+
grid-template-areas:
|
39
|
+
"header"
|
40
|
+
"search"
|
41
|
+
"main";
|
37
42
|
overflow: hidden;
|
38
43
|
animation: slideIn 0.3s ease-out;
|
39
44
|
}
|
@@ -51,6 +56,7 @@
|
|
51
56
|
|
52
57
|
/* Header */
|
53
58
|
.application-menu__header {
|
59
|
+
grid-area: header;
|
54
60
|
display: flex;
|
55
61
|
align-items: center;
|
56
62
|
justify-content: space-between;
|
@@ -84,6 +90,7 @@
|
|
84
90
|
|
85
91
|
/* Search */
|
86
92
|
.application-menu__search {
|
93
|
+
grid-area: search;
|
87
94
|
padding: 16px 24px;
|
88
95
|
border-bottom: 1px solid #e0e0e0;
|
89
96
|
}
|
@@ -102,51 +109,116 @@
|
|
102
109
|
border-color: #1976d2;
|
103
110
|
}
|
104
111
|
|
112
|
+
/* Main Grid Layout */
|
113
|
+
.application-menu__main {
|
114
|
+
grid-area: main;
|
115
|
+
display: grid;
|
116
|
+
grid-template-columns: 200px 1fr;
|
117
|
+
grid-template-areas: "sidebar content";
|
118
|
+
height: 100%;
|
119
|
+
overflow: hidden;
|
120
|
+
}
|
121
|
+
|
122
|
+
/* Sidebar */
|
123
|
+
.application-menu__sidebar {
|
124
|
+
grid-area: sidebar;
|
125
|
+
background: #f8f9fa;
|
126
|
+
border-right: 1px solid #e0e0e0;
|
127
|
+
overflow: hidden;
|
128
|
+
display: flex;
|
129
|
+
flex-direction: column;
|
130
|
+
}
|
131
|
+
|
105
132
|
/* Categories */
|
106
133
|
.application-menu__categories {
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
134
|
+
flex: 1;
|
135
|
+
padding: 16px 0;
|
136
|
+
overflow-y: auto;
|
137
|
+
scrollbar-width: thin;
|
138
|
+
scrollbar-color: #ccc transparent;
|
139
|
+
}
|
140
|
+
|
141
|
+
.application-menu__categories::-webkit-scrollbar {
|
142
|
+
width: 6px;
|
143
|
+
}
|
144
|
+
|
145
|
+
.application-menu__categories::-webkit-scrollbar-track {
|
146
|
+
background: transparent;
|
147
|
+
}
|
148
|
+
|
149
|
+
.application-menu__categories::-webkit-scrollbar-thumb {
|
150
|
+
background: #ccc;
|
151
|
+
border-radius: 3px;
|
152
|
+
}
|
153
|
+
|
154
|
+
.application-menu__categories::-webkit-scrollbar-thumb:hover {
|
155
|
+
background: #999;
|
113
156
|
}
|
114
157
|
|
115
158
|
.application-menu__category {
|
116
159
|
display: flex;
|
117
160
|
align-items: center;
|
118
|
-
gap:
|
119
|
-
padding:
|
120
|
-
|
121
|
-
|
122
|
-
border
|
161
|
+
gap: 12px;
|
162
|
+
padding: 12px 20px;
|
163
|
+
margin: 2px 8px;
|
164
|
+
background: transparent;
|
165
|
+
border: none;
|
166
|
+
border-radius: 8px;
|
123
167
|
cursor: pointer;
|
124
168
|
font-size: 14px;
|
125
|
-
|
169
|
+
text-align: left;
|
126
170
|
transition: all 0.2s ease;
|
127
171
|
color: #666;
|
172
|
+
width: calc(100% - 16px);
|
128
173
|
}
|
129
174
|
|
130
175
|
.application-menu__category:hover {
|
131
|
-
background: #
|
132
|
-
|
176
|
+
background: #e9ecef;
|
177
|
+
color: #333;
|
133
178
|
}
|
134
179
|
|
135
180
|
.application-menu__category.active {
|
136
181
|
background: #1976d2;
|
137
|
-
border-color: #1976d2;
|
138
182
|
color: white;
|
139
183
|
}
|
140
184
|
|
141
185
|
.category-icon {
|
142
|
-
font-size:
|
186
|
+
font-size: 18px;
|
187
|
+
min-width: 18px;
|
188
|
+
}
|
189
|
+
|
190
|
+
.category-name {
|
191
|
+
flex: 1;
|
192
|
+
white-space: nowrap;
|
193
|
+
overflow: hidden;
|
194
|
+
text-overflow: ellipsis;
|
143
195
|
}
|
144
196
|
|
145
197
|
/* Content */
|
146
198
|
.application-menu__content {
|
147
|
-
|
199
|
+
grid-area: content;
|
148
200
|
overflow-y: auto;
|
149
201
|
padding: 24px;
|
202
|
+
scrollbar-width: thin;
|
203
|
+
scrollbar-color: #ccc transparent;
|
204
|
+
}
|
205
|
+
|
206
|
+
.application-menu__content::-webkit-scrollbar {
|
207
|
+
width: 8px;
|
208
|
+
}
|
209
|
+
|
210
|
+
.application-menu__content::-webkit-scrollbar-track {
|
211
|
+
background: #f1f1f1;
|
212
|
+
border-radius: 4px;
|
213
|
+
}
|
214
|
+
|
215
|
+
.application-menu__content::-webkit-scrollbar-thumb {
|
216
|
+
background: #ccc;
|
217
|
+
border-radius: 4px;
|
218
|
+
}
|
219
|
+
|
220
|
+
.application-menu__content::-webkit-scrollbar-thumb:hover {
|
221
|
+
background: #999;
|
150
222
|
}
|
151
223
|
|
152
224
|
.application-menu__search-results h3,
|
@@ -168,8 +240,9 @@
|
|
168
240
|
/* Apps Grid */
|
169
241
|
.application-menu__apps-grid {
|
170
242
|
display: grid;
|
171
|
-
grid-template-columns: repeat(auto-fill, minmax(
|
243
|
+
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
172
244
|
gap: 16px;
|
245
|
+
max-width: 100%;
|
173
246
|
}
|
174
247
|
|
175
248
|
.application-menu__app {
|
@@ -228,52 +301,78 @@
|
|
228
301
|
@media (max-width: 768px) {
|
229
302
|
.application-menu {
|
230
303
|
width: 95%;
|
231
|
-
height:
|
232
|
-
|
304
|
+
height: 95%;
|
305
|
+
max-height: 100%; /* Constrained by workspace container */
|
306
|
+
margin: 5px;
|
233
307
|
}
|
234
|
-
|
308
|
+
|
309
|
+
.application-menu__main {
|
310
|
+
grid-template-columns: 160px 1fr;
|
311
|
+
}
|
312
|
+
|
313
|
+
.application-menu__category {
|
314
|
+
padding: 10px 16px;
|
315
|
+
font-size: 13px;
|
316
|
+
}
|
317
|
+
|
318
|
+
.category-icon {
|
319
|
+
font-size: 16px;
|
320
|
+
}
|
321
|
+
|
235
322
|
.application-menu__apps-grid {
|
236
|
-
grid-template-columns: repeat(auto-fill, minmax(
|
323
|
+
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
|
237
324
|
gap: 12px;
|
238
325
|
}
|
239
|
-
|
326
|
+
|
240
327
|
.application-menu__app {
|
241
328
|
padding: 12px 8px;
|
242
329
|
}
|
243
|
-
|
330
|
+
|
244
331
|
.app-icon {
|
245
|
-
font-size:
|
332
|
+
font-size: 36px;
|
246
333
|
}
|
247
|
-
|
334
|
+
|
248
335
|
.app-name {
|
249
336
|
font-size: 12px;
|
250
337
|
}
|
251
|
-
|
252
|
-
.application-menu__categories {
|
253
|
-
padding: 12px 16px;
|
254
|
-
}
|
255
|
-
|
338
|
+
|
256
339
|
.application-menu__search,
|
257
340
|
.application-menu__content {
|
258
341
|
padding: 16px;
|
259
342
|
}
|
260
343
|
}
|
261
344
|
|
262
|
-
|
263
|
-
|
264
|
-
width: 8px;
|
265
|
-
}
|
345
|
+
@media (max-width: 480px) {
|
346
|
+
/* ApplicationMenu overlay covers entire workspace on mobile */
|
266
347
|
|
267
|
-
.application-
|
268
|
-
|
269
|
-
|
270
|
-
|
348
|
+
.application-menu__main {
|
349
|
+
grid-template-columns: 1fr;
|
350
|
+
grid-template-rows: auto 1fr;
|
351
|
+
grid-template-areas:
|
352
|
+
"sidebar"
|
353
|
+
"content";
|
354
|
+
}
|
271
355
|
|
272
|
-
.application-
|
273
|
-
|
274
|
-
|
275
|
-
}
|
356
|
+
.application-menu__sidebar {
|
357
|
+
border-right: none;
|
358
|
+
border-bottom: 1px solid #e0e0e0;
|
359
|
+
}
|
276
360
|
|
277
|
-
.application-
|
278
|
-
|
361
|
+
.application-menu__categories {
|
362
|
+
display: flex;
|
363
|
+
flex-direction: row;
|
364
|
+
overflow-x: auto;
|
365
|
+
overflow-y: hidden;
|
366
|
+
padding: 12px 16px;
|
367
|
+
gap: 8px;
|
368
|
+
}
|
369
|
+
|
370
|
+
.application-menu__category {
|
371
|
+
flex-shrink: 0;
|
372
|
+
white-space: nowrap;
|
373
|
+
margin: 0;
|
374
|
+
width: auto;
|
375
|
+
}
|
279
376
|
}
|
377
|
+
|
378
|
+
|
@@ -7,6 +7,7 @@ import './ApplicationMenu.css'
|
|
7
7
|
* ApplicationMenu - Full-screen overlay menu for launching applications
|
8
8
|
*/
|
9
9
|
export const ApplicationMenu = ({ isOpen, onClose }) => {
|
10
|
+
console.log('ApplicationMenu render - isOpen:', isOpen, 'onClose:', onClose)
|
10
11
|
const appManager = useAppManager()
|
11
12
|
const [searchTerm, setSearchTerm] = useState('')
|
12
13
|
const [selectedCategory, setSelectedCategory] = useState('all')
|
@@ -112,7 +113,7 @@ export const ApplicationMenu = ({ isOpen, onClose }) => {
|
|
112
113
|
{/* Header */}
|
113
114
|
<div className="application-menu__header">
|
114
115
|
<h2>Applications</h2>
|
115
|
-
<button
|
116
|
+
<button
|
116
117
|
className="application-menu__close"
|
117
118
|
onClick={onClose}
|
118
119
|
title="Close menu"
|
@@ -133,78 +134,83 @@ export const ApplicationMenu = ({ isOpen, onClose }) => {
|
|
133
134
|
/>
|
134
135
|
</div>
|
135
136
|
|
136
|
-
{/*
|
137
|
-
<div className="application-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
137
|
+
{/* Main Grid Layout */}
|
138
|
+
<div className="application-menu__main">
|
139
|
+
{/* Categories Sidebar */}
|
140
|
+
<div className="application-menu__sidebar">
|
141
|
+
<div className="application-menu__categories">
|
142
|
+
<button
|
143
|
+
className={`application-menu__category ${selectedCategory === 'all' ? 'active' : ''}`}
|
144
|
+
onClick={() => handleCategorySelect('all')}
|
145
|
+
>
|
146
|
+
<span className="category-icon">📱</span>
|
147
|
+
<span className="category-name">All Apps</span>
|
148
|
+
</button>
|
149
|
+
{categories.map(category => (
|
150
|
+
<button
|
151
|
+
key={category.id}
|
152
|
+
className={`application-menu__category ${selectedCategory === category.id ? 'active' : ''}`}
|
153
|
+
onClick={() => handleCategorySelect(category.id)}
|
154
|
+
>
|
155
|
+
<span className="category-icon">{category.icon}</span>
|
156
|
+
<span className="category-name">{category.name}</span>
|
157
|
+
</button>
|
158
|
+
))}
|
159
|
+
</div>
|
160
|
+
</div>
|
161
|
+
|
162
|
+
{/* Applications Content */}
|
163
|
+
<div className="application-menu__content">
|
164
|
+
{searchTerm && (
|
165
|
+
<div className="application-menu__search-results">
|
166
|
+
<h3>Search Results ({filteredApps.length})</h3>
|
167
|
+
<div className="application-menu__apps-grid">
|
168
|
+
{filteredApps.map(app => (
|
169
|
+
<div
|
170
|
+
key={app.id}
|
171
|
+
className="application-menu__app"
|
172
|
+
onClick={() => handleLaunchApp(app)}
|
173
|
+
title={app.description}
|
174
|
+
>
|
175
|
+
<div className="app-icon">{app.icon}</div>
|
176
|
+
<div className="app-name">{app.name}</div>
|
177
|
+
</div>
|
178
|
+
))}
|
179
|
+
</div>
|
180
|
+
</div>
|
181
|
+
)}
|
182
|
+
|
183
|
+
{!searchTerm && (
|
184
|
+
<div className="application-menu__categories-content">
|
185
|
+
{Object.entries(groupedApps).map(([categoryName, categoryApps]) => (
|
186
|
+
<div key={categoryName} className="application-menu__category-section">
|
187
|
+
<h3 className="category-title">{categoryName}</h3>
|
188
|
+
<div className="application-menu__apps-grid">
|
189
|
+
{categoryApps.map(app => (
|
190
|
+
<div
|
191
|
+
key={app.id}
|
192
|
+
className="application-menu__app"
|
193
|
+
onClick={() => handleLaunchApp(app)}
|
194
|
+
title={app.description}
|
195
|
+
>
|
196
|
+
<div className="app-icon">{app.icon}</div>
|
197
|
+
<div className="app-name">{app.name}</div>
|
198
|
+
</div>
|
199
|
+
))}
|
200
|
+
</div>
|
172
201
|
</div>
|
173
202
|
))}
|
174
203
|
</div>
|
175
|
-
|
176
|
-
)}
|
177
|
-
|
178
|
-
{!searchTerm && (
|
179
|
-
<div className="application-menu__categories-content">
|
180
|
-
{Object.entries(groupedApps).map(([categoryName, categoryApps]) => (
|
181
|
-
<div key={categoryName} className="application-menu__category-section">
|
182
|
-
<h3 className="category-title">{categoryName}</h3>
|
183
|
-
<div className="application-menu__apps-grid">
|
184
|
-
{categoryApps.map(app => (
|
185
|
-
<div
|
186
|
-
key={app.id}
|
187
|
-
className="application-menu__app"
|
188
|
-
onClick={() => handleLaunchApp(app)}
|
189
|
-
title={app.description}
|
190
|
-
>
|
191
|
-
<div className="app-icon">{app.icon}</div>
|
192
|
-
<div className="app-name">{app.name}</div>
|
193
|
-
</div>
|
194
|
-
))}
|
195
|
-
</div>
|
196
|
-
</div>
|
197
|
-
))}
|
198
|
-
</div>
|
199
|
-
)}
|
204
|
+
)}
|
200
205
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
206
|
+
{filteredApps.length === 0 && (
|
207
|
+
<div className="application-menu__no-results">
|
208
|
+
<div style={{ fontSize: '48px', marginBottom: '16px' }}>🔍</div>
|
209
|
+
<h3>No applications found</h3>
|
210
|
+
<p>Try adjusting your search or category filter.</p>
|
211
|
+
</div>
|
212
|
+
)}
|
213
|
+
</div>
|
208
214
|
</div>
|
209
215
|
</div>
|
210
216
|
</div>
|