@khanacademy/perseus-editor 31.1.0 → 31.2.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/article-editor.d.ts +5 -0
- package/dist/editor-page.d.ts +5 -0
- package/dist/editor.d.ts +5 -0
- package/dist/es/index.js +16 -4
- package/dist/es/index.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +17 -3
- package/dist/index.js.map +1 -1
- package/dist/preview/message-types.d.ts +10 -26
- package/dist/preview/use-preview-controller.d.ts +43 -0
- package/dist/preview/use-preview-presenter.d.ts +50 -0
- package/dist/testing/feature-flags-util.d.ts +0 -8
- package/dist/widgets/interactive-graph-editor/interactive-graph-editor.d.ts +73 -73
- package/package.json +8 -8
|
@@ -15,16 +15,6 @@ export declare const PREVIEW_MESSAGE_SOURCE: "perseus-preview";
|
|
|
15
15
|
interface PreviewMessageBase {
|
|
16
16
|
source: typeof PREVIEW_MESSAGE_SOURCE;
|
|
17
17
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Base type for messages with iframe ID
|
|
20
|
-
*
|
|
21
|
-
* Note: The ID is primarily used for debugging/logging purposes.
|
|
22
|
-
* Message routing is handled by event.source filtering in the hooks,
|
|
23
|
-
* not by comparing ID strings.
|
|
24
|
-
*/
|
|
25
|
-
interface PreviewMessageWithId extends PreviewMessageBase {
|
|
26
|
-
id: string;
|
|
27
|
-
}
|
|
28
18
|
/**
|
|
29
19
|
* Data for question preview (full item with question, answer area, and hints)
|
|
30
20
|
*/
|
|
@@ -75,36 +65,30 @@ export type PreviewContent = {
|
|
|
75
65
|
/**
|
|
76
66
|
* Message from parent sending content data to iframe
|
|
77
67
|
*/
|
|
78
|
-
|
|
68
|
+
interface PreviewDataMessage extends PreviewMessageBase {
|
|
79
69
|
type: "content-data";
|
|
80
70
|
content: PreviewContent;
|
|
81
|
-
}
|
|
71
|
+
}
|
|
82
72
|
/**
|
|
83
73
|
* Union of all messages sent from parent to iframe
|
|
84
74
|
*/
|
|
85
75
|
export type ParentToIframeMessage = PreviewDataMessage;
|
|
86
76
|
/**
|
|
87
|
-
* Message from iframe
|
|
77
|
+
* Message from iframe to parent telling it the iframe is ready
|
|
88
78
|
*/
|
|
89
|
-
|
|
90
|
-
type: "
|
|
91
|
-
}
|
|
79
|
+
interface PreviewIframeReadyMessage extends PreviewMessageBase {
|
|
80
|
+
type: "iframe-ready";
|
|
81
|
+
}
|
|
92
82
|
/**
|
|
93
83
|
* Message from iframe reporting its content height
|
|
94
84
|
*/
|
|
95
|
-
|
|
85
|
+
interface PreviewHeightUpdateMessage extends PreviewMessageBase {
|
|
96
86
|
type: "height-update";
|
|
97
87
|
height: number;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Message from iframe reporting lint warnings
|
|
101
|
-
*/
|
|
102
|
-
type PreviewLintReportMessage = PreviewMessageWithId & {
|
|
103
|
-
type: "lint-report";
|
|
104
|
-
lintWarnings: ReadonlyArray<any>;
|
|
105
|
-
};
|
|
88
|
+
}
|
|
106
89
|
/**
|
|
107
90
|
* Union of all messages sent from iframe to parent
|
|
108
91
|
*/
|
|
109
|
-
export type IframeToParentMessage =
|
|
92
|
+
export type IframeToParentMessage = PreviewIframeReadyMessage | PreviewHeightUpdateMessage;
|
|
93
|
+
export declare function createPreviewIframeReadyMessage(): PreviewIframeReadyMessage;
|
|
110
94
|
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { PreviewContent } from "./message-types";
|
|
3
|
+
type UsePreviewControllerResult = {
|
|
4
|
+
/**
|
|
5
|
+
* Send preview content data to the iframe
|
|
6
|
+
*/
|
|
7
|
+
sendData: (data: PreviewContent) => void;
|
|
8
|
+
/**
|
|
9
|
+
* Current height of the iframe content (null if not yet reported)
|
|
10
|
+
*/
|
|
11
|
+
height: number | null;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Hook for parent/editor to send data to preview iframe and receive updates.
|
|
15
|
+
*
|
|
16
|
+
* This hook:
|
|
17
|
+
* - Sends preview content data to iframe via postMessage
|
|
18
|
+
* - Listens for height updates from iframe
|
|
19
|
+
* - Listens for lint reports from iframe
|
|
20
|
+
* - Automatically sanitizes apiOptions before sending (removes non-serializable functions)
|
|
21
|
+
*
|
|
22
|
+
* @param iframeRef - Reference to the iframe element
|
|
23
|
+
* @returns Object with sendData function and current height
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```tsx
|
|
27
|
+
* function Editor() {
|
|
28
|
+
* const iframeRef = React.useRef<HTMLIFrameElement>(null);
|
|
29
|
+
* const { sendData, height } = usePreviewController(iframeRef);
|
|
30
|
+
*
|
|
31
|
+
* React.useEffect(() => {
|
|
32
|
+
* sendData({
|
|
33
|
+
* type: "question",
|
|
34
|
+
* data: { item, apiOptions, ... }
|
|
35
|
+
* });
|
|
36
|
+
* }, [item, apiOptions]);
|
|
37
|
+
*
|
|
38
|
+
* return <iframe ref={iframeRef} style={{ height }} />;
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function usePreviewController(iframeRef: React.RefObject<HTMLIFrameElement>): UsePreviewControllerResult;
|
|
43
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { PreviewContent } from "./message-types";
|
|
2
|
+
type UsePreviewPresenterResult = {
|
|
3
|
+
/**
|
|
4
|
+
* The preview content data received from the parent, or null if not yet loaded
|
|
5
|
+
*/
|
|
6
|
+
data: PreviewContent | null;
|
|
7
|
+
/**
|
|
8
|
+
* Whether the preview should render in mobile mode (from data-mobile attribute)
|
|
9
|
+
*/
|
|
10
|
+
isMobile: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Whether to show the lint gutter (from data-lint-gutter attribute)
|
|
13
|
+
*/
|
|
14
|
+
hasLintGutter: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Function to report the current height of the iframe content to the parent
|
|
17
|
+
*/
|
|
18
|
+
reportHeight: (height: number) => void;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Hook for preview iframe to receive data from parent and send updates back.
|
|
22
|
+
*
|
|
23
|
+
* This hook:
|
|
24
|
+
* - Reads iframe configuration from dataset attributes (id, mobile, lintGutter)
|
|
25
|
+
* - Listens for content data from the parent window via postMessage
|
|
26
|
+
* - Requests initial data on mount
|
|
27
|
+
* - Provides functions to report height and lint warnings back to parent
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* function PreviewPage() {
|
|
32
|
+
* const { data, isMobile, reportHeight } = usePreviewPresenter();
|
|
33
|
+
*
|
|
34
|
+
* React.useEffect(() => {
|
|
35
|
+
* if (containerRef.current) {
|
|
36
|
+
* reportHeight(containerRef.current.scrollHeight);
|
|
37
|
+
* }
|
|
38
|
+
* }, [data, reportHeight]);
|
|
39
|
+
*
|
|
40
|
+
* if (!data) return <div>Loading...</div>;
|
|
41
|
+
* return <PreviewRenderer
|
|
42
|
+
* ref={containerRef}
|
|
43
|
+
* data={data}
|
|
44
|
+
* isMobile={isMobile}
|
|
45
|
+
* />;
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function usePreviewPresenter(): UsePreviewPresenterResult;
|
|
50
|
+
export {};
|
|
@@ -4,10 +4,6 @@ declare const DEFAULT_FEATURE_FLAGS: {
|
|
|
4
4
|
"new-radio-widget": boolean;
|
|
5
5
|
"image-widget-upgrade-gif-controls": boolean;
|
|
6
6
|
"image-widget-upgrade-scale": boolean;
|
|
7
|
-
"interactive-graph-absolute-value": boolean;
|
|
8
|
-
"interactive-graph-tangent": boolean;
|
|
9
|
-
"interactive-graph-logarithm": boolean;
|
|
10
|
-
"interactive-graph-exponent": boolean;
|
|
11
7
|
"interactive-graph-vector": boolean;
|
|
12
8
|
"interactive-graph-not-scored": boolean;
|
|
13
9
|
};
|
|
@@ -21,10 +17,6 @@ export declare function getFeatureFlags(overrides?: Partial<typeof DEFAULT_FEATU
|
|
|
21
17
|
"new-radio-widget": boolean;
|
|
22
18
|
"image-widget-upgrade-gif-controls": boolean;
|
|
23
19
|
"image-widget-upgrade-scale": boolean;
|
|
24
|
-
"interactive-graph-absolute-value": boolean;
|
|
25
|
-
"interactive-graph-tangent": boolean;
|
|
26
|
-
"interactive-graph-logarithm": boolean;
|
|
27
|
-
"interactive-graph-exponent": boolean;
|
|
28
20
|
"interactive-graph-vector": boolean;
|
|
29
21
|
"interactive-graph-not-scored": boolean;
|
|
30
22
|
};
|