goodteditor-ui 1.0.11 → 1.0.14
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/index.js +2 -0
- package/package.json +2 -3
- package/src/components/ui/Avatar.md +68 -0
- package/src/components/ui/Avatar.vue +177 -0
- package/src/components/ui/Popover.vue +91 -30
- package/src/components/ui/Tooltip.md +62 -0
- package/src/components/ui/utils/Helpers.js +24 -1
- package/src/components/ui/utils/WithPopover.js +18 -0
package/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Avatar from './src/components/ui/Avatar.vue';
|
|
1
2
|
import Badge from './src/components/ui/Badge.vue';
|
|
2
3
|
import Collapse from './src/components/ui/Collapse.vue';
|
|
3
4
|
import ColorPicker from './src/components/ui/ColorPicker.vue';
|
|
@@ -23,6 +24,7 @@ import Tooltip from './src/components/ui/Tooltip.vue';
|
|
|
23
24
|
import Grid from './src/components/ui/Grid.vue';
|
|
24
25
|
|
|
25
26
|
export {
|
|
27
|
+
Avatar,
|
|
26
28
|
Badge,
|
|
27
29
|
Collapse,
|
|
28
30
|
ColorPicker,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "goodteditor-ui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"homepage": "https://goodt-ui.netlify.app/",
|
|
6
6
|
"scripts": {
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
"dev": "vue-styleguidist server",
|
|
11
11
|
"docs:build": "set NODE_ENV=development && vue-styleguidist build",
|
|
12
12
|
"docs:deploy": "npx netlify deploy --dir=docs --prod",
|
|
13
|
-
"notify": "node ./ci/teams-notify.js"
|
|
14
|
-
"publish": "npm run docs:build && npm run docs:deploy && npm run notify"
|
|
13
|
+
"notify": "node ./ci/teams-notify.js"
|
|
15
14
|
},
|
|
16
15
|
"devDependencies": {
|
|
17
16
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
```vue
|
|
2
|
+
<template>
|
|
3
|
+
<div class="pad-l5">
|
|
4
|
+
<div class="p">
|
|
5
|
+
<!-- default -->
|
|
6
|
+
<ui-avatar v-bind="props" @load="onLoad" @error="onError"></ui-avatar>
|
|
7
|
+
|
|
8
|
+
<!-- custom slots -->
|
|
9
|
+
<ui-avatar v-bind="props">
|
|
10
|
+
<template v-slot="{abbr}">
|
|
11
|
+
<code>{{abbr}}</code>
|
|
12
|
+
</template>
|
|
13
|
+
<template #loading>loading</template>
|
|
14
|
+
</ui-avatar>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="row">
|
|
17
|
+
<div class="col">
|
|
18
|
+
<template v-for="key in Object.keys(props)">
|
|
19
|
+
<label class="text-small " v-if="isBool(key)">
|
|
20
|
+
<input class="checkbox checkbox-small" type="checkbox" v-model="props[key]">
|
|
21
|
+
<span class="v-mid">{{key}}</span>
|
|
22
|
+
</label>
|
|
23
|
+
<div :key="key" v-else>
|
|
24
|
+
<label class="text-xsmall">{{key}}</label>
|
|
25
|
+
<input class="input input-small d-block" type="text" v-model="props[key]">
|
|
26
|
+
</div>
|
|
27
|
+
</template>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="col">
|
|
30
|
+
<pre class="text-xsmall" style="max-height:10rem">{{logStr}}</pre>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
35
|
+
<script>
|
|
36
|
+
import UiAvatar from './Avatar.vue';
|
|
37
|
+
|
|
38
|
+
export default {
|
|
39
|
+
components: { UiAvatar },
|
|
40
|
+
data() {
|
|
41
|
+
return {
|
|
42
|
+
props: {
|
|
43
|
+
round: true,
|
|
44
|
+
src:'https://picsum.photos/150/150',
|
|
45
|
+
size: '4rem',
|
|
46
|
+
alt: 'John Wick',
|
|
47
|
+
color: '#ffffff',
|
|
48
|
+
background:'#fca522',
|
|
49
|
+
},
|
|
50
|
+
log:[]
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
computed: {
|
|
54
|
+
logStr() {
|
|
55
|
+
return this.log.reverse().join("\n")
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
methods: {
|
|
59
|
+
isBool(key) {
|
|
60
|
+
return key === 'round'
|
|
61
|
+
},
|
|
62
|
+
addLog(n,e) { this.log.push(`event: ${n}`) },
|
|
63
|
+
onLoad(e) { this.addLog('load') },
|
|
64
|
+
onError(e) { this.addLog('error') },
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
</script>
|
|
68
|
+
```
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="ui-avatar" :style="cssStyle">
|
|
3
|
+
<img
|
|
4
|
+
class="ui-avatar__img"
|
|
5
|
+
:src="src"
|
|
6
|
+
:alt="isDoneState ? alt : ''"
|
|
7
|
+
@error="onImageError"
|
|
8
|
+
@load="onImageLoad"
|
|
9
|
+
v-if="isLoadingState || isDoneState"
|
|
10
|
+
/>
|
|
11
|
+
<div class="ui-avatar__alt" v-if="isErrorState">
|
|
12
|
+
<!--
|
|
13
|
+
@slot Alternative content slot (displayed if no image provided)
|
|
14
|
+
@binding {string} alt alternative text
|
|
15
|
+
@binding {string} abbr alternative text abbr
|
|
16
|
+
-->
|
|
17
|
+
<slot v-bind="{ alt, abbr }">
|
|
18
|
+
<b class="ui-avatar__abbr">{{ abbr }}</b>
|
|
19
|
+
</slot>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="ui-avatar__loading" v-else-if="isLoadingState">
|
|
22
|
+
<!--
|
|
23
|
+
@slot Loading content slot
|
|
24
|
+
-->
|
|
25
|
+
<slot name="loading">
|
|
26
|
+
<div class="preloader color-inherit"></div>
|
|
27
|
+
</slot>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</template>
|
|
31
|
+
<style lang="less" scoped>
|
|
32
|
+
.ui-avatar {
|
|
33
|
+
--size: 2rem;
|
|
34
|
+
--alt-scale: 0.4;
|
|
35
|
+
position: relative;
|
|
36
|
+
width: var(--size);
|
|
37
|
+
height: var(--size);
|
|
38
|
+
display: inline-flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
justify-content: center;
|
|
41
|
+
overflow: hidden;
|
|
42
|
+
&__abbr {
|
|
43
|
+
font-size: calc(var(--size) * var(--alt-scale));
|
|
44
|
+
line-height: 1;
|
|
45
|
+
}
|
|
46
|
+
&__img {
|
|
47
|
+
width: 100%;
|
|
48
|
+
height: 100%;
|
|
49
|
+
object-fit: cover;
|
|
50
|
+
}
|
|
51
|
+
&__alt,
|
|
52
|
+
&__loading {
|
|
53
|
+
position: absolute;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
</style>
|
|
57
|
+
<script>
|
|
58
|
+
const State = {
|
|
59
|
+
LOADING: 'loading',
|
|
60
|
+
ERROR: 'error',
|
|
61
|
+
DONE: 'done',
|
|
62
|
+
};
|
|
63
|
+
export default {
|
|
64
|
+
props: {
|
|
65
|
+
/**
|
|
66
|
+
* Avatar src url
|
|
67
|
+
*/
|
|
68
|
+
src: {
|
|
69
|
+
type: String,
|
|
70
|
+
default: '',
|
|
71
|
+
},
|
|
72
|
+
/**
|
|
73
|
+
* Alternative text
|
|
74
|
+
*/
|
|
75
|
+
alt: {
|
|
76
|
+
type: String,
|
|
77
|
+
default: '',
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* Color (any web color format)
|
|
81
|
+
*/
|
|
82
|
+
color: {
|
|
83
|
+
type: String,
|
|
84
|
+
default: '#fff',
|
|
85
|
+
},
|
|
86
|
+
/**
|
|
87
|
+
* Background color (any web color format)
|
|
88
|
+
*/
|
|
89
|
+
background: {
|
|
90
|
+
type: String,
|
|
91
|
+
default: '#999',
|
|
92
|
+
},
|
|
93
|
+
/**
|
|
94
|
+
* Whether the avatar should be around
|
|
95
|
+
*/
|
|
96
|
+
round: {
|
|
97
|
+
type: Boolean,
|
|
98
|
+
default: true,
|
|
99
|
+
},
|
|
100
|
+
/**
|
|
101
|
+
* Defines avatar's size (any web size)
|
|
102
|
+
*/
|
|
103
|
+
size: {
|
|
104
|
+
type: String,
|
|
105
|
+
default: '2rem',
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
data: () => ({ state: State.LOADING }),
|
|
109
|
+
computed: {
|
|
110
|
+
/**
|
|
111
|
+
* @return {boolean}
|
|
112
|
+
*/
|
|
113
|
+
isLoadingState() {
|
|
114
|
+
return this.state === State.LOADING;
|
|
115
|
+
},
|
|
116
|
+
/**
|
|
117
|
+
* @return {boolean}
|
|
118
|
+
*/
|
|
119
|
+
isErrorState() {
|
|
120
|
+
return this.state === State.ERROR;
|
|
121
|
+
},
|
|
122
|
+
/**
|
|
123
|
+
* @return {boolean}
|
|
124
|
+
*/
|
|
125
|
+
isDoneState() {
|
|
126
|
+
return this.state === State.DONE;
|
|
127
|
+
},
|
|
128
|
+
/**
|
|
129
|
+
* @return {object}
|
|
130
|
+
*/
|
|
131
|
+
cssClass() {
|
|
132
|
+
return { 'ui-avatar--round': this.round };
|
|
133
|
+
},
|
|
134
|
+
/**
|
|
135
|
+
* @return {object}
|
|
136
|
+
*/
|
|
137
|
+
cssStyle() {
|
|
138
|
+
const { size, color, round, background } = this;
|
|
139
|
+
const borderRadius = round ? '50%' : 0;
|
|
140
|
+
return { '--size': size, height: size, color, background, borderRadius };
|
|
141
|
+
},
|
|
142
|
+
/**
|
|
143
|
+
* @return {string}
|
|
144
|
+
*/
|
|
145
|
+
abbr() {
|
|
146
|
+
const str = this.alt ?? '';
|
|
147
|
+
return str
|
|
148
|
+
.split(' ')
|
|
149
|
+
.map(s => (s.length ? s[0].toUpperCase() : ''))
|
|
150
|
+
.join('');
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
watch: {
|
|
154
|
+
src() {
|
|
155
|
+
this.state = State.LOADING;
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
methods: {
|
|
159
|
+
onImageError(event) {
|
|
160
|
+
this.state = State.ERROR;
|
|
161
|
+
/**
|
|
162
|
+
* Error event
|
|
163
|
+
* @property {Event} event
|
|
164
|
+
*/
|
|
165
|
+
this.$emit('error', event);
|
|
166
|
+
},
|
|
167
|
+
onImageLoad(event) {
|
|
168
|
+
this.state = State.DONE;
|
|
169
|
+
/**
|
|
170
|
+
* Load event
|
|
171
|
+
* @property {Event} event
|
|
172
|
+
*/
|
|
173
|
+
this.$emit('load', event);
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
</script>
|
|
@@ -19,10 +19,20 @@
|
|
|
19
19
|
</style>
|
|
20
20
|
<script>
|
|
21
21
|
import { createPopper } from '@popperjs/core';
|
|
22
|
-
import { Position } from './utils/Helpers';
|
|
22
|
+
import { Position, generateGetBoundingClientRect } from './utils/Helpers';
|
|
23
23
|
|
|
24
24
|
const isElem = el => el instanceof HTMLElement;
|
|
25
25
|
|
|
26
|
+
const Strategy = Object.freeze({
|
|
27
|
+
ABSOLUTE: 'absolute',
|
|
28
|
+
FIXED: 'fixed'
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const Modifier = Object.freeze({
|
|
32
|
+
FLIP: 'flip',
|
|
33
|
+
OFFSET: 'offset'
|
|
34
|
+
});
|
|
35
|
+
|
|
26
36
|
export default {
|
|
27
37
|
directives: {
|
|
28
38
|
'append-body': {
|
|
@@ -96,6 +106,27 @@ export default {
|
|
|
96
106
|
type: Boolean,
|
|
97
107
|
default: false,
|
|
98
108
|
},
|
|
109
|
+
/**
|
|
110
|
+
* Should follow the cursor
|
|
111
|
+
*/
|
|
112
|
+
shouldFollowCursor: {
|
|
113
|
+
type: Boolean,
|
|
114
|
+
default: false
|
|
115
|
+
},
|
|
116
|
+
/**
|
|
117
|
+
* Cursor coordinates [ x, y ]
|
|
118
|
+
*/
|
|
119
|
+
cursorCoordinates: {
|
|
120
|
+
type: Array,
|
|
121
|
+
default: () => [0, 0]
|
|
122
|
+
},
|
|
123
|
+
/**
|
|
124
|
+
* Whether handle events to control visibility
|
|
125
|
+
*/
|
|
126
|
+
isManualControlMode: {
|
|
127
|
+
type: Boolean,
|
|
128
|
+
default: false
|
|
129
|
+
}
|
|
99
130
|
},
|
|
100
131
|
data() {
|
|
101
132
|
return { cssStyle: {} };
|
|
@@ -114,39 +145,38 @@ export default {
|
|
|
114
145
|
}
|
|
115
146
|
return position;
|
|
116
147
|
},
|
|
148
|
+
options() {
|
|
149
|
+
const { appendToBody, placement, positionFlip, positionOffset } = this;
|
|
150
|
+
const strategy = appendToBody ? Strategy.FIXED : Strategy.ABSOLUTE;
|
|
151
|
+
const modifiers = [
|
|
152
|
+
{
|
|
153
|
+
name: Modifier.FLIP,
|
|
154
|
+
enabled: positionFlip,
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: Modifier.OFFSET,
|
|
158
|
+
options: {
|
|
159
|
+
offset: positionOffset,
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
]
|
|
163
|
+
return { placement, strategy, modifiers };
|
|
164
|
+
}
|
|
117
165
|
},
|
|
118
166
|
watch: {
|
|
119
167
|
show: {
|
|
120
168
|
handler(val) {
|
|
121
|
-
const { appendToBody, placement, positionFlip, positionOffset } = this;
|
|
122
|
-
const strategy = appendToBody ? 'fixed' : 'absolute';
|
|
123
169
|
this.$nextTick(() => {
|
|
124
|
-
if (val) {
|
|
170
|
+
if (val === false) {
|
|
171
|
+
this.handleReset();
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (this.isManualControlMode === false) {
|
|
125
176
|
this.addEventListeners();
|
|
126
|
-
this.popper = createPopper(this.getTarget(), this.$el, {
|
|
127
|
-
placement,
|
|
128
|
-
strategy,
|
|
129
|
-
modifiers: [
|
|
130
|
-
{
|
|
131
|
-
name: 'flip',
|
|
132
|
-
enabled: positionFlip,
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
name: 'offset',
|
|
136
|
-
options: {
|
|
137
|
-
offset: positionOffset,
|
|
138
|
-
},
|
|
139
|
-
},
|
|
140
|
-
],
|
|
141
|
-
});
|
|
142
|
-
this.$nextTick(() => {
|
|
143
|
-
this.calcStyle();
|
|
144
|
-
this.popper.update();
|
|
145
|
-
});
|
|
146
|
-
} else {
|
|
147
|
-
this.removeEventListeners();
|
|
148
|
-
this.destroyPopper();
|
|
149
177
|
}
|
|
178
|
+
|
|
179
|
+
this.createPopper();
|
|
150
180
|
});
|
|
151
181
|
},
|
|
152
182
|
immediate: true,
|
|
@@ -156,8 +186,7 @@ export default {
|
|
|
156
186
|
this.popper = null;
|
|
157
187
|
},
|
|
158
188
|
destroyed() {
|
|
159
|
-
this.
|
|
160
|
-
this.destroyPopper();
|
|
189
|
+
this.handleReset();
|
|
161
190
|
},
|
|
162
191
|
methods: {
|
|
163
192
|
addEventListeners() {
|
|
@@ -185,10 +214,42 @@ export default {
|
|
|
185
214
|
setShow(val) {
|
|
186
215
|
this.$nextTick(() => this.$emit('update:show', val));
|
|
187
216
|
},
|
|
217
|
+
createPopper() {
|
|
218
|
+
const { shouldFollowCursor, options, $el: popper, cursorCoordinates } = this;
|
|
219
|
+
const target = this.getTarget();
|
|
220
|
+
|
|
221
|
+
if (shouldFollowCursor) {
|
|
222
|
+
const [x, y] = cursorCoordinates;
|
|
223
|
+
const virtualElem = {
|
|
224
|
+
getBoundingClientRect: generateGetBoundingClientRect(x, y),
|
|
225
|
+
contextElement: target
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
this.popper = createPopper(virtualElem, popper, options);
|
|
229
|
+
this.unwatchCursorCoordinates = this.$watch('cursorCoordinates', ([x, y]) => {
|
|
230
|
+
virtualElem.getBoundingClientRect = generateGetBoundingClientRect(x, y);
|
|
231
|
+
this.popper?.update();
|
|
232
|
+
})
|
|
233
|
+
} else {
|
|
234
|
+
this.popper = createPopper(target, popper, options);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
this.$nextTick(() => {
|
|
238
|
+
this.calcStyle();
|
|
239
|
+
this.popper.update();
|
|
240
|
+
});
|
|
241
|
+
},
|
|
188
242
|
destroyPopper() {
|
|
189
|
-
this.popper
|
|
243
|
+
this.popper?.destroy();
|
|
190
244
|
this.popper = null;
|
|
191
245
|
},
|
|
246
|
+
handleReset() {
|
|
247
|
+
this.unwatchCursorCoordinates?.();
|
|
248
|
+
if (this.isManualControlMode === false) {
|
|
249
|
+
this.removeEventListeners();
|
|
250
|
+
}
|
|
251
|
+
this.destroyPopper();
|
|
252
|
+
},
|
|
192
253
|
onWinBlur(e) {
|
|
193
254
|
if (this.show) {
|
|
194
255
|
this.setShow(false);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
Simple example
|
|
2
|
+
|
|
1
3
|
```vue
|
|
2
4
|
<template>
|
|
3
5
|
<div class="pos-rel pad-l5">
|
|
@@ -50,3 +52,63 @@ export default {
|
|
|
50
52
|
};
|
|
51
53
|
</script>
|
|
52
54
|
```
|
|
55
|
+
|
|
56
|
+
Advanced example. Using cursor tracking
|
|
57
|
+
|
|
58
|
+
```vue
|
|
59
|
+
<template>
|
|
60
|
+
<div class="pos-rel pad-l5">
|
|
61
|
+
<ui-tooltip v-bind="options">
|
|
62
|
+
<template #target="{ binds }">
|
|
63
|
+
<div
|
|
64
|
+
ref="target"
|
|
65
|
+
class="pad-l2 bg-green color-white radius text-center"
|
|
66
|
+
v-bind="binds"
|
|
67
|
+
>
|
|
68
|
+
hover me
|
|
69
|
+
</div>
|
|
70
|
+
</template>
|
|
71
|
+
<div>
|
|
72
|
+
I follow the cursor everywhere
|
|
73
|
+
</div>
|
|
74
|
+
</ui-tooltip>
|
|
75
|
+
</div>
|
|
76
|
+
</template>
|
|
77
|
+
<script>
|
|
78
|
+
import UiTooltip from './Tooltip.vue';
|
|
79
|
+
export default {
|
|
80
|
+
components: { UiTooltip },
|
|
81
|
+
data() {
|
|
82
|
+
return {
|
|
83
|
+
options: {
|
|
84
|
+
show: false,
|
|
85
|
+
shouldFollowCursor: true,
|
|
86
|
+
cursorCoordinates: [0, 0]
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
mounted() {
|
|
91
|
+
this.$refs.target.addEventListener('mouseover', this.showTooltip);
|
|
92
|
+
this.$refs.target.addEventListener('mousemove', this.changeTooltipCoords);
|
|
93
|
+
this.$refs.target.addEventListener('mouseleave', this.hideTooltip);
|
|
94
|
+
},
|
|
95
|
+
beforeDestroy() {
|
|
96
|
+
this.$refs.target.removeEventListener('mouseover', this.showTooltip);
|
|
97
|
+
this.$refs.target.removeEventListener('mousemove', this.changeTooltipCoords);
|
|
98
|
+
this.$refs.target.removeEventListener('mouseleave', this.hideTooltip);
|
|
99
|
+
|
|
100
|
+
},
|
|
101
|
+
methods: {
|
|
102
|
+
showTooltip() {
|
|
103
|
+
this.options.show = true;
|
|
104
|
+
},
|
|
105
|
+
hideTooltip() {
|
|
106
|
+
this.options.show = false;
|
|
107
|
+
},
|
|
108
|
+
changeTooltipCoords({ clientX: x, clientY: y }) {
|
|
109
|
+
this.options.cursorCoordinates = [x, y];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
</script>
|
|
114
|
+
```
|
|
@@ -58,4 +58,27 @@ const useIntersectionObserver = (target, callback, options) => {
|
|
|
58
58
|
return { observer, stop: () => observer.disconnect() };
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
/**
|
|
62
|
+
* @param {number} x - x-axis coordinate
|
|
63
|
+
* @param {number} y - y-axis coordinate
|
|
64
|
+
* @return {function: DOMRect}
|
|
65
|
+
*/
|
|
66
|
+
const generateGetBoundingClientRect = (x = 0, y = 0) => () => ({
|
|
67
|
+
width: 0,
|
|
68
|
+
height: 0,
|
|
69
|
+
top: y,
|
|
70
|
+
right: x,
|
|
71
|
+
bottom: y,
|
|
72
|
+
left: x,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
export {
|
|
76
|
+
scrollIntoView,
|
|
77
|
+
isDateValid,
|
|
78
|
+
nextId,
|
|
79
|
+
Key,
|
|
80
|
+
Position,
|
|
81
|
+
debounce,
|
|
82
|
+
useIntersectionObserver,
|
|
83
|
+
generateGetBoundingClientRect,
|
|
84
|
+
};
|
|
@@ -43,6 +43,20 @@ export default {
|
|
|
43
43
|
type: Boolean,
|
|
44
44
|
default: false,
|
|
45
45
|
},
|
|
46
|
+
/**
|
|
47
|
+
* Should follow the cursor
|
|
48
|
+
*/
|
|
49
|
+
shouldFollowCursor: {
|
|
50
|
+
type: Boolean,
|
|
51
|
+
default: false
|
|
52
|
+
},
|
|
53
|
+
/**
|
|
54
|
+
* Cursor coordinates [ x, y ]
|
|
55
|
+
*/
|
|
56
|
+
cursorCoordinates: {
|
|
57
|
+
type: Array,
|
|
58
|
+
default: () => [0, 0]
|
|
59
|
+
}
|
|
46
60
|
},
|
|
47
61
|
data() {
|
|
48
62
|
return {
|
|
@@ -62,6 +76,8 @@ export default {
|
|
|
62
76
|
positionOffset,
|
|
63
77
|
autoWidth,
|
|
64
78
|
popoverTarget: target,
|
|
79
|
+
shouldFollowCursor,
|
|
80
|
+
cursorCoordinates
|
|
65
81
|
} = this;
|
|
66
82
|
return {
|
|
67
83
|
zIndex,
|
|
@@ -70,6 +86,8 @@ export default {
|
|
|
70
86
|
positionOffset,
|
|
71
87
|
autoWidth,
|
|
72
88
|
target,
|
|
89
|
+
shouldFollowCursor,
|
|
90
|
+
cursorCoordinates
|
|
73
91
|
};
|
|
74
92
|
},
|
|
75
93
|
},
|