diff --git a/CHANGELOG.md b/CHANGELOG.md
index ca2064a..72ecc8c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+### Added
+- Theme presets: Tooltips can now be globally styled with the "default", "primevue", or "vuetify" presets. Switching themes at runtime is supported.
+
## [1.2.2] - 2025-10-27
### Fixed
diff --git a/README.md b/README.md
index f724920..c74a10c 100644
--- a/README.md
+++ b/README.md
@@ -56,6 +56,7 @@ const app = createApp(App)
// Configure global defaults for all tooltips
app.use(VueCustomTooltip, {
+ theme: 'default', // or 'vuetify' or 'primevue'
globalConfig: {
position: 'top', // Default position for all tooltips
trigger: 'hover', // Default trigger behavior
@@ -381,6 +382,59 @@ The `v-tooltip` directive is also fully typed when you install the plugin. TypeS
```
+## Theme Presets
+
+Vue Custom Tooltip supports built-in theme presets for easy integration with popular UI frameworks, as well as a default theme:
+
+- **default**: Uses the component's original built-in styles (no extra CSS loaded)
+- **primevue**: Styles inspired by PrimeVue's design system
+- **vuetify**: Styles inspired by Vuetify's Material Design implementation
+
+You can select a theme globally when registering the plugin:
+
+```typescript
+import { VueCustomTooltip } from '@borstihd/vue-custom-tooltip'
+import { createApp } from 'vue'
+import App from './App.vue'
+import '@borstihd/vue-custom-tooltip/dist/style.css'
+
+const app = createApp(App)
+
+// Use a theme preset
+app.use(VueCustomTooltip, {
+ theme: 'primevue' // or 'vuetify' or 'default'
+})
+
+// The default theme is used if you omit the theme option:
+app.use(VueCustomTooltip) // same as theme: 'default'
+
+app.mount('#app')
+```
+
+You can also switch themes at runtime:
+
+```typescript
+import { setTooltipGlobalTheme } from '@borstihd/vue-custom-tooltip'
+
+setTooltipGlobalTheme('vuetify') // Switch to Vuetify theme
+setTooltipGlobalTheme('default') // Revert to default styles
+```
+
+### Customizing Theme Styles
+
+Each theme uses CSS custom properties (variables) for easy customization. You can override these in your global CSS:
+
+```css
+:root {
+ /* Example for PrimeVue theme */
+ --vct-primevue-background: #1a1a1a;
+ --vct-primevue-text-color: #fff;
+ --vct-primevue-border-radius: 8px;
+}
+```
+
+See the [src/styles/themes/README.md](src/styles/themes/README.md) for a full list of theme variables and instructions for creating your own custom themes.
+
## Styling
The tooltip uses CSS custom properties for theming. You can customize the appearance by overriding these variables:
diff --git a/THEME_GUIDE.md b/THEME_GUIDE.md
new file mode 100644
index 0000000..a2eeda5
--- /dev/null
+++ b/THEME_GUIDE.md
@@ -0,0 +1,139 @@
+# Theme Configuration Guide
+
+## Overview
+
+Vue Custom Tooltip supports predefined UI framework themes! You can easily apply PrimeVue or Vuetify styling to all your tooltips with a simple configuration option.
+
+## Available Themes
+
+- **`default`**: The built-in theme using the component's original styles (no additional CSS loaded)
+- **`primevue`**: Styles inspired by PrimeVue's design system
+- **`vuetify`**: Styles inspired by Vuetify's Material Design implementation
+
+## Basic Usage
+
+### Option 1: Global Theme Configuration
+
+Apply a theme to all tooltips in your application:
+
+```typescript
+import { createApp } from 'vue'
+import { VueCustomTooltip } from 'vue-custom-tooltip'
+import App from './App.vue'
+
+const app = createApp(App)
+
+app.use(VueCustomTooltip, {
+ theme: 'primevue' // or 'vuetify' or 'default'
+})
+
+app.mount('#app')
+```
+
+### Option 2: Theme with Global Config
+
+Combine theme styling with global configuration:
+
+```typescript
+app.use(VueCustomTooltip, {
+ theme: 'primevue',
+ globalConfig: {
+ position: 'top',
+ trigger: 'hover',
+ showDelay: 200,
+ hideDelay: 150,
+ dark: 'auto', // Supports auto-detection, true, or false
+ showArrow: true,
+ offset: 12,
+ maxWidth: '300px',
+ },
+})
+```
+
+### Option 3: No Theme (Default Styling)
+
+If you don't specify a theme, the default tooltip styling will be used:
+
+```typescript
+// These are equivalent
+app.use(VueCustomTooltip)
+app.use(VueCustomTooltip, { theme: 'default' })
+```
+
+## Programmatic Theme Control
+
+You can also change the theme programmatically:
+
+```typescript
+import { getTooltipGlobalTheme, setTooltipGlobalTheme } from 'vue-custom-tooltip'
+
+// Change theme at runtime
+setTooltipGlobalTheme('vuetify')
+
+// Get current theme
+const currentTheme = getTooltipGlobalTheme()
+
+// Revert to default (uses component's built-in styles)
+setTooltipGlobalTheme('default')
+// or
+setTooltipGlobalTheme(undefined)
+```
+
+## Theme Features
+
+### Dark Mode Support
+
+All themes automatically support dark mode through:
+1. **Auto detection** (`dark: 'auto'`): Responds to Tailwind's `.dark` class or `prefers-color-scheme`
+2. **Forced dark mode** (`dark: true`): Always use dark theme
+3. **Forced light mode** (`dark: false`): Always use light theme
+
+```typescript
+// Auto-detect dark mode
+app.use(VueCustomTooltip, {
+ theme: 'primevue',
+ globalConfig: {
+ dark: 'auto', // Default
+ },
+})
+
+// Force dark mode
+app.use(VueCustomTooltip, {
+ theme: 'vuetify',
+ globalConfig: {
+ dark: true,
+ },
+})
+```
+
+### CSS Custom Properties
+
+Each theme uses CSS custom properties that you can override in your own styles:
+
+```css
+/* Override PrimeVue theme colors */
+:root {
+ --vct-primevue-background: #1a1a1a;
+ --vct-primevue-text-color: #ffffff;
+ --vct-primevue-border-radius: 8px;
+}
+
+/* Override Vuetify theme colors */
+:root {
+ --vct-vuetify-background: rgba(50, 50, 50, 0.95);
+ --vct-vuetify-text-color: #e0e0e0;
+ --vct-vuetify-font-family: 'Custom Font', sans-serif;
+}
+```
+
+## Notes
+
+- Themes are injected as `
diff --git a/src/components/tooltip/Tooltip.vue b/src/components/tooltip/Tooltip.vue
index ed4a25e..88c0bdd 100644
--- a/src/components/tooltip/Tooltip.vue
+++ b/src/components/tooltip/Tooltip.vue
@@ -50,6 +50,7 @@ import {
useTooltipProps,
useTooltipVisibility,
} from '../../composables'
+import { getTooltipGlobalThemeRef } from '../../config/index'
/**
* Generic Tooltip Component
@@ -159,6 +160,9 @@ const {
// Computed properties
const hasContentSlot = computed(() => !!slots.content)
+// Get global theme
+const globalTheme = getTooltipGlobalThemeRef()
+
const tooltipClasses = computed(() => [
'custom-tooltip',
`tooltip-${actualPosition.value}`,
@@ -169,6 +173,8 @@ const tooltipClasses = computed(() => [
'tooltip-light': effectiveDark.value === false,
'tooltip-auto': effectiveDark.value === 'auto',
},
+ // Only apply theme class if it's not 'default' (default uses component's built-in styles)
+ globalTheme.value && globalTheme.value !== 'default' ? `tooltip-theme-${globalTheme.value}` : '',
effectiveTooltipClass.value,
])
diff --git a/src/config/globalConfig.ts b/src/config/globalConfig.ts
index ac36fc5..1bbe4a7 100644
--- a/src/config/globalConfig.ts
+++ b/src/config/globalConfig.ts
@@ -1,12 +1,18 @@
-import type { TooltipProps } from '@/components/tooltip/Tooltip.vue'
+import type { TooltipProps, TooltipTheme } from '@/types/tooltip'
-import { reactive } from 'vue'
+import { reactive, ref } from 'vue'
+import { injectThemeStyles } from '../index'
/**
* Global reactive configuration for tooltips
*/
const globalConfig = reactive>({})
+/**
+ * Global theme configuration (stored separately from props)
+ */
+const globalTheme = ref(undefined)
+
/**
* Set global configuration for all tooltips
* This will be used as default values that can be overridden by individual tooltip props
@@ -20,6 +26,28 @@ export function setTooltipGlobalConfig(config: Partial): void {
Object.assign(globalConfig, config)
}
+/**
+ * Set the global theme for all tooltips
+ */
+export async function setTooltipGlobalTheme(theme: TooltipTheme | undefined): Promise {
+ globalTheme.value = theme
+ await injectThemeStyles(theme || 'default')
+}
+
+/**
+ * Get the current global theme
+ */
+export function getTooltipGlobalTheme(): TooltipTheme | undefined {
+ return globalTheme.value
+}
+
+/**
+ * Get the current global theme (reactive reference)
+ */
+export function getTooltipGlobalThemeRef() {
+ return globalTheme
+}
+
/**
* Get the current global configuration
* Returns a copy to prevent external mutation
@@ -44,4 +72,5 @@ export function resetTooltipGlobalConfig(): void {
Object.keys(globalConfig).forEach((key) => {
delete globalConfig[key as keyof TooltipProps]
})
+ globalTheme.value = undefined
}
diff --git a/src/config/index.ts b/src/config/index.ts
index 664e2d4..6e35b40 100644
--- a/src/config/index.ts
+++ b/src/config/index.ts
@@ -2,6 +2,9 @@
export {
getReactiveGlobalConfig,
getTooltipGlobalConfig,
+ getTooltipGlobalTheme,
+ getTooltipGlobalThemeRef,
resetTooltipGlobalConfig,
setTooltipGlobalConfig,
+ setTooltipGlobalTheme,
} from './globalConfig'
diff --git a/src/index.ts b/src/index.ts
index 77b89ce..c8c7017 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,8 +1,8 @@
import type { App, Plugin } from 'vue'
-import type { TooltipProps } from './types/tooltip'
+import type { TooltipProps, TooltipTheme } from './types/tooltip'
import Tooltip from './components/tooltip/Tooltip.vue'
-import { setTooltipGlobalConfig } from './config/index'
+import { setTooltipGlobalConfig, setTooltipGlobalTheme } from './config/index'
import { vTooltip } from './directives/tooltip'
// Export components and directives
@@ -12,9 +12,9 @@ export { Tooltip, vTooltip }
export * from './composables'
// Export configuration functions
-export { getTooltipGlobalConfig, resetTooltipGlobalConfig, setTooltipGlobalConfig } from './config/index'
+export { getTooltipGlobalConfig, getTooltipGlobalTheme, resetTooltipGlobalConfig, setTooltipGlobalConfig, setTooltipGlobalTheme } from './config/index'
-export type { TooltipProps, TooltipSlots } from './types/tooltip'
+export type { TooltipProps, TooltipSlots, TooltipTheme } from './types/tooltip'
// Export types
export type {
TooltipDirectiveModifiers,
@@ -34,8 +34,63 @@ export interface VueCustomTooltipOptions {
* These values will be used as defaults and can be overridden by individual tooltip props
*/
globalConfig?: Partial
+ /**
+ * Theme to apply to all tooltips
+ * Available themes: 'primevue', 'vuetify'
+ * If not specified, the default theme will be used
+ */
+ theme?: TooltipTheme
+}
+
+/**
+ * Injects theme styles into the document head
+ */
+async function injectThemeStyles(theme: TooltipTheme): Promise {
+ // Default theme uses the component's built-in styles, no CSS injection needed
+ if (theme === 'default') {
+ // Remove any previously injected theme styles to revert to default
+ const oldStyles = document.querySelectorAll('style[data-vct-theme]')
+ oldStyles.forEach(style => style.remove())
+ return
+ }
+
+ // Check if theme styles are already injected
+ const existingStyle = document.querySelector(`style[data-vct-theme="${theme}"]`)
+ if (existingStyle) {
+ return
+ }
+
+ // Remove any previously injected theme styles
+ const oldStyles = document.querySelectorAll('style[data-vct-theme]')
+ oldStyles.forEach(style => style.remove())
+
+ try {
+ // Import the theme CSS dynamically
+ if (theme === 'primevue') {
+ await import('./styles/themes/primevue.css')
+ }
+ else if (theme === 'vuetify') {
+ await import('./styles/themes/vuetify.css')
+ }
+ else {
+ console.warn(`Unknown theme "${theme}"`)
+ return
+ }
+
+ // Mark that this theme has been loaded
+ const marker = document.createElement('style')
+ marker.setAttribute('data-vct-theme', theme)
+ marker.textContent = `/* Vue Custom Tooltip Theme: ${theme} */`
+ document.head.appendChild(marker)
+ }
+ catch (error) {
+ console.error(`Failed to load theme "${theme}":`, error)
+ }
}
+// Export theme CSS injector for runtime theme switching
+export { injectThemeStyles }
+
// Vue plugin for easy installation
export const VueCustomTooltip: Plugin = {
install(app: App, options?: VueCustomTooltipOptions) {
@@ -46,6 +101,15 @@ export const VueCustomTooltip: Plugin = {
if (options?.globalConfig) {
setTooltipGlobalConfig(options.globalConfig)
}
+
+ // Apply theme if provided
+ if (options?.theme) {
+ setTooltipGlobalTheme(options.theme)
+ // Inject theme styles
+ if (typeof document !== 'undefined') {
+ injectThemeStyles(options.theme)
+ }
+ }
},
}
diff --git a/src/main.ts b/src/main.ts
index ad0e965..e0814b7 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -18,23 +18,19 @@ import './assets/main.css'
const app = createApp(App)
-app.use(VueCustomTooltip)
-
-// app.directive('tooltip', vTooltip)
-// app.component('Tooltip', Tooltip)
-
// Different way to set global configuration
-// app.use(VueCustomTooltip, {
-// globalConfig: {
-// position: 'top', // Default position for all tooltips
-// trigger: 'hover', // Default trigger behavior
-// showDelay: 200, // Default show delay (ms)
-// hideDelay: 150, // Default hide delay (ms)
-// dark: false, // Force dark mode for all tooltips
-// showArrow: true, // Show arrow by default
-// offset: 12, // Default offset from trigger
-// maxWidth: '300px', // Default max width
-// },
-// })
+app.use(VueCustomTooltip, {
+ theme: 'default', // Apply Default theme to all tooltips - 'default', 'primevue' or 'vuetify'
+ // globalConfig: {
+ // position: 'top', // Default position for all tooltips
+ // trigger: 'hover', // Default trigger behavior
+ // showDelay: 200, // Default show delay (ms)
+ // hideDelay: 150, // Default hide delay (ms)
+ // dark: 'auto', // Auto detect dark mode
+ // showArrow: true, // Show arrow by default
+ // offset: 12, // Default offset from trigger
+ // maxWidth: '300px', // Default max width
+ // },
+})
app.mount('#app')
diff --git a/src/styles/themes/README.md b/src/styles/themes/README.md
new file mode 100644
index 0000000..86d5192
--- /dev/null
+++ b/src/styles/themes/README.md
@@ -0,0 +1,120 @@
+# Tooltip Themes
+
+This directory contains theme-specific styles for the Vue Custom Tooltip component.
+
+## Available Themes
+
+### Default (`default.css`)
+The built-in theme that uses the component's original styles. This file is intentionally empty as the default styles are defined in the `Tooltip.vue` component itself.
+
+**Features:**
+- Light, clean design
+- Subtle shadows and borders
+- Automatic dark mode support
+- No additional CSS loading required
+
+**When to use:**
+- When you want the original tooltip styling
+- To explicitly revert from another theme
+- As a fallback when no theme is specified
+
+**Note:** Using `theme: 'default'` is equivalent to not specifying a theme at all.
+
+### PrimeVue (`primevue.css`)
+Styles inspired by PrimeVue's design system, featuring:
+- Clean, modern appearance
+- Material-inspired shadows
+- Subtle border radius
+- Dark background with high contrast text
+- Smooth transitions
+
+### Vuetify (`vuetify.css`)
+Styles inspired by Vuetify's Material Design implementation, featuring:
+- Material Design specifications
+- Elevated shadows
+- Roboto font family
+- Semi-transparent backgrounds
+- Precise spacing and typography
+
+## Usage
+
+Themes are automatically injected when you configure the plugin:
+
+```typescript
+import { createApp } from 'vue'
+import { VueCustomTooltip } from 'vue-custom-tooltip'
+
+const app = createApp(App)
+
+// Use a specific theme
+app.use(VueCustomTooltip, {
+ theme: 'primevue' // or 'vuetify' or 'default'
+})
+
+// No theme (same as theme: 'default')
+app.use(VueCustomTooltip)
+```
+
+## Customization
+
+Each theme uses CSS custom properties (variables) that you can override:
+
+### PrimeVue Theme Variables
+```css
+--vct-primevue-text-color
+--vct-primevue-background
+--vct-primevue-border-radius
+--vct-primevue-font-family
+--vct-primevue-text-color-light
+--vct-primevue-background-light
+--vct-primevue-text-color-dark
+--vct-primevue-background-dark
+```
+
+### Vuetify Theme Variables
+```css
+--vct-vuetify-text-color
+--vct-vuetify-background
+--vct-vuetify-border-radius
+--vct-vuetify-font-family
+--vct-vuetify-text-color-light
+--vct-vuetify-background-light
+--vct-vuetify-text-color-dark
+--vct-vuetify-background-dark
+```
+
+## Dark Mode Support
+
+All themes support:
+- Forced dark mode (`dark: true`)
+- Forced light mode (`dark: false`)
+- Auto detection (`dark: 'auto'`) - responds to:
+ - Tailwind's `.dark` class
+ - `prefers-color-scheme` media query
+
+## Creating Custom Themes
+
+To create a custom theme:
+
+1. Create a new CSS file in this directory (e.g., `mytheme.css`)
+2. Use the class selector `.tooltip-theme-mytheme`
+3. Style the `.tooltip-content` and `.tooltip-arrow` elements
+4. Support all dark mode variants
+5. Add the theme name to the `TooltipTheme` type in `src/types/tooltip.ts`
+6. Update the theme injection logic in `src/index.ts`
+
+Example structure:
+```css
+.tooltip-theme-mytheme .tooltip-content {
+ /* Your styles */
+}
+
+.tooltip-theme-mytheme .tooltip-arrow {
+ /* Your styles */
+}
+
+/* Dark mode support */
+.tooltip-theme-mytheme.tooltip-dark .tooltip-content {
+ /* Dark mode styles */
+}
+```
diff --git a/src/styles/themes/default.css b/src/styles/themes/default.css
new file mode 100644
index 0000000..4e750fa
--- /dev/null
+++ b/src/styles/themes/default.css
@@ -0,0 +1,14 @@
+/**
+ * Default Theme for Vue Custom Tooltip
+ *
+ * This file is intentionally empty because the default theme uses the
+ * built-in styles from the Tooltip.vue component's