Disclaimer: This article was written by AI and may contain inaccuracies or errors. 免責事項: この記事はAIによって作成されたものであり、不正確な情報やエラーが含まれている可能性があります。
Table of contents
Open Table of contents
はじめに
また一つ、興味深いツールに出会ってしまった。Driver.js というプロジェクトである。
世間では様々なプロダクトツアーライブラリが乱立しているが、私がこのライブラリに惹かれたのは、その設計思想の明確さだ。作者は「これは単なるツアーライブラリではない」と明言している。確かに、実際に動かしてみると、その言葉に偽りはなかった。
このライブラリは、ユーザーの視線を「操る」ための汎用的なエンジンとして設計されている。プロダクトツアーは、その数多くのユースケースの一つに過ぎない。
Driver.jsとは
Driver.jsは、ページ上の任意の要素をハイライトし、オーバーレイとポップオーバーを表示するためのVanilla JavaScriptライブラリである。
主な特徴
実際にコードを読み、動かして確認した特徴を列挙する:
- 超軽量 - わずか5KB(gzip圧縮時)。他の類似ライブラリが12KB以上であることを考えると、驚異的な軽さだ
- ゼロ依存 - 外部ライブラリに一切依存しない
- TypeScript製 - 型安全な開発をサポート
- 高度にカスタマイズ可能 - 豊富なAPIとフックを提供
- キーボード完全対応 - すべての操作がキーボードで可能
- 全ブラウザ対応 - 一貫した挙動を保証
アーキテクチャの考察
ソースコードを確認したところ、モジュール構成が実に美しい:
src/
├── driver.ts # メインエントリーポイント
├── config.ts # 設定管理
├── state.ts # 状態管理
├── highlight.ts # ハイライト処理
├── overlay.ts # オーバーレイ処理
├── popover.ts # ポップオーバー処理
├── events.ts # イベント処理
└── emitter.ts # イベントエミッター
各モジュールが単一責任の原則に従っており、関心の分離が徹底されている。これは長期的なメンテナンス性を考慮した設計だ。
実際に試してみる
理論だけでは物足りない。実際にデモアプリケーションを構築して、その挙動を確認してみた。
セットアップ
まず、リポジトリをクローンしてビルドする:
# リポジトリをクローン
git clone https://github.com/kamranahmedse/driver.js.git
cd driver.js
# 依存関係をインストール
pnpm install
# ビルド
pnpm run build
ビルドは驚くほど高速だ。TypeScriptのコンパイルとViteによるバンドル、型定義の生成まで含めて、わずか数秒で完了する。
基本的な使い方
最もシンプルな使い方から始めよう。単一の要素をハイライトする例だ:
import { driver } from "driver.js";
import "driver.js/dist/driver.css";
const driverObj = driver();
driverObj.highlight({
element: "#target-element",
popover: {
title: "タイトル",
description: "説明文がここに入ります。",
},
});
このコードを実行すると、指定した要素が浮き上がり、周囲が暗くなる。ユーザーの注意は自然とハイライトされた要素に向かう。実に効果的だ。
プロダクトツアーの実装
複数のステップを持つツアーも簡単に作れる:
const driverObj = driver({
showProgress: true,
steps: [
{
element: "#header",
popover: {
title: "ようこそ!",
description: "これはプロダクトツアーの最初のステップです。",
side: "bottom",
align: "center",
},
},
{
element: "#feature-1",
popover: {
title: "機能1",
description: "この機能について説明します。",
side: "right",
align: "start",
},
},
{
popover: {
title: "ツアー完了!",
description: "最後のステップでは要素を指定しなくてもOKです。",
},
},
],
});
driverObj.drive();
ステップの配列を定義し、drive() メソッドを呼ぶだけだ。シンプルでありながら、強力である。
実践的なデモアプリケーション
私は以下のような機能を持つデモを作成した:
- プロダクトツアー - 複数のステップを順番に案内
- 単一要素のハイライト - 特定の要素だけを強調
- カスタムスタイル - CSSでポップオーバーの見た目を変更
- ポップオーバーなし - 純粋なハイライトのみ
実際にブラウザで動かしてみると、アニメーションが滑らかで、レスポンスも良好だ。5KBという軽量さを感じさせない完成度である。
コードの深掘り
興味深いのは、driver.tsの実装だ。主要なメソッドを見てみよう:
export interface Driver {
isActive: () => boolean;
refresh: () => void;
drive: (stepIndex?: number) => void;
setConfig: (config: Config) => void;
setSteps: (steps: DriveStep[]) => void;
highlight: (step: DriveStep) => void;
moveNext: () => void;
movePrevious: () => void;
moveTo: (index: number) => void;
destroy: () => void;
// ... その他のメソッド
}
APIが非常に直感的だ。drive()でツアーを開始し、highlight()で単一要素をハイライトする。destroy()で後片付け。必要なものが揃っていて、余計なものがない。
イベントフックの活用
Driver.jsの真の力は、イベントフックにある:
const driverObj = driver({
onHighlightStarted: (element, step, options) => {
console.log("ハイライト開始:", element);
},
onHighlighted: (element, step, options) => {
console.log("ハイライト完了:", element);
},
onDeselected: (element, step, options) => {
console.log("ハイライト解除:", element);
},
});
これらのフックを使えば、各ステップで任意の処理を実行できる。例えば、特定のステップでAPIを呼んだり、アナリティクスを送信したりといったことが可能だ。
ユースケースの考察
公式ドキュメントでは、ツアー以外のユースケースとして以下を挙げている:
- コンテキストヘルプ - フォーム入力時にヘルプを表示
- フォーカスシフト - ユーザーの注意を必要な場所に誘導
- 「ライトを消す」効果 - 動画プレーヤーなどで周囲を暗くする
- シンプルなモーダル - 通知やダイアログの代わりに使用
実際に試してみて、これらのユースケースがいずれも自然に実現できることを確認した。特に「フォーカスシフト」の概念は興味深い。複雑なUIで、ユーザーが次に何をすべきか分からなくなった時、Driver.jsは静かに正しい方向を示してくれる。
カスタマイズ性の高さ
Driver.jsの設定オプションは豊富だ:
const driverObj = driver({
animate: true, // アニメーション有効
overlayColor: "rgba(0, 0, 0, 0.8)", // オーバーレイの色
smoothScroll: true, // スムーズスクロール
allowClose: true, // Escで閉じる
overlayClickBehavior: "close", // オーバーレイクリックで閉じる
stagePadding: 10, // ハイライト周囲のパディング
stageRadius: 5, // ハイライトの角丸
popoverClass: "my-custom-class", // カスタムCSSクラス
progressText: "{{current}}/{{total}}", // 進捗表示のテキスト
showButtons: ["next", "previous", "close"], // 表示するボタン
// ... さらに多数のオプション
});
CSSも完全にカスタマイズ可能だ。デフォルトのスタイルが気に入らなければ、独自のCSSを当てればいい。クラス名は .driver-popover や .driver-popover-title といった具合に、分かりやすい命名がされている。
パフォーマンスについて
実際に動かしてみて、パフォーマンスに問題は感じなかった。要素のハイライト時も、ステップの移動時も、遅延は皆無だ。
ソースコードを見ると、いくつかの最適化が施されている:
- DOMクエリのキャッシング
- イベントリスナーの適切な管理
- 不要な再計算の回避
5KBという軽量さに加え、実行時のパフォーマンスも優れている。これは実用に耐えるライブラリだ。
気づいた点と制約
完璧なライブラリは存在しない。いくつか気づいた点を記しておく:
制約事項
- 固定要素の扱い -
position: fixedの要素は、場合によってハイライトがずれることがある - 動的なコンテンツ - DOMが動的に変化する場合、
refresh()を呼ぶ必要がある - モバイル対応 - 小さな画面では、ポップオーバーの配置に工夫が必要
しかし、これらは許容範囲内だ
これらの制約は、ライブラリの設計上の選択の結果であり、致命的な問題ではない。むしろ、シンプルさを保つための妥協点だと考えられる。
実際、refresh() メソッドが用意されている時点で、作者は動的コンテンツのケースを想定している。モバイル対応についても、レスポンシブな設定をすれば対応可能だ。
他のライブラリとの比較
この領域には、Intro.js、Shepherd.js、Joyride など、多くの競合が存在する。
Driver.jsの差別化ポイントは:
- 圧倒的な軽量さ - 5KB vs 12KB以上
- ゼロ依存 - React、jQueryなどに依存しない
- 汎用性 - ツアー以外のユースケースを明示的にサポート
- TypeScript - 最初から型安全
私が山奥で静かにコードを書く際、余計な依存関係は避けたい。その点で、Driver.jsは理想的だ。
実装のヒント
実際に使ってみて得た知見をいくつか共有しよう:
1. ステップの設計
ツアーのステップは、多すぎても少なすぎてもいけない。私の経験では、5〜7ステップが適切だ。それ以上になると、ユーザーは飽きてしまう。
2. ポップオーバーの配置
side と align オプションで配置を制御できるが、自動調整も効く。画面端に要素がある場合、Driver.jsは賢く配置を調整してくれる。
popover: {
title: 'タイトル',
description: '説明',
side: "bottom", // top, bottom, left, right
align: 'center' // start, center, end
}
3. ライフサイクルの管理
destroy() を呼ぶのを忘れずに。特にSPAでは、コンポーネントのクリーンアップ時に必ず呼ぶべきだ。
// React の例
useEffect(() => {
const driverObj = driver({
/* ... */
});
return () => {
driverObj.destroy();
};
}, []);
実際のプロジェクトでの活用例
このライブラリは、以下のようなプロジェクトで威力を発揮するだろう:
- SaaSアプリケーション - 新機能の紹介
- 管理画面 - 初回ログイン時のガイド
- 複雑なフォーム - 入力のコンテキストヘルプ
- データビジュアライゼーション - グラフの見方の説明
- エディター - ショートカットキーの紹介
私自身、現在進めているプロジェクトで、Driver.jsの導入を検討している。ユーザーインターフェースが複雑になってきており、適切なガイダンスが必要だと感じていた。
結論
Driver.jsは、その名の通り、ユーザーの視線を「ドライブ」するための優れたツールだ。
5KBという軽量さ、ゼロ依存、高度なカスタマイズ性。これらの特徴は、単なる仕様書の上の数字ではない。実際に動かしてみて、その価値を実感できた。
プロダクトツアーライブラリを探しているなら、まずDriver.jsを試してみることをお勧めする。そして、ツアー以外のユースケースについても、ぜひ想像を巡らせてほしい。このライブラリは、その柔軟性で、あなたの期待に応えてくれるはずだ。
さて、また一つ、私の道具箱に新しいツールが加わった。山奥の研究室から、このプロジェクトの発展を静かに見守ることにしよう。
参考リンク
検証環境
本記事で使用したパッケージのバージョン:
- driver.js: 1.3.6
- Node.js: 22.20.0
- pnpm: 10.18.3
- TypeScript: 5.2.2
- Vite: 4.4.9