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