|
|
@@ -0,0 +1,57 @@
|
|
|
+// src/composables/useDriver.ts
|
|
|
+import { driver, type DriveStep, type Config } from 'driver.js'
|
|
|
+import 'driver.js/dist/driver.css'
|
|
|
+
|
|
|
+let driverInstance: ReturnType<typeof driver> | null = null
|
|
|
+
|
|
|
+/**
|
|
|
+ * useDriver composable
|
|
|
+ * @param steps 引导步骤数组
|
|
|
+ * @param globalConfig 可选的 driver 配置
|
|
|
+ */
|
|
|
+export function useDriver(steps: DriveStep[], globalConfig?: Config) {
|
|
|
+ if (!driverInstance) {
|
|
|
+ driverInstance = driver({
|
|
|
+ ...globalConfig,
|
|
|
+ showButtons: ['previous', 'next', 'close'],
|
|
|
+ onPopoverRender: (popoverDOM, { config, state, driver }) => {
|
|
|
+ console.log('Popover rendered:', popoverDOM)
|
|
|
+ // 避免重复插入
|
|
|
+ if (!popoverDOM.container.querySelector('.custom-driver-close')) {
|
|
|
+ const closeBtn = document.createElement('span')
|
|
|
+ closeBtn.innerHTML = '×'
|
|
|
+ closeBtn.className = 'custom-driver-close'
|
|
|
+ closeBtn.style.cssText = `
|
|
|
+ position: absolute;
|
|
|
+ top: 8px;
|
|
|
+ right: 12px;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #999;
|
|
|
+ cursor: pointer;
|
|
|
+ `
|
|
|
+ closeBtn.onclick = () => {
|
|
|
+ driverInstance?.destroy()
|
|
|
+ }
|
|
|
+ popoverDOM.container.style.position = 'relative'
|
|
|
+ popoverDOM.container.appendChild(closeBtn)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果用户配置了自己的 onPopoverRender,也执行它
|
|
|
+ globalConfig?.onPopoverRender?.(popoverDOM, { config, state, driver })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ driverInstance.setSteps(steps)
|
|
|
+
|
|
|
+ return {
|
|
|
+ start: (stepIndex = 0) => driverInstance?.drive(stepIndex),
|
|
|
+ moveNext: () => driverInstance?.moveNext(),
|
|
|
+ movePrevious: () => driverInstance?.movePrevious(),
|
|
|
+ highlight: (step: DriveStep) => driverInstance?.highlight(step),
|
|
|
+ destroy: () => driverInstance?.destroy(),
|
|
|
+ isActive: () => driverInstance?.isActive(),
|
|
|
+ driverInstance // 暴露实例给你更多操作
|
|
|
+ }
|
|
|
+}
|