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,189 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<!-- <pre class="text-[0.5rem] p-2 border border-gray-300 rounded-lg max-h-72 overflow-y-auto">{{ selectedRows.map(x => x?._id)}}</pre> -->
|
|
4
|
-
<UTable
|
|
5
|
-
:checkable="true"
|
|
6
|
-
:table-loading="loading"
|
|
7
|
-
v-model:selectedRows.sync="selectedRows"
|
|
8
|
-
paginated
|
|
9
|
-
:checked-rows.sync="checkedRows"
|
|
10
|
-
backend-pagination
|
|
11
|
-
:per-page="limit"
|
|
12
|
-
:headers="studentHeader"
|
|
13
|
-
:items="studentData"
|
|
14
|
-
:total="studentData.length"
|
|
15
|
-
:default-sort-direction="defaultSortOrder"
|
|
16
|
-
default-sort=""
|
|
17
|
-
:current-page="offset"
|
|
18
|
-
table-height="h-[calc(100svh-15rem)] max-h-[calc(100svh-15rem)]"
|
|
19
|
-
:table-expanded="true"
|
|
20
|
-
@changePage="onPageChange"
|
|
21
|
-
@sort="onSort"
|
|
22
|
-
@mouseenter="select"
|
|
23
|
-
@mouseleave="(selectedIndex = null), (selected = null)"
|
|
24
|
-
>
|
|
25
|
-
<template #[`item.firstName`]="{ row, rowIndex }">
|
|
26
|
-
<div class="space-y-0.5">
|
|
27
|
-
<div class="block text-sm font-medium leading-snug">
|
|
28
|
-
{{
|
|
29
|
-
rowIndex +
|
|
30
|
-
capitalizeText(row?.firstName) +
|
|
31
|
-
" " +
|
|
32
|
-
capitalizeText(row?.lastName)
|
|
33
|
-
}}
|
|
34
|
-
</div>
|
|
35
|
-
<div class="text-xs font-medium text-gray-900 leading-[normal]">
|
|
36
|
-
{{ row?.referenceId }}
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
</template>
|
|
40
|
-
<template #[`item.lifecycleStage`]="{ row, rowIndex }">
|
|
41
|
-
<div :key="rowIndex">
|
|
42
|
-
<div>{{ row?.lifecycleStage }}</div>
|
|
43
|
-
<button
|
|
44
|
-
type="button"
|
|
45
|
-
class="inline-flex items-center gap-2 py-0.5 text-xs font-medium text-gray-700 bg-gray-300 outline-none ps-2 pe-0.5 rounded-3xl focus:outline-none"
|
|
46
|
-
@click="rowToggle(rowIndex)"
|
|
47
|
-
>
|
|
48
|
-
Foundation
|
|
49
|
-
<span
|
|
50
|
-
class="inline-flex items-center text-xss font-bold gap-1 ps-2 pe-1 py-0.5 bg-gray-100 rounded-3xl min-w-7"
|
|
51
|
-
>2 <ChevronBigDown class="transition-all duration-300 ease-in-out transform size-3" :class="activeRowIndex === rowIndex ? '-rotate-180': 'rotate-0'" />
|
|
52
|
-
</span>
|
|
53
|
-
</button>
|
|
54
|
-
</div>
|
|
55
|
-
</template>
|
|
56
|
-
|
|
57
|
-
<template #[`item.activeUser`]="{ row, rowIndex }">
|
|
58
|
-
{{ rowIndex }}
|
|
59
|
-
{{ row?.activeUser?.user?.firstName }}
|
|
60
|
-
{{ row?.activeUser?.user?.lastName }}
|
|
61
|
-
</template>
|
|
62
|
-
|
|
63
|
-
<template #expanded="{ row, rowIndex, headerLength }">
|
|
64
|
-
<tr v-if="rowIndex === activeRowIndex" class="row-expanded" :key="`${row}-${rowIndex}-val`">
|
|
65
|
-
<td :colspan="headerLength">
|
|
66
|
-
<div>
|
|
67
|
-
<table
|
|
68
|
-
class="px-12 border-separate table-auto max-w-max border-spacing-x-0 border-spacing-y-2"
|
|
69
|
-
>
|
|
70
|
-
<tbody>
|
|
71
|
-
<tr
|
|
72
|
-
class="rounded-lg group bg-white hover:bg-violet-50 hover:ring-1 ring-violet-300 hover:shadow-[0px_1px_2px_0px_#4B55631A,0px_2px_2px_0px_#4B556314]"
|
|
73
|
-
>
|
|
74
|
-
<td
|
|
75
|
-
v-for="(data, idx) in sqlApplication"
|
|
76
|
-
:key="`data-${idx}`"
|
|
77
|
-
class="py-2.5 px-3 text-sm text-gray-700 w-40"
|
|
78
|
-
:class="
|
|
79
|
-
idx === 0
|
|
80
|
-
? 'rounded-l-lg'
|
|
81
|
-
: idx === sqlApplication.length - 1
|
|
82
|
-
? 'rounded-r-lg'
|
|
83
|
-
: ''
|
|
84
|
-
"
|
|
85
|
-
>
|
|
86
|
-
{{ data }}
|
|
87
|
-
</td>
|
|
88
|
-
</tr>
|
|
89
|
-
|
|
90
|
-
<tr
|
|
91
|
-
class="rounded-lg group bg-white hover:bg-violet-50 hover:ring-1 ring-violet-300 hover:shadow-[0px_1px_2px_0px_#4B55631A,0px_2px_2px_0px_#4B556314]"
|
|
92
|
-
>
|
|
93
|
-
<td
|
|
94
|
-
v-for="(data, idx) in sqlApplication"
|
|
95
|
-
:key="`data-${idx}`"
|
|
96
|
-
class="py-2.5 px-3 text-sm text-gray-700 w-40"
|
|
97
|
-
:class="
|
|
98
|
-
idx === 0
|
|
99
|
-
? 'rounded-l-lg'
|
|
100
|
-
: idx === sqlApplication.length - 1
|
|
101
|
-
? 'rounded-r-lg'
|
|
102
|
-
: ''
|
|
103
|
-
"
|
|
104
|
-
>
|
|
105
|
-
{{ data }}
|
|
106
|
-
</td>
|
|
107
|
-
</tr>
|
|
108
|
-
|
|
109
|
-
<tr
|
|
110
|
-
class="rounded-lg group bg-white hover:bg-violet-50 hover:ring-1 ring-violet-300 hover:shadow-[0px_1px_2px_0px_#4B55631A,0px_2px_2px_0px_#4B556314]"
|
|
111
|
-
>
|
|
112
|
-
<td
|
|
113
|
-
v-for="(data, idx) in sqlApplication"
|
|
114
|
-
:key="`data-${idx}`"
|
|
115
|
-
class="py-2.5 px-3 text-sm text-gray-700 w-40"
|
|
116
|
-
:class="
|
|
117
|
-
idx === 0
|
|
118
|
-
? 'rounded-l-lg'
|
|
119
|
-
: idx === sqlApplication.length - 1
|
|
120
|
-
? 'rounded-r-lg'
|
|
121
|
-
: ''
|
|
122
|
-
"
|
|
123
|
-
>
|
|
124
|
-
{{ data }}
|
|
125
|
-
</td>
|
|
126
|
-
</tr>
|
|
127
|
-
</tbody>
|
|
128
|
-
|
|
129
|
-
</table>
|
|
130
|
-
</div>
|
|
131
|
-
</td>
|
|
132
|
-
</tr>
|
|
133
|
-
</template>
|
|
134
|
-
</UTable>
|
|
135
|
-
</div>
|
|
136
|
-
</template>
|
|
137
|
-
|
|
138
|
-
<script setup lang="ts">
|
|
139
|
-
import { ref } from "vue";
|
|
140
|
-
import UTable from "./UTable.vue";
|
|
141
|
-
import { studentData, studentHeader } from "../../data/table";
|
|
142
|
-
import { capitalizeText } from "../../utils/lodash";
|
|
143
|
-
import ChevronBigDown from "../../assets/svg/ChevronBigDown.vue";
|
|
144
|
-
|
|
145
|
-
//TODO: Dashboard Table
|
|
146
|
-
const selectedRows = ref([]);
|
|
147
|
-
const loading = ref(false);
|
|
148
|
-
const checkedRows = ref([]);
|
|
149
|
-
const defaultSortOrder = ref("asc");
|
|
150
|
-
const limit = ref(5);
|
|
151
|
-
const offset = ref(1);
|
|
152
|
-
const selectedIndex = ref<{ index: string } | null>(null);
|
|
153
|
-
const selected = ref<{ index: string } | null>(null);
|
|
154
|
-
|
|
155
|
-
const select = (_item: any, index: any) => {
|
|
156
|
-
selectedIndex.value = index;
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
const onSort = (field: string, order: string) => {
|
|
160
|
-
const modifier = order === "desc" ? -1 : 1;
|
|
161
|
-
studentData.sort((a: any, b: any) => {
|
|
162
|
-
if (a[field] < b[field]) return -1 * modifier;
|
|
163
|
-
if (a[field] > b[field]) return 1 * modifier;
|
|
164
|
-
return 0;
|
|
165
|
-
});
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
const onPageChange = (offsetData: number) => {
|
|
169
|
-
offset.value = offsetData;
|
|
170
|
-
loading.value = true;
|
|
171
|
-
console.log("@changePage:", offsetData);
|
|
172
|
-
setTimeout(() => {
|
|
173
|
-
loading.value = false;
|
|
174
|
-
}, 800);
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
const sqlApplication = ref(["Application 1", "Ready to Apply", "Mar 2025"]);
|
|
178
|
-
|
|
179
|
-
const activeRowIndex = ref()
|
|
180
|
-
const rowToggle = (index:any) => {
|
|
181
|
-
if(activeRowIndex.value === index){
|
|
182
|
-
activeRowIndex.value = null
|
|
183
|
-
} else {
|
|
184
|
-
activeRowIndex.value = index
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
</script>
|
|
188
|
-
|
|
189
|
-
<style scoped></style>
|
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="bg-white rounded-t-xl" v-bind="$attrs">
|
|
3
|
-
<div
|
|
4
|
-
class="relative z-10 inline-flex items-center w-full gap-2 pt-3 overflow-hidden transition-all duration-200 ease-in border border-b-0 border-solid rounded-t-xl isolate before:h-4 before:w-px before:bg-gray-200 before:-bottom-3 before:-left-px before:absolute after:h-4 after:w-px after:bg-gray-200 after:-bottom-3 after:-right-px after:absolute bg-gradient-to-b from-gray-100"
|
|
5
|
-
>
|
|
6
|
-
<nav
|
|
7
|
-
class="relative z-0 inline-flex flex-row items-center w-full gap-2 px-6"
|
|
8
|
-
>
|
|
9
|
-
<div
|
|
10
|
-
id="tab-indicator"
|
|
11
|
-
:style="{
|
|
12
|
-
'--border': allColor[activeColor],
|
|
13
|
-
}"
|
|
14
|
-
>
|
|
15
|
-
<span></span>
|
|
16
|
-
</div>
|
|
17
|
-
<button
|
|
18
|
-
v-for="(data, index) in items"
|
|
19
|
-
:key="`data-${index}`"
|
|
20
|
-
v-bind="buttonAttrs"
|
|
21
|
-
:data-tab="data.name"
|
|
22
|
-
:class="[
|
|
23
|
-
'capitalize box-border border-none inline-flex flex-row gap-x-2 items-center will-change-contents',
|
|
24
|
-
getBtnClass(data.name || ''),
|
|
25
|
-
activeBtnName === data.name ? 'font-semibold' : 'font-normal',
|
|
26
|
-
]"
|
|
27
|
-
:disabled="disabled"
|
|
28
|
-
:loading="loading"
|
|
29
|
-
@click="handleOnChange(data || '')"
|
|
30
|
-
style="transition: all 350ms cubic-bezier(0.15, 0.3, 0.25, 1)"
|
|
31
|
-
>
|
|
32
|
-
<component
|
|
33
|
-
:is="icon"
|
|
34
|
-
v-if="iconType === 'icon' || iconType === 'startIcon'"
|
|
35
|
-
:class="[iconWidth]"
|
|
36
|
-
/>
|
|
37
|
-
<slot :data="data" :activeName="activeBtnName">
|
|
38
|
-
{{ data?.name }}
|
|
39
|
-
</slot>
|
|
40
|
-
<component
|
|
41
|
-
:is="icon"
|
|
42
|
-
v-if="iconType === 'endIcon'"
|
|
43
|
-
:class="[iconWidth]"
|
|
44
|
-
/>
|
|
45
|
-
<svg
|
|
46
|
-
v-if="loading"
|
|
47
|
-
class="animate-spin"
|
|
48
|
-
:class="[iconWidth]"
|
|
49
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
50
|
-
fill="none"
|
|
51
|
-
viewBox="0 0 24 24"
|
|
52
|
-
>
|
|
53
|
-
<circle
|
|
54
|
-
class="opacity-25"
|
|
55
|
-
cx="12"
|
|
56
|
-
cy="12"
|
|
57
|
-
r="10"
|
|
58
|
-
stroke="currentColor"
|
|
59
|
-
stroke-width="4"
|
|
60
|
-
/>
|
|
61
|
-
<path
|
|
62
|
-
fill="currentColor"
|
|
63
|
-
class="opacity-75"
|
|
64
|
-
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
65
|
-
/>
|
|
66
|
-
</svg>
|
|
67
|
-
</button>
|
|
68
|
-
</nav>
|
|
69
|
-
</div>
|
|
70
|
-
|
|
71
|
-
<div
|
|
72
|
-
class="relative z-0 px-4 py-4 -mt-px text-gray-500 border border-gray-200 border-solid rounded-b-xl"
|
|
73
|
-
>
|
|
74
|
-
<template v-for="(data, index) in items" :key="`data-${index}`">
|
|
75
|
-
<slot
|
|
76
|
-
v-if="data.name === activeBtnName"
|
|
77
|
-
name="content"
|
|
78
|
-
:data="data"
|
|
79
|
-
:activeName="activeBtnName"
|
|
80
|
-
>
|
|
81
|
-
{{ data.name }}
|
|
82
|
-
</slot>
|
|
83
|
-
</template>
|
|
84
|
-
</div>
|
|
85
|
-
</div>
|
|
86
|
-
</template>
|
|
87
|
-
|
|
88
|
-
<script setup lang="ts">
|
|
89
|
-
import {
|
|
90
|
-
computed,
|
|
91
|
-
nextTick,
|
|
92
|
-
onMounted,
|
|
93
|
-
PropType,
|
|
94
|
-
reactive,
|
|
95
|
-
ref,
|
|
96
|
-
toRefs,
|
|
97
|
-
useAttrs,
|
|
98
|
-
} from "vue";
|
|
99
|
-
|
|
100
|
-
interface Item {
|
|
101
|
-
name: string;
|
|
102
|
-
[key: string]: any;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const props = defineProps({
|
|
106
|
-
items: {
|
|
107
|
-
type: Array as () => Item[],
|
|
108
|
-
default: () => [],
|
|
109
|
-
},
|
|
110
|
-
defaultActive: {
|
|
111
|
-
type: String,
|
|
112
|
-
default: "",
|
|
113
|
-
},
|
|
114
|
-
type: {
|
|
115
|
-
type: String,
|
|
116
|
-
default: "button",
|
|
117
|
-
},
|
|
118
|
-
size: {
|
|
119
|
-
type: String as PropType<"sm" | "md" | "lg">,
|
|
120
|
-
default: "md",
|
|
121
|
-
},
|
|
122
|
-
activeColor: {
|
|
123
|
-
type: String as PropType<"success" | "black" | "purple" | "default">,
|
|
124
|
-
default: "black",
|
|
125
|
-
},
|
|
126
|
-
iconType: {
|
|
127
|
-
type: String as PropType<"startIcon" | "endIcon" | "icon">,
|
|
128
|
-
default: "",
|
|
129
|
-
},
|
|
130
|
-
icon: {
|
|
131
|
-
type: [String, Object, Function],
|
|
132
|
-
default: "",
|
|
133
|
-
},
|
|
134
|
-
loading: Boolean,
|
|
135
|
-
disabled: Boolean,
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
const emit = defineEmits<{
|
|
139
|
-
(event: "update:activeTabItem", activeTabItem: Item): void;
|
|
140
|
-
}>();
|
|
141
|
-
|
|
142
|
-
defineOptions({
|
|
143
|
-
inheritAttrs: false, // 🛑 prevents auto-inheritance of $attrs to root
|
|
144
|
-
});
|
|
145
|
-
const attrs = useAttrs();
|
|
146
|
-
const buttonAttrs = computed(() => {
|
|
147
|
-
const { class: _class, style: _style, id: _id, ...rest } = attrs;
|
|
148
|
-
return rest;
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
const { items, defaultActive } = toRefs(props);
|
|
152
|
-
const activeBtnName = ref(defaultActive.value || items.value[0]?.name || "");
|
|
153
|
-
|
|
154
|
-
const marker = (el: HTMLElement) => {
|
|
155
|
-
const indicator = document.querySelector("#tab-indicator") as HTMLElement;
|
|
156
|
-
if (indicator && el) {
|
|
157
|
-
indicator.style.left = el.offsetLeft + "px";
|
|
158
|
-
indicator.style.width = el.offsetWidth + "px";
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
const handleOnChange = (val: any) => {
|
|
163
|
-
activeBtnName.value = val?.name;
|
|
164
|
-
emit("update:activeTabItem", val);
|
|
165
|
-
nextTick(() => {
|
|
166
|
-
const activeBtn = document.querySelector(
|
|
167
|
-
`nav button[data-tab="${activeBtnName.value}"]`
|
|
168
|
-
);
|
|
169
|
-
if (activeBtn) marker(activeBtn as HTMLElement);
|
|
170
|
-
});
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
onMounted(() => {
|
|
174
|
-
nextTick(() => {
|
|
175
|
-
requestAnimationFrame(() => {
|
|
176
|
-
const activeBtn = document.querySelector(
|
|
177
|
-
`nav button[data-tab="${activeBtnName.value}"]`
|
|
178
|
-
);
|
|
179
|
-
if (activeBtn) marker(activeBtn as HTMLElement);
|
|
180
|
-
});
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
const btnColors = {
|
|
185
|
-
default: {
|
|
186
|
-
enabled: "text-gray-500 cursor-pointer hover:text-gray-700",
|
|
187
|
-
disabled: "bg-opacity-60 cursor-not-allowed text-gray-200 bg-gray-800",
|
|
188
|
-
},
|
|
189
|
-
black: {
|
|
190
|
-
enabled: "text-black cursor-pointer",
|
|
191
|
-
disabled: "cursor-not-allowed text-gray-300",
|
|
192
|
-
},
|
|
193
|
-
success: {
|
|
194
|
-
enabled: "text-green-600 cursor-pointer",
|
|
195
|
-
disabled: "cursor-not-allowed text-green-700/60",
|
|
196
|
-
},
|
|
197
|
-
purple: {
|
|
198
|
-
enabled: "text-purple-600 cursor-pointer",
|
|
199
|
-
disabled: "cursor-not-allowed text-purple-400",
|
|
200
|
-
},
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
const iconClasses = {
|
|
204
|
-
lg: props.iconType === "icon" ? "p-3" : "px-6 py-3",
|
|
205
|
-
md: props.iconType === "icon" ? "p-2" : "px-4 py-2",
|
|
206
|
-
sm: props.iconType === "icon" ? "p-1.5" : "px-4 py-1.5",
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
const iconWidthClasses = reactive({
|
|
210
|
-
sm: "w-5 h-5 text-current",
|
|
211
|
-
md: "w-6 h-6 text-current",
|
|
212
|
-
lg: "w-6 h-6 text-current",
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
const iconWidth = computed(() => {
|
|
216
|
-
return iconWidthClasses[props.size] || "";
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
const getBtnClass = (btnName: string) => {
|
|
220
|
-
const isActive = btnName === activeBtnName.value;
|
|
221
|
-
const colorKey = isActive ? props.activeColor : "default";
|
|
222
|
-
const state = props.disabled ? "disabled" : "enabled";
|
|
223
|
-
const colorClass = btnColors[colorKey] ? btnColors[colorKey][state] : "";
|
|
224
|
-
const sizeClass = props.size === "sm" ? "text-sm" : "text-base";
|
|
225
|
-
const typeClass = iconClasses[props.size] || "";
|
|
226
|
-
return `${colorClass} ${sizeClass} ${typeClass}`;
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
const allColor = {
|
|
230
|
-
purple: "#7c3aed",
|
|
231
|
-
success: "#16a34a",
|
|
232
|
-
black: "#000",
|
|
233
|
-
default: "#9ca3af",
|
|
234
|
-
};
|
|
235
|
-
</script>
|
|
236
|
-
|
|
237
|
-
<style lang="scss">
|
|
238
|
-
:root {
|
|
239
|
-
--clr: theme("colors.white");
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
#tab-indicator {
|
|
243
|
-
transition: all 350ms cubic-bezier(0.15, 0.3, 0.25, 1);
|
|
244
|
-
background-image: linear-gradient(90deg, #fff, #fff),
|
|
245
|
-
linear-gradient(to top, #e5e7eb, #e5e7eb, var(--border));
|
|
246
|
-
background-origin: border-box;
|
|
247
|
-
background-clip: padding-box, border-box;
|
|
248
|
-
@apply absolute left-0 w-auto h-full top-0 -z-[1] rounded-t-xl border-solid border-t-2 border bg-white p-2 border-transparent;
|
|
249
|
-
&::before {
|
|
250
|
-
content: "";
|
|
251
|
-
box-shadow: 5px 5px 0 5px var(--clr);
|
|
252
|
-
@apply absolute -bottom-px -left-3 size-3 bg-transparent border border-gray-200 border-solid border-l-0 border-t-0 rounded-br-2xl;
|
|
253
|
-
}
|
|
254
|
-
&::after {
|
|
255
|
-
content: "";
|
|
256
|
-
box-shadow: -5px 5px 0 5px var(--clr);
|
|
257
|
-
@apply absolute -bottom-px -right-3 size-3 bg-transparent border border-gray-200 border-solid border-r-0 border-t-0 rounded-bl-2xl;
|
|
258
|
-
}
|
|
259
|
-
span {
|
|
260
|
-
@apply bg-white w-full h-1 absolute -bottom-px inset-x-0 z-[1];
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
</style>
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<div
|
|
4
|
-
v-if="tabStyle === 'design'"
|
|
5
|
-
class="inline-flex flex-row items-center justify-start px-[0.25rem] min-h-[34px] mb-0.5 bg-gray-100 rounded-[0.625rem] ring-1 ring-gray-200/75 gap-2 overflow-x-auto scrollbar--hide whitespace-nowrap max-w-full"
|
|
6
|
-
>
|
|
7
|
-
<template v-for="(tab, tabindex) in tabs" :key="tabindex">
|
|
8
|
-
<button
|
|
9
|
-
type="button"
|
|
10
|
-
:id="`id-${tab.name}`"
|
|
11
|
-
:disabled="tab?.disabled"
|
|
12
|
-
:title="tab?.toolTipText"
|
|
13
|
-
class="[&:not(:focus-visible)]:focus:outline-none relative w-max inline-flex items-center transition-colors duration-100 h-7"
|
|
14
|
-
:class="[
|
|
15
|
-
tab?.disabled ? ' cursor-not-allowed ' : '',
|
|
16
|
-
isHighlighedActivetab ? ' rounded-t-lg !bg-[#EDE9FE] ' : '',
|
|
17
|
-
'flex-shrink-0'
|
|
18
|
-
]"
|
|
19
|
-
role="tab"
|
|
20
|
-
tabindex="-1"
|
|
21
|
-
@click="selectTab(tabindex)"
|
|
22
|
-
>
|
|
23
|
-
<div
|
|
24
|
-
class="pointer-events-none absolute inset-0 transition-transform duration-200 transform z-[1] ease-in-out"
|
|
25
|
-
:class="{
|
|
26
|
-
'translate-x-full': tabindex < activeTabIndex,
|
|
27
|
-
'-translate-x-full': tabindex > activeTabIndex,
|
|
28
|
-
'translate-x-0 rounded-lg bg-white ring-1 ring-gray-200/75': activeTabIndex === tabindex,
|
|
29
|
-
}"
|
|
30
|
-
/>
|
|
31
|
-
<span
|
|
32
|
-
:class="[
|
|
33
|
-
'w-full px-2 py-1 text-xs tracking-wide z-10 flex items-center justify-start gap-2',
|
|
34
|
-
activeTabIndex === tabindex
|
|
35
|
-
? ' text-gray-800 font-semibold'
|
|
36
|
-
: ' text-gray-600 font-medium hover:text-gray-600 rounded-lg bg-transparent z-0 transition-colors duration-300 ease-in origin-center',
|
|
37
|
-
]"
|
|
38
|
-
>
|
|
39
|
-
<slot
|
|
40
|
-
name="title"
|
|
41
|
-
:tab="tab"
|
|
42
|
-
:tabIndex="tabindex"
|
|
43
|
-
:activeTab="activeTabIndex"
|
|
44
|
-
>
|
|
45
|
-
{{ tab?.name }}
|
|
46
|
-
</slot>
|
|
47
|
-
</span>
|
|
48
|
-
</button>
|
|
49
|
-
|
|
50
|
-
<div v-if="tabindex !== tabs.length -1" :class="['self-stretch w-px h-4 my-2',
|
|
51
|
-
tabindex === activeTabIndex - 1 ? 'bg-transparent' : activeTabIndex === tabindex ? 'bg-transparent': 'bg-gray-300']"></div>
|
|
52
|
-
</template>
|
|
53
|
-
|
|
54
|
-
</div>
|
|
55
|
-
<div
|
|
56
|
-
v-else-if="tabStyle === 'border'"
|
|
57
|
-
class="flex items-center gap-1 before:bottom-0 before:left-0 before:absolute before:content-[''] before:h-px before:w-full before:bg-gray-200 relative before:-z-[1] z-0 bg-white"
|
|
58
|
-
:class="[
|
|
59
|
-
tabAlign === 'justify'
|
|
60
|
-
? 'justify-between'
|
|
61
|
-
: tabAlign === 'end'
|
|
62
|
-
? 'justify-end'
|
|
63
|
-
: 'justify-start',
|
|
64
|
-
]"
|
|
65
|
-
>
|
|
66
|
-
<button
|
|
67
|
-
v-for="(tab, tabindex) in tabs"
|
|
68
|
-
:disabled="tab?.disabled"
|
|
69
|
-
:title="tab?.toolTipText"
|
|
70
|
-
:key="tabindex"
|
|
71
|
-
type="button"
|
|
72
|
-
role="tab"
|
|
73
|
-
:id="`id-${tab.name}`"
|
|
74
|
-
:class="[
|
|
75
|
-
'px-3 py-1 leading-5 transition-all duration-150 ease-in-out hover:text-gray-800',
|
|
76
|
-
tabSize === 'sm'
|
|
77
|
-
? 'text-sm font-semibold border-b-2'
|
|
78
|
-
: 'text-base font-bold border-b-[3px]',
|
|
79
|
-
activeTabIndex === tabindex
|
|
80
|
-
? 'border-gray-900 text-gray-900'
|
|
81
|
-
: 'border-transparent text-gray-500',
|
|
82
|
-
tab?.disabled ? ' cursor-not-allowed ' : '',
|
|
83
|
-
isHighlighedActivetab&&activeTabIndex === tabindex ? ' rounded-t-lg !bg-[#EDE9FE]' : '',
|
|
84
|
-
'flex-shrink-0'
|
|
85
|
-
]"
|
|
86
|
-
@click="selectTab(tabindex)"
|
|
87
|
-
>
|
|
88
|
-
<slot
|
|
89
|
-
name="title"
|
|
90
|
-
:tab="tab"
|
|
91
|
-
:tabIndex="tabindex"
|
|
92
|
-
:activeTab="activeTabIndex"
|
|
93
|
-
>
|
|
94
|
-
{{ tab?.name }}
|
|
95
|
-
</slot>
|
|
96
|
-
</button>
|
|
97
|
-
</div>
|
|
98
|
-
<div
|
|
99
|
-
v-else-if="tabStyle === 'shadow'"
|
|
100
|
-
class="justify-start relative z-0 inline-flex items-center gap-0 bg-white/50 rounded-t-lg shadow-[0px_1px_2px_0px_rgba(55,65,81,0.10)]"
|
|
101
|
-
>
|
|
102
|
-
<button
|
|
103
|
-
v-for="(tab, tabindex) in tabs"
|
|
104
|
-
:disabled="tab?.disabled"
|
|
105
|
-
:title="tab?.toolTipText"
|
|
106
|
-
:key="tabindex"
|
|
107
|
-
type="button"
|
|
108
|
-
role="tab"
|
|
109
|
-
:id="`id-${tab.name}`"
|
|
110
|
-
:class="[
|
|
111
|
-
'px-3 py-1 leading-5 transition-all duration-150 ease-in-out hover:text-gray-800 h-12 rounded-t-lg',
|
|
112
|
-
tabSize === 'sm'
|
|
113
|
-
? 'text-sm font-medium border-b-2'
|
|
114
|
-
: 'text-base font-semibold border-b-[3px]',
|
|
115
|
-
activeTabIndex === tabindex
|
|
116
|
-
? 'border-purple-800 text-purple-800 bg-white z-10 rounded-t-lg shadow-[0px_2px_4px_0px_rgba(55,65,81,0.1)]'
|
|
117
|
-
: 'border-transparent text-gray-500 z-0',
|
|
118
|
-
tab?.disabled ? ' cursor-not-allowed ' : '',
|
|
119
|
-
isHighlighedActivetab&&activeTabIndex === tabindex ? ' rounded-t-lg !bg-[#EDE9FE]' : '',
|
|
120
|
-
'flex-shrink-0'
|
|
121
|
-
]"
|
|
122
|
-
@click="selectTab(tabindex)"
|
|
123
|
-
>
|
|
124
|
-
<slot
|
|
125
|
-
name="title"
|
|
126
|
-
:tab="tab"
|
|
127
|
-
:tabIndex="tabindex"
|
|
128
|
-
:activeTab="activeTabIndex"
|
|
129
|
-
>
|
|
130
|
-
{{ tab?.name }}
|
|
131
|
-
</slot>
|
|
132
|
-
</button>
|
|
133
|
-
</div>
|
|
134
|
-
<div v-else class="flex items-center gap-1 p-2 transition-all duration-100">
|
|
135
|
-
<button
|
|
136
|
-
v-for="(tab, tabindex) in tabs"
|
|
137
|
-
:disabled="tab?.disabled"
|
|
138
|
-
:title="tab?.toolTipText"
|
|
139
|
-
:key="tabindex"
|
|
140
|
-
type="button"
|
|
141
|
-
role="tab"
|
|
142
|
-
:id="`id-${tab.name}`"
|
|
143
|
-
class="px-4 py-1 text-sm font-semibold transition-colors duration-150 ease-in-out border rounded-full"
|
|
144
|
-
:class="[
|
|
145
|
-
activeTabIndex === tabindex
|
|
146
|
-
? 'shadow-lg shadow-gray-100 bg-white border-gray-200 focus-within:border-purple-600 text-gray-900'
|
|
147
|
-
: 'border-white hover:bg-gray-50 text-gray-700',
|
|
148
|
-
tab?.disabled ? ' cursor-not-allowed ' : '',
|
|
149
|
-
isHighlighedActivetab&&activeTabIndex === tabindex ? ' rounded-t-lg !bg-[#EDE9FE]' : '',
|
|
150
|
-
'flex-shrink-0'
|
|
151
|
-
]"
|
|
152
|
-
@click="selectTab(tabindex)"
|
|
153
|
-
>
|
|
154
|
-
<slot
|
|
155
|
-
name="title"
|
|
156
|
-
:tab="tab"
|
|
157
|
-
:tabIndex="tabindex"
|
|
158
|
-
:activeTab="activeTabIndex"
|
|
159
|
-
>
|
|
160
|
-
{{ tab?.name }}
|
|
161
|
-
</slot>
|
|
162
|
-
</button>
|
|
163
|
-
</div>
|
|
164
|
-
<slot name="content" :active-tab="tabs[activeTabIndex]">
|
|
165
|
-
<div
|
|
166
|
-
:class="[
|
|
167
|
-
'py-2 text-base font-normal text-gray-700 bg-white relative',
|
|
168
|
-
contentClass,
|
|
169
|
-
{
|
|
170
|
-
'rounded-lg !rounded-tl-none shadow-[0px_-2px_24px_0px_rgba(0,0,0,0.075)] z-20':
|
|
171
|
-
tabStyle === 'shadow',
|
|
172
|
-
},
|
|
173
|
-
]"
|
|
174
|
-
>
|
|
175
|
-
{{ tabs[activeTabIndex]?.content }}
|
|
176
|
-
</div>
|
|
177
|
-
</slot>
|
|
178
|
-
</div>
|
|
179
|
-
</template>
|
|
180
|
-
|
|
181
|
-
<script setup lang="ts">
|
|
182
|
-
import { defineProps, ref, watch } from "vue";
|
|
183
|
-
|
|
184
|
-
interface Tab {
|
|
185
|
-
name: string;
|
|
186
|
-
content?: string;
|
|
187
|
-
disabled?: boolean;
|
|
188
|
-
toolTipText?: string;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const props = defineProps<{
|
|
192
|
-
tabs: Tab[];
|
|
193
|
-
defaultActiveIndex?: number;
|
|
194
|
-
tabStyle: "rounded" | "border" | "design" | "shadow";
|
|
195
|
-
contentClass?: string[] | string;
|
|
196
|
-
tabSize?: "sm" | "md";
|
|
197
|
-
tabAlign?: "start" | "justify" | "end";
|
|
198
|
-
isHighlighedActivetab?: boolean;
|
|
199
|
-
}>();
|
|
200
|
-
|
|
201
|
-
const emit = defineEmits<{
|
|
202
|
-
(event: "update:activeTab", activeTab: Tab): void;
|
|
203
|
-
(event: "update:defaultActiveIndex", defaultActiveIndex: number): void;
|
|
204
|
-
}>();
|
|
205
|
-
|
|
206
|
-
const activeTabIndex = ref(props.defaultActiveIndex ?? 0);
|
|
207
|
-
|
|
208
|
-
const selectTab = (index: number) => {
|
|
209
|
-
activeTabIndex.value = index;
|
|
210
|
-
emit("update:defaultActiveIndex", activeTabIndex.value );
|
|
211
|
-
emit("update:activeTab", props.tabs[activeTabIndex.value]);
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
watch(
|
|
215
|
-
() => props.defaultActiveIndex,
|
|
216
|
-
(newIndex) => {
|
|
217
|
-
activeTabIndex.value = newIndex ?? 0;
|
|
218
|
-
},{
|
|
219
|
-
immediate:true
|
|
220
|
-
}
|
|
221
|
-
);
|
|
222
|
-
</script>
|
|
223
|
-
|
|
224
|
-
<style scoped>
|
|
225
|
-
/* Add any scoped styles if needed */
|
|
226
|
-
</style>
|