testomatio-editor-blocks 0.4.74 → 0.4.75
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/package/editor/blocks/step.js +106 -73
- package/package/editor/blocks/stepField.d.ts +11 -0
- package/package/editor/blocks/stepField.js +120 -4
- package/package/styles.css +76 -0
- package/package.json +1 -1
- package/src/editor/blocks/step.tsx +137 -106
- package/src/editor/blocks/stepField.tsx +163 -5
- package/src/editor/styles.css +76 -0
- package/package/editor/blocks/useDeferredMount.d.ts +0 -26
- package/package/editor/blocks/useDeferredMount.js +0 -54
- package/src/editor/blocks/useDeferredMount.ts +0 -66
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Defers mounting of expensive block content until the element is at (or near)
|
|
3
|
-
* the viewport. Heavy blocks (e.g. test steps that each spin up an OverType
|
|
4
|
-
* editor) render a cheap placeholder first; the real interactive content is
|
|
5
|
-
* mounted only once the block scrolls into view. This keeps pasting/loading a
|
|
6
|
-
* large document fast — only the visible steps pay the editor-init cost up
|
|
7
|
-
* front, the rest are upgraded lazily as the user scrolls.
|
|
8
|
-
*
|
|
9
|
-
* Returns a ref to attach to the wrapper element and a boolean that flips to
|
|
10
|
-
* `true` once (and stays true — we never tear an editor back down).
|
|
11
|
-
*
|
|
12
|
-
* `activate(focus)` lets the caller upgrade eagerly on interaction. Passing
|
|
13
|
-
* `focus: true` (a click/focus on the placeholder) records that the freshly
|
|
14
|
-
* mounted content should take focus, so a single click on a preview starts
|
|
15
|
-
* editing. Passive activation (hover pre-warm, scroll-into-view) leaves focus
|
|
16
|
-
* alone via `shouldFocusOnActivate === false`.
|
|
17
|
-
*/
|
|
18
|
-
export declare function useDeferredMount<T extends HTMLElement>(options?: {
|
|
19
|
-
rootMargin?: string;
|
|
20
|
-
initiallyActive?: boolean;
|
|
21
|
-
}): {
|
|
22
|
-
ref: React.RefObject<T | null>;
|
|
23
|
-
active: boolean;
|
|
24
|
-
activate: (focus?: boolean) => void;
|
|
25
|
-
shouldFocusOnActivate: boolean;
|
|
26
|
-
};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from "react";
|
|
2
|
-
/**
|
|
3
|
-
* Defers mounting of expensive block content until the element is at (or near)
|
|
4
|
-
* the viewport. Heavy blocks (e.g. test steps that each spin up an OverType
|
|
5
|
-
* editor) render a cheap placeholder first; the real interactive content is
|
|
6
|
-
* mounted only once the block scrolls into view. This keeps pasting/loading a
|
|
7
|
-
* large document fast — only the visible steps pay the editor-init cost up
|
|
8
|
-
* front, the rest are upgraded lazily as the user scrolls.
|
|
9
|
-
*
|
|
10
|
-
* Returns a ref to attach to the wrapper element and a boolean that flips to
|
|
11
|
-
* `true` once (and stays true — we never tear an editor back down).
|
|
12
|
-
*
|
|
13
|
-
* `activate(focus)` lets the caller upgrade eagerly on interaction. Passing
|
|
14
|
-
* `focus: true` (a click/focus on the placeholder) records that the freshly
|
|
15
|
-
* mounted content should take focus, so a single click on a preview starts
|
|
16
|
-
* editing. Passive activation (hover pre-warm, scroll-into-view) leaves focus
|
|
17
|
-
* alone via `shouldFocusOnActivate === false`.
|
|
18
|
-
*/
|
|
19
|
-
export function useDeferredMount(options = {}) {
|
|
20
|
-
const { rootMargin = "300px 0px", initiallyActive = false } = options;
|
|
21
|
-
const ref = useRef(null);
|
|
22
|
-
const [active, setActive] = useState(initiallyActive);
|
|
23
|
-
const activeRef = useRef(active);
|
|
24
|
-
activeRef.current = active;
|
|
25
|
-
const focusOnActivateRef = useRef(false);
|
|
26
|
-
const activate = (focus = false) => {
|
|
27
|
-
if (activeRef.current)
|
|
28
|
-
return;
|
|
29
|
-
if (focus)
|
|
30
|
-
focusOnActivateRef.current = true;
|
|
31
|
-
setActive(true);
|
|
32
|
-
};
|
|
33
|
-
useEffect(() => {
|
|
34
|
-
if (activeRef.current)
|
|
35
|
-
return;
|
|
36
|
-
const el = ref.current;
|
|
37
|
-
if (!el)
|
|
38
|
-
return;
|
|
39
|
-
// Environments without IntersectionObserver (or SSR) just mount eagerly.
|
|
40
|
-
if (typeof IntersectionObserver === "undefined") {
|
|
41
|
-
setActive(true);
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
const observer = new IntersectionObserver((entries) => {
|
|
45
|
-
if (entries.some((entry) => entry.isIntersecting)) {
|
|
46
|
-
setActive(true);
|
|
47
|
-
observer.disconnect();
|
|
48
|
-
}
|
|
49
|
-
}, { rootMargin });
|
|
50
|
-
observer.observe(el);
|
|
51
|
-
return () => observer.disconnect();
|
|
52
|
-
}, [rootMargin]);
|
|
53
|
-
return { ref, active, activate, shouldFocusOnActivate: focusOnActivateRef.current };
|
|
54
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from "react";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Defers mounting of expensive block content until the element is at (or near)
|
|
5
|
-
* the viewport. Heavy blocks (e.g. test steps that each spin up an OverType
|
|
6
|
-
* editor) render a cheap placeholder first; the real interactive content is
|
|
7
|
-
* mounted only once the block scrolls into view. This keeps pasting/loading a
|
|
8
|
-
* large document fast — only the visible steps pay the editor-init cost up
|
|
9
|
-
* front, the rest are upgraded lazily as the user scrolls.
|
|
10
|
-
*
|
|
11
|
-
* Returns a ref to attach to the wrapper element and a boolean that flips to
|
|
12
|
-
* `true` once (and stays true — we never tear an editor back down).
|
|
13
|
-
*
|
|
14
|
-
* `activate(focus)` lets the caller upgrade eagerly on interaction. Passing
|
|
15
|
-
* `focus: true` (a click/focus on the placeholder) records that the freshly
|
|
16
|
-
* mounted content should take focus, so a single click on a preview starts
|
|
17
|
-
* editing. Passive activation (hover pre-warm, scroll-into-view) leaves focus
|
|
18
|
-
* alone via `shouldFocusOnActivate === false`.
|
|
19
|
-
*/
|
|
20
|
-
export function useDeferredMount<T extends HTMLElement>(
|
|
21
|
-
options: { rootMargin?: string; initiallyActive?: boolean } = {},
|
|
22
|
-
): {
|
|
23
|
-
ref: React.RefObject<T | null>;
|
|
24
|
-
active: boolean;
|
|
25
|
-
activate: (focus?: boolean) => void;
|
|
26
|
-
shouldFocusOnActivate: boolean;
|
|
27
|
-
} {
|
|
28
|
-
const { rootMargin = "300px 0px", initiallyActive = false } = options;
|
|
29
|
-
const ref = useRef<T>(null);
|
|
30
|
-
const [active, setActive] = useState(initiallyActive);
|
|
31
|
-
const activeRef = useRef(active);
|
|
32
|
-
activeRef.current = active;
|
|
33
|
-
const focusOnActivateRef = useRef(false);
|
|
34
|
-
|
|
35
|
-
const activate = (focus = false) => {
|
|
36
|
-
if (activeRef.current) return;
|
|
37
|
-
if (focus) focusOnActivateRef.current = true;
|
|
38
|
-
setActive(true);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
if (activeRef.current) return;
|
|
43
|
-
const el = ref.current;
|
|
44
|
-
if (!el) return;
|
|
45
|
-
|
|
46
|
-
// Environments without IntersectionObserver (or SSR) just mount eagerly.
|
|
47
|
-
if (typeof IntersectionObserver === "undefined") {
|
|
48
|
-
setActive(true);
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const observer = new IntersectionObserver(
|
|
53
|
-
(entries) => {
|
|
54
|
-
if (entries.some((entry) => entry.isIntersecting)) {
|
|
55
|
-
setActive(true);
|
|
56
|
-
observer.disconnect();
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
{ rootMargin },
|
|
60
|
-
);
|
|
61
|
-
observer.observe(el);
|
|
62
|
-
return () => observer.disconnect();
|
|
63
|
-
}, [rootMargin]);
|
|
64
|
-
|
|
65
|
-
return { ref, active, activate, shouldFocusOnActivate: focusOnActivateRef.current };
|
|
66
|
-
}
|