ywana-core8 0.2.3 → 0.2.5

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.js CHANGED
@@ -32252,6 +32252,386 @@ const Window = ({
32252
32252
  statusBar && /* @__PURE__ */ React.createElement("div", { className: "window__status-bar" }, statusBar)
32253
32253
  );
32254
32254
  };
32255
+ const ApplicationMenu = ({ isOpen, onClose }) => {
32256
+ const appManager = useAppManager();
32257
+ const [searchTerm, setSearchTerm] = React.useState("");
32258
+ const [selectedCategory, setSelectedCategory] = React.useState("all");
32259
+ const [apps, setApps] = React.useState([]);
32260
+ const [categories, setCategories] = React.useState([]);
32261
+ const searchInputRef = React.useRef(null);
32262
+ const { createWindow } = useWindows();
32263
+ React.useEffect(() => {
32264
+ const loadData = () => {
32265
+ setApps(appManager.getAllApps());
32266
+ setCategories(appManager.getAllCategories());
32267
+ };
32268
+ loadData();
32269
+ appManager.addListener(loadData);
32270
+ return () => {
32271
+ appManager.removeListener(loadData);
32272
+ };
32273
+ }, [appManager]);
32274
+ React.useEffect(() => {
32275
+ if (isOpen && searchInputRef.current) {
32276
+ setTimeout(() => {
32277
+ searchInputRef.current.focus();
32278
+ }, 100);
32279
+ }
32280
+ }, [isOpen]);
32281
+ React.useEffect(() => {
32282
+ const handleKeyDown = (e) => {
32283
+ if (e.key === "Escape" && isOpen) {
32284
+ onClose();
32285
+ }
32286
+ };
32287
+ if (isOpen) {
32288
+ document.addEventListener("keydown", handleKeyDown);
32289
+ return () => document.removeEventListener("keydown", handleKeyDown);
32290
+ }
32291
+ }, [isOpen, onClose]);
32292
+ const filteredApps = apps.filter((app) => {
32293
+ const matchesSearch = searchTerm === "" || app.name.toLowerCase().includes(searchTerm.toLowerCase()) || app.description.toLowerCase().includes(searchTerm.toLowerCase());
32294
+ const matchesCategory = selectedCategory === "all" || app.category.toLowerCase() === selectedCategory.toLowerCase();
32295
+ return matchesSearch && matchesCategory;
32296
+ });
32297
+ const groupedApps = filteredApps.reduce((groups, app) => {
32298
+ const category = app.category;
32299
+ if (!groups[category]) {
32300
+ groups[category] = [];
32301
+ }
32302
+ groups[category].push(app);
32303
+ return groups;
32304
+ }, {});
32305
+ const handleLaunchApp = (app) => {
32306
+ createWindow({
32307
+ id: `${app.id}-${Date.now()}`,
32308
+ title: app.name,
32309
+ icon: app.icon,
32310
+ size: app.size,
32311
+ toolbar: app.toolbar,
32312
+ statusBar: app.statusBar,
32313
+ 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."))
32314
+ });
32315
+ onClose();
32316
+ };
32317
+ const handleCategorySelect = (categoryId) => {
32318
+ setSelectedCategory(categoryId);
32319
+ setSearchTerm("");
32320
+ };
32321
+ if (!isOpen) return null;
32322
+ 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(
32323
+ "button",
32324
+ {
32325
+ className: "application-menu__close",
32326
+ onClick: onClose,
32327
+ title: "Close menu"
32328
+ },
32329
+ "×"
32330
+ )), /* @__PURE__ */ React.createElement("div", { className: "application-menu__search" }, /* @__PURE__ */ React.createElement(
32331
+ "input",
32332
+ {
32333
+ ref: searchInputRef,
32334
+ type: "text",
32335
+ placeholder: "Search applications...",
32336
+ value: searchTerm,
32337
+ onChange: (e) => setSearchTerm(e.target.value),
32338
+ className: "application-menu__search-input"
32339
+ }
32340
+ )), /* @__PURE__ */ React.createElement("div", { className: "application-menu__categories" }, /* @__PURE__ */ React.createElement(
32341
+ "button",
32342
+ {
32343
+ className: `application-menu__category ${selectedCategory === "all" ? "active" : ""}`,
32344
+ onClick: () => handleCategorySelect("all")
32345
+ },
32346
+ /* @__PURE__ */ React.createElement("span", { className: "category-icon" }, "📱"),
32347
+ "All Apps"
32348
+ ), categories.map((category) => /* @__PURE__ */ React.createElement(
32349
+ "button",
32350
+ {
32351
+ key: category.id,
32352
+ className: `application-menu__category ${selectedCategory === category.id ? "active" : ""}`,
32353
+ onClick: () => handleCategorySelect(category.id)
32354
+ },
32355
+ /* @__PURE__ */ React.createElement("span", { className: "category-icon" }, category.icon),
32356
+ category.name
32357
+ ))), /* @__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(
32358
+ "div",
32359
+ {
32360
+ key: app.id,
32361
+ className: "application-menu__app",
32362
+ onClick: () => handleLaunchApp(app),
32363
+ title: app.description
32364
+ },
32365
+ /* @__PURE__ */ React.createElement("div", { className: "app-icon" }, app.icon),
32366
+ /* @__PURE__ */ React.createElement("div", { className: "app-name" }, app.name)
32367
+ )))), !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(
32368
+ "div",
32369
+ {
32370
+ key: app.id,
32371
+ className: "application-menu__app",
32372
+ onClick: () => handleLaunchApp(app),
32373
+ title: app.description
32374
+ },
32375
+ /* @__PURE__ */ React.createElement("div", { className: "app-icon" }, app.icon),
32376
+ /* @__PURE__ */ React.createElement("div", { className: "app-name" }, app.name)
32377
+ )))))), 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.")))));
32378
+ };
32379
+ class AppManager {
32380
+ constructor() {
32381
+ this.applications = /* @__PURE__ */ new Map();
32382
+ this.categories = /* @__PURE__ */ new Map();
32383
+ this.listeners = /* @__PURE__ */ new Set();
32384
+ this.initializeDefaultApps();
32385
+ }
32386
+ /**
32387
+ * Initialize default applications
32388
+ */
32389
+ initializeDefaultApps() {
32390
+ this.registerApp({
32391
+ id: "file-explorer",
32392
+ name: "File Explorer",
32393
+ description: "Browse and manage files",
32394
+ icon: "📁",
32395
+ category: "System",
32396
+ component: null,
32397
+ // Will be set when registering actual components
32398
+ size: { width: 600, height: 400 },
32399
+ toolbar: null,
32400
+ statusBar: null
32401
+ });
32402
+ this.registerApp({
32403
+ id: "text-editor",
32404
+ name: "Text Editor",
32405
+ description: "Edit text files",
32406
+ icon: "📝",
32407
+ category: "Productivity",
32408
+ component: null,
32409
+ size: { width: 500, height: 350 },
32410
+ toolbar: null,
32411
+ statusBar: null
32412
+ });
32413
+ this.registerApp({
32414
+ id: "calculator",
32415
+ name: "Calculator",
32416
+ description: "Perform calculations",
32417
+ icon: "🧮",
32418
+ category: "Utilities",
32419
+ component: null,
32420
+ size: { width: 300, height: 400 }
32421
+ });
32422
+ this.registerApp({
32423
+ id: "settings",
32424
+ name: "Settings",
32425
+ description: "System configuration",
32426
+ icon: "⚙️",
32427
+ category: "System",
32428
+ component: null,
32429
+ size: { width: 450, height: 300 }
32430
+ });
32431
+ this.registerApp({
32432
+ id: "browser",
32433
+ name: "Web Browser",
32434
+ description: "Browse the internet",
32435
+ icon: "🌐",
32436
+ category: "Internet",
32437
+ component: null,
32438
+ size: { width: 800, height: 500 }
32439
+ });
32440
+ this.registerApp({
32441
+ id: "terminal",
32442
+ name: "Terminal",
32443
+ description: "Command line interface",
32444
+ icon: "💻",
32445
+ category: "Development",
32446
+ component: null,
32447
+ size: { width: 700, height: 400 }
32448
+ });
32449
+ this.registerApp({
32450
+ id: "image-viewer",
32451
+ name: "Image Viewer",
32452
+ description: "View and edit images",
32453
+ icon: "🖼️",
32454
+ category: "Media",
32455
+ component: null,
32456
+ size: { width: 600, height: 500 }
32457
+ });
32458
+ this.registerApp({
32459
+ id: "music-player",
32460
+ name: "Music Player",
32461
+ description: "Play audio files",
32462
+ icon: "🎵",
32463
+ category: "Media",
32464
+ component: null,
32465
+ size: { width: 400, height: 300 }
32466
+ });
32467
+ this.initializeCategories();
32468
+ }
32469
+ /**
32470
+ * Initialize application categories
32471
+ */
32472
+ initializeCategories() {
32473
+ const categoryData = [
32474
+ { id: "system", name: "System", icon: "⚙️", color: "#607d8b" },
32475
+ { id: "productivity", name: "Productivity", icon: "📊", color: "#2196f3" },
32476
+ { id: "utilities", name: "Utilities", icon: "🔧", color: "#ff9800" },
32477
+ { id: "internet", name: "Internet", icon: "🌐", color: "#4caf50" },
32478
+ { id: "development", name: "Development", icon: "💻", color: "#9c27b0" },
32479
+ { id: "media", name: "Media", icon: "🎬", color: "#e91e63" },
32480
+ { id: "games", name: "Games", icon: "🎮", color: "#f44336" }
32481
+ ];
32482
+ categoryData.forEach((category) => {
32483
+ this.categories.set(category.id, category);
32484
+ });
32485
+ }
32486
+ /**
32487
+ * Register a new application
32488
+ */
32489
+ registerApp(appConfig) {
32490
+ const app = {
32491
+ id: appConfig.id,
32492
+ name: appConfig.name,
32493
+ description: appConfig.description || "",
32494
+ icon: appConfig.icon || "📄",
32495
+ category: appConfig.category || "Utilities",
32496
+ component: appConfig.component || null,
32497
+ size: appConfig.size || { width: 600, height: 400 },
32498
+ toolbar: appConfig.toolbar || null,
32499
+ statusBar: appConfig.statusBar || null,
32500
+ ...appConfig
32501
+ };
32502
+ this.applications.set(app.id, app);
32503
+ this.notifyListeners();
32504
+ return app.id;
32505
+ }
32506
+ /**
32507
+ * Unregister an application
32508
+ */
32509
+ unregisterApp(appId) {
32510
+ const removed = this.applications.delete(appId);
32511
+ if (removed) {
32512
+ this.notifyListeners();
32513
+ }
32514
+ return removed;
32515
+ }
32516
+ /**
32517
+ * Get an application by ID
32518
+ */
32519
+ getApp(appId) {
32520
+ return this.applications.get(appId);
32521
+ }
32522
+ /**
32523
+ * Get all applications
32524
+ */
32525
+ getAllApps() {
32526
+ return Array.from(this.applications.values());
32527
+ }
32528
+ /**
32529
+ * Get applications by category
32530
+ */
32531
+ getAppsByCategory(categoryId) {
32532
+ return Array.from(this.applications.values()).filter((app) => app.category.toLowerCase() === categoryId.toLowerCase());
32533
+ }
32534
+ /**
32535
+ * Get all categories
32536
+ */
32537
+ getAllCategories() {
32538
+ return Array.from(this.categories.values());
32539
+ }
32540
+ /**
32541
+ * Get category by ID
32542
+ */
32543
+ getCategory(categoryId) {
32544
+ return this.categories.get(categoryId.toLowerCase());
32545
+ }
32546
+ /**
32547
+ * Search applications
32548
+ */
32549
+ searchApps(query) {
32550
+ const searchTerm = query.toLowerCase();
32551
+ return Array.from(this.applications.values()).filter(
32552
+ (app) => app.name.toLowerCase().includes(searchTerm) || app.description.toLowerCase().includes(searchTerm) || app.category.toLowerCase().includes(searchTerm)
32553
+ );
32554
+ }
32555
+ /**
32556
+ * Add listener for changes
32557
+ */
32558
+ addListener(listener) {
32559
+ this.listeners.add(listener);
32560
+ }
32561
+ /**
32562
+ * Remove listener
32563
+ */
32564
+ removeListener(listener) {
32565
+ this.listeners.delete(listener);
32566
+ }
32567
+ /**
32568
+ * Notify all listeners about changes
32569
+ */
32570
+ notifyListeners() {
32571
+ this.listeners.forEach((listener) => listener(this.getAllApps()));
32572
+ }
32573
+ /**
32574
+ * Get applications grouped by category
32575
+ */
32576
+ getAppsGroupedByCategory() {
32577
+ const grouped = {};
32578
+ const categories = this.getAllCategories();
32579
+ categories.forEach((category) => {
32580
+ grouped[category.id] = {
32581
+ category,
32582
+ apps: []
32583
+ };
32584
+ });
32585
+ this.getAllApps().forEach((app) => {
32586
+ const categoryId = app.category.toLowerCase();
32587
+ if (grouped[categoryId]) {
32588
+ grouped[categoryId].apps.push(app);
32589
+ } else {
32590
+ grouped[categoryId] = {
32591
+ category: { id: categoryId, name: app.category, icon: "📁", color: "#757575" },
32592
+ apps: [app]
32593
+ };
32594
+ }
32595
+ });
32596
+ Object.keys(grouped).forEach((key) => {
32597
+ if (grouped[key].apps.length === 0) {
32598
+ delete grouped[key];
32599
+ }
32600
+ });
32601
+ return grouped;
32602
+ }
32603
+ }
32604
+ const defaultAppManager = new AppManager();
32605
+ const AppContext = React.createContext();
32606
+ const useApplicationMenu = () => {
32607
+ const context = React.useContext(AppContext);
32608
+ if (!context) {
32609
+ throw new Error("useApplicationMenu must be used within AppProvider");
32610
+ }
32611
+ return context.applicationMenu;
32612
+ };
32613
+ const useAppManager = () => {
32614
+ const context = React.useContext(AppContext);
32615
+ if (!context) {
32616
+ throw new Error("useAppManager must be used within AppProvider");
32617
+ }
32618
+ return context.appManager;
32619
+ };
32620
+ const AppProvider = ({ children, appManager = defaultAppManager }) => {
32621
+ const [isApplicationMenuOpen, setIsApplicationMenuOpen] = React.useState(false);
32622
+ const value = {
32623
+ // Application Menu state
32624
+ applicationMenu: {
32625
+ isOpen: isApplicationMenuOpen,
32626
+ open: () => setIsApplicationMenuOpen(true),
32627
+ close: () => setIsApplicationMenuOpen(false),
32628
+ toggle: () => setIsApplicationMenuOpen(!isApplicationMenuOpen)
32629
+ },
32630
+ // App Manager instance
32631
+ appManager
32632
+ };
32633
+ return /* @__PURE__ */ React.createElement(AppContext.Provider, { value }, children);
32634
+ };
32255
32635
  const DesktopLayout = ({ children, className = "", ...props }) => {
32256
32636
  const desktopRef = React.useRef(null);
32257
32637
  const { windowManager } = useWindows();
@@ -32307,7 +32687,7 @@ const Workspace = ({ children }) => {
32307
32687
  toolbar: window2.toolbar,
32308
32688
  statusBar: window2.statusBar
32309
32689
  },
32310
- /* @__PURE__ */ React.createElement("div", { style: { padding: "16px" } }, /* @__PURE__ */ React.createElement("h3", null, "Window: ", window2.title), /* @__PURE__ */ React.createElement("p", null, /* @__PURE__ */ React.createElement("strong", null, "ID:"), " ", window2.id), /* @__PURE__ */ React.createElement("p", null, /* @__PURE__ */ React.createElement("strong", null, "Position:"), " ", window2.position.x, ", ", window2.position.y), /* @__PURE__ */ React.createElement("p", null, /* @__PURE__ */ React.createElement("strong", null, "Size:"), " ", window2.size.width, " × ", window2.size.height), /* @__PURE__ */ React.createElement("p", null, /* @__PURE__ */ React.createElement("strong", null, "Z-Index:"), " ", window2.zIndex), /* @__PURE__ */ React.createElement("p", null, /* @__PURE__ */ React.createElement("strong", null, "Status:"), " ", window2.minimized ? "Minimized" : window2.maximized ? "Maximized" : "Normal"), /* @__PURE__ */ React.createElement("div", { style: { marginTop: "16px", padding: "12px", background: "#f8f9fa", borderRadius: "4px" } }, /* @__PURE__ */ React.createElement("p", null, /* @__PURE__ */ React.createElement("strong", null, "Window Content Area")), /* @__PURE__ */ React.createElement("p", null, "This is where your application content would go."), /* @__PURE__ */ React.createElement("p", null, "The window is fully draggable and has working minimize, maximize, and close buttons.")))
32690
+ /* @__PURE__ */ React.createElement("div", { style: { padding: "16px" } }, window2.content)
32311
32691
  )));
32312
32692
  };
32313
32693
  const DesktopTaskbar = () => {
@@ -32320,6 +32700,7 @@ const DesktopTaskbar = () => {
32320
32700
  minimizeWindow,
32321
32701
  closeWindow
32322
32702
  } = useWindows();
32703
+ const { open: openApplicationMenu } = useApplicationMenu();
32323
32704
  const handleCreateWindow = () => {
32324
32705
  const windowTypes = [
32325
32706
  { title: "File Explorer", icon: "📁", size: { width: 600, height: 400 } },
@@ -32371,12 +32752,34 @@ const DesktopTaskbar = () => {
32371
32752
  padding: "0 16px",
32372
32753
  gap: "8px"
32373
32754
  } }, /* @__PURE__ */ React.createElement(
32755
+ "button",
32756
+ {
32757
+ onClick: openApplicationMenu,
32758
+ style: {
32759
+ padding: "8px 16px",
32760
+ background: "#1976d2",
32761
+ color: "white",
32762
+ border: "none",
32763
+ borderRadius: "4px",
32764
+ cursor: "pointer",
32765
+ fontSize: "14px",
32766
+ fontWeight: "bold",
32767
+ flexShrink: 0,
32768
+ display: "flex",
32769
+ alignItems: "center",
32770
+ gap: "6px"
32771
+ },
32772
+ title: "Open application menu"
32773
+ },
32774
+ /* @__PURE__ */ React.createElement("span", { style: { fontSize: "16px" } }, "🚀"),
32775
+ "Start"
32776
+ ), /* @__PURE__ */ React.createElement(
32374
32777
  "button",
32375
32778
  {
32376
32779
  onClick: handleCreateWindow,
32377
32780
  style: {
32378
32781
  padding: "8px 12px",
32379
- background: "#1976d2",
32782
+ background: "#666",
32380
32783
  color: "white",
32381
32784
  border: "none",
32382
32785
  borderRadius: "4px",
@@ -32384,7 +32787,7 @@ const DesktopTaskbar = () => {
32384
32787
  fontSize: "12px",
32385
32788
  flexShrink: 0
32386
32789
  },
32387
- title: "Create new window"
32790
+ title: "Create random window (for testing)"
32388
32791
  },
32389
32792
  "+"
32390
32793
  ), /* @__PURE__ */ React.createElement("div", { style: {
@@ -32454,8 +32857,18 @@ Middle click: Close`
32454
32857
  textAlign: "right"
32455
32858
  } }, desktopSize.width, "×", desktopSize.height));
32456
32859
  };
32860
+ const DesktopInternal = ({ desktopSize, children, ...props }) => {
32861
+ const { isOpen, close } = useApplicationMenu();
32862
+ 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(
32863
+ ApplicationMenu,
32864
+ {
32865
+ isOpen,
32866
+ onClose: close
32867
+ }
32868
+ )));
32869
+ };
32457
32870
  const Desktop = ({ desktopSize, children, ...props }) => {
32458
- return /* @__PURE__ */ React.createElement(WindowProvider, { desktopSize }, /* @__PURE__ */ React.createElement(DesktopLayout, { ...props }, /* @__PURE__ */ React.createElement(Workspace, null, children), /* @__PURE__ */ React.createElement(DesktopTaskbar, null)));
32871
+ return /* @__PURE__ */ React.createElement(AppProvider, null, /* @__PURE__ */ React.createElement(DesktopInternal, { desktopSize, ...props }, children));
32459
32872
  };
32460
32873
  const ContentForm = ({ content, columns = 1, filter: filter2, rules, onChange }) => {
32461
32874
  const form = content.form();
@@ -42175,6 +42588,9 @@ exports.Accordion = Accordion;
42175
42588
  exports.AccordionExamples = AccordionExamples;
42176
42589
  exports.ActionButton = ActionButton;
42177
42590
  exports.ActionsCell = ActionsCell;
42591
+ exports.AppManager = AppManager;
42592
+ exports.AppProvider = AppProvider;
42593
+ exports.ApplicationMenu = ApplicationMenu;
42178
42594
  exports.Avatar = Avatar;
42179
42595
  exports.Button = Button;
42180
42596
  exports.ButtonExamples = ButtonExamples;
@@ -42328,8 +42744,11 @@ exports.WindowProvider = WindowProvider;
42328
42744
  exports.Wizard = Wizard;
42329
42745
  exports.WizardContext = WizardContext;
42330
42746
  exports.Workspace = Workspace;
42747
+ exports.defaultAppManager = defaultAppManager;
42331
42748
  exports.isEmpty = isEmpty;
42332
42749
  exports.isFunction = isFunction;
42750
+ exports.useAppManager = useAppManager;
42751
+ exports.useApplicationMenu = useApplicationMenu;
42333
42752
  exports.useCreateWindow = useCreateWindow;
42334
42753
  exports.useHashPage = useHashPage;
42335
42754
  exports.useWindow = useWindow;