Skip to content

Commit

Permalink
fix helperLayer transition
Browse files Browse the repository at this point in the history
  • Loading branch information
binrysearch committed Sep 5, 2024
1 parent 9e73d8e commit 4ba62d4
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 131 deletions.
40 changes: 22 additions & 18 deletions src/packages/tour/helperLayer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { style } from "../../util/style";
import van from "../dom/van";
import van, { State } from "../dom/van";
import { helperLayerClassName } from "./classNames";
import { setPositionRelativeToStep } from "./position";
import { TourStep } from "./steps";
Expand All @@ -10,14 +10,14 @@ const getClassName = ({
step,
tourHighlightClass,
}: {
step: TourStep;
step: State<TourStep | null>;
tourHighlightClass: string;
}) => {
let highlightClass = helperLayerClassName;

// check for a current step highlight class
if (typeof step.highlightClass === "string") {
highlightClass += ` ${step.highlightClass}`;
if (step.val && typeof step.val.highlightClass === "string") {
highlightClass += ` ${step.val.highlightClass}`;
}

// check for options highlight class
Expand All @@ -29,41 +29,45 @@ const getClassName = ({
};

export type HelperLayerProps = {
step: TourStep;
currentStep: State<number>;
steps: TourStep[];
targetElement: HTMLElement;
tourHighlightClass: string;
overlayOpacity: number;
helperLayerPadding: number;
};

export const HelperLayer = ({
step,
currentStep,
steps,
targetElement,
tourHighlightClass,
overlayOpacity,
helperLayerPadding,
}: HelperLayerProps) => {
if (!step) {
return null;
}

const className = getClassName({ step: step, tourHighlightClass });
const step = van.derive(() =>
currentStep.val !== undefined ? steps[currentStep.val] : null
);

const helperLayer = div({
className,
className: () => getClassName({ step, tourHighlightClass }),
style: style({
// the inner box shadow is the border for the highlighted element
// the outer box shadow is the overlay effect
"box-shadow": `0 0 1px 2px rgba(33, 33, 33, 0.8), rgba(33, 33, 33, ${overlayOpacity.toString()}) 0 0 0 5000px`,
}),
});

setPositionRelativeToStep(
targetElement,
helperLayer,
step,
helperLayerPadding
);
van.derive(() => {
if (!step.val) return;

setPositionRelativeToStep(
targetElement,
helperLayer,
step.val,
helperLayerPadding
);
});

return helperLayer;
};
244 changes: 131 additions & 113 deletions src/packages/tour/tourRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,121 +16,139 @@ export type TourRootProps = {
export const TourRoot = ({ tour }: TourRootProps) => {
const currentStep = tour.currentStepSignal;
const steps = tour.getSteps();
const step = van.derive(() =>
currentStep.val !== undefined ? steps[currentStep.val] : null
);

return () => {
if (!step.val) {
return null;
const helperLayer = HelperLayer({
currentStep,
steps,
targetElement: tour.getTargetElement(),
tourHighlightClass: tour.getOption("highlightClass"),
overlayOpacity: tour.getOption("overlayOpacity"),
helperLayerPadding: tour.getOption("helperElementPadding"),
});

const root = div(
{ className: "introjs-tour" },
// helperLayer should not be re-rendered when the state changes for the transition to work
helperLayer,
() => {
// do not remove this check, it is necessary for this state-binding to work
// and render the entire section every time the state changes
if (currentStep.val === undefined) {
return null;
}

const step = van.derive(() =>
currentStep.val !== undefined ? steps[currentStep.val] : null
);

if (!step.val) {
return null;
}

const exitOnOverlayClick = tour.getOption("exitOnOverlayClick") === true;
const overlayLayer = OverlayLayer({
exitOnOverlayClick,
onExitTour: async () => {
return tour.exit();
},
});

const referenceLayer = ReferenceLayer({
step: step.val,
targetElement: tour.getTargetElement(),
helperElementPadding: tour.getOption("helperElementPadding"),

positionPrecedence: tour.getOption("positionPrecedence"),
autoPosition: tour.getOption("autoPosition"),
showStepNumbers: tour.getOption("showStepNumbers"),

steps: tour.getSteps(),
currentStep: tour.currentStepSignal,

onBulletClick: (stepNumber: number) => {
tour.goToStep(stepNumber);
},

bullets: tour.getOption("showBullets"),

buttons: tour.getOption("showButtons"),
nextLabel: "Next",
onNextClick: async (e: any) => {
if (!tour.isLastStep()) {
await nextStep(tour);
} else if (
new RegExp(doneButtonClassName, "gi").test(
(e.target as HTMLElement).className
)
) {
await tour
.callback("complete")
?.call(tour, tour.getCurrentStep(), "done");

await tour.exit();
}
},
prevLabel: tour.getOption("prevLabel"),
onPrevClick: async () => {
if (tour.getCurrentStep() > 0) {
await previousStep(tour);
}
},
skipLabel: tour.getOption("skipLabel"),
onSkipClick: async () => {
if (tour.isLastStep()) {
await tour
.callback("complete")
?.call(tour, tour.getCurrentStep(), "skip");
}

await tour.callback("skip")?.call(tour, tour.getCurrentStep());

await tour.exit();
},
buttonClass: tour.getOption("buttonClass"),
nextToDone: tour.getOption("nextToDone"),
doneLabel: tour.getOption("doneLabel"),
hideNext: tour.getOption("hideNext"),
hidePrev: tour.getOption("hidePrev"),

progress: tour.getOption("showProgress"),
progressBarAdditionalClass: tour.getOption(
"progressBarAdditionalClass"
),

stepNumbers: tour.getOption("showStepNumbers"),
stepNumbersOfLabel: tour.getOption("stepNumbersOfLabel"),

scrollToElement: tour.getOption("scrollToElement"),
scrollPadding: tour.getOption("scrollPadding"),

dontShowAgain: tour.getOption("dontShowAgain"),
onDontShowAgainChange: (e: any) => {
tour.setDontShowAgain((<HTMLInputElement>e.target).checked);
},
dontShowAgainLabel: tour.getOption("dontShowAgainLabel"),
});

const disableInteraction = step.val.disableInteraction
? DisableInteraction({
currentStep: tour.currentStepSignal,
steps: tour.getSteps(),
targetElement: tour.getTargetElement(),
helperElementPadding: tour.getOption("helperElementPadding"),
})
: null;

return div(overlayLayer, referenceLayer, disableInteraction);
}
);

const exitOnOverlayClick = tour.getOption("exitOnOverlayClick") === true;
const overlayLayer = OverlayLayer({
exitOnOverlayClick,
onExitTour: async () => {
return tour.exit();
},
});

const helperLayer = HelperLayer({
step: step.val,
targetElement: tour.getTargetElement(),
tourHighlightClass: tour.getOption("highlightClass"),
overlayOpacity: tour.getOption("overlayOpacity"),
helperLayerPadding: tour.getOption("helperElementPadding"),
});

const referenceLayer = ReferenceLayer({
step: step.val,
targetElement: tour.getTargetElement(),
helperElementPadding: tour.getOption("helperElementPadding"),

positionPrecedence: tour.getOption("positionPrecedence"),
autoPosition: tour.getOption("autoPosition"),
showStepNumbers: tour.getOption("showStepNumbers"),

steps: tour.getSteps(),
currentStep: tour.currentStepSignal,

onBulletClick: (stepNumber: number) => {
tour.goToStep(stepNumber);
},

bullets: tour.getOption("showBullets"),

buttons: tour.getOption("showButtons"),
nextLabel: "Next",
onNextClick: async (e: any) => {
if (!tour.isLastStep()) {
await nextStep(tour);
} else if (
new RegExp(doneButtonClassName, "gi").test(
(e.target as HTMLElement).className
)
) {
await tour
.callback("complete")
?.call(tour, tour.getCurrentStep(), "done");
van.derive(() => {
// to clean up the root element when the tour is done
if (currentStep.val === undefined || currentStep.val < 0) {
root.remove();
}
});

await tour.exit();
}
},
prevLabel: tour.getOption("prevLabel"),
onPrevClick: async () => {
if (tour.getCurrentStep() > 0) {
await previousStep(tour);
}
},
skipLabel: tour.getOption("skipLabel"),
onSkipClick: async () => {
if (tour.isLastStep()) {
await tour
.callback("complete")
?.call(tour, tour.getCurrentStep(), "skip");
}

await tour.callback("skip")?.call(tour, tour.getCurrentStep());

await tour.exit();
},
buttonClass: tour.getOption("buttonClass"),
nextToDone: tour.getOption("nextToDone"),
doneLabel: tour.getOption("doneLabel"),
hideNext: tour.getOption("hideNext"),
hidePrev: tour.getOption("hidePrev"),

progress: tour.getOption("showProgress"),
progressBarAdditionalClass: tour.getOption("progressBarAdditionalClass"),

stepNumbers: tour.getOption("showStepNumbers"),
stepNumbersOfLabel: tour.getOption("stepNumbersOfLabel"),

scrollToElement: tour.getOption("scrollToElement"),
scrollPadding: tour.getOption("scrollPadding"),

dontShowAgain: tour.getOption("dontShowAgain"),
onDontShowAgainChange: (e: any) => {
tour.setDontShowAgain((<HTMLInputElement>e.target).checked);
},
dontShowAgainLabel: tour.getOption("dontShowAgainLabel"),
});

const disableInteraction = step.val.disableInteraction
? DisableInteraction({
currentStep: tour.currentStepSignal,
steps: tour.getSteps(),
targetElement: tour.getTargetElement(),
helperElementPadding: tour.getOption("helperElementPadding"),
})
: null;

return div(
{ className: "introjs-tour" },
overlayLayer,
helperLayer,
referenceLayer,
disableInteraction
);
};
return root;
};

0 comments on commit 4ba62d4

Please sign in to comment.