@alpaca-editor/core 1.0.3955 → 1.0.3959
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/build.css +1 -1
- package/dist/components/ui/badge.d.ts +9 -0
- package/dist/components/ui/badge.js +23 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/button.js +3 -3
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/command.d.ts +18 -0
- package/dist/components/ui/command.js +35 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +15 -0
- package/dist/components/ui/dialog.js +37 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +25 -0
- package/dist/components/ui/dropdown-menu.js +52 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/input.d.ts +3 -0
- package/dist/components/ui/input.js +7 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/menubar.d.ts +26 -0
- package/dist/components/ui/menubar.js +55 -0
- package/dist/components/ui/menubar.js.map +1 -0
- package/dist/components/ui/popover.d.ts +9 -0
- package/dist/components/ui/popover.js +63 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/switch.d.ts +4 -0
- package/dist/components/ui/switch.js +9 -0
- package/dist/components/ui/switch.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +7 -0
- package/dist/components/ui/tooltip.js +18 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/config/config.js +79 -63
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +3 -3
- package/dist/editor/ContentTree.js +1 -1
- package/dist/editor/ContentTree.js.map +1 -1
- package/dist/editor/Editor.js +6 -2
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/FieldList.js +1 -1
- package/dist/editor/FieldList.js.map +1 -1
- package/dist/editor/FieldListField.js +1 -1
- package/dist/editor/FieldListField.js.map +1 -1
- package/dist/editor/ImageEditor.js +16 -6
- package/dist/editor/ImageEditor.js.map +1 -1
- package/dist/editor/MainLayout.js +4 -4
- package/dist/editor/MainLayout.js.map +1 -1
- package/dist/editor/MobileLayout.js +3 -3
- package/dist/editor/MobileLayout.js.map +1 -1
- package/dist/editor/PictureEditor.js +29 -15
- package/dist/editor/PictureEditor.js.map +1 -1
- package/dist/editor/Titlebar.js +6 -11
- package/dist/editor/Titlebar.js.map +1 -1
- package/dist/editor/ai/GhostWriter.js +1 -1
- package/dist/editor/ai/GhostWriter.js.map +1 -1
- package/dist/editor/client/EditorClient.d.ts +4 -2
- package/dist/editor/client/EditorClient.js +32 -11
- package/dist/editor/client/EditorClient.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +4 -1
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/operations.js +2 -2
- package/dist/editor/client/pageModelBuilder.js +3 -6
- package/dist/editor/client/pageModelBuilder.js.map +1 -1
- package/dist/editor/commands/itemCommands.d.ts +2 -0
- package/dist/editor/commands/itemCommands.js +180 -0
- package/dist/editor/commands/itemCommands.js.map +1 -1
- package/dist/editor/field-types/MultiLineText.js +1 -1
- package/dist/editor/field-types/MultiLineText.js.map +1 -1
- package/dist/editor/field-types/SingleLineText.js +1 -1
- package/dist/editor/field-types/SingleLineText.js.map +1 -1
- package/dist/editor/menubar/ActiveUsers.js +98 -4
- package/dist/editor/menubar/ActiveUsers.js.map +1 -1
- package/dist/editor/menubar/{ActionsMenu.d.ts → ItemActionsMenu.d.ts} +1 -1
- package/dist/editor/menubar/ItemActionsMenu.js +23 -0
- package/dist/editor/menubar/ItemActionsMenu.js.map +1 -0
- package/dist/editor/menubar/ItemLanguageVersion.js +2 -2
- package/dist/editor/menubar/ItemLanguageVersion.js.map +1 -1
- package/dist/editor/menubar/LanguageSelector.d.ts +1 -2
- package/dist/editor/menubar/LanguageSelector.js +23 -23
- package/dist/editor/menubar/LanguageSelector.js.map +1 -1
- package/dist/editor/menubar/PageSelector.js +7 -8
- package/dist/editor/menubar/PageSelector.js.map +1 -1
- package/dist/editor/menubar/PageViewerControls.js +22 -19
- package/dist/editor/menubar/PageViewerControls.js.map +1 -1
- package/dist/editor/menubar/PreviewSecondaryControls.js +2 -3
- package/dist/editor/menubar/PreviewSecondaryControls.js.map +1 -1
- package/dist/editor/menubar/User.js +1 -1
- package/dist/editor/menubar/User.js.map +1 -1
- package/dist/editor/menubar/VersionSelector.js +36 -31
- package/dist/editor/menubar/VersionSelector.js.map +1 -1
- package/dist/editor/menubar/WorkflowButton.d.ts +1 -0
- package/dist/editor/menubar/WorkflowButton.js +41 -0
- package/dist/editor/menubar/WorkflowButton.js.map +1 -0
- package/dist/editor/page-editor-chrome/FrameMenu.js +5 -5
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/SuggestionHighlightings.js +2 -2
- package/dist/editor/page-editor-chrome/SuggestionHighlightings.js.map +1 -1
- package/dist/editor/page-viewer/EditorForm.d.ts +2 -1
- package/dist/editor/page-viewer/EditorForm.js +61 -49
- package/dist/editor/page-viewer/EditorForm.js.map +1 -1
- package/dist/editor/page-viewer/PageViewer.d.ts +2 -1
- package/dist/editor/page-viewer/PageViewer.js +28 -44
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/reviews/Comments.js +9 -9
- package/dist/editor/reviews/Comments.js.map +1 -1
- package/dist/editor/reviews/SuggestedEdit.js +3 -3
- package/dist/editor/services/contentService.d.ts +18 -0
- package/dist/editor/services/contentService.js +6 -0
- package/dist/editor/services/contentService.js.map +1 -1
- package/dist/editor/services/editService.d.ts +5 -0
- package/dist/editor/services/editService.js +4 -0
- package/dist/editor/services/editService.js.map +1 -1
- package/dist/editor/services/systemService.d.ts +2 -1
- package/dist/editor/services/systemService.js +4 -1
- package/dist/editor/services/systemService.js.map +1 -1
- package/dist/editor/sidebar/ComponentTree.js +26 -10
- package/dist/editor/sidebar/ComponentTree.js.map +1 -1
- package/dist/editor/sidebar/Divider.d.ts +6 -0
- package/dist/editor/sidebar/Divider.js +6 -0
- package/dist/editor/sidebar/Divider.js.map +1 -0
- package/dist/editor/sidebar/LeftToolbar.d.ts +1 -0
- package/dist/editor/sidebar/LeftToolbar.js +16 -0
- package/dist/editor/sidebar/LeftToolbar.js.map +1 -0
- package/dist/editor/sidebar/SEOInfo.d.ts +1 -0
- package/dist/editor/sidebar/SEOInfo.js +169 -0
- package/dist/editor/sidebar/SEOInfo.js.map +1 -0
- package/dist/editor/sidebar/Sidebar.js +1 -1
- package/dist/editor/sidebar/Sidebar.js.map +1 -1
- package/dist/editor/sidebar/SidebarView.d.ts +3 -2
- package/dist/editor/sidebar/SidebarView.js +22 -60
- package/dist/editor/sidebar/SidebarView.js.map +1 -1
- package/dist/editor/sidebar/ViewSelector.js +66 -20
- package/dist/editor/sidebar/ViewSelector.js.map +1 -1
- package/dist/editor/ui/Icons.d.ts +4 -0
- package/dist/editor/ui/Icons.js +15 -3
- package/dist/editor/ui/Icons.js.map +1 -1
- package/dist/editor/ui/Section.js +1 -1
- package/dist/editor/ui/Section.js.map +1 -1
- package/dist/editor/ui/SimpleIconButton.d.ts +1 -2
- package/dist/editor/ui/SimpleIconButton.js +8 -13
- package/dist/editor/ui/SimpleIconButton.js.map +1 -1
- package/dist/editor/ui/SimpleTabs.js +2 -2
- package/dist/editor/ui/SimpleTabs.js.map +1 -1
- package/dist/editor/ui/SimpleToolbar.js +1 -1
- package/dist/editor/ui/SimpleToolbar.js.map +1 -1
- package/dist/editor/ui/Splitter.d.ts +4 -0
- package/dist/editor/ui/Splitter.js +6 -7
- package/dist/editor/ui/Splitter.js.map +1 -1
- package/dist/editor/views/CompareView.js +16 -4
- package/dist/editor/views/CompareView.js.map +1 -1
- package/dist/editor/views/SingleEditView.d.ts +2 -1
- package/dist/editor/views/SingleEditView.js +2 -2
- package/dist/editor/views/SingleEditView.js.map +1 -1
- package/dist/page-wizard/steps/ContentStep.js +1 -1
- package/dist/page-wizard/steps/ContentStep.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/splash-screen/NewPage.js +8 -6
- package/dist/splash-screen/NewPage.js.map +1 -1
- package/dist/splash-screen/RecentPages.js +3 -8
- package/dist/splash-screen/RecentPages.js.map +1 -1
- package/dist/styles.css +1519 -543
- package/dist/tour/Tour.js +79 -10
- package/dist/tour/Tour.js.map +1 -1
- package/dist/tour/default-tour.js +55 -45
- package/dist/tour/default-tour.js.map +1 -1
- package/dist/types.d.ts +19 -1
- package/package.json +13 -5
- package/src/components/ui/badge.tsx +46 -0
- package/src/components/ui/button.tsx +3 -3
- package/src/components/ui/command.tsx +184 -0
- package/src/components/ui/dialog.tsx +143 -0
- package/src/components/ui/dropdown-menu.tsx +257 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/menubar.tsx +276 -0
- package/src/components/ui/popover.tsx +113 -0
- package/src/components/ui/switch.tsx +31 -0
- package/src/components/ui/tooltip.tsx +61 -0
- package/src/config/config.tsx +102 -65
- package/src/config/types.ts +3 -3
- package/src/editor/ContentTree.tsx +1 -1
- package/src/editor/Editor.tsx +8 -2
- package/src/editor/FieldList.tsx +2 -2
- package/src/editor/FieldListField.tsx +1 -1
- package/src/editor/ImageEditor.tsx +44 -21
- package/src/editor/MainLayout.tsx +21 -16
- package/src/editor/MobileLayout.tsx +3 -2
- package/src/editor/PictureEditor.tsx +74 -45
- package/src/editor/Titlebar.tsx +12 -24
- package/src/editor/ai/GhostWriter.tsx +1 -1
- package/src/editor/client/EditorClient.tsx +55 -13
- package/src/editor/client/editContext.ts +5 -0
- package/src/editor/client/operations.ts +2 -2
- package/src/editor/client/pageModelBuilder.ts +3 -7
- package/src/editor/commands/itemCommands.tsx +272 -0
- package/src/editor/field-types/MultiLineText.tsx +1 -1
- package/src/editor/field-types/SingleLineText.tsx +1 -1
- package/src/editor/menubar/ActiveUsers.tsx +271 -5
- package/src/editor/menubar/ItemActionsMenu.tsx +89 -0
- package/src/editor/menubar/ItemLanguageVersion.tsx +7 -5
- package/src/editor/menubar/LanguageSelector.tsx +105 -134
- package/src/editor/menubar/PageSelector.tsx +25 -27
- package/src/editor/menubar/PageViewerControls.tsx +126 -78
- package/src/editor/menubar/PreviewSecondaryControls.tsx +0 -2
- package/src/editor/menubar/User.tsx +2 -2
- package/src/editor/menubar/VersionSelector.tsx +124 -99
- package/src/editor/menubar/WorkflowButton.tsx +115 -0
- package/src/editor/page-editor-chrome/FrameMenu.tsx +5 -5
- package/src/editor/page-editor-chrome/SuggestionHighlightings.tsx +2 -2
- package/src/editor/page-viewer/EditorForm.tsx +112 -87
- package/src/editor/page-viewer/PageViewer.tsx +75 -92
- package/src/editor/page-viewer/PageViewerFrame.tsx +1 -1
- package/src/editor/reviews/Comments.tsx +19 -20
- package/src/editor/reviews/SuggestedEdit.tsx +3 -3
- package/src/editor/services/contentService.ts +28 -0
- package/src/editor/services/editService.ts +12 -0
- package/src/editor/services/systemService.ts +5 -2
- package/src/editor/sidebar/ComponentTree.tsx +34 -12
- package/src/editor/sidebar/Divider.tsx +22 -0
- package/src/editor/sidebar/LeftToolbar.tsx +36 -0
- package/src/editor/sidebar/SEOInfo.tsx +265 -0
- package/src/editor/sidebar/Sidebar.tsx +1 -0
- package/src/editor/sidebar/SidebarView.tsx +77 -111
- package/src/editor/sidebar/ViewSelector.tsx +211 -43
- package/src/editor/ui/Icons.tsx +155 -10
- package/src/editor/ui/Section.tsx +1 -1
- package/src/editor/ui/SimpleIconButton.tsx +30 -28
- package/src/editor/ui/SimpleTabs.tsx +3 -3
- package/src/editor/ui/SimpleToolbar.tsx +1 -1
- package/src/editor/ui/Splitter.tsx +14 -7
- package/src/editor/views/CompareView.tsx +23 -11
- package/src/editor/views/SingleEditView.tsx +3 -0
- package/src/page-wizard/steps/ContentStep.tsx +0 -1
- package/src/revision.ts +2 -2
- package/src/splash-screen/NewPage.tsx +18 -13
- package/src/splash-screen/RecentPages.tsx +4 -10
- package/src/tour/Tour.tsx +125 -34
- package/src/tour/default-tour.tsx +55 -45
- package/src/types.ts +21 -1
- package/styles.css +301 -1
- package/dist/editor/menubar/ActionsMenu.js +0 -49
- package/dist/editor/menubar/ActionsMenu.js.map +0 -1
- package/dist/editor/menubar/SecondaryControls.d.ts +0 -1
- package/dist/editor/menubar/SecondaryControls.js +0 -17
- package/dist/editor/menubar/SecondaryControls.js.map +0 -1
- package/src/editor/menubar/ActionsMenu.tsx +0 -94
- package/src/editor/menubar/SecondaryControls.tsx +0 -45
package/src/tour/Tour.tsx
CHANGED
|
@@ -9,6 +9,7 @@ import { ActionButton } from "../components/ActionButton";
|
|
|
9
9
|
export function Tour({ tourStopCallback }: { tourStopCallback: () => void }) {
|
|
10
10
|
const [currentStep, setCurrentStep] = useState<string>("start-tour");
|
|
11
11
|
const [show, setShow] = useState(true);
|
|
12
|
+
const [bubbleVisible, setBubbleVisible] = useState(true);
|
|
12
13
|
const editContext = useEditContext();
|
|
13
14
|
const [focusRect, setFocusRect] = useState<DOMRect | null>(null);
|
|
14
15
|
const [pointToRect, setPointToRect] = useState<DOMRect | null>(null);
|
|
@@ -36,7 +37,6 @@ export function Tour({ tourStopCallback }: { tourStopCallback: () => void }) {
|
|
|
36
37
|
rect.width + extendFocus,
|
|
37
38
|
rect.height + extendFocus,
|
|
38
39
|
);
|
|
39
|
-
|
|
40
40
|
resolve(rect);
|
|
41
41
|
} else if (timeout > 0 && Date.now() - startTime >= timeout) {
|
|
42
42
|
resolve(undefined);
|
|
@@ -178,6 +178,16 @@ export function Tour({ tourStopCallback }: { tourStopCallback: () => void }) {
|
|
|
178
178
|
await delay(randomDelay);
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* Animated step change with fade out/in transition
|
|
183
|
+
*/
|
|
184
|
+
const animatedStepChange = async (newStepId: string) => {
|
|
185
|
+
setBubbleVisible(false); // Fade out
|
|
186
|
+
await delay(200); // Wait for fade out
|
|
187
|
+
setCurrentStep(newStepId); // Change content
|
|
188
|
+
await delay(50); // Small delay
|
|
189
|
+
setBubbleVisible(true); // Fade in
|
|
190
|
+
};
|
|
181
191
|
|
|
182
192
|
/**
|
|
183
193
|
* Stops the tour and resets the state.
|
|
@@ -191,10 +201,9 @@ export function Tour({ tourStopCallback }: { tourStopCallback: () => void }) {
|
|
|
191
201
|
const tours = editContext!.configuration.tours;
|
|
192
202
|
const tour =
|
|
193
203
|
tours[editContext!.configuration.activeTour as keyof typeof tours];
|
|
194
|
-
|
|
195
204
|
const tourSteps = tour.getSteps({
|
|
196
205
|
editContext: editContext as EditContextType,
|
|
197
|
-
nextStep: (stepId) =>
|
|
206
|
+
nextStep: (stepId) => animatedStepChange(stepId),
|
|
198
207
|
stopTour: () => tourStopCallback(),
|
|
199
208
|
waitForElement,
|
|
200
209
|
waitForElementToDisappear,
|
|
@@ -224,22 +233,20 @@ export function Tour({ tourStopCallback }: { tourStopCallback: () => void }) {
|
|
|
224
233
|
|
|
225
234
|
if (step.focusElement) {
|
|
226
235
|
const rect = await waitForElement(step.focusElement, 5000);
|
|
227
|
-
if (!rect)
|
|
236
|
+
if (!rect) animatedStepChange("error");
|
|
228
237
|
else setFocusRect(rect);
|
|
229
238
|
}
|
|
230
239
|
|
|
231
|
-
setShow(true);
|
|
232
|
-
|
|
233
|
-
if (step.waitForUserInput) {
|
|
240
|
+
setShow(true); if (step.waitForUserInput) {
|
|
234
241
|
const nextStep = (await step.waitForUserInput()) || step.nextStep;
|
|
235
242
|
if (nextStep) {
|
|
236
|
-
|
|
243
|
+
animatedStepChange(nextStep);
|
|
237
244
|
} else console.log("no next step defined for step", currentStep);
|
|
238
245
|
} else {
|
|
239
246
|
if (step.waitForElement) {
|
|
240
247
|
await waitForElement(step.waitForElement);
|
|
241
248
|
if (step.nextStep) {
|
|
242
|
-
|
|
249
|
+
animatedStepChange(step.nextStep);
|
|
243
250
|
}
|
|
244
251
|
}
|
|
245
252
|
}
|
|
@@ -274,8 +281,23 @@ export function Tour({ tourStopCallback }: { tourStopCallback: () => void }) {
|
|
|
274
281
|
if (!step) {
|
|
275
282
|
throw new Error(`Tour step ${currentStep} not found`);
|
|
276
283
|
}
|
|
277
|
-
|
|
278
|
-
const
|
|
284
|
+
// On mobile, always use bottom or top positioning for better UX
|
|
285
|
+
const isMobile = window.innerWidth < 768;
|
|
286
|
+
let bubblePosition: "left" | "right" | "bottom" | "top-right" = step.bubblePosition as
|
|
287
|
+
| "left"
|
|
288
|
+
| "right"
|
|
289
|
+
| "bottom"
|
|
290
|
+
| "top-right"
|
|
291
|
+
|| "right";
|
|
292
|
+
|
|
293
|
+
if (isMobile) {
|
|
294
|
+
// On mobile, prefer bottom positioning, but use top if element is in bottom half of screen
|
|
295
|
+
if (pointToRect && pointToRect.top > window.innerHeight / 2) {
|
|
296
|
+
bubblePosition = "top-right"; // We'll use top-right but modify it for mobile
|
|
297
|
+
} else {
|
|
298
|
+
bubblePosition = "bottom";
|
|
299
|
+
}
|
|
300
|
+
}
|
|
279
301
|
const bubbleStyle: React.CSSProperties = {};
|
|
280
302
|
|
|
281
303
|
let boxStyle: React.CSSProperties = {
|
|
@@ -312,12 +334,12 @@ export function Tour({ tourStopCallback }: { tourStopCallback: () => void }) {
|
|
|
312
334
|
arrowStyle = {
|
|
313
335
|
marginRight: "-20px",
|
|
314
336
|
};
|
|
315
|
-
}
|
|
316
|
-
|
|
337
|
+
}
|
|
338
|
+
|
|
317
339
|
if (bubblePosition === "bottom") {
|
|
318
340
|
boxStyle = {
|
|
319
341
|
position: "absolute",
|
|
320
|
-
left: pointToRect.left + pointToRect.width / 2,
|
|
342
|
+
left: isMobile ? "50%" : pointToRect.left + pointToRect.width / 2,
|
|
321
343
|
top: pointToRect.top + pointToRect.height,
|
|
322
344
|
transform: "translate(-50%, 0)",
|
|
323
345
|
};
|
|
@@ -331,7 +353,7 @@ export function Tour({ tourStopCallback }: { tourStopCallback: () => void }) {
|
|
|
331
353
|
if (bubblePosition === "top-right") {
|
|
332
354
|
boxStyle = {
|
|
333
355
|
position: "absolute",
|
|
334
|
-
left: pointToRect.left + pointToRect.width,
|
|
356
|
+
left: isMobile ? "50%" : pointToRect.left + pointToRect.width,
|
|
335
357
|
bottom: window.innerHeight - pointToRect.top,
|
|
336
358
|
transform: "translate(-50%, 0)",
|
|
337
359
|
flexDirection: "column-reverse",
|
|
@@ -344,11 +366,60 @@ export function Tour({ tourStopCallback }: { tourStopCallback: () => void }) {
|
|
|
344
366
|
arrowStyle = {
|
|
345
367
|
transform: "scaleX(-1)",
|
|
346
368
|
};
|
|
369
|
+
} }
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Viewport correction: ensure bubble stays within screen bounds
|
|
373
|
+
const getCorrectedBoxStyle = (style: React.CSSProperties): React.CSSProperties => {
|
|
374
|
+
if (!pointToRect) return style;
|
|
375
|
+
|
|
376
|
+
const correctedStyle = { ...style };
|
|
377
|
+
const margin = 10; // Small margin from screen edges
|
|
378
|
+
|
|
379
|
+
// For absolute positioning, check if bubble would be outside viewport
|
|
380
|
+
if (correctedStyle.position === 'absolute') {
|
|
381
|
+
// If bubble would be too far down, move it up (can overlap with target element)
|
|
382
|
+
if (typeof correctedStyle.top === 'number') {
|
|
383
|
+
const maxTop = window.innerHeight - 250; // Reserve 250px for bubble height
|
|
384
|
+
if (correctedStyle.top > maxTop) {
|
|
385
|
+
correctedStyle.top = Math.max(margin, maxTop);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// If bubble would be too far right, move it left
|
|
390
|
+
if (typeof correctedStyle.left === 'number') {
|
|
391
|
+
const bubbleWidth = isMobile ? window.innerWidth * 0.95 : 500;
|
|
392
|
+
const maxLeft = window.innerWidth - bubbleWidth - margin;
|
|
393
|
+
if (correctedStyle.left > maxLeft) {
|
|
394
|
+
correctedStyle.left = Math.max(margin, maxLeft);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Handle right positioning
|
|
399
|
+
if (typeof correctedStyle.right === 'number') {
|
|
400
|
+
const bubbleWidth = isMobile ? window.innerWidth * 0.95 : 500;
|
|
401
|
+
if (correctedStyle.right > window.innerWidth - bubbleWidth - margin) {
|
|
402
|
+
correctedStyle.right = margin;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// Handle bottom positioning - if too high, place at bottom of screen
|
|
407
|
+
if (typeof correctedStyle.bottom === 'number') {
|
|
408
|
+
const maxBottom = window.innerHeight - 250;
|
|
409
|
+
if (correctedStyle.bottom > maxBottom) {
|
|
410
|
+
delete correctedStyle.bottom;
|
|
411
|
+
correctedStyle.top = window.innerHeight - 200 - margin; // Place near bottom
|
|
412
|
+
}
|
|
347
413
|
}
|
|
348
414
|
}
|
|
349
|
-
|
|
415
|
+
|
|
416
|
+
return correctedStyle;
|
|
417
|
+
};
|
|
350
418
|
|
|
351
|
-
|
|
419
|
+
// Apply viewport correction
|
|
420
|
+
boxStyle = getCorrectedBoxStyle(boxStyle);
|
|
421
|
+
|
|
422
|
+
const arrowRotation = bubblePosition === "right" ? "-rotate-90" : "";
|
|
352
423
|
|
|
353
424
|
const overlayStyle: React.CSSProperties = {
|
|
354
425
|
position: "fixed",
|
|
@@ -358,6 +429,7 @@ export function Tour({ tourStopCallback }: { tourStopCallback: () => void }) {
|
|
|
358
429
|
height: "100%",
|
|
359
430
|
backgroundColor: "rgba(0, 0, 0, 0.3)",
|
|
360
431
|
pointerEvents: "auto",
|
|
432
|
+
transition: "all 0.2s ease-in-out",
|
|
361
433
|
clipPath: focusRect
|
|
362
434
|
? `polygon(0% 0%, 0% 100%, ${focusRect.left}px 100%, ${
|
|
363
435
|
focusRect.left
|
|
@@ -380,26 +452,30 @@ export function Tour({ tourStopCallback }: { tourStopCallback: () => void }) {
|
|
|
380
452
|
return (
|
|
381
453
|
<>
|
|
382
454
|
<div className="overlay" style={overlayStyle}></div>
|
|
383
|
-
|
|
455
|
+
|
|
384
456
|
<div
|
|
385
457
|
style={boxStyle}
|
|
386
|
-
className=
|
|
458
|
+
className={`fade-in flex flex-col items-center text-gray-800 transition-opacity duration-200 ${
|
|
459
|
+
bubbleVisible ? 'opacity-100' : 'opacity-0'
|
|
460
|
+
}`}
|
|
387
461
|
>
|
|
388
462
|
{focusRect && (
|
|
389
|
-
<
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
463
|
+
<div className="pointer-events-none">
|
|
464
|
+
<svg
|
|
465
|
+
width="100px"
|
|
466
|
+
height="100px"
|
|
467
|
+
viewBox="0 -7.89 113.08 113.08"
|
|
468
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
469
|
+
className={classNames("pointer-events-none", arrowRotation)}
|
|
470
|
+
style={arrowStyle}
|
|
471
|
+
>
|
|
397
472
|
<path
|
|
398
473
|
style={{ stroke: "#0000ff", fill: "#0000ff" }}
|
|
399
474
|
d="M20.1871 175C15.7485 172.891 13.0008 172.469 12.1553 170.992C8.98489 165.508 5.39173 160.024 3.70083 153.908C-1.37187 137.666 -0.737781 121.214 2.64402 104.762C8.35081 76.7092 21.0325 51.8201 36.8847 28.1966C38.5756 25.6655 40.0552 23.1344 41.7461 20.3924C41.7461 20.1814 41.5347 19.7596 41.112 19.1268C36.462 20.3923 31.6007 21.6579 26.9507 22.7125C24.4144 23.1344 21.4552 23.1344 18.9189 22.2907C17.4394 21.8688 15.3258 19.5486 15.3258 18.0722C15.3258 16.1739 16.8053 13.8537 18.0735 12.1663C19.1303 11.1117 21.0326 10.9008 22.7235 10.4789C35.4052 7.31508 48.087 3.72935 60.9801 0.776411C71.9709 -1.75468 75.564 1.83105 74.9299 12.5882C74.2959 23.7672 74.0845 34.9462 73.6618 45.9142C73.4505 49.289 72.8164 52.8747 72.3936 56.6714C63.5164 52.6638 63.5164 52.6638 60.346 18.494C47.0301 33.2588 38.1529 49.289 29.9098 65.7411C21.6666 82.1932 16.1712 99.489 13.2121 117.839C10.2531 136.823 13.8462 154.751 20.1871 175Z"
|
|
400
475
|
fill="#0D1927"
|
|
401
|
-
|
|
476
|
+
/>
|
|
402
477
|
</svg>
|
|
478
|
+
</div>
|
|
403
479
|
)}
|
|
404
480
|
|
|
405
481
|
<style>
|
|
@@ -421,16 +497,28 @@ export function Tour({ tourStopCallback }: { tourStopCallback: () => void }) {
|
|
|
421
497
|
`}
|
|
422
498
|
</style>
|
|
423
499
|
<div
|
|
424
|
-
className={`border-theme-secondary relative flex
|
|
500
|
+
className={`border-theme-secondary relative flex rounded-lg border bg-gray-50 shadow-2xl ${
|
|
501
|
+
isMobile
|
|
502
|
+
? 'w-[95vw] flex-col items-center gap-3 p-4'
|
|
503
|
+
: 'items-stretch justify-center gap-6'
|
|
504
|
+
}`}
|
|
425
505
|
style={bubbleStyle}
|
|
426
|
-
>
|
|
427
|
-
<div className=
|
|
428
|
-
|
|
506
|
+
>
|
|
507
|
+
<div className={`flex flex-col gap-2 ${
|
|
508
|
+
isMobile ? 'items-center justify-center' : 'items-end justify-end pt-5'
|
|
509
|
+
}`}>
|
|
510
|
+
<div className={`bg-wizard-tour aspect-square ${
|
|
511
|
+
isMobile ? 'w-20' : 'w-40'
|
|
512
|
+
}`}></div>
|
|
429
513
|
</div>
|
|
430
|
-
<div className=
|
|
514
|
+
<div className={`flex flex-col gap-3 ${
|
|
515
|
+
isMobile ? 'items-center justify-center p-3' : 'items-end justify-between p-6'
|
|
516
|
+
}`}>
|
|
431
517
|
{/* Step Content */}
|
|
432
518
|
<div className="flex items-start">
|
|
433
|
-
<div className=
|
|
519
|
+
<div className={`flex flex-col gap-2 text-center text-gray-800 ${
|
|
520
|
+
isMobile ? 'max-w-[80vw] text-lg' : 'max-w-[450px] text-2xl'
|
|
521
|
+
}`}>
|
|
434
522
|
<div className="flex items-center gap-3">
|
|
435
523
|
<Logo className="w-8" />
|
|
436
524
|
<div className="text-xl font-bold">{step.title}</div>
|
|
@@ -440,6 +528,9 @@ export function Tour({ tourStopCallback }: { tourStopCallback: () => void }) {
|
|
|
440
528
|
<button
|
|
441
529
|
className="text-2xs flex cursor-pointer items-center gap-2 font-bold"
|
|
442
530
|
onClick={stopTour}
|
|
531
|
+
type="button"
|
|
532
|
+
title="Close tour"
|
|
533
|
+
aria-label="Close tour"
|
|
443
534
|
>
|
|
444
535
|
<X className="h-4 w-4" />
|
|
445
536
|
</button>
|
|
@@ -52,8 +52,8 @@ export function getDefaultTourSteps(
|
|
|
52
52
|
className: "button button-secondary mt-2",
|
|
53
53
|
},
|
|
54
54
|
],
|
|
55
|
-
},
|
|
56
|
-
|
|
55
|
+
}, "new-page": {
|
|
56
|
+
title: "Create a New Page",
|
|
57
57
|
description: (
|
|
58
58
|
<>
|
|
59
59
|
Click on the <b>New Page</b> tab to create a new page
|
|
@@ -65,30 +65,39 @@ export function getDefaultTourSteps(
|
|
|
65
65
|
await waitForElement(".tour-pick-location");
|
|
66
66
|
},
|
|
67
67
|
nextStep: "pick-location",
|
|
68
|
-
},
|
|
69
|
-
|
|
68
|
+
}, "pick-location": {
|
|
69
|
+
title: "Choose Location",
|
|
70
70
|
description: (
|
|
71
71
|
<>
|
|
72
72
|
Open up a folder for your page
|
|
73
73
|
</>
|
|
74
74
|
),
|
|
75
|
-
focusElement: ".
|
|
76
|
-
bubblePosition: "
|
|
75
|
+
focusElement: ".tour-pick-location",
|
|
76
|
+
bubblePosition: "right",
|
|
77
77
|
waitForUserInput: async () => {
|
|
78
78
|
await waitForElement(".bg-theme-secondary-light");
|
|
79
79
|
},
|
|
80
80
|
nextStep: "choose-template",
|
|
81
|
-
},
|
|
82
|
-
|
|
81
|
+
}, "choose-template": {
|
|
82
|
+
title: "Select Template",
|
|
83
83
|
description: "Select a template for your page",
|
|
84
84
|
focusElement: ".tour-choose-template",
|
|
85
85
|
waitForUserInput: async () => {
|
|
86
|
-
|
|
86
|
+
return new Promise<void>((resolve) => {
|
|
87
|
+
const templateArea = document.querySelector(".tour-choose-template");
|
|
88
|
+
if (templateArea) {
|
|
89
|
+
const handleClick = () => {
|
|
90
|
+
templateArea.removeEventListener("click", handleClick);
|
|
91
|
+
resolve();
|
|
92
|
+
};
|
|
93
|
+
templateArea.addEventListener("click", handleClick);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
87
96
|
},
|
|
88
97
|
bubblePosition: "left",
|
|
89
98
|
nextStep: "enter-name",
|
|
90
|
-
},
|
|
91
|
-
|
|
99
|
+
}, "enter-name": {
|
|
100
|
+
title: "Name Your Page",
|
|
92
101
|
description: "Enter a name for your page",
|
|
93
102
|
focusElement: "#new-page-name",
|
|
94
103
|
bubblePosition: "left",
|
|
@@ -96,25 +105,25 @@ export function getDefaultTourSteps(
|
|
|
96
105
|
await waitForElement("#create-new-page-button:not([disabled])");
|
|
97
106
|
},
|
|
98
107
|
nextStep: "create-page",
|
|
99
|
-
},
|
|
100
|
-
|
|
108
|
+
}, "create-page": {
|
|
109
|
+
title: "Create Page",
|
|
101
110
|
description: "Click the Create button",
|
|
102
111
|
focusElement: "#create-new-page-button",
|
|
103
|
-
bubblePosition: "
|
|
112
|
+
bubblePosition: "left",
|
|
104
113
|
waitForUserInput: async () => {
|
|
105
114
|
// wait for loading spinner
|
|
106
115
|
await waitForElement(".pi-cog");
|
|
107
116
|
},
|
|
108
117
|
nextStep: "loading",
|
|
109
|
-
},
|
|
110
|
-
|
|
118
|
+
}, "loading": {
|
|
119
|
+
title: "Loading...",
|
|
111
120
|
description: "Waiting for your new page...",
|
|
112
121
|
waitForUserInput: async () => {
|
|
113
122
|
await waitForElementToDisappear(".pi-cog");
|
|
114
123
|
},
|
|
115
124
|
nextStep: "ready-to-add-component",
|
|
116
|
-
},
|
|
117
|
-
|
|
125
|
+
}, "ready-to-add-component": {
|
|
126
|
+
title: "Ready to Add Components",
|
|
118
127
|
description: "Wanna add a component to your beautiful empty page?",
|
|
119
128
|
buttons: [
|
|
120
129
|
{
|
|
@@ -132,8 +141,8 @@ export function getDefaultTourSteps(
|
|
|
132
141
|
},
|
|
133
142
|
},
|
|
134
143
|
],
|
|
135
|
-
},
|
|
136
|
-
|
|
144
|
+
}, "insert-component": {
|
|
145
|
+
title: "Insert Component",
|
|
137
146
|
description: "Excellent, click on the plus button to insert a component.",
|
|
138
147
|
focusElement: "#insert-component-button",
|
|
139
148
|
bubblePosition: "bottom",
|
|
@@ -141,17 +150,17 @@ export function getDefaultTourSteps(
|
|
|
141
150
|
await waitForElement(".tour-component-palette");
|
|
142
151
|
},
|
|
143
152
|
nextStep: "drag-component",
|
|
144
|
-
},
|
|
145
|
-
|
|
153
|
+
}, "drag-component": {
|
|
154
|
+
title: "Drag & Drop Component",
|
|
146
155
|
description: `Drag and drop a ${config.firstComponentTemplateName} component to your page.`,
|
|
147
156
|
focusElement: `#insert-component-${config.firstComponentTemplateId}`,
|
|
148
|
-
bubblePosition: "
|
|
157
|
+
bubblePosition: "right",
|
|
149
158
|
waitForUserInput: async () => {
|
|
150
159
|
await waitForElement(".tour-placeholder-dropzone");
|
|
151
160
|
},
|
|
152
161
|
nextStep: "drop-component-on-placeholder",
|
|
153
|
-
},
|
|
154
|
-
|
|
162
|
+
}, "drop-component-on-placeholder": {
|
|
163
|
+
title: "Drop Here!",
|
|
155
164
|
description: "Drop the component onto this placeholder!",
|
|
156
165
|
focusElement: ".tour-placeholder-dropzone",
|
|
157
166
|
bubblePosition: "left",
|
|
@@ -165,8 +174,8 @@ export function getDefaultTourSteps(
|
|
|
165
174
|
return "drag-component";
|
|
166
175
|
},
|
|
167
176
|
nextStep: "enter-title",
|
|
168
|
-
},
|
|
169
|
-
|
|
177
|
+
}, "enter-title": {
|
|
178
|
+
title: "Fill in Content",
|
|
170
179
|
description: `Excellent! Now lets fill in the fields. First enter a ${config.firstComponentTextFieldName}`,
|
|
171
180
|
focusElement: `[data-field-id='${config.firstComponentTextFieldId}']`,
|
|
172
181
|
waitForUserInput: async () => {
|
|
@@ -177,8 +186,8 @@ export function getDefaultTourSteps(
|
|
|
177
186
|
);
|
|
178
187
|
},
|
|
179
188
|
nextStep: "see-content-update",
|
|
180
|
-
},
|
|
181
|
-
|
|
189
|
+
}, "see-content-update": {
|
|
190
|
+
title: "Live Updates",
|
|
182
191
|
description:
|
|
183
192
|
"See how the content is automatically updating on your page?",
|
|
184
193
|
focusElement: `[data-field-id='${config.firstComponentTextFieldId}']`,
|
|
@@ -193,8 +202,8 @@ export function getDefaultTourSteps(
|
|
|
193
202
|
);
|
|
194
203
|
},
|
|
195
204
|
nextStep: "edit-content-inline",
|
|
196
|
-
},
|
|
197
|
-
|
|
205
|
+
}, "edit-content-inline": {
|
|
206
|
+
title: "Inline Editing",
|
|
198
207
|
description:
|
|
199
208
|
"You can also directly edit the content on the page. Click on the [Introduction] placeholder here and start typing!",
|
|
200
209
|
focusElement: `iframe:[data-fieldid='${config.firstComponentRichTextFieldId}']`,
|
|
@@ -208,8 +217,8 @@ export function getDefaultTourSteps(
|
|
|
208
217
|
);
|
|
209
218
|
},
|
|
210
219
|
nextStep: "ai-intro",
|
|
211
|
-
},
|
|
212
|
-
|
|
220
|
+
}, "ai-intro": {
|
|
221
|
+
title: "AI-Powered Editing",
|
|
213
222
|
description:
|
|
214
223
|
"But hey, this is an AI editor, so why not let the AI do some of the work for you?",
|
|
215
224
|
buttons: [
|
|
@@ -222,16 +231,17 @@ export function getDefaultTourSteps(
|
|
|
222
231
|
onClick: () => nextStep("ai-sidebar"),
|
|
223
232
|
},
|
|
224
233
|
],
|
|
225
|
-
},
|
|
226
|
-
|
|
234
|
+
}, "ai-sidebar": {
|
|
235
|
+
title: "Open AI Chat",
|
|
227
236
|
description: "Click on the AI sidebar to open the AI chat.",
|
|
228
237
|
focusElement: `[data-sidebarview-name='ai']`,
|
|
238
|
+
bubblePosition: "right",
|
|
229
239
|
nextStep: "ai-terminal",
|
|
230
240
|
waitForElement: "[data-sidebarview-name='ai'].active",
|
|
231
|
-
},
|
|
232
|
-
|
|
241
|
+
}, "ai-terminal": {
|
|
242
|
+
title: "AI Assistant",
|
|
233
243
|
description:
|
|
234
|
-
"Let me take control and
|
|
244
|
+
"Let me take control and tell the AI to add some more components.",
|
|
235
245
|
focusElement: `.tour-ai-terminal textarea`,
|
|
236
246
|
waitForUserInput: async () => {
|
|
237
247
|
await delay(1000);
|
|
@@ -240,25 +250,25 @@ export function getDefaultTourSteps(
|
|
|
240
250
|
(aiTerminal as HTMLTextAreaElement).focus();
|
|
241
251
|
await simulateTyping(
|
|
242
252
|
aiTerminal as HTMLTextAreaElement,
|
|
243
|
-
`
|
|
253
|
+
`Please add three components of type ${config.firstComponentTemplateName} with some funny dummy content to the page.`,
|
|
244
254
|
);
|
|
245
255
|
}
|
|
246
256
|
},
|
|
247
257
|
bubblePosition: "top-right",
|
|
248
258
|
nextStep: "ai-submit",
|
|
249
|
-
},
|
|
250
|
-
|
|
259
|
+
}, "ai-submit": {
|
|
260
|
+
title: "Send AI Request",
|
|
251
261
|
description: "Click on the Send button to submit the prompt to the AI.",
|
|
252
262
|
focusElement: ".tour-ai-terminal .tour-send-button",
|
|
253
263
|
bubblePosition: "top-right",
|
|
254
264
|
nextStep: "ai-watch-components-added",
|
|
255
|
-
waitForElement: ".tour-ai-terminal .
|
|
256
|
-
},
|
|
257
|
-
|
|
265
|
+
waitForElement: ".tour-ai-terminal .prompt",
|
|
266
|
+
}, "ai-watch-components-added": {
|
|
267
|
+
title: "AI Magic in Action",
|
|
258
268
|
description:
|
|
259
269
|
"Watch how the AI adds the components to the page. This can take a few seconds.",
|
|
260
270
|
focusElement: ".tour-ai-terminal",
|
|
261
|
-
pointToElement: ".tour-ai-terminal .
|
|
271
|
+
pointToElement: ".tour-ai-terminal .prompt",
|
|
262
272
|
waitForElement: ".tour-ai-response-message-changes",
|
|
263
273
|
nextStep: "congratulations",
|
|
264
274
|
},
|
package/src/types.ts
CHANGED
|
@@ -152,6 +152,8 @@ export type View = {
|
|
|
152
152
|
export type UserInfo = {
|
|
153
153
|
user: User;
|
|
154
154
|
views: View[];
|
|
155
|
+
browseHistory?: UserBrowseHistoryEntry[];
|
|
156
|
+
preferences: UserPreferences;
|
|
155
157
|
};
|
|
156
158
|
|
|
157
159
|
export type User = {
|
|
@@ -162,6 +164,12 @@ export type User = {
|
|
|
162
164
|
isLimitedPreviewUser?: boolean;
|
|
163
165
|
};
|
|
164
166
|
|
|
167
|
+
export type UserPreferences = {
|
|
168
|
+
pinnedViews?: string[];
|
|
169
|
+
showViewNames?: boolean;
|
|
170
|
+
showRightSidebar?: boolean;
|
|
171
|
+
};
|
|
172
|
+
|
|
165
173
|
export type HistoryEntry = {
|
|
166
174
|
name: string;
|
|
167
175
|
path: string;
|
|
@@ -173,6 +181,18 @@ export type HistoryEntry = {
|
|
|
173
181
|
language: string;
|
|
174
182
|
};
|
|
175
183
|
|
|
184
|
+
export type UserBrowseHistoryEntry = {
|
|
185
|
+
id: number;
|
|
186
|
+
userName: string;
|
|
187
|
+
itemId: string;
|
|
188
|
+
itemLanguage: string;
|
|
189
|
+
itemVersion: number;
|
|
190
|
+
visitedAt: string;
|
|
191
|
+
sessionId?: string;
|
|
192
|
+
itemPath: string;
|
|
193
|
+
itemName: string;
|
|
194
|
+
};
|
|
195
|
+
|
|
176
196
|
export type FieldHistoryItem = {
|
|
177
197
|
user: string;
|
|
178
198
|
date: string;
|
|
@@ -320,7 +340,7 @@ export interface SuggestedEdit {
|
|
|
320
340
|
author?: string;
|
|
321
341
|
authorDisplayName?: string;
|
|
322
342
|
created?: string;
|
|
323
|
-
status:
|
|
343
|
+
status: "rejected" | "applied" | "pending";
|
|
324
344
|
updatedBy?: string;
|
|
325
345
|
updated?: string;
|
|
326
346
|
comments?: string;
|