@teammodlr/ui-kit 2.1.78 → 2.2.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/lib/components/dialog/Dialog.vue.d.ts +1 -1
- package/lib/components/dropdown/Dropdown.vue.d.ts +14 -9
- package/lib/components/dropdown/DropdownTrigger.vue.d.ts +11 -0
- package/lib/components/messageprovider/Message.vue.d.ts +1 -1
- package/lib/components/modal/Modal.vue.d.ts +1 -1
- package/lib/components/primative/index.d.ts +2 -0
- package/lib/components/primative/primitive.d.ts +30 -0
- package/lib/components/primative/slot.d.ts +5 -0
- package/lib/components/tooltip/Tooltip.vue.d.ts +12 -6
- package/lib/components/tooltip/TooltipTrigger.vue.d.ts +11 -0
- package/lib/index.cjs.js +7 -7
- package/lib/index.es.js +2675 -2542
- package/lib/utils/renderSlotFragments.d.ts +2 -0
- package/lib/utils/useForwardExpose.d.ts +6 -0
- package/package.json +1 -1
- package/src/components/button/Button.vue +1 -2
- package/src/components/dialog/Dialog.vue +4 -2
- package/src/components/dialogprovider/examples/basic.vue +54 -54
- package/src/components/dialogprovider/examples/index.stories.ts +26 -26
- package/src/components/dropdown/Dropdown.vue +28 -7
- package/src/components/dropdown/DropdownTrigger.vue +20 -0
- package/src/components/primative/examples/as-child.vue +13 -0
- package/src/components/primative/examples/as.vue +13 -0
- package/src/components/primative/examples/index.stories.ts +12 -0
- package/src/components/primative/examples/index.ts +2 -0
- package/src/components/primative/index.ts +2 -0
- package/src/components/primative/primitive.ts +56 -0
- package/src/components/primative/slot.ts +45 -0
- package/src/components/tooltip/Tooltip.vue +26 -8
- package/src/components/tooltip/TooltipTrigger.vue +20 -0
- package/src/components/tooltip/examples/basic.vue +1 -1
- package/src/utils/renderSlotFragments.ts +15 -0
- package/src/utils/useForwardExpose.ts +65 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type ComponentPublicInstance } from 'vue';
|
|
2
|
+
export declare function useForwardExpose(): {
|
|
3
|
+
forwardRef: (ref: Element | ComponentPublicInstance | null) => void;
|
|
4
|
+
currentRef: import("vue").Ref<Element | ComponentPublicInstance | null | undefined>;
|
|
5
|
+
currentElement: import("vue").ComputedRef<HTMLElement>;
|
|
6
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<component :is="computedTag" :to="to" :href="href" :type="type" :class="computedClasses" :disabled="disabled"
|
|
3
3
|
@click="handleClick" v-bind="$attrs">
|
|
4
|
-
<!-- <div :class="computedWaveClasses" :key="waveTimerId"></div>-->
|
|
5
4
|
<div :class="computedBorderClasses"></div>
|
|
6
5
|
<div :class="computedBorderStateClasses"></div>
|
|
7
6
|
<span v-if="hasIconLeft" :class="iconLeft">
|
|
@@ -201,4 +200,4 @@ export default defineComponent({
|
|
|
201
200
|
}
|
|
202
201
|
})
|
|
203
202
|
</script>
|
|
204
|
-
|
|
203
|
+
|
|
@@ -108,7 +108,7 @@ export default defineComponent({
|
|
|
108
108
|
const wrapper = ref<HTMLElement | null>(null);
|
|
109
109
|
const dialog = ref<HTMLElement | null>(null);
|
|
110
110
|
const handle = ref<HTMLElement | null>(null);
|
|
111
|
-
const { nextZIndex } = useZIndex();
|
|
111
|
+
const { nextZIndex, current: maxZIndex } = useZIndex();
|
|
112
112
|
const zIndex = ref(props.zIndex ?? nextZIndex());
|
|
113
113
|
|
|
114
114
|
const isOpen = ref<boolean>(props.open);
|
|
@@ -174,7 +174,9 @@ export default defineComponent({
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
function onDragStart() {
|
|
177
|
-
zIndex.value
|
|
177
|
+
if (zIndex.value < maxZIndex.value) {
|
|
178
|
+
zIndex.value = nextZIndex();
|
|
179
|
+
}
|
|
178
180
|
isDragging.value = true;
|
|
179
181
|
}
|
|
180
182
|
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<button @click="showDialog">Show Dialog</button>
|
|
4
|
-
<button @click="showDialog2">Show Dialog 2</button>
|
|
5
|
-
{{ testTitle }}
|
|
6
|
-
</div>
|
|
7
|
-
</template>
|
|
8
|
-
|
|
9
|
-
<script lang="ts" setup>
|
|
10
|
-
import {ref, h} from 'vue';
|
|
11
|
-
import {useDialog} from '../useDialog';
|
|
12
|
-
|
|
13
|
-
const dialog = useDialog();
|
|
14
|
-
const testTitle = ref('This is a test');
|
|
15
|
-
|
|
16
|
-
function renderMessage({message}: { message: string }) {
|
|
17
|
-
return h('p', [
|
|
18
|
-
'Here are ',
|
|
19
|
-
h('span', {style: 'color: red'}, [message]),
|
|
20
|
-
' that using render function',
|
|
21
|
-
]);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function showDialog() {
|
|
25
|
-
dialog.create('hello', {
|
|
26
|
-
title: testTitle,
|
|
27
|
-
render: renderMessage,
|
|
28
|
-
props: {message: testTitle},
|
|
29
|
-
open: true,
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
setTimeout(() => {
|
|
33
|
-
testTitle.value = 'changed';
|
|
34
|
-
}, 4000);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function showDialog2() {
|
|
38
|
-
dialog.create('hello-two', {
|
|
39
|
-
title: "Hello Second Dialog",
|
|
40
|
-
render: renderMessage,
|
|
41
|
-
props: {message: testTitle},
|
|
42
|
-
open: true,
|
|
43
|
-
modal: false,
|
|
44
|
-
draggable: false,
|
|
45
|
-
onOpen: () => {
|
|
46
|
-
console.log('hello world')
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
setTimeout(() => {
|
|
51
|
-
testTitle.value = 'changed again';
|
|
52
|
-
}, 4000);
|
|
53
|
-
}
|
|
54
|
-
</script>
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<button @click="showDialog">Show Dialog</button>
|
|
4
|
+
<button @click="showDialog2">Show Dialog 2</button>
|
|
5
|
+
{{ testTitle }}
|
|
6
|
+
</div>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script lang="ts" setup>
|
|
10
|
+
import {ref, h} from 'vue';
|
|
11
|
+
import {useDialog} from '../useDialog';
|
|
12
|
+
|
|
13
|
+
const dialog = useDialog();
|
|
14
|
+
const testTitle = ref('This is a test');
|
|
15
|
+
|
|
16
|
+
function renderMessage({message}: { message: string }) {
|
|
17
|
+
return h('p', [
|
|
18
|
+
'Here are ',
|
|
19
|
+
h('span', {style: 'color: red'}, [message]),
|
|
20
|
+
' that using render function',
|
|
21
|
+
]);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function showDialog() {
|
|
25
|
+
dialog.create('hello', {
|
|
26
|
+
title: testTitle,
|
|
27
|
+
render: renderMessage,
|
|
28
|
+
props: {message: testTitle},
|
|
29
|
+
open: true,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
setTimeout(() => {
|
|
33
|
+
testTitle.value = 'changed';
|
|
34
|
+
}, 4000);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function showDialog2() {
|
|
38
|
+
dialog.create('hello-two', {
|
|
39
|
+
title: "Hello Second Dialog",
|
|
40
|
+
render: renderMessage,
|
|
41
|
+
props: {message: testTitle},
|
|
42
|
+
open: true,
|
|
43
|
+
modal: false,
|
|
44
|
+
draggable: false,
|
|
45
|
+
onOpen: () => {
|
|
46
|
+
console.log('hello world')
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
setTimeout(() => {
|
|
51
|
+
testTitle.value = 'changed again';
|
|
52
|
+
}, 4000);
|
|
53
|
+
}
|
|
54
|
+
</script>
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import MDialogProvider from '../DialogProvider.vue';
|
|
2
|
-
import { MDialogProviderBasic } from './index';
|
|
3
|
-
|
|
4
|
-
const Template = (args: any) => ({
|
|
5
|
-
components: {
|
|
6
|
-
MDialogProvider,
|
|
7
|
-
MDialogProviderBasic
|
|
8
|
-
},
|
|
9
|
-
setup() {
|
|
10
|
-
return {
|
|
11
|
-
args
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
template: `
|
|
15
|
-
<m-dialog-provider v-bind="args">
|
|
16
|
-
<MDialogProviderBasic />
|
|
17
|
-
</m-dialog-provider>
|
|
18
|
-
`
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
export default {
|
|
22
|
-
component: MDialogProvider,
|
|
23
|
-
title: 'Components/DialogProvider'
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const Primary = Template.bind({});
|
|
1
|
+
import MDialogProvider from '../DialogProvider.vue';
|
|
2
|
+
import { MDialogProviderBasic } from './index';
|
|
3
|
+
|
|
4
|
+
const Template = (args: any) => ({
|
|
5
|
+
components: {
|
|
6
|
+
MDialogProvider,
|
|
7
|
+
MDialogProviderBasic
|
|
8
|
+
},
|
|
9
|
+
setup() {
|
|
10
|
+
return {
|
|
11
|
+
args
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
template: `
|
|
15
|
+
<m-dialog-provider v-bind="args">
|
|
16
|
+
<MDialogProviderBasic />
|
|
17
|
+
</m-dialog-provider>
|
|
18
|
+
`
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export default {
|
|
22
|
+
component: MDialogProvider,
|
|
23
|
+
title: 'Components/DialogProvider'
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const Primary = Template.bind({});
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
2
|
+
<Primitive
|
|
3
|
+
as-child
|
|
4
|
+
ref="wrapper">
|
|
5
|
+
|
|
6
|
+
<DropdownTrigger
|
|
4
7
|
ref="referenceRef"
|
|
5
8
|
:class="computedReferenceClasses"
|
|
6
9
|
@click="toggleDropdown">
|
|
7
10
|
<slot />
|
|
8
|
-
</
|
|
11
|
+
</DropdownTrigger>
|
|
9
12
|
|
|
10
13
|
<DropdownWrapper>
|
|
11
14
|
<Teleport :disabled="isNested" to="body">
|
|
@@ -24,13 +27,14 @@
|
|
|
24
27
|
</transition>
|
|
25
28
|
</Teleport>
|
|
26
29
|
</DropdownWrapper>
|
|
27
|
-
</
|
|
30
|
+
</Primitive>
|
|
28
31
|
</template>
|
|
29
32
|
|
|
30
33
|
<script lang="ts">
|
|
31
34
|
import { usePopper } from '../../composables/usePopper';
|
|
32
35
|
import type { Placement, VirtualElement } from '@popperjs/core';
|
|
33
36
|
import { scale } from '../../styles/transitions.css';
|
|
37
|
+
import {Primitive} from "../primative/primitive";
|
|
34
38
|
import {
|
|
35
39
|
defineComponent,
|
|
36
40
|
inject,
|
|
@@ -43,7 +47,7 @@ import {
|
|
|
43
47
|
computed,
|
|
44
48
|
toRef,
|
|
45
49
|
reactive,
|
|
46
|
-
watchEffect
|
|
50
|
+
watchEffect, type Ref
|
|
47
51
|
} from 'vue';
|
|
48
52
|
import { onClickOutside, useEventListener } from '@vueuse/core';
|
|
49
53
|
import DropdownWrapper from './DropdownWrapper.vue';
|
|
@@ -52,11 +56,23 @@ import { useZIndex } from '../../composables/useZIndex';
|
|
|
52
56
|
import type { DropdownState } from './symbol';
|
|
53
57
|
import { DROPDOWN_STATE } from './symbol';
|
|
54
58
|
import * as style from './style';
|
|
59
|
+
import {createContext} from "../../utils/injection";
|
|
60
|
+
import DropdownTrigger from "./DropdownTrigger.vue";
|
|
61
|
+
|
|
62
|
+
interface DropdownContext {
|
|
63
|
+
reference: Ref<HTMLElement | undefined>
|
|
64
|
+
onReferenceChange: (element: HTMLElement | undefined) => void
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const [injectDropdownContext, provideDropdownContext] = createContext<DropdownContext>('Dropdown');
|
|
68
|
+
|
|
55
69
|
|
|
56
70
|
export default defineComponent({
|
|
57
71
|
name: 'Dropdown',
|
|
58
72
|
components: {
|
|
59
|
-
|
|
73
|
+
DropdownTrigger,
|
|
74
|
+
DropdownWrapper,
|
|
75
|
+
Primitive
|
|
60
76
|
},
|
|
61
77
|
props: {
|
|
62
78
|
open: {
|
|
@@ -113,7 +129,7 @@ export default defineComponent({
|
|
|
113
129
|
const placement = ref(props.placement);
|
|
114
130
|
const transfer = toRef(props, 'transfer');
|
|
115
131
|
const wrapper = ref(null);
|
|
116
|
-
const referenceRef = ref(
|
|
132
|
+
const referenceRef = ref<HTMLElement>();
|
|
117
133
|
const zIndex = ref(props.zIndex ?? nextZIndex());
|
|
118
134
|
const reference = computed(() => {
|
|
119
135
|
if (props.virtual !== null) {
|
|
@@ -141,6 +157,11 @@ export default defineComponent({
|
|
|
141
157
|
return referenceRef.value;
|
|
142
158
|
});
|
|
143
159
|
|
|
160
|
+
provideDropdownContext({
|
|
161
|
+
reference: referenceRef,
|
|
162
|
+
onReferenceChange: element => referenceRef.value = element
|
|
163
|
+
});
|
|
164
|
+
|
|
144
165
|
const { popper, transferTo, updatePopper } = usePopper({
|
|
145
166
|
reference: reference,
|
|
146
167
|
placement,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {Primitive} from "../primative/primitive";
|
|
3
|
+
import { useForwardExpose } from "../../utils/useForwardExpose";
|
|
4
|
+
import {onMounted} from "vue";
|
|
5
|
+
import { injectDropdownContext } from "./Dropdown.vue";
|
|
6
|
+
|
|
7
|
+
const { forwardRef, currentElement } = useForwardExpose();
|
|
8
|
+
|
|
9
|
+
const dropdownContext = injectDropdownContext();
|
|
10
|
+
|
|
11
|
+
onMounted(() => {
|
|
12
|
+
dropdownContext.onReferenceChange(currentElement.value);
|
|
13
|
+
})
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<Primitive as-child :ref="forwardRef">
|
|
18
|
+
<slot />
|
|
19
|
+
</Primitive>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { Primitive, type PrimitiveProps } from '../index'
|
|
3
|
+
|
|
4
|
+
const props = withDefaults(defineProps<PrimitiveProps>(), {
|
|
5
|
+
asChild: true
|
|
6
|
+
})
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<Primitive v-bind="props">
|
|
11
|
+
<a href="https://google.com">Google</a>
|
|
12
|
+
</Primitive>
|
|
13
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { Primitive, type PrimitiveProps } from '../index'
|
|
3
|
+
|
|
4
|
+
const props = withDefaults(defineProps<PrimitiveProps>(), {
|
|
5
|
+
as: 'span'
|
|
6
|
+
})
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<Primitive v-bind="props">
|
|
11
|
+
...
|
|
12
|
+
</Primitive>
|
|
13
|
+
</template>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Primitive } from '../';
|
|
2
|
+
import { PrimitiveAs, PrimitiveAsChild } from './index';
|
|
3
|
+
|
|
4
|
+
import { createStory } from '../../../__storybook__';
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
component: Primitive,
|
|
8
|
+
title: 'Components/Primitive'
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const As = createStory(PrimitiveAs);
|
|
12
|
+
export const AsChild = createStory(PrimitiveAsChild);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type Component, type PropType, defineComponent, h } from "vue";
|
|
2
|
+
import { Slot } from './slot';
|
|
3
|
+
|
|
4
|
+
export type AsTag =
|
|
5
|
+
| 'a'
|
|
6
|
+
| 'button'
|
|
7
|
+
| 'div'
|
|
8
|
+
| 'form'
|
|
9
|
+
| 'h2'
|
|
10
|
+
| 'h3'
|
|
11
|
+
| 'img'
|
|
12
|
+
| 'input'
|
|
13
|
+
| 'label'
|
|
14
|
+
| 'li'
|
|
15
|
+
| 'nav'
|
|
16
|
+
| 'ol'
|
|
17
|
+
| 'p'
|
|
18
|
+
| 'span'
|
|
19
|
+
| 'svg'
|
|
20
|
+
| 'ul'
|
|
21
|
+
| 'template'
|
|
22
|
+
| ({} & string);
|
|
23
|
+
|
|
24
|
+
export interface PrimitiveProps {
|
|
25
|
+
asChild?: boolean
|
|
26
|
+
as?: AsTag | Component
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const Primitive = defineComponent({
|
|
30
|
+
name: "Primitive",
|
|
31
|
+
inheritAttrs: false,
|
|
32
|
+
props: {
|
|
33
|
+
asChild: {
|
|
34
|
+
type: Boolean,
|
|
35
|
+
default: false
|
|
36
|
+
},
|
|
37
|
+
as: {
|
|
38
|
+
type: [String, Object] as PropType<AsTag | Component>,
|
|
39
|
+
default: 'div'
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
setup(props, { attrs, slots }) {
|
|
43
|
+
const asTag = props.asChild ? 'template' : props.as;
|
|
44
|
+
|
|
45
|
+
const SELF_CLOSING = ['area', 'img', 'input'];
|
|
46
|
+
if (typeof asTag === 'string' && SELF_CLOSING.includes(asTag)) {
|
|
47
|
+
return () => h(asTag, attrs);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (asTag !== 'template') {
|
|
51
|
+
return () => h(props.as, attrs, { default: slots.default });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return () => h(Slot, attrs, { default: slots.default });
|
|
55
|
+
}
|
|
56
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Comment, cloneVNode, defineComponent, mergeProps } from 'vue';
|
|
2
|
+
import {renderSlotFragments} from "../../utils/renderSlotFragments";
|
|
3
|
+
|
|
4
|
+
export const Slot = defineComponent({
|
|
5
|
+
name: 'PrimativeSlot',
|
|
6
|
+
inheritAttrs: false,
|
|
7
|
+
setup(_, { attrs, slots }) {
|
|
8
|
+
return () => {
|
|
9
|
+
if (!slots.default) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const children = renderSlotFragments(slots.default());
|
|
14
|
+
const firstNonCommentChildIndex = children.findIndex(child => child.type !== Comment);
|
|
15
|
+
if (firstNonCommentChildIndex === -1) {
|
|
16
|
+
return children;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const firstNonCommentChild = children[firstNonCommentChildIndex];
|
|
20
|
+
delete firstNonCommentChild.props?.ref;
|
|
21
|
+
|
|
22
|
+
const mergedProps = firstNonCommentChild.props ? mergeProps(attrs, firstNonCommentChild.props) : attrs;
|
|
23
|
+
|
|
24
|
+
if (attrs.class && firstNonCommentChild.props?.class) {
|
|
25
|
+
delete firstNonCommentChild.props.class;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const cloned = cloneVNode(firstNonCommentChild, mergedProps);
|
|
29
|
+
|
|
30
|
+
for (const prop in mergedProps) {
|
|
31
|
+
if (prop.startsWith('on')) {
|
|
32
|
+
cloned.props ||= {};
|
|
33
|
+
cloned.props[prop] = mergedProps[prop];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (children.length === 1) {
|
|
38
|
+
return cloned;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
children[firstNonCommentChildIndex] = cloned;
|
|
42
|
+
return children;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
})
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<Primitive
|
|
3
|
+
as-child
|
|
3
4
|
v-bind="$attrs"
|
|
4
|
-
style="display: inline-flex"
|
|
5
5
|
@mouseenter="show"
|
|
6
6
|
@mouseleave="hide"
|
|
7
7
|
ref="wrapper">
|
|
8
|
-
<
|
|
9
|
-
<slot
|
|
10
|
-
</
|
|
8
|
+
<TooltipTrigger ref="reference" >
|
|
9
|
+
<slot/>
|
|
10
|
+
</TooltipTrigger>
|
|
11
11
|
|
|
12
12
|
<Teleport :to="transferTo">
|
|
13
13
|
<Transition
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
</div>
|
|
28
28
|
</Transition>
|
|
29
29
|
</Teleport>
|
|
30
|
-
</
|
|
30
|
+
</Primitive>
|
|
31
31
|
</template>
|
|
32
32
|
|
|
33
33
|
<script lang="ts">
|
|
@@ -38,19 +38,31 @@ import {
|
|
|
38
38
|
type PropType,
|
|
39
39
|
computed,
|
|
40
40
|
watch,
|
|
41
|
-
onUnmounted
|
|
41
|
+
onUnmounted, type Ref
|
|
42
42
|
} from 'vue';
|
|
43
43
|
import {
|
|
44
44
|
type Placement,
|
|
45
45
|
placementWhileList,
|
|
46
46
|
usePopper
|
|
47
47
|
} from '../../composables/usePopper';
|
|
48
|
+
|
|
48
49
|
import { fade } from '../../styles/transitions.css';
|
|
49
50
|
import * as style from './style';
|
|
50
51
|
import { useZIndex } from '../../composables/useZIndex';
|
|
52
|
+
import {Primitive} from "../primative/primitive";
|
|
53
|
+
import TooltipTrigger from "@/components/tooltip/TooltipTrigger.vue";
|
|
54
|
+
import {createContext} from "../../utils/injection";
|
|
55
|
+
|
|
56
|
+
interface TooltipContext {
|
|
57
|
+
reference: Ref<HTMLElement | undefined>
|
|
58
|
+
onReferenceChange: (element: HTMLElement | undefined) => void
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const [injectionTooltipContext, providerTooltipContext] = createContext<TooltipContext>('Tooltip');
|
|
51
62
|
|
|
52
63
|
export default defineComponent({
|
|
53
64
|
name: 'MTooltip',
|
|
65
|
+
components: {TooltipTrigger, Primitive},
|
|
54
66
|
props: {
|
|
55
67
|
text: {
|
|
56
68
|
type: String,
|
|
@@ -87,7 +99,7 @@ export default defineComponent({
|
|
|
87
99
|
// @ts-ignore
|
|
88
100
|
const transfer = toRef(props, 'transfer');
|
|
89
101
|
const wrapper = ref<HTMLElement | null>(null);
|
|
90
|
-
const reference = ref<HTMLElement
|
|
102
|
+
const reference = ref<HTMLElement>();
|
|
91
103
|
const isOpen = ref(false);
|
|
92
104
|
const zIndex = ref(props.zIndex ?? nextZIndex());
|
|
93
105
|
const timeout = ref<ReturnType<typeof setTimeout> | null>(null);
|
|
@@ -106,6 +118,11 @@ export default defineComponent({
|
|
|
106
118
|
}
|
|
107
119
|
});
|
|
108
120
|
|
|
121
|
+
providerTooltipContext({
|
|
122
|
+
reference,
|
|
123
|
+
onReferenceChange: element => reference.value = element
|
|
124
|
+
});
|
|
125
|
+
|
|
109
126
|
const { popper, transferTo, updatePopper } = usePopper({
|
|
110
127
|
placement,
|
|
111
128
|
transfer,
|
|
@@ -179,6 +196,7 @@ export default defineComponent({
|
|
|
179
196
|
|
|
180
197
|
return {
|
|
181
198
|
reference,
|
|
199
|
+
offset,
|
|
182
200
|
popper,
|
|
183
201
|
transferTo,
|
|
184
202
|
isOpen,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {Primitive} from "../primative/primitive";
|
|
3
|
+
import { useForwardExpose } from "../../utils/useForwardExpose";
|
|
4
|
+
import {onMounted} from "vue";
|
|
5
|
+
import { injectionTooltipContext } from "./Tooltip.vue";
|
|
6
|
+
|
|
7
|
+
const { forwardRef, currentElement } = useForwardExpose();
|
|
8
|
+
|
|
9
|
+
const tooltipContext = injectionTooltipContext();
|
|
10
|
+
|
|
11
|
+
onMounted(() => {
|
|
12
|
+
tooltipContext.onReferenceChange(currentElement.value);
|
|
13
|
+
})
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<Primitive as-child :ref="forwardRef">
|
|
18
|
+
<slot />
|
|
19
|
+
</Primitive>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Fragment, type VNode } from 'vue';
|
|
2
|
+
|
|
3
|
+
export function renderSlotFragments(children?: VNode[]): VNode[] {
|
|
4
|
+
if (!children) {
|
|
5
|
+
return [];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return children.flatMap((child) => {
|
|
9
|
+
if (child.type === Fragment) {
|
|
10
|
+
return renderSlotFragments(child.children as VNode[]);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return [child];
|
|
14
|
+
});
|
|
15
|
+
}
|