@deadragdoll/reactnu 0.1.76 → 0.1.77

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.cjs CHANGED
@@ -3177,6 +3177,7 @@ function writeStoredWindowSnapshot(windowStoreKey, snapshot) {
3177
3177
  } catch {
3178
3178
  }
3179
3179
  }
3180
+ var WINDOW_STORE_WRITE_DEBOUNCE_MS = 250;
3180
3181
  function resolveSavedWindowStyle(definition, mode, ownerCenteredStyle, index) {
3181
3182
  const snapshot = definition.onOpen?.() ?? readStoredWindowSnapshot(definition.windowStoreKey);
3182
3183
  const savedStyle = {};
@@ -3315,6 +3316,7 @@ function NuWindowProvider({
3315
3316
  const creationOrderRef = (0, import_react19.useRef)(0);
3316
3317
  const idRef = (0, import_react19.useRef)(0);
3317
3318
  const windowBoundsByIdRef = (0, import_react19.useRef)({});
3319
+ const pendingWindowStoreWritesRef = (0, import_react19.useRef)(/* @__PURE__ */ new Map());
3318
3320
  const [windows, setWindows] = (0, import_react19.useState)([]);
3319
3321
  const [windowBoundsById, setWindowBoundsById] = (0, import_react19.useState)({});
3320
3322
  const appHostMenuContext = (0, import_react19.useContext)(AppHostMenuContext);
@@ -3737,16 +3739,52 @@ function NuWindowProvider({
3737
3739
  onAppModalChange?.(hasAppModal);
3738
3740
  }, [hasAppModal, onAppModalChange]);
3739
3741
  (0, import_react19.useEffect)(() => {
3742
+ const pendingWindowStoreWrites = pendingWindowStoreWritesRef.current;
3743
+ const windowStoreKeyById = new Map(
3744
+ windows.map((windowEntry) => [windowEntry.id, windowEntry.windowStoreKey])
3745
+ );
3746
+ for (const [id, pending] of pendingWindowStoreWrites) {
3747
+ if (windowStoreKeyById.get(id) === pending.windowStoreKey) {
3748
+ continue;
3749
+ }
3750
+ clearTimeout(pending.timeoutId);
3751
+ pendingWindowStoreWrites.delete(id);
3752
+ writeStoredWindowSnapshot(pending.windowStoreKey, pending.snapshot);
3753
+ }
3740
3754
  for (const windowEntry of windows) {
3741
3755
  if (!windowEntry.windowStoreKey) {
3742
3756
  continue;
3743
3757
  }
3744
- writeStoredWindowSnapshot(
3745
- windowEntry.windowStoreKey,
3746
- resolveManagedWindowSnapshot(windowEntry, windowBoundsById)
3758
+ const existing = pendingWindowStoreWrites.get(windowEntry.id);
3759
+ if (existing) {
3760
+ clearTimeout(existing.timeoutId);
3761
+ }
3762
+ const windowStoreKey = windowEntry.windowStoreKey;
3763
+ const snapshot = resolveManagedWindowSnapshot(
3764
+ windowEntry,
3765
+ windowBoundsById
3747
3766
  );
3767
+ const timeoutId = setTimeout(() => {
3768
+ writeStoredWindowSnapshot(windowStoreKey, snapshot);
3769
+ pendingWindowStoreWrites.delete(windowEntry.id);
3770
+ }, WINDOW_STORE_WRITE_DEBOUNCE_MS);
3771
+ pendingWindowStoreWrites.set(windowEntry.id, {
3772
+ timeoutId,
3773
+ windowStoreKey,
3774
+ snapshot
3775
+ });
3748
3776
  }
3749
3777
  }, [windowBoundsById, windows]);
3778
+ (0, import_react19.useEffect)(() => {
3779
+ const pendingWindowStoreWrites = pendingWindowStoreWritesRef.current;
3780
+ return () => {
3781
+ for (const entry of pendingWindowStoreWrites.values()) {
3782
+ clearTimeout(entry.timeoutId);
3783
+ writeStoredWindowSnapshot(entry.windowStoreKey, entry.snapshot);
3784
+ }
3785
+ pendingWindowStoreWrites.clear();
3786
+ };
3787
+ }, []);
3750
3788
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(NuWindowContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: ["nu-window-host", className].filter(Boolean).join(" "), children: [
3751
3789
  children,
3752
3790
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "nu-window-layer", children: renderWindows.map((windowEntry) => {
@@ -5046,7 +5084,7 @@ function NuIconGridItem({
5046
5084
  icon.contextMenuItems,
5047
5085
  icon
5048
5086
  );
5049
- const dragSource = useNuDragSource({
5087
+ const { dragRef, isDragging } = useNuDragSource({
5050
5088
  disabled: icon.disabled,
5051
5089
  getItem: () => ({ data: icon, id: icon.id, type: "icon" }),
5052
5090
  onDropAccepted: (result) => {
@@ -5089,14 +5127,14 @@ function NuIconGridItem({
5089
5127
  {
5090
5128
  "aria-haspopup": contextMenuItems.length > 0 ? "menu" : void 0,
5091
5129
  className: "nu-icon-grid__icon",
5092
- "data-dragging": dragSource.isDragging || void 0,
5130
+ "data-dragging": isDragging || void 0,
5093
5131
  "data-selected": manager.selectedIconId === icon.id || void 0,
5094
5132
  disabled: icon.disabled,
5095
5133
  onClick: handleClick,
5096
5134
  onContextMenu: handleContextMenu,
5097
5135
  onDoubleClick: icon.onDoubleClick,
5098
5136
  onKeyDown: handleKeyDown,
5099
- ref: dragSource.dragRef,
5137
+ ref: (node) => dragRef(node),
5100
5138
  style: { left: icon.position.x, top: icon.position.y },
5101
5139
  type: "button",
5102
5140
  children: [
package/dist/index.js CHANGED
@@ -3125,6 +3125,7 @@ function writeStoredWindowSnapshot(windowStoreKey, snapshot) {
3125
3125
  } catch {
3126
3126
  }
3127
3127
  }
3128
+ var WINDOW_STORE_WRITE_DEBOUNCE_MS = 250;
3128
3129
  function resolveSavedWindowStyle(definition, mode, ownerCenteredStyle, index) {
3129
3130
  const snapshot = definition.onOpen?.() ?? readStoredWindowSnapshot(definition.windowStoreKey);
3130
3131
  const savedStyle = {};
@@ -3263,6 +3264,7 @@ function NuWindowProvider({
3263
3264
  const creationOrderRef = useRef8(0);
3264
3265
  const idRef = useRef8(0);
3265
3266
  const windowBoundsByIdRef = useRef8({});
3267
+ const pendingWindowStoreWritesRef = useRef8(/* @__PURE__ */ new Map());
3266
3268
  const [windows, setWindows] = useState10([]);
3267
3269
  const [windowBoundsById, setWindowBoundsById] = useState10({});
3268
3270
  const appHostMenuContext = useContext7(AppHostMenuContext);
@@ -3685,16 +3687,52 @@ function NuWindowProvider({
3685
3687
  onAppModalChange?.(hasAppModal);
3686
3688
  }, [hasAppModal, onAppModalChange]);
3687
3689
  useEffect6(() => {
3690
+ const pendingWindowStoreWrites = pendingWindowStoreWritesRef.current;
3691
+ const windowStoreKeyById = new Map(
3692
+ windows.map((windowEntry) => [windowEntry.id, windowEntry.windowStoreKey])
3693
+ );
3694
+ for (const [id, pending] of pendingWindowStoreWrites) {
3695
+ if (windowStoreKeyById.get(id) === pending.windowStoreKey) {
3696
+ continue;
3697
+ }
3698
+ clearTimeout(pending.timeoutId);
3699
+ pendingWindowStoreWrites.delete(id);
3700
+ writeStoredWindowSnapshot(pending.windowStoreKey, pending.snapshot);
3701
+ }
3688
3702
  for (const windowEntry of windows) {
3689
3703
  if (!windowEntry.windowStoreKey) {
3690
3704
  continue;
3691
3705
  }
3692
- writeStoredWindowSnapshot(
3693
- windowEntry.windowStoreKey,
3694
- resolveManagedWindowSnapshot(windowEntry, windowBoundsById)
3706
+ const existing = pendingWindowStoreWrites.get(windowEntry.id);
3707
+ if (existing) {
3708
+ clearTimeout(existing.timeoutId);
3709
+ }
3710
+ const windowStoreKey = windowEntry.windowStoreKey;
3711
+ const snapshot = resolveManagedWindowSnapshot(
3712
+ windowEntry,
3713
+ windowBoundsById
3695
3714
  );
3715
+ const timeoutId = setTimeout(() => {
3716
+ writeStoredWindowSnapshot(windowStoreKey, snapshot);
3717
+ pendingWindowStoreWrites.delete(windowEntry.id);
3718
+ }, WINDOW_STORE_WRITE_DEBOUNCE_MS);
3719
+ pendingWindowStoreWrites.set(windowEntry.id, {
3720
+ timeoutId,
3721
+ windowStoreKey,
3722
+ snapshot
3723
+ });
3696
3724
  }
3697
3725
  }, [windowBoundsById, windows]);
3726
+ useEffect6(() => {
3727
+ const pendingWindowStoreWrites = pendingWindowStoreWritesRef.current;
3728
+ return () => {
3729
+ for (const entry of pendingWindowStoreWrites.values()) {
3730
+ clearTimeout(entry.timeoutId);
3731
+ writeStoredWindowSnapshot(entry.windowStoreKey, entry.snapshot);
3732
+ }
3733
+ pendingWindowStoreWrites.clear();
3734
+ };
3735
+ }, []);
3698
3736
  return /* @__PURE__ */ jsx29(NuWindowContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs17("div", { className: ["nu-window-host", className].filter(Boolean).join(" "), children: [
3699
3737
  children,
3700
3738
  /* @__PURE__ */ jsx29("div", { className: "nu-window-layer", children: renderWindows.map((windowEntry) => {
@@ -5011,7 +5049,7 @@ function NuIconGridItem({
5011
5049
  icon.contextMenuItems,
5012
5050
  icon
5013
5051
  );
5014
- const dragSource = useNuDragSource({
5052
+ const { dragRef, isDragging } = useNuDragSource({
5015
5053
  disabled: icon.disabled,
5016
5054
  getItem: () => ({ data: icon, id: icon.id, type: "icon" }),
5017
5055
  onDropAccepted: (result) => {
@@ -5054,14 +5092,14 @@ function NuIconGridItem({
5054
5092
  {
5055
5093
  "aria-haspopup": contextMenuItems.length > 0 ? "menu" : void 0,
5056
5094
  className: "nu-icon-grid__icon",
5057
- "data-dragging": dragSource.isDragging || void 0,
5095
+ "data-dragging": isDragging || void 0,
5058
5096
  "data-selected": manager.selectedIconId === icon.id || void 0,
5059
5097
  disabled: icon.disabled,
5060
5098
  onClick: handleClick,
5061
5099
  onContextMenu: handleContextMenu,
5062
5100
  onDoubleClick: icon.onDoubleClick,
5063
5101
  onKeyDown: handleKeyDown,
5064
- ref: dragSource.dragRef,
5102
+ ref: (node) => dragRef(node),
5065
5103
  style: { left: icon.position.x, top: icon.position.y },
5066
5104
  type: "button",
5067
5105
  children: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deadragdoll/reactnu",
3
- "version": "0.1.76",
3
+ "version": "0.1.77",
4
4
  "private": false,
5
5
  "description": "React components with a precise DOS-era utility interface.",
6
6
  "license": "MIT",