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