From 83ec6f8bcc6cca16945751e573f8401aa4737c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Kuna?= <1282324+codecalm@users.noreply.github.com> Date: Mon, 8 Dec 2025 21:08:22 +0100 Subject: [PATCH] feat: add Tour component using Driver.js (#2549) --- .changeset/silly-crabs-walk.md | 7 ++ core/libs.json | 9 ++ core/package.json | 3 +- pnpm-lock.yaml | 8 ++ preview/pages/tour.html | 223 +++++++++++++++++++++++++++++++++ shared/data/menu.json | 4 + shared/includes/ui/button.html | 2 +- 7 files changed, 254 insertions(+), 2 deletions(-) create mode 100644 .changeset/silly-crabs-walk.md create mode 100644 preview/pages/tour.html diff --git a/.changeset/silly-crabs-walk.md b/.changeset/silly-crabs-walk.md new file mode 100644 index 000000000..5d0f04d20 --- /dev/null +++ b/.changeset/silly-crabs-walk.md @@ -0,0 +1,7 @@ +--- +"@tabler/core": patch +"@tabler/preview": patch +--- + +Added Driver.js library integration and Tour demo page for interactive product tours and onboarding guides. + diff --git a/core/libs.json b/core/libs.json index 00a57a7d7..e9fe1cc5b 100644 --- a/core/libs.json +++ b/core/libs.json @@ -166,5 +166,14 @@ "dist/turbo.es2017-umd.js" ], "head": true + }, + "driver.js": { + "npm": "driver.js", + "js": [ + "dist/driver.js.iife.js" + ], + "css": [ + "dist/driver.css" + ] } } diff --git a/core/package.json b/core/package.json index 5a3162a74..c6f1cf2ec 100644 --- a/core/package.json +++ b/core/package.json @@ -178,7 +178,8 @@ "sortablejs": "^1.15.6", "star-rating.js": "^4.3.1", "tom-select": "^2.4.3", - "typed.js": "^2.1.0" + "typed.js": "^2.1.0", + "driver.js": "^1.0.0" }, "directories": { "doc": "docs" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 342f323b0..491fc0bc3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -130,6 +130,9 @@ importers: countup.js: specifier: ^2.9.0 version: 2.9.0 + driver.js: + specifier: ^1.0.0 + version: 1.4.0 dropzone: specifier: ^6.0.0-beta.2 version: 6.0.0-beta.2 @@ -1792,6 +1795,9 @@ packages: resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} engines: {node: '>=10'} + driver.js@1.4.0: + resolution: {integrity: sha512-Gm64jm6PmcU+si21sQhBrTAM1JvUrR0QhNmjkprNLxohOBzul9+pNHXgQaT9lW84gwg9GMLB3NZGuGolsz5uew==} + dropzone@6.0.0-beta.2: resolution: {integrity: sha512-k44yLuFFhRk53M8zP71FaaNzJYIzr99SKmpbO/oZKNslDjNXQsBTdfLs+iONd0U0L94zzlFzRnFdqbLcs7h9fQ==} @@ -5191,6 +5197,8 @@ snapshots: dotenv@8.6.0: {} + driver.js@1.4.0: {} + dropzone@6.0.0-beta.2: dependencies: '@swc/helpers': 0.2.14 diff --git a/preview/pages/tour.html b/preview/pages/tour.html new file mode 100644 index 000000000..6f92ec6e8 --- /dev/null +++ b/preview/pages/tour.html @@ -0,0 +1,223 @@ +--- +title: Driver Tour +page-header: Driver Tour +page-libs: [driver.js] +page-menu: plugins.tour +layout: default +permalink: tour.html +--- + +
+
+
+
+

Product Tour Example

+
+ {% include "ui/button.html" id="start-tour" text="Start Tour" icon="play" color="primary" element="button" %} +
+
+
+

+ Click the "Start Tour" button to begin an interactive tour of this page. + The tour will guide you through different elements and features. +

+
+
+
+
+
+
+

Welcome Section

+
+
+

This is the first card in our tour. It demonstrates how Driver.js highlights elements on the page.

+
+ {% include "ui/button.html" text="Action Button" color="primary" element="button" %} + {% include "ui/button.html" text="Secondary" element="button" %} +
+
+
+
+ +
+
+
+

Features Section

+
+
+

This card shows additional features and demonstrates the tour's ability to navigate between different + elements.

+
+ + +
+
+
+
+
+
+
+

Navigation Example

+
+
+

This is a full-width card that demonstrates how the tour works with larger elements.

+
+ + + + + + + + + + + + + + + + + + + + + + + +
NameStatusRole
John Doe{% include "ui/badge.html" text="Active" color="success" %}Developer + {% include "ui/button.html" text="Edit" size="sm" href="#" %} +
Jane Smith{% include "ui/badge.html" text="Pending" color="warning" %}Designer + {% include "ui/button.html" text="Edit" size="sm" href="#" %} +
+
+
+
+
+ +
+
+
+
+ {% include "ui/icon.html" icon="settings" size="48" %} +
+

Settings

+

Configure your application settings here.

+
+
+
+ +
+
+
+
+ {% include "ui/icon.html" icon="users" size="48" %} +
+

Users

+

Manage your team members and permissions.

+
+
+
+ +
+
+
+
+ {% include "ui/icon.html" icon="chart-bar" size="48" %} +
+

Analytics

+

View your application statistics and reports.

+
+
+
+
+ + + diff --git a/shared/data/menu.json b/shared/data/menu.json index 93206751e..632a5adc2 100644 --- a/shared/data/menu.json +++ b/shared/data/menu.json @@ -479,6 +479,10 @@ "url": "maps-vector.html", "title": "Map vector" }, + "tour": { + "url": "tour.html", + "title": "Tour" + }, "turbo": { "url": "turbo-loader.html", "title": "Turbo loader" diff --git a/shared/includes/ui/button.html b/shared/includes/ui/button.html index 4b10d981b..713e013f2 100644 --- a/shared/includes/ui/button.html +++ b/shared/includes/ui/button.html @@ -18,7 +18,7 @@ {% endif %} {% assign e = include.element | default: 'a' %} -<{{ e }}{% if e == 'a' %} href="{{ href }}"{% endif %}{% if include.type %} type="{{ include.type }}"{% endif %} class="btn{% if include.height %} btn-{{ include.height }}{% endif %}{% if color %} btn-{% if include.outline %}outline-{% elsif include.ghost %}ghost-{% endif %}{{ color }}{% endif %}{% if include.disabled %} disabled{% endif %}{% if include.square %} btn-square{% endif %}{% if include.loading %} btn-loading{% endif %}{% if include.pill %} btn-pill{% endif %}{% if include['size'] %} btn-{{ include['size'] }}{% endif %}{% if include.class %} {{ include.class }}{% endif %}{% if include.block %} w-100{% endif %}{% if include.link %} btn-link{% endif %}{% if include.icon-only %} btn-icon{% endif %}"{% if include.external %} target="_blank" rel="noreferrer"{% endif %}{% if include.modal-id %} data-bs-toggle="modal" data-bs-target="#modal-{{ include.modal-id }}"{% endif %}{% if include.toast-id %} data-bs-toggle="toast" data-bs-target="#toast-{{ include.toast-id }}"{% endif %}{% if include.icon-only %} aria-label="{{ include.text | default: "Button" }}"{% endif %}{% if include.dismiss %} data-bs-dismiss="modal"{% endif %}> +<{{ e }}{% if e == 'a' %} href="{{ href }}"{% endif %}{% if include.type %} type="{{ include.type }}"{% endif %}{% if include.id %} id="{{ include.id }}"{% endif %} class="btn{% if include.height %} btn-{{ include.height }}{% endif %}{% if color %} btn-{% if include.outline %}outline-{% elsif include.ghost %}ghost-{% endif %}{{ color }}{% endif %}{% if include.disabled %} disabled{% endif %}{% if include.square %} btn-square{% endif %}{% if include.loading %} btn-loading{% endif %}{% if include.pill %} btn-pill{% endif %}{% if include['size'] %} btn-{{ include['size'] }}{% endif %}{% if include.class %} {{ include.class }}{% endif %}{% if include.block %} w-100{% endif %}{% if include.link %} btn-link{% endif %}{% if include.icon-only %} btn-icon{% endif %}"{% if include.external %} target="_blank" rel="noreferrer"{% endif %}{% if include.modal-id %} data-bs-toggle="modal" data-bs-target="#modal-{{ include.modal-id }}"{% endif %}{% if include.toast-id %} data-bs-toggle="toast" data-bs-target="#toast-{{ include.toast-id }}"{% endif %}{% if include.icon-only %} aria-label="{{ include.text | default: "Button" }}"{% endif %}{% if include.dismiss %} data-bs-dismiss="modal"{% endif %}> {% if include.spinner %} {% include "ui/spinner.html" color=false size="sm" class=spinner-class element="span" %}{% endif %} {% if include.icon %}{% include "ui/icon.html" icon=include.icon color=include.icon-color %}{% endif %}