edvoyui-component-library-test-flight 0.0.25 → 0.0.27
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/{input/EUIInput.vue.d.ts → EUIInput.vue.d.ts} +1 -1
- package/dist/EUIInput.vue.d.ts.map +1 -0
- package/dist/button/EUIButton.vue.d.ts.map +1 -0
- package/dist/library-vue-ts.cjs.js +21 -21
- package/dist/library-vue-ts.es.js +6229 -6201
- package/dist/library-vue-ts.umd.js +24 -24
- package/dist/modal/EUIModal.vue.d.ts +1 -1
- package/dist/modal/EUIModal.vue.d.ts.map +1 -1
- package/dist/table/EUIDashboardTable.vue.d.ts +1 -1
- package/dist/table/EUITable.vue.d.ts +1 -1
- package/package.json +1 -1
- package/src/assets/svg/ChevronBigDown.vue +22 -0
- package/src/components/HelloWorld.vue +235 -77
- package/src/components/checkbox/EUICheckbox.vue +2 -2
- package/src/components/datepicker/EUIDatepicker.stories.ts +136 -12
- package/src/components/datepicker/EUIDatepicker.vue +41 -15
- package/src/components/delete.vue +49 -1
- package/src/components/index.ts +0 -1
- package/src/components/input/EUIInput.stories.ts +219 -6
- package/src/components/input/EUIInput.vue +30 -15
- package/src/components/modal/EUIModal.vue +13 -16
- package/src/components/select/EUISelect.stories.ts +49 -3
- package/src/components/select/EUISelect.vue +79 -34
- package/src/components/table/EUIDashboardTable.vue +68 -36
- package/src/components/table/EUITable.vue +2 -2
- package/src/components/telephone/EUITelephone.stories.ts +164 -8
- package/src/components/telephone/EUITelephone.vue +33 -11
- package/src/components/textArea/EUITextArea.stories.ts +52 -0
- package/src/components/textArea/EUITextArea.vue +36 -5
- package/dist/EUIButton.vue.d.ts.map +0 -1
- package/dist/input/EUIInput.vue.d.ts.map +0 -1
- package/dist/inputNormal/EUIInputNormal.vue.d.ts +0 -5
- package/dist/inputNormal/EUIInputNormal.vue.d.ts.map +0 -1
- package/src/components/inputNormal/EUIInputNormal.stories.ts +0 -164
- package/src/components/inputNormal/EUIInputNormal.vue +0 -161
- package/src/components/select/EUISelect.scss +0 -0
- /package/dist/{EUIButton.vue.d.ts → button/EUIButton.vue.d.ts} +0 -0
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="isUseCustomSelect ? 'isUseCustomSelect' : ''">
|
|
3
|
+
<label
|
|
4
|
+
v-if="!inputFilled && label"
|
|
5
|
+
:class="[
|
|
6
|
+
'text-xs w-full text-gray-500 cursor-pointer font-medium block mb-1',
|
|
7
|
+
required && `after:content-['*'] after:ml-0.5 after:text-red-500`,
|
|
8
|
+
]"
|
|
9
|
+
>
|
|
10
|
+
{{ label }}
|
|
11
|
+
</label>
|
|
3
12
|
<vSelect
|
|
4
13
|
v-model="selected"
|
|
5
14
|
:filter="isFussySeach ? fuseSearch : undefined"
|
|
@@ -18,7 +27,14 @@
|
|
|
18
27
|
:loading="loading"
|
|
19
28
|
:disabled="disabled"
|
|
20
29
|
:selectable="selectedLimit"
|
|
21
|
-
:class="[
|
|
30
|
+
:class="[
|
|
31
|
+
isUseCustomSelect
|
|
32
|
+
? 'customselect'
|
|
33
|
+
: 'border border-gray-200 focus-within:border-purple-600 focus-within:ring-inset focus-within:ring-1 focus-within:ring-purple-600 z-10 focus-within:rounded',
|
|
34
|
+
inputFilled ? 'rounded-2xl min-h-14' : 'rounded-md min-h-10',
|
|
35
|
+
'group relative w-full bg-white cursor-pointer overflow-hidden',
|
|
36
|
+
{ 'opacity-25': disabled },
|
|
37
|
+
]"
|
|
22
38
|
:clearable="isUseCustomSelect ? clearable : undefined"
|
|
23
39
|
:no-drop="nodropDown"
|
|
24
40
|
@search="search($event)"
|
|
@@ -26,18 +42,18 @@
|
|
|
26
42
|
@option:deselected="deselected($event)"
|
|
27
43
|
@option:created="handleOptionCreate"
|
|
28
44
|
>
|
|
29
|
-
<template #header>
|
|
45
|
+
<template v-if="inputFilled" #header>
|
|
30
46
|
<div
|
|
31
47
|
:class="[
|
|
32
48
|
inputValue
|
|
33
49
|
? 'top-3.5 text-xs text-gray-400 cursor-default max-w-max'
|
|
34
|
-
: 'top-1/2 text-sm text-gray-700 cursor-pointer h-14 pt-5 pb-4 bg-transparent ring-0 ring-gray-200 group-hover:top-3.5 group-hover:py-0 group-hover:h-auto bg-white group-hover:text-xs group-hover:
|
|
50
|
+
: 'top-1/2 text-sm text-gray-700 cursor-pointer h-14 pt-5 pb-4 bg-transparent ring-0 ring-gray-200 group-hover:top-3.5 group-hover:py-0 group-hover:h-auto bg-white group-hover:text-xs group-hover:w-max w-11/12 group-hover:-translate-y-1/2 group-hover:text-gray-400',
|
|
35
51
|
disabled ? ' cursor-not-allowed' : '',
|
|
36
52
|
required && `after:content-['*'] after:ml-0.5 after:text-red-500`,
|
|
37
53
|
]"
|
|
38
54
|
class="absolute text-left font-medium inset-x-0 px-4 z-10 -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 capitalize leading-[normal]"
|
|
39
55
|
>
|
|
40
|
-
{{ startCaseText(label) }}
|
|
56
|
+
{{ startCaseText(label) || "Select" }}
|
|
41
57
|
</div>
|
|
42
58
|
</template>
|
|
43
59
|
<template #selected-option="{ name: nameText, iconlink }">
|
|
@@ -90,6 +106,11 @@
|
|
|
90
106
|
</button>
|
|
91
107
|
</div>
|
|
92
108
|
</template>
|
|
109
|
+
<template #open-indicator="{ attributes }">
|
|
110
|
+
<span v-bind="attributes as Record<string, any>"
|
|
111
|
+
><ChevronBigDown class="text-current size-6"
|
|
112
|
+
/></span>
|
|
113
|
+
</template>
|
|
93
114
|
</vSelect>
|
|
94
115
|
<EUIErrorMessage :errors="errors" :name="name" class="mt-2" />
|
|
95
116
|
</div>
|
|
@@ -111,8 +132,8 @@ import {
|
|
|
111
132
|
toRefs,
|
|
112
133
|
watch,
|
|
113
134
|
} from "vue";
|
|
114
|
-
import "./EUISelect.scss";
|
|
115
135
|
import { ValidationErrors } from "../../utils/types";
|
|
136
|
+
import ChevronBigDown from "../../assets/svg/ChevronBigDown.vue";
|
|
116
137
|
|
|
117
138
|
type VirtualElement = {
|
|
118
139
|
getBoundingClientRect: () => ClientRect | DOMRect;
|
|
@@ -146,7 +167,7 @@ const props = defineProps({
|
|
|
146
167
|
default: "",
|
|
147
168
|
required: false,
|
|
148
169
|
},
|
|
149
|
-
customOffset:{
|
|
170
|
+
customOffset: {
|
|
150
171
|
type: Array as PropType<any>,
|
|
151
172
|
required: false,
|
|
152
173
|
},
|
|
@@ -170,7 +191,7 @@ const props = defineProps({
|
|
|
170
191
|
},
|
|
171
192
|
label: {
|
|
172
193
|
type: String,
|
|
173
|
-
default: "
|
|
194
|
+
default: "",
|
|
174
195
|
required: false,
|
|
175
196
|
},
|
|
176
197
|
searchLabel: {
|
|
@@ -198,10 +219,10 @@ const props = defineProps({
|
|
|
198
219
|
required: false,
|
|
199
220
|
default: false,
|
|
200
221
|
},
|
|
201
|
-
multipleLimit:{
|
|
222
|
+
multipleLimit: {
|
|
202
223
|
type: Number,
|
|
203
224
|
required: false,
|
|
204
|
-
default: false
|
|
225
|
+
default: false,
|
|
205
226
|
},
|
|
206
227
|
disabled: {
|
|
207
228
|
type: Boolean as PropType<boolean>,
|
|
@@ -252,6 +273,10 @@ const props = defineProps({
|
|
|
252
273
|
required: false,
|
|
253
274
|
default: true,
|
|
254
275
|
},
|
|
276
|
+
inputFilled: {
|
|
277
|
+
type: Boolean,
|
|
278
|
+
default: false,
|
|
279
|
+
},
|
|
255
280
|
});
|
|
256
281
|
|
|
257
282
|
const {
|
|
@@ -302,7 +327,7 @@ const deselected = (newValue: any) => {
|
|
|
302
327
|
}
|
|
303
328
|
};
|
|
304
329
|
|
|
305
|
-
watch(modelValue, (newValue:any) => {
|
|
330
|
+
watch(modelValue, (newValue: any) => {
|
|
306
331
|
selected.value = newValue;
|
|
307
332
|
});
|
|
308
333
|
|
|
@@ -311,8 +336,8 @@ const search = (x: string) => {
|
|
|
311
336
|
emit("search", x);
|
|
312
337
|
};
|
|
313
338
|
|
|
314
|
-
const selectWidth = computed(() => props.customWidth)
|
|
315
|
-
const offsetValue = computed(() => props.customOffset)
|
|
339
|
+
const selectWidth = computed(() => props.customWidth);
|
|
340
|
+
const offsetValue = computed(() => props.customOffset);
|
|
316
341
|
|
|
317
342
|
const withPopper = (
|
|
318
343
|
dropdownList: HTMLElement,
|
|
@@ -320,10 +345,10 @@ const withPopper = (
|
|
|
320
345
|
{ width }: any
|
|
321
346
|
) => {
|
|
322
347
|
const newwidth = selectWidth.value || width; //setcustom width '400px'
|
|
323
|
-
const newOffset = offsetValue.value || [0,
|
|
348
|
+
const newOffset = offsetValue.value || [0, 7]; //setcustom Offset '[123, -1]'
|
|
324
349
|
const customWidth = isUseCustomSelect.value ? newwidth : width;
|
|
325
350
|
dropdownList.style.width = customWidth;
|
|
326
|
-
const offsetValues = isUseCustomSelect.value ? newOffset : [0,
|
|
351
|
+
const offsetValues = isUseCustomSelect.value ? newOffset : [0, 7];
|
|
327
352
|
const popper = createPopper(component.$refs.toggle, dropdownList, {
|
|
328
353
|
placement: "bottom",
|
|
329
354
|
modifiers: [
|
|
@@ -360,7 +385,13 @@ onBeforeUnmount(() => {
|
|
|
360
385
|
|
|
361
386
|
const slectedChipbg = computed(() => (props.multiple ? "#f3e8ff" : ""));
|
|
362
387
|
const slectedChiptextColor = computed(() => (props.multiple ? "#7e22ce" : ""));
|
|
363
|
-
const slectedChipHeight = computed(() =>
|
|
388
|
+
const slectedChipHeight = computed(() =>
|
|
389
|
+
props.multiple && props.inputFilled
|
|
390
|
+
? "fit-content"
|
|
391
|
+
: props.inputFilled
|
|
392
|
+
? ""
|
|
393
|
+
: "auto"
|
|
394
|
+
);
|
|
364
395
|
|
|
365
396
|
const dropDownIcon = computed(() => (props.clearable ? "flex" : "none"));
|
|
366
397
|
|
|
@@ -372,17 +403,17 @@ const selectBG = computed(() => {
|
|
|
372
403
|
});
|
|
373
404
|
const selectHeight = computed(() => {
|
|
374
405
|
if (selected.value?.length === 0 || _.isEmpty(selected.value)) {
|
|
375
|
-
return "54px";
|
|
406
|
+
return props.inputFilled ? "54px" : "36px";
|
|
376
407
|
}
|
|
377
408
|
|
|
378
409
|
let heightValue;
|
|
379
410
|
|
|
380
411
|
if (props.multiple) {
|
|
381
|
-
heightValue = "32px";
|
|
412
|
+
heightValue = props.inputFilled ? "32px" : "0px";
|
|
382
413
|
} else if (isUseCustomSelect.value) {
|
|
383
414
|
heightValue = "fit-content";
|
|
384
415
|
} else {
|
|
385
|
-
heightValue = "
|
|
416
|
+
heightValue = props.inputFilled ? "40px" : "30px";
|
|
386
417
|
}
|
|
387
418
|
|
|
388
419
|
return heightValue;
|
|
@@ -396,15 +427,28 @@ const selectedMultiple = computed(() => {
|
|
|
396
427
|
let heightValue;
|
|
397
428
|
|
|
398
429
|
if (isUseCustomSelect.value || props.multiple) {
|
|
399
|
-
heightValue = "24px";
|
|
430
|
+
heightValue = props.inputFilled ? "24px" : "4px";
|
|
400
431
|
} else {
|
|
401
|
-
heightValue = "2px";
|
|
432
|
+
heightValue = props.inputFilled ? "12px" : "2px";
|
|
402
433
|
}
|
|
403
434
|
|
|
404
435
|
return heightValue;
|
|
405
436
|
});
|
|
406
437
|
|
|
407
|
-
const selectFocus = computed(() =>
|
|
438
|
+
const selectFocus = computed(() =>
|
|
439
|
+
props.multiple && props.inputFilled
|
|
440
|
+
? "8px"
|
|
441
|
+
: props.inputFilled
|
|
442
|
+
? "8px"
|
|
443
|
+
: "0px"
|
|
444
|
+
);
|
|
445
|
+
const searchMargin = computed(() =>
|
|
446
|
+
props.multiple && props.inputFilled
|
|
447
|
+
? "10px"
|
|
448
|
+
: props.inputFilled
|
|
449
|
+
? "10px"
|
|
450
|
+
: "0px"
|
|
451
|
+
);
|
|
408
452
|
|
|
409
453
|
const selectRequited = computed(() =>
|
|
410
454
|
props.required
|
|
@@ -435,7 +479,8 @@ const inputValue = computed(() => {
|
|
|
435
479
|
const selectedValue = selected.value;
|
|
436
480
|
if (modelValue) return true;
|
|
437
481
|
if (Array.isArray(selectedValue)) return !!selectedValue.length;
|
|
438
|
-
if (selectedValue && typeof selectedValue ===
|
|
482
|
+
if (selectedValue && typeof selectedValue === "object")
|
|
483
|
+
return !!Object.keys(selectedValue).length;
|
|
439
484
|
return !!selectedValue;
|
|
440
485
|
});
|
|
441
486
|
|
|
@@ -444,17 +489,18 @@ const handleOptionCreate = (e: any) => {
|
|
|
444
489
|
};
|
|
445
490
|
|
|
446
491
|
const isSelectable = computed(() => {
|
|
447
|
-
return
|
|
492
|
+
return (
|
|
493
|
+
!props.multipleLimit || (selected.value?.length ?? 0) < props.multipleLimit
|
|
494
|
+
);
|
|
448
495
|
});
|
|
449
496
|
|
|
450
|
-
const selectedLimit = () =>
|
|
451
|
-
if(!props.multipleLimit) return true
|
|
497
|
+
const selectedLimit = () => {
|
|
498
|
+
if (!props.multipleLimit) return true;
|
|
452
499
|
|
|
453
|
-
if(props.multipleLimit) {
|
|
454
|
-
return isSelectable.value
|
|
500
|
+
if (props.multipleLimit) {
|
|
501
|
+
return isSelectable.value;
|
|
455
502
|
}
|
|
456
|
-
}
|
|
457
|
-
|
|
503
|
+
};
|
|
458
504
|
|
|
459
505
|
// const handlers = (e: Event) => {
|
|
460
506
|
// console.log("@e", e);
|
|
@@ -492,9 +538,6 @@ const selectedLimit = () => {
|
|
|
492
538
|
}
|
|
493
539
|
}
|
|
494
540
|
|
|
495
|
-
.vs__search:focus {
|
|
496
|
-
padding-top: v-bind(selectFocus);
|
|
497
|
-
}
|
|
498
541
|
.vs--single.vs--open .vs__selected,
|
|
499
542
|
.vs--single.vs--loading .vs__selected {
|
|
500
543
|
@apply opacity-0;
|
|
@@ -551,9 +594,11 @@ const selectedLimit = () => {
|
|
|
551
594
|
|
|
552
595
|
.vs {
|
|
553
596
|
&__search {
|
|
554
|
-
@apply
|
|
597
|
+
@apply px-2 placeholder:text-sm placeholder:font-medium placeholder:leading-loose appearance-none;
|
|
598
|
+
margin-top: v-bind(searchMargin);
|
|
555
599
|
&:focus {
|
|
556
|
-
@apply text-sm font-medium;
|
|
600
|
+
@apply text-sm font-medium pl-2.5;
|
|
601
|
+
padding-top: v-bind(selectFocus);
|
|
557
602
|
}
|
|
558
603
|
}
|
|
559
604
|
&__selected {
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
</th>
|
|
23
23
|
</template>
|
|
24
24
|
<th
|
|
25
|
-
|
|
25
|
+
v-for="(header, headerIndex) in headers"
|
|
26
26
|
:key="`item-${headerIndex}`"
|
|
27
27
|
scope="col"
|
|
28
28
|
:class="[
|
|
29
29
|
'px-3 py-2 text-gray-600 snap-start snap-always',
|
|
30
|
-
|
|
30
|
+
isScrolled && headerIndex === 0 ? stickyClass.head : '',
|
|
31
31
|
{ 'cursor-pointer hover:text-gray-900': header?.sortable },
|
|
32
32
|
]"
|
|
33
33
|
:style="
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
class="flex items-center gap-2 text-sm font-normal text-current"
|
|
42
42
|
>
|
|
43
43
|
<slot name="header" :header="header">
|
|
44
|
-
{{ capitalizeText(header?.text ?? header.name ??
|
|
44
|
+
{{ capitalizeText(header?.text ?? header.name ?? "") }}
|
|
45
45
|
</slot>
|
|
46
46
|
<slot name="headerOptionalItem"></slot>
|
|
47
47
|
<SortArrow
|
|
@@ -59,27 +59,47 @@
|
|
|
59
59
|
</tr>
|
|
60
60
|
</thead>
|
|
61
61
|
<tbody>
|
|
62
|
+
<template v-if="loading">
|
|
63
|
+
<tr class="norecords">
|
|
64
|
+
<td :colspan="headers.length">
|
|
65
|
+
<div
|
|
66
|
+
class="flex items-center justify-center text-xl font-medium text-gray-500 min-h-96"
|
|
67
|
+
>
|
|
68
|
+
<EUICircleLoader />
|
|
69
|
+
</div>
|
|
70
|
+
</td>
|
|
71
|
+
</tr>
|
|
72
|
+
</template>
|
|
62
73
|
<template
|
|
74
|
+
v-else-if="computedItems.length > 0"
|
|
63
75
|
v-for="(row, rowIndex) in computedItems"
|
|
64
76
|
:key="`table-row-${rowIndex}`"
|
|
65
77
|
>
|
|
66
78
|
<tr
|
|
67
|
-
@mouseenter="
|
|
68
|
-
|
|
79
|
+
@mouseenter="
|
|
80
|
+
$attrs.mouseenter ? $emit('mouseenter', row, rowIndex) : null
|
|
81
|
+
"
|
|
82
|
+
@mouseleave="
|
|
83
|
+
$attrs.mouseleave ? $emit('mouseleave', row, rowIndex) : null
|
|
84
|
+
"
|
|
69
85
|
>
|
|
70
86
|
<template v-if="checkable">
|
|
71
87
|
<td class="checkable">
|
|
72
88
|
<EUITableCheckbox
|
|
73
89
|
:disabled="!isRowCheckable(row)"
|
|
74
90
|
:checked="isRowChecked(row)"
|
|
75
|
-
@change.prevent.stop="
|
|
91
|
+
@change.prevent.stop="
|
|
92
|
+
($event) => checkRow(row, rowIndex, $event)
|
|
93
|
+
"
|
|
76
94
|
/>
|
|
77
95
|
</td>
|
|
78
96
|
</template>
|
|
79
|
-
|
|
97
|
+
<td
|
|
80
98
|
v-for="(header, headerIndex) in headers"
|
|
81
99
|
:key="headerIndex"
|
|
82
|
-
:class="[
|
|
100
|
+
:class="[
|
|
101
|
+
isScrolled && headerIndex === 0 ? stickyClass.body : '',
|
|
102
|
+
]"
|
|
83
103
|
>
|
|
84
104
|
<slot
|
|
85
105
|
:name="`item.${header.value}`"
|
|
@@ -94,17 +114,18 @@
|
|
|
94
114
|
<slot name="expanded" :row="row" :rowIndex="rowIndex"></slot>
|
|
95
115
|
</template>
|
|
96
116
|
</template>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
117
|
+
|
|
118
|
+
<template v-if="computedItems.length === 0">
|
|
119
|
+
<tr class="norecords">
|
|
120
|
+
<td :colspan="headers.length">
|
|
121
|
+
<div
|
|
122
|
+
class="flex items-center justify-center text-xl font-medium text-gray-500 min-h-96"
|
|
123
|
+
>
|
|
124
|
+
No matching records found
|
|
125
|
+
</div>
|
|
126
|
+
</td>
|
|
127
|
+
</tr>
|
|
128
|
+
</template>
|
|
108
129
|
</tbody>
|
|
109
130
|
</table>
|
|
110
131
|
</div>
|
|
@@ -144,12 +165,21 @@
|
|
|
144
165
|
</template>
|
|
145
166
|
|
|
146
167
|
<script setup lang="ts">
|
|
147
|
-
import {
|
|
168
|
+
import {
|
|
169
|
+
computed,
|
|
170
|
+
onMounted,
|
|
171
|
+
onUnmounted,
|
|
172
|
+
PropType,
|
|
173
|
+
ref,
|
|
174
|
+
toRefs,
|
|
175
|
+
watch,
|
|
176
|
+
} from "vue";
|
|
148
177
|
import EUIPagination from "./EUIPagination.vue";
|
|
149
178
|
import EUITableCheckbox from "./EUITableCheckbox.vue";
|
|
150
179
|
import SortArrow from "../../assets/svg/SortArrow.vue";
|
|
151
180
|
import EUIPageLimit from "./EUIPageLimit.vue";
|
|
152
181
|
import { capitalizeText } from "../../utils/lodash";
|
|
182
|
+
import EUICircleLoader from "../loader/EUICircleLoader.vue";
|
|
153
183
|
|
|
154
184
|
interface Header {
|
|
155
185
|
value: string;
|
|
@@ -169,7 +199,11 @@ const props = defineProps({
|
|
|
169
199
|
tableExpanded: { type: Boolean, default: false },
|
|
170
200
|
backendPagination: { type: Boolean, default: false },
|
|
171
201
|
checkedRows: { type: Array, default: () => ({}), required: true },
|
|
172
|
-
headers: {
|
|
202
|
+
headers: {
|
|
203
|
+
type: Array as PropType<Header[]>,
|
|
204
|
+
default: () => ({}),
|
|
205
|
+
required: true,
|
|
206
|
+
},
|
|
173
207
|
items: { type: Array, required: true, default: () => ({}) },
|
|
174
208
|
defaultSort: { type: String, default: "" },
|
|
175
209
|
defaultSortDirection: { type: String, default: "asc" },
|
|
@@ -182,6 +216,7 @@ const props = defineProps({
|
|
|
182
216
|
default: () => () => false,
|
|
183
217
|
},
|
|
184
218
|
isRowCheckable: { type: Function, default: () => true },
|
|
219
|
+
tableLoading: { type: Boolean, default: true },
|
|
185
220
|
});
|
|
186
221
|
const {
|
|
187
222
|
defaultSort,
|
|
@@ -206,6 +241,8 @@ const lastCheckedRowIndex = ref();
|
|
|
206
241
|
|
|
207
242
|
const limit = ref(props.perPage);
|
|
208
243
|
|
|
244
|
+
const loading = computed(() => props.tableLoading);
|
|
245
|
+
|
|
209
246
|
// Computed Property
|
|
210
247
|
const filteredItems = computed(() => {
|
|
211
248
|
let filteredItems = items.value.slice();
|
|
@@ -227,18 +264,13 @@ const filteredItems = computed(() => {
|
|
|
227
264
|
const computedItems = computed(() => {
|
|
228
265
|
let items = filteredItems.value;
|
|
229
266
|
// Sort items before slicing for pagination
|
|
230
|
-
items.sort((a:any, b:any) => {
|
|
267
|
+
items.sort((a: any, b: any) => {
|
|
231
268
|
const modifier = currentSortDir.value === "desc" ? -1 : 1;
|
|
232
269
|
if (a[currentSort.value] < b[currentSort.value]) return -1 * modifier;
|
|
233
270
|
if (a[currentSort.value] > b[currentSort.value]) return 1 * modifier;
|
|
234
271
|
return 0;
|
|
235
272
|
});
|
|
236
|
-
return items
|
|
237
|
-
|
|
238
|
-
// Apply pagination
|
|
239
|
-
// const start = (newCurrentPage.value - 0) * limit.value;
|
|
240
|
-
// const end = start + limit.value;
|
|
241
|
-
// return items.slice(start, end);
|
|
273
|
+
return items;
|
|
242
274
|
});
|
|
243
275
|
|
|
244
276
|
const searchData = (data: number) => {
|
|
@@ -281,7 +313,7 @@ const isAllUncheckable = computed(() => {
|
|
|
281
313
|
});
|
|
282
314
|
|
|
283
315
|
// methods
|
|
284
|
-
const defaultFilter = (value:any, search:any) => {
|
|
316
|
+
const defaultFilter = (value: any, search: any) => {
|
|
285
317
|
return value.toString().toLowerCase().includes(search);
|
|
286
318
|
};
|
|
287
319
|
|
|
@@ -289,7 +321,7 @@ const indexOf = (
|
|
|
289
321
|
array: any[],
|
|
290
322
|
obj: any,
|
|
291
323
|
fn: (item: any, obj: any) => boolean
|
|
292
|
-
): number =>
|
|
324
|
+
): number => {
|
|
293
325
|
if (!array) return -1;
|
|
294
326
|
if (!fn || typeof fn !== "function") return array?.indexOf(obj);
|
|
295
327
|
for (let i = 0; i < array.length; i++) {
|
|
@@ -318,7 +350,7 @@ const emit = defineEmits([
|
|
|
318
350
|
"update:checkedRows",
|
|
319
351
|
"changeLimit",
|
|
320
352
|
"mouseenter",
|
|
321
|
-
"mouseleave"
|
|
353
|
+
"mouseleave",
|
|
322
354
|
]);
|
|
323
355
|
|
|
324
356
|
const changeLimit = (limitData: number) => {
|
|
@@ -354,20 +386,20 @@ const checkAll = () => {
|
|
|
354
386
|
emit("update:checkedRows", newCheckedRows.value);
|
|
355
387
|
};
|
|
356
388
|
|
|
357
|
-
const removeCheckedRow = (row:any) => {
|
|
389
|
+
const removeCheckedRow = (row: any) => {
|
|
358
390
|
const index = indexOf(newCheckedRows.value, row, customIsChecked.value);
|
|
359
391
|
if (index >= 0) {
|
|
360
392
|
newCheckedRows.value.splice(index, 1);
|
|
361
393
|
}
|
|
362
394
|
};
|
|
363
395
|
|
|
364
|
-
const isRowChecked = (row:any) => {
|
|
396
|
+
const isRowChecked = (row: any) => {
|
|
365
397
|
return indexOf(newCheckedRows.value, row, customIsChecked.value) >= 0;
|
|
366
398
|
};
|
|
367
399
|
|
|
368
400
|
const checkRow = (row: any, rowIndex: number, event: Event) => {
|
|
369
401
|
if (!isRowCheckable.value(row)) return;
|
|
370
|
-
if(event) {
|
|
402
|
+
if (event) {
|
|
371
403
|
lastCheckedRowIndex.value = rowIndex;
|
|
372
404
|
if (!isRowChecked(row)) {
|
|
373
405
|
newCheckedRows.value.push(row);
|
|
@@ -457,8 +489,8 @@ watch(() => tableContainer.value?.clientWidth, checkOverflow);
|
|
|
457
489
|
}
|
|
458
490
|
}
|
|
459
491
|
tbody {
|
|
460
|
-
|
|
461
|
-
tr {
|
|
492
|
+
@apply snap-y snap-mandatory snap-always;
|
|
493
|
+
tr:not(.norecords) {
|
|
462
494
|
@apply text-gray-500 transition-all duration-150 rounded-xl bg-white snap-start ease-in-out snap-x snap-mandatory;
|
|
463
495
|
&:hover {
|
|
464
496
|
@apply shadow-[1px_2px_40px_0px_#03022912] ring-1 ring-gray-100 ring-inset z-30;
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
</template>
|
|
126
126
|
</tbody>
|
|
127
127
|
<tbody v-if="computedItems.length === 0">
|
|
128
|
-
<tr>
|
|
128
|
+
<tr class="norecords">
|
|
129
129
|
<td :colspan="checkable === true ? headers.length + 1 : headers.length">
|
|
130
130
|
<div
|
|
131
131
|
class="flex items-center justify-center text-xl font-medium text-gray-500 min-h-96"
|
|
@@ -484,7 +484,7 @@ watch(() => tableContainer.value?.clientWidth, checkOverflow);
|
|
|
484
484
|
|
|
485
485
|
tbody {
|
|
486
486
|
@apply snap-y snap-mandatory snap-always;
|
|
487
|
-
|
|
487
|
+
tr:not(.norecords) {
|
|
488
488
|
@apply text-gray-600 transition-colors duration-100 bg-white snap-start ease-in-out snap-x snap-mandatory rounded-sm h-12;
|
|
489
489
|
&:hover {
|
|
490
490
|
@apply bg-purple-50 ring-1 ring-purple-100 ring-inset;
|