kamrify commited on
Commit
3223525
·
1 Parent(s): 76d4a2e

Normalize hooks and write docs

Browse files
docs/package.json CHANGED
@@ -16,7 +16,7 @@
16
  "@types/react": "^18.0.21",
17
  "@types/react-dom": "^18.0.6",
18
  "astro": "^2.7.0",
19
- "driver.js": "1.1.4-next.0",
20
  "react": "^18.0.0",
21
  "react-dom": "^18.0.0",
22
  "react-fast-marquee": "^1.6.0",
 
16
  "@types/react": "^18.0.21",
17
  "@types/react-dom": "^18.0.6",
18
  "astro": "^2.7.0",
19
+ "driver.js": "1.1.5-next.0",
20
  "react": "^18.0.0",
21
  "react-dom": "^18.0.0",
22
  "react-fast-marquee": "^1.6.0",
docs/pnpm-lock.yaml CHANGED
@@ -24,8 +24,8 @@ dependencies:
24
  specifier: ^2.7.0
25
  version: 2.7.0
26
  driver.js:
27
- specifier: 1.1.4-next.0
28
- version: 1.1.4-next.0
29
  react:
30
  specifier: ^18.0.0
31
  version: 18.2.0
@@ -1376,8 +1376,8 @@ packages:
1376
  /dlv@1.1.3:
1377
  resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
1378
 
1379
- /driver.js@1.1.4-next.0:
1380
- resolution: {integrity: sha512-3pxb5HcBKbYKpJCsHxNU+dNwfds6iUTmI1H33l+r5EkMa/5Mb11B+jejvHL0gRvbzkwx/8d6VudCDIwyw4R9cg==}
1381
  dev: false
1382
 
1383
  /dset@3.1.2:
 
24
  specifier: ^2.7.0
25
  version: 2.7.0
26
  driver.js:
27
+ specifier: 1.1.5-next.0
28
+ version: 1.1.5-next.0
29
  react:
30
  specifier: ^18.0.0
31
  version: 18.2.0
 
1376
  /dlv@1.1.3:
1377
  resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
1378
 
1379
+ /driver.js@1.1.5-next.0:
1380
+ resolution: {integrity: sha512-/S8err9QIkEerXGj44kssnqR8iTioDQplmA5Foj5g6AMxWMGTu6FaAjMrRksm50jVJ1SkyOPw8N7QEGdND5IfQ==}
1381
  dev: false
1382
 
1383
  /dset@3.1.2:
docs/src/components/CodeSample.tsx ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { Config, DriveStep } from "driver.js";
2
+ import { driver } from "driver.js";
3
+ import "driver.js/dist/driver.css";
4
+
5
+ type CodeSampleProps = {
6
+ heading: string;
7
+
8
+ config?: Config;
9
+ highlight?: DriveStep;
10
+ tour?: DriveStep[];
11
+
12
+ id?: string;
13
+ className?: string;
14
+ children: any;
15
+ };
16
+
17
+ export function CodeSample(props: CodeSampleProps) {
18
+ const { heading, id, children, className, config, highlight, tour } = props;
19
+
20
+ function onClick() {
21
+ if (highlight) {
22
+ const driverObj = driver();
23
+ driverObj.highlight(highlight);
24
+ } else if (tour) {
25
+ const driverObj = driver({
26
+ ...config,
27
+ steps: tour,
28
+ });
29
+ driverObj.drive();
30
+ }
31
+ }
32
+
33
+ return (
34
+ <div id={id} className={className}>
35
+ <p className="text-lg -mt-0 font-medium text-black -mb-3 rounded-md">{ heading }</p>
36
+ <div className="-mb-4">{children}</div>
37
+ <button onClick={onClick} className="w-full rounded-md bg-black p-2 text-white">
38
+ Show me an Example
39
+ </button>
40
+ </div>
41
+ );
42
+ }
docs/src/components/DocsHeader.astro CHANGED
@@ -3,7 +3,7 @@ import { getFormattedStars } from "../lib/github";
3
 
4
  const starCount = await getFormattedStars('kamranahmedse/driver.js');
5
  ---
6
- <div class="border-b flex items-center justify-between">
7
  <div class="w-[300px] text-right flex justify-end">
8
  <a href="/" class="flex items-center py-4 pr-5 border-r">
9
  <img src="/driver-head.svg" alt="Astro" class="w-8 h-8 mr-2" />
 
3
 
4
  const starCount = await getFormattedStars('kamranahmedse/driver.js');
5
  ---
6
+ <div class="border-b flex items-center justify-between" docs-header>
7
  <div class="w-[300px] text-right flex justify-end">
8
  <a href="/" class="flex items-center py-4 pr-5 border-r">
9
  <img src="/driver-head.svg" alt="Astro" class="w-8 h-8 mr-2" />
docs/src/components/FeatureMarquee.tsx CHANGED
@@ -2,18 +2,18 @@ import React from "react";
2
  import Marquee from "react-fast-marquee";
3
 
4
  const featureList = [
5
- "Open Source",
6
- "Written in TypeScript",
7
- "No dependencies",
8
- "Vanilla JavaScript",
9
  "Light-weight",
 
10
  "Feature Rich",
11
- "Highly Customizable",
12
- "Supports all Major Browsers",
 
13
  "Easy to use",
14
  "Accessible",
15
  "Frameworks Ready",
16
- "MIT Licensed",
17
  ];
18
 
19
  export function FeatureMarquee() {
 
2
  import Marquee from "react-fast-marquee";
3
 
4
  const featureList = [
5
+ "Supports all Major Browsers",
6
+ "Works on Mobile Devices",
7
+ "Highly Customizable",
 
8
  "Light-weight",
9
+ "No dependencies",
10
  "Feature Rich",
11
+ "MIT Licensed",
12
+ "Written in TypeScript",
13
+ "Vanilla JavaScript",
14
  "Easy to use",
15
  "Accessible",
16
  "Frameworks Ready",
 
17
  ];
18
 
19
  export function FeatureMarquee() {
docs/src/components/examples/SimpleHighlight.tsx CHANGED
@@ -1,11 +1,11 @@
1
  import { useEffect } from "react";
2
  import { Config, driver } from "driver.js";
3
- import "driver.js/dist/driver.js.css";
4
 
5
  import type { DriveStep } from "driver.js";
6
 
7
  type SimpleHighlightProps = {
8
- config: Config;
9
  step: DriveStep;
10
  };
11
 
 
1
  import { useEffect } from "react";
2
  import { Config, driver } from "driver.js";
3
+ import "driver.js/dist/driver.css";
4
 
5
  import type { DriveStep } from "driver.js";
6
 
7
  type SimpleHighlightProps = {
8
+ config?: Config;
9
  step: DriveStep;
10
  };
11
 
docs/src/content/guides/basic-usage.mdx CHANGED
@@ -4,29 +4,65 @@ groupTitle: "Introduction"
4
  sort: 2
5
  ---
6
 
7
- import { SimpleHighlight } from "../../components/examples/SimpleHighlight.tsx";
8
 
9
  Once installed, you can import and start using the library. Given below is a simple example of how to highlight a single element.
10
 
11
- <div id="simple-example">
12
- ```js
13
- import Driver from 'driver.js';
14
- import 'driver.js/dist/driver.js.css';
15
-
16
- const driver = new Driver();
17
- driver.highlight({
18
- element: '#some-element',
19
- popover: {
20
- title: 'Title for the Popover',
21
- description: 'Description for it',
22
- },
 
 
 
 
 
 
23
  });
24
- ```
25
- <SimpleHighlight step={{
26
- element: "#simple-example",
27
- popover: {
28
- title: "Title for the Popover",
29
- description: "Description for it",
30
- },
31
- }} client:load />
32
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  sort: 2
5
  ---
6
 
7
+ import { CodeSample } from "../../components/CodeSample.tsx";
8
 
9
  Once installed, you can import and start using the library. Given below is a simple example of how to highlight a single element.
10
 
11
+ <CodeSample heading='Highlighting a simple Element' id={"some-element"} highlight={{
12
+ element: '#some-element',
13
+ popover: {
14
+ title: 'Title for the Popover',
15
+ description: 'Description for it',
16
+ },
17
+ }} client:load>
18
+ ```js
19
+ import { driver } from "driver.js";
20
+ import "driver.js/dist/driver.css";
21
+
22
+ const driverObj = driver();
23
+ driverObj.highlight({
24
+ element: '#some-element',
25
+ popover: {
26
+ title: 'Title for the Popover',
27
+ description: 'Description for it',
28
+ },
29
  });
30
+ ```
31
+ </CodeSample>
32
+
33
+ There are many different options to customize the highlight e.g. change position, change overlay color, control interactions, change buttons etc. You can find more details about the options in the [API Reference](/api-reference).
34
+
35
+ The same configuration passed to the `highlight` method can be used to create a tour. Given below is a simple example of how to create a tour with a single step.
36
+
37
+ <CodeSample
38
+ heading={'Basic Tour Example'}
39
+ config={{
40
+ showProgress: true,
41
+ }}
42
+ tour={[
43
+ { element: '#tour-example', popover: { title: 'Highlight Anything', description: 'You can highlight anything on the page.' }},
44
+ { element: '#tour-example pre', popover: { title: 'Control with Keyboard', description: 'You can use your keyboard to highlight elements.' }},
45
+ { popover: { title: 'Control with Keyboard', description: 'You can use your keyboard to highlight elements.' }},
46
+ { element: '#tour-example code .line:first-child', popover: { title: 'Control with Code', description: 'You can use the code to highlight elements.' }},
47
+ { element: '#tour-example code .line:nth-child(2)', popover: { title: 'Control with Code', description: 'You can use the code to highlight elements.', side: "bottom", align: 'start' }},
48
+ ]}
49
+ id={"tour-example"}
50
+ client:load
51
+ >
52
+ ```js
53
+ import { driver } from "driver.js";
54
+ import "driver.js/dist/driver.css";
55
+
56
+ const driverObj = driver({
57
+ showProgress: true,
58
+ steps: [
59
+ { elment: '.page-header', popover: { title: 'Title', description: 'Description' } },
60
+ { element: '.top-nav', popover: { title: 'Title', description: 'Description' } },
61
+ { element: '.sidebar', popover: { title: 'Title', description: 'Description' } },
62
+ { element: '.footer', popover: { title: 'Title', description: 'Description' } },
63
+ ]
64
+ });
65
+
66
+ driver.drive();
67
+ ```
68
+ </CodeSample>
docs/src/content/guides/configuration.mdx ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: "Configuration"
3
+ groupTitle: "Introduction"
4
+ sort: 3
5
+ ---
6
+
7
+ import { CodeSample } from "../../components/CodeSample.tsx";
8
+
9
+ Driver.js is built to be highly configurable. You can configure the driver globally, or per step. You can also configure the driver on the fly, while it's running.
10
+
11
+ > Driver.js is written in TypeScript. Configuration options are mostly self-explanatory. Also, if you're using an IDE like WebStorm or VSCode, you'll get autocomplete and documentation for all the configuration options.
12
+
13
+ ## Popover Configuration
14
+
15
+ The popover is the main UI element of Driver.js. It's the element that highlights the target element, and shows the step content. You can configure the popover globally, or per step. Given below are some of the available configuration options.
16
+
17
+ ```typescript
18
+ type Popover = {
19
+ // Title and descriptions shown in the popover.
20
+ // You can use HTML in these. Also, you can
21
+ // omit one of these to show only the other.
22
+ title?: string;
23
+ description?: string;
24
+
25
+ // The position and alignment of the popover
26
+ // relative to the target element.
27
+ side?: "top" | "right" | "bottom" | "left";
28
+ align?: "start" | "center" | "end";
29
+
30
+ // Array of buttons to show in the popover.
31
+ // When highlighting a single element, there
32
+ // are no buttons by default. When showing
33
+ // a tour, the default buttons are "next",
34
+ // "previous" and "close".
35
+ showButtons?: ("next" | "previous" | "close")[];
36
+ // An array of buttons to disable. This is
37
+ // useful when you want to show some of the
38
+ // buttons, but disable some of them.
39
+ disableButtons?: ("next" | "previous" | "close")[];
40
+
41
+ // Text to show in the buttons. `doneBtnText`
42
+ // is used on the last step of a tour.
43
+ nextBtnText?: string;
44
+ prevBtnText?: string;
45
+ doneBtnText?: string;
46
+
47
+ // Whether to show the progress text in popover.
48
+ showProgress?: boolean;
49
+ // Template for the progress text. You can use
50
+ // the following placeholders in the template:
51
+ // - {{current}}: The current step number
52
+ // - {{total}}: Total number of steps
53
+ // Defaults to following if `showProgress` is true:
54
+ // - "{{current}} of {{total}}"
55
+ progressText?: string;
56
+
57
+ // Custom class to add to the popover element.
58
+ // This can be used to style the popover.
59
+ popoverClass?: string;
60
+
61
+ // Hook to run after the popover is rendered.
62
+ // You can modify the popover element here.
63
+ // Parameter is an object with references to
64
+ // the popover DOM elements such as buttons
65
+ // title, descriptions, body, etc.
66
+ onPopoverRendered?: (popover: PopoverDOM) => void;
67
+
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 target 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
75
+ onNextClick?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void
76
+ onPrevClick?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void
77
+ onCloseClick?: (element?: Element, step: DriveStep, options: { config: Config; state: State }) => void
78
+ }
79
+ ```
docs/src/content/guides/installation.mdx CHANGED
@@ -23,18 +23,18 @@ Alternatively, you can use CDN and include the script in your HTML file:
23
 
24
  ```html
25
  <script src="https://cdn.jsdelivr.net/npm/driver.js@1.1.1-next.0/dist/driver.js.iife.js"></script>
26
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/driver.js@1.1.1-next.0/dist/style.css"/>
27
  ```
28
 
29
  ## Start Using
30
  Once installed, you can import the package in your project. The following example shows how to highlight an element:
31
 
32
  ```js
33
- import Driver from "driver.js";
34
  import "driver.js/dist/driver.css";
35
 
36
- const driver = new Driver();
37
- driver.highlight({
38
  element: "#some-element",
39
  popover: {
40
  title: "Title",
@@ -48,9 +48,9 @@ driver.highlight({
48
  If you are using the CDN, you will have to use the package from the `window` object:
49
 
50
  ```js
51
- const Driver = window.driver.js.driver;
52
 
53
- const driver = new Driver();
54
  driver.highlight({
55
  element: "#some-element",
56
  popover: {
 
23
 
24
  ```html
25
  <script src="https://cdn.jsdelivr.net/npm/driver.js@1.1.1-next.0/dist/driver.js.iife.js"></script>
26
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/driver.js@1.1.1-next.0/dist/driver.css"/>
27
  ```
28
 
29
  ## Start Using
30
  Once installed, you can import the package in your project. The following example shows how to highlight an element:
31
 
32
  ```js
33
+ import driver from "driver.js";
34
  import "driver.js/dist/driver.css";
35
 
36
+ const driverObj = driver();
37
+ driverObj.highlight({
38
  element: "#some-element",
39
  popover: {
40
  title: "Title",
 
48
  If you are using the CDN, you will have to use the package from the `window` object:
49
 
50
  ```js
51
+ const driver = window.driver.js.driver;
52
 
53
+ const driverObj = driver();
54
  driver.highlight({
55
  element: "#some-element",
56
  popover: {
src/config.ts CHANGED
@@ -2,7 +2,7 @@ import { DriveStep } from "./driver";
2
  import { AllowedButtons, PopoverDOM } from "./popover";
3
  import { State } from "./state";
4
 
5
- type DriverHook = (element: Element | undefined, step: DriveStep, opts: { config: Config; state: State }) => void;
6
 
7
  export type Config = {
8
  steps?: DriveStep[];
 
2
  import { AllowedButtons, PopoverDOM } from "./popover";
3
  import { State } from "./state";
4
 
5
+ export type DriverHook = (element: Element | undefined, step: DriveStep, opts: { config: Config; state: State }) => void;
6
 
7
  export type Config = {
8
  steps?: DriveStep[];
src/driver.ts CHANGED
@@ -1,7 +1,7 @@
1
  import { AllowedButtons, destroyPopover, Popover } from "./popover";
2
  import { destroyStage } from "./stage";
3
  import { destroyEvents, initEvents, requireRefresh } from "./events";
4
- import { Config, configure, getConfig } from "./config";
5
  import { destroyHighlight, highlight } from "./highlight";
6
  import { destroyEmitter, listen } from "./emitter";
7
  import { getState, resetState, setState } from "./state";
@@ -9,7 +9,7 @@ import "./driver.css";
9
 
10
  export type DriveStep = {
11
  element?: string | Element;
12
- onDeselected?: (element: Element | undefined, step: DriveStep) => void;
13
  popover?: Popover;
14
  };
15
 
 
1
  import { AllowedButtons, destroyPopover, Popover } from "./popover";
2
  import { destroyStage } from "./stage";
3
  import { destroyEvents, initEvents, requireRefresh } from "./events";
4
+ import { Config, configure, DriverHook, getConfig } from "./config";
5
  import { destroyHighlight, highlight } from "./highlight";
6
  import { destroyEmitter, listen } from "./emitter";
7
  import { getState, resetState, setState } from "./state";
 
9
 
10
  export type DriveStep = {
11
  element?: string | Element;
12
+ onDeselected?: DriverHook;
13
  popover?: Popover;
14
  };
15
 
src/popover.ts CHANGED
@@ -1,5 +1,5 @@
1
  import { bringInView } from "./utils";
2
- import { getConfig } from "./config";
3
  import { getState, setState } from "./state";
4
  import { DriveStep } from "./driver";
5
  import { onDriverClick } from "./events";
@@ -31,9 +31,9 @@ export type Popover = {
31
  onPopoverRendered?: (popover: PopoverDOM) => void;
32
 
33
  // Button callbacks
34
- onNextClick?: (element: Element | undefined, step: DriveStep) => void;
35
- onPrevClick?: (element: Element | undefined, step: DriveStep) => void;
36
- onCloseClick?: (element: Element | undefined, step: DriveStep) => void;
37
  };
38
 
39
  export type PopoverDOM = {
 
1
  import { bringInView } from "./utils";
2
+ import { DriverHook, getConfig } from "./config";
3
  import { getState, setState } from "./state";
4
  import { DriveStep } from "./driver";
5
  import { onDriverClick } from "./events";
 
31
  onPopoverRendered?: (popover: PopoverDOM) => void;
32
 
33
  // Button callbacks
34
+ onNextClick?: DriverHook;
35
+ onPrevClick?: DriverHook;
36
+ onCloseClick?: DriverHook;
37
  };
38
 
39
  export type PopoverDOM = {