canopycms 0.0.68-int.94 → 0.0.68-int.95

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.
@@ -113,6 +113,16 @@ export function useCommentSystem(options) {
113
113
  }, [activeCommentContext, options.selectedPath, options.branchName]);
114
114
  // Listen for field focus messages from preview frame
115
115
  useEffect(() => {
116
+ // Delayed undo steps (highlight restore, focus clear). Cleanup runs them early rather than
117
+ // dropping them, so an entry switch never leaves a field highlighted or focused.
118
+ const pending = new Map();
119
+ const later = (undo, ms) => {
120
+ const id = window.setTimeout(() => {
121
+ pending.delete(id);
122
+ undo();
123
+ }, ms);
124
+ pending.set(id, undo);
125
+ };
116
126
  const handleFocus = (event) => {
117
127
  // Only accept messages from the preview's origin (same-origin when previewSrc is
118
128
  // relative). Origin-only by design: this hook has no handle on the preview iframe
@@ -136,21 +146,26 @@ export function useCommentSystem(options) {
136
146
  target.scrollIntoView({ behavior: 'smooth', block: 'center' });
137
147
  const previous = target.style.boxShadow;
138
148
  target.style.boxShadow = '0 0 0 3px rgba(79, 70, 229, 0.35)';
139
- window.setTimeout(() => {
149
+ later(() => {
140
150
  target.style.boxShadow = previous;
141
151
  }, 1200);
142
152
  // Set focused field path to trigger FieldWrapper auto-focus
143
153
  if (normalizedPath) {
144
154
  setFocusedFieldPath(normalizedPath);
145
155
  // Clear after brief delay to allow FieldWrapper to detect the change
146
- window.setTimeout(() => {
147
- setFocusedFieldPath(undefined);
148
- }, 100);
156
+ later(() => setFocusedFieldPath(undefined), 100);
149
157
  }
150
158
  }
151
159
  };
152
160
  window.addEventListener('message', handleFocus);
153
- return () => window.removeEventListener('message', handleFocus);
161
+ return () => {
162
+ window.removeEventListener('message', handleFocus);
163
+ for (const [id, undo] of pending) {
164
+ window.clearTimeout(id);
165
+ undo();
166
+ }
167
+ pending.clear();
168
+ };
154
169
  }, [options.currentEntry]);
155
170
  const handleJumpToField = (entryPath, canopyPath, threadId) => {
156
171
  if (entryPath !== options.selectedPath) {
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const CANOPYCMS_VERSION = "0.0.68-int.94";
1
+ export declare const CANOPYCMS_VERSION = "0.0.68-int.95";
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // Generated by scripts/bump-version.mjs, its only writer. The package builds with plain
2
2
  // tsc (rootDir: src), so src/ cannot import ../package.json; version.test.ts keeps the two equal.
3
- export const CANOPYCMS_VERSION = '0.0.68-int.94';
3
+ export const CANOPYCMS_VERSION = '0.0.68-int.95';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "//": "@codemirror/language, @lezer/highlight: workaround — @mdxeditor/editor uses cm6-theme-basic-light which peer-requires these but mdxeditor doesn't declare them as dependencies",
3
3
  "name": "canopycms",
4
- "version": "0.0.68-int.94",
4
+ "version": "0.0.68-int.95",
5
5
  "description": "CanopyCMS core package: schema-driven content, branch-aware editing, and editor UI for Next.js.",
6
6
  "license": "MIT",
7
7
  "repository": {