@vingy/vueltip 1.3.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -17
- package/dist/index.d.mts +11 -11
- package/dist/index.mjs +22 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,13 +13,16 @@ A headless tooltip component for Vue.js.
|
|
|
13
13
|
To install Vueltip, use npm or yarn:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
pnpm add vueltip
|
|
16
|
+
pnpm add @vingy/vueltip
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Register the tooltip in your app:
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
vueltipPlugin,
|
|
24
|
+
vueltipDirective,
|
|
25
|
+
} from '@vingy/vueltip'
|
|
23
26
|
|
|
24
27
|
createApp(App)
|
|
25
28
|
.use(vueltipPlugin, { component: Tooltip })
|
|
@@ -52,7 +55,7 @@ First, create a tooltip component using the \`useTooltip\` composable:
|
|
|
52
55
|
|
|
53
56
|
<script setup>
|
|
54
57
|
import { useTemplateRef } from 'vue'
|
|
55
|
-
import { useVueltip } from 'vueltip'
|
|
58
|
+
import { useVueltip } from '@vingy/vueltip'
|
|
56
59
|
|
|
57
60
|
const tooltipElement = useTemplateRef('tooltipElement')
|
|
58
61
|
const arrowElement = useTemplateRef('arrowElement')
|
|
@@ -90,7 +93,10 @@ Import and register the tooltip component and plugin in your app's entry point:
|
|
|
90
93
|
// main.ts
|
|
91
94
|
import { createApp } from 'vue'
|
|
92
95
|
import App from './App.vue'
|
|
93
|
-
import {
|
|
96
|
+
import {
|
|
97
|
+
vueltipPlugin,
|
|
98
|
+
vueltipDirective,
|
|
99
|
+
} from '@vingy/vueltip'
|
|
94
100
|
import Tooltip from './components/Tooltip.vue'
|
|
95
101
|
|
|
96
102
|
const app = createApp(App)
|
|
@@ -121,7 +127,7 @@ Now you can use the `v-tooltip` directive on any element:
|
|
|
121
127
|
|
|
122
128
|
<span
|
|
123
129
|
v-tooltip="{
|
|
124
|
-
|
|
130
|
+
text: 'This is a helpful tooltip',
|
|
125
131
|
placement: 'right',
|
|
126
132
|
}"
|
|
127
133
|
>
|
|
@@ -139,17 +145,17 @@ See the demo app in [demo/](../../demo/).
|
|
|
139
145
|
|
|
140
146
|
The `vueltipPlugin` accepts the following options:
|
|
141
147
|
|
|
142
|
-
| Option | Type | Default
|
|
143
|
-
| -------------------------- | -------------------------------- |
|
|
144
|
-
| `component` | `Component` | Required
|
|
145
|
-
| `showDelay` | `number` | `0`
|
|
146
|
-
| `hideDelay` | `number` | `200`
|
|
147
|
-
| `defaultPlacement` | `Placement` | `'top'`
|
|
148
|
-
| `defaultTruncateDetection` | `'x' \| 'y' \| 'both' \| 'none'` | `'both'`
|
|
149
|
-
| `handleDialogModals` | `boolean` | `false`
|
|
150
|
-
| `placementAttribute` | `string` | `'vueltip-placement'` | HTML attribute name for tooltip placement overrides |
|
|
151
|
-
| `keyAttribute` | `string` | `'vueltip-key'` | HTML attribute name for tooltip identification |
|
|
152
|
-
| `truncateAttribute` | `string` | `'vueltip-truncate'` | HTML attribute name for truncate detection overrides |
|
|
148
|
+
| Option | Type | Default | Description |
|
|
149
|
+
| -------------------------- | -------------------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
|
150
|
+
| `component` | `Component` | Required | The Vue component to render as the tooltip |
|
|
151
|
+
| `showDelay` | `number` | `0` | Delay in milliseconds before the tooltip appears on hover |
|
|
152
|
+
| `hideDelay` | `number` | `200` | Delay in milliseconds before the tooltip disappears when the cursor leaves |
|
|
153
|
+
| `defaultPlacement` | `Placement` | `'top'` | Default tooltip placement: `'top'`, `'bottom'`, `'left'`, `'right'`, etc. |
|
|
154
|
+
| `defaultTruncateDetection` | `'x' \| 'y' \| 'both' \| 'none'` | `'both'` | Direction(s) to check for text truncation (`'x'` for horizontal, `'y'` for vertical, `'both'`, or `'none'` to disable) |
|
|
155
|
+
| `handleDialogModals` | `boolean` | `false` | Whether to handle tooltips within HTML `<dialog>` elements with the `open` attribute (modal dialogs) |
|
|
156
|
+
| `placementAttribute` | `string` | `'data-vueltip-placement'` | HTML attribute name for tooltip placement overrides |
|
|
157
|
+
| `keyAttribute` | `string` | `'data-vueltip-key'` | HTML attribute name for tooltip identification |
|
|
158
|
+
| `truncateAttribute` | `string` | `'data-vueltip-truncate'` | HTML attribute name for truncate detection overrides |
|
|
153
159
|
|
|
154
160
|
### useVueltip Composable Options
|
|
155
161
|
|
|
@@ -178,7 +184,64 @@ v-tooltip="'Tooltip text'"
|
|
|
178
184
|
|
|
179
185
|
```ts
|
|
180
186
|
v-tooltip="{
|
|
181
|
-
|
|
187
|
+
text: 'Tooltip text',
|
|
182
188
|
placement: 'right' // Placement: 'top', 'bottom', 'left', 'right', etc.
|
|
183
189
|
}"
|
|
184
190
|
```
|
|
191
|
+
|
|
192
|
+
## Custom Data
|
|
193
|
+
|
|
194
|
+
You can extend the tooltip content with custom typed data for use in your tooltip component:
|
|
195
|
+
|
|
196
|
+
**1. Create a type declaration file (e.g., `vueltip.d.ts`):**
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
declare module '@vingy/vueltip' {
|
|
200
|
+
interface CustomVueltipData {
|
|
201
|
+
userId?: number
|
|
202
|
+
userName?: string
|
|
203
|
+
severity?: 'info' | 'warning' | 'error'
|
|
204
|
+
metadata?: Record<string, unknown>
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**2. Use custom data in your directive:**
|
|
210
|
+
|
|
211
|
+
```vue
|
|
212
|
+
<button
|
|
213
|
+
v-tooltip="{
|
|
214
|
+
text: 'User profile',
|
|
215
|
+
custom: {
|
|
216
|
+
userId: 123,
|
|
217
|
+
userName: 'John Doe',
|
|
218
|
+
severity: 'info',
|
|
219
|
+
},
|
|
220
|
+
}"
|
|
221
|
+
>
|
|
222
|
+
View Profile
|
|
223
|
+
</button>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**3. Access custom data in your Tooltip component:**
|
|
227
|
+
|
|
228
|
+
```vue
|
|
229
|
+
<script setup>
|
|
230
|
+
import { useVueltip } from '@vingy/vueltip'
|
|
231
|
+
|
|
232
|
+
const { content, show } = useVueltip({
|
|
233
|
+
/* ... */
|
|
234
|
+
})
|
|
235
|
+
</script>
|
|
236
|
+
|
|
237
|
+
<template>
|
|
238
|
+
<div v-if="show">
|
|
239
|
+
{{ content?.text }}
|
|
240
|
+
|
|
241
|
+
<!-- Access your custom data -->
|
|
242
|
+
<span v-if="content?.custom?.userId">
|
|
243
|
+
User ID: {{ content.custom.userId }}
|
|
244
|
+
</span>
|
|
245
|
+
</div>
|
|
246
|
+
</template>
|
|
247
|
+
```
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { n as __reExport, t as __exportAll } from "./chunk-CtajNgzt.mjs";
|
|
2
1
|
import * as Vue from "vue";
|
|
3
2
|
import { App, Component, Directive, DirectiveBinding, ShallowRef, StyleValue } from "vue";
|
|
4
3
|
|
|
@@ -249,18 +248,19 @@ declare type UseFloatingOptions<T extends ReferenceElement = ReferenceElement> =
|
|
|
249
248
|
type Maybe<T> = T | null | undefined; //#endregion
|
|
250
249
|
//#endregion
|
|
251
250
|
//#region src/types.d.ts
|
|
251
|
+
interface CustomVueltipData {}
|
|
252
252
|
interface Content {
|
|
253
253
|
text: Maybe<string>;
|
|
254
|
+
custom?: CustomVueltipData;
|
|
254
255
|
}
|
|
255
|
-
type
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
};
|
|
256
|
+
type Value = Maybe<string> | (Content & {
|
|
257
|
+
placement?: Placement;
|
|
258
|
+
});
|
|
259
259
|
type Modifier = 'x' | 'y' | 'none' | 'both';
|
|
260
|
-
type TooltipDirective = Directive<HTMLElement,
|
|
260
|
+
type TooltipDirective = Directive<HTMLElement, Value, Modifier, Placement>;
|
|
261
261
|
type Options = {
|
|
262
|
-
/** @default 'vueltip-placement' */placementAttribute: string; /** @default 'vueltip-key' */
|
|
263
|
-
keyAttribute: string; /** @default 'vueltip-truncate' */
|
|
262
|
+
/** @default 'data-vueltip-placement' */placementAttribute: string; /** @default 'data-vueltip-key' */
|
|
263
|
+
keyAttribute: string; /** @default 'data-vueltip-truncate' */
|
|
264
264
|
truncateAttribute: string; /** @default 0 */
|
|
265
265
|
showDelay: number; /** @default 200 */
|
|
266
266
|
hideDelay: number; /** @default false */
|
|
@@ -311,8 +311,8 @@ declare const useVueltip: ({
|
|
|
311
311
|
//#endregion
|
|
312
312
|
//#region src/directive.d.ts
|
|
313
313
|
declare const vueltipDirective: {
|
|
314
|
-
updated: (el: HTMLElement, binding: DirectiveBinding<
|
|
315
|
-
created: (el: HTMLElement, binding: DirectiveBinding<
|
|
314
|
+
updated: (el: HTMLElement, binding: DirectiveBinding<Value, Modifier, Placement>) => void;
|
|
315
|
+
created: (el: HTMLElement, binding: DirectiveBinding<Value, Modifier, Placement>) => void;
|
|
316
316
|
beforeUnmount: (el: HTMLElement) => void;
|
|
317
317
|
};
|
|
318
318
|
//#endregion
|
|
@@ -326,4 +326,4 @@ declare const vueltipPlugin: {
|
|
|
326
326
|
}>) => void;
|
|
327
327
|
};
|
|
328
328
|
//#endregion
|
|
329
|
-
export { type Content, setOptions, useVueltip, vueltipDirective, vueltipPlugin };
|
|
329
|
+
export { type Content, type CustomVueltipData, setOptions, useVueltip, vueltipDirective, vueltipPlugin };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as __reExport, t as __exportAll } from "./chunk-CtajNgzt.mjs";
|
|
2
2
|
import * as Vue from "vue";
|
|
3
|
-
import { computed, createApp,
|
|
3
|
+
import { computed, createApp, ref, watch } from "vue";
|
|
4
4
|
|
|
5
5
|
//#region ../../node_modules/.pnpm/@floating-ui+utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
|
|
6
6
|
const min = Math.min;
|
|
@@ -1390,9 +1390,9 @@ function useFloating(reference, floating, options) {
|
|
|
1390
1390
|
//#endregion
|
|
1391
1391
|
//#region src/options.ts
|
|
1392
1392
|
let options = {
|
|
1393
|
-
placementAttribute: "vueltip-placement",
|
|
1394
|
-
keyAttribute: "vueltip-key",
|
|
1395
|
-
truncateAttribute: "vueltip-truncate",
|
|
1393
|
+
placementAttribute: "data-vueltip-placement",
|
|
1394
|
+
keyAttribute: "data-vueltip-key",
|
|
1395
|
+
truncateAttribute: "data-vueltip-truncate",
|
|
1396
1396
|
showDelay: 0,
|
|
1397
1397
|
hideDelay: 200,
|
|
1398
1398
|
handleDialogModals: false,
|
|
@@ -1448,11 +1448,21 @@ const sideMap = {
|
|
|
1448
1448
|
};
|
|
1449
1449
|
const useVueltip = ({ tooltipElement, arrowElement, offset: _offset, padding, arrowSize, floatingOptions }) => {
|
|
1450
1450
|
let initialParent;
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1451
|
+
const show = computed(() => !!debouncedHoveredElement.value);
|
|
1452
|
+
watch(show, (value, _, onCleanup) => {
|
|
1453
|
+
if (!value) return;
|
|
1454
|
+
const el = tooltipElement.value;
|
|
1455
|
+
if (!el) return;
|
|
1456
|
+
initialParent = el.parentElement;
|
|
1457
|
+
const onEnter = () => hoveredElement.value = debouncedHoveredElement.value;
|
|
1458
|
+
const onLeave = () => hoveredElement.value = void 0;
|
|
1459
|
+
el.addEventListener("mouseenter", onEnter);
|
|
1460
|
+
el.addEventListener("mouseleave", onLeave);
|
|
1461
|
+
onCleanup(() => {
|
|
1462
|
+
el.removeEventListener("mouseenter", onEnter);
|
|
1463
|
+
el.removeEventListener("mouseleave", onLeave);
|
|
1464
|
+
});
|
|
1465
|
+
}, { flush: "post" });
|
|
1456
1466
|
const middleware = [
|
|
1457
1467
|
offset(_offset),
|
|
1458
1468
|
flip(),
|
|
@@ -1481,7 +1491,6 @@ const useVueltip = ({ tooltipElement, arrowElement, offset: _offset, padding, ar
|
|
|
1481
1491
|
[staticSide.value]: `-${size / 2}px`
|
|
1482
1492
|
};
|
|
1483
1493
|
});
|
|
1484
|
-
const show = computed(() => !!debouncedHoveredElement.value);
|
|
1485
1494
|
if (getOption("handleDialogModals")) watch(show, (value) => {
|
|
1486
1495
|
if (!value || !tooltipElement.value || !debouncedHoveredElement.value || !initialParent) return;
|
|
1487
1496
|
const dialogEl = debouncedHoveredElement.value.closest("dialog");
|
|
@@ -1564,13 +1573,12 @@ const onMouseout = ensureEventTarget((target) => {
|
|
|
1564
1573
|
const toContent = (value) => {
|
|
1565
1574
|
if (value == null) return { text: value };
|
|
1566
1575
|
if (typeof value === "string") return { text: value };
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
return value.content;
|
|
1576
|
+
const { placement: _, ...rest } = value;
|
|
1577
|
+
return rest;
|
|
1570
1578
|
};
|
|
1571
1579
|
const extractPlacement = (binding) => {
|
|
1572
1580
|
const { value, arg } = binding;
|
|
1573
|
-
if (value && typeof value !== "string" && "placement" in value) return value.placement;
|
|
1581
|
+
if (value && typeof value !== "string" && "placement" in value && value.placement != null) return value.placement;
|
|
1574
1582
|
if (!arg) return getOption("defaultPlacement");
|
|
1575
1583
|
return arg;
|
|
1576
1584
|
};
|