ywana-core8 0.2.19 → 0.2.21

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.
@@ -1666,26 +1666,43 @@ const Menu = (props) => {
1666
1666
  return /* @__PURE__ */ React.createElement(MenuContext.Provider, { value: [open, setOpen] }, /* @__PURE__ */ React.createElement("ul", null, children));
1667
1667
  };
1668
1668
  const MenuIcon = (props) => {
1669
- const { icon = "more_vert", children, align = "left", size = "normal" } = props;
1669
+ const {
1670
+ icon = "more_vert",
1671
+ children,
1672
+ align,
1673
+ // Deprecated, kept for backwards compatibility
1674
+ position = align === "right" ? "bottom-right" : "bottom-left",
1675
+ size = "normal",
1676
+ menuSize = "normal"
1677
+ } = props;
1670
1678
  const [open, setOpen] = useState(false);
1671
1679
  function toggle() {
1672
1680
  setOpen(!open);
1673
1681
  }
1674
- const getAlignClass = (alignment) => {
1675
- switch (alignment) {
1676
- case "right":
1677
- return "alignRight";
1678
- case "left":
1679
- return "alignLeft";
1680
- default:
1681
- return "alignLeft";
1682
- }
1682
+ const getPositionClass = (pos) => {
1683
+ const validPositions = [
1684
+ "bottom-left",
1685
+ "bottom-right",
1686
+ "top-left",
1687
+ "top-right",
1688
+ "left",
1689
+ "right",
1690
+ "top",
1691
+ "bottom"
1692
+ ];
1693
+ return validPositions.includes(pos) ? `position-${pos}` : "position-bottom-left";
1683
1694
  };
1684
- return /* @__PURE__ */ React.createElement(MenuContext.Provider, { value: [open, setOpen] }, /* @__PURE__ */ React.createElement("div", { className: "menu-icon" }, /* @__PURE__ */ React.createElement(Icon, { icon, size, clickable: true, action: toggle }), open ? /* @__PURE__ */ React.createElement("menu", { className: getAlignClass(align) }, children) : null, open ? /* @__PURE__ */ React.createElement("div", { className: "overlay", onClick: toggle }) : null));
1695
+ const menuClasses = [
1696
+ getPositionClass(position),
1697
+ menuSize === "compact" ? "menu-compact" : ""
1698
+ ].filter(Boolean).join(" ");
1699
+ return /* @__PURE__ */ React.createElement(MenuContext.Provider, { value: [open, setOpen, menuSize] }, /* @__PURE__ */ React.createElement("div", { className: "menu-icon" }, /* @__PURE__ */ React.createElement(Icon, { icon, size, clickable: true, action: toggle }), open ? /* @__PURE__ */ React.createElement("menu", { className: menuClasses }, children) : null, open ? /* @__PURE__ */ React.createElement("div", { className: "overlay", onClick: toggle }) : null));
1685
1700
  };
1686
1701
  const MenuItem = (props) => {
1687
- const { id, icon, label, meta, disabled = false, size = "normal", onSelect: onSelect2 } = props;
1688
- const [open, setOpen] = useContext(MenuContext);
1702
+ const { id, icon, label, meta, disabled = false, size, onSelect: onSelect2 } = props;
1703
+ const context = useContext(MenuContext);
1704
+ const [open, setOpen, menuSize] = Array.isArray(context) ? context : [context, null, "normal"];
1705
+ const iconSize = size || (menuSize === "compact" ? "small" : "normal");
1689
1706
  function select() {
1690
1707
  if (!disabled) {
1691
1708
  if (onSelect2) onSelect2();
@@ -1694,7 +1711,7 @@ const MenuItem = (props) => {
1694
1711
  }
1695
1712
  const style = disabled ? "disabled" : "";
1696
1713
  const labelTxt = label ? /* @__PURE__ */ React.createElement(Text, { format: TEXTFORMATS.STRING }, label) : null;
1697
- return /* @__PURE__ */ React.createElement("li", { className: `menu-item ${style}`, onClick: select }, icon ? /* @__PURE__ */ React.createElement(Icon, { icon, size }) : null, /* @__PURE__ */ React.createElement("label", null, labelTxt), meta ? /* @__PURE__ */ React.createElement("div", { className: "meta" }, meta) : null);
1714
+ return /* @__PURE__ */ React.createElement("li", { className: `menu-item ${style}`, onClick: select }, icon ? /* @__PURE__ */ React.createElement(Icon, { icon, size: iconSize }) : null, /* @__PURE__ */ React.createElement("label", null, labelTxt), meta ? /* @__PURE__ */ React.createElement("div", { className: "meta" }, meta) : null);
1698
1715
  };
1699
1716
  const MenuSeparator = (props) => {
1700
1717
  return /* @__PURE__ */ React.createElement("li", { className: "menu-separator" });
@@ -32077,6 +32094,52 @@ class WindowManager {
32077
32094
  });
32078
32095
  this.notifyListeners();
32079
32096
  }
32097
+ /**
32098
+ * Arrange windows in columns
32099
+ */
32100
+ arrangeWindowsInColumns() {
32101
+ const visibleWindows = this.getVisibleWindows().filter((w) => !w.maximized);
32102
+ if (visibleWindows.length === 0) return;
32103
+ const cols = visibleWindows.length;
32104
+ const windowWidth = Math.floor(this.desktopSize.width / cols);
32105
+ const windowHeight = this.desktopSize.height;
32106
+ const padding = 5;
32107
+ visibleWindows.forEach((window2, index) => {
32108
+ window2.position = {
32109
+ x: index * windowWidth + padding,
32110
+ y: padding
32111
+ };
32112
+ window2.size = {
32113
+ width: windowWidth - padding * 2,
32114
+ height: windowHeight - padding * 2
32115
+ };
32116
+ window2.maximized = false;
32117
+ });
32118
+ this.notifyListeners();
32119
+ }
32120
+ /**
32121
+ * Arrange windows in rows
32122
+ */
32123
+ arrangeWindowsInRows() {
32124
+ const visibleWindows = this.getVisibleWindows().filter((w) => !w.maximized);
32125
+ if (visibleWindows.length === 0) return;
32126
+ const rows = visibleWindows.length;
32127
+ const windowWidth = this.desktopSize.width;
32128
+ const windowHeight = Math.floor(this.desktopSize.height / rows);
32129
+ const padding = 5;
32130
+ visibleWindows.forEach((window2, index) => {
32131
+ window2.position = {
32132
+ x: padding,
32133
+ y: index * windowHeight + padding
32134
+ };
32135
+ window2.size = {
32136
+ width: windowWidth - padding * 2,
32137
+ height: windowHeight - padding * 2
32138
+ };
32139
+ window2.maximized = false;
32140
+ });
32141
+ this.notifyListeners();
32142
+ }
32080
32143
  /**
32081
32144
  * Get statistics
32082
32145
  */
@@ -32153,6 +32216,8 @@ const WindowProvider = ({ children, desktopSize }) => {
32153
32216
  // Layout functions
32154
32217
  cascadeWindows: () => windowManagerRef.current.cascadeWindows(),
32155
32218
  tileWindows: () => windowManagerRef.current.tileWindows(),
32219
+ arrangeWindowsInColumns: () => windowManagerRef.current.arrangeWindowsInColumns(),
32220
+ arrangeWindowsInRows: () => windowManagerRef.current.arrangeWindowsInRows(),
32156
32221
  centerWindow: (id) => windowManagerRef.current.centerWindow(id),
32157
32222
  centerAllWindows: () => windowManagerRef.current.centerAllWindows(),
32158
32223
  // Utility functions
@@ -32753,8 +32818,7 @@ const FloatingElementsRenderer = () => {
32753
32818
  ))
32754
32819
  )));
32755
32820
  };
32756
- const ApplicationMenu = ({ isOpen, onClose }) => {
32757
- console.log("ApplicationMenu render - isOpen:", isOpen, "onClose:", onClose);
32821
+ const LaunchPad = ({ isOpen, onClose }) => {
32758
32822
  const appManager = useAppManager();
32759
32823
  const [searchTerm, setSearchTerm] = useState("");
32760
32824
  const [selectedCategory, setSelectedCategory] = useState("all");
@@ -32823,10 +32887,10 @@ const ApplicationMenu = ({ isOpen, onClose }) => {
32823
32887
  setSearchTerm("");
32824
32888
  };
32825
32889
  if (!isOpen) return null;
32826
- return /* @__PURE__ */ React.createElement("div", { className: "application-menu-overlay", onClick: onClose }, /* @__PURE__ */ React.createElement("div", { className: `application-menu ${isCondensed ? "application-menu--condensed" : ""}`, onClick: (e) => e.stopPropagation() }, /* @__PURE__ */ React.createElement("div", { className: "application-menu__header" }, /* @__PURE__ */ React.createElement("div", { className: "application-menu__header-controls" }, /* @__PURE__ */ React.createElement(
32890
+ return /* @__PURE__ */ React.createElement("div", { className: `launchpad ${isCondensed ? "launchpad--condensed" : ""}` }, /* @__PURE__ */ React.createElement("div", { className: "launchpad__header" }, /* @__PURE__ */ React.createElement("div", { className: "launchpad__header-controls" }, /* @__PURE__ */ React.createElement(
32827
32891
  "button",
32828
32892
  {
32829
- className: `application-menu__view-toggle ${isCondensed ? "active" : ""}`,
32893
+ className: `launchpad__view-toggle ${isCondensed ? "active" : ""}`,
32830
32894
  onClick: () => setIsCondensed(!isCondensed),
32831
32895
  title: isCondensed ? "Normal view" : "Condensed view"
32832
32896
  },
@@ -32834,7 +32898,7 @@ const ApplicationMenu = ({ isOpen, onClose }) => {
32834
32898
  ), /* @__PURE__ */ React.createElement(
32835
32899
  "button",
32836
32900
  {
32837
- className: `application-menu__view-toggle ${viewMode === "grid" ? "active" : ""}`,
32901
+ className: `launchpad__view-toggle ${viewMode === "grid" ? "active" : ""}`,
32838
32902
  onClick: () => setViewMode("grid"),
32839
32903
  title: "Grid view"
32840
32904
  },
@@ -32842,7 +32906,7 @@ const ApplicationMenu = ({ isOpen, onClose }) => {
32842
32906
  ), /* @__PURE__ */ React.createElement(
32843
32907
  "button",
32844
32908
  {
32845
- className: `application-menu__view-toggle ${viewMode === "list" ? "active" : ""}`,
32909
+ className: `launchpad__view-toggle ${viewMode === "list" ? "active" : ""}`,
32846
32910
  onClick: () => setViewMode("list"),
32847
32911
  title: "List view"
32848
32912
  },
@@ -32850,12 +32914,12 @@ const ApplicationMenu = ({ isOpen, onClose }) => {
32850
32914
  ), /* @__PURE__ */ React.createElement(
32851
32915
  "button",
32852
32916
  {
32853
- className: "application-menu__close",
32917
+ className: "launchpad__close",
32854
32918
  onClick: onClose,
32855
32919
  title: "Close menu"
32856
32920
  },
32857
32921
  "×"
32858
- ))), /* @__PURE__ */ React.createElement("div", { className: "application-menu__search" }, /* @__PURE__ */ React.createElement(
32922
+ ))), /* @__PURE__ */ React.createElement("div", { className: "launchpad__search" }, /* @__PURE__ */ React.createElement(
32859
32923
  "input",
32860
32924
  {
32861
32925
  ref: searchInputRef,
@@ -32863,12 +32927,12 @@ const ApplicationMenu = ({ isOpen, onClose }) => {
32863
32927
  placeholder: "Search applications...",
32864
32928
  value: searchTerm,
32865
32929
  onChange: (e) => setSearchTerm(e.target.value),
32866
- className: "application-menu__search-input"
32930
+ className: "launchpad__search-input"
32867
32931
  }
32868
- )), /* @__PURE__ */ React.createElement("div", { className: "application-menu__main" }, /* @__PURE__ */ React.createElement("div", { className: "application-menu__sidebar" }, /* @__PURE__ */ React.createElement("div", { className: "application-menu__categories" }, /* @__PURE__ */ React.createElement(
32932
+ )), /* @__PURE__ */ React.createElement("div", { className: "launchpad__main" }, /* @__PURE__ */ React.createElement("div", { className: "launchpad__sidebar" }, /* @__PURE__ */ React.createElement("div", { className: "launchpad__categories" }, /* @__PURE__ */ React.createElement(
32869
32933
  "button",
32870
32934
  {
32871
- className: `application-menu__category ${selectedCategory === "all" ? "active" : ""}`,
32935
+ className: `launchpad__category ${selectedCategory === "all" ? "active" : ""}`,
32872
32936
  onClick: () => handleCategorySelect("all"),
32873
32937
  title: "All Apps"
32874
32938
  },
@@ -32878,33 +32942,33 @@ const ApplicationMenu = ({ isOpen, onClose }) => {
32878
32942
  "button",
32879
32943
  {
32880
32944
  key: category.id,
32881
- className: `application-menu__category ${selectedCategory === category.id ? "active" : ""}`,
32945
+ className: `launchpad__category ${selectedCategory === category.id ? "active" : ""}`,
32882
32946
  onClick: () => handleCategorySelect(category.id),
32883
32947
  title: category.name
32884
32948
  },
32885
32949
  /* @__PURE__ */ React.createElement("span", { className: "category-icon" }, category.icon),
32886
32950
  /* @__PURE__ */ React.createElement("span", { className: "category-name" }, category.name)
32887
- )))), /* @__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-${viewMode}` }, filteredApps.map((app) => /* @__PURE__ */ React.createElement(
32951
+ )))), /* @__PURE__ */ React.createElement("div", { className: "launchpad__content" }, searchTerm && /* @__PURE__ */ React.createElement("div", { className: "launchpad__search-results" }, /* @__PURE__ */ React.createElement("h3", null, "Search Results (", filteredApps.length, ")"), /* @__PURE__ */ React.createElement("div", { className: `launchpad__apps-${viewMode}` }, filteredApps.map((app) => /* @__PURE__ */ React.createElement(
32888
32952
  "div",
32889
32953
  {
32890
32954
  key: app.id,
32891
- className: `application-menu__app--${viewMode}`,
32955
+ className: `launchpad__app--${viewMode}`,
32892
32956
  onClick: () => handleLaunchApp(app),
32893
32957
  title: app.description
32894
32958
  },
32895
32959
  /* @__PURE__ */ React.createElement("div", { className: "app-icon" }, app.icon),
32896
32960
  viewMode === "list" ? /* @__PURE__ */ React.createElement("div", { className: "app-info" }, /* @__PURE__ */ React.createElement("div", { className: "app-name" }, app.name), /* @__PURE__ */ React.createElement("div", { className: "app-description" }, app.description)) : /* @__PURE__ */ React.createElement("div", { className: "app-name" }, app.name)
32897
- )))), !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-${viewMode}` }, categoryApps.map((app) => /* @__PURE__ */ React.createElement(
32961
+ )))), !searchTerm && /* @__PURE__ */ React.createElement("div", { className: "launchpad__categories-content" }, Object.entries(groupedApps).map(([categoryName, categoryApps]) => /* @__PURE__ */ React.createElement("div", { key: categoryName, className: "launchpad__category-section" }, /* @__PURE__ */ React.createElement("h3", { className: "category-title" }, categoryName), /* @__PURE__ */ React.createElement("div", { className: `launchpad__apps-${viewMode}` }, categoryApps.map((app) => /* @__PURE__ */ React.createElement(
32898
32962
  "div",
32899
32963
  {
32900
32964
  key: app.id,
32901
- className: `application-menu__app--${viewMode}`,
32965
+ className: `launchpad__app--${viewMode}`,
32902
32966
  onClick: () => handleLaunchApp(app),
32903
32967
  title: app.description
32904
32968
  },
32905
32969
  /* @__PURE__ */ React.createElement("div", { className: "app-icon" }, app.icon),
32906
32970
  viewMode === "list" ? /* @__PURE__ */ React.createElement("div", { className: "app-info" }, /* @__PURE__ */ React.createElement("div", { className: "app-name" }, app.name), /* @__PURE__ */ React.createElement("div", { className: "app-description" }, app.description)) : /* @__PURE__ */ React.createElement("div", { className: "app-name" }, app.name)
32907
- )))))), 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."))))));
32971
+ )))))), filteredApps.length === 0 && /* @__PURE__ */ React.createElement("div", { className: "launchpad__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.")))));
32908
32972
  };
32909
32973
  class AppManager {
32910
32974
  constructor() {
@@ -33185,48 +33249,221 @@ const defaultDesktopConfig = {
33185
33249
  ]
33186
33250
  };
33187
33251
  const defaultAppManager = new AppManager();
33188
- const AppContext = createContext();
33189
- const useApplicationMenu = () => {
33190
- const context = useContext(AppContext);
33252
+ const DesktopContext = createContext();
33253
+ const useLaunchPad = () => {
33254
+ const context = useContext(DesktopContext);
33191
33255
  if (!context) {
33192
- throw new Error("useApplicationMenu must be used within AppProvider");
33256
+ throw new Error("useLaunchPad must be used within DesktopProvider");
33193
33257
  }
33194
- return context.applicationMenu;
33258
+ return context.launchPad;
33195
33259
  };
33196
33260
  const useAppManager = () => {
33197
- const context = useContext(AppContext);
33261
+ const context = useContext(DesktopContext);
33198
33262
  if (!context) {
33199
- throw new Error("useAppManager must be used within AppProvider");
33263
+ throw new Error("useAppManager must be used within DesktopProvider");
33200
33264
  }
33201
33265
  return context.appManager;
33202
33266
  };
33203
- const AppProvider = ({
33267
+ const useDesktopOverlays = () => {
33268
+ const context = useContext(DesktopContext);
33269
+ if (!context) {
33270
+ throw new Error("useDesktopOverlays must be used within DesktopProvider");
33271
+ }
33272
+ return context.overlays;
33273
+ };
33274
+ const useDesktopTheme = () => {
33275
+ const context = useContext(DesktopContext);
33276
+ if (!context) {
33277
+ throw new Error("useDesktopTheme must be used within DesktopProvider");
33278
+ }
33279
+ return context.theme;
33280
+ };
33281
+ const DesktopProvider = ({
33204
33282
  children,
33205
- desktopConfig = defaultDesktopConfig
33283
+ desktopConfig = defaultDesktopConfig,
33284
+ initialTheme = "windows"
33206
33285
  }) => {
33207
33286
  const appManager = new AppManager();
33208
- const [isApplicationMenuOpen, setIsApplicationMenuOpen] = useState(false);
33287
+ const [isLaunchPadOpen, setIsLaunchPadOpen] = useState(false);
33288
+ const [currentTheme, setCurrentTheme] = useState(initialTheme);
33289
+ const [overlays, setOverlays] = useState([]);
33290
+ const overlayIdCounter = useRef(0);
33209
33291
  useEffect(() => {
33210
33292
  if (appManager.getAllApps().length === 0 && desktopConfig) {
33211
33293
  AppLoader.load(appManager, desktopConfig);
33212
33294
  }
33213
33295
  }, [appManager, desktopConfig]);
33296
+ const showOverlay = (config) => {
33297
+ const id = `overlay-${overlayIdCounter.current++}`;
33298
+ const overlay = {
33299
+ id,
33300
+ content: config.content,
33301
+ onClose: config.onClose || (() => hideOverlay(id)),
33302
+ backdrop: config.backdrop !== false,
33303
+ backdropBlur: config.backdropBlur !== false,
33304
+ closeOnBackdrop: config.closeOnBackdrop !== false,
33305
+ closeOnEscape: config.closeOnEscape !== false,
33306
+ zIndex: config.zIndex || 9500,
33307
+ animation: config.animation || "fade",
33308
+ animationDuration: config.animationDuration || 300,
33309
+ position: config.position || "center",
33310
+ customPosition: config.customPosition,
33311
+ size: config.size || "auto",
33312
+ customSize: config.customSize,
33313
+ padding: config.padding,
33314
+ margin: config.margin,
33315
+ isClosing: false
33316
+ };
33317
+ setOverlays((prev) => [...prev, overlay]);
33318
+ return id;
33319
+ };
33320
+ const hideOverlay = (id, animation) => {
33321
+ setOverlays((prev) => prev.map(
33322
+ (o) => o.id === id ? { ...o, isClosing: true, exitAnimation: animation } : o
33323
+ ));
33324
+ const overlay = overlays.find((o) => o.id === id);
33325
+ const duration = overlay?.animationDuration || 300;
33326
+ setTimeout(() => {
33327
+ setOverlays((prev) => prev.filter((o) => o.id !== id));
33328
+ }, duration);
33329
+ };
33330
+ const hideAllOverlays = () => {
33331
+ setOverlays([]);
33332
+ };
33333
+ const updateOverlay = (id, updates) => {
33334
+ setOverlays((prev) => prev.map(
33335
+ (o) => o.id === id ? { ...o, ...updates } : o
33336
+ ));
33337
+ };
33214
33338
  const value = {
33215
- // Application Menu state
33216
- applicationMenu: {
33217
- isOpen: isApplicationMenuOpen,
33218
- open: () => setIsApplicationMenuOpen(true),
33219
- close: () => setIsApplicationMenuOpen(false),
33220
- toggle: () => setIsApplicationMenuOpen(!isApplicationMenuOpen)
33339
+ // LaunchPad state
33340
+ launchPad: {
33341
+ isOpen: isLaunchPadOpen,
33342
+ open: () => setIsLaunchPadOpen(true),
33343
+ close: () => setIsLaunchPadOpen(false),
33344
+ toggle: () => setIsLaunchPadOpen(!isLaunchPadOpen)
33221
33345
  },
33222
33346
  // App Manager instance
33223
- appManager
33347
+ appManager,
33348
+ // Desktop Overlays API
33349
+ overlays: {
33350
+ items: overlays,
33351
+ show: showOverlay,
33352
+ hide: hideOverlay,
33353
+ hideAll: hideAllOverlays,
33354
+ update: updateOverlay
33355
+ },
33356
+ // Desktop Theme API
33357
+ theme: {
33358
+ current: currentTheme,
33359
+ set: setCurrentTheme,
33360
+ available: ["windows", "macos", "gnome", "windowsxp", "windows98", "nextstep", "macintosh", "msx"]
33361
+ }
33362
+ };
33363
+ return /* @__PURE__ */ React.createElement(DesktopContext.Provider, { value }, children);
33364
+ };
33365
+ const DesktopOverlay = ({
33366
+ id,
33367
+ content,
33368
+ zIndex,
33369
+ onClose,
33370
+ backdrop,
33371
+ backdropBlur,
33372
+ closeOnBackdrop,
33373
+ closeOnEscape,
33374
+ animation,
33375
+ animationDuration,
33376
+ position,
33377
+ customPosition,
33378
+ size,
33379
+ customSize,
33380
+ padding,
33381
+ margin,
33382
+ isClosing,
33383
+ exitAnimation
33384
+ }) => {
33385
+ const { hide } = useDesktopOverlays();
33386
+ const handleBackdropClick = () => {
33387
+ if (closeOnBackdrop && onClose) {
33388
+ onClose();
33389
+ }
33224
33390
  };
33225
- return /* @__PURE__ */ React.createElement(AppContext.Provider, { value }, children);
33391
+ useEffect(() => {
33392
+ if (!closeOnEscape) return;
33393
+ const handleKeyDown = (e) => {
33394
+ if (e.key === "Escape") {
33395
+ onClose();
33396
+ }
33397
+ };
33398
+ document.addEventListener("keydown", handleKeyDown);
33399
+ return () => document.removeEventListener("keydown", handleKeyDown);
33400
+ }, [closeOnEscape, onClose]);
33401
+ const overlayClasses = [
33402
+ "desktop-overlay",
33403
+ backdrop ? "desktop-overlay--backdrop" : "",
33404
+ backdropBlur ? "desktop-overlay--blur" : "",
33405
+ `desktop-overlay--position-${position}`,
33406
+ `desktop-overlay--size-${size}`,
33407
+ isClosing ? `desktop-overlay--exit-${exitAnimation || animation}` : `desktop-overlay--enter-${animation}`
33408
+ ].filter(Boolean).join(" ");
33409
+ const overlayStyle = {
33410
+ zIndex,
33411
+ animationDuration: `${animationDuration}ms`,
33412
+ ...customPosition
33413
+ };
33414
+ const contentStyle = {
33415
+ padding,
33416
+ margin,
33417
+ ...customSize
33418
+ };
33419
+ return /* @__PURE__ */ React.createElement(
33420
+ "div",
33421
+ {
33422
+ className: overlayClasses,
33423
+ style: overlayStyle,
33424
+ onClick: handleBackdropClick
33425
+ },
33426
+ /* @__PURE__ */ React.createElement(
33427
+ "div",
33428
+ {
33429
+ className: "desktop-overlay__content",
33430
+ style: contentStyle,
33431
+ onClick: (e) => e.stopPropagation()
33432
+ },
33433
+ content
33434
+ )
33435
+ );
33436
+ };
33437
+ const DesktopOverlayLayer = () => {
33438
+ const { items } = useDesktopOverlays();
33439
+ const { isOpen, close } = useLaunchPad();
33440
+ return /* @__PURE__ */ React.createElement("div", { className: "desktop-overlay-layer" }, isOpen && /* @__PURE__ */ React.createElement(
33441
+ "div",
33442
+ {
33443
+ className: "desktop-overlay desktop-overlay--backdrop desktop-overlay--blur desktop-overlay--launchpad desktop-overlay--enter-fade",
33444
+ style: { zIndex: 9e3 },
33445
+ onClick: close
33446
+ },
33447
+ /* @__PURE__ */ React.createElement(
33448
+ "div",
33449
+ {
33450
+ className: "desktop-overlay__content desktop-overlay__content--launchpad",
33451
+ onClick: (e) => e.stopPropagation()
33452
+ },
33453
+ /* @__PURE__ */ React.createElement(LaunchPad, { isOpen, onClose: close })
33454
+ )
33455
+ ), items.map((overlay) => /* @__PURE__ */ React.createElement(
33456
+ DesktopOverlay,
33457
+ {
33458
+ key: overlay.id,
33459
+ ...overlay
33460
+ }
33461
+ )));
33226
33462
  };
33227
- const DesktopLayout = ({ children, className = "", theme = "windows", workspaceRef, ...props }) => {
33463
+ const DesktopLayout = ({ children, className = "", workspaceRef, ...props }) => {
33228
33464
  const desktopRef = useRef(null);
33229
33465
  const { windowManager } = useWindows();
33466
+ const { current: theme } = useDesktopTheme();
33230
33467
  useEffect(() => {
33231
33468
  let currentSize = { width: 1200, height: 750 };
33232
33469
  const measureWorkspace = () => {
@@ -33283,6 +33520,67 @@ const Workspace = ({ children }) => {
33283
33520
  window2.content
33284
33521
  )));
33285
33522
  };
33523
+ const ThemeMenu = () => {
33524
+ const { current: currentTheme, set: setTheme, available: availableThemes } = useDesktopTheme();
33525
+ const themeIcons = {
33526
+ "windows": "computer",
33527
+ "macos": "laptop_mac",
33528
+ "gnome": "terminal",
33529
+ "windowsxp": "desktop_windows",
33530
+ "windows98": "computer",
33531
+ "nextstep": "business_center",
33532
+ "macintosh": "desktop_mac",
33533
+ "msx": "videogame_asset"
33534
+ };
33535
+ const themeLabels = {
33536
+ "windows": "Windows 11",
33537
+ "macos": "macOS",
33538
+ "gnome": "GNOME",
33539
+ "windowsxp": "Windows XP",
33540
+ "windows98": "Windows 98",
33541
+ "nextstep": "NeXTSTEP",
33542
+ "macintosh": "Macintosh",
33543
+ "msx": "MSX"
33544
+ };
33545
+ const modernThemes = ["windows", "macos", "gnome"];
33546
+ const retroThemes = ["windowsxp", "windows98", "nextstep", "macintosh", "msx"];
33547
+ return /* @__PURE__ */ React.createElement(
33548
+ MenuIcon,
33549
+ {
33550
+ icon: "palette",
33551
+ size: "small",
33552
+ position: "top-right",
33553
+ menuSize: "compact"
33554
+ },
33555
+ modernThemes.map((theme) => /* @__PURE__ */ React.createElement(
33556
+ MenuItem,
33557
+ {
33558
+ key: theme,
33559
+ icon: themeIcons[theme] || "desktop_windows",
33560
+ label: themeLabels[theme] || theme,
33561
+ meta: currentTheme === theme ? "✓" : "",
33562
+ onSelect: () => {
33563
+ console.log("Theme changed to:", theme);
33564
+ setTheme(theme);
33565
+ }
33566
+ }
33567
+ )),
33568
+ /* @__PURE__ */ React.createElement(MenuSeparator, null),
33569
+ retroThemes.map((theme) => /* @__PURE__ */ React.createElement(
33570
+ MenuItem,
33571
+ {
33572
+ key: theme,
33573
+ icon: themeIcons[theme] || "desktop_windows",
33574
+ label: themeLabels[theme] || theme,
33575
+ meta: currentTheme === theme ? "✓" : "",
33576
+ onSelect: () => {
33577
+ console.log("Theme changed to:", theme);
33578
+ setTheme(theme);
33579
+ }
33580
+ }
33581
+ ))
33582
+ );
33583
+ };
33286
33584
  const DesktopTaskbar = () => {
33287
33585
  console.log("DesktopTaskbar render");
33288
33586
  const windowsContext = useWindows();
@@ -33297,10 +33595,12 @@ const DesktopTaskbar = () => {
33297
33595
  closeWindow,
33298
33596
  cascadeWindows,
33299
33597
  tileWindows,
33598
+ arrangeWindowsInColumns,
33599
+ arrangeWindowsInRows,
33300
33600
  centerAllWindows,
33301
33601
  clearAllWindows
33302
33602
  } = windowsContext;
33303
- const { isOpen, toggle } = useApplicationMenu();
33603
+ const { isOpen, toggle } = useLaunchPad();
33304
33604
  console.log("DesktopTaskbar - isOpen:", isOpen, "toggle:", toggle);
33305
33605
  const handleWindowClick = (window2) => {
33306
33606
  if (window2.minimized) {
@@ -33326,7 +33626,6 @@ const DesktopTaskbar = () => {
33326
33626
  };
33327
33627
  return /* @__PURE__ */ React.createElement("div", { className: "desktop-taskbar", style: {
33328
33628
  height: "50px",
33329
- background: "rgba(0,0,0,0.8)",
33330
33629
  display: "flex",
33331
33630
  alignItems: "center",
33332
33631
  padding: "0 16px",
@@ -33408,71 +33707,92 @@ Middle click: Close`
33408
33707
  marginLeft: "auto",
33409
33708
  marginRight: "8px"
33410
33709
  } }, /* @__PURE__ */ React.createElement(
33411
- Icon,
33412
- {
33413
- clickable: true,
33414
- size: "small",
33415
- action: () => {
33416
- console.log("Cascade windows clicked!");
33417
- cascadeWindows();
33418
- },
33419
- icon: "view_stream",
33420
- label: "Cascade"
33421
- }
33422
- ), /* @__PURE__ */ React.createElement(
33423
- Icon,
33424
- {
33425
- clickable: true,
33426
- size: "small",
33427
- action: () => {
33428
- console.log("Tile windows clicked!");
33429
- tileWindows();
33430
- },
33431
- icon: "view_module",
33432
- label: "Tile"
33433
- }
33434
- ), /* @__PURE__ */ React.createElement(
33435
- Icon,
33436
- {
33437
- clickable: true,
33438
- size: "small",
33439
- action: () => {
33440
- console.log("Center all windows clicked!");
33441
- centerAllWindows();
33442
- },
33443
- icon: "center_focus_strong",
33444
- label: "Center"
33445
- }
33446
- ), /* @__PURE__ */ React.createElement(
33447
- Icon,
33710
+ MenuIcon,
33448
33711
  {
33449
- clickable: true,
33712
+ icon: "window",
33450
33713
  size: "small",
33451
- action: () => {
33452
- console.log("Clear all windows clicked!");
33453
- clearAllWindows();
33454
- },
33455
- icon: "clear_all",
33456
- label: "Clear"
33457
- }
33458
- )), /* @__PURE__ */ React.createElement("div", { style: {
33714
+ position: "top-right",
33715
+ menuSize: "compact"
33716
+ },
33717
+ /* @__PURE__ */ React.createElement(
33718
+ MenuItem,
33719
+ {
33720
+ icon: "view_stream",
33721
+ label: "Cascade",
33722
+ onSelect: () => {
33723
+ console.log("Cascade windows clicked!");
33724
+ cascadeWindows();
33725
+ }
33726
+ }
33727
+ ),
33728
+ /* @__PURE__ */ React.createElement(
33729
+ MenuItem,
33730
+ {
33731
+ icon: "view_module",
33732
+ label: "Tile",
33733
+ onSelect: () => {
33734
+ console.log("Tile windows clicked!");
33735
+ tileWindows();
33736
+ }
33737
+ }
33738
+ ),
33739
+ /* @__PURE__ */ React.createElement(MenuSeparator, null),
33740
+ /* @__PURE__ */ React.createElement(
33741
+ MenuItem,
33742
+ {
33743
+ icon: "view_week",
33744
+ label: "Columns",
33745
+ onSelect: () => {
33746
+ console.log("Arrange in columns clicked!");
33747
+ arrangeWindowsInColumns();
33748
+ }
33749
+ }
33750
+ ),
33751
+ /* @__PURE__ */ React.createElement(
33752
+ MenuItem,
33753
+ {
33754
+ icon: "view_agenda",
33755
+ label: "Rows",
33756
+ onSelect: () => {
33757
+ console.log("Arrange in rows clicked!");
33758
+ arrangeWindowsInRows();
33759
+ }
33760
+ }
33761
+ ),
33762
+ /* @__PURE__ */ React.createElement(MenuSeparator, null),
33763
+ /* @__PURE__ */ React.createElement(
33764
+ MenuItem,
33765
+ {
33766
+ icon: "center_focus_strong",
33767
+ label: "Center All",
33768
+ onSelect: () => {
33769
+ console.log("Center all windows clicked!");
33770
+ centerAllWindows();
33771
+ }
33772
+ }
33773
+ ),
33774
+ /* @__PURE__ */ React.createElement(
33775
+ MenuItem,
33776
+ {
33777
+ icon: "clear_all",
33778
+ label: "Clear All",
33779
+ onSelect: () => {
33780
+ console.log("Clear all windows clicked!");
33781
+ clearAllWindows();
33782
+ }
33783
+ }
33784
+ )
33785
+ ), /* @__PURE__ */ React.createElement(ThemeMenu, null)), /* @__PURE__ */ React.createElement("div", { style: {
33459
33786
  color: "rgba(255,255,255,0.7)",
33460
33787
  fontSize: "11px",
33461
33788
  fontFamily: "monospace",
33462
33789
  flexShrink: 0,
33463
33790
  textAlign: "right"
33464
- } }, desktopSize.width, "×", desktopSize.height));
33791
+ } }, Math.round(desktopSize.width), "×", Math.round(desktopSize.height)));
33465
33792
  };
33466
33793
  const DesktopInternal = ({ desktopSize, children, ...props }) => {
33467
- const { isOpen, close } = useApplicationMenu();
33468
33794
  const workspaceRef = useRef(null);
33469
- return /* @__PURE__ */ React.createElement(WindowProvider, { desktopSize }, /* @__PURE__ */ React.createElement(DesktopLayout, { workspaceRef, ...props }, /* @__PURE__ */ React.createElement("div", { ref: workspaceRef, className: "desktop__workspace-container" }, /* @__PURE__ */ React.createElement(Workspace, null, children), /* @__PURE__ */ React.createElement(
33470
- ApplicationMenu,
33471
- {
33472
- isOpen,
33473
- onClose: close
33474
- }
33475
- )), /* @__PURE__ */ React.createElement(DesktopTaskbar, null)));
33795
+ return /* @__PURE__ */ React.createElement(WindowProvider, { desktopSize }, /* @__PURE__ */ React.createElement(DesktopLayout, { workspaceRef, ...props }, /* @__PURE__ */ React.createElement("div", { ref: workspaceRef, className: "desktop__workspace-container" }, /* @__PURE__ */ React.createElement(Workspace, null, children), /* @__PURE__ */ React.createElement(DesktopOverlayLayer, null)), /* @__PURE__ */ React.createElement(DesktopTaskbar, null)));
33476
33796
  };
33477
33797
  const Desktop = ({
33478
33798
  desktopSize,
@@ -33481,7 +33801,7 @@ const Desktop = ({
33481
33801
  ...props
33482
33802
  }) => {
33483
33803
  return /* @__PURE__ */ React.createElement(
33484
- AppProvider,
33804
+ DesktopProvider,
33485
33805
  {
33486
33806
  desktopConfig
33487
33807
  },
@@ -43265,8 +43585,6 @@ export {
43265
43585
  ActionButton,
43266
43586
  ActionsCell,
43267
43587
  AppManager,
43268
- AppProvider,
43269
- ApplicationMenu,
43270
43588
  Avatar,
43271
43589
  Button,
43272
43590
  ButtonExamples,
@@ -43301,6 +43619,7 @@ export {
43301
43619
  DateRange,
43302
43620
  DateRange2,
43303
43621
  Desktop,
43622
+ DesktopProvider,
43304
43623
  DesktopTaskbar,
43305
43624
  Dialog,
43306
43625
  DropDown,
@@ -43335,6 +43654,7 @@ export {
43335
43654
  LOGIN_API,
43336
43655
  LOGIN_CONTEXT,
43337
43656
  LOGIN_DICTIONARY,
43657
+ LaunchPad,
43338
43658
  LinearProgress,
43339
43659
  List,
43340
43660
  ListEditor,
@@ -43429,9 +43749,11 @@ export {
43429
43749
  isEmpty,
43430
43750
  isFunction,
43431
43751
  useAppManager,
43432
- useApplicationMenu,
43433
43752
  useCreateWindow,
43753
+ useDesktopOverlays,
43754
+ useDesktopTheme,
43434
43755
  useHashPage,
43756
+ useLaunchPad,
43435
43757
  useWindow,
43436
43758
  useWindowContextMenus,
43437
43759
  useWindowDialogs,