@weni/unnnic-system 3.9.1 → 3.9.2
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/CHANGELOG.md +16 -0
- package/dist/components/DataTable/index.vue.d.ts +11 -1
- package/dist/components/DataTable/index.vue.d.ts.map +1 -1
- package/dist/{es-efb4f902.mjs → es-4aab69cb.mjs} +1 -1
- package/dist/{index-e30fc518.mjs → index-789225a6.mjs} +5103 -5070
- package/dist/{pt-br-4bacdbb6.mjs → pt-br-2f695ddd.mjs} +1 -1
- package/dist/style.css +1 -1
- package/dist/unnnic.mjs +1 -1
- package/dist/unnnic.umd.js +32 -32
- package/package.json +1 -1
- package/src/components/DataTable/index.vue +48 -0
- package/src/stories/DataTable.stories.js +192 -0
package/package.json
CHANGED
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
</tr>
|
|
57
57
|
</thead>
|
|
58
58
|
<tbody
|
|
59
|
+
ref="tbodyRef"
|
|
59
60
|
:class="[
|
|
60
61
|
'unnnic-data-table__body',
|
|
61
62
|
{ 'unnnic-data-table__body--hide-headers': props.hideHeaders },
|
|
@@ -120,6 +121,27 @@
|
|
|
120
121
|
</td>
|
|
121
122
|
</template>
|
|
122
123
|
</tr>
|
|
124
|
+
<tr
|
|
125
|
+
v-if="props.infiniteScroll && props.isLoadingMore"
|
|
126
|
+
:class="[
|
|
127
|
+
'unnnic-data-table__body-row',
|
|
128
|
+
'unnnic-data-table__body-row--loading-more',
|
|
129
|
+
]"
|
|
130
|
+
>
|
|
131
|
+
<td
|
|
132
|
+
:class="[
|
|
133
|
+
'unnnic-data-table__body-cell',
|
|
134
|
+
`unnnic-data-table__body-cell--${size}`,
|
|
135
|
+
]"
|
|
136
|
+
>
|
|
137
|
+
<img
|
|
138
|
+
class="unnnic-data-table__body-cell--loading"
|
|
139
|
+
data-testid="body-row-loading-more"
|
|
140
|
+
src="../../assets/icons/weni-loading.svg"
|
|
141
|
+
height="40"
|
|
142
|
+
/>
|
|
143
|
+
</td>
|
|
144
|
+
</tr>
|
|
123
145
|
</template>
|
|
124
146
|
<tr
|
|
125
147
|
v-else
|
|
@@ -166,6 +188,7 @@
|
|
|
166
188
|
|
|
167
189
|
<script setup lang="ts">
|
|
168
190
|
import { computed, ComputedRef, ref, useSlots } from 'vue';
|
|
191
|
+
import { useInfiniteScroll } from '@vueuse/core';
|
|
169
192
|
|
|
170
193
|
import Icon from '../Icon.vue';
|
|
171
194
|
import IconArrowsDefault from '../icons/iconArrowsDefault.vue';
|
|
@@ -205,6 +228,10 @@ interface Props {
|
|
|
205
228
|
pageInterval?: number;
|
|
206
229
|
locale?: string;
|
|
207
230
|
sort?: SortState;
|
|
231
|
+
infiniteScroll?: boolean;
|
|
232
|
+
infiniteScrollDistance?: number;
|
|
233
|
+
infiniteScrollDisabled?: boolean;
|
|
234
|
+
isLoadingMore?: boolean;
|
|
208
235
|
}
|
|
209
236
|
|
|
210
237
|
defineOptions({
|
|
@@ -217,6 +244,7 @@ const emit = defineEmits<{
|
|
|
217
244
|
'update:sort': [sort: { header: string; itemKey: string; order: string }];
|
|
218
245
|
itemClick: [item: DataTableItem];
|
|
219
246
|
'update:page': [page: number];
|
|
247
|
+
loadMore: [];
|
|
220
248
|
}>();
|
|
221
249
|
|
|
222
250
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -233,6 +261,10 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
233
261
|
pageInterval: 5,
|
|
234
262
|
locale: 'en',
|
|
235
263
|
sort: undefined,
|
|
264
|
+
infiniteScroll: false,
|
|
265
|
+
infiniteScrollDistance: 100,
|
|
266
|
+
infiniteScrollDisabled: false,
|
|
267
|
+
isLoadingMore: false,
|
|
236
268
|
});
|
|
237
269
|
|
|
238
270
|
const defaultTranslations = {
|
|
@@ -318,6 +350,21 @@ const handleClickRow = (item: DataTableItem) => {
|
|
|
318
350
|
|
|
319
351
|
emit('itemClick', item);
|
|
320
352
|
};
|
|
353
|
+
|
|
354
|
+
const tbodyRef = ref<HTMLElement | null>(null);
|
|
355
|
+
|
|
356
|
+
const handleLoadMore = () => {
|
|
357
|
+
if (props.infiniteScrollDisabled || props.isLoading || props.isLoadingMore) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
emit('loadMore');
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
if (props.infiniteScroll) {
|
|
364
|
+
useInfiniteScroll(tbodyRef, handleLoadMore, {
|
|
365
|
+
distance: props.infiniteScrollDistance,
|
|
366
|
+
});
|
|
367
|
+
}
|
|
321
368
|
</script>
|
|
322
369
|
|
|
323
370
|
<style scoped lang="scss">
|
|
@@ -428,6 +475,7 @@ $tableBorder: $unnnic-border-width-thinner solid $unnnic-color-neutral-soft;
|
|
|
428
475
|
grid-template-columns: v-bind(gridTemplateColumns);
|
|
429
476
|
|
|
430
477
|
&--loading,
|
|
478
|
+
&--loading-more,
|
|
431
479
|
&--without-results {
|
|
432
480
|
grid-template-columns: 1fr;
|
|
433
481
|
}
|
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
import UnnnicDataTable from '../components/DataTable/index.vue';
|
|
2
2
|
import { action } from '@storybook/addon-actions';
|
|
3
3
|
|
|
4
|
+
const SAMPLE_NAMES = [
|
|
5
|
+
'Eduardo',
|
|
6
|
+
'Marcus',
|
|
7
|
+
'Paulo',
|
|
8
|
+
'Cristian',
|
|
9
|
+
'Aldemylla',
|
|
10
|
+
'João',
|
|
11
|
+
'Maria',
|
|
12
|
+
'Ana',
|
|
13
|
+
'Pedro',
|
|
14
|
+
'Lucas',
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const SAMPLE_COUNTRIES = ['Brazil', 'USA', 'Canada', 'Argentina', 'Chile'];
|
|
18
|
+
|
|
19
|
+
const generateItems = (count, startId) => {
|
|
20
|
+
return Array.from({ length: count }, (_, i) => ({
|
|
21
|
+
id: String(startId + i),
|
|
22
|
+
name: SAMPLE_NAMES[Math.floor(Math.random() * SAMPLE_NAMES.length)],
|
|
23
|
+
age: Math.floor(Math.random() * 30) + 20,
|
|
24
|
+
country:
|
|
25
|
+
SAMPLE_COUNTRIES[Math.floor(Math.random() * SAMPLE_COUNTRIES.length)],
|
|
26
|
+
}));
|
|
27
|
+
};
|
|
28
|
+
|
|
4
29
|
export default {
|
|
5
30
|
title: 'Data Display/DataTable',
|
|
6
31
|
component: UnnnicDataTable,
|
|
@@ -70,6 +95,26 @@ export default {
|
|
|
70
95
|
control: { type: 'select' },
|
|
71
96
|
options: ['en', 'pt-br', 'es'],
|
|
72
97
|
},
|
|
98
|
+
infiniteScroll: {
|
|
99
|
+
description:
|
|
100
|
+
'Enables infinite scroll functionality. When enabled, the table will emit a loadMore event when the user scrolls near the bottom.',
|
|
101
|
+
control: 'boolean',
|
|
102
|
+
},
|
|
103
|
+
infiniteScrollDistance: {
|
|
104
|
+
description:
|
|
105
|
+
'Distance in pixels from the bottom of the table to trigger the loadMore event.',
|
|
106
|
+
control: 'number',
|
|
107
|
+
},
|
|
108
|
+
infiniteScrollDisabled: {
|
|
109
|
+
description:
|
|
110
|
+
'Disables the infinite scroll functionality. Useful when all data has been loaded.',
|
|
111
|
+
control: 'boolean',
|
|
112
|
+
},
|
|
113
|
+
isLoadingMore: {
|
|
114
|
+
description:
|
|
115
|
+
'Indicates whether more data is being loaded for infinite scroll. Shows a loading indicator at the bottom of the table.',
|
|
116
|
+
control: 'boolean',
|
|
117
|
+
},
|
|
73
118
|
},
|
|
74
119
|
render: (args) => ({
|
|
75
120
|
components: {
|
|
@@ -390,3 +435,150 @@ export const ControlledSort = {
|
|
|
390
435
|
`,
|
|
391
436
|
}),
|
|
392
437
|
};
|
|
438
|
+
|
|
439
|
+
export const InfiniteScroll = {
|
|
440
|
+
args: { headers },
|
|
441
|
+
render: (args) => ({
|
|
442
|
+
components: {
|
|
443
|
+
UnnnicDataTable,
|
|
444
|
+
},
|
|
445
|
+
data() {
|
|
446
|
+
return {
|
|
447
|
+
args,
|
|
448
|
+
currentId: 11,
|
|
449
|
+
displayedItems: generateItems(10, 1),
|
|
450
|
+
isLoadingMore: false,
|
|
451
|
+
};
|
|
452
|
+
},
|
|
453
|
+
methods: {
|
|
454
|
+
loadMore() {
|
|
455
|
+
action('loadMore')();
|
|
456
|
+
this.isLoadingMore = true;
|
|
457
|
+
|
|
458
|
+
setTimeout(() => {
|
|
459
|
+
const newItems = generateItems(5, this.currentId);
|
|
460
|
+
this.displayedItems = [...this.displayedItems, ...newItems];
|
|
461
|
+
this.currentId += 5;
|
|
462
|
+
this.isLoadingMore = false;
|
|
463
|
+
}, 1000);
|
|
464
|
+
},
|
|
465
|
+
},
|
|
466
|
+
template: `
|
|
467
|
+
<UnnnicDataTable
|
|
468
|
+
v-bind="args"
|
|
469
|
+
:headers="args.headers"
|
|
470
|
+
:items="displayedItems"
|
|
471
|
+
:infiniteScroll="true"
|
|
472
|
+
:infiniteScrollDistance="100"
|
|
473
|
+
:isLoadingMore="isLoadingMore"
|
|
474
|
+
:hidePagination="true"
|
|
475
|
+
height="400px"
|
|
476
|
+
@loadMore="loadMore"
|
|
477
|
+
>
|
|
478
|
+
</UnnnicDataTable>
|
|
479
|
+
`,
|
|
480
|
+
}),
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
export const InfiniteScrollWithFixedHeaders = {
|
|
484
|
+
args: { headers },
|
|
485
|
+
render: (args) => ({
|
|
486
|
+
components: {
|
|
487
|
+
UnnnicDataTable,
|
|
488
|
+
},
|
|
489
|
+
data() {
|
|
490
|
+
return {
|
|
491
|
+
args,
|
|
492
|
+
currentId: 11,
|
|
493
|
+
displayedItems: generateItems(10, 1),
|
|
494
|
+
isLoadingMore: false,
|
|
495
|
+
hasMore: true,
|
|
496
|
+
};
|
|
497
|
+
},
|
|
498
|
+
methods: {
|
|
499
|
+
loadMore() {
|
|
500
|
+
if (!this.hasMore) return;
|
|
501
|
+
|
|
502
|
+
action('loadMore')();
|
|
503
|
+
this.isLoadingMore = true;
|
|
504
|
+
|
|
505
|
+
setTimeout(() => {
|
|
506
|
+
const newItems = generateItems(5, this.currentId);
|
|
507
|
+
this.displayedItems = [...this.displayedItems, ...newItems];
|
|
508
|
+
this.currentId += 5;
|
|
509
|
+
|
|
510
|
+
if (this.displayedItems.length >= 50) {
|
|
511
|
+
this.hasMore = false;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
this.isLoadingMore = false;
|
|
515
|
+
}, 1000);
|
|
516
|
+
},
|
|
517
|
+
},
|
|
518
|
+
template: `
|
|
519
|
+
<UnnnicDataTable
|
|
520
|
+
v-bind="args"
|
|
521
|
+
:headers="args.headers"
|
|
522
|
+
:items="displayedItems"
|
|
523
|
+
:infiniteScroll="true"
|
|
524
|
+
:infiniteScrollDistance="50"
|
|
525
|
+
:infiniteScrollDisabled="!hasMore"
|
|
526
|
+
:isLoadingMore="isLoadingMore"
|
|
527
|
+
:hidePagination="true"
|
|
528
|
+
:fixedHeaders="true"
|
|
529
|
+
height="400px"
|
|
530
|
+
@loadMore="loadMore"
|
|
531
|
+
>
|
|
532
|
+
</UnnnicDataTable>
|
|
533
|
+
`,
|
|
534
|
+
}),
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
export const InfiniteScrollClickable = {
|
|
538
|
+
args: { headers },
|
|
539
|
+
render: (args) => ({
|
|
540
|
+
components: {
|
|
541
|
+
UnnnicDataTable,
|
|
542
|
+
},
|
|
543
|
+
data() {
|
|
544
|
+
return {
|
|
545
|
+
args,
|
|
546
|
+
currentId: 11,
|
|
547
|
+
displayedItems: generateItems(10, 1),
|
|
548
|
+
isLoadingMore: false,
|
|
549
|
+
};
|
|
550
|
+
},
|
|
551
|
+
methods: {
|
|
552
|
+
loadMore() {
|
|
553
|
+
action('loadMore')();
|
|
554
|
+
this.isLoadingMore = true;
|
|
555
|
+
|
|
556
|
+
setTimeout(() => {
|
|
557
|
+
const newItems = generateItems(5, this.currentId);
|
|
558
|
+
this.displayedItems = [...this.displayedItems, ...newItems];
|
|
559
|
+
this.currentId += 5;
|
|
560
|
+
this.isLoadingMore = false;
|
|
561
|
+
}, 1000);
|
|
562
|
+
},
|
|
563
|
+
itemClick(item) {
|
|
564
|
+
action('itemClick')(item);
|
|
565
|
+
},
|
|
566
|
+
},
|
|
567
|
+
template: `
|
|
568
|
+
<UnnnicDataTable
|
|
569
|
+
v-bind="args"
|
|
570
|
+
:headers="args.headers"
|
|
571
|
+
:items="displayedItems"
|
|
572
|
+
:infiniteScroll="true"
|
|
573
|
+
:infiniteScrollDistance="100"
|
|
574
|
+
:isLoadingMore="isLoadingMore"
|
|
575
|
+
:hidePagination="true"
|
|
576
|
+
:clickable="true"
|
|
577
|
+
height="400px"
|
|
578
|
+
@loadMore="loadMore"
|
|
579
|
+
@itemClick="itemClick"
|
|
580
|
+
>
|
|
581
|
+
</UnnnicDataTable>
|
|
582
|
+
`,
|
|
583
|
+
}),
|
|
584
|
+
};
|