ywana-core8 0.2.4 → 0.2.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/dist/index.css +961 -0
- package/dist/index.js +450 -6
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +450 -6
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +450 -6
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/desktop/AppManager.js +270 -0
- package/src/desktop/ApplicationMenu.css +279 -0
- package/src/desktop/ApplicationMenu.js +214 -0
- package/src/desktop/Desktop.stories.jsx +432 -5
- package/src/desktop/WindowContext.js +1 -0
- package/src/desktop/WindowManager.js +23 -0
- package/src/desktop/desktop-linux.css +232 -0
- package/src/desktop/desktop-macos.css +260 -0
- package/src/desktop/desktop-windows.css +190 -0
- package/src/desktop/desktop.js +131 -33
- package/src/desktop/index.js +5 -1
- package/src/desktop/window.js +9 -2
- package/src/examples/ApplicationMenuExample.js +361 -0
package/dist/index.modern.js
CHANGED
@@ -31867,6 +31867,24 @@ class WindowManager {
|
|
31867
31867
|
this.notifyListeners();
|
31868
31868
|
return true;
|
31869
31869
|
}
|
31870
|
+
/**
|
31871
|
+
* Update window size
|
31872
|
+
*/
|
31873
|
+
updateWindowSize(windowId, size) {
|
31874
|
+
const window2 = this.windows.get(windowId);
|
31875
|
+
if (!window2) return false;
|
31876
|
+
const minWidth = 200;
|
31877
|
+
const minHeight = 150;
|
31878
|
+
const maxWidth = this.desktopSize.width;
|
31879
|
+
const maxHeight = this.desktopSize.height - 50;
|
31880
|
+
const constrainedSize = {
|
31881
|
+
width: Math.max(minWidth, Math.min(size.width || window2.size.width, maxWidth)),
|
31882
|
+
height: Math.max(minHeight, Math.min(size.height || window2.size.height, maxHeight))
|
31883
|
+
};
|
31884
|
+
window2.size = { ...window2.size, ...constrainedSize };
|
31885
|
+
this.notifyListeners();
|
31886
|
+
return true;
|
31887
|
+
}
|
31870
31888
|
/**
|
31871
31889
|
* Get all windows
|
31872
31890
|
*/
|
@@ -32029,6 +32047,7 @@ const WindowProvider = ({ children, desktopSize }) => {
|
|
32029
32047
|
minimizeWindow: (id, minimize) => windowManagerRef.current.minimizeWindow(id, minimize),
|
32030
32048
|
maximizeWindow: (id, maximize) => windowManagerRef.current.maximizeWindow(id, maximize),
|
32031
32049
|
updateWindowPosition: (id, position) => windowManagerRef.current.updateWindowPosition(id, position),
|
32050
|
+
updateWindowSize: (id, size) => windowManagerRef.current.updateWindowSize(id, size),
|
32032
32051
|
// Window queries
|
32033
32052
|
getWindow: (id) => windowManagerRef.current.getWindow(id),
|
32034
32053
|
getAllWindows: () => windowManagerRef.current.getAllWindows(),
|
@@ -32091,11 +32110,16 @@ const Window = ({
|
|
32091
32110
|
}) => {
|
32092
32111
|
const windowRef = useRef(null);
|
32093
32112
|
const headerRef = useRef(null);
|
32094
|
-
const { getWindow, updateWindowPosition, closeWindow, minimizeWindow, maximizeWindow, focusWindow } = useWindows();
|
32113
|
+
const { getWindow, updateWindowPosition, updateWindowSize, closeWindow, minimizeWindow, maximizeWindow, focusWindow } = useWindows();
|
32095
32114
|
const windowData = getWindow(id);
|
32096
32115
|
const [isDragging, setIsDragging] = useState(false);
|
32097
32116
|
const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
|
32098
32117
|
const [dragStartPosition, setDragStartPosition] = useState({ x: 0, y: 0 });
|
32118
|
+
const [isResizing, setIsResizing] = useState(false);
|
32119
|
+
const [resizeDirection, setResizeDirection] = useState("");
|
32120
|
+
const [resizeStartSize, setResizeStartSize] = useState({ width: 0, height: 0 });
|
32121
|
+
const [resizeStartPosition, setResizeStartPosition] = useState({ x: 0, y: 0 });
|
32122
|
+
const [resizeStartMouse, setResizeStartMouse] = useState({ x: 0, y: 0 });
|
32099
32123
|
if (!windowData) {
|
32100
32124
|
return null;
|
32101
32125
|
}
|
@@ -32250,7 +32274,387 @@ const Window = ({
|
|
32250
32274
|
statusBar && /* @__PURE__ */ React.createElement("div", { className: "window__status-bar" }, statusBar)
|
32251
32275
|
);
|
32252
32276
|
};
|
32253
|
-
const
|
32277
|
+
const ApplicationMenu = ({ isOpen, onClose }) => {
|
32278
|
+
const appManager = useAppManager();
|
32279
|
+
const [searchTerm, setSearchTerm] = useState("");
|
32280
|
+
const [selectedCategory, setSelectedCategory] = useState("all");
|
32281
|
+
const [apps, setApps] = useState([]);
|
32282
|
+
const [categories, setCategories] = useState([]);
|
32283
|
+
const searchInputRef = useRef(null);
|
32284
|
+
const { createWindow } = useWindows();
|
32285
|
+
useEffect(() => {
|
32286
|
+
const loadData = () => {
|
32287
|
+
setApps(appManager.getAllApps());
|
32288
|
+
setCategories(appManager.getAllCategories());
|
32289
|
+
};
|
32290
|
+
loadData();
|
32291
|
+
appManager.addListener(loadData);
|
32292
|
+
return () => {
|
32293
|
+
appManager.removeListener(loadData);
|
32294
|
+
};
|
32295
|
+
}, [appManager]);
|
32296
|
+
useEffect(() => {
|
32297
|
+
if (isOpen && searchInputRef.current) {
|
32298
|
+
setTimeout(() => {
|
32299
|
+
searchInputRef.current.focus();
|
32300
|
+
}, 100);
|
32301
|
+
}
|
32302
|
+
}, [isOpen]);
|
32303
|
+
useEffect(() => {
|
32304
|
+
const handleKeyDown = (e) => {
|
32305
|
+
if (e.key === "Escape" && isOpen) {
|
32306
|
+
onClose();
|
32307
|
+
}
|
32308
|
+
};
|
32309
|
+
if (isOpen) {
|
32310
|
+
document.addEventListener("keydown", handleKeyDown);
|
32311
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
32312
|
+
}
|
32313
|
+
}, [isOpen, onClose]);
|
32314
|
+
const filteredApps = apps.filter((app) => {
|
32315
|
+
const matchesSearch = searchTerm === "" || app.name.toLowerCase().includes(searchTerm.toLowerCase()) || app.description.toLowerCase().includes(searchTerm.toLowerCase());
|
32316
|
+
const matchesCategory = selectedCategory === "all" || app.category.toLowerCase() === selectedCategory.toLowerCase();
|
32317
|
+
return matchesSearch && matchesCategory;
|
32318
|
+
});
|
32319
|
+
const groupedApps = filteredApps.reduce((groups, app) => {
|
32320
|
+
const category = app.category;
|
32321
|
+
if (!groups[category]) {
|
32322
|
+
groups[category] = [];
|
32323
|
+
}
|
32324
|
+
groups[category].push(app);
|
32325
|
+
return groups;
|
32326
|
+
}, {});
|
32327
|
+
const handleLaunchApp = (app) => {
|
32328
|
+
createWindow({
|
32329
|
+
id: `${app.id}-${Date.now()}`,
|
32330
|
+
title: app.name,
|
32331
|
+
icon: app.icon,
|
32332
|
+
size: app.size,
|
32333
|
+
toolbar: app.toolbar,
|
32334
|
+
statusBar: app.statusBar,
|
32335
|
+
content: app.component || /* @__PURE__ */ React.createElement("div", { style: { padding: "20px", textAlign: "center" } }, /* @__PURE__ */ React.createElement("div", { style: { fontSize: "48px", marginBottom: "16px" } }, app.icon), /* @__PURE__ */ React.createElement("h2", null, app.name), /* @__PURE__ */ React.createElement("p", { style: { color: "#666", marginBottom: "20px" } }, app.description), /* @__PURE__ */ React.createElement("p", { style: { fontSize: "14px", color: "#999" } }, "This is a placeholder for the ", app.name, " application."))
|
32336
|
+
});
|
32337
|
+
onClose();
|
32338
|
+
};
|
32339
|
+
const handleCategorySelect = (categoryId) => {
|
32340
|
+
setSelectedCategory(categoryId);
|
32341
|
+
setSearchTerm("");
|
32342
|
+
};
|
32343
|
+
if (!isOpen) return null;
|
32344
|
+
return /* @__PURE__ */ React.createElement("div", { className: "application-menu-overlay", onClick: onClose }, /* @__PURE__ */ React.createElement("div", { className: "application-menu", onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ React.createElement("div", { className: "application-menu__header" }, /* @__PURE__ */ React.createElement("h2", null, "Applications"), /* @__PURE__ */ React.createElement(
|
32345
|
+
"button",
|
32346
|
+
{
|
32347
|
+
className: "application-menu__close",
|
32348
|
+
onClick: onClose,
|
32349
|
+
title: "Close menu"
|
32350
|
+
},
|
32351
|
+
"×"
|
32352
|
+
)), /* @__PURE__ */ React.createElement("div", { className: "application-menu__search" }, /* @__PURE__ */ React.createElement(
|
32353
|
+
"input",
|
32354
|
+
{
|
32355
|
+
ref: searchInputRef,
|
32356
|
+
type: "text",
|
32357
|
+
placeholder: "Search applications...",
|
32358
|
+
value: searchTerm,
|
32359
|
+
onChange: (e) => setSearchTerm(e.target.value),
|
32360
|
+
className: "application-menu__search-input"
|
32361
|
+
}
|
32362
|
+
)), /* @__PURE__ */ React.createElement("div", { className: "application-menu__categories" }, /* @__PURE__ */ React.createElement(
|
32363
|
+
"button",
|
32364
|
+
{
|
32365
|
+
className: `application-menu__category ${selectedCategory === "all" ? "active" : ""}`,
|
32366
|
+
onClick: () => handleCategorySelect("all")
|
32367
|
+
},
|
32368
|
+
/* @__PURE__ */ React.createElement("span", { className: "category-icon" }, "📱"),
|
32369
|
+
"All Apps"
|
32370
|
+
), categories.map((category) => /* @__PURE__ */ React.createElement(
|
32371
|
+
"button",
|
32372
|
+
{
|
32373
|
+
key: category.id,
|
32374
|
+
className: `application-menu__category ${selectedCategory === category.id ? "active" : ""}`,
|
32375
|
+
onClick: () => handleCategorySelect(category.id)
|
32376
|
+
},
|
32377
|
+
/* @__PURE__ */ React.createElement("span", { className: "category-icon" }, category.icon),
|
32378
|
+
category.name
|
32379
|
+
))), /* @__PURE__ */ React.createElement("div", { className: "application-menu__content" }, searchTerm && /* @__PURE__ */ React.createElement("div", { className: "application-menu__search-results" }, /* @__PURE__ */ React.createElement("h3", null, "Search Results (", filteredApps.length, ")"), /* @__PURE__ */ React.createElement("div", { className: "application-menu__apps-grid" }, filteredApps.map((app) => /* @__PURE__ */ React.createElement(
|
32380
|
+
"div",
|
32381
|
+
{
|
32382
|
+
key: app.id,
|
32383
|
+
className: "application-menu__app",
|
32384
|
+
onClick: () => handleLaunchApp(app),
|
32385
|
+
title: app.description
|
32386
|
+
},
|
32387
|
+
/* @__PURE__ */ React.createElement("div", { className: "app-icon" }, app.icon),
|
32388
|
+
/* @__PURE__ */ React.createElement("div", { className: "app-name" }, app.name)
|
32389
|
+
)))), !searchTerm && /* @__PURE__ */ React.createElement("div", { className: "application-menu__categories-content" }, Object.entries(groupedApps).map(([categoryName, categoryApps]) => /* @__PURE__ */ React.createElement("div", { key: categoryName, className: "application-menu__category-section" }, /* @__PURE__ */ React.createElement("h3", { className: "category-title" }, categoryName), /* @__PURE__ */ React.createElement("div", { className: "application-menu__apps-grid" }, categoryApps.map((app) => /* @__PURE__ */ React.createElement(
|
32390
|
+
"div",
|
32391
|
+
{
|
32392
|
+
key: app.id,
|
32393
|
+
className: "application-menu__app",
|
32394
|
+
onClick: () => handleLaunchApp(app),
|
32395
|
+
title: app.description
|
32396
|
+
},
|
32397
|
+
/* @__PURE__ */ React.createElement("div", { className: "app-icon" }, app.icon),
|
32398
|
+
/* @__PURE__ */ React.createElement("div", { className: "app-name" }, app.name)
|
32399
|
+
)))))), filteredApps.length === 0 && /* @__PURE__ */ React.createElement("div", { className: "application-menu__no-results" }, /* @__PURE__ */ React.createElement("div", { style: { fontSize: "48px", marginBottom: "16px" } }, "🔍"), /* @__PURE__ */ React.createElement("h3", null, "No applications found"), /* @__PURE__ */ React.createElement("p", null, "Try adjusting your search or category filter.")))));
|
32400
|
+
};
|
32401
|
+
class AppManager {
|
32402
|
+
constructor() {
|
32403
|
+
this.applications = /* @__PURE__ */ new Map();
|
32404
|
+
this.categories = /* @__PURE__ */ new Map();
|
32405
|
+
this.listeners = /* @__PURE__ */ new Set();
|
32406
|
+
this.initializeDefaultApps();
|
32407
|
+
}
|
32408
|
+
/**
|
32409
|
+
* Initialize default applications
|
32410
|
+
*/
|
32411
|
+
initializeDefaultApps() {
|
32412
|
+
this.registerApp({
|
32413
|
+
id: "file-explorer",
|
32414
|
+
name: "File Explorer",
|
32415
|
+
description: "Browse and manage files",
|
32416
|
+
icon: "📁",
|
32417
|
+
category: "System",
|
32418
|
+
component: null,
|
32419
|
+
// Will be set when registering actual components
|
32420
|
+
size: { width: 600, height: 400 },
|
32421
|
+
toolbar: null,
|
32422
|
+
statusBar: null
|
32423
|
+
});
|
32424
|
+
this.registerApp({
|
32425
|
+
id: "text-editor",
|
32426
|
+
name: "Text Editor",
|
32427
|
+
description: "Edit text files",
|
32428
|
+
icon: "📝",
|
32429
|
+
category: "Productivity",
|
32430
|
+
component: null,
|
32431
|
+
size: { width: 500, height: 350 },
|
32432
|
+
toolbar: null,
|
32433
|
+
statusBar: null
|
32434
|
+
});
|
32435
|
+
this.registerApp({
|
32436
|
+
id: "calculator",
|
32437
|
+
name: "Calculator",
|
32438
|
+
description: "Perform calculations",
|
32439
|
+
icon: "🧮",
|
32440
|
+
category: "Utilities",
|
32441
|
+
component: null,
|
32442
|
+
size: { width: 300, height: 400 }
|
32443
|
+
});
|
32444
|
+
this.registerApp({
|
32445
|
+
id: "settings",
|
32446
|
+
name: "Settings",
|
32447
|
+
description: "System configuration",
|
32448
|
+
icon: "⚙️",
|
32449
|
+
category: "System",
|
32450
|
+
component: null,
|
32451
|
+
size: { width: 450, height: 300 }
|
32452
|
+
});
|
32453
|
+
this.registerApp({
|
32454
|
+
id: "browser",
|
32455
|
+
name: "Web Browser",
|
32456
|
+
description: "Browse the internet",
|
32457
|
+
icon: "🌐",
|
32458
|
+
category: "Internet",
|
32459
|
+
component: null,
|
32460
|
+
size: { width: 800, height: 500 }
|
32461
|
+
});
|
32462
|
+
this.registerApp({
|
32463
|
+
id: "terminal",
|
32464
|
+
name: "Terminal",
|
32465
|
+
description: "Command line interface",
|
32466
|
+
icon: "💻",
|
32467
|
+
category: "Development",
|
32468
|
+
component: null,
|
32469
|
+
size: { width: 700, height: 400 }
|
32470
|
+
});
|
32471
|
+
this.registerApp({
|
32472
|
+
id: "image-viewer",
|
32473
|
+
name: "Image Viewer",
|
32474
|
+
description: "View and edit images",
|
32475
|
+
icon: "🖼️",
|
32476
|
+
category: "Media",
|
32477
|
+
component: null,
|
32478
|
+
size: { width: 600, height: 500 }
|
32479
|
+
});
|
32480
|
+
this.registerApp({
|
32481
|
+
id: "music-player",
|
32482
|
+
name: "Music Player",
|
32483
|
+
description: "Play audio files",
|
32484
|
+
icon: "🎵",
|
32485
|
+
category: "Media",
|
32486
|
+
component: null,
|
32487
|
+
size: { width: 400, height: 300 }
|
32488
|
+
});
|
32489
|
+
this.initializeCategories();
|
32490
|
+
}
|
32491
|
+
/**
|
32492
|
+
* Initialize application categories
|
32493
|
+
*/
|
32494
|
+
initializeCategories() {
|
32495
|
+
const categoryData = [
|
32496
|
+
{ id: "system", name: "System", icon: "⚙️", color: "#607d8b" },
|
32497
|
+
{ id: "productivity", name: "Productivity", icon: "📊", color: "#2196f3" },
|
32498
|
+
{ id: "utilities", name: "Utilities", icon: "🔧", color: "#ff9800" },
|
32499
|
+
{ id: "internet", name: "Internet", icon: "🌐", color: "#4caf50" },
|
32500
|
+
{ id: "development", name: "Development", icon: "💻", color: "#9c27b0" },
|
32501
|
+
{ id: "media", name: "Media", icon: "🎬", color: "#e91e63" },
|
32502
|
+
{ id: "games", name: "Games", icon: "🎮", color: "#f44336" }
|
32503
|
+
];
|
32504
|
+
categoryData.forEach((category) => {
|
32505
|
+
this.categories.set(category.id, category);
|
32506
|
+
});
|
32507
|
+
}
|
32508
|
+
/**
|
32509
|
+
* Register a new application
|
32510
|
+
*/
|
32511
|
+
registerApp(appConfig) {
|
32512
|
+
const app = {
|
32513
|
+
id: appConfig.id,
|
32514
|
+
name: appConfig.name,
|
32515
|
+
description: appConfig.description || "",
|
32516
|
+
icon: appConfig.icon || "📄",
|
32517
|
+
category: appConfig.category || "Utilities",
|
32518
|
+
component: appConfig.component || null,
|
32519
|
+
size: appConfig.size || { width: 600, height: 400 },
|
32520
|
+
toolbar: appConfig.toolbar || null,
|
32521
|
+
statusBar: appConfig.statusBar || null,
|
32522
|
+
...appConfig
|
32523
|
+
};
|
32524
|
+
this.applications.set(app.id, app);
|
32525
|
+
this.notifyListeners();
|
32526
|
+
return app.id;
|
32527
|
+
}
|
32528
|
+
/**
|
32529
|
+
* Unregister an application
|
32530
|
+
*/
|
32531
|
+
unregisterApp(appId) {
|
32532
|
+
const removed = this.applications.delete(appId);
|
32533
|
+
if (removed) {
|
32534
|
+
this.notifyListeners();
|
32535
|
+
}
|
32536
|
+
return removed;
|
32537
|
+
}
|
32538
|
+
/**
|
32539
|
+
* Get an application by ID
|
32540
|
+
*/
|
32541
|
+
getApp(appId) {
|
32542
|
+
return this.applications.get(appId);
|
32543
|
+
}
|
32544
|
+
/**
|
32545
|
+
* Get all applications
|
32546
|
+
*/
|
32547
|
+
getAllApps() {
|
32548
|
+
return Array.from(this.applications.values());
|
32549
|
+
}
|
32550
|
+
/**
|
32551
|
+
* Get applications by category
|
32552
|
+
*/
|
32553
|
+
getAppsByCategory(categoryId) {
|
32554
|
+
return Array.from(this.applications.values()).filter((app) => app.category.toLowerCase() === categoryId.toLowerCase());
|
32555
|
+
}
|
32556
|
+
/**
|
32557
|
+
* Get all categories
|
32558
|
+
*/
|
32559
|
+
getAllCategories() {
|
32560
|
+
return Array.from(this.categories.values());
|
32561
|
+
}
|
32562
|
+
/**
|
32563
|
+
* Get category by ID
|
32564
|
+
*/
|
32565
|
+
getCategory(categoryId) {
|
32566
|
+
return this.categories.get(categoryId.toLowerCase());
|
32567
|
+
}
|
32568
|
+
/**
|
32569
|
+
* Search applications
|
32570
|
+
*/
|
32571
|
+
searchApps(query) {
|
32572
|
+
const searchTerm = query.toLowerCase();
|
32573
|
+
return Array.from(this.applications.values()).filter(
|
32574
|
+
(app) => app.name.toLowerCase().includes(searchTerm) || app.description.toLowerCase().includes(searchTerm) || app.category.toLowerCase().includes(searchTerm)
|
32575
|
+
);
|
32576
|
+
}
|
32577
|
+
/**
|
32578
|
+
* Add listener for changes
|
32579
|
+
*/
|
32580
|
+
addListener(listener) {
|
32581
|
+
this.listeners.add(listener);
|
32582
|
+
}
|
32583
|
+
/**
|
32584
|
+
* Remove listener
|
32585
|
+
*/
|
32586
|
+
removeListener(listener) {
|
32587
|
+
this.listeners.delete(listener);
|
32588
|
+
}
|
32589
|
+
/**
|
32590
|
+
* Notify all listeners about changes
|
32591
|
+
*/
|
32592
|
+
notifyListeners() {
|
32593
|
+
this.listeners.forEach((listener) => listener(this.getAllApps()));
|
32594
|
+
}
|
32595
|
+
/**
|
32596
|
+
* Get applications grouped by category
|
32597
|
+
*/
|
32598
|
+
getAppsGroupedByCategory() {
|
32599
|
+
const grouped = {};
|
32600
|
+
const categories = this.getAllCategories();
|
32601
|
+
categories.forEach((category) => {
|
32602
|
+
grouped[category.id] = {
|
32603
|
+
category,
|
32604
|
+
apps: []
|
32605
|
+
};
|
32606
|
+
});
|
32607
|
+
this.getAllApps().forEach((app) => {
|
32608
|
+
const categoryId = app.category.toLowerCase();
|
32609
|
+
if (grouped[categoryId]) {
|
32610
|
+
grouped[categoryId].apps.push(app);
|
32611
|
+
} else {
|
32612
|
+
grouped[categoryId] = {
|
32613
|
+
category: { id: categoryId, name: app.category, icon: "📁", color: "#757575" },
|
32614
|
+
apps: [app]
|
32615
|
+
};
|
32616
|
+
}
|
32617
|
+
});
|
32618
|
+
Object.keys(grouped).forEach((key) => {
|
32619
|
+
if (grouped[key].apps.length === 0) {
|
32620
|
+
delete grouped[key];
|
32621
|
+
}
|
32622
|
+
});
|
32623
|
+
return grouped;
|
32624
|
+
}
|
32625
|
+
}
|
32626
|
+
const defaultAppManager = new AppManager();
|
32627
|
+
const AppContext = createContext();
|
32628
|
+
const useApplicationMenu = () => {
|
32629
|
+
const context = useContext(AppContext);
|
32630
|
+
if (!context) {
|
32631
|
+
throw new Error("useApplicationMenu must be used within AppProvider");
|
32632
|
+
}
|
32633
|
+
return context.applicationMenu;
|
32634
|
+
};
|
32635
|
+
const useAppManager = () => {
|
32636
|
+
const context = useContext(AppContext);
|
32637
|
+
if (!context) {
|
32638
|
+
throw new Error("useAppManager must be used within AppProvider");
|
32639
|
+
}
|
32640
|
+
return context.appManager;
|
32641
|
+
};
|
32642
|
+
const AppProvider = ({ children, appManager = defaultAppManager }) => {
|
32643
|
+
const [isApplicationMenuOpen, setIsApplicationMenuOpen] = useState(false);
|
32644
|
+
const value = {
|
32645
|
+
// Application Menu state
|
32646
|
+
applicationMenu: {
|
32647
|
+
isOpen: isApplicationMenuOpen,
|
32648
|
+
open: () => setIsApplicationMenuOpen(true),
|
32649
|
+
close: () => setIsApplicationMenuOpen(false),
|
32650
|
+
toggle: () => setIsApplicationMenuOpen(!isApplicationMenuOpen)
|
32651
|
+
},
|
32652
|
+
// App Manager instance
|
32653
|
+
appManager
|
32654
|
+
};
|
32655
|
+
return /* @__PURE__ */ React.createElement(AppContext.Provider, { value }, children);
|
32656
|
+
};
|
32657
|
+
const DesktopLayout = ({ children, className = "", theme = "windows", ...props }) => {
|
32254
32658
|
const desktopRef = useRef(null);
|
32255
32659
|
const { windowManager } = useWindows();
|
32256
32660
|
useEffect(() => {
|
@@ -32281,11 +32685,12 @@ const DesktopLayout = ({ children, className = "", ...props }) => {
|
|
32281
32685
|
e.preventDefault();
|
32282
32686
|
console.log("Desktop context menu at:", e.clientX, e.clientY);
|
32283
32687
|
};
|
32688
|
+
const themeClass = `desktop--${theme}`;
|
32284
32689
|
return /* @__PURE__ */ React.createElement(
|
32285
32690
|
"div",
|
32286
32691
|
{
|
32287
32692
|
ref: desktopRef,
|
32288
|
-
className: `desktop ${className}`,
|
32693
|
+
className: `desktop ${themeClass} ${className}`,
|
32289
32694
|
onContextMenu: handleContextMenu,
|
32290
32695
|
...props
|
32291
32696
|
},
|
@@ -32318,6 +32723,7 @@ const DesktopTaskbar = () => {
|
|
32318
32723
|
minimizeWindow,
|
32319
32724
|
closeWindow
|
32320
32725
|
} = useWindows();
|
32726
|
+
const { open: openApplicationMenu } = useApplicationMenu();
|
32321
32727
|
const handleCreateWindow = () => {
|
32322
32728
|
const windowTypes = [
|
32323
32729
|
{ title: "File Explorer", icon: "📁", size: { width: 600, height: 400 } },
|
@@ -32369,12 +32775,34 @@ const DesktopTaskbar = () => {
|
|
32369
32775
|
padding: "0 16px",
|
32370
32776
|
gap: "8px"
|
32371
32777
|
} }, /* @__PURE__ */ React.createElement(
|
32778
|
+
"button",
|
32779
|
+
{
|
32780
|
+
onClick: openApplicationMenu,
|
32781
|
+
style: {
|
32782
|
+
padding: "8px 16px",
|
32783
|
+
background: "#1976d2",
|
32784
|
+
color: "white",
|
32785
|
+
border: "none",
|
32786
|
+
borderRadius: "4px",
|
32787
|
+
cursor: "pointer",
|
32788
|
+
fontSize: "14px",
|
32789
|
+
fontWeight: "bold",
|
32790
|
+
flexShrink: 0,
|
32791
|
+
display: "flex",
|
32792
|
+
alignItems: "center",
|
32793
|
+
gap: "6px"
|
32794
|
+
},
|
32795
|
+
title: "Open application menu"
|
32796
|
+
},
|
32797
|
+
/* @__PURE__ */ React.createElement("span", { style: { fontSize: "16px" } }, "🚀"),
|
32798
|
+
"Start"
|
32799
|
+
), /* @__PURE__ */ React.createElement(
|
32372
32800
|
"button",
|
32373
32801
|
{
|
32374
32802
|
onClick: handleCreateWindow,
|
32375
32803
|
style: {
|
32376
32804
|
padding: "8px 12px",
|
32377
|
-
background: "#
|
32805
|
+
background: "#666",
|
32378
32806
|
color: "white",
|
32379
32807
|
border: "none",
|
32380
32808
|
borderRadius: "4px",
|
@@ -32382,7 +32810,7 @@ const DesktopTaskbar = () => {
|
|
32382
32810
|
fontSize: "12px",
|
32383
32811
|
flexShrink: 0
|
32384
32812
|
},
|
32385
|
-
title: "Create
|
32813
|
+
title: "Create random window (for testing)"
|
32386
32814
|
},
|
32387
32815
|
"+"
|
32388
32816
|
), /* @__PURE__ */ React.createElement("div", { style: {
|
@@ -32452,8 +32880,18 @@ Middle click: Close`
|
|
32452
32880
|
textAlign: "right"
|
32453
32881
|
} }, desktopSize.width, "×", desktopSize.height));
|
32454
32882
|
};
|
32883
|
+
const DesktopInternal = ({ desktopSize, children, ...props }) => {
|
32884
|
+
const { isOpen, close } = useApplicationMenu();
|
32885
|
+
return /* @__PURE__ */ React.createElement(WindowProvider, { desktopSize }, /* @__PURE__ */ React.createElement(DesktopLayout, { ...props }, /* @__PURE__ */ React.createElement(Workspace, null, children), /* @__PURE__ */ React.createElement(DesktopTaskbar, null), /* @__PURE__ */ React.createElement(
|
32886
|
+
ApplicationMenu,
|
32887
|
+
{
|
32888
|
+
isOpen,
|
32889
|
+
onClose: close
|
32890
|
+
}
|
32891
|
+
)));
|
32892
|
+
};
|
32455
32893
|
const Desktop = ({ desktopSize, children, ...props }) => {
|
32456
|
-
return /* @__PURE__ */ React.createElement(
|
32894
|
+
return /* @__PURE__ */ React.createElement(AppProvider, null, /* @__PURE__ */ React.createElement(DesktopInternal, { desktopSize, ...props }, children));
|
32457
32895
|
};
|
32458
32896
|
const ContentForm = ({ content, columns = 1, filter: filter2, rules, onChange }) => {
|
32459
32897
|
const form = content.form();
|
@@ -42174,6 +42612,9 @@ export {
|
|
42174
42612
|
AccordionExamples,
|
42175
42613
|
ActionButton,
|
42176
42614
|
ActionsCell,
|
42615
|
+
AppManager,
|
42616
|
+
AppProvider,
|
42617
|
+
ApplicationMenu,
|
42177
42618
|
Avatar,
|
42178
42619
|
Button,
|
42179
42620
|
ButtonExamples,
|
@@ -42327,8 +42768,11 @@ export {
|
|
42327
42768
|
Wizard,
|
42328
42769
|
WizardContext,
|
42329
42770
|
Workspace,
|
42771
|
+
defaultAppManager,
|
42330
42772
|
isEmpty,
|
42331
42773
|
isFunction,
|
42774
|
+
useAppManager,
|
42775
|
+
useApplicationMenu,
|
42332
42776
|
useCreateWindow,
|
42333
42777
|
useHashPage,
|
42334
42778
|
useWindow,
|