@alpaca-editor/core 1.0.3903 → 1.0.3905
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/editContext.d.ts +14 -1
- package/dist/editor/client/editContext.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 +62 -16
- 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 +182 -63
- 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/editContext.ts +23 -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 +161 -32
- 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 -236
- 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
|
>
|
|
@@ -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[];
|
|
@@ -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
|
|
|
@@ -1,21 +1,56 @@
|
|
|
1
1
|
import { cn } from "../lib/utils";
|
|
2
2
|
|
|
3
|
-
export function WizardBoxConnector({
|
|
3
|
+
export function WizardBoxConnector({
|
|
4
|
+
className,
|
|
5
|
+
direction,
|
|
6
|
+
}: {
|
|
7
|
+
className?: string;
|
|
8
|
+
direction?: "horizontal" | "vertical";
|
|
9
|
+
}) {
|
|
4
10
|
return (
|
|
5
|
-
|
|
6
|
-
<
|
|
7
|
-
className={
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
<>
|
|
12
|
+
<div
|
|
13
|
+
className={cn(
|
|
14
|
+
"mt-[-3px] mb-[-3px] flex items-center justify-center",
|
|
15
|
+
className,
|
|
16
|
+
(!direction || direction === "horizontal") && "md:hidden",
|
|
17
|
+
)}
|
|
13
18
|
>
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
<svg
|
|
20
|
+
width="40"
|
|
21
|
+
height="31"
|
|
22
|
+
viewBox="0 0 40 31"
|
|
23
|
+
fill="none"
|
|
24
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
25
|
+
>
|
|
26
|
+
<path
|
|
27
|
+
d="M40 3.04199C33.8405 3.55018 29 8.70936 29 15C29 21.2906 33.8405 26.4498 40 26.958L40 31L-1.35505e-06 31L-1.18021e-06 27C6.62741 27 12 21.6274 12 15C12 8.37258 6.62741 3 -1.31134e-07 3L0 -1.74846e-06L40 0L40 3.04199Z"
|
|
28
|
+
fill="white"
|
|
29
|
+
/>
|
|
30
|
+
</svg>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div
|
|
34
|
+
className={cn(
|
|
35
|
+
"mt-6 mr-[-3px] ml-[-3px] hidden",
|
|
36
|
+
className,
|
|
37
|
+
(!direction || direction === "horizontal") && "md:block",
|
|
38
|
+
)}
|
|
39
|
+
>
|
|
40
|
+
<svg
|
|
41
|
+
className={className}
|
|
42
|
+
width="31"
|
|
43
|
+
height="40"
|
|
44
|
+
viewBox="0 0 31 40"
|
|
45
|
+
fill="none"
|
|
46
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
47
|
+
>
|
|
48
|
+
<path
|
|
49
|
+
d="M3.04199 0C3.55018 6.15949 8.70936 11 15 11C21.2906 11 26.4498 6.1595 26.958 0H31V40H27C27 33.3726 21.6274 28 15 28C8.37258 28 3 33.3726 3 40H0V0H3.04199Z"
|
|
50
|
+
fill="white"
|
|
51
|
+
/>
|
|
52
|
+
</svg>
|
|
53
|
+
</div>
|
|
54
|
+
</>
|
|
20
55
|
);
|
|
21
56
|
}
|