Skip to content

Commit

Permalink
pass Step to downstream components instead of State
Browse files Browse the repository at this point in the history
  • Loading branch information
binrysearch committed Sep 5, 2024
1 parent fced29b commit 067a7c0
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 133 deletions.
68 changes: 12 additions & 56 deletions src/packages/tooltip/tooltip.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import getOffset, { Offset } from "../../util/getOffset";
import { Offset } from "../../util/getOffset";
import getWindowSize from "../../util/getWindowSize";
import van, { ChildDom, State } from "../dom/van";
import {
arrowClassName,
tooltipClassName,
} from "../tour/classNames";
import { arrowClassName, tooltipClassName } from "../tour/classNames";
import { determineAutoPosition, TooltipPosition } from "./tooltipPosition";

const { div } = van.tags;
Expand Down Expand Up @@ -300,8 +297,8 @@ const alignTooltip = (
};

export type TooltipProps = {
position: State<TooltipPosition>;
targetOffset: State<Offset>;
position: TooltipPosition;
targetOffset: Offset;
hintMode: boolean;
showStepNumbers: boolean;

Expand All @@ -312,7 +309,7 @@ export type TooltipProps = {

export const Tooltip = (
{
position,
position: initialPosition,
targetOffset,
hintMode = false,
showStepNumbers = false,
Expand All @@ -329,31 +326,28 @@ export const Tooltip = (
const left = van.state<string>("auto");
const marginLeft = van.state<string>("auto");
const marginTop = van.state<string>("auto");
const opacity = van.state<number>(0);
const display = van.state<string>("none");
// setting a default height for the tooltip instead of 0 to avoid flickering
const tooltipHeight = van.state<number>(150);
// max width of the tooltip according to its CSS class
const tooltipWidth = van.state<number>(300);
const position = van.state<TooltipPosition>(initialPosition);
const windowSize = getWindowSize();
const tooltipBottomOverflow = van.derive(
() => targetOffset.val!.top + tooltipHeight.val! > windowSize.height
() => targetOffset.top + tooltipHeight.val! > windowSize.height
);
const isActive = van.state(false);
let isActiveTimeout = 0;

// auto-align tooltip based on position precedence and target offset
van.derive(() => {
if (
position.val !== undefined &&
position.val !== "floating" &&
autoPosition &&
tooltipWidth.val &&
tooltipHeight.val &&
position.val !== undefined
tooltipHeight.val
) {
position.val = determineAutoPosition(
positionPrecedence,
targetOffset.val!,
targetOffset,
tooltipWidth.val,
tooltipHeight.val,
position.val
Expand All @@ -371,7 +365,7 @@ export const Tooltip = (
) {
alignTooltip(
position.val,
targetOffset.val!,
targetOffset,
tooltipWidth.val,
tooltipHeight.val,
top,
Expand All @@ -387,26 +381,10 @@ export const Tooltip = (
}
});

// show/hide tooltip
van.derive(() => {
if (isActive.val) {
display.val = "block";

// wait for the tooltip to be rendered before setting opacity
setTimeout(() => {
opacity.val = 1;
}, 1);
} else {
// hide the tooltip by setting display to none then opacity to 0 to avoid flickering and enable transitions
display.val = "none";
opacity.val = 0;
}
});

const tooltip = div(
{
style: () =>
`top: ${top.val}; right: ${right.val}; bottom: ${bottom.val}; left: ${left.val}; margin-left: ${marginLeft.val}; margin-top: ${marginTop.val}; opacity: ${opacity.val}; display: ${display.val};`,
`top: ${top.val}; right: ${right.val}; bottom: ${bottom.val}; left: ${left.val}; margin-left: ${marginLeft.val}; margin-top: ${marginTop.val};`,
className: () => `${tooltipClassName} introjs-${position.val}`,
role: "dialog",
},
Expand All @@ -419,27 +397,5 @@ export const Tooltip = (
]
);

// recalculate tooltip width/height when targetOffset changes
// a targetOffset change means the tooltip width/height needs to be recalculated
van.derive(() => {
if (tooltip && targetOffset.val) {
isActive.val = false;

// wait for the tooltip to be rendered before calculating the position
setTimeout(() => {
const tooltipOffset = getOffset(tooltip);
tooltipHeight.val = tooltipOffset.height;
tooltipWidth.val = tooltipOffset.width;
}, 1);

setTimeout(() => {
isActive.val = true;

// reset the timeout to a higher value to avoid flickering
isActiveTimeout = 350;
}, isActiveTimeout);
}
});

return tooltip;
};
5 changes: 1 addition & 4 deletions src/packages/tour/components/ReferenceLayer.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import van from "../../dom/van";
import { tooltipReferenceLayerClassName } from "../classNames";
import { setPositionRelativeToStep } from "../position";
import { TourStep } from "../steps";
import { TourTooltip, TourTooltipProps } from "./TourTooltip";

const { div } = van.tags;

export type ReferenceLayerProps = TourTooltipProps & {
step: TourStep;
targetElement: HTMLElement;
helperElementPadding: number;
};

export const ReferenceLayer = ({
step,
targetElement,
helperElementPadding,
...props
Expand All @@ -28,7 +25,7 @@ export const ReferenceLayer = ({
setPositionRelativeToStep(
targetElement,
referenceLayer,
step,
props.step,
helperElementPadding
);

Expand Down
22 changes: 19 additions & 3 deletions src/packages/tour/components/TourRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DisableInteraction } from "./DisableInteraction";
import { OverlayLayer } from "./OverlayLayer";
import { nextStep, previousStep } from "../steps";
import { doneButtonClassName } from "../classNames";
import { style } from "../../../util/style";

const { div } = van.tags;

Expand All @@ -26,8 +27,14 @@ export const TourRoot = ({ tour }: TourRootProps) => {
helperLayerPadding: tour.getOption("helperElementPadding"),
});

const opacity = van.state(0);

const root = div(
{ className: "introjs-tour" },
{
className: "introjs-tour",
style: () =>
style({ transition: "all 250ms ease-out", opacity: `${opacity.val}` }),
},
// helperLayer should not be re-rendered when the state changes for the transition to work
helperLayer,
() => {
Expand Down Expand Up @@ -63,7 +70,7 @@ export const TourRoot = ({ tour }: TourRootProps) => {
showStepNumbers: tour.getOption("showStepNumbers"),

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

onBulletClick: (stepNumber: number) => {
tour.goToStep(stepNumber);
Expand Down Expand Up @@ -147,9 +154,18 @@ export const TourRoot = ({ tour }: TourRootProps) => {
van.derive(() => {
// to clean up the root element when the tour is done
if (currentStep.val === undefined) {
root.remove();
opacity.val = 0;

setTimeout(() => {
root.remove();
}, 250);
}

});

setTimeout(() => {
opacity.val = 1;
}, 1);

return root;
};
Loading

0 comments on commit 067a7c0

Please sign in to comment.