kamrify commited on
Commit
d0e0b03
·
1 Parent(s): 647be2c

Add support for listening to events

Browse files
Files changed (7) hide show
  1. index.html +20 -1
  2. src/config.ts +1 -1
  3. src/driver.ts +1 -2
  4. src/emitter.ts +1 -1
  5. src/events.ts +1 -1
  6. src/popover.ts +53 -1
  7. src/style.css +4 -0
index.html CHANGED
@@ -161,7 +161,7 @@
161
  <br />
162
  <p>You can Attach events to buttons.</p>
163
  <div class="buttons">
164
- <button id="button-config-events">Global Button Listeners</button>
165
  </div>
166
 
167
  <ul>
@@ -395,6 +395,25 @@ npm install driver.js</pre
395
  });
396
  });
397
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
398
  document.getElementById("is-active-btn").addEventListener("click", () => {
399
  alert(driver().isActive());
400
  });
 
161
  <br />
162
  <p>You can Attach events to buttons.</p>
163
  <div class="buttons">
164
+ <button id="button-config-events">Button Listeners</button>
165
  </div>
166
 
167
  <ul>
 
395
  });
396
  });
397
 
398
+ document.getElementById("button-config-events").addEventListener("click", () => {
399
+ const driverObj = driver({
400
+ onNextClick: () => alert("Next Clicked"),
401
+ onPrevClick: () => alert("Previous Clicked"),
402
+ onCloseClick: () => {
403
+ driverObj.destroy();
404
+ },
405
+ });
406
+
407
+ driverObj.highlight({
408
+ popover: {
409
+ title: "Global Button Listener",
410
+ description: "You can listen to the button clicks globally.",
411
+ showButtons: ["close", "next", "previous"],
412
+ onPrevClick: () => alert("Overriding — Previous Clicked"),
413
+ },
414
+ });
415
+ });
416
+
417
  document.getElementById("is-active-btn").addEventListener("click", () => {
418
  alert(driver().isActive());
419
  });
src/config.ts CHANGED
@@ -26,7 +26,7 @@ export type Config = {
26
 
27
  // Event based callbacks, called upon events
28
  onNextClick?: (element: Element | undefined, step: DriveStep) => void;
29
- onPreviousClick?: (element: Element | undefined, step: DriveStep) => void;
30
  onCloseClick?: (element: Element | undefined, step: DriveStep) => void;
31
  };
32
 
 
26
 
27
  // Event based callbacks, called upon events
28
  onNextClick?: (element: Element | undefined, step: DriveStep) => void;
29
+ onPrevClick?: (element: Element | undefined, step: DriveStep) => void;
30
  onCloseClick?: (element: Element | undefined, step: DriveStep) => void;
31
  };
32
 
src/driver.ts CHANGED
@@ -42,7 +42,7 @@ export function driver(options: Config = {}) {
42
  initEvents();
43
 
44
  listen("overlayClick", handleClose);
45
- listen("escape", handleClose);
46
  }
47
 
48
  function destroy() {
@@ -74,7 +74,6 @@ export function driver(options: Config = {}) {
74
  },
75
  drive: (steps: DriveStep[]) => console.log(steps),
76
  highlight: (step: DriveStep) => {
77
- console.log(step.popover?.showButtons);
78
  init();
79
  highlight({
80
  ...step,
 
42
  initEvents();
43
 
44
  listen("overlayClick", handleClose);
45
+ listen("escapePress", handleClose);
46
  }
47
 
48
  function destroy() {
 
74
  },
75
  drive: (steps: DriveStep[]) => console.log(steps),
76
  highlight: (step: DriveStep) => {
 
77
  init();
78
  highlight({
79
  ...step,
src/emitter.ts CHANGED
@@ -1,4 +1,4 @@
1
- type allowedEvents = "overlayClick" | "escape";
2
 
3
  let registeredListeners: Partial<{ [key in allowedEvents]: () => void }> = {};
4
 
 
1
+ type allowedEvents = "overlayClick" | "escapePress" | "nextClick" | "prevClick" | "closeClick";
2
 
3
  let registeredListeners: Partial<{ [key in allowedEvents]: () => void }> = {};
4
 
src/events.ts CHANGED
@@ -13,7 +13,7 @@ export function requireRefresh() {
13
 
14
  function onKeyup(e: KeyboardEvent) {
15
  if (e.key === "Escape") {
16
- emit("escape");
17
  }
18
  }
19
 
 
13
 
14
  function onKeyup(e: KeyboardEvent) {
15
  if (e.key === "Escape") {
16
+ emit("escapePress");
17
  }
18
  }
19
 
src/popover.ts CHANGED
@@ -2,6 +2,8 @@ import { bringInView } from "./utils";
2
  import { getConfig } from "./config";
3
  import { getState, setState } from "./state";
4
  import { DriveStep } from "./driver";
 
 
5
 
6
  export type Side = "top" | "right" | "bottom" | "left" | "over";
7
  export type Alignment = "start" | "center" | "end";
@@ -15,10 +17,16 @@ export type Popover = {
15
 
16
  showButtons?: AllowedButtons[];
17
 
 
18
  doneBtnText?: string;
19
  closeBtnText?: string;
20
  nextBtnText?: string;
21
  prevBtnText?: string;
 
 
 
 
 
22
  };
23
 
24
  export type PopoverDOM = {
@@ -80,7 +88,6 @@ export function renderPopover(element: Element, step: DriveStep) {
80
  const showButtonsConfig: AllowedButtons[] =
81
  popoverShowButtons !== undefined ? popoverShowButtons : getConfig("showButtons")!;
82
 
83
- console.log(popoverShowButtons);
84
  if (showButtonsConfig?.length! > 0) {
85
  popover.footer.style.display = "flex";
86
 
@@ -111,6 +118,51 @@ export function renderPopover(element: Element, step: DriveStep) {
111
  const popoverArrow = popover.arrow;
112
  popoverArrow.className = "driver-popover-arrow";
113
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  setState("popover", popover);
115
 
116
  repositionPopover(element, step);
 
2
  import { getConfig } from "./config";
3
  import { getState, setState } from "./state";
4
  import { DriveStep } from "./driver";
5
+ import { onDriverClick } from "./events";
6
+ import { emit } from "./emitter";
7
 
8
  export type Side = "top" | "right" | "bottom" | "left" | "over";
9
  export type Alignment = "start" | "center" | "end";
 
17
 
18
  showButtons?: AllowedButtons[];
19
 
20
+ // Button texts
21
  doneBtnText?: string;
22
  closeBtnText?: string;
23
  nextBtnText?: string;
24
  prevBtnText?: string;
25
+
26
+ // Button callbacks
27
+ onNextClick?: (element: Element | undefined, step: DriveStep) => void;
28
+ onPrevClick?: (element: Element | undefined, step: DriveStep) => void;
29
+ onCloseClick?: (element: Element | undefined, step: DriveStep) => void;
30
  };
31
 
32
  export type PopoverDOM = {
 
88
  const showButtonsConfig: AllowedButtons[] =
89
  popoverShowButtons !== undefined ? popoverShowButtons : getConfig("showButtons")!;
90
 
 
91
  if (showButtonsConfig?.length! > 0) {
92
  popover.footer.style.display = "flex";
93
 
 
118
  const popoverArrow = popover.arrow;
119
  popoverArrow.className = "driver-popover-arrow";
120
 
121
+ // Handles the popover button clicks
122
+ onDriverClick(
123
+ popover.wrapper,
124
+ e => {
125
+ const target = e.target as HTMLElement;
126
+
127
+ const onNextClick = step.popover?.onNextClick || getConfig("onNextClick");
128
+ const onPrevClick = step.popover?.onPrevClick || getConfig("onPrevClick");
129
+ const onCloseClick = step.popover?.onCloseClick || getConfig("onCloseClick");
130
+
131
+ if (target.classList.contains("driver-popover-next-btn")) {
132
+ // If the user has provided a custom callback, call it
133
+ // otherwise, emit the event.
134
+ if (onNextClick) {
135
+ return onNextClick(element, step);
136
+ } else {
137
+ return emit("nextClick");
138
+ }
139
+ }
140
+
141
+ if (target.classList.contains("driver-popover-prev-btn")) {
142
+ if (onPrevClick) {
143
+ return onPrevClick(element, step);
144
+ } else {
145
+ return emit("prevClick");
146
+ }
147
+ }
148
+
149
+ if (target.classList.contains("driver-popover-close-btn")) {
150
+ if (onCloseClick) {
151
+ return onCloseClick(element, step);
152
+ } else {
153
+ return emit("closeClick");
154
+ }
155
+ }
156
+
157
+ return undefined;
158
+ },
159
+ target => {
160
+ // Only prevent the default action if we're clicking on a button
161
+ // This allows us to have links inside the popover title and description
162
+ return !popover?.description.contains(target) && !popover?.title.contains(target);
163
+ }
164
+ );
165
+
166
  setState("popover", popover);
167
 
168
  repositionPopover(element, step);
src/style.css CHANGED
@@ -97,6 +97,10 @@
97
  border-radius: 3px;
98
  }
99
 
 
 
 
 
100
  .driver-popover-navigation-btns {
101
  display: flex;
102
  flex-grow: 1;
 
97
  border-radius: 3px;
98
  }
99
 
100
+ .driver-popover-footer button:hover {
101
+ background-color: #f7f7f7;
102
+ }
103
+
104
  .driver-popover-navigation-btns {
105
  display: flex;
106
  flex-grow: 1;