@alpaca-editor/core 1.0.3883 → 1.0.3885
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/editor/MainLayout.js +7 -3
- package/dist/editor/MainLayout.js.map +1 -1
- package/dist/editor/MobileLayout.js +4 -2
- package/dist/editor/MobileLayout.js.map +1 -1
- package/dist/editor/Terminal.js +2 -2
- package/dist/editor/Terminal.js.map +1 -1
- package/dist/editor/ai/AiTerminal.js +0 -1
- package/dist/editor/ai/AiTerminal.js.map +1 -1
- package/dist/editor/client/EditorClient.js +1 -1
- package/dist/editor/client/EditorClient.js.map +1 -1
- package/dist/editor/page-editor-chrome/CommentHighlighting.js +28 -16
- package/dist/editor/page-editor-chrome/CommentHighlighting.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +2 -2
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/sidebar/Translations.js +1 -1
- package/dist/editor/sidebar/Translations.js.map +1 -1
- package/dist/editor/sidebar/ViewSelector.js.map +1 -1
- package/dist/editor/ui/PerfectTree.js +0 -1
- package/dist/editor/ui/PerfectTree.js.map +1 -1
- package/dist/editor/ui/Splitter.d.ts +1 -0
- package/dist/editor/ui/Splitter.js +6 -5
- package/dist/editor/ui/Splitter.js.map +1 -1
- package/dist/editor/utils.js +0 -7
- package/dist/editor/utils.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/styles.css +33 -0
- package/package.json +1 -1
- package/src/editor/MainLayout.tsx +20 -13
- package/src/editor/MobileLayout.tsx +19 -7
- package/src/editor/Terminal.tsx +15 -15
- package/src/editor/ai/AiTerminal.tsx +0 -2
- package/src/editor/client/EditorClient.tsx +1 -1
- package/src/editor/page-editor-chrome/CommentHighlighting.tsx +41 -25
- package/src/editor/page-viewer/PageViewerFrame.tsx +6 -2
- package/src/editor/sidebar/Translations.tsx +1 -1
- package/src/editor/sidebar/ViewSelector.tsx +0 -9
- package/src/editor/ui/PerfectTree.tsx +0 -1
- package/src/editor/ui/Splitter.tsx +11 -11
- package/src/editor/utils.ts +0 -8
- package/src/revision.ts +2 -2
package/src/editor/Terminal.tsx
CHANGED
|
@@ -19,7 +19,7 @@ export const Terminal = forwardRef<
|
|
|
19
19
|
{
|
|
20
20
|
commandHandler: (
|
|
21
21
|
text: string,
|
|
22
|
-
callback: (text: React.ReactNode, finished: boolean) => void
|
|
22
|
+
callback: (text: React.ReactNode, finished: boolean) => void,
|
|
23
23
|
) => void;
|
|
24
24
|
prompt: string;
|
|
25
25
|
setPrompt: (text: string) => void;
|
|
@@ -51,7 +51,7 @@ export const Terminal = forwardRef<
|
|
|
51
51
|
const [promptHistory, setPromptHistory] = useState<string[]>(() => {
|
|
52
52
|
if (typeof window !== "undefined") {
|
|
53
53
|
return JSON.parse(
|
|
54
|
-
localStorage.getItem("editor.ai.promptHistory") || "[]"
|
|
54
|
+
localStorage.getItem("editor.ai.promptHistory") || "[]",
|
|
55
55
|
);
|
|
56
56
|
}
|
|
57
57
|
return [];
|
|
@@ -61,7 +61,7 @@ export const Terminal = forwardRef<
|
|
|
61
61
|
useEffect(() => {
|
|
62
62
|
localStorage.setItem(
|
|
63
63
|
"editor.ai.promptHistory",
|
|
64
|
-
JSON.stringify(promptHistory)
|
|
64
|
+
JSON.stringify(promptHistory),
|
|
65
65
|
);
|
|
66
66
|
}, [promptHistory]);
|
|
67
67
|
|
|
@@ -153,20 +153,20 @@ export const Terminal = forwardRef<
|
|
|
153
153
|
}));
|
|
154
154
|
|
|
155
155
|
return (
|
|
156
|
-
<div className={classNames("flex flex-col
|
|
157
|
-
<div className="
|
|
156
|
+
<div className={classNames("flex h-full flex-col", className)}>
|
|
157
|
+
<div className="flex items-center justify-between gap-2 border-b border-gray-200 p-1 text-xs">
|
|
158
158
|
<button
|
|
159
159
|
onClick={() => {
|
|
160
160
|
setMessages([]);
|
|
161
161
|
onReset();
|
|
162
162
|
}}
|
|
163
163
|
>
|
|
164
|
-
<i className="pi pi-trash text-sm
|
|
164
|
+
<i className="pi pi-trash m-1 text-sm" />
|
|
165
165
|
</button>
|
|
166
166
|
{toolbar}
|
|
167
167
|
</div>
|
|
168
|
-
<div className="
|
|
169
|
-
<div className="flex flex-col gap-3
|
|
168
|
+
<div className="h-full overflow-x-hidden overflow-y-auto p-2">
|
|
169
|
+
<div className="flex flex-col items-end gap-3 select-text">
|
|
170
170
|
{messages.map((m, i) => (
|
|
171
171
|
<div key={i} className={getClasses(m)}>
|
|
172
172
|
{m.text}
|
|
@@ -175,11 +175,11 @@ export const Terminal = forwardRef<
|
|
|
175
175
|
|
|
176
176
|
{response != null && (
|
|
177
177
|
<div className={responseBoxClasses}>
|
|
178
|
-
<div className="flex text-xs">
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
178
|
+
<div className="flex text-xs">{response}</div>
|
|
179
|
+
<div className="mr-4 flex items-center justify-end space-x-1 text-xs text-gray-400">
|
|
180
|
+
<div className="h-1 w-1 animate-bounce rounded-full bg-gray-400 [animation-delay:-0.3s]"></div>
|
|
181
|
+
<div className="h-1 w-1 animate-bounce rounded-full bg-gray-400 [animation-delay:-0.15s]"></div>
|
|
182
|
+
<div className="h-1 w-1 animate-bounce rounded-full bg-gray-400"></div>
|
|
183
183
|
</div>
|
|
184
184
|
</div>
|
|
185
185
|
)}
|
|
@@ -191,14 +191,14 @@ export const Terminal = forwardRef<
|
|
|
191
191
|
<InputTextarea
|
|
192
192
|
ref={inputRef}
|
|
193
193
|
value={prompt}
|
|
194
|
-
className="
|
|
194
|
+
className="flex-1 resize-none self-stretch rounded border border-gray-300 text-xs"
|
|
195
195
|
onKeyDown={handleKeyPress}
|
|
196
196
|
onChange={(e) => setPrompt(e.target.value)}
|
|
197
197
|
rows={4}
|
|
198
198
|
cols={30}
|
|
199
199
|
disabled={disabled}
|
|
200
200
|
/>
|
|
201
|
-
<div className="flex justify-between
|
|
201
|
+
<div className="flex items-center justify-between py-1">
|
|
202
202
|
{statusbar}
|
|
203
203
|
<Button
|
|
204
204
|
icon={"pi pi-send"}
|
|
@@ -2,12 +2,13 @@ import {
|
|
|
2
2
|
useEditContext,
|
|
3
3
|
useModifiedFieldsContext,
|
|
4
4
|
} from "../client/editContext";
|
|
5
|
-
import { findFieldElement } from "../utils";
|
|
5
|
+
import { findComponentRect, findFieldElement } from "../utils";
|
|
6
6
|
import { Comment } from "../../types";
|
|
7
7
|
import { useState } from "react";
|
|
8
8
|
import { useEffect } from "react";
|
|
9
9
|
import { classNames } from "primereact/utils";
|
|
10
10
|
import { CommentIcon } from "../ui/Icons";
|
|
11
|
+
import { getComponentById } from "../componentTreeHelper";
|
|
11
12
|
|
|
12
13
|
export function CommentHighlighting({
|
|
13
14
|
comment,
|
|
@@ -73,22 +74,21 @@ export function CommentHighlighting({
|
|
|
73
74
|
|
|
74
75
|
if (!editContext) return null;
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (!fieldElement) return null;
|
|
77
|
+
const fieldElement = comment.fieldId
|
|
78
|
+
? findFieldElement(iframe, {
|
|
79
|
+
item: {
|
|
80
|
+
id: comment.itemId,
|
|
81
|
+
language: comment.language,
|
|
82
|
+
version: comment.version,
|
|
83
|
+
},
|
|
84
|
+
fieldId: comment.fieldId,
|
|
85
|
+
})
|
|
86
|
+
: undefined;
|
|
88
87
|
|
|
89
88
|
let rects: DOMRectList | null = null;
|
|
89
|
+
let isTextRange = false;
|
|
90
90
|
|
|
91
|
-
if (range[0] !== undefined && range[1] !== undefined) {
|
|
91
|
+
if (fieldElement && range[0] !== undefined && range[1] !== undefined) {
|
|
92
92
|
const startData = getTextNodeAtOffset(fieldElement, range[0]);
|
|
93
93
|
const endData = getTextNodeAtOffset(fieldElement, range[1]);
|
|
94
94
|
|
|
@@ -97,11 +97,25 @@ export function CommentHighlighting({
|
|
|
97
97
|
textRange.setStart(startData.node, startData.offset);
|
|
98
98
|
textRange.setEnd(endData.node, endData.offset);
|
|
99
99
|
rects = textRange.getClientRects();
|
|
100
|
+
isTextRange = true;
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
if (!rects || rects.length === 0) {
|
|
104
|
-
|
|
105
|
+
let fallbackElement = fieldElement;
|
|
106
|
+
if (!fallbackElement && comment.itemId && editContext.page) {
|
|
107
|
+
const componentStart = iframe.contentWindow?.document.body.querySelector(
|
|
108
|
+
"[data-component-start='" + comment.itemId + "']",
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
fallbackElement = componentStart?.nextElementSibling;
|
|
112
|
+
while (fallbackElement && fallbackElement.tagName === "SCRIPT") {
|
|
113
|
+
fallbackElement = fallbackElement.nextElementSibling;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (!fallbackElement) return null;
|
|
117
|
+
const fallbackRect = fallbackElement.getBoundingClientRect();
|
|
118
|
+
if (!fallbackRect) return null;
|
|
105
119
|
rects = {
|
|
106
120
|
length: 1,
|
|
107
121
|
0: fallbackRect,
|
|
@@ -146,16 +160,18 @@ export function CommentHighlighting({
|
|
|
146
160
|
<CommentIcon className="text-blue-500 hover:text-blue-600" />
|
|
147
161
|
</div>
|
|
148
162
|
)}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
163
|
+
{isTextRange && (
|
|
164
|
+
<div
|
|
165
|
+
className="opacity-45"
|
|
166
|
+
style={{
|
|
167
|
+
width: "100%",
|
|
168
|
+
height: "100%",
|
|
169
|
+
backgroundColor: comment.isResolved
|
|
170
|
+
? "rgba(0, 255, 0, 0.45)"
|
|
171
|
+
: "rgba(255, 0, 0, 0.45)",
|
|
172
|
+
}}
|
|
173
|
+
></div>
|
|
174
|
+
)}
|
|
159
175
|
</div>
|
|
160
176
|
))}
|
|
161
177
|
</>
|
|
@@ -273,7 +273,7 @@ export function PageViewerFrame({
|
|
|
273
273
|
injectSXAScripts(iframeRef.current!);
|
|
274
274
|
}, 1000);
|
|
275
275
|
|
|
276
|
-
|
|
276
|
+
buildPageModelThrottled(doc, editContextRef, pageViewContextRef);
|
|
277
277
|
}
|
|
278
278
|
};
|
|
279
279
|
|
|
@@ -604,7 +604,11 @@ export function PageViewerFrame({
|
|
|
604
604
|
//attributes: true, // observe attribute changes (like style or class)
|
|
605
605
|
});
|
|
606
606
|
|
|
607
|
-
|
|
607
|
+
buildPageModelThrottled(
|
|
608
|
+
iframeDocument,
|
|
609
|
+
editContextRef,
|
|
610
|
+
pageViewContextRef,
|
|
611
|
+
);
|
|
608
612
|
}
|
|
609
613
|
};
|
|
610
614
|
|
|
@@ -46,15 +46,6 @@ export function ViewSelector() {
|
|
|
46
46
|
)}
|
|
47
47
|
</div>
|
|
48
48
|
))}
|
|
49
|
-
{/* <div
|
|
50
|
-
title="Tour"
|
|
51
|
-
className={
|
|
52
|
-
"text-gray-400 hover:text-gray-900 cursor-pointer p-3"
|
|
53
|
-
}
|
|
54
|
-
onClick={() => editContext!.startTour()}
|
|
55
|
-
>
|
|
56
|
-
<i className="pi pi-question-circle text-xl" />
|
|
57
|
-
</div> */}
|
|
58
49
|
</div>
|
|
59
50
|
);
|
|
60
51
|
}
|
|
@@ -5,6 +5,7 @@ export type SplitterPanel = {
|
|
|
5
5
|
name: string;
|
|
6
6
|
content: React.ReactNode;
|
|
7
7
|
collapsible?: boolean;
|
|
8
|
+
hidden?: boolean;
|
|
8
9
|
};
|
|
9
10
|
|
|
10
11
|
interface SplitterProps {
|
|
@@ -155,7 +156,7 @@ export const Splitter: React.FC<SplitterProps> = ({
|
|
|
155
156
|
document.addEventListener("mousemove", onMouseMove);
|
|
156
157
|
document.addEventListener("mouseup", onMouseUp, true);
|
|
157
158
|
},
|
|
158
|
-
[panels, panelSizes]
|
|
159
|
+
[panels, panelSizes],
|
|
159
160
|
);
|
|
160
161
|
|
|
161
162
|
const isLastResizer = (index: number) => index === panels.length - 2;
|
|
@@ -184,7 +185,7 @@ export const Splitter: React.FC<SplitterProps> = ({
|
|
|
184
185
|
return (
|
|
185
186
|
<div
|
|
186
187
|
onClick={!isResizing ? toggleLastPanelCollapse : undefined}
|
|
187
|
-
className="
|
|
188
|
+
className="flex cursor-pointer items-center justify-center bg-gray-200 p-1 text-gray-500 select-none hover:bg-blue-700 hover:text-white"
|
|
188
189
|
style={{ writingMode: "vertical-rl", userSelect: "none" }}
|
|
189
190
|
>
|
|
190
191
|
{expandLabel}
|
|
@@ -200,7 +201,7 @@ export const Splitter: React.FC<SplitterProps> = ({
|
|
|
200
201
|
return (
|
|
201
202
|
<div
|
|
202
203
|
className={
|
|
203
|
-
"
|
|
204
|
+
"relative z-1000 flex w-[4px] cursor-ew-resize items-center justify-center bg-gray-200 select-none hover:bg-blue-700"
|
|
204
205
|
}
|
|
205
206
|
onDoubleClick={
|
|
206
207
|
isLastResizer(index) ? toggleLastPanelCollapse : undefined
|
|
@@ -213,10 +214,7 @@ export const Splitter: React.FC<SplitterProps> = ({
|
|
|
213
214
|
};
|
|
214
215
|
|
|
215
216
|
return (
|
|
216
|
-
<div
|
|
217
|
-
className="flex w-full h-full overflow-hidden"
|
|
218
|
-
ref={splitterRef}
|
|
219
|
-
>
|
|
217
|
+
<div className="flex h-full w-full overflow-hidden" ref={splitterRef}>
|
|
220
218
|
{panels.map((panel, index) => (
|
|
221
219
|
<React.Fragment key={panel.name}>
|
|
222
220
|
<div
|
|
@@ -226,13 +224,15 @@ export const Splitter: React.FC<SplitterProps> = ({
|
|
|
226
224
|
className="relative"
|
|
227
225
|
style={{
|
|
228
226
|
flex: `${panel.defaultSize === "auto" ? 1 : 0} 1 ${getFlexBasis(
|
|
229
|
-
index
|
|
227
|
+
index,
|
|
230
228
|
)}`,
|
|
229
|
+
|
|
231
230
|
minWidth: 0,
|
|
232
231
|
display:
|
|
233
|
-
panel.collapsible &&
|
|
234
|
-
|
|
235
|
-
|
|
232
|
+
(panel.collapsible &&
|
|
233
|
+
isLastPanelCollapsed &&
|
|
234
|
+
index === totalPanels - 1) ||
|
|
235
|
+
panel.hidden
|
|
236
236
|
? "none"
|
|
237
237
|
: "block",
|
|
238
238
|
}}
|
package/src/editor/utils.ts
CHANGED
|
@@ -319,14 +319,6 @@ export function findComponentRect(
|
|
|
319
319
|
const elements =
|
|
320
320
|
startElement === endElement ? [startElement] : [startElement, endElement];
|
|
321
321
|
|
|
322
|
-
// console.log(
|
|
323
|
-
// "start rect",
|
|
324
|
-
// startRect,
|
|
325
|
-
// startElement,
|
|
326
|
-
// iframe.contentWindow?.scrollY,
|
|
327
|
-
// takeScrollPositionIntoAccount
|
|
328
|
-
// );
|
|
329
|
-
|
|
330
322
|
return {
|
|
331
323
|
rect: {
|
|
332
324
|
x: startRect.x,
|
package/src/revision.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = "1.0.
|
|
2
|
-
export const buildDate = "2025-05-20
|
|
1
|
+
export const version = "1.0.3885";
|
|
2
|
+
export const buildDate = "2025-05-20 13:49:48";
|