@teammodlr/ui-kit 2.1.67 → 2.1.69
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 +10 -0
- package/lib/components/dialog/Dialog.vue.d.ts +15 -14
- package/lib/components/dialogprovider/DialogProvider.vue.d.ts +7 -0
- package/lib/components/dialogprovider/types.d.ts +23 -0
- package/lib/components/dialogprovider/useDialog.d.ts +2 -0
- package/lib/components/index.d.ts +1 -0
- package/lib/components/messageprovider/MessageProvider.vue.d.ts +0 -1
- package/lib/components/slider/Slider.vue.d.ts +4 -6
- package/lib/composables/index.d.ts +1 -0
- package/lib/index.cjs.js +9 -9
- package/lib/index.es.js +3060 -2938
- package/package.json +1 -1
- package/src/components/colorpicker/ColorPicker.vue +72 -45
- package/src/components/colorpicker/examples/basic.vue +20 -9
- package/src/components/dialog/Dialog.vue +90 -60
- package/src/components/dialogprovider/DialogProvider.vue +97 -0
- package/src/components/dialogprovider/examples/basic.vue +51 -0
- package/src/components/dialogprovider/examples/index.stories.ts +26 -0
- package/src/components/dialogprovider/examples/index.ts +1 -0
- package/src/components/dialogprovider/types.ts +25 -0
- package/src/components/dialogprovider/useDialog.ts +14 -0
- package/src/components/index.ts +1 -0
- package/src/components/messageprovider/MessageProvider.vue +0 -4
- package/src/components/slider/Slider.vue +111 -76
- package/src/composables/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,38 +1,39 @@
|
|
|
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"
|
|
4
|
+
<slot :r="finalColor.r" :g="finalColor.g" :b="finalColor.b" :a="finalColor.a" :hex="hexInput"
|
|
5
|
+
:transparent="style.transparent">
|
|
5
6
|
<div>
|
|
6
7
|
<div :class="style.referenceColor"
|
|
7
|
-
|
|
8
|
+
:style="{ backgroundColor: `rgba(${finalColor.r}, ${finalColor.g}, ${finalColor.b}, ${finalColor.a})` }">
|
|
8
9
|
</div>
|
|
9
10
|
</div>
|
|
10
11
|
</slot>
|
|
11
12
|
</div>
|
|
12
13
|
<Teleport to="body">
|
|
13
14
|
<transition :enter-active-class="scale.enterActive" :leave-active-class="scale.leaveActive"
|
|
14
|
-
|
|
15
|
+
:enter-from-class="scale.enterFrom" :leave-to-class="scale.leaveTo">
|
|
15
16
|
<div :class="style.container" v-if="isOpen" ref="popper" :style="{ zIndex: zIndex }">
|
|
16
17
|
<div ref="picker" @mousedown="handleMouseDown" :class="style.colours"
|
|
17
|
-
|
|
18
|
+
:style="`background: rgb(${mainColor.r}, ${mainColor.g}, ${mainColor.b});`">
|
|
18
19
|
<div :class="style.whiteGradient"></div>
|
|
19
20
|
<div :class="style.blackGradient"></div>
|
|
20
21
|
<div :class="style.sliderThumb" @mousedown="handleMouseDown" @dragover.prevent=""
|
|
21
|
-
|
|
22
|
+
:style="{ left: `${position.x * 100}%`, top: `${position.y * 100}%` }"></div>
|
|
22
23
|
</div>
|
|
23
24
|
|
|
24
25
|
<div :class="style.colorActions">
|
|
25
26
|
<template v-if="canPickColor">
|
|
26
27
|
<button role="button" :disabled="!canPickColor" :class="style.eyeDrop"
|
|
27
|
-
|
|
28
|
+
@click="openEyeDropper">
|
|
28
29
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
|
|
29
|
-
|
|
30
|
+
xmlns="http://www.w3.org/2000/svg">
|
|
30
31
|
<path
|
|
31
32
|
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"/>
|
|
33
|
+
fill="currentColor" />
|
|
33
34
|
<path fill-rule="evenodd" clip-rule="evenodd"
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
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"
|
|
36
|
+
fill="currentColor" />
|
|
36
37
|
</svg>
|
|
37
38
|
</button>
|
|
38
39
|
</template>
|
|
@@ -44,12 +45,12 @@
|
|
|
44
45
|
</div>
|
|
45
46
|
</template>
|
|
46
47
|
<div style="width: 100%; display: flex; flex-direction: column; gap: 10px;">
|
|
47
|
-
<MSlider v-model="hueSlider"
|
|
48
|
-
|
|
48
|
+
<MSlider v-model="hueSlider" @change="onSliderChangeComplete"
|
|
49
|
+
background="linear-gradient(to right, #FF0000, #FFFF00, #00FF00, #00FFFF, #0000FF, #FF00FF, #FF0000)">
|
|
49
50
|
</MSlider>
|
|
50
51
|
|
|
51
|
-
<MSlider v-model="opacitySlider"
|
|
52
|
-
|
|
52
|
+
<MSlider v-model="opacitySlider" @change="onSliderChangeComplete"
|
|
53
|
+
:background="`linear-gradient(to right, rgba(${finalColor.r}, ${finalColor.g}, ${finalColor.b}, 0), rgba(${finalColor.r}, ${finalColor.g}, ${finalColor.b}, 1))`">
|
|
53
54
|
</MSlider>
|
|
54
55
|
</div>
|
|
55
56
|
</div>
|
|
@@ -57,26 +58,26 @@
|
|
|
57
58
|
<div :class="style.colorActions">
|
|
58
59
|
<template v-if="rgbOrHex">
|
|
59
60
|
<MInput @keyup.enter="updateFromRGB" @blur="updateFromRGB" block ref="rInputElement"
|
|
60
|
-
|
|
61
|
+
v-model="rInput" name="r" placeholder="R" />
|
|
61
62
|
<MInput @keyup.enter="updateFromRGB" @blur="updateFromRGB" block ref="gInputElement"
|
|
62
|
-
|
|
63
|
+
v-model="gInput" name="g" placeholder="G" />
|
|
63
64
|
<MInput @keyup.enter="updateFromRGB" @blur="updateFromRGB" block ref="bInputElement"
|
|
64
|
-
|
|
65
|
+
v-model="bInput" name="b" placeholder="B" />
|
|
65
66
|
<MInput @keyup.enter="updateFromRGB" @blur="updateFromRGB" block ref="aInputElement"
|
|
66
|
-
|
|
67
|
+
v-model="aInput" name="a" placeholder="A" />
|
|
67
68
|
</template>
|
|
68
69
|
<template v-else>
|
|
69
70
|
<MInput @keyup.enter="updateFromHex" @blur="updateFromHex" block ref="hexInputElement"
|
|
70
|
-
|
|
71
|
+
v-model="hexInput" name="hex" placeholder="#00000000" />
|
|
71
72
|
</template>
|
|
72
73
|
|
|
73
74
|
<MButton icon @click.prevent="rgbOrHex = !rgbOrHex">
|
|
74
75
|
|
|
75
76
|
<svg style="width: 18px; height: 18px;" xmlns="http://www.w3.org/2000/svg"
|
|
76
|
-
|
|
77
|
+
viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5">
|
|
77
78
|
<path fill-rule="evenodd"
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
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"
|
|
80
|
+
clip-rule="evenodd" />
|
|
80
81
|
</svg>
|
|
81
82
|
|
|
82
83
|
</MButton>
|
|
@@ -88,14 +89,14 @@
|
|
|
88
89
|
</template>
|
|
89
90
|
|
|
90
91
|
<script lang="ts">
|
|
91
|
-
import {onClickOutside, useEyeDropper, useMouseInElement, useMousePressed} from '@vueuse/core';
|
|
92
|
-
import {computed, defineComponent, onMounted, type PropType, reactive, ref, toRef, watch} from "vue";
|
|
92
|
+
import { onClickOutside, useEyeDropper, useMouseInElement, useMousePressed } from '@vueuse/core';
|
|
93
|
+
import { computed, defineComponent, onMounted, type PropType, reactive, ref, toRef, watch } from "vue";
|
|
93
94
|
import * as style from './style';
|
|
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";
|
|
95
|
+
import { scale } from "../../styles/transitions.css";
|
|
96
|
+
import { hexToRGB, type HSV, HSVToRGBA, HueToRGBA, RGBAToHex, RGBToHSV } from './utils';
|
|
97
|
+
import { usePopper } from "../../composables/usePopper";
|
|
98
|
+
import type { Placement } from "@popperjs/core";
|
|
99
|
+
import { useZIndex } from "../../composables/useZIndex";
|
|
99
100
|
import MSlider from "../../components/slider/Slider.vue";
|
|
100
101
|
import MButton from "../../components/button/Button.vue";
|
|
101
102
|
import MInput from "../../components/input/Input.vue";
|
|
@@ -107,6 +108,10 @@ export default defineComponent({
|
|
|
107
108
|
type: String,
|
|
108
109
|
default: "#FFFFFF"
|
|
109
110
|
},
|
|
111
|
+
modelModifiers: {
|
|
112
|
+
type: Object,
|
|
113
|
+
default: () => ({})
|
|
114
|
+
},
|
|
110
115
|
transfer: {
|
|
111
116
|
type: Boolean,
|
|
112
117
|
default: false
|
|
@@ -129,9 +134,10 @@ export default defineComponent({
|
|
|
129
134
|
MInput,
|
|
130
135
|
MButton
|
|
131
136
|
},
|
|
132
|
-
setup(props, {emit}) {
|
|
133
|
-
const
|
|
134
|
-
const {
|
|
137
|
+
setup(props, { emit }) {
|
|
138
|
+
const modelModifiers = props.modelModifiers;
|
|
139
|
+
const { isSupported: canPickColor, open: openEyeDrop, sRGBHex: eyeDropColor } = useEyeDropper();
|
|
140
|
+
const { nextZIndex } = useZIndex();
|
|
135
141
|
const isOpen = ref(false);
|
|
136
142
|
const rgbOrHex = ref<boolean>(false);
|
|
137
143
|
const hexInput = ref("");
|
|
@@ -139,6 +145,7 @@ export default defineComponent({
|
|
|
139
145
|
const gInput = ref("");
|
|
140
146
|
const bInput = ref("");
|
|
141
147
|
const aInput = ref("");
|
|
148
|
+
const internalValue = ref(props.modelValue);
|
|
142
149
|
|
|
143
150
|
const picker = ref<HTMLElement>();
|
|
144
151
|
const wrapper = ref<HTMLElement>();
|
|
@@ -155,9 +162,9 @@ export default defineComponent({
|
|
|
155
162
|
});
|
|
156
163
|
const zIndex = ref(props.zIndex ?? nextZIndex());
|
|
157
164
|
|
|
158
|
-
const {elementX, elementY} = useMouseInElement(picker);
|
|
159
|
-
const {pressed} = useMousePressed();
|
|
160
|
-
const {popper, transferTo, updatePopper} = usePopper({
|
|
165
|
+
const { elementX, elementY } = useMouseInElement(picker);
|
|
166
|
+
const { pressed } = useMousePressed();
|
|
167
|
+
const { popper, transferTo, updatePopper } = usePopper({
|
|
161
168
|
reference: referenceRef,
|
|
162
169
|
placement,
|
|
163
170
|
transfer,
|
|
@@ -181,6 +188,10 @@ export default defineComponent({
|
|
|
181
188
|
return HueToRGBA(hueSlider.value * 3.6, opacitySlider.value / 100);
|
|
182
189
|
});
|
|
183
190
|
|
|
191
|
+
const emitModelValue = () => {
|
|
192
|
+
emit('update:modelValue', hexInput.value);
|
|
193
|
+
};
|
|
194
|
+
|
|
184
195
|
const setInputs = () => {
|
|
185
196
|
hexInput.value = RGBAToHex(finalColor.value.r, finalColor.value.g, finalColor.value.b, finalColor.value.a);
|
|
186
197
|
rInput.value = finalColor.value.r.toString();
|
|
@@ -188,7 +199,9 @@ export default defineComponent({
|
|
|
188
199
|
bInput.value = finalColor.value.b.toString();
|
|
189
200
|
aInput.value = finalColor.value.a.toFixed(2).toString();
|
|
190
201
|
|
|
191
|
-
|
|
202
|
+
if (!modelModifiers.lazy) {
|
|
203
|
+
emitModelValue();
|
|
204
|
+
}
|
|
192
205
|
};
|
|
193
206
|
|
|
194
207
|
watch(() => finalColor.value, () => {
|
|
@@ -206,6 +219,9 @@ export default defineComponent({
|
|
|
206
219
|
const updateFromHex = () => {
|
|
207
220
|
let color = hexToRGB(hexInput.value, finalColor.value.r, finalColor.value.g, finalColor.value.b, finalColor.value.a);
|
|
208
221
|
updateFromHSV(RGBToHSV(color.r, color.g, color.b), color.a);
|
|
222
|
+
if (modelModifiers.lazy) {
|
|
223
|
+
emitModelValue();
|
|
224
|
+
}
|
|
209
225
|
}
|
|
210
226
|
|
|
211
227
|
const updateFromRGB = () => {
|
|
@@ -230,6 +246,9 @@ export default defineComponent({
|
|
|
230
246
|
}
|
|
231
247
|
|
|
232
248
|
updateFromHSV(RGBToHSV(red, green, blue), alpha);
|
|
249
|
+
if (modelModifiers.lazy) {
|
|
250
|
+
emitModelValue();
|
|
251
|
+
}
|
|
233
252
|
};
|
|
234
253
|
|
|
235
254
|
watch(() => pressed.value, () => {
|
|
@@ -238,6 +257,12 @@ export default defineComponent({
|
|
|
238
257
|
}
|
|
239
258
|
});
|
|
240
259
|
|
|
260
|
+
watch(() => dragging.value, (newVal, oldVal) => {
|
|
261
|
+
if (oldVal && !newVal && modelModifiers.lazy) {
|
|
262
|
+
emitModelValue();
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
|
|
241
266
|
watch(() => [elementX.value, elementY.value], () => {
|
|
242
267
|
if (!dragging.value) {
|
|
243
268
|
return;
|
|
@@ -246,18 +271,13 @@ export default defineComponent({
|
|
|
246
271
|
setThumbPosition();
|
|
247
272
|
});
|
|
248
273
|
|
|
249
|
-
|
|
250
|
-
hexInput.value
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
watch(() => props.modelValue, (newValue) => {
|
|
274
|
+
watch(() => props.modelValue, () => {
|
|
254
275
|
let val = props.modelValue;
|
|
255
|
-
if (!
|
|
256
|
-
val = props.defaultColor
|
|
276
|
+
if (!val || val.trim() === "") {
|
|
277
|
+
val = props.defaultColor ?? "#FFFFFF"
|
|
257
278
|
}
|
|
258
279
|
hexInput.value = val;
|
|
259
280
|
updateFromHex();
|
|
260
|
-
|
|
261
281
|
});
|
|
262
282
|
|
|
263
283
|
const setThumbPosition = () => {
|
|
@@ -292,6 +312,12 @@ export default defineComponent({
|
|
|
292
312
|
}
|
|
293
313
|
}
|
|
294
314
|
|
|
315
|
+
const onSliderChangeComplete = () => {
|
|
316
|
+
if (modelModifiers.lazy) {
|
|
317
|
+
emitModelValue();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
295
321
|
return {
|
|
296
322
|
isOpen,
|
|
297
323
|
popper,
|
|
@@ -323,7 +349,8 @@ export default defineComponent({
|
|
|
323
349
|
zIndex,
|
|
324
350
|
canPickColor,
|
|
325
351
|
openEyeDropper,
|
|
326
|
-
scale
|
|
352
|
+
scale,
|
|
353
|
+
onSliderChangeComplete
|
|
327
354
|
};
|
|
328
355
|
}
|
|
329
356
|
})
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
<div
|
|
7
|
-
|
|
2
|
+
<div>
|
|
3
|
+
<p>Selected Color: {{ colorValue }}</p>
|
|
4
|
+
<MColorPicker v-model.lazy="colorValue" style="display: inline-block;">
|
|
5
|
+
<template #default="{ r, g, b, hex, transparent }">
|
|
6
|
+
<div :class="transparent"
|
|
7
|
+
style="width: 100px; height: 100px; border: 1px solid black; position: relative; overflow: hidden;">
|
|
8
|
+
<div style="position: absolute; inset: 0" :style="{ backgroundColor: hex }"></div>
|
|
8
9
|
</div>
|
|
9
|
-
</
|
|
10
|
-
</
|
|
11
|
-
</
|
|
10
|
+
</template>
|
|
11
|
+
</MColorPicker>
|
|
12
|
+
</div>
|
|
12
13
|
</template>
|
|
14
|
+
|
|
15
|
+
<script>
|
|
16
|
+
export default {
|
|
17
|
+
data() {
|
|
18
|
+
return {
|
|
19
|
+
colorValue: '#FFFFFF' // Initial color value
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
</script>
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
:enter-active-class="fade.enterActive"
|
|
6
6
|
:leave-active-class="fade.leaveActive"
|
|
7
7
|
:enter-from-class="fade.enterFrom"
|
|
8
|
-
:leave-to-class="fade.leaveTo"
|
|
9
|
-
|
|
8
|
+
:leave-to-class="fade.leaveTo"
|
|
9
|
+
>
|
|
10
|
+
<div :class="style.root" v-if="open" :style="{ zIndex: zIndex, position: 'fixed', inset: '0', pointerEvents: modal ? 'all' : 'none' }">
|
|
10
11
|
<div :class="backdropClasses" v-if="modal"></div>
|
|
11
12
|
<div ref="wrapper" :class="wrapperClasses">
|
|
12
13
|
<Transition
|
|
@@ -27,7 +28,7 @@
|
|
|
27
28
|
<div :class="style.header" ref="handle">
|
|
28
29
|
<div :class="style.title">
|
|
29
30
|
<slot name="title">
|
|
30
|
-
{{
|
|
31
|
+
{{ resolvedTitle }}
|
|
31
32
|
</slot>
|
|
32
33
|
</div>
|
|
33
34
|
</div>
|
|
@@ -48,26 +49,33 @@
|
|
|
48
49
|
</TransitionGroup>
|
|
49
50
|
</Teleport>
|
|
50
51
|
</template>
|
|
51
|
-
|
|
52
52
|
<script lang="ts">
|
|
53
|
-
import {
|
|
54
|
-
import {
|
|
55
|
-
|
|
53
|
+
import {fade, modalScale} from '../../styles/transitions.css';
|
|
54
|
+
import {
|
|
55
|
+
computed,
|
|
56
|
+
defineComponent,
|
|
57
|
+
ref,
|
|
58
|
+
watch,
|
|
59
|
+
nextTick,
|
|
60
|
+
isRef,
|
|
61
|
+
type CSSProperties, type PropType, type Ref,
|
|
62
|
+
} from 'vue';
|
|
63
|
+
import type {ComputedRef} from 'vue';
|
|
56
64
|
|
|
57
|
-
import {
|
|
58
|
-
import {
|
|
59
|
-
import * as style from
|
|
65
|
+
import {useZIndex} from '../../composables/useZIndex';
|
|
66
|
+
import {useDraggable} from '@vueuse/core';
|
|
67
|
+
import * as style from './style';
|
|
60
68
|
|
|
61
69
|
export default defineComponent({
|
|
62
|
-
name:
|
|
70
|
+
name: 'Dialog',
|
|
63
71
|
props: {
|
|
64
72
|
title: {
|
|
65
|
-
type: String,
|
|
66
|
-
default:
|
|
73
|
+
type: [String, Object] as PropType<string | Ref<string>>,
|
|
74
|
+
default: '',
|
|
67
75
|
},
|
|
68
76
|
draggable: {
|
|
69
77
|
type: Boolean,
|
|
70
|
-
default: true
|
|
78
|
+
default: true,
|
|
71
79
|
},
|
|
72
80
|
modal: {
|
|
73
81
|
type: Boolean,
|
|
@@ -75,32 +83,36 @@ export default defineComponent({
|
|
|
75
83
|
},
|
|
76
84
|
onClose: {
|
|
77
85
|
type: Function,
|
|
78
|
-
default: () => {
|
|
86
|
+
default: () => {
|
|
87
|
+
},
|
|
79
88
|
},
|
|
80
89
|
zIndex: {
|
|
81
|
-
type: Number
|
|
90
|
+
type: Number,
|
|
82
91
|
},
|
|
83
92
|
width: {
|
|
84
93
|
type: [Number, String],
|
|
85
|
-
default:
|
|
94
|
+
default: '500px',
|
|
86
95
|
},
|
|
87
96
|
focusTrap: {
|
|
88
97
|
type: Boolean,
|
|
89
|
-
default: true
|
|
98
|
+
default: true,
|
|
90
99
|
},
|
|
91
100
|
open: {
|
|
92
|
-
type: Boolean
|
|
93
|
-
|
|
101
|
+
type: Boolean,
|
|
102
|
+
default: false,
|
|
103
|
+
},
|
|
94
104
|
},
|
|
95
105
|
emits: ['onOpen', 'onClose', 'update:open'],
|
|
96
|
-
setup(props, {
|
|
106
|
+
setup(props, {emit, expose}) {
|
|
97
107
|
const wrapper = ref<HTMLElement | null>(null);
|
|
98
108
|
const dialog = ref<HTMLElement | null>(null);
|
|
99
109
|
const handle = ref<HTMLElement | null>(null);
|
|
100
|
-
const {
|
|
110
|
+
const {nextZIndex} = useZIndex();
|
|
101
111
|
const zIndex = ref(props.zIndex ?? nextZIndex());
|
|
102
112
|
|
|
103
|
-
const
|
|
113
|
+
const isOpen = ref<boolean>(props.open);
|
|
114
|
+
|
|
115
|
+
const {x, y} = useDraggable(dialog, {
|
|
104
116
|
handle,
|
|
105
117
|
preventDefault: true,
|
|
106
118
|
containerElement: wrapper,
|
|
@@ -108,6 +120,10 @@ export default defineComponent({
|
|
|
108
120
|
onStart: onDragStart,
|
|
109
121
|
});
|
|
110
122
|
|
|
123
|
+
const resolvedTitle = computed(() =>
|
|
124
|
+
isRef(props.title) ? props.title.value : props.title
|
|
125
|
+
);
|
|
126
|
+
|
|
111
127
|
const backdropClasses = computed(() => ({
|
|
112
128
|
[style.backdrop]: true,
|
|
113
129
|
[style.backdropColor]: props.modal === true,
|
|
@@ -118,21 +134,25 @@ export default defineComponent({
|
|
|
118
134
|
[style.notModal]: !props.modal,
|
|
119
135
|
}));
|
|
120
136
|
|
|
121
|
-
const width = computed(() =>
|
|
122
|
-
typeof props.width ===
|
|
123
|
-
)
|
|
137
|
+
const width = computed(() =>
|
|
138
|
+
typeof props.width === 'number' ? `${props.width}px` : props.width,
|
|
139
|
+
);
|
|
124
140
|
|
|
125
141
|
const computedStyle: ComputedRef<CSSProperties> = computed(() => ({
|
|
126
142
|
position: 'fixed',
|
|
127
143
|
left: `${x.value}px`,
|
|
128
144
|
top: `${y.value}px`,
|
|
129
145
|
width: width.value,
|
|
130
|
-
zIndex: zIndex.value
|
|
146
|
+
zIndex: zIndex.value,
|
|
131
147
|
}));
|
|
132
148
|
|
|
133
149
|
function close() {
|
|
150
|
+
isOpen.value = false;
|
|
134
151
|
emit('update:open', false);
|
|
135
152
|
emit('onClose');
|
|
153
|
+
if (props.onClose) {
|
|
154
|
+
props.onClose();
|
|
155
|
+
}
|
|
136
156
|
}
|
|
137
157
|
|
|
138
158
|
function onEnter() {
|
|
@@ -140,41 +160,51 @@ export default defineComponent({
|
|
|
140
160
|
zIndex.value = nextZIndex();
|
|
141
161
|
}
|
|
142
162
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
163
|
+
function onDragStart() {
|
|
164
|
+
zIndex.value = nextZIndex();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function centerDialog() {
|
|
168
|
+
if (dialog.value) {
|
|
169
|
+
const boundingRect = dialog.value.getBoundingClientRect();
|
|
170
|
+
x.value = (window.innerWidth - boundingRect.width) / 2;
|
|
171
|
+
y.value = (window.innerHeight - boundingRect.height) / 2;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
146
174
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
175
|
+
watch(
|
|
176
|
+
() => props.open,
|
|
177
|
+
async (newVal) => {
|
|
178
|
+
isOpen.value = newVal;
|
|
179
|
+
if (newVal) {
|
|
180
|
+
await nextTick();
|
|
181
|
+
centerDialog();
|
|
153
182
|
}
|
|
183
|
+
},
|
|
184
|
+
{immediate: true},
|
|
185
|
+
);
|
|
154
186
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
}
|
|
187
|
+
// Expose methods to parent components
|
|
188
|
+
expose({
|
|
189
|
+
close,
|
|
178
190
|
});
|
|
179
|
-
</script>
|
|
180
191
|
|
|
192
|
+
return {
|
|
193
|
+
wrapper,
|
|
194
|
+
dialog,
|
|
195
|
+
handle,
|
|
196
|
+
zIndex,
|
|
197
|
+
fade,
|
|
198
|
+
modalScale,
|
|
199
|
+
style,
|
|
200
|
+
computedStyle,
|
|
201
|
+
backdropClasses,
|
|
202
|
+
resolvedTitle,
|
|
203
|
+
wrapperClasses,
|
|
204
|
+
isOpen,
|
|
205
|
+
close,
|
|
206
|
+
onEnter,
|
|
207
|
+
};
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
</script>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<slot/>
|
|
3
|
+
<template v-if="Object.keys(dialogMap).length > 0">
|
|
4
|
+
<Teleport to="body">
|
|
5
|
+
<MDialog
|
|
6
|
+
v-for="dialog in Object.values(dialogMap)"
|
|
7
|
+
:key="dialog.key"
|
|
8
|
+
v-bind="dialog.options"
|
|
9
|
+
ref="setDialogRef(dialog.key)"
|
|
10
|
+
@close="remove(dialog.key)"
|
|
11
|
+
>
|
|
12
|
+
<MRenderer v-if="dialog.options.render" :h="dialog.options.render" :props="dialog.options.props" />
|
|
13
|
+
</MDialog>
|
|
14
|
+
</Teleport>
|
|
15
|
+
</template>
|
|
16
|
+
</template>
|
|
17
|
+
<script lang="ts">
|
|
18
|
+
import {defineComponent, reactive, provide, ref} from 'vue';
|
|
19
|
+
import type {DialogApiInjection, DialogOptions, DialogReactive} from './types';
|
|
20
|
+
import MDialog from '../dialog/Dialog.vue';
|
|
21
|
+
import MRenderer from '../renderer/renderer';
|
|
22
|
+
|
|
23
|
+
export default defineComponent({
|
|
24
|
+
name: 'DialogProvider',
|
|
25
|
+
components: {
|
|
26
|
+
MDialog,
|
|
27
|
+
MRenderer,
|
|
28
|
+
},
|
|
29
|
+
setup() {
|
|
30
|
+
const dialogMap = reactive<Record<string, DialogReactive>>({});
|
|
31
|
+
const dialogRefs = ref<Record<string, any>>({});
|
|
32
|
+
|
|
33
|
+
function setDialogRef(key: string) {
|
|
34
|
+
return (el: any) => {
|
|
35
|
+
if (el) {
|
|
36
|
+
dialogRefs.value[key] = el;
|
|
37
|
+
} else {
|
|
38
|
+
delete dialogRefs.value[key];
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function create(key: string, options: DialogOptions = {}): DialogReactive {
|
|
44
|
+
if (dialogMap[key]) {
|
|
45
|
+
// Merge new options into existing reactive options
|
|
46
|
+
Object.assign(dialogMap[key].options, options);
|
|
47
|
+
return dialogMap[key];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Make options reactive
|
|
51
|
+
const reactiveOptions = reactive(options);
|
|
52
|
+
|
|
53
|
+
const dialog: DialogReactive = {
|
|
54
|
+
key,
|
|
55
|
+
options: reactiveOptions,
|
|
56
|
+
open: () => {
|
|
57
|
+
const dialogComponent = dialogRefs.value[key];
|
|
58
|
+
if (dialogComponent && dialogComponent.open) {
|
|
59
|
+
dialogComponent.open();
|
|
60
|
+
} else {
|
|
61
|
+
dialog.options.open = true;
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
close: () => {
|
|
65
|
+
const dialogComponent = dialogRefs.value[key];
|
|
66
|
+
if (dialogComponent && dialogComponent.close) {
|
|
67
|
+
dialogComponent.close();
|
|
68
|
+
} else {
|
|
69
|
+
remove(key);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
dialogMap[key] = dialog;
|
|
75
|
+
return dialog;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function remove(key: string) {
|
|
79
|
+
delete dialogMap[key];
|
|
80
|
+
delete dialogRefs.value[key];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const api: DialogApiInjection = {
|
|
84
|
+
create,
|
|
85
|
+
remove,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
provide('m-dialog', api);
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
dialogMap,
|
|
92
|
+
remove,
|
|
93
|
+
setDialogRef,
|
|
94
|
+
};
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
</script>
|