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.
Files changed (69) hide show
  1. package/package.json +10 -3
  2. package/src/App.vue +0 -16
  3. package/src/assets/svg/CheckTick.vue +0 -21
  4. package/src/assets/svg/ChevronBigDown.vue +0 -22
  5. package/src/assets/svg/ChevronDownSolid.vue +0 -19
  6. package/src/assets/svg/ChevronDownStroke.vue +0 -22
  7. package/src/assets/svg/ChevronDownStrokeSolid.vue +0 -19
  8. package/src/assets/svg/SearchBigZoomIn.vue +0 -21
  9. package/src/assets/svg/SortArrow.vue +0 -24
  10. package/src/assets/svg/Student.vue +0 -30
  11. package/src/assets/svg/partner.vue +0 -33
  12. package/src/assets/svg/people.vue +0 -25
  13. package/src/components/HelloWorld.vue +0 -1974
  14. package/src/components/accordion/EUIAccordion.vue +0 -152
  15. package/src/components/alerts/EUIAlerts.vue +0 -194
  16. package/src/components/avatar/EUIAvatar.vue +0 -96
  17. package/src/components/breadcrumb/EUIBreadcrumb.vue +0 -59
  18. package/src/components/button/EUIButton.vue +0 -154
  19. package/src/components/button/EUIButtonGroup.vue +0 -287
  20. package/src/components/button/buttonAnimateTab.vue +0 -74
  21. package/src/components/checkbox/EUICheckbox.vue +0 -110
  22. package/src/components/datepicker/EUIDatepicker.vue +0 -295
  23. package/src/components/delete.vue +0 -262
  24. package/src/components/dragModal/EUIDrag.vue +0 -179
  25. package/src/components/dropdown/EUIMultiDropdown.vue +0 -174
  26. package/src/components/errorMessage/EUIErrorMessage.vue +0 -25
  27. package/src/components/input/EUIInput.vue +0 -223
  28. package/src/components/input/EUINumberInput.vue +0 -250
  29. package/src/components/loader/EUICircleLoader.vue +0 -31
  30. package/src/components/loader/EUICubeLoader.vue +0 -237
  31. package/src/components/loader/EUILoader.vue +0 -17
  32. package/src/components/loader/EUISquareLoader.vue +0 -47
  33. package/src/components/modal/EUIModal.vue +0 -224
  34. package/src/components/pillSelect/EUIPillSelect.vue +0 -149
  35. package/src/components/popover/EUIPopover.vue +0 -297
  36. package/src/components/radio/EUIRadio.vue +0 -75
  37. package/src/components/searchInput/EUISearch.vue +0 -223
  38. package/src/components/searchTagSelect/EUISearchTagSelect.vue +0 -642
  39. package/src/components/searchTagSelect/SearchInput.vue +0 -167
  40. package/src/components/searchexpand/EUISearchExpand.vue +0 -148
  41. package/src/components/searchexpand/EUISearchToggle.vue +0 -86
  42. package/src/components/select/EUISelect.vue +0 -1092
  43. package/src/components/selectSearch/EUISelectSearch.vue +0 -23
  44. package/src/components/slideover/EUISlideover.vue +0 -207
  45. package/src/components/stepperTimeline/EUIStepperHorizontal.vue +0 -242
  46. package/src/components/stepperTimeline/EUIStepperTimeline.vue +0 -16
  47. package/src/components/stepperTimeline/EUIStepperVertical.vue +0 -112
  48. package/src/components/table/ColumnResizeTable.vue +0 -740
  49. package/src/components/table/EUIDashboardTable.vue +0 -514
  50. package/src/components/table/EUIPageLimit.vue +0 -66
  51. package/src/components/table/EUIPagination.vue +0 -175
  52. package/src/components/table/EUIStudentPagination.vue +0 -172
  53. package/src/components/table/EUITable.vue +0 -559
  54. package/src/components/table/EUITableCheckbox.vue +0 -98
  55. package/src/components/table/GrowthTable.vue +0 -575
  56. package/src/components/table/GrowthTableView.vue +0 -108
  57. package/src/components/table/ResizeTableview.vue +0 -198
  58. package/src/components/table/UCheckbox.vue +0 -169
  59. package/src/components/table/UTable.vue +0 -611
  60. package/src/components/table/UTableview.vue +0 -189
  61. package/src/components/tabs/EUITabOutline.vue +0 -263
  62. package/src/components/tabs/EUITabs.vue +0 -226
  63. package/src/components/tag/EUITag.vue +0 -88
  64. package/src/components/telephone/EUITelephone.vue +0 -299
  65. package/src/components/textArea/EUITextArea.vue +0 -155
  66. package/src/components/timeLine/EUITimeLine.vue +0 -148
  67. package/src/components/toggle/EUIToggle.vue +0 -101
  68. package/src/components/tooltip/EUITooltip.vue +0 -111
  69. package/src/components/uidemo/select-com.vue +0 -120
@@ -1,88 +0,0 @@
1
- <template>
2
- <div
3
- :class="[
4
- 'inline-flex items-center max-w-xs w-auto',
5
- {'pointer-events-none select-none': disabled},
6
- tagClass
7
- ]"
8
- >
9
- <div class="text-current truncate cursor-pointer" :class="[props.size === 'lg'? 'text-base font-semibold':'text-sm font-medium']"><slot /></div>
10
- <button
11
- v-if="closeIcon"
12
- type="button"
13
- class="relative -mr-1 rounded group hover:bg-red-300/50 active:bg-red-300"
14
- :class="[props.size === 'lg' ? 'size-6' : props.size === 'md'? 'size-5' : 'size-3.5']"
15
- @click.stop="removeTag"
16
- >
17
- <span class="sr-only">Remove</span>
18
- <svg
19
- viewBox="0 0 14 14"
20
- class="stroke-gray-400 group-hover:stroke-red-600/75"
21
- >
22
- <path d="M4 4l6 6m0-6l-6 6" />
23
- </svg>
24
- </button>
25
- </div>
26
- </template>
27
-
28
- <script setup lang="ts">
29
- import { computed, PropType, reactive, toRefs } from "vue";
30
-
31
- const props = defineProps({
32
- closeIcon: {
33
- type: Boolean,
34
- default: false,
35
- },
36
- errors: { type: Object, required: false, default: () => {} },
37
- disabled: {
38
- type: Boolean,
39
- default: false,
40
- },
41
- size: {
42
- type: String as PropType<"sm" | "md" | "lg">, //28,40, 48
43
- default: "sm",
44
- },
45
- color: {
46
- type: String as PropType<
47
- "white" | "secondary" | 'tertiary'>,
48
- default: "tertiary",
49
- },
50
- });
51
- const { closeIcon } = toRefs(props);
52
- const emit = defineEmits(["remove"]);
53
-
54
- const removeTag = () => {
55
- emit("remove");
56
- };
57
-
58
- const sizeClasses = reactive({
59
- sm: "px-2 py-1 rounded-md gap-x-1", // 32
60
- md: "px-4 py-2 rounded-full gap-2", // 40
61
- lg: "px-6 py-3 rounded-full gap-2", // 48
62
- });
63
-
64
- const tagClass = computed(() => {
65
- const btnDisabled = props.disabled;
66
- const btnColor = {
67
- white: btnDisabled
68
- ? "bg-opacity-80 cursor-not-allowed text-gray-400 bg-gray-200"
69
- : "bg-white hover:bg-gray-100 text-black cursor-pointer active:shadow-white/50 active:bg-transparent",
70
- secondary: btnDisabled
71
- ? "bg-opacity-75 cursor-not-allowed text-gray-400 bg-purple-50"
72
- : "bg-purple-100 hover:bg-purple-50 active:bg-purple-100 cursor-pointer text-gray-700 active:shadow-purple-200",
73
- tertiary: btnDisabled
74
- ? "bg-opacity-75 cursor-not-allowed text-gray-400 bg-gray-50 ring-1 ring-gray-400/20"
75
- : "bg-gray-100 hover:bg-gray-50 active:bg-gray-100 text-gray-700 cursor-pointer active:shadow-bg-gray-200/50 ring-1 ring-gray-200",
76
- }
77
- const disabledClass =
78
- props.disabled === true
79
- ? "active:!translate-y-0 active:!scale-100 active:!shadow-none"
80
- : "";
81
-
82
- const colorClass = btnColor[props.color] || "";
83
- const sizeClass = sizeClasses[props.size] || "";
84
- return `${colorClass} ${sizeClass} ${disabledClass}`;
85
- })
86
- </script>
87
-
88
- <style scoped></style>
@@ -1,299 +0,0 @@
1
- <template>
2
- <div class="relative z-[calc(infinity)]">
3
- <label
4
- v-if="!inputFilled && label"
5
- :class="[
6
- 'text-xs w-full text-gray-500 cursor-pointer font-medium',
7
- required && `after:content-['*'] after:ml-0.5 after:text-red-500`,
8
- ]"> {{ label }} </label>
9
-
10
- <button
11
- type="button"
12
- :class="[disabled ? 'pointer-events-none cursor-not-allowed bg-gray-50' : 'bg-white', inputFilled ? 'h-14 rounded-2xl' : 'h-10 rounded-md', 'relative w-full mb-2 border border-gray-200 cursor-pointer z-1 group focus-within:border-purple-600 focus-within:ring-1 focus-within:ring-purple-600']"
13
- @click="focusInput"
14
- >
15
- <label
16
- v-if="inputFilled"
17
- :for="`${name}-${id}`"
18
- :class="[
19
- getIconClass(),
20
- inputValue
21
- ? 'top-3.5 text-xs text-gray-400 leading-none cursor-default'
22
- : 'top-1/2 text-sm w-full text-gray-700 cursor-pointer h-14 pt-5 pb-4 bg-white ring-1 ring-gray-200',
23
- disabled ? ' cursor-not-allowed' : '',
24
- required && `after:content-['*'] after:ml-0.5 after:text-red-500`,
25
- ]"
26
- class="absolute font-medium left-0 px-4 z-[1] -translate-y-1/2 duration-200 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 text-start first-letter:capitalize"
27
- >
28
- {{ label }}
29
- </label>
30
- <div
31
- v-if="icon && iconType"
32
- class="absolute inset-y-0 z-10 flex items-center pointer-events-none"
33
- :class="[
34
- iconType === 'startIcon' ? 'start-0 ps-3' : 'end-0 pe-3',
35
- disabled ? 'cursor-not-allowed' : '',
36
- ]"
37
- >
38
- <component
39
- :is="icon"
40
- class="text-gray-400 size-6"
41
- aria-hidden="true"
42
- />
43
- </div>
44
- <vue-tel-input
45
- ref="inputRef"
46
- v-model.trim="mobile"
47
- v-bind="bindProps"
48
- :class="[getIconClass()]"
49
- @on-input="onInputChanged"
50
- @country-changed="onCountryChanged"
51
- @blur="$emit('blur')"
52
- ></vue-tel-input>
53
- </button>
54
-
55
- <div class="errors" v-if="errorMessage">
56
- <p class="mt-2 text-xs text-red-500">
57
- {{ errorMessage }}
58
- </p>
59
- </div>
60
- <div
61
- class="absolute top-0 px-2 text-xs text-white rounded right-2"
62
- :class="[
63
- { 'bg-gray-400': tagColor === 'None' },
64
- { 'bg-green-400': tagColor === 'Success' },
65
- { 'bg-red-400': tagColor === 'Error' },
66
- ]"
67
- v-if="tag"
68
- >
69
- {{ tag }}
70
- </div>
71
- </div>
72
-
73
- </template>
74
- <script lang="ts" setup>
75
- import { computed, onUpdated, PropType, ref, toRefs, watch } from "vue";
76
- import { VueTelInput, VueTelInputCountryOption } from "vue-tel-input";
77
- import "vue-tel-input/vue-tel-input.css";
78
- const emit = defineEmits(["update:modelValue", "blur", "update:isValid"]);
79
- const props = defineProps({
80
- modelValue: {
81
- type: [String, Number],
82
- default: "",
83
- },
84
- name: {
85
- type: String,
86
- default: "",
87
- },
88
- label: {
89
- type: String,
90
- default: "Mobile Number"
91
- },
92
- placeholder: {
93
- type: String,
94
- },
95
- required: {
96
- type: Boolean,
97
- default: false,
98
- },
99
- readonly: {
100
- type: Boolean,
101
- },
102
- disabled: {
103
- type: Boolean,
104
- },
105
- autoFocus: {
106
- type: Boolean,
107
- required: false,
108
- default: false,
109
- },
110
- errors: { type: Object, required: false, default: () => {} },
111
- isValid: {
112
- type: Boolean,
113
- default: false,
114
- },
115
- tag: {
116
- type: String,
117
- default: "",
118
- },
119
- tagColor: {
120
- type: String as PropType<"None" | "Success" | "Error">,
121
- default: "None",
122
- },
123
- length: {
124
- type: Number,
125
- required: false,
126
- default: 25,
127
- },
128
- iconType: {
129
- type: String as PropType<"startIcon" | "endIcon">,
130
- default: "",
131
- },
132
- icon: {
133
- type: [Object, String],
134
- default: "",
135
- },
136
- inputFilled: {
137
- type:Boolean,
138
- default: false
139
- }
140
- });
141
- const { isValid } = toRefs(props);
142
-
143
- const generateUID = () => {
144
- const data = "euid-" + Math.random().toString(36).substr(2, 9) + "-" + Date.now().toString(36);
145
- return data;
146
- };
147
- const id = generateUID();
148
-
149
- const hasError = computed({
150
- set: (value) => {
151
- emit("update:isValid", value);
152
- },
153
- get: () => isValid.value,
154
- });
155
-
156
- const inputValue = computed(() => {
157
- return props.modelValue === 0 ? true : !!props.modelValue;
158
- });
159
-
160
- const mobile = ref(props.modelValue);
161
- const listener = computed(() => props.modelValue);
162
- watch(listener, (value) => {
163
- mobile.value = value;
164
- });
165
-
166
- const updateValue = computed(() => {
167
- return {
168
- focus: props.autoFocus,
169
- place: props.placeholder,
170
- disabled: props.disabled,
171
- required: props.required,
172
- name: props.name,
173
- length: props.length,
174
- readonly: props.readonly
175
- };
176
- });
177
-
178
- const bindProps = {
179
- mode: "international",
180
- autoFormat: false,
181
- autoDefaultCountry: true,
182
- styleClasses: "eui-tel",
183
- invalidMsg: "Required mobile number",
184
- validCharactersOnly: true,
185
- preferredCountries: [],
186
- disabled: updateValue.value.disabled,
187
- inputOptions: {
188
- autocomplete: "off",
189
- autofocus: updateValue.value.focus,
190
- name: updateValue.value.name,
191
- id: id,
192
- placeholder: updateValue.value.place,
193
- maxlength: updateValue.value.length,
194
- showDialCode: true,
195
- tabindex: 0,
196
- readonly: updateValue.value.readonly,
197
- required: updateValue.value.required,
198
- styleClasses: "eui-tel_input",
199
- },
200
- dropdownOptions: {
201
- disabled: updateValue.value.readonly || updateValue.value.disabled,
202
- showFlags: true,
203
- showDialCodeInList: true,
204
- showSearchBox: true,
205
- searchBoxPlaceholder: "Search country...",
206
- },
207
- };
208
-
209
- const onInputChanged = (_formattedNumber: string, phoneObject: any) => {
210
- hasError.value = phoneObject.valid ? true : false;
211
- emit("update:modelValue", phoneObject.number);
212
- };
213
-
214
- const firstTime = ref(true);
215
- const onCountryChanged = (_event: VueTelInputCountryOption) => {
216
- if (!firstTime.value) {
217
- emit("update:modelValue", "");
218
- }
219
- };
220
-
221
- onUpdated(() => {
222
- setTimeout(() => {
223
- firstTime.value = false;
224
- }, 1500);
225
- });
226
-
227
- const errorMessage = computed(() => {
228
- if (Array.isArray(props.errors)) {
229
- if (typeof props.errors?.at(0) === "object") {
230
- return props.errors?.at(0)?.$message;
231
- } else {
232
- return props.errors[0];
233
- }
234
- } else {
235
- if (typeof props.errors === "object") {
236
- return props.errors?.[props.name];
237
- } else {
238
- return props.errors;
239
- }
240
- }
241
- });
242
-
243
- const getIconClass = () => {
244
- switch (props.iconType) {
245
- case "startIcon":
246
- return props.inputFilled ? "pl-12 pr-4" : "normal pl-10 pr-4";
247
- case "endIcon":
248
- return props.inputFilled ? "pr-12 pl-4" : "normal pr-10 pl-4";
249
- default:
250
- return props.inputFilled ? "px-4" : "normal px-4";
251
- }
252
- };
253
-
254
- const inputRef = ref<HTMLElement | null>(null);
255
- const focusInput = () => {
256
- if (inputRef.value) {
257
- inputRef.value?.focus();
258
- }
259
- };
260
- </script>
261
-
262
- <style lang="scss">
263
- .vue-tel-input.eui-tel {
264
- @apply rounded-none border-none focus-within:shadow-none focus-within:border-transparent;
265
- .vti__dropdown {
266
- @apply mt-4 p-2 ps-0 rounded-2xl hover:bg-transparent open:bg-transparent bg-transparent;
267
- }
268
- .vti__dropdown-list {
269
- @apply rounded-md;
270
- .vti__search_box_container {
271
- @apply sticky top-0 left-0 p-1 pr-0 bg-white;
272
- }
273
- .vti__dropdown-item {
274
- @apply text-sm text-gray-700 hover:text-gray-900;
275
- strong {
276
- @apply font-medium;
277
- }
278
- &.highlighted {
279
- @apply bg-gray-100;
280
- }
281
- }
282
- }
283
- .vti__search_box {
284
- @apply w-[98%] rounded-[4px] placeholder:text-sm;
285
- }
286
- .eui-tel_input {
287
- @apply z-0 h-full w-full pt-6 pb-3 placeholder:text-gray-400 focus:outline-none block text-sm font-medium appearance-none focus:border-purple-600 autofill:bg-white leading-6 disabled:opacity-75 disabled:bg-transparent;
288
- }
289
- }
290
-
291
- .vue-tel-input.eui-tel.normal {
292
- .vti__dropdown {
293
- @apply mt-0 p-2 ps-0 hover:bg-transparent open:bg-transparent bg-transparent;
294
- }
295
- .eui-tel_input {
296
- @apply rounded-md py-2;
297
- }
298
- }
299
- </style>
@@ -1,155 +0,0 @@
1
- <template>
2
- <div class="relative">
3
- <button
4
- v-if="inputFilled"
5
- :class="[
6
- disabled ? 'pointer-events-none cursor-not-allowed bg-gray-50' : '',
7
- 'group transition-all duration-100 ease-in-out outline-none border-none z-0 focus:border-purple-600 min-h-[4.5rem] mb-2 relative w-full rounded-md ring-1 ring-gray-200 focus-within:ring-2 focus-within:ring-purple-600 cursor-pointer overflow-hidden;',
8
- ]"
9
- @click="focusInput"
10
- >
11
- <label
12
- for="text"
13
- :class="[
14
- inputValue
15
- ? 'top-2 text-xs text-gray-400 cursor-default'
16
- : 'top-4 text-sm text-gray-700 cursor-pointer pb-2',
17
- disabled ? 'cursor-not-allowed bg-gray-50' : 'bg-white',
18
- required && `after:content-['*'] after:ml-0.5 after:text-red-500`,
19
- 'absolute left-0 z-10 w-full h-auto px-4 font-medium leading-normal text-left transition-all duration-300 ease-in-out transform translate-y-0 group-focus-within:top-2 group-focus-within:bg-transparent group-focus-within:py-0 group-focus-within:h-auto'
20
- ]"
21
- >
22
- {{ label }}
23
- </label>
24
- <textarea
25
- ref="inputRef"
26
- :class="['min-h-[4.5rem] max-h-40 appearance-none block w-full px-4 py-2 placeholder:text-gray-400 text-sm font-medium relative z-0 mt-4 bg-transparent border-none focus:outline-none focus:shadow-none focus-within:outline-none focus:border-none disabled:opacity-75 autofill:bg-white leading-6 placeholder:capitalize rounded-2xl' ,{'border-red-500': errors}]"
27
- :placeholder="placeholder"
28
- v-model="localValue"
29
- :disabled="disabled"
30
- :readonly="readonly"
31
- :autofocus="autoFocus"
32
- aria-invalid="true"
33
- :rows="rows"
34
- :cols="cols"
35
- @input="$emit('update:modelValue', localValue)"
36
- @blur="$emit('blur')"
37
- >
38
- </textarea>
39
- </button>
40
-
41
- <div v-else>
42
- <label
43
- v-if="label"
44
- :class="['text-xs w-full text-gray-500 cursor-pointer font-medium', required && `after:content-['*'] after:ml-0.5 after:text-red-500`]">
45
- {{ label }}
46
- </label>
47
- <textarea
48
- ref="inputRef"
49
- :class="['min-h-[4.5rem] max-h-40 appearance-none block w-full px-4 py-2 placeholder:text-gray-400 text-sm font-medium relative z-0 bg-transparent border-gray-200 focus:outline-none focus:shadow-none focus-within:outline-none focus:border-purple-600 disabled:opacity-75 autofill:bg-white leading-6 placeholder:capitalize rounded-md border-solid border focus-within:ring-1 focus-within:ring-purple-600 transition-colors duration-300 ease-in-out',{'border-red-500': errors}]"
50
- v-model="localValue"
51
- :placeholder="placeholder"
52
- :disabled="disabled"
53
- :readonly="readonly"
54
- :autofocus="autoFocus"
55
- aria-invalid="true"
56
- :rows="rows"
57
- :cols="cols"
58
- @input="$emit('update:modelValue', localValue)"
59
- @blur="$emit('blur')"
60
- >
61
- </textarea>
62
- </div>
63
- </div>
64
- <template v-if="errors && Object.keys(errors).length">
65
- <EUIErrorMessage :errors="errors" :name="name" />
66
- </template>
67
- </template>
68
- <script setup lang="ts">
69
- import { PropType, ref, watch, computed } from "vue";
70
- import { ValidationErrors } from "../../utils/types";
71
- import EUIErrorMessage from "../errorMessage/EUIErrorMessage.vue";
72
-
73
- const props = defineProps({
74
- errors: {
75
- type: Object as PropType<ValidationErrors>,
76
- required: false,
77
- default: () => {},
78
- },
79
- modelValue: {
80
- type: String as PropType<string>,
81
- required: true,
82
- default: "",
83
- },
84
- name: {
85
- type: String,
86
- required: false,
87
- default: "",
88
- },
89
- label: {
90
- type: String as PropType<string>,
91
- required: true,
92
- default: "",
93
- },
94
- placeholder: {
95
- type: String as PropType<string>,
96
- required: true,
97
- default: "",
98
- },
99
- rows: {
100
- type: Number as PropType<number>,
101
- required: true,
102
- default: 5,
103
- },
104
- cols: {
105
- type: Number as PropType<number>,
106
- required: true,
107
- default: 0,
108
- },
109
- disabled: {
110
- type: Boolean,
111
- default: false,
112
- required: false,
113
- },
114
- autoFocus: {
115
- type: Boolean,
116
- default: false,
117
- },
118
- required: {
119
- type: Boolean,
120
- default: false,
121
- },
122
- readonly: {
123
- type: Boolean,
124
- default: false,
125
- },
126
- inputFilled: {
127
- type:Boolean,
128
- default: false
129
- }
130
- });
131
-
132
- const { label, rows, cols, placeholder } = props;
133
-
134
- const localValue = ref(props.modelValue);
135
- const emit = defineEmits(["update:modelValue", "blur"]);
136
-
137
- watch(() => props.modelValue, (newVal) => {
138
- localValue.value = newVal;
139
- });
140
-
141
- const inputRef = ref<HTMLElement | null>(null);
142
- const inputValue = computed(() => {
143
- return !!localValue.value;
144
- });
145
-
146
- const focusInput = () => {
147
- if (inputRef.value) {
148
- inputRef.value?.focus();
149
- }
150
- };
151
- </script>
152
-
153
- <style lang="scss" scoped>
154
-
155
- </style>
@@ -1,148 +0,0 @@
1
- <template>
2
- <div>
3
- <ul role="list" class="p-4 space-y-6">
4
- <li
5
- v-for="(item, itemIdx) in items"
6
- :data="item"
7
- :key="`timeline_${itemIdx}`"
8
- class="relative flex gap-x-4 group"
9
- :type="type"
10
- :timeline-icon="icon"
11
- :show-more="showMore"
12
- >
13
- <div
14
- :class="[
15
- itemIdx === items.length - 1 ? 'h-6' : '-bottom-6',
16
- 'absolute left-0 top-0 flex w-6 justify-center',
17
- ]"
18
- >
19
- <slot name="line" :type="type">
20
- <div
21
- :class="[
22
- type === 'icon' ? 'w-0.5 bg-green-500' : 'w-px bg-gray-200',
23
- ]"
24
- />
25
- </slot>
26
-
27
- </div>
28
- <template v-if="type === 'image'">
29
- <slot name="image" :data="item" :dataIndex="itemIdx">
30
- <img
31
- :src="item.person?.imageUrl"
32
- alt=""
33
- class="relative flex-initial flex-shrink-0 rounded-full size-6 bg-gray-50"
34
- />
35
- </slot>
36
- <slot name="details" :data="item" :dataIndex="itemIdx">
37
- <div
38
- class="flex-1 min-w-0 p-3 rounded-md ring-1 ring-inset ring-gray-200"
39
- >
40
- <div class="flex justify-between gap-x-4 mb-0.5">
41
- <div class="text-xs leading-5 text-gray-500">
42
- <span class="font-medium text-gray-900">{{
43
- item.person?.name
44
- }}</span>
45
- </div>
46
- <time
47
- :datetime="item.dateTime"
48
- class="flex-none text-xs leading-5 text-gray-500"
49
- >
50
- {{ item.date + " " + item.dateTime }}
51
- </time>
52
- </div>
53
- <p class="text-sm leading-6 text-gray-500">
54
- {{ item.comment }}
55
- </p>
56
-
57
- <details
58
- v-if="showMore"
59
- :open="itemIdx === 0"
60
- class="h-6 p-2 mt-2 text-xs text-gray-500 transition-colors duration-100 ease-in-out select-none open:border open:border-gray-100 open:bg-gray-50 open:rounded-md group open:h-auto"
61
- >
62
- <summary
63
- class="flex flex-row items-center justify-start text-sm leading-5 text-gray-900 list-none cursor-pointer"
64
- >
65
- <slot name="showMoreTitle" :data="item" :open="itemIdx === 0">
66
- {{ item.showmore?.title || "More Details" }}
67
- <PlusIcon
68
- class="ml-auto -mr-1 transition-all duration-300 opacity-75 fill-current size-4 group-open:hidden"
69
- />
70
- <MinusIcon
71
- class="hidden ml-auto -mr-1 transition-all duration-300 opacity-75 fill-current size-4 group-open:inline-block"
72
- />
73
- </slot>
74
- </summary>
75
- <slot name="showMoreContent" :data="item">
76
- <div>{{ item.showmore?.content }}</div>
77
- </slot>
78
- </details>
79
- </div>
80
- </slot>
81
- </template>
82
- <template v-else>
83
- <div
84
- class="relative flex items-center justify-center flex-none bg-white size-6"
85
- >
86
- <component
87
- v-if="type === 'icon'"
88
- :is="icon || CheckCircleIcon"
89
- class="text-green-500 size-6"
90
- aria-hidden="true"
91
- />
92
- <div
93
- v-else
94
- class="size-1.5 rounded-full bg-gray-100 ring-1 ring-gray-300 group-hover:bg-purple-200 group-hover:ring-purple-500"
95
- />
96
- </div>
97
- <p class="flex-auto py-0.5 text-xs leading-5 text-gray-500">
98
- <span class="font-medium text-gray-900">{{
99
- item.person?.name
100
- }}</span>
101
- {{ item?.comment }}
102
- </p>
103
- <time
104
- :datetime="item.dateTime"
105
- class="flex-none py-0.5 text-xs leading-5 text-gray-500"
106
- >{{ item.date + " " + item.dateTime }}</time
107
- >
108
- </template>
109
- </li>
110
- </ul>
111
- </div>
112
- </template>
113
-
114
- <script setup lang="ts">
115
- import { PropType, toRefs } from "vue";
116
- import { MinusIcon, PlusIcon } from "@heroicons/vue/24/outline";
117
- import { CheckCircleIcon } from "@heroicons/vue/24/solid";
118
-
119
- interface ITimeLine {
120
- id: number | string;
121
- person: any;
122
- comment?: string;
123
- date?: string;
124
- dateTime?: string;
125
- showmore?: any;
126
- }
127
-
128
- const props = defineProps({
129
- items: {
130
- type: Array<ITimeLine>,
131
- default: [],
132
- },
133
- type: {
134
- type: String as PropType<"view" | "icon" | "image">,
135
- default: "",
136
- },
137
- icon: {
138
- type: [String, Object],
139
- default: "",
140
- },
141
- showMore: {
142
- type: Boolean,
143
- default: false,
144
- },
145
- });
146
-
147
- const { items, type, icon, showMore } = toRefs(props);
148
- </script>