@replohq/sandbox-runtime 1.7.10 → 1.7.12

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.
Files changed (41) hide show
  1. package/_vendor/replo-utils/react/zustand.d.ts +11 -0
  2. package/_vendor/replo-utils/react/zustand.mjs +13 -0
  3. package/_vendor/schemas/generated/selectModeIframeRpc.d.ts +11 -8
  4. package/_vendor/schemas/selectModeIframeRpc.d.ts +66 -130
  5. package/_vendor/schemas/selectModeIframeRpc.mjs +16 -11
  6. package/buildMetadata.js +3 -3
  7. package/package.json +6 -5
  8. package/select-mode/EditorSelection.d.ts +1 -22
  9. package/select-mode/EditorSelection.js +61 -100
  10. package/select-mode/SelectionFrames.d.ts +1 -0
  11. package/select-mode/SelectionFrames.js +58 -0
  12. package/select-mode/annotationFrames.d.ts +13 -0
  13. package/select-mode/annotationFrames.js +31 -1
  14. package/select-mode/displayModeStore.d.ts +0 -2
  15. package/select-mode/displayModeStore.js +11 -30
  16. package/select-mode/hooks/useParentMessaging.js +3 -0
  17. package/select-mode/hooks/useSelectionHover.d.ts +1 -19
  18. package/select-mode/hooks/useSelectionHover.js +37 -49
  19. package/select-mode/hooks/useSelectionInteractions.d.ts +1 -12
  20. package/select-mode/hooks/useSelectionInteractions.js +57 -39
  21. package/select-mode/hooks/useSelectionScrollSync.d.ts +1 -25
  22. package/select-mode/hooks/useSelectionScrollSync.js +48 -40
  23. package/select-mode/iframeRpcChannel.d.ts +24 -1
  24. package/select-mode/inlineEditFeedback.d.ts +6 -0
  25. package/select-mode/inlineEditFeedback.js +47 -0
  26. package/select-mode/isTextEditableElement.d.ts +1 -0
  27. package/select-mode/isTextEditableElement.js +15 -0
  28. package/select-mode/selectModeStore.d.ts +160 -0
  29. package/select-mode/selectModeStore.js +586 -0
  30. package/select-mode/selectionFrame.d.ts +10 -59
  31. package/select-mode/selectionFrame.js +26 -150
  32. package/select-mode/symbolicate.js +4 -0
  33. package/select-mode/tiptapInlineEditor.js +16 -1
  34. package/select-mode/useShallowStore.d.ts +2 -0
  35. package/select-mode/useShallowStore.js +9 -0
  36. package/select-mode/hooks/useCrosshairCursor.d.ts +0 -10
  37. package/select-mode/hooks/useCrosshairCursor.js +0 -23
  38. package/select-mode/hooks/useEditModeStateMachine.d.ts +0 -16
  39. package/select-mode/hooks/useEditModeStateMachine.js +0 -228
  40. package/select-mode/hooks/useSelectModeController.d.ts +0 -11
  41. package/select-mode/hooks/useSelectModeController.js +0 -72
@@ -19,18 +19,14 @@ import {
19
19
  isAdditiveSelectionClick,
20
20
  unionElementPageRects
21
21
  } from "../interactions/selectionGeometry";
22
- import {
23
- hideSelectionFrame,
24
- showAreaSelectionFrames,
25
- showElementSelectionFrames
26
- } from "../selectionFrame";
22
+ import { isTextEditableElement } from "../isTextEditableElement";
27
23
  import { isSelectionStillCurrent } from "../selectionPublish";
28
24
  import {
29
25
  getConnectedSelectedElement,
30
26
  IDLE_SESSION
31
27
  } from "../selectModeSession";
28
+ import { useDisplayMode, useSelectModeStore } from "../selectModeStore";
32
29
  import { symbolicateSelectedElement } from "../symbolicate";
33
- import { isTextEditableElement } from "./useEditModeStateMachine";
34
30
  import { getRepetitionSiblingElements } from "./useSiblingResolution";
35
31
  const DOUBLE_CLICK_THRESHOLD_MS = 500;
36
32
  function getSelectedElementsFromSession(session) {
@@ -49,21 +45,35 @@ function getSelectedElementsFromSession(session) {
49
45
  async function maybeSymbolicate(data) {
50
46
  return data.kind === "react-element" ? symbolicateSelectedElement(data) : data;
51
47
  }
52
- function useSelectionInteractions({
53
- displayMode,
54
- editingElementRef,
55
- interactionSessionRef,
56
- onBeginEditing
57
- }) {
48
+ function useSelectionInteractions() {
49
+ const selectModeStore = useSelectModeStore();
50
+ const displayMode = useDisplayMode();
58
51
  useEffect(() => {
59
52
  if (displayMode !== "selection") {
60
53
  return;
61
54
  }
62
- let dragAnimationFrameId = null;
63
- const editingPointerIds = /* @__PURE__ */ new Set();
64
- let lastClick = null;
65
- let dragCandidates = [];
66
- let committedSelectionAtPointerDown = [];
55
+ const store = () => selectModeStore.getState();
56
+ const interactionSessionRef = {
57
+ get current() {
58
+ return store().interactionSession;
59
+ },
60
+ set current(next) {
61
+ store().actions.setInteractionSession(next);
62
+ }
63
+ };
64
+ const editingElementRef = {
65
+ get current() {
66
+ return store().editingElement;
67
+ }
68
+ };
69
+ const actions = () => store().actions;
70
+ const onBeginEditing = actions().beginEditing;
71
+ const hideSelectionFrame = () => {
72
+ actions().hideSelectionFrames();
73
+ };
74
+ const showAreaSelectionFrames = actions().showAreaSelectionFrames;
75
+ const showElementSelectionFrames = actions().showElementSelectionFrames;
76
+ const editingPointerIds = store().editingPointerIds;
67
77
  const clearCommittedSelection = ({
68
78
  rect
69
79
  }) => {
@@ -72,11 +82,12 @@ function useSelectionInteractions({
72
82
  getWebsiteBuilderRpc()?.areaSelected({ rect, items: [] });
73
83
  };
74
84
  const stopDragAnimation = () => {
85
+ const dragAnimationFrameId = store().dragAnimationFrameId;
75
86
  if (dragAnimationFrameId === null) {
76
87
  return;
77
88
  }
78
89
  cancelAnimationFrame(dragAnimationFrameId);
79
- dragAnimationFrameId = null;
90
+ actions().setDragAnimationFrameId(null);
80
91
  };
81
92
  const resetDragState = ({
82
93
  notifyParentDragCleared = true
@@ -84,7 +95,7 @@ function useSelectionInteractions({
84
95
  const currentSession = interactionSessionRef.current;
85
96
  stopDragAnimation();
86
97
  if (currentSession.type !== "drag") {
87
- dragCandidates = [];
98
+ actions().setDragCandidates([]);
88
99
  return;
89
100
  }
90
101
  if (notifyParentDragCleared && currentSession.hasExceededThreshold) {
@@ -93,7 +104,7 @@ function useSelectionInteractions({
93
104
  selectionRects: []
94
105
  });
95
106
  }
96
- dragCandidates = [];
107
+ actions().setDragCandidates([]);
97
108
  interactionSessionRef.current = IDLE_SESSION;
98
109
  };
99
110
  const postCurrentDragRect = () => {
@@ -120,7 +131,7 @@ function useSelectionInteractions({
120
131
  scrollOffset: session.scrollOffset
121
132
  });
122
133
  const selectionRects = getCandidatesInSelection({
123
- candidates: dragCandidates,
134
+ candidates: store().dragCandidates,
124
135
  selectionPageRect
125
136
  }).map((candidate) => ({
126
137
  id: candidate.id,
@@ -137,7 +148,7 @@ function useSelectionInteractions({
137
148
  const syncDragRectToViewport = () => {
138
149
  const session = interactionSessionRef.current;
139
150
  if (session.type !== "drag") {
140
- dragAnimationFrameId = null;
151
+ actions().setDragAnimationFrameId(null);
141
152
  return;
142
153
  }
143
154
  const nextScrollOffset = getDocumentScrollOffset();
@@ -159,7 +170,9 @@ function useSelectionInteractions({
159
170
  scrollOffset: nextScrollOffset
160
171
  };
161
172
  }
162
- dragAnimationFrameId = requestAnimationFrame(syncDragRectToViewport);
173
+ actions().setDragAnimationFrameId(
174
+ requestAnimationFrame(syncDragRectToViewport)
175
+ );
163
176
  };
164
177
  const handlePointerDown = (event) => {
165
178
  if (event.button !== 0) {
@@ -173,8 +186,8 @@ function useSelectionInteractions({
173
186
  event.preventDefault();
174
187
  event.stopPropagation();
175
188
  const scrollOffset = getDocumentScrollOffset();
176
- committedSelectionAtPointerDown = getSelectedElementsFromSession(
177
- interactionSessionRef.current
189
+ actions().setCommittedSelectionAtPointerDown(
190
+ getSelectedElementsFromSession(interactionSessionRef.current)
178
191
  );
179
192
  const dragStart = getDragPositionFromClient({
180
193
  clientX: event.clientX,
@@ -188,9 +201,11 @@ function useSelectionInteractions({
188
201
  scrollOffset,
189
202
  hasExceededThreshold: false
190
203
  };
191
- dragCandidates = collectDragCandidates(scrollOffset);
192
- if (dragAnimationFrameId === null) {
193
- dragAnimationFrameId = requestAnimationFrame(syncDragRectToViewport);
204
+ actions().setDragCandidates(collectDragCandidates(scrollOffset));
205
+ if (store().dragAnimationFrameId === null) {
206
+ actions().setDragAnimationFrameId(
207
+ requestAnimationFrame(syncDragRectToViewport)
208
+ );
194
209
  }
195
210
  };
196
211
  const handlePointerMove = (event) => {
@@ -210,10 +225,12 @@ function useSelectionInteractions({
210
225
  };
211
226
  const handleViewportChangeDuringDrag = () => {
212
227
  const session = interactionSessionRef.current;
213
- if (session.type !== "drag" || dragAnimationFrameId !== null) {
228
+ if (session.type !== "drag" || store().dragAnimationFrameId !== null) {
214
229
  return;
215
230
  }
216
- dragAnimationFrameId = requestAnimationFrame(syncDragRectToViewport);
231
+ actions().setDragAnimationFrameId(
232
+ requestAnimationFrame(syncDragRectToViewport)
233
+ );
217
234
  };
218
235
  const commitAreaSelection = ({
219
236
  selectedElements,
@@ -275,9 +292,9 @@ function useSelectionInteractions({
275
292
  scrollOffset
276
293
  });
277
294
  const now = pointerEvent.timeStamp;
278
- const previousClick = lastClick;
295
+ const previousClick = store().lastClick;
279
296
  if (previousClick && previousClick.target === selectionElement && now - previousClick.time <= DOUBLE_CLICK_THRESHOLD_MS && isTextEditableElement(selectionElement)) {
280
- lastClick = null;
297
+ actions().setLastClick(null);
281
298
  onBeginEditing({
282
299
  element: selectionElement,
283
300
  descriptorPromise: previousClick.descriptorPromise
@@ -289,11 +306,11 @@ function useSelectionInteractions({
289
306
  clickPosition,
290
307
  siblingSelectors: siblingElements.map(buildSelector)
291
308
  });
292
- lastClick = {
309
+ actions().setLastClick({
293
310
  descriptorPromise: Promise.resolve(data),
294
311
  target: selectionElement,
295
312
  time: now
296
- };
313
+ });
297
314
  if (!selectionElement.isConnected) {
298
315
  return;
299
316
  }
@@ -309,6 +326,7 @@ function useSelectionInteractions({
309
326
  };
310
327
  void maybeSymbolicate(data).then((symbolicated) => {
311
328
  const session = interactionSessionRef.current;
329
+ const committedSelectionAtPointerDown = store().committedSelectionAtPointerDown;
312
330
  const isPendingClickOnSelection = session.type === "drag" && !session.hasExceededThreshold && committedSelectionAtPointerDown.length === 1 && committedSelectionAtPointerDown[0] === selectionElement;
313
331
  if (!isPendingClickOnSelection && !isSelectionStillCurrent({
314
332
  session: interactionSessionRef.current,
@@ -329,14 +347,14 @@ function useSelectionInteractions({
329
347
  commitElementSelection({ selectionElement, pointerEvent });
330
348
  return;
331
349
  }
332
- lastClick = null;
350
+ actions().setLastClick(null);
333
351
  const pointerRect = getPointRect({
334
352
  x: pointerEvent.clientX,
335
353
  y: pointerEvent.clientY
336
354
  });
337
355
  const nextElements = getSelectionAfterAdditiveClick({
338
356
  candidates,
339
- currentSelectedElements: committedSelectionAtPointerDown,
357
+ currentSelectedElements: store().committedSelectionAtPointerDown,
340
358
  targetElement: selectionElement
341
359
  });
342
360
  const [firstElement] = nextElements;
@@ -349,7 +367,7 @@ function useSelectionInteractions({
349
367
  selectionElement: firstElement,
350
368
  pointerEvent
351
369
  });
352
- lastClick = null;
370
+ actions().setLastClick(null);
353
371
  return;
354
372
  }
355
373
  const scrollOffset = getDocumentScrollOffset();
@@ -382,7 +400,7 @@ function useSelectionInteractions({
382
400
  const dragStart = snapshot.type === "drag" ? snapshot.dragStart : null;
383
401
  const dragCurrent = snapshot.type === "drag" ? snapshot.dragCurrent : null;
384
402
  const scrollOffset = snapshot.type === "drag" ? snapshot.scrollOffset : getDocumentScrollOffset();
385
- const candidates = dragCandidates;
403
+ const candidates = store().dragCandidates;
386
404
  resetDragState({ notifyParentDragCleared: false });
387
405
  if (!dragStart || snapshot.type !== "drag") {
388
406
  const targetElement = event.target;
@@ -469,7 +487,7 @@ function useSelectionInteractions({
469
487
  window.removeEventListener("resize", handleViewportChangeDuringDrag);
470
488
  resetDragState();
471
489
  };
472
- }, [displayMode, editingElementRef, interactionSessionRef, onBeginEditing]);
490
+ }, [displayMode, selectModeStore]);
473
491
  }
474
492
  export {
475
493
  useSelectionInteractions
@@ -1,25 +1 @@
1
- import type { MutableRefObject } from "react";
2
- import type { DisplayMode } from "../../_vendor/schemas/generated/selectMode";
3
- import type { SelectModeInteractionSession } from "../selectModeSession";
4
- /**
5
- * After a selection (element or area) has been resolved, the parent's
6
- * highlight overlay is positioned in viewport coordinates. When the user
7
- * scrolls the iframe document the highlight would otherwise lag behind the
8
- * underlying element. This hook re-sends an updated rect on every scroll
9
- * (rAF-coalesced) so the parent overlay tracks the element/area through
10
- * scrolls without us having to mirror scroll state into the parent.
11
- *
12
- * - For an `element` session we send only `{ boundingRect, clickPosition }`
13
- * — the rest of the descriptor (selector, outerHTML, computed styles,
14
- * text metrics, source location) was captured at selection-commit time
15
- * and doesn't change while the user is just scrolling. Rebuilding the
16
- * full descriptor here would call `serializeStyledElement` recursively.
17
- * The in-iframe frames only remeasure the selected repetition group.
18
- * - For an `area` session we keep the original *page* rect (which doesn't
19
- * move) and convert it to viewport coordinates using the latest scroll
20
- * offset before sending.
21
- */
22
- export declare function useSelectionScrollSync({ displayMode, interactionSessionRef, }: {
23
- displayMode: DisplayMode;
24
- interactionSessionRef: MutableRefObject<SelectModeInteractionSession>;
25
- }): void;
1
+ export declare function useSelectionScrollSync(): void;
@@ -5,59 +5,67 @@ import {
5
5
  getElementBoundingRect,
6
6
  getViewportRectFromPageRect
7
7
  } from "../interactions/selectionGeometry";
8
- import { showElementSelectionFrames } from "../selectionFrame";
9
- function useSelectionScrollSync({
10
- displayMode,
11
- interactionSessionRef
12
- }) {
8
+ import { useDisplayMode, useSelectModeStore } from "../selectModeStore";
9
+ function useSelectionScrollSync() {
10
+ const store = useSelectModeStore();
11
+ const displayMode = useDisplayMode();
13
12
  useEffect(() => {
14
13
  if (displayMode !== "selection") {
15
14
  return;
16
15
  }
17
- let animationFrameId = null;
18
16
  const handleScroll = () => {
19
- if (animationFrameId !== null) {
17
+ const { scrollSyncAnimationFrameId, actions } = store.getState();
18
+ if (scrollSyncAnimationFrameId !== null) {
20
19
  return;
21
20
  }
22
- animationFrameId = requestAnimationFrame(() => {
23
- animationFrameId = null;
24
- const session = interactionSessionRef.current;
25
- if (session.type === "element") {
26
- const boundingRect = getElementBoundingRect(session.element);
27
- const sessionClickPosition = session.clickPosition;
28
- const clickPosition = {
29
- x: sessionClickPosition !== null ? boundingRect.left + sessionClickPosition.x : boundingRect.right,
30
- y: sessionClickPosition !== null ? boundingRect.top + sessionClickPosition.y : boundingRect.bottom
31
- };
32
- const scrollOffset = getDocumentScrollOffset();
33
- showElementSelectionFrames({
34
- elements: [session.element, ...session.siblingElements],
35
- scrollOffset
36
- });
37
- getWebsiteBuilderRpc()?.selectedElementRectUpdate({
38
- rect: boundingRect,
39
- clickPosition
40
- });
41
- return;
42
- }
43
- if (session.type === "area") {
44
- getWebsiteBuilderRpc()?.selectedAreaRectUpdate({
45
- rect: getViewportRectFromPageRect({
46
- rect: session.pageRect,
47
- scrollOffset: getDocumentScrollOffset()
48
- })
49
- });
50
- }
51
- });
21
+ actions.setScrollSyncAnimationFrameId(
22
+ requestAnimationFrame(() => {
23
+ const { interactionSession, actions: storeActions } = store.getState();
24
+ storeActions.setScrollSyncAnimationFrameId(null);
25
+ if (interactionSession.type === "element") {
26
+ const boundingRect = getElementBoundingRect(
27
+ interactionSession.element
28
+ );
29
+ const sessionClickPosition = interactionSession.clickPosition;
30
+ const clickPosition = {
31
+ x: sessionClickPosition !== null ? boundingRect.left + sessionClickPosition.x : boundingRect.right,
32
+ y: sessionClickPosition !== null ? boundingRect.top + sessionClickPosition.y : boundingRect.bottom
33
+ };
34
+ const scrollOffset = getDocumentScrollOffset();
35
+ storeActions.showElementSelectionFrames({
36
+ elements: [
37
+ interactionSession.element,
38
+ ...interactionSession.siblingElements
39
+ ],
40
+ scrollOffset
41
+ });
42
+ getWebsiteBuilderRpc()?.selectedElementRectUpdate({
43
+ rect: boundingRect,
44
+ clickPosition
45
+ });
46
+ return;
47
+ }
48
+ if (interactionSession.type === "area") {
49
+ getWebsiteBuilderRpc()?.selectedAreaRectUpdate({
50
+ rect: getViewportRectFromPageRect({
51
+ rect: interactionSession.pageRect,
52
+ scrollOffset: getDocumentScrollOffset()
53
+ })
54
+ });
55
+ }
56
+ })
57
+ );
52
58
  };
53
59
  document.addEventListener("scroll", handleScroll, true);
54
60
  return () => {
55
61
  document.removeEventListener("scroll", handleScroll, true);
56
- if (animationFrameId !== null) {
57
- cancelAnimationFrame(animationFrameId);
62
+ const { scrollSyncAnimationFrameId, actions } = store.getState();
63
+ if (scrollSyncAnimationFrameId !== null) {
64
+ cancelAnimationFrame(scrollSyncAnimationFrameId);
65
+ actions.setScrollSyncAnimationFrameId(null);
58
66
  }
59
67
  };
60
- }, [displayMode, interactionSessionRef]);
68
+ }, [displayMode, store]);
61
69
  }
62
70
  export {
63
71
  useSelectionScrollSync
@@ -337,6 +337,28 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
337
337
  }, import("zod/v4/core").$strip>;
338
338
  outputSchema: import("zod").ZodVoid;
339
339
  };
340
+ inlineEditFeedbackChanged: {
341
+ inputSchema: import("zod").ZodObject<{
342
+ feedback: import("zod").ZodNullable<import("zod").ZodObject<{
343
+ status: import("zod").ZodEnum<{
344
+ unavailable: "unavailable";
345
+ pending: "pending";
346
+ failed: "failed";
347
+ }>;
348
+ rect: import("zod").ZodObject<{
349
+ x: import("zod").ZodNumber;
350
+ y: import("zod").ZodNumber;
351
+ left: import("zod").ZodNumber;
352
+ top: import("zod").ZodNumber;
353
+ right: import("zod").ZodNumber;
354
+ bottom: import("zod").ZodNumber;
355
+ width: import("zod").ZodNumber;
356
+ height: import("zod").ZodNumber;
357
+ }, import("zod/v4/core").$strip>;
358
+ }, import("zod/v4/core").$strip>>;
359
+ }, import("zod/v4/core").$strip>;
360
+ outputSchema: import("zod").ZodVoid;
361
+ };
340
362
  editorStateUpdate: {
341
363
  inputSchema: import("zod").ZodObject<{
342
364
  activeMarks: import("zod").ZodObject<{
@@ -345,7 +367,8 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
345
367
  underline: import("zod").ZodBoolean;
346
368
  strike: import("zod").ZodBoolean;
347
369
  }, import("zod/v4/core").$strip>;
348
- isEditing: import("zod").ZodBoolean;
370
+ isInlineEditing: import("zod").ZodBoolean;
371
+ isInlineEditPending: import("zod").ZodBoolean;
349
372
  }, import("zod/v4/core").$strip>;
350
373
  outputSchema: import("zod").ZodVoid;
351
374
  };
@@ -0,0 +1,6 @@
1
+ import type { InlineEditFeedback } from "../_vendor/schemas/generated/selectModeIframeRpc";
2
+ export declare function reportInlineEditFeedback({ element, onDisconnected, status, }: {
3
+ element: HTMLElement;
4
+ onDisconnected: () => void;
5
+ status?: InlineEditFeedback["status"];
6
+ }): () => void;
@@ -0,0 +1,47 @@
1
+ import { getWebsiteBuilderRpc } from "./iframeRpcChannel";
2
+ function reportInlineEditFeedback({
3
+ element,
4
+ onDisconnected,
5
+ status = "pending"
6
+ }) {
7
+ let animationFrame = 0;
8
+ let stopped = false;
9
+ let previousRect = "";
10
+ const report = () => {
11
+ if (stopped) return;
12
+ if (!element.isConnected) {
13
+ onDisconnected();
14
+ return;
15
+ }
16
+ const bounds = element.getBoundingClientRect();
17
+ const rect = {
18
+ x: bounds.x,
19
+ y: bounds.y,
20
+ top: bounds.top,
21
+ right: bounds.right,
22
+ bottom: bounds.bottom,
23
+ left: bounds.left,
24
+ width: bounds.width,
25
+ height: bounds.height
26
+ };
27
+ const serializedRect = JSON.stringify(rect);
28
+ if (serializedRect !== previousRect) {
29
+ previousRect = serializedRect;
30
+ getWebsiteBuilderRpc()?.inlineEditFeedbackChanged({
31
+ feedback: { status, rect }
32
+ });
33
+ }
34
+ animationFrame = requestAnimationFrame(report);
35
+ };
36
+ const timer = status === "pending" ? window.setTimeout(report, 150) : null;
37
+ if (status !== "pending") report();
38
+ return () => {
39
+ stopped = true;
40
+ if (timer !== null) clearTimeout(timer);
41
+ cancelAnimationFrame(animationFrame);
42
+ getWebsiteBuilderRpc()?.inlineEditFeedbackChanged({ feedback: null });
43
+ };
44
+ }
45
+ export {
46
+ reportInlineEditFeedback
47
+ };
@@ -0,0 +1 @@
1
+ export declare function isTextEditableElement(element: Element): element is HTMLElement;
@@ -0,0 +1,15 @@
1
+ function isTextEditableElement(element) {
2
+ const tagName = element.tagName.toLowerCase();
3
+ return element instanceof HTMLElement && Boolean(element.textContent?.trim()) && ![
4
+ "input",
5
+ "textarea",
6
+ "select",
7
+ "option",
8
+ "img",
9
+ "video",
10
+ "canvas"
11
+ ].includes(tagName);
12
+ }
13
+ export {
14
+ isTextEditableElement
15
+ };
@@ -0,0 +1,160 @@
1
+ import type { DisplayMode, SelectableData, SelectModeBoundingRect, SelectModeFormatCommand, SelectModeSelectionType } from "../_vendor/schemas/generated/selectMode";
2
+ import type { InlineEditFeedback } from "../_vendor/schemas/generated/selectModeIframeRpc";
3
+ import type { DragCandidate } from "./interactions/selectionGeometry";
4
+ import type { SelectionFrameSpec } from "./selectionFrame";
5
+ import type { SelectModeInteractionSession } from "./selectModeSession";
6
+ import type { InlineTiptapEditor } from "./tiptapInlineEditor";
7
+ export type ActiveMarks = {
8
+ bold: boolean;
9
+ italic: boolean;
10
+ underline: boolean;
11
+ strike: boolean;
12
+ };
13
+ export declare const EMPTY_ACTIVE_MARKS: ActiveMarks;
14
+ type InlineEditRequest = {
15
+ status: "pending";
16
+ editId: string;
17
+ element: HTMLElement;
18
+ timeout: number;
19
+ stopFeedback: () => void;
20
+ } | {
21
+ status: Exclude<InlineEditFeedback["status"], "pending">;
22
+ element: HTMLElement;
23
+ stopFeedback: () => void;
24
+ };
25
+ type LastClick = {
26
+ descriptorPromise: Promise<SelectableData>;
27
+ target: Element;
28
+ time: number;
29
+ };
30
+ interface SelectModeStoreState {
31
+ displayMode: DisplayMode;
32
+ interactionSession: SelectModeInteractionSession;
33
+ selectionFrames: SelectionFrameSpec[];
34
+ isSelectionFrameEditing: boolean;
35
+ lastPointerClientPosition: {
36
+ x: number;
37
+ y: number;
38
+ } | null;
39
+ lastPostedHoverRect: SelectModeBoundingRect | null | undefined;
40
+ hoverSyncAnimationFrameId: number | null;
41
+ lastClick: LastClick | null;
42
+ dragCandidates: DragCandidate[];
43
+ committedSelectionAtPointerDown: Element[];
44
+ dragAnimationFrameId: number | null;
45
+ editingPointerIds: Set<number>;
46
+ scrollSyncAnimationFrameId: number | null;
47
+ inlineEditRequest: InlineEditRequest | null;
48
+ editor: InlineTiptapEditor | null;
49
+ editingElement: HTMLElement | null;
50
+ editId: string | null;
51
+ originalInnerHTML: string | null;
52
+ initialHTML: string | null;
53
+ isCommitting: boolean;
54
+ beginEditingAt: number;
55
+ activeMarks: ActiveMarks;
56
+ actions: {
57
+ reset: () => void;
58
+ setDisplayMode: (displayMode: DisplayMode) => void;
59
+ setSelectionType: ({ selectionType, selectors, }: {
60
+ selectionType: SelectModeSelectionType;
61
+ selectors?: string[];
62
+ }) => void;
63
+ setInteractionSession: (interactionSession: SelectModeInteractionSession) => void;
64
+ resetInteractionSession: () => void;
65
+ postSelectedElementSnapshot: (options?: {
66
+ clearMissing?: boolean;
67
+ }) => boolean;
68
+ showElementSelectionFrames: ({ elements, scrollOffset, }: {
69
+ elements: Element[];
70
+ scrollOffset: {
71
+ left: number;
72
+ top: number;
73
+ };
74
+ }) => void;
75
+ showAreaSelectionFrames: ({ elements, scrollOffset, }: {
76
+ elements: Element[];
77
+ scrollOffset: {
78
+ left: number;
79
+ top: number;
80
+ };
81
+ }) => void;
82
+ hideSelectionFrames: () => void;
83
+ setLastPointerClientPosition: (position: {
84
+ x: number;
85
+ y: number;
86
+ } | null) => void;
87
+ setLastPostedHoverRect: (rect: SelectModeBoundingRect | null | undefined) => void;
88
+ resetHoverRectDedup: () => void;
89
+ setHoverSyncAnimationFrameId: (id: number | null) => void;
90
+ setLastClick: (lastClick: LastClick | null) => void;
91
+ setDragCandidates: (dragCandidates: DragCandidate[]) => void;
92
+ setCommittedSelectionAtPointerDown: (elements: Element[]) => void;
93
+ setDragAnimationFrameId: (id: number | null) => void;
94
+ setScrollSyncAnimationFrameId: (id: number | null) => void;
95
+ beginEditing: ({ element, descriptorPromise, }: {
96
+ element: Element;
97
+ descriptorPromise: Promise<SelectableData>;
98
+ }) => void;
99
+ commitInlineEdit: () => void;
100
+ revertInlineEdit: () => void;
101
+ formatCommand: (command: SelectModeFormatCommand) => void;
102
+ dismissInlineEditRequest: () => void;
103
+ };
104
+ }
105
+ export declare const selectModeStore: import("zustand/traditional").UseBoundStoreWithEqualityFn<import("zustand").StoreApi<SelectModeStoreState>>;
106
+ export declare function useSelectModeStore(): import("zustand/traditional").UseBoundStoreWithEqualityFn<import("zustand").StoreApi<SelectModeStoreState>>;
107
+ export declare const useSelectModeStoreActions: () => {
108
+ reset: () => void;
109
+ setDisplayMode: (displayMode: DisplayMode) => void;
110
+ setSelectionType: ({ selectionType, selectors, }: {
111
+ selectionType: SelectModeSelectionType;
112
+ selectors?: string[];
113
+ }) => void;
114
+ setInteractionSession: (interactionSession: SelectModeInteractionSession) => void;
115
+ resetInteractionSession: () => void;
116
+ postSelectedElementSnapshot: (options?: {
117
+ clearMissing?: boolean;
118
+ }) => boolean;
119
+ showElementSelectionFrames: ({ elements, scrollOffset, }: {
120
+ elements: Element[];
121
+ scrollOffset: {
122
+ left: number;
123
+ top: number;
124
+ };
125
+ }) => void;
126
+ showAreaSelectionFrames: ({ elements, scrollOffset, }: {
127
+ elements: Element[];
128
+ scrollOffset: {
129
+ left: number;
130
+ top: number;
131
+ };
132
+ }) => void;
133
+ hideSelectionFrames: () => void;
134
+ setLastPointerClientPosition: (position: {
135
+ x: number;
136
+ y: number;
137
+ } | null) => void;
138
+ setLastPostedHoverRect: (rect: SelectModeBoundingRect | null | undefined) => void;
139
+ resetHoverRectDedup: () => void;
140
+ setHoverSyncAnimationFrameId: (id: number | null) => void;
141
+ setLastClick: (lastClick: LastClick | null) => void;
142
+ setDragCandidates: (dragCandidates: DragCandidate[]) => void;
143
+ setCommittedSelectionAtPointerDown: (elements: Element[]) => void;
144
+ setDragAnimationFrameId: (id: number | null) => void;
145
+ setScrollSyncAnimationFrameId: (id: number | null) => void;
146
+ beginEditing: ({ element, descriptorPromise, }: {
147
+ element: Element;
148
+ descriptorPromise: Promise<SelectableData>;
149
+ }) => void;
150
+ commitInlineEdit: () => void;
151
+ revertInlineEdit: () => void;
152
+ formatCommand: (command: SelectModeFormatCommand) => void;
153
+ dismissInlineEditRequest: () => void;
154
+ };
155
+ export declare const useDisplayMode: () => DisplayMode;
156
+ export declare const useSelectionFrames: () => SelectionFrameSpec[];
157
+ export declare const useIsSelectionFrameEditing: () => boolean;
158
+ export declare const useEditingElement: () => HTMLElement | null;
159
+ export declare const useInteractionSession: () => SelectModeInteractionSession;
160
+ export {};