edvoyui-component-library-test-flight 0.0.168 → 0.0.170
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/package.json +10 -3
- package/src/App.vue +0 -16
- package/src/assets/svg/CheckTick.vue +0 -21
- package/src/assets/svg/ChevronBigDown.vue +0 -22
- package/src/assets/svg/ChevronDownSolid.vue +0 -19
- package/src/assets/svg/ChevronDownStroke.vue +0 -22
- package/src/assets/svg/ChevronDownStrokeSolid.vue +0 -19
- package/src/assets/svg/SearchBigZoomIn.vue +0 -21
- package/src/assets/svg/SortArrow.vue +0 -24
- package/src/assets/svg/Student.vue +0 -30
- package/src/assets/svg/partner.vue +0 -33
- package/src/assets/svg/people.vue +0 -25
- package/src/components/HelloWorld.vue +0 -1974
- package/src/components/accordion/EUIAccordion.vue +0 -152
- package/src/components/alerts/EUIAlerts.vue +0 -194
- package/src/components/avatar/EUIAvatar.vue +0 -96
- package/src/components/breadcrumb/EUIBreadcrumb.vue +0 -59
- package/src/components/button/EUIButton.vue +0 -154
- package/src/components/button/EUIButtonGroup.vue +0 -287
- package/src/components/button/buttonAnimateTab.vue +0 -74
- package/src/components/checkbox/EUICheckbox.vue +0 -110
- package/src/components/datepicker/EUIDatepicker.vue +0 -295
- package/src/components/delete.vue +0 -262
- package/src/components/dragModal/EUIDrag.vue +0 -179
- package/src/components/dropdown/EUIMultiDropdown.vue +0 -174
- package/src/components/errorMessage/EUIErrorMessage.vue +0 -25
- package/src/components/input/EUIInput.vue +0 -223
- package/src/components/input/EUINumberInput.vue +0 -250
- package/src/components/loader/EUICircleLoader.vue +0 -31
- package/src/components/loader/EUICubeLoader.vue +0 -237
- package/src/components/loader/EUILoader.vue +0 -17
- package/src/components/loader/EUISquareLoader.vue +0 -47
- package/src/components/modal/EUIModal.vue +0 -224
- package/src/components/pillSelect/EUIPillSelect.vue +0 -149
- package/src/components/popover/EUIPopover.vue +0 -297
- package/src/components/radio/EUIRadio.vue +0 -75
- package/src/components/searchInput/EUISearch.vue +0 -223
- package/src/components/searchTagSelect/EUISearchTagSelect.vue +0 -642
- package/src/components/searchTagSelect/SearchInput.vue +0 -167
- package/src/components/searchexpand/EUISearchExpand.vue +0 -148
- package/src/components/searchexpand/EUISearchToggle.vue +0 -86
- package/src/components/select/EUISelect.vue +0 -1092
- package/src/components/selectSearch/EUISelectSearch.vue +0 -23
- package/src/components/slideover/EUISlideover.vue +0 -207
- package/src/components/stepperTimeline/EUIStepperHorizontal.vue +0 -242
- package/src/components/stepperTimeline/EUIStepperTimeline.vue +0 -16
- package/src/components/stepperTimeline/EUIStepperVertical.vue +0 -112
- package/src/components/table/ColumnResizeTable.vue +0 -740
- package/src/components/table/EUIDashboardTable.vue +0 -514
- package/src/components/table/EUIPageLimit.vue +0 -66
- package/src/components/table/EUIPagination.vue +0 -175
- package/src/components/table/EUIStudentPagination.vue +0 -172
- package/src/components/table/EUITable.vue +0 -559
- package/src/components/table/EUITableCheckbox.vue +0 -98
- package/src/components/table/GrowthTable.vue +0 -575
- package/src/components/table/GrowthTableView.vue +0 -108
- package/src/components/table/ResizeTableview.vue +0 -198
- package/src/components/table/UCheckbox.vue +0 -169
- package/src/components/table/UTable.vue +0 -611
- package/src/components/table/UTableview.vue +0 -189
- package/src/components/tabs/EUITabOutline.vue +0 -263
- package/src/components/tabs/EUITabs.vue +0 -226
- package/src/components/tag/EUITag.vue +0 -88
- package/src/components/telephone/EUITelephone.vue +0 -299
- package/src/components/textArea/EUITextArea.vue +0 -155
- package/src/components/timeLine/EUITimeLine.vue +0 -148
- package/src/components/toggle/EUIToggle.vue +0 -101
- package/src/components/tooltip/EUITooltip.vue +0 -111
- package/src/components/uidemo/select-com.vue +0 -120
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div
|
|
3
|
-
v-if="isVisible"
|
|
4
|
-
ref="containerRef"
|
|
5
|
-
class="draggable-card"
|
|
6
|
-
:style="containerStyle"
|
|
7
|
-
>
|
|
8
|
-
<!-- HEADER / DRAG HANDLE -->
|
|
9
|
-
<div
|
|
10
|
-
class="flex items-center justify-between flex-shrink-0 px-2 bg-white cursor-grab"
|
|
11
|
-
@mousedown.prevent="startDrag"
|
|
12
|
-
@touchstart.prevent="startDrag"
|
|
13
|
-
>
|
|
14
|
-
<div class="flex items-center gap-4">
|
|
15
|
-
<EUIAvatar
|
|
16
|
-
image-url="https://tinyurl.com/43e5fxh9"
|
|
17
|
-
:profile="true"
|
|
18
|
-
full-name="JohnCena"
|
|
19
|
-
:show-status="true"
|
|
20
|
-
status="Online"
|
|
21
|
-
size="sm"
|
|
22
|
-
>
|
|
23
|
-
<template #name>John Cena</template>
|
|
24
|
-
<template #designation>Actor</template>
|
|
25
|
-
</EUIAvatar>
|
|
26
|
-
</div>
|
|
27
|
-
<EUIButton
|
|
28
|
-
color="white"
|
|
29
|
-
size="xs"
|
|
30
|
-
rounded
|
|
31
|
-
icon-type="icon"
|
|
32
|
-
:icon="ChevronBigDown"
|
|
33
|
-
:class="minimized ? 'rotate-0' : '-rotate-90'"
|
|
34
|
-
@click="onToggle"
|
|
35
|
-
/>
|
|
36
|
-
</div>
|
|
37
|
-
|
|
38
|
-
<!-- BODY -->
|
|
39
|
-
<transition name="slide-fade">
|
|
40
|
-
<div
|
|
41
|
-
v-if="minimized"
|
|
42
|
-
class="px-4 py-3 mt-4 overflow-y-auto border border-gray-100 border-solid rounded-lg bg-gray-50"
|
|
43
|
-
>
|
|
44
|
-
<h3 class="mb-2 text-lg font-semibold text-gray-900">
|
|
45
|
-
Card Title Here....
|
|
46
|
-
</h3>
|
|
47
|
-
<p class="mb-4 text-sm text-gray-500">
|
|
48
|
-
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Corporis non
|
|
49
|
-
velit doloremque sint repellat beatae accusamus? Recusandae possimus
|
|
50
|
-
voluptas beatae, labore dolor dolorem necessitatibus architecto
|
|
51
|
-
laudantium deserunt ipsam autem. Dignissimos?
|
|
52
|
-
</p>
|
|
53
|
-
|
|
54
|
-
<p class="text-sm text-gray-500">
|
|
55
|
-
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dicta minima
|
|
56
|
-
ullam porro voluptate ea, amet accusamus et debitis.
|
|
57
|
-
</p>
|
|
58
|
-
|
|
59
|
-
<div class="mt-4 text-right">
|
|
60
|
-
<EUIButton
|
|
61
|
-
color="primary"
|
|
62
|
-
size="sm"
|
|
63
|
-
icon-type="endIcon"
|
|
64
|
-
:icon="XMarkIcon"
|
|
65
|
-
rounded
|
|
66
|
-
@click="isVisible = false"
|
|
67
|
-
>
|
|
68
|
-
Close
|
|
69
|
-
</EUIButton>
|
|
70
|
-
</div>
|
|
71
|
-
</div>
|
|
72
|
-
</transition>
|
|
73
|
-
</div>
|
|
74
|
-
</template>
|
|
75
|
-
|
|
76
|
-
<script setup lang="ts">
|
|
77
|
-
import { ref, computed, watch, onBeforeUnmount } from "vue";
|
|
78
|
-
import { XMarkIcon } from "@heroicons/vue/24/outline";
|
|
79
|
-
import EUIAvatar from "../avatar/EUIAvatar.vue";
|
|
80
|
-
import EUIButton from "../button/EUIButton.vue";
|
|
81
|
-
import ChevronBigDown from "../../assets/svg/ChevronBigDown.vue";
|
|
82
|
-
|
|
83
|
-
const isVisible = ref(true);
|
|
84
|
-
const minimized = ref(true);
|
|
85
|
-
const containerRef = ref<HTMLElement | null>(null);
|
|
86
|
-
|
|
87
|
-
const x = ref(20);
|
|
88
|
-
const y = ref(80);
|
|
89
|
-
const dragging = ref(false);
|
|
90
|
-
const startX = ref(0);
|
|
91
|
-
const startY = ref(0);
|
|
92
|
-
const origX = ref(0);
|
|
93
|
-
const origY = ref(0);
|
|
94
|
-
|
|
95
|
-
const onToggle = () => {
|
|
96
|
-
minimized.value = !minimized.value;
|
|
97
|
-
if (minimized.value) {
|
|
98
|
-
y.value = y.value <= 284 ? y.value : 284;
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
const startDrag = (e: MouseEvent | TouchEvent) => {
|
|
103
|
-
const tag = (e.target as Element).tagName.toLowerCase();
|
|
104
|
-
if (["input", "textarea", "select", "button", "svg", "path"].includes(tag))
|
|
105
|
-
return;
|
|
106
|
-
|
|
107
|
-
const { pageX, pageY } = "touches" in e ? e.touches[0] : e;
|
|
108
|
-
dragging.value = true;
|
|
109
|
-
startX.value = pageX;
|
|
110
|
-
startY.value = pageY;
|
|
111
|
-
origX.value = x.value;
|
|
112
|
-
origY.value = y.value;
|
|
113
|
-
|
|
114
|
-
window.addEventListener("mousemove", onDrag);
|
|
115
|
-
window.addEventListener("mouseup", stopDrag);
|
|
116
|
-
window.addEventListener("touchmove", onDrag);
|
|
117
|
-
window.addEventListener("touchend", stopDrag);
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
const onDrag = (e: MouseEvent | TouchEvent) => {
|
|
121
|
-
if (!dragging.value) return;
|
|
122
|
-
const { pageX, pageY } = "touches" in e ? e.touches[0] : e;
|
|
123
|
-
const dx = pageX - startX.value;
|
|
124
|
-
const dy = pageY - startY.value;
|
|
125
|
-
|
|
126
|
-
let newX = origX.value - dx;
|
|
127
|
-
let newY = origY.value + dy;
|
|
128
|
-
|
|
129
|
-
const el = containerRef.value;
|
|
130
|
-
if (el) {
|
|
131
|
-
const { offsetWidth: w, offsetHeight: h } = el;
|
|
132
|
-
newX = Math.min(Math.max(0, newX), window.innerWidth - w);
|
|
133
|
-
newY = Math.min(Math.max(0, newY), window.innerHeight - h);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
x.value = newX;
|
|
137
|
-
y.value = newY;
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
const stopDrag = () => {
|
|
141
|
-
dragging.value = false;
|
|
142
|
-
window.removeEventListener("mousemove", onDrag);
|
|
143
|
-
window.removeEventListener("mouseup", stopDrag);
|
|
144
|
-
window.removeEventListener("touchmove", onDrag);
|
|
145
|
-
window.removeEventListener("touchend", stopDrag);
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
onBeforeUnmount(stopDrag);
|
|
149
|
-
|
|
150
|
-
// clamp Y when toggling
|
|
151
|
-
watch(minimized, (val) => {
|
|
152
|
-
if (!val && y.value > 300) {
|
|
153
|
-
y.value = 300;
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
const containerStyle = computed(() => ({
|
|
158
|
-
position: "fixed" as const,
|
|
159
|
-
right: `${x.value}px`,
|
|
160
|
-
top: `${y.value}px`,
|
|
161
|
-
cursor: dragging.value ? "grabbing" : "grab",
|
|
162
|
-
zIndex: 999,
|
|
163
|
-
}));
|
|
164
|
-
</script>
|
|
165
|
-
|
|
166
|
-
<style lang="scss" scoped>
|
|
167
|
-
.draggable-card {
|
|
168
|
-
@apply p-2 w-96 border border-solid border-purple-100 overflow-hidden flex-col flex bg-white rounded-2xl shadow-xl shadow-violet-100;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
.slide-fade-enter-active,
|
|
172
|
-
.slide-fade-leave-active {
|
|
173
|
-
transition: opacity 0.3s ease;
|
|
174
|
-
}
|
|
175
|
-
.slide-fade-enter-from,
|
|
176
|
-
.slide-fade-leave-to {
|
|
177
|
-
opacity: 0;
|
|
178
|
-
}
|
|
179
|
-
</style>
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="relative">
|
|
3
|
-
<!-- Main Dropdown Button -->
|
|
4
|
-
<button
|
|
5
|
-
type="button"
|
|
6
|
-
ref="dropdownButton"
|
|
7
|
-
:class="[
|
|
8
|
-
'inline-flex items-center text-sm font-semibold gap-x-2 capitalize outline-none focus:outline-none',
|
|
9
|
-
className,
|
|
10
|
-
]"
|
|
11
|
-
:disabled="disabled"
|
|
12
|
-
@click="toggleDropdown()"
|
|
13
|
-
>
|
|
14
|
-
<slot name="dropdownName" :open="isOpen">
|
|
15
|
-
{{ title }}
|
|
16
|
-
<component :is="isSolidArrow ? ChevronDownStrokeSolid : ChevronDownStroke" :class="isOpen ? 'text-gray-900 rotate-180' : 'text-gray-500'"
|
|
17
|
-
class="transition duration-100 ease-in-out transform rotate-0 size-6 group-hover:text-opacity-80"
|
|
18
|
-
aria-hidden="true" />
|
|
19
|
-
</slot>
|
|
20
|
-
</button>
|
|
21
|
-
<!-- Menu lists -->
|
|
22
|
-
<div
|
|
23
|
-
v-if="isOpen && menuItems.length"
|
|
24
|
-
:class="[
|
|
25
|
-
'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',
|
|
26
|
-
placement === 'top' ? 'bottom-full' : 'top-full',
|
|
27
|
-
dropdownClass,
|
|
28
|
-
]"
|
|
29
|
-
@click.stop
|
|
30
|
-
>
|
|
31
|
-
<div
|
|
32
|
-
v-for="item in menuItems"
|
|
33
|
-
:key="item.text"
|
|
34
|
-
class="relative flex items-center px-4 py-2 rounded-lg cursor-pointer hover:bg-gray-100"
|
|
35
|
-
@mouseenter="setActiveMenuItem(item.text)"
|
|
36
|
-
@mouseleave="clearActiveMenuItem"
|
|
37
|
-
@click.stop="$emit('menuItem', item)"
|
|
38
|
-
>
|
|
39
|
-
<div
|
|
40
|
-
class="flex items-center justify-between w-full gap-2 text-sm font-medium text-gray-800 break-words hover:text-gray-900"
|
|
41
|
-
>
|
|
42
|
-
<slot name="menu" :menuitem="item">
|
|
43
|
-
{{ item.text }}
|
|
44
|
-
<ChevronDownStroke
|
|
45
|
-
v-if="item.subMenu"
|
|
46
|
-
:class="
|
|
47
|
-
activeMenuItem === item.text
|
|
48
|
-
? 'text-gray-900 -rotate-90'
|
|
49
|
-
: 'text-gray-500 rotate-0'
|
|
50
|
-
"
|
|
51
|
-
class="ml-auto transition duration-300 ease-in-out transform size-6 group-hover:text-opacity-80"
|
|
52
|
-
aria-hidden="true"
|
|
53
|
-
/>
|
|
54
|
-
</slot>
|
|
55
|
-
</div>
|
|
56
|
-
|
|
57
|
-
<!-- Sub-menu lists-->
|
|
58
|
-
<div
|
|
59
|
-
v-if="item.subMenu && activeMenuItem === item.text"
|
|
60
|
-
class="absolute top-0 z-10 transition-all duration-300 ease-in-out left-full min-w-32 max-w-64 w-max"
|
|
61
|
-
>
|
|
62
|
-
<div
|
|
63
|
-
class="bg-white border border-gray-200 border-solid rounded-lg shadow-2xl ms-2 shadow-gray-300"
|
|
64
|
-
>
|
|
65
|
-
<div
|
|
66
|
-
v-if="item.enableAction"
|
|
67
|
-
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"
|
|
68
|
-
@click.prevent="$emit('actionItem', 'action')"
|
|
69
|
-
>
|
|
70
|
-
<slot name="actionName">{{ "+ Action Name" }}</slot>
|
|
71
|
-
</div>
|
|
72
|
-
<div
|
|
73
|
-
class="p-2 overflow-y-auto overscroll-auto max-h-[50svh] min-h-0 scrollbar--thin"
|
|
74
|
-
>
|
|
75
|
-
<div
|
|
76
|
-
v-for="subItem in item.subMenu"
|
|
77
|
-
:key="subItem.text"
|
|
78
|
-
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"
|
|
79
|
-
@click.stop="$emit('subMenuItem', subItem)"
|
|
80
|
-
>
|
|
81
|
-
<slot name="submenu" :subItem="subItem">
|
|
82
|
-
{{ subItem.text }}
|
|
83
|
-
</slot>
|
|
84
|
-
</div>
|
|
85
|
-
</div>
|
|
86
|
-
</div>
|
|
87
|
-
</div>
|
|
88
|
-
</div>
|
|
89
|
-
</div>
|
|
90
|
-
</div>
|
|
91
|
-
</template>
|
|
92
|
-
|
|
93
|
-
<script setup lang="ts">
|
|
94
|
-
import { ref, defineProps, PropType } from "vue";
|
|
95
|
-
import { onClickOutside } from "@vueuse/core";
|
|
96
|
-
import ChevronDownStroke from "../../assets/svg/ChevronDownStroke.vue";
|
|
97
|
-
import ChevronDownStrokeSolid from "../../assets/svg/ChevronDownStrokeSolid.vue";
|
|
98
|
-
|
|
99
|
-
interface MenuItem {
|
|
100
|
-
text: string;
|
|
101
|
-
subMenu?: MenuItem[];
|
|
102
|
-
enableAction?: boolean;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
defineProps({
|
|
106
|
-
title: {
|
|
107
|
-
type: String,
|
|
108
|
-
default: "My Students",
|
|
109
|
-
},
|
|
110
|
-
className: {
|
|
111
|
-
type: String,
|
|
112
|
-
required: false,
|
|
113
|
-
},
|
|
114
|
-
dropdownClass: {
|
|
115
|
-
type: String,
|
|
116
|
-
required: false,
|
|
117
|
-
},
|
|
118
|
-
isSolidArrow: {
|
|
119
|
-
type: Boolean,
|
|
120
|
-
default: false,
|
|
121
|
-
},
|
|
122
|
-
menuItems: {
|
|
123
|
-
type: Array as PropType<MenuItem[]>,
|
|
124
|
-
default: () => [
|
|
125
|
-
{ text: "All Students" },
|
|
126
|
-
{ text: "My Students" },
|
|
127
|
-
{ text: "Genie Completed Students" },
|
|
128
|
-
{
|
|
129
|
-
text: "Standard Filter",
|
|
130
|
-
subMenu: [
|
|
131
|
-
{ text: "UKI Fair" },
|
|
132
|
-
{ text: "Germany Q4' 24" },
|
|
133
|
-
{ text: "Edvoy Express" },
|
|
134
|
-
{ text: "Q1 2025 Pipeline" },
|
|
135
|
-
],
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
text: "Custom Filter",
|
|
139
|
-
subMenu: [{ text: "Application Intakes" }, { text: "New Students" }],
|
|
140
|
-
enableAction: true,
|
|
141
|
-
},
|
|
142
|
-
],
|
|
143
|
-
},
|
|
144
|
-
disabled: Boolean,
|
|
145
|
-
placement: {
|
|
146
|
-
type: String as PropType<"top" | "bottom">,
|
|
147
|
-
default: "bottom",
|
|
148
|
-
},
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
const isOpen = ref(false);
|
|
152
|
-
const activeMenuItem = ref<string | null>(null);
|
|
153
|
-
const dropdownButton = ref<HTMLElement | null>(null);
|
|
154
|
-
|
|
155
|
-
defineEmits(["subMenuItem", "menuItem", "actionItem"]);
|
|
156
|
-
|
|
157
|
-
const toggleDropdown = () => {
|
|
158
|
-
isOpen.value = !isOpen.value;
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
const setActiveMenuItem = (text: string) => {
|
|
162
|
-
activeMenuItem.value = text;
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
const clearActiveMenuItem = () => {
|
|
166
|
-
activeMenuItem.value = null;
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
onClickOutside(dropdownButton, () => {
|
|
170
|
-
isOpen.value = false;
|
|
171
|
-
});
|
|
172
|
-
</script>
|
|
173
|
-
|
|
174
|
-
<style lang="scss" scoped></style>
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<template v-if="Array.isArray(errors)">
|
|
3
|
-
<div class="text-red-500 text-xs font-medium first-letter:uppercase">
|
|
4
|
-
{{ errors?.at(0)?.$message ? errors?.at(0)?.$message : errors.at(0) }}
|
|
5
|
-
</div>
|
|
6
|
-
</template>
|
|
7
|
-
<template v-else>
|
|
8
|
-
<div class="text-red-500 text-xs font-medium first-letter:uppercase">
|
|
9
|
-
{{ name ? errors?.[name] : errors }}
|
|
10
|
-
</div>
|
|
11
|
-
</template>
|
|
12
|
-
</template>
|
|
13
|
-
|
|
14
|
-
<script setup lang="ts">
|
|
15
|
-
import { PropType, toRefs } from "vue";
|
|
16
|
-
import { ValidationErrors, ErrorObject } from "../../utils/types";
|
|
17
|
-
const props = defineProps({
|
|
18
|
-
name: { type: String, required: true },
|
|
19
|
-
errors: {
|
|
20
|
-
type: Object as PropType<ValidationErrors | ErrorObject[]>,
|
|
21
|
-
required: true,
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
const { errors, name } = toRefs(props);
|
|
25
|
-
</script>
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<label
|
|
4
|
-
v-if="!inputFilled && label"
|
|
5
|
-
:for="`${name}-${id}`"
|
|
6
|
-
:class="[
|
|
7
|
-
'text-xs w-full text-gray-500 cursor-pointer font-medium',
|
|
8
|
-
required && `after:content-['*'] after:ml-0.5 after:text-red-500`,
|
|
9
|
-
]"
|
|
10
|
-
>
|
|
11
|
-
{{ label }}
|
|
12
|
-
</label>
|
|
13
|
-
<div
|
|
14
|
-
:class="[
|
|
15
|
-
'relative',
|
|
16
|
-
{ 'pointer-events-none cursor-not-allowed': disabled },
|
|
17
|
-
{
|
|
18
|
-
'h-14 rounded-2xl focus-within:border-purple-600 focus-within:ring-1 focus-within:ring-purple-600 border border-gray-200':
|
|
19
|
-
inputFilled,
|
|
20
|
-
},
|
|
21
|
-
'group cursor-pointer relative w-full mb-2 overflow-hidden',
|
|
22
|
-
]"
|
|
23
|
-
>
|
|
24
|
-
<button
|
|
25
|
-
v-if="type === 'search'"
|
|
26
|
-
:class="inputValue ? 'absolute inset-y-0 right-3' : 'hidden'"
|
|
27
|
-
@click="emit('update:modelValue', '')"
|
|
28
|
-
>
|
|
29
|
-
<svg
|
|
30
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
31
|
-
fill="none"
|
|
32
|
-
viewBox="0 0 24 24"
|
|
33
|
-
stroke-width="1.5"
|
|
34
|
-
stroke="currentColor"
|
|
35
|
-
class="size-5"
|
|
36
|
-
>
|
|
37
|
-
<path
|
|
38
|
-
stroke-linecap="round"
|
|
39
|
-
stroke-linejoin="round"
|
|
40
|
-
d="M6 18 18 6M6 6l12 12"
|
|
41
|
-
/>
|
|
42
|
-
</svg>
|
|
43
|
-
</button>
|
|
44
|
-
<label
|
|
45
|
-
v-if="inputFilled"
|
|
46
|
-
:for="`${name}-${id}`"
|
|
47
|
-
:class="[
|
|
48
|
-
getIconClass(),
|
|
49
|
-
inputValue
|
|
50
|
-
? 'top-3.5 text-xs text-gray-400 leading-none cursor-default'
|
|
51
|
-
: 'top-1/2 text-sm w-full text-gray-700 cursor-pointer h-14 pt-5 pb-4',
|
|
52
|
-
disabled ? 'cursor-not-allowed bg-gray-50 z-10' : 'z-0 bg-white',
|
|
53
|
-
required && `after:content-['*'] after:ml-0.5 after:text-red-500`,
|
|
54
|
-
'absolute font-medium left-0 px-4 -translate-y-1/2 duration-300 group-focus-within:top-3.5 group-focus-within:text-xs group-focus-within:text-gray-400 rounded-2xl group-focus-within:bg-transparent group-focus-within:-translate-y-1/2 group-focus-within:ring-transparent group-focus-within:h-auto group-focus-within:py-0 first-letter:capitalize transition-all ease-in-out',
|
|
55
|
-
]"
|
|
56
|
-
>
|
|
57
|
-
{{ label || "Label" }}
|
|
58
|
-
</label>
|
|
59
|
-
<div
|
|
60
|
-
v-if="icon && iconType"
|
|
61
|
-
:class="[
|
|
62
|
-
'absolute inset-y-0 flex items-center pointer-events-none',
|
|
63
|
-
iconType === 'startIcon' ? 'left-0 pl-3' : 'right-0 pr-3',
|
|
64
|
-
disabled ? 'z-20' : '',
|
|
65
|
-
]"
|
|
66
|
-
>
|
|
67
|
-
<component :is="icon" class="text-gray-400 size-6" aria-hidden="true" />
|
|
68
|
-
</div>
|
|
69
|
-
<input
|
|
70
|
-
:id="`${name}-${id}`"
|
|
71
|
-
ref="input"
|
|
72
|
-
:type="type === 'search' ? 'text' : type"
|
|
73
|
-
:value="modelValue"
|
|
74
|
-
:placeholder="placeholder"
|
|
75
|
-
:name="name"
|
|
76
|
-
:class="[
|
|
77
|
-
'z-10 block placeholder:text-gray-400 focus:outline-none text-sm font-medium appearance-none disabled:opacity-75 autofill:bg-white leading-6 transition-all duration-100 border-none outline-none',
|
|
78
|
-
inputFilled
|
|
79
|
-
? 'pt-6 pb-3 rounded-2xl size-full'
|
|
80
|
-
: 'py-3 h-10 w-full ring-1 ring-gray-200 focus-within:ring-purple-600 focus-within:ring-2 ring-inset',
|
|
81
|
-
!inputFilled && rounded ? 'rounded-2xl' : 'rounded-md',
|
|
82
|
-
disabled ? 'cursor-not-allowed' : 'cursor-text',
|
|
83
|
-
getIconClass(),
|
|
84
|
-
!inputFilled && className,
|
|
85
|
-
'pr-8'
|
|
86
|
-
]"
|
|
87
|
-
:required="required"
|
|
88
|
-
:disabled="disabled"
|
|
89
|
-
:readonly="readonly"
|
|
90
|
-
autocomplete="off"
|
|
91
|
-
@input="emitInput"
|
|
92
|
-
@focus="hasFocus = true"
|
|
93
|
-
@blur="hasFocus = false"
|
|
94
|
-
/>
|
|
95
|
-
</div>
|
|
96
|
-
<template v-if="errors && Object.keys(errors).length">
|
|
97
|
-
<EUIErrorMessage :errors="errors" :name="name" />
|
|
98
|
-
</template>
|
|
99
|
-
</div>
|
|
100
|
-
</template>
|
|
101
|
-
|
|
102
|
-
<script lang="ts" setup>
|
|
103
|
-
import EUIErrorMessage from "../errorMessage/EUIErrorMessage.vue";
|
|
104
|
-
import {
|
|
105
|
-
defineProps,
|
|
106
|
-
defineEmits,
|
|
107
|
-
computed,
|
|
108
|
-
PropType,
|
|
109
|
-
ref,
|
|
110
|
-
onMounted,
|
|
111
|
-
} from "vue";
|
|
112
|
-
|
|
113
|
-
const props = defineProps({
|
|
114
|
-
errors: { type: Object, required: false, default: () => {} },
|
|
115
|
-
type: {
|
|
116
|
-
type: String as PropType<
|
|
117
|
-
"text" | "number" | "email" | "password" | "search" | "date" | "url"
|
|
118
|
-
>,
|
|
119
|
-
default: "text",
|
|
120
|
-
},
|
|
121
|
-
modelValue: {
|
|
122
|
-
type: [String, Number],
|
|
123
|
-
default: "",
|
|
124
|
-
},
|
|
125
|
-
name: {
|
|
126
|
-
type: String,
|
|
127
|
-
required: false,
|
|
128
|
-
default: "",
|
|
129
|
-
},
|
|
130
|
-
label: {
|
|
131
|
-
type: String,
|
|
132
|
-
required: true,
|
|
133
|
-
default: "",
|
|
134
|
-
},
|
|
135
|
-
autoFocus: {
|
|
136
|
-
type: Boolean,
|
|
137
|
-
required: false,
|
|
138
|
-
default: false,
|
|
139
|
-
},
|
|
140
|
-
placeholder: {
|
|
141
|
-
type: String,
|
|
142
|
-
required: false,
|
|
143
|
-
default: "",
|
|
144
|
-
},
|
|
145
|
-
iconType: {
|
|
146
|
-
type: String as PropType<"startIcon" | "endIcon">,
|
|
147
|
-
default: "",
|
|
148
|
-
},
|
|
149
|
-
icon: {
|
|
150
|
-
type: [Object, String],
|
|
151
|
-
default: "",
|
|
152
|
-
},
|
|
153
|
-
disabled: {
|
|
154
|
-
type: Boolean,
|
|
155
|
-
default: false,
|
|
156
|
-
},
|
|
157
|
-
required: {
|
|
158
|
-
type: Boolean,
|
|
159
|
-
default: false,
|
|
160
|
-
},
|
|
161
|
-
readonly: {
|
|
162
|
-
type: Boolean,
|
|
163
|
-
default: false,
|
|
164
|
-
},
|
|
165
|
-
inputFilled: {
|
|
166
|
-
type: Boolean,
|
|
167
|
-
default: false,
|
|
168
|
-
},
|
|
169
|
-
rounded: Boolean,
|
|
170
|
-
className: {
|
|
171
|
-
type: Array as PropType<string[]>,
|
|
172
|
-
required: false,
|
|
173
|
-
default: () => [],
|
|
174
|
-
},
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
const hasFocus = ref(false);
|
|
178
|
-
const input = ref<HTMLInputElement>();
|
|
179
|
-
|
|
180
|
-
const id = "id"; //generateUID();
|
|
181
|
-
|
|
182
|
-
const emit = defineEmits(["update:modelValue"]);
|
|
183
|
-
const emitInput = (event: Event) => {
|
|
184
|
-
const newValue = (event?.target as HTMLInputElement)?.value;
|
|
185
|
-
if (newValue !== undefined) {
|
|
186
|
-
emit("update:modelValue", newValue);
|
|
187
|
-
}
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
const inputValue = computed(() => {
|
|
191
|
-
return props.modelValue === 0 ? true : !!props.modelValue;
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
const getIconClass = () => {
|
|
195
|
-
switch (props.iconType) {
|
|
196
|
-
case "startIcon":
|
|
197
|
-
return "pl-12 pr-4";
|
|
198
|
-
case "endIcon":
|
|
199
|
-
return "pr-12 pl-4";
|
|
200
|
-
default:
|
|
201
|
-
return "px-4";
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
onMounted(() => {
|
|
206
|
-
if (props?.autoFocus) {
|
|
207
|
-
input?.value?.focus();
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
</script>
|
|
211
|
-
|
|
212
|
-
<style lang="scss" scoped>
|
|
213
|
-
/* Chrome, Safari, Edge, Opera */
|
|
214
|
-
input::-webkit-outer-spin-button,
|
|
215
|
-
input::-webkit-inner-spin-button {
|
|
216
|
-
-webkit-appearance: none;
|
|
217
|
-
margin: 0;
|
|
218
|
-
}
|
|
219
|
-
/* Firefox */
|
|
220
|
-
input[type="number"] {
|
|
221
|
-
-moz-appearance: textfield;
|
|
222
|
-
}
|
|
223
|
-
</style>
|