Add highlight hooks and allow reconfiguring driver
Browse files- docs/src/content/guides/configuration.mdx +153 -1
- src/driver.ts +7 -2
- src/highlight.ts +2 -2
docs/src/content/guides/configuration.mdx
CHANGED
|
@@ -68,7 +68,7 @@ type Popover = {
|
|
| 68 |
// Callbacks for button clicks. You can use
|
| 69 |
// these to add custom behavior to the buttons.
|
| 70 |
// Each callback receives the following parameters:
|
| 71 |
-
// - element: The
|
| 72 |
// - step: The step object configured for the step
|
| 73 |
// - options.config: The current configuration options
|
| 74 |
// - options.state: The current state of the driver
|
|
@@ -77,3 +77,155 @@ type Popover = {
|
|
| 77 |
onCloseClick?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void
|
| 78 |
}
|
| 79 |
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
// Callbacks for button clicks. You can use
|
| 69 |
// these to add custom behavior to the buttons.
|
| 70 |
// Each callback receives the following parameters:
|
| 71 |
+
// - element: The current DOM element of the step
|
| 72 |
// - step: The step object configured for the step
|
| 73 |
// - options.config: The current configuration options
|
| 74 |
// - options.state: The current state of the driver
|
|
|
|
| 77 |
onCloseClick?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void
|
| 78 |
}
|
| 79 |
```
|
| 80 |
+
|
| 81 |
+
## Drive Step Configuration
|
| 82 |
+
|
| 83 |
+
Drive step is the configuration object passed to the `highlight` method or the `steps` array of the `drive` method. You can configure the popover and the target element for each step. Given below are some of the available configuration options.
|
| 84 |
+
|
| 85 |
+
```typescript
|
| 86 |
+
type DriveStep = {
|
| 87 |
+
// The target element to highlight.
|
| 88 |
+
// This can be a DOM element, or a CSS selector.
|
| 89 |
+
// If this is a selector, the first matching
|
| 90 |
+
// element will be highlighted.
|
| 91 |
+
element: Element | string;
|
| 92 |
+
|
| 93 |
+
// The popover configuration for this step.
|
| 94 |
+
// Look at the Popover Configuration section
|
| 95 |
+
popover?: Popover;
|
| 96 |
+
|
| 97 |
+
// Callback when the current step is deselected,
|
| 98 |
+
// about to be highlighted or highlighted.
|
| 99 |
+
// Each callback receives the following parameters:
|
| 100 |
+
// - element: The current DOM element of the step
|
| 101 |
+
// - step: The step object configured for the step
|
| 102 |
+
// - options.config: The current configuration options
|
| 103 |
+
// - options.state: The current state of the driver
|
| 104 |
+
onDeselected?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void;
|
| 105 |
+
onHighlightStarted?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void;
|
| 106 |
+
onHighlighted?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void;
|
| 107 |
+
}
|
| 108 |
+
```
|
| 109 |
+
|
| 110 |
+
## Global Configuration
|
| 111 |
+
|
| 112 |
+
You can configure the driver globally by passing the configuration object to the `driver` call or by using the `setConfig` method. Given below are some of the available configuration options.
|
| 113 |
+
|
| 114 |
+
```typescript
|
| 115 |
+
type Config = {
|
| 116 |
+
// Array of steps to highlight. You should pass
|
| 117 |
+
// this when you want to setup a product tour.
|
| 118 |
+
steps?: DriveStep[];
|
| 119 |
+
|
| 120 |
+
// Whether to animate the product tour. (default: true)
|
| 121 |
+
animate?: boolean;
|
| 122 |
+
// Overlay color. (default: rgba(0, 0, 0, 0.5))
|
| 123 |
+
// This is useful when you have a dark background
|
| 124 |
+
// and want to highlight elements with a light
|
| 125 |
+
// background color.
|
| 126 |
+
backdropColor?: string;
|
| 127 |
+
// Whether to smooth scroll to the highlighted element. (default: false)
|
| 128 |
+
smoothScroll?: boolean;
|
| 129 |
+
// Whether to allow closing the popover by clicking on the backdrop. (default: true)
|
| 130 |
+
allowClose?: boolean;
|
| 131 |
+
// Opacity of the backdrop. (default: 0.5)
|
| 132 |
+
opacity?: number;
|
| 133 |
+
// Distance between the highlighted element and the cutout. (default: 10)
|
| 134 |
+
stagePadding?: number;
|
| 135 |
+
// Radius of the cutout around the highlighted element. (default: 5)
|
| 136 |
+
stageRadius?: number;
|
| 137 |
+
|
| 138 |
+
// Whether to allow keyboard navigation. (default: true)
|
| 139 |
+
allowKeyboardControl?: boolean;
|
| 140 |
+
|
| 141 |
+
// If you want to add custom class to the popover
|
| 142 |
+
popoverClass?: string;
|
| 143 |
+
// Distance between the popover and the highlighted element. (default: 10)
|
| 144 |
+
popoverOffset?: number;
|
| 145 |
+
// Array of buttons to show in the popover. Defaults to ["next", "previous", "close"]
|
| 146 |
+
// for product tours and [] for single element highlighting.
|
| 147 |
+
showButtons?: AllowedButtons[];
|
| 148 |
+
// Array of buttons to disable. This is useful when you want to show some of the
|
| 149 |
+
// buttons, but disable some of them.
|
| 150 |
+
disableButtons?: AllowedButtons[];
|
| 151 |
+
|
| 152 |
+
// Whether to show the progress text in popover. (default: false)
|
| 153 |
+
showProgress?: boolean;
|
| 154 |
+
// Template for the progress text. You can use the following placeholders in the template:
|
| 155 |
+
// - {{current}}: The current step number
|
| 156 |
+
// - {{total}}: Total number of steps
|
| 157 |
+
progressText?: string;
|
| 158 |
+
|
| 159 |
+
// Text to show in the buttons. `doneBtnText`
|
| 160 |
+
// is used on the last step of a tour.
|
| 161 |
+
nextBtnText?: string;
|
| 162 |
+
prevBtnText?: string;
|
| 163 |
+
doneBtnText?: string;
|
| 164 |
+
|
| 165 |
+
// Called after the popover is rendered.
|
| 166 |
+
// PopoverDOM is an object with references to
|
| 167 |
+
// the popover DOM elements such as buttons
|
| 168 |
+
// title, descriptions, body, container etc.
|
| 169 |
+
onPopoverRendered?: (popover: PopoverDOM) => void;
|
| 170 |
+
|
| 171 |
+
// Hooks to run before and after highlighting
|
| 172 |
+
// each step. Each hook receives the following
|
| 173 |
+
// parameters:
|
| 174 |
+
// - element: The target DOM element of the step
|
| 175 |
+
// - step: The step object configured for the step
|
| 176 |
+
// - options.config: The current configuration options
|
| 177 |
+
// - options.state: The current state of the driver
|
| 178 |
+
onHighlightStarted?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void;;
|
| 179 |
+
onHighlighted?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void;;
|
| 180 |
+
onDeselected?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void;;
|
| 181 |
+
|
| 182 |
+
// Hooks to run before and after the driver
|
| 183 |
+
// is destroyed. Each hook receives
|
| 184 |
+
// the following parameters:
|
| 185 |
+
// - element: Currently active element
|
| 186 |
+
// - step: The step object configured for the currently active
|
| 187 |
+
// - options.config: The current configuration options
|
| 188 |
+
// - options.state: The current state of the driver
|
| 189 |
+
onDestroyStarted?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void;;
|
| 190 |
+
onDestroyed?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void;;
|
| 191 |
+
|
| 192 |
+
// Hooks to run on button clicks. Each hook receives
|
| 193 |
+
// the following parameters:
|
| 194 |
+
// - element: The current DOM element of the step
|
| 195 |
+
// - step: The step object configured for the step
|
| 196 |
+
// - options.config: The current configuration options
|
| 197 |
+
// - options.state: The current state of the driver
|
| 198 |
+
onNextClick?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void;;
|
| 199 |
+
onPrevClick?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void;;
|
| 200 |
+
onCloseClick?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void;;
|
| 201 |
+
};
|
| 202 |
+
```
|
| 203 |
+
|
| 204 |
+
## State
|
| 205 |
+
|
| 206 |
+
You can access the current state of the driver by calling the `getState` method. It's also passed to the hooks and callbacks.
|
| 207 |
+
|
| 208 |
+
```typescript
|
| 209 |
+
type State = {
|
| 210 |
+
// Whether the driver is currently active or not
|
| 211 |
+
isInitialized?: boolean;
|
| 212 |
+
|
| 213 |
+
// Index of the currently active step if using
|
| 214 |
+
// as a product tour and have configured the
|
| 215 |
+
// steps array.
|
| 216 |
+
activeIndex?: number;
|
| 217 |
+
// DOM element of the currently active step
|
| 218 |
+
activeElement?: Element;
|
| 219 |
+
// Step object of the currently active step
|
| 220 |
+
activeStep?: DriveStep;
|
| 221 |
+
|
| 222 |
+
// DOM element that was previously active
|
| 223 |
+
previousElement?: Element;
|
| 224 |
+
// Step object of the previously active step
|
| 225 |
+
previousStep?: DriveStep;
|
| 226 |
+
|
| 227 |
+
// DOM elements for the popover i.e. including
|
| 228 |
+
// container, title, description, buttons etc.
|
| 229 |
+
popover?: PopoverDOM;
|
| 230 |
+
}
|
| 231 |
+
```
|
src/driver.ts
CHANGED
|
@@ -9,6 +9,8 @@ import "./driver.css";
|
|
| 9 |
|
| 10 |
export type DriveStep = {
|
| 11 |
element?: string | Element;
|
|
|
|
|
|
|
| 12 |
onDeselected?: DriverHook;
|
| 13 |
popover?: Popover;
|
| 14 |
};
|
|
@@ -132,7 +134,6 @@ export function driver(options: Config = {}) {
|
|
| 132 |
.replace("{{current}}", `${stepIndex + 1}`)
|
| 133 |
.replace("{{total}}", `${steps.length}`);
|
| 134 |
|
| 135 |
-
console.log(showProgress);
|
| 136 |
highlight({
|
| 137 |
...currentStep,
|
| 138 |
popover: {
|
|
@@ -168,7 +169,8 @@ export function driver(options: Config = {}) {
|
|
| 168 |
// the hook for when user calls `destroy`, driver will get into infinite loop
|
| 169 |
// not causing tour to be destroyed.
|
| 170 |
if (withOnDestroyStartedHook && onDestroyStarted) {
|
| 171 |
-
|
|
|
|
| 172 |
config: getConfig(),
|
| 173 |
state: getState(),
|
| 174 |
});
|
|
@@ -213,6 +215,9 @@ export function driver(options: Config = {}) {
|
|
| 213 |
init();
|
| 214 |
drive(stepIndex);
|
| 215 |
},
|
|
|
|
|
|
|
|
|
|
| 216 |
moveNext,
|
| 217 |
movePrevious,
|
| 218 |
hasNextStep: () => {
|
|
|
|
| 9 |
|
| 10 |
export type DriveStep = {
|
| 11 |
element?: string | Element;
|
| 12 |
+
onHighlightStarted?: DriverHook;
|
| 13 |
+
onHighlighted?: DriverHook;
|
| 14 |
onDeselected?: DriverHook;
|
| 15 |
popover?: Popover;
|
| 16 |
};
|
|
|
|
| 134 |
.replace("{{current}}", `${stepIndex + 1}`)
|
| 135 |
.replace("{{total}}", `${steps.length}`);
|
| 136 |
|
|
|
|
| 137 |
highlight({
|
| 138 |
...currentStep,
|
| 139 |
popover: {
|
|
|
|
| 169 |
// the hook for when user calls `destroy`, driver will get into infinite loop
|
| 170 |
// not causing tour to be destroyed.
|
| 171 |
if (withOnDestroyStartedHook && onDestroyStarted) {
|
| 172 |
+
const isActiveDummyElement = !activeElement || activeElement?.id === "driver-dummy-element";
|
| 173 |
+
onDestroyStarted(isActiveDummyElement ? undefined : activeElement, activeStep!, {
|
| 174 |
config: getConfig(),
|
| 175 |
state: getState(),
|
| 176 |
});
|
|
|
|
| 215 |
init();
|
| 216 |
drive(stepIndex);
|
| 217 |
},
|
| 218 |
+
setConfig: configure,
|
| 219 |
+
getConfig,
|
| 220 |
+
getState,
|
| 221 |
moveNext,
|
| 222 |
movePrevious,
|
| 223 |
hasNextStep: () => {
|
src/highlight.ts
CHANGED
|
@@ -70,8 +70,8 @@ function transferHighlight(toElement: Element, toStep: DriveStep) {
|
|
| 70 |
const isFromDummyElement = fromElement.id === "driver-dummy-element";
|
| 71 |
|
| 72 |
const isAnimatedTour = getConfig("animate");
|
| 73 |
-
const highlightStartedHook = getConfig("onHighlightStarted");
|
| 74 |
-
const highlightedHook = getConfig("onHighlighted");
|
| 75 |
const deselectedHook = fromStep?.onDeselected || getConfig("onDeselected");
|
| 76 |
|
| 77 |
const config = getConfig();
|
|
|
|
| 70 |
const isFromDummyElement = fromElement.id === "driver-dummy-element";
|
| 71 |
|
| 72 |
const isAnimatedTour = getConfig("animate");
|
| 73 |
+
const highlightStartedHook = toStep.onHighlightStarted || getConfig("onHighlightStarted");
|
| 74 |
+
const highlightedHook = toStep?.onHighlighted || getConfig("onHighlighted");
|
| 75 |
const deselectedHook = fromStep?.onDeselected || getConfig("onDeselected");
|
| 76 |
|
| 77 |
const config = getConfig();
|