diff --git a/demo/scripts/demo.js b/demo/scripts/demo.js index 0ff92f65e818d1037d4a51ca8fd3c3b087f901bf..fbe35143a3d0aceed4bd366adee351da6e392f3b 100644 --- a/demo/scripts/demo.js +++ b/demo/scripts/demo.js @@ -3,7 +3,7 @@ document.addEventListener("DOMContentLoaded", function () { const tourSteps = [ { - element: '#driver-demo-head', + element: document.getElementById('driver-demo-head'), popover: { title: 'Before we start', description: 'This is just one use-case, make sure to check out the rest of the docs below.', diff --git a/index.html b/index.html index dc4b06f65a4ba9c07a48e068e8ab10dc6f60e111..9f4eee4e0b9a5aae30053945637f232cad6f9e6f 100644 --- a/index.html +++ b/index.html @@ -292,9 +292,9 @@ driver.highlight({

Here are the set of options that you can pass in each step i.e. an item in array of steps or the object that you pass to highlight method

const stepDefinition = {
-  element: '#some-item', // Query selector for the item to be highlighted
-  popover: {             // There will be no popover if empty or not given
-    title: 'Title',      // Title on the popover
+  element: '#some-item',  // Query selector string or Node to be highlighted
+  popover: {              // There will be no popover if empty or not given
+    title: 'Title',       // Title on the popover
     description: 'Description', // Body of the popover
     showButtons: false,      // Do not show control buttons in footer
     closeBtnText: 'Close',   // Text on the close button for this step
diff --git a/readme.md b/readme.md
index dc5f40cf3c4920854ea34daa2e08c13871eecadc..8ceb7d0cdc7efdf9f84a3f94eb089014459cc081 100644
--- a/readme.md
+++ b/readme.md
@@ -182,7 +182,7 @@ Here are the set of options that you can pass while defining steps `defineSteps`
 
 ```javascript
 const stepDefinition = {
-  element: '#some-item',        // Query selector for the item to be highlighted
+  element: '#some-item',        // Query selector string or Node to be highlighted
   stageBackground: '#ffffff',   // This will override the one set in driver
   popover: {                    // There will be no popover if empty or not given
     title: 'Title',             // Title on the popover
diff --git a/src/common/utils.js b/src/common/utils.js
index 5f5eb9bb16832c1a6e9efb741c8339c16b0205a9..324a1072ffd21180c7598f4fe370f6863403750b 100644
--- a/src/common/utils.js
+++ b/src/common/utils.js
@@ -47,3 +47,11 @@ export const getStyleProperty = (element, propertyName, prefixVendor = false) =>
   return propertyValue && propertyValue.toLowerCase ? propertyValue.toLowerCase() : propertyValue;
 };
 
+/**
+ * Checks if the passed element is dom object or not
+ * @param element
+ * @returns {boolean}
+ */
+export const isDomElement = function (element) {
+  return element && typeof element === 'object' && 'nodeType' in element;
+};
diff --git a/src/index.js b/src/index.js
index 53bb84e09613eb01110dbefe20c9ff2597a61e29..b3523df61ec70f46f5a97d12ec3cf684563c7412 100644
--- a/src/index.js
+++ b/src/index.js
@@ -17,6 +17,7 @@ import {
   SHOULD_OUTSIDE_CLICK_NEXT,
 } from './common/constants';
 import Stage from './core/stage';
+import { isDomElement } from './common/utils';
 
 /**
  * Plugin class that drives the plugin
@@ -248,10 +249,6 @@ export default class Driver {
     this.steps = [];
 
     steps.forEach((step, index) => {
-      if (!step.element || typeof step.element !== 'string') {
-        throw new Error(`Element (query selector string) missing in step ${index}`);
-      }
-
       const element = this.prepareElementFromStep(step, steps, index);
       if (!element) {
         return;
@@ -272,13 +269,18 @@ export default class Driver {
    * @private
    */
   prepareElementFromStep(currentStep, allSteps = [], index = 0) {
-    let querySelector = '';
     let elementOptions = {};
+    let querySelector = currentStep;
 
-    // If it is just a query selector string
-    if (typeof currentStep === 'string') {
-      querySelector = currentStep;
-    } else {
+    // If the `currentStep` is step definition
+    // then grab the options and element from the definition
+    const isStepDefinition = typeof currentStep !== 'string' && !isDomElement(currentStep);
+
+    if (!currentStep || (isStepDefinition && !currentStep.element)) {
+      throw new Error(`Element is required in step ${index}`);
+    }
+
+    if (isStepDefinition) {
       querySelector = currentStep.element;
       elementOptions = {
         ...this.options,
@@ -286,7 +288,7 @@ export default class Driver {
       };
     }
 
-    const domElement = this.document.querySelector(querySelector);
+    const domElement = isDomElement(querySelector) ? querySelector : this.document.querySelector(querySelector);
     if (!domElement) {
       console.warn(`Element to highlight ${querySelector} not found`);
       return null;
diff --git a/types/index.d.ts b/types/index.d.ts
index a73a62863cab65497d8e9c21bd376ae18430d15f..383cef0599d2dae16582525fd8ef3fe70b6cdabc 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -138,7 +138,7 @@ declare module 'driver.js' {
       /**
        * Query selector representing the DOM Element
        */
-      element: string;
+      element: string | HTMLElement | Node;
 
       /**
        * Color of stage when this step is active