@alpaca-editor/core 1.0.3902 → 1.0.3904
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/components/ui/CardConnector.d.ts +2 -1
- package/dist/components/ui/CardConnector.js +3 -3
- package/dist/components/ui/CardConnector.js.map +1 -1
- package/dist/components/ui/button.js +1 -1
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/card.d.ts +7 -1
- package/dist/components/ui/card.js +71 -3
- package/dist/components/ui/card.js.map +1 -1
- package/dist/config/config.js +4 -2
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +1 -0
- package/dist/editor/MobileLayout.js +1 -1
- package/dist/editor/MobileLayout.js.map +1 -1
- package/dist/editor/PictureEditor.js +13 -5
- package/dist/editor/PictureEditor.js.map +1 -1
- package/dist/editor/client/EditorClient.js +2 -2
- package/dist/editor/client/EditorClient.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +14 -1
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/operations.js +1 -1
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/page-editor-chrome/CommentHighlighting.js +4 -1
- package/dist/editor/page-editor-chrome/CommentHighlighting.js.map +1 -1
- package/dist/editor/ui/Splitter.js +3 -1
- package/dist/editor/ui/Splitter.js.map +1 -1
- package/dist/page-wizard/WizardBoxConnector.d.ts +2 -1
- package/dist/page-wizard/WizardBoxConnector.js +3 -3
- package/dist/page-wizard/WizardBoxConnector.js.map +1 -1
- package/dist/page-wizard/WizardSteps.js +63 -17
- package/dist/page-wizard/WizardSteps.js.map +1 -1
- package/dist/page-wizard/service.d.ts +1 -1
- package/dist/page-wizard/service.js +1 -1
- package/dist/page-wizard/service.js.map +1 -1
- package/dist/page-wizard/steps/CollectStep.js +11 -17
- package/dist/page-wizard/steps/CollectStep.js.map +1 -1
- package/dist/page-wizard/steps/ComponentTypesSelector.d.ts +1 -0
- package/dist/page-wizard/steps/ComponentTypesSelector.js +53 -78
- package/dist/page-wizard/steps/ComponentTypesSelector.js.map +1 -1
- package/dist/page-wizard/steps/ContentStep.d.ts +2 -0
- package/dist/page-wizard/steps/ContentStep.js +403 -0
- package/dist/page-wizard/steps/ContentStep.js.map +1 -0
- package/dist/page-wizard/steps/Generate.js +1 -1
- package/dist/page-wizard/steps/Generate.js.map +1 -1
- package/dist/page-wizard/steps/ImagesStep.js +16 -13
- package/dist/page-wizard/steps/ImagesStep.js.map +1 -1
- package/dist/page-wizard/steps/SelectStep.js +1 -1
- package/dist/page-wizard/steps/SelectStep.js.map +1 -1
- package/dist/page-wizard/steps/SetupPageStep.d.ts +2 -0
- package/dist/page-wizard/steps/SetupPageStep.js +152 -0
- package/dist/page-wizard/steps/SetupPageStep.js.map +1 -0
- package/dist/page-wizard/steps/usePageCreator.js +4 -4
- package/dist/page-wizard/steps/usePageCreator.js.map +1 -1
- package/dist/page-wizard/usePageWizard.d.ts +17 -3
- package/dist/page-wizard/usePageWizard.js +62 -2
- package/dist/page-wizard/usePageWizard.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/splash-screen/NewPage.js +10 -10
- package/dist/splash-screen/NewPage.js.map +1 -1
- package/dist/splash-screen/SplashScreen.js +3 -3
- package/dist/splash-screen/SplashScreen.js.map +1 -1
- package/dist/styles.css +184 -68
- package/package.json +1 -1
- package/src/components/ui/CardConnector.tsx +50 -15
- package/src/components/ui/button.tsx +1 -1
- package/src/components/ui/card.tsx +331 -15
- package/src/config/config.tsx +4 -2
- package/src/config/types.ts +3 -0
- package/src/editor/MobileLayout.tsx +7 -9
- package/src/editor/PictureEditor.tsx +16 -10
- package/src/editor/client/EditorClient.tsx +3 -5
- package/src/editor/client/editContext.ts +23 -1
- package/src/editor/client/operations.ts +1 -1
- package/src/editor/page-editor-chrome/CommentHighlighting.tsx +6 -1
- package/src/editor/ui/Splitter.tsx +10 -1
- package/src/page-wizard/WizardBoxConnector.tsx +50 -15
- package/src/page-wizard/WizardSteps.tsx +163 -34
- package/src/page-wizard/service.ts +2 -2
- package/src/page-wizard/steps/CollectStep.tsx +95 -141
- package/src/page-wizard/steps/ComponentTypesSelector.tsx +225 -245
- package/src/page-wizard/steps/ContentStep.tsx +648 -0
- package/src/page-wizard/steps/Generate.tsx +3 -3
- package/src/page-wizard/steps/ImagesStep.tsx +20 -15
- package/src/page-wizard/steps/SelectStep.tsx +4 -4
- package/src/page-wizard/steps/SetupPageStep.tsx +329 -0
- package/src/page-wizard/steps/usePageCreator.ts +4 -4
- package/src/page-wizard/usePageWizard.ts +69 -4
- package/src/revision.ts +2 -2
- package/src/splash-screen/NewPage.tsx +22 -16
- package/src/splash-screen/SplashScreen.tsx +3 -1
- package/dist/page-wizard/steps/CreatePage.d.ts +0 -12
- package/dist/page-wizard/steps/CreatePage.js +0 -149
- package/dist/page-wizard/steps/CreatePage.js.map +0 -1
- package/dist/page-wizard/steps/CreatePageAndLayoutStep.d.ts +0 -2
- package/dist/page-wizard/steps/CreatePageAndLayoutStep.js +0 -235
- package/dist/page-wizard/steps/CreatePageAndLayoutStep.js.map +0 -1
- package/src/page-wizard/steps/CreatePage.tsx +0 -329
- package/src/page-wizard/steps/CreatePageAndLayoutStep.tsx +0 -430
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { cn } from "../../lib/utils";
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
3
|
+
import { Expand, Shrink } from "lucide-react";
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* A reusable card component with header (icon, title, description) and content area.
|
|
@@ -11,6 +13,12 @@ export function Card({
|
|
|
11
13
|
description,
|
|
12
14
|
className,
|
|
13
15
|
noPadding,
|
|
16
|
+
collapsible = "no",
|
|
17
|
+
defaultCollapsed = "no",
|
|
18
|
+
summary,
|
|
19
|
+
footer,
|
|
20
|
+
showFullscreenButton = false,
|
|
21
|
+
onFullscreen,
|
|
14
22
|
}: {
|
|
15
23
|
children: React.ReactNode;
|
|
16
24
|
icon: React.ReactNode;
|
|
@@ -18,27 +26,335 @@ export function Card({
|
|
|
18
26
|
description: string;
|
|
19
27
|
className?: string;
|
|
20
28
|
noPadding?: boolean;
|
|
29
|
+
collapsible?: "yes" | "no" | "mobileOnly";
|
|
30
|
+
defaultCollapsed?: "yes" | "no" | "mobileOnly";
|
|
31
|
+
summary?: React.ReactNode;
|
|
32
|
+
footer?: React.ReactNode;
|
|
33
|
+
showFullscreenButton?: boolean;
|
|
34
|
+
onFullscreen?: () => void;
|
|
21
35
|
}) {
|
|
36
|
+
const [isExpanded, setIsExpanded] = useState(() => {
|
|
37
|
+
if (defaultCollapsed === "yes") return false; // Starts collapsed
|
|
38
|
+
if (defaultCollapsed === "no") return true; // Starts expanded
|
|
39
|
+
if (defaultCollapsed === "mobileOnly") return false; // Starts collapsed on mobile, but we'll handle desktop separately
|
|
40
|
+
return true; // Default
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
44
|
+
|
|
45
|
+
const isCollapsibleEnabled = collapsible !== "no";
|
|
46
|
+
|
|
47
|
+
// Prevent body scroll when fullscreen is active
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (isFullscreen) {
|
|
50
|
+
document.body.style.overflow = "hidden";
|
|
51
|
+
return () => {
|
|
52
|
+
document.body.style.overflow = "";
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}, [isFullscreen]);
|
|
56
|
+
|
|
57
|
+
// Check if collapsible behavior should be active (considering mobile-only options)
|
|
58
|
+
const isCollapsibleActive = () => {
|
|
59
|
+
if (collapsible === "no") return false;
|
|
60
|
+
if (collapsible === "mobileOnly") {
|
|
61
|
+
// Only collapsible on mobile - we'll handle this with CSS classes
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
return true; // For "yes"
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Determine what content to show based on collapsible state
|
|
68
|
+
const getContentToShow = () => {
|
|
69
|
+
if (!isCollapsibleEnabled) return children;
|
|
70
|
+
|
|
71
|
+
return isExpanded ? children : summary;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const shouldShowContent = () => {
|
|
75
|
+
if (!isCollapsibleEnabled) return true;
|
|
76
|
+
|
|
77
|
+
// Always show content area if we have either main content or summary
|
|
78
|
+
if (!isExpanded && summary) return true;
|
|
79
|
+
if (isExpanded) return true;
|
|
80
|
+
|
|
81
|
+
return false;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const toggleExpanded = () => {
|
|
85
|
+
if (isCollapsibleActive()) {
|
|
86
|
+
setIsExpanded(!isExpanded);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const handleFullscreen = () => {
|
|
91
|
+
setIsFullscreen(true);
|
|
92
|
+
onFullscreen?.();
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const handleExitFullscreen = () => {
|
|
96
|
+
setIsFullscreen(false);
|
|
97
|
+
};
|
|
98
|
+
|
|
22
99
|
return (
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
100
|
+
<>
|
|
101
|
+
{/* Blurred background overlay - only visible in fullscreen */}
|
|
102
|
+
{isFullscreen && (
|
|
103
|
+
<div
|
|
104
|
+
className="fixed inset-0 z-40 bg-black/20 backdrop-blur-sm md:hidden"
|
|
105
|
+
onClick={handleExitFullscreen}
|
|
106
|
+
/>
|
|
27
107
|
)}
|
|
28
|
-
|
|
29
|
-
<div
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
108
|
+
|
|
109
|
+
<div
|
|
110
|
+
className={cn(
|
|
111
|
+
"flex flex-col rounded-md bg-white transition-all duration-300 ease-in-out",
|
|
112
|
+
className,
|
|
113
|
+
isFullscreen && [
|
|
114
|
+
// Fullscreen styles - only on mobile
|
|
115
|
+
"fixed inset-0 z-50 mx-0 mt-[30px] h-[calc(100vh-60px)] shadow-xl md:relative md:inset-auto md:mx-auto md:mt-0 md:h-auto md:shadow-none",
|
|
116
|
+
],
|
|
117
|
+
)}
|
|
118
|
+
>
|
|
119
|
+
<div
|
|
120
|
+
className={cn(
|
|
121
|
+
"flex flex-col justify-between gap-1 p-4 pb-2 md:p-6",
|
|
122
|
+
isCollapsibleEnabled && "cursor-pointer",
|
|
123
|
+
)}
|
|
124
|
+
onClick={isCollapsibleEnabled ? toggleExpanded : undefined}
|
|
125
|
+
>
|
|
126
|
+
<div className="flex items-center justify-between gap-2">
|
|
127
|
+
<div className="flex items-center gap-2">
|
|
128
|
+
<div className="text-theme-secondary flex h-4 w-4 items-center justify-center rounded-full">
|
|
129
|
+
{icon}
|
|
130
|
+
</div>
|
|
131
|
+
<div className="text-base font-bold text-neutral-800">
|
|
132
|
+
{title}
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
<div className="flex items-center gap-2">
|
|
136
|
+
{/* Fullscreen button - only on mobile */}
|
|
137
|
+
{showFullscreenButton && (
|
|
138
|
+
<button
|
|
139
|
+
onClick={handleFullscreen}
|
|
140
|
+
className={cn(
|
|
141
|
+
"flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700 md:hidden",
|
|
142
|
+
isFullscreen && "hidden",
|
|
143
|
+
)}
|
|
144
|
+
aria-label="Open fullscreen"
|
|
145
|
+
>
|
|
146
|
+
<Expand className="h-4 w-4" />
|
|
147
|
+
</button>
|
|
148
|
+
)}
|
|
149
|
+
|
|
150
|
+
{/* Exit fullscreen button - only visible in fullscreen */}
|
|
151
|
+
{showFullscreenButton && isFullscreen && (
|
|
152
|
+
<button
|
|
153
|
+
onClick={handleExitFullscreen}
|
|
154
|
+
className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700 md:hidden"
|
|
155
|
+
aria-label="Exit fullscreen"
|
|
156
|
+
>
|
|
157
|
+
<Shrink className="h-4 w-4" />
|
|
158
|
+
</button>
|
|
159
|
+
)}
|
|
160
|
+
|
|
161
|
+
{/* Show toggle in header when no summary is provided */}
|
|
162
|
+
{isCollapsibleEnabled && !summary && (
|
|
163
|
+
<>
|
|
164
|
+
{collapsible === "yes" && (
|
|
165
|
+
<button
|
|
166
|
+
onClick={toggleExpanded}
|
|
167
|
+
className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700"
|
|
168
|
+
aria-label={isExpanded ? "Collapse" : "Expand"}
|
|
169
|
+
>
|
|
170
|
+
<svg
|
|
171
|
+
className={cn(
|
|
172
|
+
"h-4 w-4 transition-transform duration-200",
|
|
173
|
+
isExpanded ? "rotate-180" : "rotate-0",
|
|
174
|
+
)}
|
|
175
|
+
fill="none"
|
|
176
|
+
stroke="currentColor"
|
|
177
|
+
viewBox="0 0 24 24"
|
|
178
|
+
>
|
|
179
|
+
<path
|
|
180
|
+
strokeLinecap="round"
|
|
181
|
+
strokeLinejoin="round"
|
|
182
|
+
strokeWidth={2}
|
|
183
|
+
d="M19 9l-7 7-7-7"
|
|
184
|
+
/>
|
|
185
|
+
</svg>
|
|
186
|
+
</button>
|
|
187
|
+
)}
|
|
188
|
+
{collapsible === "mobileOnly" && (
|
|
189
|
+
<button
|
|
190
|
+
onClick={toggleExpanded}
|
|
191
|
+
className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700 md:hidden"
|
|
192
|
+
aria-label={isExpanded ? "Collapse" : "Expand"}
|
|
193
|
+
>
|
|
194
|
+
<svg
|
|
195
|
+
className={cn(
|
|
196
|
+
"h-4 w-4 transition-transform duration-200",
|
|
197
|
+
isExpanded ? "rotate-180" : "rotate-0",
|
|
198
|
+
)}
|
|
199
|
+
fill="none"
|
|
200
|
+
stroke="currentColor"
|
|
201
|
+
viewBox="0 0 24 24"
|
|
202
|
+
>
|
|
203
|
+
<path
|
|
204
|
+
strokeLinecap="round"
|
|
205
|
+
strokeLinejoin="round"
|
|
206
|
+
strokeWidth={2}
|
|
207
|
+
d="M19 9l-7 7-7-7"
|
|
208
|
+
/>
|
|
209
|
+
</svg>
|
|
210
|
+
</button>
|
|
211
|
+
)}
|
|
212
|
+
</>
|
|
213
|
+
)}
|
|
214
|
+
</div>
|
|
33
215
|
</div>
|
|
34
|
-
<div className="
|
|
216
|
+
<div className="mb-1 text-xs text-neutral-500">{description}</div>
|
|
35
217
|
</div>
|
|
36
|
-
<div className="mb-1 text-xs text-neutral-500">{description}</div>
|
|
37
|
-
</div>
|
|
38
218
|
|
|
39
|
-
|
|
40
|
-
|
|
219
|
+
{shouldShowContent() && (
|
|
220
|
+
<div
|
|
221
|
+
className={cn(
|
|
222
|
+
"flex-1 transition-all duration-300 ease-in-out",
|
|
223
|
+
noPadding ? "" : "p-6 pt-0",
|
|
224
|
+
isFullscreen && "overflow-hidden",
|
|
225
|
+
// Handle responsive behavior for mobile-only collapsible options
|
|
226
|
+
collapsible === "mobileOnly" &&
|
|
227
|
+
!isExpanded &&
|
|
228
|
+
summary &&
|
|
229
|
+
"block md:hidden",
|
|
230
|
+
collapsible === "mobileOnly" && isExpanded && "block",
|
|
231
|
+
className,
|
|
232
|
+
)}
|
|
233
|
+
>
|
|
234
|
+
{!isExpanded && summary && isCollapsibleEnabled ? (
|
|
235
|
+
<div className="flex items-start justify-between gap-2">
|
|
236
|
+
<div className="flex-1">{summary}</div>
|
|
237
|
+
{/* Show toggle button next to summary when summary exists */}
|
|
238
|
+
{collapsible === "yes" && (
|
|
239
|
+
<button
|
|
240
|
+
onClick={toggleExpanded}
|
|
241
|
+
className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700"
|
|
242
|
+
aria-label="Expand"
|
|
243
|
+
>
|
|
244
|
+
<svg
|
|
245
|
+
className="h-4 w-4 rotate-0 transition-transform duration-200"
|
|
246
|
+
fill="none"
|
|
247
|
+
stroke="currentColor"
|
|
248
|
+
viewBox="0 0 24 24"
|
|
249
|
+
>
|
|
250
|
+
<path
|
|
251
|
+
strokeLinecap="round"
|
|
252
|
+
strokeLinejoin="round"
|
|
253
|
+
strokeWidth={2}
|
|
254
|
+
d="M19 9l-7 7-7-7"
|
|
255
|
+
/>
|
|
256
|
+
</svg>
|
|
257
|
+
</button>
|
|
258
|
+
)}
|
|
259
|
+
{collapsible === "mobileOnly" && (
|
|
260
|
+
<button
|
|
261
|
+
onClick={toggleExpanded}
|
|
262
|
+
className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700 md:hidden"
|
|
263
|
+
aria-label="Expand"
|
|
264
|
+
>
|
|
265
|
+
<svg
|
|
266
|
+
className="h-4 w-4 rotate-0 transition-transform duration-200"
|
|
267
|
+
fill="none"
|
|
268
|
+
stroke="currentColor"
|
|
269
|
+
viewBox="0 0 24 24"
|
|
270
|
+
>
|
|
271
|
+
<path
|
|
272
|
+
strokeLinecap="round"
|
|
273
|
+
strokeLinejoin="round"
|
|
274
|
+
strokeWidth={2}
|
|
275
|
+
d="M19 9l-7 7-7-7"
|
|
276
|
+
/>
|
|
277
|
+
</svg>
|
|
278
|
+
</button>
|
|
279
|
+
)}
|
|
280
|
+
</div>
|
|
281
|
+
) : (
|
|
282
|
+
<>
|
|
283
|
+
{isExpanded && isCollapsibleEnabled && summary ? (
|
|
284
|
+
<div className="flex items-start justify-between gap-2">
|
|
285
|
+
<div className="flex-1">{children}</div>
|
|
286
|
+
{/* Show toggle button next to content when summary exists */}
|
|
287
|
+
{collapsible === "yes" && (
|
|
288
|
+
<button
|
|
289
|
+
onClick={toggleExpanded}
|
|
290
|
+
className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700"
|
|
291
|
+
aria-label="Collapse"
|
|
292
|
+
>
|
|
293
|
+
<svg
|
|
294
|
+
className="h-4 w-4 rotate-180 transition-transform duration-200"
|
|
295
|
+
fill="none"
|
|
296
|
+
stroke="currentColor"
|
|
297
|
+
viewBox="0 0 24 24"
|
|
298
|
+
>
|
|
299
|
+
<path
|
|
300
|
+
strokeLinecap="round"
|
|
301
|
+
strokeLinejoin="round"
|
|
302
|
+
strokeWidth={2}
|
|
303
|
+
d="M19 9l-7 7-7-7"
|
|
304
|
+
/>
|
|
305
|
+
</svg>
|
|
306
|
+
</button>
|
|
307
|
+
)}
|
|
308
|
+
{collapsible === "mobileOnly" && (
|
|
309
|
+
<button
|
|
310
|
+
onClick={toggleExpanded}
|
|
311
|
+
className="flex-shrink-0 text-neutral-500 transition-colors duration-200 hover:text-neutral-700 md:hidden"
|
|
312
|
+
aria-label="Collapse"
|
|
313
|
+
>
|
|
314
|
+
<svg
|
|
315
|
+
className="h-4 w-4 rotate-180 transition-transform duration-200"
|
|
316
|
+
fill="none"
|
|
317
|
+
stroke="currentColor"
|
|
318
|
+
viewBox="0 0 24 24"
|
|
319
|
+
>
|
|
320
|
+
<path
|
|
321
|
+
strokeLinecap="round"
|
|
322
|
+
strokeLinejoin="round"
|
|
323
|
+
strokeWidth={2}
|
|
324
|
+
d="M19 9l-7 7-7-7"
|
|
325
|
+
/>
|
|
326
|
+
</svg>
|
|
327
|
+
</button>
|
|
328
|
+
)}
|
|
329
|
+
</div>
|
|
330
|
+
) : (
|
|
331
|
+
getContentToShow()
|
|
332
|
+
)}
|
|
333
|
+
</>
|
|
334
|
+
)}
|
|
335
|
+
</div>
|
|
336
|
+
)}
|
|
337
|
+
|
|
338
|
+
{/* Show full content on desktop when using mobile-only collapsible options */}
|
|
339
|
+
{collapsible === "mobileOnly" && (
|
|
340
|
+
<div
|
|
341
|
+
className={cn(
|
|
342
|
+
"hidden flex-1 transition-all duration-300 ease-in-out md:block",
|
|
343
|
+
noPadding ? "" : "p-6 pt-0",
|
|
344
|
+
className,
|
|
345
|
+
)}
|
|
346
|
+
>
|
|
347
|
+
{children}
|
|
348
|
+
</div>
|
|
349
|
+
)}
|
|
350
|
+
|
|
351
|
+
{/* Footer - always displayed regardless of collapsed state */}
|
|
352
|
+
{footer && (
|
|
353
|
+
<div className="border-t border-gray-100 p-4 pt-0 md:p-6 md:pt-0">
|
|
354
|
+
{footer}
|
|
355
|
+
</div>
|
|
356
|
+
)}
|
|
41
357
|
</div>
|
|
42
|
-
|
|
358
|
+
</>
|
|
43
359
|
);
|
|
44
360
|
}
|
package/src/config/config.tsx
CHANGED
|
@@ -94,7 +94,8 @@ import { LayoutStep } from "../page-wizard/steps/LayoutStep";
|
|
|
94
94
|
import { BuildPageStep } from "../page-wizard/steps/BuildPageStep";
|
|
95
95
|
import { SelectStep } from "../page-wizard/steps/SelectStep";
|
|
96
96
|
import { ImagesStep } from "../page-wizard/steps/ImagesStep";
|
|
97
|
-
import {
|
|
97
|
+
import { ContentStep } from "../page-wizard/steps/ContentStep";
|
|
98
|
+
import { SetupPageStep } from "../page-wizard/steps/SetupPageStep";
|
|
98
99
|
import { getWizards } from "../page-wizard/service";
|
|
99
100
|
|
|
100
101
|
import { startPageWizardCommand } from "../page-wizard/startPageWizardCommand";
|
|
@@ -323,7 +324,8 @@ export const getConfiguration = (): EditorConfiguration => {
|
|
|
323
324
|
BuildPageStep,
|
|
324
325
|
SelectStep,
|
|
325
326
|
ImagesStep,
|
|
326
|
-
|
|
327
|
+
ContentStep,
|
|
328
|
+
SetupPageStep,
|
|
327
329
|
},
|
|
328
330
|
},
|
|
329
331
|
|
package/src/config/types.ts
CHANGED
|
@@ -267,11 +267,14 @@ export type TranslationStatus = {
|
|
|
267
267
|
|
|
268
268
|
export interface StepComponentProps {
|
|
269
269
|
step: any;
|
|
270
|
+
|
|
270
271
|
data: WizardData;
|
|
271
272
|
setData: React.Dispatch<React.SetStateAction<WizardData>>;
|
|
272
273
|
wizard: Wizard;
|
|
273
274
|
parentItem?: ItemDescriptor;
|
|
274
275
|
setStepCompleted: (completed: boolean) => void;
|
|
276
|
+
setBeforeNextCallback?: (callback: (() => Promise<boolean>) | null) => void;
|
|
277
|
+
|
|
275
278
|
internalState: any;
|
|
276
279
|
setInternalState: Dispatch<SetStateAction<any>>;
|
|
277
280
|
pageModel: WizardPageModel;
|
|
@@ -51,15 +51,13 @@ export function MobileLayout(props: MainLayoutProps) {
|
|
|
51
51
|
return (
|
|
52
52
|
<div className={cn("flex flex-col select-none", className)}>
|
|
53
53
|
{editContext?.configuration.editor.titlebar}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
</div>
|
|
62
|
-
</div>
|
|
54
|
+
|
|
55
|
+
<Splitter
|
|
56
|
+
panels={panels}
|
|
57
|
+
direction="vertical"
|
|
58
|
+
localStorageKey="mobile-layout-splitter"
|
|
59
|
+
/>
|
|
60
|
+
|
|
63
61
|
{!props.view.hideViewSelector && <ViewSelector />}
|
|
64
62
|
{/* <div className="text-2xs fixed right-0 bottom-0 z-50 flex flex-col rounded-tl-2xl bg-gray-50/70 px-1 pt-1 text-center font-mono text-gray-400">
|
|
65
63
|
<div title={buildDate}>{version}</div>
|
|
@@ -22,10 +22,16 @@ export function PictureEditor({
|
|
|
22
22
|
const editContext = useEditContext();
|
|
23
23
|
|
|
24
24
|
const variant = field.value?.variants?.find((v) => v.name === variantName);
|
|
25
|
-
const raw =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
const raw = (() => {
|
|
26
|
+
try {
|
|
27
|
+
return field?.rawValue && field?.rawValue[0] === "{"
|
|
28
|
+
? (JSON.parse(field?.rawValue) as PictureRawValue)
|
|
29
|
+
: ({ Variants: [] } as PictureRawValue);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.warn("Failed to parse picture field raw value:", error);
|
|
32
|
+
return { Variants: [] } as PictureRawValue;
|
|
33
|
+
}
|
|
34
|
+
})();
|
|
29
35
|
|
|
30
36
|
const rawVariant = raw.Variants?.find((x) => x.Name == variantName);
|
|
31
37
|
|
|
@@ -57,7 +63,7 @@ export function PictureEditor({
|
|
|
57
63
|
refresh: "immediate",
|
|
58
64
|
});
|
|
59
65
|
},
|
|
60
|
-
[field, variant]
|
|
66
|
+
[field, variant],
|
|
61
67
|
);
|
|
62
68
|
|
|
63
69
|
const videoSelected = useCallback(
|
|
@@ -79,7 +85,7 @@ export function PictureEditor({
|
|
|
79
85
|
refresh: "immediate",
|
|
80
86
|
});
|
|
81
87
|
},
|
|
82
|
-
[field, variant]
|
|
88
|
+
[field, variant],
|
|
83
89
|
);
|
|
84
90
|
|
|
85
91
|
async function selectMedia(mode: MediaSelectorMode) {
|
|
@@ -117,21 +123,21 @@ export function PictureEditor({
|
|
|
117
123
|
behavior: "instant",
|
|
118
124
|
left: 0,
|
|
119
125
|
top: e.deltaY,
|
|
120
|
-
}
|
|
126
|
+
},
|
|
121
127
|
);
|
|
122
128
|
editContext?.pageView.editorIframeRef!.current?.contentWindow?.document.body?.scrollBy(
|
|
123
129
|
{
|
|
124
130
|
behavior: "instant",
|
|
125
131
|
left: 0,
|
|
126
132
|
top: e.deltaY,
|
|
127
|
-
}
|
|
133
|
+
},
|
|
128
134
|
);
|
|
129
135
|
}}
|
|
130
136
|
style={style}
|
|
131
137
|
data-testid="select-media"
|
|
132
138
|
>
|
|
133
139
|
{showMenu && (
|
|
134
|
-
<div className="
|
|
140
|
+
<div className="grid min-w-48 grid-cols-2 items-stretch justify-center gap-1.5 p-3 text-sm">
|
|
135
141
|
<Btn
|
|
136
142
|
label="Select"
|
|
137
143
|
icon="pi pi-image"
|
|
@@ -196,7 +202,7 @@ function Btn({
|
|
|
196
202
|
}) {
|
|
197
203
|
return (
|
|
198
204
|
<button
|
|
199
|
-
className={`btn
|
|
205
|
+
className={`btn flex cursor-pointer items-center gap-1.5 rounded-lg border bg-gray-500 p-1.5 text-white opacity-70 hover:opacity-85 ${className}`}
|
|
200
206
|
onClick={onClick}
|
|
201
207
|
data-testid={testId}
|
|
202
208
|
>
|
|
@@ -555,7 +555,7 @@ export function EditorClient({
|
|
|
555
555
|
message: msg,
|
|
556
556
|
label: label,
|
|
557
557
|
};
|
|
558
|
-
console.log(newAction);
|
|
558
|
+
// console.log(newAction);
|
|
559
559
|
return [...x, newAction];
|
|
560
560
|
}
|
|
561
561
|
});
|
|
@@ -1489,16 +1489,14 @@ export function EditorClient({
|
|
|
1489
1489
|
const result = await currentView.beforeClose(editContext);
|
|
1490
1490
|
if (!result) return;
|
|
1491
1491
|
}
|
|
1492
|
-
if (typeof document.startViewTransition ===
|
|
1492
|
+
if (typeof document.startViewTransition === "function") {
|
|
1493
1493
|
document.startViewTransition(() => {
|
|
1494
1494
|
flushSync(() => {
|
|
1495
1495
|
setViewName(viewName);
|
|
1496
1496
|
});
|
|
1497
1497
|
});
|
|
1498
1498
|
} else {
|
|
1499
|
-
|
|
1500
|
-
setViewName(viewName);
|
|
1501
|
-
|
|
1499
|
+
setViewName(viewName);
|
|
1502
1500
|
}
|
|
1503
1501
|
}
|
|
1504
1502
|
switchView();
|
|
@@ -51,7 +51,11 @@ import { ItemsRepository } from "./itemsRepository";
|
|
|
51
51
|
import { MediaSelectorMode } from "../media-selector/MediaSelector";
|
|
52
52
|
import { ComponentCommand } from "../commands/componentCommands";
|
|
53
53
|
import { AiTerminalOptions } from "../ai/AiTerminal";
|
|
54
|
-
import {
|
|
54
|
+
import {
|
|
55
|
+
Wizard,
|
|
56
|
+
WizardData,
|
|
57
|
+
WizardPageModel,
|
|
58
|
+
} from "../../page-wizard/PageWizard";
|
|
55
59
|
export type DragObject = {
|
|
56
60
|
type: "template" | "component" | "link-component" | "items";
|
|
57
61
|
typeId: string;
|
|
@@ -322,6 +326,24 @@ export type EditContextType = {
|
|
|
322
326
|
setParentItem: React.Dispatch<
|
|
323
327
|
React.SetStateAction<ItemDescriptor | undefined>
|
|
324
328
|
>;
|
|
329
|
+
// Wizard step state
|
|
330
|
+
currentStepIndex: number;
|
|
331
|
+
setCurrentStepIndex: React.Dispatch<React.SetStateAction<number>>;
|
|
332
|
+
data: WizardData;
|
|
333
|
+
setData: React.Dispatch<React.SetStateAction<WizardData>>;
|
|
334
|
+
pageModel: WizardPageModel;
|
|
335
|
+
setPageModel: React.Dispatch<React.SetStateAction<WizardPageModel>>;
|
|
336
|
+
internalState: any;
|
|
337
|
+
setInternalState: React.Dispatch<React.SetStateAction<any>>;
|
|
338
|
+
stepCompleted: number;
|
|
339
|
+
setStepCompleted: React.Dispatch<React.SetStateAction<number>>;
|
|
340
|
+
pageItem: ItemDescriptor | undefined;
|
|
341
|
+
setPageItem: React.Dispatch<
|
|
342
|
+
React.SetStateAction<ItemDescriptor | undefined>
|
|
343
|
+
>;
|
|
344
|
+
beforeNextCallbackRef: React.MutableRefObject<
|
|
345
|
+
(() => Promise<boolean>) | null
|
|
346
|
+
>;
|
|
325
347
|
};
|
|
326
348
|
|
|
327
349
|
webSocketMessages: WebSocketMessage[];
|
|
@@ -93,7 +93,7 @@ export function getOperationsContext(
|
|
|
93
93
|
console.log("Executing op", op);
|
|
94
94
|
setExecutingEditOperations((ops) => (ops ? [...ops, op] : [op]));
|
|
95
95
|
const result = await executeEditOperation(op, state.sessionId);
|
|
96
|
-
console.log("Result", result);
|
|
96
|
+
// console.log("Result", result);
|
|
97
97
|
handleResult(result, options);
|
|
98
98
|
await state.refreshHistory(op.mainItem);
|
|
99
99
|
//state.addToEditHistory(result.data as EditOperation);
|
|
@@ -103,7 +103,12 @@ export function CommentHighlighting({
|
|
|
103
103
|
|
|
104
104
|
if (!rects || rects.length === 0) {
|
|
105
105
|
let fallbackElement = fieldElement;
|
|
106
|
-
if (
|
|
106
|
+
if (
|
|
107
|
+
!fallbackElement &&
|
|
108
|
+
comment.itemId &&
|
|
109
|
+
editContext.page &&
|
|
110
|
+
iframe.contentWindow?.document.body
|
|
111
|
+
) {
|
|
107
112
|
const componentStart = iframe.contentWindow?.document.body.querySelector(
|
|
108
113
|
"[data-component-start='" + comment.itemId + "']",
|
|
109
114
|
);
|
|
@@ -260,7 +260,16 @@ export const Splitter: React.FC<SplitterProps> = ({
|
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
}}
|
|
263
|
-
|
|
263
|
+
>
|
|
264
|
+
{/* Visual indicator line for mobile splitters */}
|
|
265
|
+
<div
|
|
266
|
+
className={`${
|
|
267
|
+
isHorizontal
|
|
268
|
+
? "h-8 w-[2px] bg-gray-500 md:hidden"
|
|
269
|
+
: "h-[2px] w-8 bg-gray-500 md:hidden"
|
|
270
|
+
}`}
|
|
271
|
+
/>
|
|
272
|
+
</div>
|
|
264
273
|
);
|
|
265
274
|
};
|
|
266
275
|
|