mirror of
https://github.com/kamranahmedse/driver.js.git
synced 2026-10-31 03:52:13 +08:00
Driver refactoring
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: "Theming"
|
||||
groupTitle: "Introduction"
|
||||
sort: 3
|
||||
---
|
||||
|
||||
You can customize the look and feel of the driver by applying CSS to following classes.
|
||||
|
||||
```css
|
||||
/* Applied to the `body` when the driver: */
|
||||
.driver-active {} /* is active */
|
||||
.driver-fade {} /* is animated */
|
||||
.driver-simple {} /* is not animated */
|
||||
```
|
||||
|
||||
Following classes are applied to the overlay element (i.e. called stage.
|
||||
|
||||
```css
|
||||
.driver-stage {}
|
||||
+29
-7
@@ -1,5 +1,5 @@
|
||||
import { AllowedButtons, destroyPopover, Popover } from "./popover";
|
||||
import { destroyStage } from "./stage";
|
||||
import { destroyOverlay } from "./overlay";
|
||||
import { destroyEvents, initEvents, requireRefresh } from "./events";
|
||||
import { Config, configure, DriverHook, getConfig } from "./config";
|
||||
import { destroyHighlight, highlight } from "./highlight";
|
||||
@@ -57,19 +57,40 @@ export function driver(options: Config = {}) {
|
||||
}
|
||||
|
||||
function handleArrowLeft() {
|
||||
const steps = getConfig("steps") || [];
|
||||
const isTransitioning = getState("__transitionCallback");
|
||||
if (isTransitioning) {
|
||||
return;
|
||||
}
|
||||
|
||||
const activeIndex = getState("activeIndex");
|
||||
const activeStep = getState("activeStep");
|
||||
const activeElement = getState("activeElement");
|
||||
if (typeof activeIndex === "undefined" || typeof activeStep === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentStepIndex = getState("activeIndex");
|
||||
if (typeof currentStepIndex === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
const previousStepIndex = currentStepIndex - 1;
|
||||
if (steps[previousStepIndex]) {
|
||||
drive(previousStepIndex);
|
||||
const onPrevClick = activeStep.popover?.onPrevClick || getConfig("onPrevClick");
|
||||
if (onPrevClick) {
|
||||
return onPrevClick(activeElement, activeStep, {
|
||||
config: getConfig(),
|
||||
state: getState(),
|
||||
});
|
||||
}
|
||||
|
||||
movePrevious();
|
||||
}
|
||||
|
||||
function handleArrowRight() {
|
||||
const isTransitioning = getState("__transitionCallback");
|
||||
if (isTransitioning) {
|
||||
return;
|
||||
}
|
||||
|
||||
const activeIndex = getState("activeIndex");
|
||||
const activeStep = getState("activeStep");
|
||||
const activeElement = getState("activeElement");
|
||||
@@ -113,8 +134,9 @@ export function driver(options: Config = {}) {
|
||||
}
|
||||
|
||||
if (!steps[stepIndex]) {
|
||||
console.warn(`Step not found at index: ${stepIndex}`);
|
||||
destroy();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setState("activeIndex", stepIndex);
|
||||
@@ -185,7 +207,7 @@ export function driver(options: Config = {}) {
|
||||
destroyEvents();
|
||||
destroyPopover();
|
||||
destroyHighlight();
|
||||
destroyStage();
|
||||
destroyOverlay();
|
||||
destroyEmitter();
|
||||
|
||||
resetState();
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import { DriveStep } from "./driver";
|
||||
import { refreshStage, trackActiveElement, transitionStage } from "./stage";
|
||||
import { refreshOverlay, trackActiveElement, transitionStage } from "./overlay";
|
||||
import { getConfig } from "./config";
|
||||
import { repositionPopover, renderPopover, hidePopover } from "./popover";
|
||||
import { bringInView } from "./utils";
|
||||
@@ -51,7 +51,7 @@ export function refreshActiveHighlight() {
|
||||
}
|
||||
|
||||
trackActiveElement(activeHighlight);
|
||||
refreshStage();
|
||||
refreshOverlay();
|
||||
repositionPopover(activeHighlight, activeStep);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ export function transitionStage(elapsed: number, duration: number, from: Element
|
||||
height,
|
||||
};
|
||||
|
||||
renderStage(activeStagePosition);
|
||||
renderOverlay(activeStagePosition);
|
||||
setState("__activeStagePosition", activeStagePosition);
|
||||
}
|
||||
|
||||
@@ -51,18 +51,18 @@ export function trackActiveElement(element: Element) {
|
||||
|
||||
setState("__activeStagePosition", activeStagePosition);
|
||||
|
||||
renderStage(activeStagePosition);
|
||||
renderOverlay(activeStagePosition);
|
||||
}
|
||||
|
||||
export function refreshStage() {
|
||||
export function refreshOverlay() {
|
||||
const activeStagePosition = getState("__activeStagePosition");
|
||||
const stageSvg = getState("__stageSvg");
|
||||
const overlaySvg = getState("__overlaySvg");
|
||||
|
||||
if (!activeStagePosition) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!stageSvg) {
|
||||
if (!overlaySvg) {
|
||||
console.warn("No stage svg found.");
|
||||
return;
|
||||
}
|
||||
@@ -70,14 +70,14 @@ export function refreshStage() {
|
||||
const windowX = window.innerWidth;
|
||||
const windowY = window.innerHeight;
|
||||
|
||||
stageSvg.setAttribute("viewBox", `0 0 ${windowX} ${windowY}`);
|
||||
overlaySvg.setAttribute("viewBox", `0 0 ${windowX} ${windowY}`);
|
||||
}
|
||||
|
||||
function mountStage(stagePosition: StageDefinition) {
|
||||
const stageSvg = createStageSvg(stagePosition);
|
||||
document.body.appendChild(stageSvg);
|
||||
function mountOverlay(stagePosition: StageDefinition) {
|
||||
const overlaySvg = createOverlaySvg(stagePosition);
|
||||
document.body.appendChild(overlaySvg);
|
||||
|
||||
onDriverClick(stageSvg, e => {
|
||||
onDriverClick(overlaySvg, e => {
|
||||
const target = e.target as SVGElement;
|
||||
if (target.tagName !== "path") {
|
||||
return;
|
||||
@@ -86,20 +86,20 @@ function mountStage(stagePosition: StageDefinition) {
|
||||
emit("overlayClick");
|
||||
});
|
||||
|
||||
setState("__stageSvg", stageSvg);
|
||||
setState("__overlaySvg", overlaySvg);
|
||||
}
|
||||
|
||||
function renderStage(stagePosition: StageDefinition) {
|
||||
const stageSvg = getState("__stageSvg");
|
||||
function renderOverlay(stagePosition: StageDefinition) {
|
||||
const overlaySvg = getState("__overlaySvg");
|
||||
|
||||
// TODO: cancel rendering if element is not visible
|
||||
if (!stageSvg) {
|
||||
mountStage(stagePosition);
|
||||
if (!overlaySvg) {
|
||||
mountOverlay(stagePosition);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const pathElement = stageSvg.firstElementChild as SVGPathElement | null;
|
||||
const pathElement = overlaySvg.firstElementChild as SVGPathElement | null;
|
||||
if (pathElement?.tagName !== "path") {
|
||||
throw new Error("no path element found in stage svg");
|
||||
}
|
||||
@@ -107,7 +107,7 @@ function renderStage(stagePosition: StageDefinition) {
|
||||
pathElement.setAttribute("d", generateStageSvgPathString(stagePosition));
|
||||
}
|
||||
|
||||
function createStageSvg(stage: StageDefinition): SVGSVGElement {
|
||||
function createOverlaySvg(stage: StageDefinition): SVGSVGElement {
|
||||
const windowX = window.innerWidth;
|
||||
const windowY = window.innerHeight;
|
||||
|
||||
@@ -170,9 +170,9 @@ function generateStageSvgPathString(stage: StageDefinition) {
|
||||
M${highlightBoxX},${highlightBoxY} h${highlightBoxWidth} a${normalizedRadius},${normalizedRadius} 0 0 1 ${normalizedRadius},${normalizedRadius} v${highlightBoxHeight} a${normalizedRadius},${normalizedRadius} 0 0 1 -${normalizedRadius},${normalizedRadius} h-${highlightBoxWidth} a${normalizedRadius},${normalizedRadius} 0 0 1 -${normalizedRadius},-${normalizedRadius} v-${highlightBoxHeight} a${normalizedRadius},${normalizedRadius} 0 0 1 ${normalizedRadius},-${normalizedRadius} z`;
|
||||
}
|
||||
|
||||
export function destroyStage() {
|
||||
const stageSvg = getState("__stageSvg");
|
||||
if (stageSvg) {
|
||||
stageSvg.remove();
|
||||
export function destroyOverlay() {
|
||||
const overlaySvg = getState("__overlaySvg");
|
||||
if (overlaySvg) {
|
||||
overlaySvg.remove();
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import { StageDefinition } from "./stage";
|
||||
import { StageDefinition } from "./overlay";
|
||||
import { PopoverDOM } from "./popover";
|
||||
import { DriveStep } from "./driver";
|
||||
|
||||
@@ -17,7 +17,7 @@ export type State = {
|
||||
__resizeTimeout?: number;
|
||||
__transitionCallback?: () => void;
|
||||
__activeStagePosition?: StageDefinition;
|
||||
__stageSvg?: SVGSVGElement;
|
||||
__overlaySvg?: SVGSVGElement;
|
||||
};
|
||||
|
||||
let currentState: State = {};
|
||||
|
||||
Reference in New Issue
Block a user