@teammodlr/ui-kit 2.1.68 → 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/dialog/Dialog.vue.d.ts +14 -13
- 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/composables/index.d.ts +1 -0
- package/lib/index.cjs.js +9 -9
- package/lib/index.es.js +2477 -2382
- package/package.json +1 -1
- 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/composables/index.ts +1 -0
package/package.json
CHANGED
|
@@ -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>
|
|
@@ -0,0 +1,51 @@
|
|
|
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: true
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
setTimeout(() => {
|
|
48
|
+
testTitle.value = 'changed again';
|
|
49
|
+
}, 4000);
|
|
50
|
+
}
|
|
51
|
+
</script>
|
|
@@ -0,0 +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({});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as MDialogProviderBasic } from './basic.vue';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Ref, VNodeChild } from 'vue';
|
|
2
|
+
|
|
3
|
+
export type DialogContent = VNodeChild;
|
|
4
|
+
|
|
5
|
+
export interface DialogOptions {
|
|
6
|
+
title?: string | Ref<string>;
|
|
7
|
+
render?: (props: any) => VNodeChild;
|
|
8
|
+
props?: { [key: string]: any };
|
|
9
|
+
onClose?: () => void;
|
|
10
|
+
open?: boolean;
|
|
11
|
+
draggable?: boolean;
|
|
12
|
+
modal?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface DialogReactive {
|
|
16
|
+
key: string;
|
|
17
|
+
options: DialogOptions;
|
|
18
|
+
open: () => void;
|
|
19
|
+
close: () => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface DialogApiInjection {
|
|
23
|
+
create: (key: string, options?: DialogOptions) => DialogReactive;
|
|
24
|
+
remove: (key: string) => void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { inject } from 'vue';
|
|
2
|
+
import type { DialogApiInjection} from "./types";
|
|
3
|
+
|
|
4
|
+
export function useDialog(): DialogApiInjection {
|
|
5
|
+
const api = inject('m-dialog', null);
|
|
6
|
+
|
|
7
|
+
if (api === null) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
`m-dialog api is not provided, ensure component is wrapped in <m-dialog-provider />`
|
|
10
|
+
)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return api;
|
|
14
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -48,4 +48,5 @@ export { default as MVirtualScroll } from './virtualscroll/VirtualScroll.vue';
|
|
|
48
48
|
export { default as MConfirm } from './confirm/Confirm.vue';
|
|
49
49
|
export { default as MConfirmProvider } from './confirm/ConfirmProvider.vue';
|
|
50
50
|
export { default as MDialog } from './dialog/Dialog.vue';
|
|
51
|
+
export { default as MDialogProvider } from './dialogprovider/DialogProvider.vue';
|
|
51
52
|
export { default as MTree } from './tree/Tree.vue';
|
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
import {
|
|
29
29
|
ref,
|
|
30
30
|
reactive,
|
|
31
|
-
Teleport,
|
|
32
31
|
defineComponent,
|
|
33
32
|
provide,
|
|
34
33
|
computed
|
|
@@ -43,11 +42,8 @@ import type {
|
|
|
43
42
|
} from './types';
|
|
44
43
|
import type { PropType } from 'vue';
|
|
45
44
|
import MMessage from './Message.vue';
|
|
46
|
-
import { useId } from '../../composables/useCachedUid';
|
|
47
45
|
import * as style from './style';
|
|
48
46
|
import { modalScale } from '../../styles/transitions.css';
|
|
49
|
-
import { useIsServer } from '../../composables/useIsServer';
|
|
50
|
-
export type MessageProviderInst = MessageApiInjection;
|
|
51
47
|
|
|
52
48
|
interface PrivateMessageReactive extends MessageReactive {
|
|
53
49
|
key: string;
|
package/src/composables/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { useMessage } from '../components/messageprovider/useMessage';
|
|
2
|
+
export { useDialog } from '../components/dialogprovider/useDialog';
|
|
2
3
|
export { useConfirm } from '../components/confirm/useConfirm';
|
|
3
4
|
export { usePopper } from './usePopper';
|
|
4
5
|
export { useZIndex } from './useZIndex';
|