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();
|