Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 43d7131

Browse filesBrowse files
committed
feat(CTooltip): add CTooltip component
1 parent 2084775 commit 43d7131
Copy full SHA for 43d7131

File tree

Expand file treeCollapse file tree

5 files changed

+263
-2
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+263
-2
lines changed

‎docs/api/tooltip/CTooltip.api.md

Copy file name to clipboard
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
### CTooltip
2+
3+
```jsx
4+
import { CTooltip } from '@coreui/vue'
5+
// or
6+
import CTooltip from '@coreui/vue/src/components/tooltip/CTooltip'
7+
```
8+
9+
#### Props
10+
11+
| Prop name | Description | Type | Values | Default |
12+
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ------------------------------- | ------- |
13+
| **content** | Content for your component. If you want to pass non-string value please use dedicated slot `<template #content>...</template>` | string | - | - |
14+
| **offset** | Offset of the tooltip relative to its target. | array | - | [0, 0] |
15+
| **placement** | Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property. | Placement | - | 'top' |
16+
| **trigger** | Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them. | string \| string[] | `'click'`, `'focus'`, `'hover'` | 'hover' |
17+
| **visible** | Toggle the visibility of tooltip component. | boolean | - | |
18+
19+
#### Events
20+
21+
| Event name | Description | Properties |
22+
| ---------- | -------------------------------------------------------- | ---------- |
23+
| **hide** | Callback fired when the component requests to be hidden. |
24+
| **show** | Callback fired when the component requests to be shown. |

‎docs/components/tooltip.md

Copy file name to clipboardExpand all lines: docs/components/tooltip.md
+59-2Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
---
2-
title: Vue Tooltip Directive
2+
title: Vue Tooltip Component and Directive
33
name: Tooltip
44
description: Documentation and examples for adding Vue Tooltips.
55
---
66

7+
## Examples
8+
9+
Hover over the links below to see tooltips:
10+
711
::: demo
812
<p class="text-medium-emphasis">
913
Tight pants next level keffiyeh
@@ -43,8 +47,57 @@ description: Documentation and examples for adding Vue Tooltips.
4347
</p>
4448
```
4549

50+
### Component
51+
4652
Hover over the buttons below to see the four tooltips directions: top, right, bottom, and left. Directions are mirrored when using CoreUI in RTL.
4753

54+
::: demo
55+
<CTooltip content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus" placement="top">
56+
<template #toggler="{ on }">
57+
<CButton color="secondary" v-on="on">Tooltip on top</CButton>
58+
</template>
59+
</CTooltip>
60+
<CTooltip content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus" placement="right">
61+
<template #toggler="{ on }">
62+
<CButton color="secondary" v-on="on">Tooltip on right</CButton>
63+
</template>
64+
</CTooltip>
65+
<CTooltip content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus" placement="bottom">
66+
<template #toggler="{ on }">
67+
<CButton color="secondary" v-on="on">Tooltip on bottom</CButton>
68+
</template>
69+
</CTooltip>
70+
<CTooltip content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus" placement="left">
71+
<template #toggler="{ on }">
72+
<CButton color="secondary" v-on="on">Tooltip on left</CButton>
73+
</template>
74+
</CTooltip>
75+
:::
76+
```vue
77+
<CTooltip content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus" placement="top">
78+
<template #toggler="{ on }">
79+
<CButton color="secondary" v-on="on">Tooltip on top</CButton>
80+
</template>
81+
</CTooltip>
82+
<CTooltip content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus" placement="right">
83+
<template #toggler="{ on }">
84+
<CButton color="secondary" v-on="on">Tooltip on right</CButton>
85+
</template>
86+
</CTooltip>
87+
<CTooltip content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus" placement="bottom">
88+
<template #toggler="{ on }">
89+
<CButton color="secondary" v-on="on">Tooltip on bottom</CButton>
90+
</template>
91+
</CTooltip>
92+
<CTooltip content="Vivamus sagittis lacus vel augue laoreet rutrum faucibus" placement="left">
93+
<template #toggler="{ on }">
94+
<CButton color="secondary" v-on="on">Tooltip on left</CButton>
95+
</template>
96+
</CTooltip>
97+
```
98+
99+
### Directive
100+
48101
::: demo
49102
<CButton color="secondary" v-c-tooltip="{content: 'Vivamus sagittis lacus vel augue laoreet rutrum faucibus.', placement: 'top'}">Tooltip on top</CButton>
50103
<CButton color="secondary" v-c-tooltip="{content: 'Vivamus sagittis lacus vel augue laoreet rutrum faucibus.', placement: 'right'}">Tooltip on right</CButton>
@@ -56,4 +109,8 @@ Hover over the buttons below to see the four tooltips directions: top, right, bo
56109
<CButton color="secondary" v-c-tooltip="{content: 'Vivamus sagittis lacus vel augue laoreet rutrum faucibus.', placement: 'right'}">Tooltip on right</CButton>
57110
<CButton color="secondary" v-c-tooltip="{content: 'Vivamus sagittis lacus vel augue laoreet rutrum faucibus.', placement: 'bottom'}">Tooltip on bottom</CButton>
58111
<CButton color="secondary" v-c-tooltip="{content: 'Vivamus sagittis lacus vel augue laoreet rutrum faucibus.', placement: 'left'}">Tooltip on left</CButton>
59-
```
112+
```
113+
114+
## API
115+
116+
!!!include(./docs/api/tooltip/CTooltip.api.md)!!!

‎src/components/index.ts

Copy file name to clipboardExpand all lines: src/components/index.ts
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ export * from './spinner'
3131
export * from './table'
3232
export * from './tabs'
3333
export * from './toast'
34+
export * from './tooltip'
3435
export * from './widgets'

‎src/components/tooltip/CTooltip.ts

Copy file name to clipboard
+169Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import { defineComponent, h, PropType, ref, RendererElement, Teleport, Transition } from 'vue'
2+
import { createPopper, Placement } from '@popperjs/core'
3+
4+
const CTooltip = defineComponent({
5+
name: 'CTooltip',
6+
props: {
7+
/**
8+
* Content for your component. If you want to pass non-string value please use dedicated slot `<template #content>...</template>`
9+
*/
10+
content: {
11+
type: String,
12+
default: undefined,
13+
required: false,
14+
},
15+
/**
16+
* Offset of the tooltip relative to its target.
17+
*/
18+
offset: {
19+
type: Array,
20+
default: () => [0, 0],
21+
required: false,
22+
},
23+
/**
24+
* Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property.
25+
*/
26+
placement: {
27+
type: String as PropType<Placement>,
28+
default: 'top',
29+
required: false,
30+
validator: (value: string) => {
31+
return ['top', 'right', 'bottom', 'left'].includes(value)
32+
},
33+
},
34+
/**
35+
* Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them.
36+
*
37+
* @values 'click', 'focus', 'hover'
38+
*/
39+
trigger: {
40+
type: [String, Array] as PropType<string | string[]>,
41+
default: 'hover',
42+
required: false,
43+
validator: (value: string | string[]) => {
44+
if (typeof value === 'string') {
45+
return ['click', 'focus', 'hover'].includes(value)
46+
}
47+
if (Array.isArray(value)) {
48+
return value.every((e) => ['click', 'focus', 'hover'].includes(e))
49+
}
50+
return false
51+
},
52+
},
53+
/**
54+
* Toggle the visibility of tooltip component.
55+
*/
56+
visible: Boolean,
57+
},
58+
emits: [
59+
/**
60+
* Callback fired when the component requests to be hidden.
61+
*/
62+
'hide',
63+
/**
64+
* Callback fired when the component requests to be shown.
65+
*/
66+
'show',
67+
],
68+
setup(props, { slots, emit }) {
69+
const togglerRef = ref()
70+
const tooltipRef = ref()
71+
const popper = ref()
72+
const visible = ref(props.visible)
73+
74+
const handleEnter = (el: RendererElement, done: () => void) => {
75+
emit('show')
76+
initPopper()
77+
el.classList.add('show')
78+
el.addEventListener('transitionend', () => {
79+
done()
80+
})
81+
}
82+
83+
const handleLeave = (el: RendererElement, done: () => void) => {
84+
emit('hide')
85+
el.classList.remove('show')
86+
el.addEventListener('transitionend', () => {
87+
done()
88+
destroyPopper()
89+
})
90+
}
91+
92+
const handleToggle = (event: Event) => {
93+
togglerRef.value = event.target
94+
visible.value = !visible.value
95+
}
96+
97+
const initPopper = () => {
98+
if (togglerRef.value) {
99+
popper.value = createPopper(togglerRef.value, tooltipRef.value, {
100+
placement: props.placement,
101+
modifiers: [
102+
{
103+
name: 'offset',
104+
options: {
105+
offset: props.offset,
106+
},
107+
},
108+
],
109+
})
110+
}
111+
}
112+
113+
const destroyPopper = () => {
114+
if (popper.value) {
115+
popper.value.destroy()
116+
}
117+
popper.value = undefined
118+
}
119+
120+
return () => [
121+
h(
122+
Teleport,
123+
{
124+
to: 'body',
125+
},
126+
h(
127+
Transition,
128+
{
129+
onEnter: (el, done) => handleEnter(el, done),
130+
onLeave: (el, done) => handleLeave(el, done),
131+
},
132+
() =>
133+
visible.value &&
134+
h(
135+
'div',
136+
{
137+
class: 'tooltip fade bs-tooltip-auto',
138+
ref: tooltipRef,
139+
role: 'tooltip',
140+
},
141+
[
142+
h('div', { class: 'tooltip-arrow', 'data-popper-arrow': '' }),
143+
(props.content || slots.content) &&
144+
h(
145+
'div',
146+
{ class: 'tooltip-inner' },
147+
{
148+
default: () => (slots.content && slots.content()) || props.content,
149+
},
150+
),
151+
],
152+
),
153+
),
154+
),
155+
slots.toggler &&
156+
slots.toggler({
157+
on: {
158+
click: (event: Event) => props.trigger.includes('click') && handleToggle(event),
159+
blur: (event: Event) => props.trigger.includes('focus') && handleToggle(event),
160+
focus: (event: Event) => props.trigger.includes('focus') && handleToggle(event),
161+
mouseenter: (event: Event) => props.trigger.includes('hover') && handleToggle(event),
162+
mouseleave: (event: Event) => props.trigger.includes('hover') && handleToggle(event),
163+
},
164+
}),
165+
]
166+
},
167+
})
168+
169+
export { CTooltip }

‎src/components/tooltip/index.ts

Copy file name to clipboard
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { App } from 'vue'
2+
import { CTooltip } from './CTooltip'
3+
4+
const CTooltipPlugin = {
5+
install: (app: App): void => {
6+
app.component(CTooltip.name, CTooltip)
7+
},
8+
}
9+
10+
export { CTooltipPlugin, CTooltip }

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.