@cmssy/react 12.2.0 → 12.4.0
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/client.cjs +52 -1
- package/dist/client.js +52 -1
- package/package.json +2 -2
package/dist/client.cjs
CHANGED
|
@@ -38,6 +38,34 @@ function blocksToMeta(blocks, defaults = {}) {
|
|
|
38
38
|
}
|
|
39
39
|
return out;
|
|
40
40
|
}
|
|
41
|
+
|
|
42
|
+
// src/bridge/shortcut-keys.ts
|
|
43
|
+
function isMacPlatform() {
|
|
44
|
+
const platform = typeof navigator !== "undefined" ? navigator.platform : void 0;
|
|
45
|
+
return typeof platform === "string" && platform.toUpperCase().includes("MAC");
|
|
46
|
+
}
|
|
47
|
+
function isTypingTarget(target) {
|
|
48
|
+
const el = target;
|
|
49
|
+
if (!el || typeof el.tagName !== "string") return false;
|
|
50
|
+
return el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.isContentEditable === true;
|
|
51
|
+
}
|
|
52
|
+
function resolveShortcutAction(event, isMac, isTyping) {
|
|
53
|
+
if (event.repeat || event.isComposing) return null;
|
|
54
|
+
const modifier = isMac ? event.metaKey : event.ctrlKey;
|
|
55
|
+
const key = event.key.length === 1 ? event.key.toLowerCase() : event.key;
|
|
56
|
+
if (modifier && key === "z") {
|
|
57
|
+
if (isTyping) return null;
|
|
58
|
+
return event.shiftKey ? "redo" : "undo";
|
|
59
|
+
}
|
|
60
|
+
if (modifier && key === "s") return "save";
|
|
61
|
+
if (modifier && key === "d") return isTyping ? null : "duplicate";
|
|
62
|
+
const isDeleteKey = key === "Delete" || isMac && key === "Backspace";
|
|
63
|
+
if (isDeleteKey) return isTyping ? null : "delete";
|
|
64
|
+
if (key === "Escape") return "escape";
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/bridge/use-edit-bridge.tsx
|
|
41
69
|
var ZERO_RECT = { x: 0, y: 0, width: 0, height: 0 };
|
|
42
70
|
function collectRects() {
|
|
43
71
|
const rects = /* @__PURE__ */ new Map();
|
|
@@ -94,6 +122,8 @@ function useEditBridge(page, config) {
|
|
|
94
122
|
const selectedIdRef = react.useRef(null);
|
|
95
123
|
const postSafeRef = react.useRef(() => {
|
|
96
124
|
});
|
|
125
|
+
const emitBoundsRef = react.useRef(() => {
|
|
126
|
+
});
|
|
97
127
|
const { id: pageId, blocks } = page;
|
|
98
128
|
const blocksKey = blocks.map((b) => `${b.id}:${b.type}`).join("|");
|
|
99
129
|
react.useEffect(() => {
|
|
@@ -141,7 +171,8 @@ function useEditBridge(page, config) {
|
|
|
141
171
|
...collectLayoutBlocks(rects, pageIds)
|
|
142
172
|
],
|
|
143
173
|
schemas: config.schemas ?? /* @__PURE__ */ Object.create(null),
|
|
144
|
-
blockMeta: config.blockMeta ?? /* @__PURE__ */ Object.create(null)
|
|
174
|
+
blockMeta: config.blockMeta ?? /* @__PURE__ */ Object.create(null),
|
|
175
|
+
capabilities: ["shortcuts"]
|
|
145
176
|
});
|
|
146
177
|
} catch (error) {
|
|
147
178
|
if (typeof console !== "undefined") {
|
|
@@ -236,6 +267,20 @@ function useEditBridge(page, config) {
|
|
|
236
267
|
...layoutPosition !== null ? { layoutPosition } : {}
|
|
237
268
|
});
|
|
238
269
|
};
|
|
270
|
+
const onKeyDown = (event) => {
|
|
271
|
+
const action = resolveShortcutAction(
|
|
272
|
+
event,
|
|
273
|
+
isMacPlatform(),
|
|
274
|
+
isTypingTarget(event.target)
|
|
275
|
+
);
|
|
276
|
+
if (!action) return;
|
|
277
|
+
event.preventDefault();
|
|
278
|
+
postSafe({
|
|
279
|
+
type: "cmssy:shortcut",
|
|
280
|
+
protocolVersion: core.PROTOCOL_VERSION,
|
|
281
|
+
action
|
|
282
|
+
});
|
|
283
|
+
};
|
|
239
284
|
let boundsRaf = 0;
|
|
240
285
|
let boundsPending = false;
|
|
241
286
|
const emitSelectedBounds = () => {
|
|
@@ -256,8 +301,10 @@ function useEditBridge(page, config) {
|
|
|
256
301
|
});
|
|
257
302
|
});
|
|
258
303
|
};
|
|
304
|
+
emitBoundsRef.current = emitSelectedBounds;
|
|
259
305
|
window.addEventListener("message", handler);
|
|
260
306
|
document.addEventListener("click", onClick, { capture: true });
|
|
307
|
+
document.addEventListener("keydown", onKeyDown, { capture: true });
|
|
261
308
|
window.addEventListener("scroll", emitSelectedBounds, {
|
|
262
309
|
capture: true,
|
|
263
310
|
passive: true
|
|
@@ -268,12 +315,16 @@ function useEditBridge(page, config) {
|
|
|
268
315
|
if (boundsRaf) cancelAnimationFrame(boundsRaf);
|
|
269
316
|
window.removeEventListener("message", handler);
|
|
270
317
|
document.removeEventListener("click", onClick, { capture: true });
|
|
318
|
+
document.removeEventListener("keydown", onKeyDown, { capture: true });
|
|
271
319
|
window.removeEventListener("scroll", emitSelectedBounds, {
|
|
272
320
|
capture: true
|
|
273
321
|
});
|
|
274
322
|
window.removeEventListener("resize", emitSelectedBounds);
|
|
275
323
|
};
|
|
276
324
|
}, [config.editorOrigin, pageId, blocksKey]);
|
|
325
|
+
react.useEffect(() => {
|
|
326
|
+
emitBoundsRef.current();
|
|
327
|
+
});
|
|
277
328
|
react.useEffect(() => {
|
|
278
329
|
if (typeof window === "undefined" || window.parent === window) return;
|
|
279
330
|
const notifySelectionGone = () => {
|
package/dist/client.js
CHANGED
|
@@ -36,6 +36,34 @@ function blocksToMeta(blocks, defaults = {}) {
|
|
|
36
36
|
}
|
|
37
37
|
return out;
|
|
38
38
|
}
|
|
39
|
+
|
|
40
|
+
// src/bridge/shortcut-keys.ts
|
|
41
|
+
function isMacPlatform() {
|
|
42
|
+
const platform = typeof navigator !== "undefined" ? navigator.platform : void 0;
|
|
43
|
+
return typeof platform === "string" && platform.toUpperCase().includes("MAC");
|
|
44
|
+
}
|
|
45
|
+
function isTypingTarget(target) {
|
|
46
|
+
const el = target;
|
|
47
|
+
if (!el || typeof el.tagName !== "string") return false;
|
|
48
|
+
return el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.isContentEditable === true;
|
|
49
|
+
}
|
|
50
|
+
function resolveShortcutAction(event, isMac, isTyping) {
|
|
51
|
+
if (event.repeat || event.isComposing) return null;
|
|
52
|
+
const modifier = isMac ? event.metaKey : event.ctrlKey;
|
|
53
|
+
const key = event.key.length === 1 ? event.key.toLowerCase() : event.key;
|
|
54
|
+
if (modifier && key === "z") {
|
|
55
|
+
if (isTyping) return null;
|
|
56
|
+
return event.shiftKey ? "redo" : "undo";
|
|
57
|
+
}
|
|
58
|
+
if (modifier && key === "s") return "save";
|
|
59
|
+
if (modifier && key === "d") return isTyping ? null : "duplicate";
|
|
60
|
+
const isDeleteKey = key === "Delete" || isMac && key === "Backspace";
|
|
61
|
+
if (isDeleteKey) return isTyping ? null : "delete";
|
|
62
|
+
if (key === "Escape") return "escape";
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/bridge/use-edit-bridge.tsx
|
|
39
67
|
var ZERO_RECT = { x: 0, y: 0, width: 0, height: 0 };
|
|
40
68
|
function collectRects() {
|
|
41
69
|
const rects = /* @__PURE__ */ new Map();
|
|
@@ -92,6 +120,8 @@ function useEditBridge(page, config) {
|
|
|
92
120
|
const selectedIdRef = useRef(null);
|
|
93
121
|
const postSafeRef = useRef(() => {
|
|
94
122
|
});
|
|
123
|
+
const emitBoundsRef = useRef(() => {
|
|
124
|
+
});
|
|
95
125
|
const { id: pageId, blocks } = page;
|
|
96
126
|
const blocksKey = blocks.map((b) => `${b.id}:${b.type}`).join("|");
|
|
97
127
|
useEffect(() => {
|
|
@@ -139,7 +169,8 @@ function useEditBridge(page, config) {
|
|
|
139
169
|
...collectLayoutBlocks(rects, pageIds)
|
|
140
170
|
],
|
|
141
171
|
schemas: config.schemas ?? /* @__PURE__ */ Object.create(null),
|
|
142
|
-
blockMeta: config.blockMeta ?? /* @__PURE__ */ Object.create(null)
|
|
172
|
+
blockMeta: config.blockMeta ?? /* @__PURE__ */ Object.create(null),
|
|
173
|
+
capabilities: ["shortcuts"]
|
|
143
174
|
});
|
|
144
175
|
} catch (error) {
|
|
145
176
|
if (typeof console !== "undefined") {
|
|
@@ -234,6 +265,20 @@ function useEditBridge(page, config) {
|
|
|
234
265
|
...layoutPosition !== null ? { layoutPosition } : {}
|
|
235
266
|
});
|
|
236
267
|
};
|
|
268
|
+
const onKeyDown = (event) => {
|
|
269
|
+
const action = resolveShortcutAction(
|
|
270
|
+
event,
|
|
271
|
+
isMacPlatform(),
|
|
272
|
+
isTypingTarget(event.target)
|
|
273
|
+
);
|
|
274
|
+
if (!action) return;
|
|
275
|
+
event.preventDefault();
|
|
276
|
+
postSafe({
|
|
277
|
+
type: "cmssy:shortcut",
|
|
278
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
279
|
+
action
|
|
280
|
+
});
|
|
281
|
+
};
|
|
237
282
|
let boundsRaf = 0;
|
|
238
283
|
let boundsPending = false;
|
|
239
284
|
const emitSelectedBounds = () => {
|
|
@@ -254,8 +299,10 @@ function useEditBridge(page, config) {
|
|
|
254
299
|
});
|
|
255
300
|
});
|
|
256
301
|
};
|
|
302
|
+
emitBoundsRef.current = emitSelectedBounds;
|
|
257
303
|
window.addEventListener("message", handler);
|
|
258
304
|
document.addEventListener("click", onClick, { capture: true });
|
|
305
|
+
document.addEventListener("keydown", onKeyDown, { capture: true });
|
|
259
306
|
window.addEventListener("scroll", emitSelectedBounds, {
|
|
260
307
|
capture: true,
|
|
261
308
|
passive: true
|
|
@@ -266,12 +313,16 @@ function useEditBridge(page, config) {
|
|
|
266
313
|
if (boundsRaf) cancelAnimationFrame(boundsRaf);
|
|
267
314
|
window.removeEventListener("message", handler);
|
|
268
315
|
document.removeEventListener("click", onClick, { capture: true });
|
|
316
|
+
document.removeEventListener("keydown", onKeyDown, { capture: true });
|
|
269
317
|
window.removeEventListener("scroll", emitSelectedBounds, {
|
|
270
318
|
capture: true
|
|
271
319
|
});
|
|
272
320
|
window.removeEventListener("resize", emitSelectedBounds);
|
|
273
321
|
};
|
|
274
322
|
}, [config.editorOrigin, pageId, blocksKey]);
|
|
323
|
+
useEffect(() => {
|
|
324
|
+
emitBoundsRef.current();
|
|
325
|
+
});
|
|
275
326
|
useEffect(() => {
|
|
276
327
|
if (typeof window === "undefined" || window.parent === window) return;
|
|
277
328
|
const notifySelectionGone = () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cmssy/react",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.4.0",
|
|
4
4
|
"description": "React blocks, renderers, data client and editor bridge for cmssy headless sites",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cmssy",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
},
|
|
98
98
|
"dependencies": {
|
|
99
99
|
"@cmssy/types": "0.35.0",
|
|
100
|
-
"@cmssy/core": "12.
|
|
100
|
+
"@cmssy/core": "12.4.0"
|
|
101
101
|
},
|
|
102
102
|
"scripts": {
|
|
103
103
|
"build": "tsup",
|