updates
This commit is contained in:
parent
c5752e756a
commit
0a9cbb7589
@ -42,3 +42,7 @@
|
|||||||
.shepherd-element[data-popper-placement^='top'] > .shepherd-arrow {
|
.shepherd-element[data-popper-placement^='top'] > .shepherd-arrow {
|
||||||
bottom: 2px !important;
|
bottom: 2px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shepherd-modal-overlay-container.shepherd-modal-is-visible {
|
||||||
|
@apply !opacity-70
|
||||||
|
}
|
||||||
|
|||||||
@ -5,15 +5,7 @@ import { useLocation } from 'react-router';
|
|||||||
import 'shepherd.js/dist/css/shepherd.css';
|
import 'shepherd.js/dist/css/shepherd.css';
|
||||||
import './Onboarding.css';
|
import './Onboarding.css';
|
||||||
|
|
||||||
const getShownTours = () => JSON.parse(localStorage.getItem('shownTours')) || [];
|
import { hasTourBeenShown, markTourAsShown, defaultShowHandler, middleware } from './utilities';
|
||||||
const hasTourBeenShown = (tourId: string) => getShownTours().includes(tourId);
|
|
||||||
const markTourAsShown = (tourId: string) => {
|
|
||||||
const shownTours = getShownTours();
|
|
||||||
if (!shownTours.includes(tourId)) {
|
|
||||||
shownTours.push(tourId);
|
|
||||||
localStorage.setItem('shownTours', JSON.stringify(shownTours));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const Onboarding = () => {
|
const Onboarding = () => {
|
||||||
const Shepherd = useShepherd();
|
const Shepherd = useShepherd();
|
||||||
@ -25,6 +17,10 @@ const Onboarding = () => {
|
|||||||
steps: StepOptions[];
|
steps: StepOptions[];
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the tour if it hasn't been shown yet based on the current route.
|
||||||
|
* Constructs a tour instance and adds steps to it based on the matching tour.
|
||||||
|
*/
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!tours) {
|
if (!tours) {
|
||||||
return;
|
return;
|
||||||
@ -35,29 +31,17 @@ const Onboarding = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultShowHandler = () => {
|
|
||||||
const currentStep = Shepherd.activeTour?.getCurrentStep();
|
|
||||||
if (currentStep) {
|
|
||||||
const progress = document.createElement('span');
|
|
||||||
progress.className = 'shepherd-progress text-base text-muted-foreground';
|
|
||||||
progress.innerText = `${Shepherd.activeTour?.steps.indexOf(currentStep) + 1}/${Shepherd.activeTour?.steps.length}`;
|
|
||||||
progress.style.position = 'absolute';
|
|
||||||
progress.style.left = '13px';
|
|
||||||
progress.style.bottom = '20px';
|
|
||||||
progress.style.zIndex = '1';
|
|
||||||
|
|
||||||
const footer = currentStep?.getElement()?.querySelector('.shepherd-footer');
|
|
||||||
footer?.appendChild(progress);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const tourInstance = new Shepherd.Tour({
|
const tourInstance = new Shepherd.Tour({
|
||||||
...matchingTour.tourOptions,
|
...matchingTour.tourOptions,
|
||||||
defaultStepOptions: {
|
defaultStepOptions: {
|
||||||
...matchingTour.tourOptions.defaultStepOptions,
|
...matchingTour.tourOptions?.defaultStepOptions,
|
||||||
|
floatingUIOptions:
|
||||||
|
matchingTour.tourOptions?.defaultStepOptions?.floatingUIOptions || middleware,
|
||||||
when: {
|
when: {
|
||||||
...matchingTour.tourOptions?.defaultStepOptions?.when,
|
...matchingTour.tourOptions?.defaultStepOptions?.when,
|
||||||
show: matchingTour.tourOptions?.defaultStepOptions?.when?.show || defaultShowHandler,
|
show:
|
||||||
|
matchingTour.tourOptions?.defaultStepOptions?.when?.show ||
|
||||||
|
(() => defaultShowHandler(Shepherd)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
91
platform/ui-next/src/components/Onboarding/utilities.ts
Normal file
91
platform/ui-next/src/components/Onboarding/utilities.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import { ShepherdBase } from 'shepherd.js';
|
||||||
|
import { offset, flip, shift, detectOverflow } from '@floating-ui/dom';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of tours that have been shown from localStorage.
|
||||||
|
* @returns {string[]} An array of tour IDs that have been shown.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const getShownTours = () => JSON.parse(localStorage.getItem('shownTours')) || [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a specific tour has been shown.
|
||||||
|
* @param {string} tourId - The ID of the tour to check.
|
||||||
|
* @returns {boolean} True if the tour has been shown, false otherwise.
|
||||||
|
*/
|
||||||
|
const hasTourBeenShown = (tourId: string) => getShownTours().includes(tourId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks a specific tour as shown by adding it to localStorage.
|
||||||
|
* @param {string} tourId - The ID of the tour to mark as shown.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
const markTourAsShown = (tourId: string) => {
|
||||||
|
const shownTours = getShownTours();
|
||||||
|
if (!shownTours.includes(tourId)) {
|
||||||
|
shownTours.push(tourId);
|
||||||
|
localStorage.setItem('shownTours', JSON.stringify(shownTours));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default handler for the 'show' event in Shepherd steps.
|
||||||
|
* Adds a progress indicator to the footer of the current step.
|
||||||
|
*
|
||||||
|
* @param {ShepherdBase} Shepherd - The Shepherd.js instance.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
const defaultShowHandler = (Shepherd: ShepherdBase) => {
|
||||||
|
const currentStep = Shepherd.activeTour?.getCurrentStep();
|
||||||
|
if (currentStep) {
|
||||||
|
const progress = document.createElement('span');
|
||||||
|
progress.className = 'shepherd-progress text-base text-muted-foreground';
|
||||||
|
progress.innerText = `${Shepherd.activeTour?.steps.indexOf(currentStep) + 1}/${Shepherd.activeTour?.steps.length}`;
|
||||||
|
progress.style.position = 'absolute';
|
||||||
|
progress.style.left = '13px';
|
||||||
|
progress.style.bottom = '20px';
|
||||||
|
progress.style.zIndex = '1';
|
||||||
|
|
||||||
|
const footer = currentStep?.getElement()?.querySelector('.shepherd-footer');
|
||||||
|
footer?.appendChild(progress);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom middleware for adjusting Shepherd step positioning when overflowing.
|
||||||
|
*
|
||||||
|
* @type {object}
|
||||||
|
* @property {string} name - The name of the middleware.
|
||||||
|
* @property {function} fn - The function that adjusts the position of the step when overflowing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const customMiddleware = {
|
||||||
|
name: 'customOverflowMiddleware',
|
||||||
|
async fn(state) {
|
||||||
|
const overflow = await detectOverflow(state, {
|
||||||
|
boundary: document.querySelector('body'),
|
||||||
|
padding: 24,
|
||||||
|
});
|
||||||
|
|
||||||
|
const xAdjustment =
|
||||||
|
overflow.left > 0 ? overflow.left : overflow.right > 0 ? -overflow.right : 0;
|
||||||
|
const yAdjustment =
|
||||||
|
overflow.top > 0 ? overflow.top : overflow.bottom > 0 ? -overflow.bottom : 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: state.x + xAdjustment,
|
||||||
|
y: state.y + yAdjustment,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Floating UI middleware for positioning steps in Shepherd.js.
|
||||||
|
* Includes offset, shift, flip, and custom overflow middleware.
|
||||||
|
*
|
||||||
|
* @type {Array<object>}
|
||||||
|
*/
|
||||||
|
|
||||||
|
const middleware = [offset(15), shift(), flip(), customMiddleware];
|
||||||
|
|
||||||
|
export { hasTourBeenShown, markTourAsShown, middleware, defaultShowHandler };
|
||||||
Loading…
Reference in New Issue
Block a user