@teammodlr/ui-kit 2.1.64 → 2.1.67
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/colorpicker/ColorPicker.vue.d.ts +9 -0
- package/lib/components/colorpicker/style/ColorPicker.css.d.ts +1 -0
- package/lib/components/dialog/Dialog.vue.d.ts +36 -22
- package/lib/components/dialog/style/Dialog.css.d.ts +1 -0
- package/lib/index.cjs.js +7 -7
- package/lib/index.es.js +2098 -2038
- package/lib/style.css +1 -1
- package/package.json +76 -75
- package/src/components/colorpicker/ColorPicker.vue +54 -42
- package/src/components/colorpicker/examples/basic.vue +8 -3
- package/src/components/colorpicker/style/ColorPicker.css.ts +10 -0
- package/src/components/dialog/Dialog.vue +180 -118
- package/src/components/dialog/examples/basic.vue +8 -1
- package/src/components/dialog/style/Dialog.css.ts +60 -22
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div ref="wrapper" class="m-color-picker">
|
|
3
3
|
<div ref="referenceRef" @click="isOpen = !isOpen">
|
|
4
|
-
<slot :r="finalColor.r" :g="finalColor.g" :b="finalColor.b" :a="finalColor.a" :hex="hexInput">
|
|
5
|
-
<div
|
|
4
|
+
<slot :r="finalColor.r" :g="finalColor.g" :b="finalColor.b" :a="finalColor.a" :hex="hexInput" :transparent="style.transparent">
|
|
5
|
+
<div>
|
|
6
6
|
<div :class="style.referenceColor"
|
|
7
|
-
|
|
7
|
+
:style="{ backgroundColor: `rgba(${finalColor.r}, ${finalColor.g}, ${finalColor.b}, ${finalColor.a})` }">
|
|
8
8
|
</div>
|
|
9
9
|
</div>
|
|
10
10
|
</slot>
|
|
11
11
|
</div>
|
|
12
12
|
<Teleport to="body">
|
|
13
13
|
<transition :enter-active-class="scale.enterActive" :leave-active-class="scale.leaveActive"
|
|
14
|
-
|
|
14
|
+
:enter-from-class="scale.enterFrom" :leave-to-class="scale.leaveTo">
|
|
15
15
|
<div :class="style.container" v-if="isOpen" ref="popper" :style="{ zIndex: zIndex }">
|
|
16
16
|
<div ref="picker" @mousedown="handleMouseDown" :class="style.colours"
|
|
17
|
-
|
|
17
|
+
:style="`background: rgb(${mainColor.r}, ${mainColor.g}, ${mainColor.b});`">
|
|
18
18
|
<div :class="style.whiteGradient"></div>
|
|
19
19
|
<div :class="style.blackGradient"></div>
|
|
20
20
|
<div :class="style.sliderThumb" @mousedown="handleMouseDown" @dragover.prevent=""
|
|
21
|
-
|
|
21
|
+
:style="{ left: `${position.x * 100}%`, top: `${position.y * 100}%` }"></div>
|
|
22
22
|
</div>
|
|
23
23
|
|
|
24
24
|
<div :class="style.colorActions">
|
|
25
25
|
<template v-if="canPickColor">
|
|
26
26
|
<button role="button" :disabled="!canPickColor" :class="style.eyeDrop"
|
|
27
|
-
|
|
27
|
+
@click="openEyeDropper">
|
|
28
28
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
|
|
29
|
-
|
|
29
|
+
xmlns="http://www.w3.org/2000/svg">
|
|
30
30
|
<path
|
|
31
31
|
d="M20.3847 2.87868C19.2132 1.70711 17.3137 1.70711 16.1421 2.87868L14.0202 5.00052L13.313 4.29332C12.9225 3.9028 12.2894 3.9028 11.8988 4.29332C11.5083 4.68385 11.5083 5.31701 11.8988 5.70754L17.5557 11.3644C17.9462 11.7549 18.5794 11.7549 18.9699 11.3644C19.3604 10.9739 19.3604 10.3407 18.9699 9.95018L18.2629 9.24316L20.3847 7.12132C21.5563 5.94975 21.5563 4.05025 20.3847 2.87868Z"
|
|
32
|
-
fill="currentColor"
|
|
32
|
+
fill="currentColor"/>
|
|
33
33
|
<path fill-rule="evenodd" clip-rule="evenodd"
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
d="M11.9297 7.09116L4.1515 14.8693C3.22786 15.793 3.03239 17.169 3.5651 18.2842L1.99994 19.8493L3.41415 21.2635L4.97931 19.6984C6.09444 20.2311 7.4705 20.0356 8.39414 19.112L16.1723 11.3338L11.9297 7.09116ZM13.3439 11.3338L11.9297 9.91959L5.56571 16.2835C5.17518 16.6741 5.17518 17.3072 5.56571 17.6978C5.95623 18.0883 6.5894 18.0883 6.97992 17.6978L13.3439 11.3338Z"
|
|
35
|
+
fill="currentColor"/>
|
|
36
36
|
</svg>
|
|
37
37
|
</button>
|
|
38
38
|
</template>
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
</template>
|
|
46
46
|
<div style="width: 100%; display: flex; flex-direction: column; gap: 10px;">
|
|
47
47
|
<MSlider v-model="hueSlider"
|
|
48
|
-
|
|
48
|
+
background="linear-gradient(to right, #FF0000, #FFFF00, #00FF00, #00FFFF, #0000FF, #FF00FF, #FF0000)">
|
|
49
49
|
</MSlider>
|
|
50
50
|
|
|
51
51
|
<MSlider v-model="opacitySlider"
|
|
52
|
-
|
|
52
|
+
:background="`linear-gradient(to right, rgba(${finalColor.r}, ${finalColor.g}, ${finalColor.b}, 0), rgba(${finalColor.r}, ${finalColor.g}, ${finalColor.b}, 1))`">
|
|
53
53
|
</MSlider>
|
|
54
54
|
</div>
|
|
55
55
|
</div>
|
|
@@ -57,26 +57,26 @@
|
|
|
57
57
|
<div :class="style.colorActions">
|
|
58
58
|
<template v-if="rgbOrHex">
|
|
59
59
|
<MInput @keyup.enter="updateFromRGB" @blur="updateFromRGB" block ref="rInputElement"
|
|
60
|
-
|
|
60
|
+
v-model="rInput" name="r" placeholder="R"/>
|
|
61
61
|
<MInput @keyup.enter="updateFromRGB" @blur="updateFromRGB" block ref="gInputElement"
|
|
62
|
-
|
|
62
|
+
v-model="gInput" name="g" placeholder="G"/>
|
|
63
63
|
<MInput @keyup.enter="updateFromRGB" @blur="updateFromRGB" block ref="bInputElement"
|
|
64
|
-
|
|
64
|
+
v-model="bInput" name="b" placeholder="B"/>
|
|
65
65
|
<MInput @keyup.enter="updateFromRGB" @blur="updateFromRGB" block ref="aInputElement"
|
|
66
|
-
|
|
66
|
+
v-model="aInput" name="a" placeholder="A"/>
|
|
67
67
|
</template>
|
|
68
68
|
<template v-else>
|
|
69
69
|
<MInput @keyup.enter="updateFromHex" @blur="updateFromHex" block ref="hexInputElement"
|
|
70
|
-
|
|
70
|
+
v-model="hexInput" name="hex" placeholder="#00000000"/>
|
|
71
71
|
</template>
|
|
72
72
|
|
|
73
73
|
<MButton icon @click.prevent="rgbOrHex = !rgbOrHex">
|
|
74
74
|
|
|
75
75
|
<svg style="width: 18px; height: 18px;" xmlns="http://www.w3.org/2000/svg"
|
|
76
|
-
|
|
76
|
+
viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5">
|
|
77
77
|
<path fill-rule="evenodd"
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
d="M10 3a.75.75 0 01.55.24l3.25 3.5a.75.75 0 11-1.1 1.02L10 4.852 7.3 7.76a.75.75 0 01-1.1-1.02l3.25-3.5A.75.75 0 0110 3zm-3.76 9.2a.75.75 0 011.06.04l2.7 2.908 2.7-2.908a.75.75 0 111.1 1.02l-3.25 3.5a.75.75 0 01-1.1 0l-3.25-3.5a.75.75 0 01.04-1.06z"
|
|
79
|
+
clip-rule="evenodd"/>
|
|
80
80
|
</svg>
|
|
81
81
|
|
|
82
82
|
</MButton>
|
|
@@ -88,14 +88,14 @@
|
|
|
88
88
|
</template>
|
|
89
89
|
|
|
90
90
|
<script lang="ts">
|
|
91
|
-
import {
|
|
92
|
-
import {
|
|
91
|
+
import {onClickOutside, useEyeDropper, useMouseInElement, useMousePressed} from '@vueuse/core';
|
|
92
|
+
import {computed, defineComponent, onMounted, type PropType, reactive, ref, toRef, watch} from "vue";
|
|
93
93
|
import * as style from './style';
|
|
94
|
-
import {
|
|
95
|
-
import {
|
|
96
|
-
import {
|
|
97
|
-
import type {
|
|
98
|
-
import {
|
|
94
|
+
import {scale} from "../../styles/transitions.css";
|
|
95
|
+
import {hexToRGB, type HSV, HSVToRGBA, HueToRGBA, RGBAToHex, RGBToHSV} from './utils';
|
|
96
|
+
import {usePopper} from "../../composables/usePopper";
|
|
97
|
+
import type {Placement} from "@popperjs/core";
|
|
98
|
+
import {useZIndex} from "../../composables/useZIndex";
|
|
99
99
|
import MSlider from "../../components/slider/Slider.vue";
|
|
100
100
|
import MButton from "../../components/button/Button.vue";
|
|
101
101
|
import MInput from "../../components/input/Input.vue";
|
|
@@ -105,7 +105,7 @@ export default defineComponent({
|
|
|
105
105
|
props: {
|
|
106
106
|
modelValue: {
|
|
107
107
|
type: String,
|
|
108
|
-
default: "#
|
|
108
|
+
default: "#FFFFFF"
|
|
109
109
|
},
|
|
110
110
|
transfer: {
|
|
111
111
|
type: Boolean,
|
|
@@ -117,6 +117,10 @@ export default defineComponent({
|
|
|
117
117
|
},
|
|
118
118
|
zIndex: {
|
|
119
119
|
type: Number
|
|
120
|
+
},
|
|
121
|
+
defaultColor: {
|
|
122
|
+
type: String,
|
|
123
|
+
default: "#FFFFFF"
|
|
120
124
|
}
|
|
121
125
|
},
|
|
122
126
|
emits: ['update:modelValue'],
|
|
@@ -125,9 +129,9 @@ export default defineComponent({
|
|
|
125
129
|
MInput,
|
|
126
130
|
MButton
|
|
127
131
|
},
|
|
128
|
-
setup(props, {
|
|
129
|
-
const {
|
|
130
|
-
const {
|
|
132
|
+
setup(props, {emit}) {
|
|
133
|
+
const {isSupported: canPickColor, open: openEyeDrop, sRGBHex: eyeDropColor} = useEyeDropper();
|
|
134
|
+
const {nextZIndex} = useZIndex();
|
|
131
135
|
const isOpen = ref(false);
|
|
132
136
|
const rgbOrHex = ref<boolean>(false);
|
|
133
137
|
const hexInput = ref("");
|
|
@@ -151,9 +155,9 @@ export default defineComponent({
|
|
|
151
155
|
});
|
|
152
156
|
const zIndex = ref(props.zIndex ?? nextZIndex());
|
|
153
157
|
|
|
154
|
-
const {
|
|
155
|
-
const {
|
|
156
|
-
const {
|
|
158
|
+
const {elementX, elementY} = useMouseInElement(picker);
|
|
159
|
+
const {pressed} = useMousePressed();
|
|
160
|
+
const {popper, transferTo, updatePopper} = usePopper({
|
|
157
161
|
reference: referenceRef,
|
|
158
162
|
placement,
|
|
159
163
|
transfer,
|
|
@@ -200,27 +204,27 @@ export default defineComponent({
|
|
|
200
204
|
}
|
|
201
205
|
|
|
202
206
|
const updateFromHex = () => {
|
|
203
|
-
|
|
207
|
+
let color = hexToRGB(hexInput.value, finalColor.value.r, finalColor.value.g, finalColor.value.b, finalColor.value.a);
|
|
204
208
|
updateFromHSV(RGBToHSV(color.r, color.g, color.b), color.a);
|
|
205
209
|
}
|
|
206
210
|
|
|
207
211
|
const updateFromRGB = () => {
|
|
208
|
-
|
|
212
|
+
let red = parseInt(rInput.value);
|
|
209
213
|
if (isNaN(red) || red > 255 || red < 0) {
|
|
210
214
|
red = finalColor.value.r;
|
|
211
215
|
}
|
|
212
216
|
|
|
213
|
-
|
|
217
|
+
let green = parseInt(gInput.value);
|
|
214
218
|
if (isNaN(green) || green > 255 || green < 0) {
|
|
215
219
|
green = finalColor.value.g;
|
|
216
220
|
}
|
|
217
221
|
|
|
218
|
-
|
|
222
|
+
let blue = parseInt(bInput.value);
|
|
219
223
|
if (isNaN(blue) || blue > 255 || blue < 0) {
|
|
220
224
|
blue = finalColor.value.b;
|
|
221
225
|
}
|
|
222
226
|
|
|
223
|
-
|
|
227
|
+
let alpha = parseFloat(aInput.value);
|
|
224
228
|
if (isNaN(alpha) || alpha > 1 || alpha < 0) {
|
|
225
229
|
alpha = finalColor.value.a;
|
|
226
230
|
}
|
|
@@ -242,8 +246,16 @@ export default defineComponent({
|
|
|
242
246
|
setThumbPosition();
|
|
243
247
|
});
|
|
244
248
|
|
|
245
|
-
|
|
246
|
-
hexInput.value
|
|
249
|
+
const setDefaultColor = () => {
|
|
250
|
+
hexInput.value
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
watch(() => props.modelValue, (newValue) => {
|
|
254
|
+
let val = props.modelValue;
|
|
255
|
+
if (!newValue || newValue.trim() === "") {
|
|
256
|
+
val = props.defaultColor || "#FFFFFF"
|
|
257
|
+
}
|
|
258
|
+
hexInput.value = val;
|
|
247
259
|
updateFromHex();
|
|
248
260
|
|
|
249
261
|
});
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<MColorPicker>
|
|
3
|
-
<template #default="{r,g,b,hex}">
|
|
4
|
-
<div
|
|
2
|
+
<MColorPicker style="display: inline-block;">
|
|
3
|
+
<template #default="{r,g,b,hex, transparent}">
|
|
4
|
+
<div :class="transparent"
|
|
5
|
+
style="width: 100px; height: 100px; border: 1px solid black; position: relative; overflow: hidden;">
|
|
6
|
+
<div style="position: absolute; inset: 0" :style="{backgroundColor: `${hex}`}">
|
|
7
|
+
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
5
10
|
</template>
|
|
6
11
|
</MColorPicker>
|
|
7
12
|
</template>
|
|
@@ -92,6 +92,16 @@ export const reference = style({
|
|
|
92
92
|
userSelect: 'none'
|
|
93
93
|
});
|
|
94
94
|
|
|
95
|
+
export const transparent = style({
|
|
96
|
+
backgroundImage:
|
|
97
|
+
'linear-gradient(45deg, #bebebe 25%, transparent 25%), linear-gradient(-45deg, #bebebe 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #bebebe 75%), linear-gradient(-45deg, transparent 75%, #bebebe 75%)',
|
|
98
|
+
backgroundSize: '12px 12px',
|
|
99
|
+
backgroundPosition: '0 0, 0 6px, 6px -6px, -6px 0px',
|
|
100
|
+
overflow: 'hidden',
|
|
101
|
+
cursor: 'pointer',
|
|
102
|
+
userSelect: 'none',
|
|
103
|
+
})
|
|
104
|
+
|
|
95
105
|
export const referenceColor = style({
|
|
96
106
|
position: 'absolute',
|
|
97
107
|
top: 0,
|
|
@@ -1,118 +1,180 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<Teleport to="body">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
</
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
style,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<Teleport to="body">
|
|
3
|
+
<TransitionGroup
|
|
4
|
+
type="animation"
|
|
5
|
+
:enter-active-class="fade.enterActive"
|
|
6
|
+
:leave-active-class="fade.leaveActive"
|
|
7
|
+
:enter-from-class="fade.enterFrom"
|
|
8
|
+
:leave-to-class="fade.leaveTo">
|
|
9
|
+
<div :class="style.root" v-if="open">
|
|
10
|
+
<div :class="backdropClasses" v-if="modal"></div>
|
|
11
|
+
<div ref="wrapper" :class="wrapperClasses">
|
|
12
|
+
<Transition
|
|
13
|
+
type="animation"
|
|
14
|
+
:enter-active-class="modalScale.enterActive"
|
|
15
|
+
:leave-active-class="modalScale.leaveActive"
|
|
16
|
+
:enter-from-class="modalScale.enterFrom"
|
|
17
|
+
:leave-to-class="modalScale.leaveTo"
|
|
18
|
+
@enter="onEnter"
|
|
19
|
+
>
|
|
20
|
+
<div ref="dialog" :style="computedStyle">
|
|
21
|
+
<div tabindex="0" aria-hidden="true"
|
|
22
|
+
style="width: 0px; height: 0px; overflow: hidden; outline: none;"></div>
|
|
23
|
+
<slot v-if="$slots.container" name="container" :close="close"></slot>
|
|
24
|
+
<template v-else>
|
|
25
|
+
<div :class="style.content">
|
|
26
|
+
<button role="button" :class="style.close" @click="close"></button>
|
|
27
|
+
<div :class="style.header" ref="handle">
|
|
28
|
+
<div :class="style.title">
|
|
29
|
+
<slot name="title">
|
|
30
|
+
{{ title }}
|
|
31
|
+
</slot>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
<div>
|
|
35
|
+
<slot></slot>
|
|
36
|
+
</div>
|
|
37
|
+
<div v-if="$slots.footer" :class="style.footer">
|
|
38
|
+
<slot name="footer"></slot>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</template>
|
|
42
|
+
<div tabindex="0" aria-hidden="true"
|
|
43
|
+
style="width: 0px; height: 0px; overflow: hidden; outline: none;"></div>
|
|
44
|
+
</div>
|
|
45
|
+
</Transition>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</TransitionGroup>
|
|
49
|
+
</Teleport>
|
|
50
|
+
</template>
|
|
51
|
+
|
|
52
|
+
<script lang="ts">
|
|
53
|
+
import { fade, modalScale } from '../../styles/transitions.css';
|
|
54
|
+
import {computed, defineComponent, ref, watch, nextTick, type CSSProperties} from "vue";
|
|
55
|
+
import type { ComputedRef } from "vue";
|
|
56
|
+
|
|
57
|
+
import { useZIndex } from "../../composables/useZIndex";
|
|
58
|
+
import { useDraggable } from "@vueuse/core";
|
|
59
|
+
import * as style from "./style";
|
|
60
|
+
|
|
61
|
+
export default defineComponent({
|
|
62
|
+
name: "Dialog",
|
|
63
|
+
props: {
|
|
64
|
+
title: {
|
|
65
|
+
type: String,
|
|
66
|
+
default: ""
|
|
67
|
+
},
|
|
68
|
+
draggable: {
|
|
69
|
+
type: Boolean,
|
|
70
|
+
default: true
|
|
71
|
+
},
|
|
72
|
+
modal: {
|
|
73
|
+
type: Boolean,
|
|
74
|
+
default: false,
|
|
75
|
+
},
|
|
76
|
+
onClose: {
|
|
77
|
+
type: Function,
|
|
78
|
+
default: () => {}
|
|
79
|
+
},
|
|
80
|
+
zIndex: {
|
|
81
|
+
type: Number
|
|
82
|
+
},
|
|
83
|
+
width: {
|
|
84
|
+
type: [Number, String],
|
|
85
|
+
default: "500px"
|
|
86
|
+
},
|
|
87
|
+
focusTrap: {
|
|
88
|
+
type: Boolean,
|
|
89
|
+
default: true
|
|
90
|
+
},
|
|
91
|
+
open: {
|
|
92
|
+
type: Boolean
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
emits: ['onOpen', 'onClose', 'update:open'],
|
|
96
|
+
setup(props, { slots, emit }) {
|
|
97
|
+
const wrapper = ref<HTMLElement | null>(null);
|
|
98
|
+
const dialog = ref<HTMLElement | null>(null);
|
|
99
|
+
const handle = ref<HTMLElement | null>(null);
|
|
100
|
+
const { nextZIndex } = useZIndex();
|
|
101
|
+
const zIndex = ref(props.zIndex ?? nextZIndex());
|
|
102
|
+
|
|
103
|
+
const { x, y } = useDraggable(dialog, {
|
|
104
|
+
handle,
|
|
105
|
+
preventDefault: true,
|
|
106
|
+
containerElement: wrapper,
|
|
107
|
+
disabled: computed(() => !props.draggable),
|
|
108
|
+
onStart: onDragStart,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const backdropClasses = computed(() => ({
|
|
112
|
+
[style.backdrop]: true,
|
|
113
|
+
[style.backdropColor]: props.modal === true,
|
|
114
|
+
}));
|
|
115
|
+
|
|
116
|
+
const wrapperClasses = computed(() => ({
|
|
117
|
+
[style.wrapper]: true,
|
|
118
|
+
[style.notModal]: !props.modal,
|
|
119
|
+
}));
|
|
120
|
+
|
|
121
|
+
const width = computed(() => (
|
|
122
|
+
typeof props.width === "number" ? `${props.width}px` : props.width
|
|
123
|
+
));
|
|
124
|
+
|
|
125
|
+
const computedStyle: ComputedRef<CSSProperties> = computed(() => ({
|
|
126
|
+
position: 'fixed',
|
|
127
|
+
left: `${x.value}px`,
|
|
128
|
+
top: `${y.value}px`,
|
|
129
|
+
width: width.value,
|
|
130
|
+
zIndex: zIndex.value
|
|
131
|
+
}));
|
|
132
|
+
|
|
133
|
+
function close() {
|
|
134
|
+
emit('update:open', false);
|
|
135
|
+
emit('onClose');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function onEnter() {
|
|
139
|
+
emit('onOpen');
|
|
140
|
+
zIndex.value = nextZIndex();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function onDragStart() {
|
|
144
|
+
zIndex.value = nextZIndex();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function centerDialog() {
|
|
148
|
+
if (dialog.value) {
|
|
149
|
+
const boundingRect = dialog.value.getBoundingClientRect();
|
|
150
|
+
x.value = (window.innerWidth - boundingRect.width) / 2;
|
|
151
|
+
y.value = (window.innerHeight - boundingRect.height) / 2;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
watch(() => props.open, async (newVal) => {
|
|
156
|
+
if (newVal) {
|
|
157
|
+
await nextTick();
|
|
158
|
+
centerDialog();
|
|
159
|
+
}
|
|
160
|
+
}, { immediate: true });
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
slots,
|
|
164
|
+
wrapper,
|
|
165
|
+
dialog,
|
|
166
|
+
handle,
|
|
167
|
+
zIndex,
|
|
168
|
+
fade,
|
|
169
|
+
modalScale,
|
|
170
|
+
style,
|
|
171
|
+
computedStyle,
|
|
172
|
+
backdropClasses,
|
|
173
|
+
wrapperClasses,
|
|
174
|
+
close,
|
|
175
|
+
onEnter,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
</script>
|
|
180
|
+
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<MDialog>
|
|
3
|
+
<MDialog :draggable="true" v-model:open="open" width="1000px" title="Hello World" @onClose="closed">
|
|
4
4
|
<input type="text" />
|
|
5
5
|
<input type="text" />
|
|
6
6
|
<template #footer>
|
|
7
7
|
Bootom
|
|
8
8
|
</template>
|
|
9
9
|
</MDialog>
|
|
10
|
+
|
|
11
|
+
<button @click="open = true">Open</button>
|
|
10
12
|
</div>
|
|
11
13
|
</template>
|
|
12
14
|
|
|
13
15
|
<script lang="ts" setup>
|
|
14
16
|
import { ref } from 'vue'
|
|
15
17
|
|
|
18
|
+
const open = ref(false);
|
|
19
|
+
|
|
20
|
+
function closed() {
|
|
21
|
+
console.log('closed');
|
|
22
|
+
}
|
|
16
23
|
</script>
|