ywana-core8 0.2.20 → 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,7 +32820,7 @@ const FloatingElementsRenderer = () => {
32755
32820
  ))
32756
32821
  )));
32757
32822
  };
32758
- const ApplicationMenu = ({ isOpen, onClose }) => {
32823
+ const LaunchPad = ({ isOpen, onClose }) => {
32759
32824
  const appManager = useAppManager();
32760
32825
  const [searchTerm, setSearchTerm] = React.useState("");
32761
32826
  const [selectedCategory, setSelectedCategory] = React.useState("all");
@@ -32824,10 +32889,10 @@ const ApplicationMenu = ({ isOpen, onClose }) => {
32824
32889
  setSearchTerm("");
32825
32890
  };
32826
32891
  if (!isOpen) return null;
32827
- 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(
32828
32893
  "button",
32829
32894
  {
32830
- className: `application-menu__view-toggle ${isCondensed ? "active" : ""}`,
32895
+ className: `launchpad__view-toggle ${isCondensed ? "active" : ""}`,
32831
32896
  onClick: () => setIsCondensed(!isCondensed),
32832
32897
  title: isCondensed ? "Normal view" : "Condensed view"
32833
32898
  },
@@ -32835,7 +32900,7 @@ const ApplicationMenu = ({ isOpen, onClose }) => {
32835
32900
  ), /* @__PURE__ */ React.createElement(
32836
32901
  "button",
32837
32902
  {
32838
- className: `application-menu__view-toggle ${viewMode === "grid" ? "active" : ""}`,
32903
+ className: `launchpad__view-toggle ${viewMode === "grid" ? "active" : ""}`,
32839
32904
  onClick: () => setViewMode("grid"),
32840
32905
  title: "Grid view"
32841
32906
  },
@@ -32843,7 +32908,7 @@ const ApplicationMenu = ({ isOpen, onClose }) => {
32843
32908
  ), /* @__PURE__ */ React.createElement(
32844
32909
  "button",
32845
32910
  {
32846
- className: `application-menu__view-toggle ${viewMode === "list" ? "active" : ""}`,
32911
+ className: `launchpad__view-toggle ${viewMode === "list" ? "active" : ""}`,
32847
32912
  onClick: () => setViewMode("list"),
32848
32913
  title: "List view"
32849
32914
  },
@@ -32851,12 +32916,12 @@ const ApplicationMenu = ({ isOpen, onClose }) => {
32851
32916
  ), /* @__PURE__ */ React.createElement(
32852
32917
  "button",
32853
32918
  {
32854
- className: "application-menu__close",
32919
+ className: "launchpad__close",
32855
32920
  onClick: onClose,
32856
32921
  title: "Close menu"
32857
32922
  },
32858
32923
  "×"
32859
- ))), /* @__PURE__ */ React.createElement("div", { className: "application-menu__search" }, /* @__PURE__ */ React.createElement(
32924
+ ))), /* @__PURE__ */ React.createElement("div", { className: "launchpad__search" }, /* @__PURE__ */ React.createElement(
32860
32925
  "input",
32861
32926
  {
32862
32927
  ref: searchInputRef,
@@ -32864,12 +32929,12 @@ const ApplicationMenu = ({ isOpen, onClose }) => {
32864
32929
  placeholder: "Search applications...",
32865
32930
  value: searchTerm,
32866
32931
  onChange: (e) => setSearchTerm(e.target.value),
32867
- className: "application-menu__search-input"
32932
+ className: "launchpad__search-input"
32868
32933
  }
32869
- )), /* @__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(
32870
32935
  "button",
32871
32936
  {
32872
- className: `application-menu__category ${selectedCategory === "all" ? "active" : ""}`,
32937
+ className: `launchpad__category ${selectedCategory === "all" ? "active" : ""}`,
32873
32938
  onClick: () => handleCategorySelect("all"),
32874
32939
  title: "All Apps"
32875
32940
  },
@@ -32879,33 +32944,33 @@ const ApplicationMenu = ({ isOpen, onClose }) => {
32879
32944
  "button",
32880
32945
  {
32881
32946
  key: category.id,
32882
- className: `application-menu__category ${selectedCategory === category.id ? "active" : ""}`,
32947
+ className: `launchpad__category ${selectedCategory === category.id ? "active" : ""}`,
32883
32948
  onClick: () => handleCategorySelect(category.id),
32884
32949
  title: category.name
32885
32950
  },
32886
32951
  /* @__PURE__ */ React.createElement("span", { className: "category-icon" }, category.icon),
32887
32952
  /* @__PURE__ */ React.createElement("span", { className: "category-name" }, category.name)
32888
- )))), /* @__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(
32889
32954
  "div",
32890
32955
  {
32891
32956
  key: app.id,
32892
- className: `application-menu__app--${viewMode}`,
32957
+ className: `launchpad__app--${viewMode}`,
32893
32958
  onClick: () => handleLaunchApp(app),
32894
32959
  title: app.description
32895
32960
  },
32896
32961
  /* @__PURE__ */ React.createElement("div", { className: "app-icon" }, app.icon),
32897
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)
32898
- )))), !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(
32899
32964
  "div",
32900
32965
  {
32901
32966
  key: app.id,
32902
- className: `application-menu__app--${viewMode}`,
32967
+ className: `launchpad__app--${viewMode}`,
32903
32968
  onClick: () => handleLaunchApp(app),
32904
32969
  title: app.description
32905
32970
  },
32906
32971
  /* @__PURE__ */ React.createElement("div", { className: "app-icon" }, app.icon),
32907
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)
32908
- )))))), 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.")))));
32909
32974
  };
32910
32975
  class AppManager {
32911
32976
  constructor() {
@@ -33186,48 +33251,221 @@ const defaultDesktopConfig = {
33186
33251
  ]
33187
33252
  };
33188
33253
  const defaultAppManager = new AppManager();
33189
- const AppContext = React.createContext();
33190
- const useApplicationMenu = () => {
33191
- const context = React.useContext(AppContext);
33254
+ const DesktopContext = React.createContext();
33255
+ const useLaunchPad = () => {
33256
+ const context = React.useContext(DesktopContext);
33192
33257
  if (!context) {
33193
- throw new Error("useApplicationMenu must be used within AppProvider");
33258
+ throw new Error("useLaunchPad must be used within DesktopProvider");
33194
33259
  }
33195
- return context.applicationMenu;
33260
+ return context.launchPad;
33196
33261
  };
33197
33262
  const useAppManager = () => {
33198
- const context = React.useContext(AppContext);
33263
+ const context = React.useContext(DesktopContext);
33199
33264
  if (!context) {
33200
- throw new Error("useAppManager must be used within AppProvider");
33265
+ throw new Error("useAppManager must be used within DesktopProvider");
33201
33266
  }
33202
33267
  return context.appManager;
33203
33268
  };
33204
- 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 = ({
33205
33284
  children,
33206
- desktopConfig = defaultDesktopConfig
33285
+ desktopConfig = defaultDesktopConfig,
33286
+ initialTheme = "windows"
33207
33287
  }) => {
33208
33288
  const appManager = new AppManager();
33209
- 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);
33210
33293
  React.useEffect(() => {
33211
33294
  if (appManager.getAllApps().length === 0 && desktopConfig) {
33212
33295
  AppLoader.load(appManager, desktopConfig);
33213
33296
  }
33214
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
+ };
33215
33340
  const value = {
33216
- // Application Menu state
33217
- applicationMenu: {
33218
- isOpen: isApplicationMenuOpen,
33219
- open: () => setIsApplicationMenuOpen(true),
33220
- close: () => setIsApplicationMenuOpen(false),
33221
- toggle: () => setIsApplicationMenuOpen(!isApplicationMenuOpen)
33341
+ // LaunchPad state
33342
+ launchPad: {
33343
+ isOpen: isLaunchPadOpen,
33344
+ open: () => setIsLaunchPadOpen(true),
33345
+ close: () => setIsLaunchPadOpen(false),
33346
+ toggle: () => setIsLaunchPadOpen(!isLaunchPadOpen)
33222
33347
  },
33223
33348
  // App Manager instance
33224
- 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
+ }
33225
33392
  };
33226
- 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
+ )));
33227
33464
  };
33228
- const DesktopLayout = ({ children, className = "", theme = "windows", workspaceRef, ...props }) => {
33465
+ const DesktopLayout = ({ children, className = "", workspaceRef, ...props }) => {
33229
33466
  const desktopRef = React.useRef(null);
33230
33467
  const { windowManager } = useWindows();
33468
+ const { current: theme } = useDesktopTheme();
33231
33469
  React.useEffect(() => {
33232
33470
  let currentSize = { width: 1200, height: 750 };
33233
33471
  const measureWorkspace = () => {
@@ -33284,6 +33522,67 @@ const Workspace = ({ children }) => {
33284
33522
  window2.content
33285
33523
  )));
33286
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
+ };
33287
33586
  const DesktopTaskbar = () => {
33288
33587
  console.log("DesktopTaskbar render");
33289
33588
  const windowsContext = useWindows();
@@ -33298,10 +33597,12 @@ const DesktopTaskbar = () => {
33298
33597
  closeWindow,
33299
33598
  cascadeWindows,
33300
33599
  tileWindows,
33600
+ arrangeWindowsInColumns,
33601
+ arrangeWindowsInRows,
33301
33602
  centerAllWindows,
33302
33603
  clearAllWindows
33303
33604
  } = windowsContext;
33304
- const { isOpen, toggle } = useApplicationMenu();
33605
+ const { isOpen, toggle } = useLaunchPad();
33305
33606
  console.log("DesktopTaskbar - isOpen:", isOpen, "toggle:", toggle);
33306
33607
  const handleWindowClick = (window2) => {
33307
33608
  if (window2.minimized) {
@@ -33327,7 +33628,6 @@ const DesktopTaskbar = () => {
33327
33628
  };
33328
33629
  return /* @__PURE__ */ React.createElement("div", { className: "desktop-taskbar", style: {
33329
33630
  height: "50px",
33330
- background: "rgba(0,0,0,0.8)",
33331
33631
  display: "flex",
33332
33632
  alignItems: "center",
33333
33633
  padding: "0 16px",
@@ -33409,71 +33709,92 @@ Middle click: Close`
33409
33709
  marginLeft: "auto",
33410
33710
  marginRight: "8px"
33411
33711
  } }, /* @__PURE__ */ React.createElement(
33412
- Icon,
33413
- {
33414
- clickable: true,
33415
- size: "small",
33416
- action: () => {
33417
- console.log("Cascade windows clicked!");
33418
- cascadeWindows();
33419
- },
33420
- icon: "view_stream",
33421
- label: "Cascade"
33422
- }
33423
- ), /* @__PURE__ */ React.createElement(
33424
- Icon,
33425
- {
33426
- clickable: true,
33427
- size: "small",
33428
- action: () => {
33429
- console.log("Tile windows clicked!");
33430
- tileWindows();
33431
- },
33432
- icon: "view_module",
33433
- label: "Tile"
33434
- }
33435
- ), /* @__PURE__ */ React.createElement(
33436
- Icon,
33437
- {
33438
- clickable: true,
33439
- size: "small",
33440
- action: () => {
33441
- console.log("Center all windows clicked!");
33442
- centerAllWindows();
33443
- },
33444
- icon: "center_focus_strong",
33445
- label: "Center"
33446
- }
33447
- ), /* @__PURE__ */ React.createElement(
33448
- Icon,
33712
+ MenuIcon,
33449
33713
  {
33450
- clickable: true,
33714
+ icon: "window",
33451
33715
  size: "small",
33452
- action: () => {
33453
- console.log("Clear all windows clicked!");
33454
- clearAllWindows();
33455
- },
33456
- icon: "clear_all",
33457
- label: "Clear"
33458
- }
33459
- )), /* @__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: {
33460
33788
  color: "rgba(255,255,255,0.7)",
33461
33789
  fontSize: "11px",
33462
33790
  fontFamily: "monospace",
33463
33791
  flexShrink: 0,
33464
33792
  textAlign: "right"
33465
- } }, desktopSize.width, "×", desktopSize.height));
33793
+ } }, Math.round(desktopSize.width), "×", Math.round(desktopSize.height)));
33466
33794
  };
33467
33795
  const DesktopInternal = ({ desktopSize, children, ...props }) => {
33468
- const { isOpen, close } = useApplicationMenu();
33469
33796
  const workspaceRef = React.useRef(null);
33470
- 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(
33471
- ApplicationMenu,
33472
- {
33473
- isOpen,
33474
- onClose: close
33475
- }
33476
- )), /* @__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)));
33477
33798
  };
33478
33799
  const Desktop = ({
33479
33800
  desktopSize,
@@ -33482,7 +33803,7 @@ const Desktop = ({
33482
33803
  ...props
33483
33804
  }) => {
33484
33805
  return /* @__PURE__ */ React.createElement(
33485
- AppProvider,
33806
+ DesktopProvider,
33486
33807
  {
33487
33808
  desktopConfig
33488
33809
  },
@@ -43265,8 +43586,6 @@ exports.AccordionExamples = AccordionExamples;
43265
43586
  exports.ActionButton = ActionButton;
43266
43587
  exports.ActionsCell = ActionsCell;
43267
43588
  exports.AppManager = AppManager;
43268
- exports.AppProvider = AppProvider;
43269
- exports.ApplicationMenu = ApplicationMenu;
43270
43589
  exports.Avatar = Avatar;
43271
43590
  exports.Button = Button;
43272
43591
  exports.ButtonExamples = ButtonExamples;
@@ -43301,6 +43620,7 @@ exports.DataTable2Examples = DataTable2Examples;
43301
43620
  exports.DateRange = DateRange;
43302
43621
  exports.DateRange2 = DateRange2;
43303
43622
  exports.Desktop = Desktop;
43623
+ exports.DesktopProvider = DesktopProvider;
43304
43624
  exports.DesktopTaskbar = DesktopTaskbar;
43305
43625
  exports.Dialog = Dialog;
43306
43626
  exports.DropDown = DropDown;
@@ -43335,6 +43655,7 @@ exports.KanbanSwimlane = KanbanSwimlane;
43335
43655
  exports.LOGIN_API = LOGIN_API;
43336
43656
  exports.LOGIN_CONTEXT = LOGIN_CONTEXT;
43337
43657
  exports.LOGIN_DICTIONARY = LOGIN_DICTIONARY;
43658
+ exports.LaunchPad = LaunchPad;
43338
43659
  exports.LinearProgress = LinearProgress;
43339
43660
  exports.List = List;
43340
43661
  exports.ListEditor = ListEditor;
@@ -43429,9 +43750,11 @@ exports.defaultAppManager = defaultAppManager;
43429
43750
  exports.isEmpty = isEmpty;
43430
43751
  exports.isFunction = isFunction;
43431
43752
  exports.useAppManager = useAppManager;
43432
- exports.useApplicationMenu = useApplicationMenu;
43433
43753
  exports.useCreateWindow = useCreateWindow;
43754
+ exports.useDesktopOverlays = useDesktopOverlays;
43755
+ exports.useDesktopTheme = useDesktopTheme;
43434
43756
  exports.useHashPage = useHashPage;
43757
+ exports.useLaunchPad = useLaunchPad;
43435
43758
  exports.useWindow = useWindow;
43436
43759
  exports.useWindowContextMenus = useWindowContextMenus;
43437
43760
  exports.useWindowDialogs = useWindowDialogs;