edvoyui-component-library-test-flight 0.0.106 → 0.0.107
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/dist/library-vue-ts.cjs.js +18 -18
- package/dist/library-vue-ts.css +1 -1
- package/dist/library-vue-ts.es.js +323 -293
- package/dist/library-vue-ts.umd.js +3 -3
- package/dist/modal/EUIModal.vue.d.ts +1 -1
- package/dist/modal/EUIModal.vue.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/dropdown/EUIMultiDropdown.vue +74 -39
- package/src/components/modal/EUIModal.stories.ts +20 -0
- package/src/components/modal/EUIModal.vue +36 -8
- package/src/components/slideover/EUISlideover.stories.ts +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from "/Volumes/work/repos/edvoy-ui-v2/src/components/modal/EUIModal.vue?vue&type=script&lang.ts";
|
|
2
|
-
import "/Volumes/work/repos/edvoy-ui-v2/src/components/modal/EUIModal.vue?vue&type=style&index=0&scoped=
|
|
2
|
+
import "/Volumes/work/repos/edvoy-ui-v2/src/components/modal/EUIModal.vue?vue&type=style&index=0&scoped=0a1278e7&lang.scss";
|
|
3
3
|
declare const _default: any;
|
|
4
4
|
export default _default;
|
|
5
5
|
//# sourceMappingURL=EUIModal.vue.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EUIModal.vue.d.ts","sourceRoot":"","sources":["../../src/components/modal/EUIModal.vue"],"names":[],"mappings":"AACA,cAAc,2FAA2F,CAAC;
|
|
1
|
+
{"version":3,"file":"EUIModal.vue.d.ts","sourceRoot":"","sources":["../../src/components/modal/EUIModal.vue"],"names":[],"mappings":"AACA,cAAc,2FAA2F,CAAC;AA6F1G,OAAO,oHAAoH,CAAC;;AAE5H,wBAAmH"}
|
package/package.json
CHANGED
|
@@ -4,20 +4,32 @@
|
|
|
4
4
|
<button
|
|
5
5
|
type="button"
|
|
6
6
|
ref="dropdownButton"
|
|
7
|
-
:class="[
|
|
7
|
+
:class="[
|
|
8
|
+
'inline-flex items-center text-sm font-semibold gap-x-2 capitalize outline-none focus:outline-none',
|
|
9
|
+
className,
|
|
10
|
+
]"
|
|
8
11
|
:disabled="disabled"
|
|
9
12
|
@click="toggleDropdown()"
|
|
10
13
|
>
|
|
11
14
|
<slot name="dropdownName" :open="isOpen">
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
{{ title }}
|
|
16
|
+
<ChevronDownStroke
|
|
17
|
+
:class="isOpen ? 'text-gray-900 rotate-180' : 'text-gray-500'"
|
|
18
|
+
class="transition duration-100 ease-in-out transform rotate-0 size-6 group-hover:text-opacity-80"
|
|
19
|
+
aria-hidden="true"
|
|
16
20
|
/>
|
|
17
21
|
</slot>
|
|
18
22
|
</button>
|
|
19
23
|
<!-- Menu lists -->
|
|
20
|
-
<div
|
|
24
|
+
<div
|
|
25
|
+
v-if="isOpen && menuItems.length"
|
|
26
|
+
:class="[
|
|
27
|
+
'absolute left-0 z-0 p-2 mt-1 transition-all duration-300 ease-in-out bg-white border border-gray-200 border-solid rounded-lg shadow-2xl shadow-gray-300 min-w-32 max-w-64 w-max',
|
|
28
|
+
placement === 'top' ? 'bottom-full' : 'top-full',
|
|
29
|
+
dropdownClass,
|
|
30
|
+
]"
|
|
31
|
+
@click.stop
|
|
32
|
+
>
|
|
21
33
|
<div
|
|
22
34
|
v-for="item in menuItems"
|
|
23
35
|
:key="item.text"
|
|
@@ -26,36 +38,55 @@
|
|
|
26
38
|
@mouseleave="clearActiveMenuItem"
|
|
27
39
|
@click.stop="$emit('menuItem', item)"
|
|
28
40
|
>
|
|
29
|
-
<div
|
|
41
|
+
<div
|
|
42
|
+
class="flex items-center justify-between w-full gap-2 text-sm font-medium text-gray-800 break-words hover:text-gray-900"
|
|
43
|
+
>
|
|
30
44
|
<slot name="menu" :menuitem="item">
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
45
|
+
{{ item.text }}
|
|
46
|
+
<ChevronDownStroke
|
|
47
|
+
v-if="item.subMenu"
|
|
48
|
+
:class="
|
|
49
|
+
activeMenuItem === item.text
|
|
50
|
+
? 'text-gray-900 -rotate-90'
|
|
51
|
+
: 'text-gray-500 rotate-0'
|
|
52
|
+
"
|
|
53
|
+
class="ml-auto transition duration-300 ease-in-out transform size-6 group-hover:text-opacity-80"
|
|
54
|
+
aria-hidden="true"
|
|
55
|
+
/>
|
|
35
56
|
</slot>
|
|
36
57
|
</div>
|
|
37
58
|
|
|
38
59
|
<!-- Sub-menu lists-->
|
|
39
|
-
<div
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
60
|
+
<div
|
|
61
|
+
v-if="item.subMenu && activeMenuItem === item.text"
|
|
62
|
+
class="absolute top-0 z-10 transition-all duration-300 ease-in-out left-full min-w-32 max-w-64 w-max"
|
|
63
|
+
>
|
|
64
|
+
<div
|
|
65
|
+
class="bg-white border border-gray-200 border-solid rounded-lg shadow-2xl ms-2 shadow-gray-300"
|
|
66
|
+
>
|
|
67
|
+
<div
|
|
68
|
+
v-if="item.enableAction"
|
|
69
|
+
class="flex items-center justify-center w-full gap-1 px-6 py-3 text-sm font-medium text-gray-900 bg-purple-100 rounded-t-md"
|
|
70
|
+
@click.prevent="$emit('actionItem', 'action')"
|
|
71
|
+
>
|
|
72
|
+
<slot name="actionName">{{ "+ Action Name" }}</slot>
|
|
73
|
+
</div>
|
|
74
|
+
<div
|
|
75
|
+
class="p-2 overflow-y-auto overscroll-auto max-h-[50svh] min-h-0 scrollbar--thin"
|
|
76
|
+
>
|
|
45
77
|
<div
|
|
46
78
|
v-for="subItem in item.subMenu"
|
|
47
79
|
:key="subItem.text"
|
|
48
80
|
class="flex items-center justify-between gap-2 px-3 py-2 text-sm font-medium text-gray-700 rounded-lg cursor-pointer hover:bg-gray-100 hover:text-gray-900"
|
|
49
81
|
@click.stop="$emit('subMenuItem', subItem)"
|
|
50
82
|
>
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
83
|
+
<slot name="submenu" :subItem="subItem">
|
|
84
|
+
{{ subItem.text }}
|
|
85
|
+
</slot>
|
|
54
86
|
</div>
|
|
55
|
-
|
|
87
|
+
</div>
|
|
56
88
|
</div>
|
|
57
89
|
</div>
|
|
58
|
-
|
|
59
90
|
</div>
|
|
60
91
|
</div>
|
|
61
92
|
</div>
|
|
@@ -69,7 +100,7 @@ import ChevronDownStroke from "../../assets/svg/ChevronDownStroke.vue";
|
|
|
69
100
|
interface MenuItem {
|
|
70
101
|
text: string;
|
|
71
102
|
subMenu?: MenuItem[];
|
|
72
|
-
enableAction?:boolean;
|
|
103
|
+
enableAction?: boolean;
|
|
73
104
|
}
|
|
74
105
|
|
|
75
106
|
defineProps({
|
|
@@ -81,6 +112,10 @@ defineProps({
|
|
|
81
112
|
type: String,
|
|
82
113
|
required: false,
|
|
83
114
|
},
|
|
115
|
+
dropdownClass: {
|
|
116
|
+
type: String,
|
|
117
|
+
required: false,
|
|
118
|
+
},
|
|
84
119
|
menuItems: {
|
|
85
120
|
type: Array as PropType<MenuItem[]>,
|
|
86
121
|
default: () => [
|
|
@@ -93,44 +128,44 @@ defineProps({
|
|
|
93
128
|
{ text: "UKI Fair" },
|
|
94
129
|
{ text: "Germany Q4' 24" },
|
|
95
130
|
{ text: "Edvoy Express" },
|
|
96
|
-
{ text: "Q1 2025 Pipeline" }
|
|
97
|
-
]
|
|
131
|
+
{ text: "Q1 2025 Pipeline" },
|
|
132
|
+
],
|
|
98
133
|
},
|
|
99
134
|
{
|
|
100
135
|
text: "Custom Filter",
|
|
101
|
-
subMenu: [
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
enableAction: true
|
|
106
|
-
}
|
|
107
|
-
]
|
|
136
|
+
subMenu: [{ text: "Application Intakes" }, { text: "New Students" }],
|
|
137
|
+
enableAction: true,
|
|
138
|
+
},
|
|
139
|
+
],
|
|
108
140
|
},
|
|
109
141
|
disabled: Boolean,
|
|
142
|
+
placement: {
|
|
143
|
+
type: String as PropType<"top" | "bottom">,
|
|
144
|
+
default: "bottom",
|
|
145
|
+
},
|
|
110
146
|
});
|
|
111
147
|
|
|
112
148
|
const isOpen = ref(false);
|
|
113
149
|
const activeMenuItem = ref<string | null>(null);
|
|
114
150
|
const dropdownButton = ref<HTMLElement | null>(null);
|
|
115
151
|
|
|
116
|
-
defineEmits([
|
|
152
|
+
defineEmits(["subMenuItem", "menuItem", "actionItem"]);
|
|
117
153
|
|
|
118
154
|
const toggleDropdown = () => {
|
|
119
155
|
isOpen.value = !isOpen.value;
|
|
120
|
-
}
|
|
156
|
+
};
|
|
121
157
|
|
|
122
|
-
const setActiveMenuItem = (text:string) => {
|
|
158
|
+
const setActiveMenuItem = (text: string) => {
|
|
123
159
|
activeMenuItem.value = text;
|
|
124
|
-
}
|
|
160
|
+
};
|
|
125
161
|
|
|
126
162
|
const clearActiveMenuItem = () => {
|
|
127
163
|
activeMenuItem.value = null;
|
|
128
|
-
}
|
|
164
|
+
};
|
|
129
165
|
|
|
130
166
|
onClickOutside(dropdownButton, () => {
|
|
131
167
|
isOpen.value = false;
|
|
132
168
|
});
|
|
133
169
|
</script>
|
|
134
170
|
|
|
135
|
-
<style lang="scss" scoped>
|
|
136
|
-
</style>
|
|
171
|
+
<style lang="scss" scoped></style>
|
|
@@ -44,6 +44,17 @@ const meta: Meta<typeof EUIModal> = {
|
|
|
44
44
|
"Prevents the modal from being closed by clicking on the backdrop or pressing the Escape key.",
|
|
45
45
|
defaultValue: false,
|
|
46
46
|
},
|
|
47
|
+
size: {
|
|
48
|
+
control: {
|
|
49
|
+
type: "select",
|
|
50
|
+
options: ["xs", "sm", "md", "lg", "xl", "full"],
|
|
51
|
+
},
|
|
52
|
+
description: "Size of the slideover.",
|
|
53
|
+
defaultValue: "sm",
|
|
54
|
+
table: {
|
|
55
|
+
defaultValue: { summary: "sm" },
|
|
56
|
+
},
|
|
57
|
+
},
|
|
47
58
|
},
|
|
48
59
|
},
|
|
49
60
|
parameters: {
|
|
@@ -58,6 +69,15 @@ type Story = StoryObj<typeof meta>;
|
|
|
58
69
|
|
|
59
70
|
// Default EUIModal story with basic content
|
|
60
71
|
export const Default: Story = {
|
|
72
|
+
argTypes: {
|
|
73
|
+
size: {
|
|
74
|
+
control: "select",
|
|
75
|
+
options: ["xs", "sm", "md", "lg", "full"],
|
|
76
|
+
persistent: false,
|
|
77
|
+
slimHeader: false,
|
|
78
|
+
visibleClose: true,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
61
81
|
args: {
|
|
62
82
|
isVisible: false,
|
|
63
83
|
},
|
|
@@ -3,16 +3,18 @@
|
|
|
3
3
|
<Transition name="modal" appear>
|
|
4
4
|
<div
|
|
5
5
|
v-if="isVisible"
|
|
6
|
-
class="fixed
|
|
6
|
+
class="fixed z-50 flex flex-col items-center justify-end inset-2 sm:justify-center"
|
|
7
7
|
@click.self="closeModal"
|
|
8
8
|
>
|
|
9
9
|
<div
|
|
10
10
|
class="backdrop fixed inset-0 z-[-1] w-screen h-screen bg-black/50 pointer-events-none overflow-hidden"
|
|
11
11
|
></div>
|
|
12
12
|
<div
|
|
13
|
-
class="bg-white shadow-lg max-w-lg w-full max-h-[calc(100svh-3rem)] md:h-auto overflow-hidden relative"
|
|
14
13
|
:class="[
|
|
14
|
+
'bg-white shadow-lg w-full overflow-hidden relative flex flex-col justify-between',
|
|
15
|
+
slideClass,
|
|
15
16
|
roundedClass !== '' ? roundedClass : 'rounded-t-3xl md:rounded-2xl',
|
|
17
|
+
size === 'full' ? 'h-full max-h-svh' : 'max-h-[calc(100svh-3rem)] md:h-auto'
|
|
16
18
|
]"
|
|
17
19
|
>
|
|
18
20
|
<template v-if="$slots.header">
|
|
@@ -55,14 +57,14 @@
|
|
|
55
57
|
<template v-if="$slots.content">
|
|
56
58
|
<slot name="content"></slot>
|
|
57
59
|
</template>
|
|
58
|
-
<div v-else class="p-4 border-t border-b border-gray-200">
|
|
60
|
+
<div v-else class="p-4 border-t border-b border-gray-200 max-h-[calc(100svh-3rem)] flex-1">
|
|
59
61
|
<slot></slot>
|
|
60
62
|
</div>
|
|
61
63
|
|
|
62
64
|
<template v-if="$slots.footer">
|
|
63
65
|
<slot name="footer"></slot>
|
|
64
66
|
</template>
|
|
65
|
-
<div v-else class="flex items-center justify-end p-4 space-x-2">
|
|
67
|
+
<div v-else class="sticky bottom-0 flex items-center justify-end float-none p-4 space-x-2">
|
|
66
68
|
<button
|
|
67
69
|
@click="closeModal"
|
|
68
70
|
class="px-4 py-2 text-base font-semibold tracking-wide text-gray-600 transition-colors duration-75 bg-white rounded-md hover:bg-gray-100"
|
|
@@ -83,7 +85,14 @@
|
|
|
83
85
|
</template>
|
|
84
86
|
|
|
85
87
|
<script lang="ts">
|
|
86
|
-
import {
|
|
88
|
+
import {
|
|
89
|
+
defineComponent,
|
|
90
|
+
onMounted,
|
|
91
|
+
onUnmounted,
|
|
92
|
+
watch,
|
|
93
|
+
computed,
|
|
94
|
+
type PropType,
|
|
95
|
+
} from "vue";
|
|
87
96
|
|
|
88
97
|
export default defineComponent({
|
|
89
98
|
name: "Modal",
|
|
@@ -112,9 +121,27 @@ export default defineComponent({
|
|
|
112
121
|
type: Boolean,
|
|
113
122
|
default: false,
|
|
114
123
|
},
|
|
124
|
+
size: {
|
|
125
|
+
type: String as PropType<"xs" | "sm" | "md" | "lg" | "xl" | "full">,
|
|
126
|
+
default: "sm",
|
|
127
|
+
},
|
|
115
128
|
},
|
|
116
129
|
emits: ["update:isVisible", "confirm"],
|
|
117
130
|
setup(props, { emit }) {
|
|
131
|
+
const slideClass = computed(() => {
|
|
132
|
+
const sizeClass = {
|
|
133
|
+
full: "max-w-screen",
|
|
134
|
+
xl: "max-w-screen-lg min-w-[100svw] sm:min-w-[1024px]",
|
|
135
|
+
lg: "max-w-2xl min-w-[100svw] sm:min-w-[42rem]",
|
|
136
|
+
md: "max-w-xl min-w-[100svw] sm:min-w-[36rem]",
|
|
137
|
+
sm: "max-w-lg min-w-[100svw] sm:min-w-[32rem]",
|
|
138
|
+
xs: "max-w-md min-w-[100svw] sm:min-w-[28rem]",
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const slideWidth = sizeClass[props.size];
|
|
142
|
+
return slideWidth;
|
|
143
|
+
});
|
|
144
|
+
|
|
118
145
|
// Methods
|
|
119
146
|
const closeModal = () => {
|
|
120
147
|
if (!props.persistent) {
|
|
@@ -143,9 +170,10 @@ export default defineComponent({
|
|
|
143
170
|
window.removeEventListener("keydown", handleKeydown);
|
|
144
171
|
});
|
|
145
172
|
return {
|
|
146
|
-
closeModal
|
|
173
|
+
closeModal,
|
|
174
|
+
slideClass,
|
|
147
175
|
};
|
|
148
|
-
}
|
|
176
|
+
},
|
|
149
177
|
});
|
|
150
178
|
</script>
|
|
151
179
|
|
|
@@ -160,7 +188,7 @@ export default defineComponent({
|
|
|
160
188
|
}
|
|
161
189
|
.modal-enter-to,
|
|
162
190
|
.modal-leave-from {
|
|
163
|
-
|
|
191
|
+
@apply opacity-100;
|
|
164
192
|
}
|
|
165
193
|
|
|
166
194
|
.backdrop {
|
|
@@ -23,7 +23,7 @@ const meta: Meta<typeof EUISlideover> = {
|
|
|
23
23
|
},
|
|
24
24
|
},
|
|
25
25
|
size: {
|
|
26
|
-
control: { type: "select", options: ["xs", "sm", "md", "lg"] },
|
|
26
|
+
control: { type: "select", options: ["xs", "sm", "md", "lg", "full"] },
|
|
27
27
|
description: "Size of the slideover.",
|
|
28
28
|
defaultValue: "xs",
|
|
29
29
|
table: {
|