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