sprintify-ui 0.8.25 → 0.8.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.
@@ -20,6 +20,7 @@ declare const _default: import("vue").DefineComponent<{
20
20
  isRowCheckable: Function;
21
21
  maxHeight: number;
22
22
  rowKey: ((row: import("@/index.js").CollectionItem) => string | number) | undefined;
23
+ virtualScrolling: boolean;
23
24
  data: import("@/index.js").Row[];
24
25
  visibleColumns: string[];
25
26
  }> & Omit<{
@@ -32,6 +33,7 @@ declare const _default: import("vue").DefineComponent<{
32
33
  readonly checkable: boolean;
33
34
  readonly checkedRows: import("@/index.js").Row[];
34
35
  readonly isRowCheckable: Function;
36
+ readonly virtualScrolling: boolean;
35
37
  readonly data: import("@/index.js").Row[];
36
38
  readonly rowTo?: ((row: import("@/index.js").CollectionItem) => import("vue-router").RouteLocationRaw) | undefined;
37
39
  readonly rowHref?: ((row: import("@/index.js").CollectionItem) => string) | undefined;
@@ -113,6 +115,10 @@ declare const _default: import("vue").DefineComponent<{
113
115
  default: undefined;
114
116
  type: PropType<((row: import("@/index.js").CollectionItem) => string | number) | undefined>;
115
117
  };
118
+ virtualScrolling: {
119
+ default: boolean;
120
+ type: BooleanConstructor;
121
+ };
116
122
  }>> & {
117
123
  onCheck?: ((...args: any[]) => any) | undefined;
118
124
  onSort?: ((...args: any[]) => any) | undefined;
@@ -123,7 +129,7 @@ declare const _default: import("vue").DefineComponent<{
123
129
  "onUpdate:openedDetailed"?: ((...args: any[]) => any) | undefined;
124
130
  "onCell-click"?: ((...args: any[]) => any) | undefined;
125
131
  "onRow-click"?: ((...args: any[]) => any) | undefined;
126
- }, "size" | "loading" | "sortField" | "sortDirection" | "rowTo" | "rowHref" | "onRowClick" | "detailed" | "hasDetailedVisible" | "checkable" | "checkedRows" | "isRowCheckable" | "maxHeight" | "rowKey" | "data" | "visibleColumns">;
132
+ }, "size" | "loading" | "sortField" | "sortDirection" | "rowTo" | "rowHref" | "onRowClick" | "detailed" | "hasDetailedVisible" | "checkable" | "checkedRows" | "isRowCheckable" | "maxHeight" | "rowKey" | "virtualScrolling" | "data" | "visibleColumns">;
127
133
  $attrs: {
128
134
  [x: string]: unknown;
129
135
  };
@@ -202,6 +208,10 @@ declare const _default: import("vue").DefineComponent<{
202
208
  default: undefined;
203
209
  type: PropType<((row: import("@/index.js").CollectionItem) => string | number) | undefined>;
204
210
  };
211
+ virtualScrolling: {
212
+ default: boolean;
213
+ type: BooleanConstructor;
214
+ };
205
215
  }>> & {
206
216
  onCheck?: ((...args: any[]) => any) | undefined;
207
217
  onSort?: ((...args: any[]) => any) | undefined;
@@ -263,6 +273,7 @@ declare const _default: import("vue").DefineComponent<{
263
273
  isRowCheckable: Function;
264
274
  maxHeight: number;
265
275
  rowKey: ((row: import("@/index.js").CollectionItem) => string | number) | undefined;
276
+ virtualScrolling: boolean;
266
277
  data: import("@/index.js").Row[];
267
278
  visibleColumns: string[];
268
279
  }, {}, string, {}> & {
@@ -350,6 +361,10 @@ declare const _default: import("vue").DefineComponent<{
350
361
  default: undefined;
351
362
  type: PropType<((row: import("@/index.js").CollectionItem) => string | number) | undefined>;
352
363
  };
364
+ virtualScrolling: {
365
+ default: boolean;
366
+ type: BooleanConstructor;
367
+ };
353
368
  }>> & {
354
369
  onCheck?: ((...args: any[]) => any) | undefined;
355
370
  onSort?: ((...args: any[]) => any) | undefined;
@@ -424,6 +439,7 @@ declare const _default: import("vue").DefineComponent<{
424
439
  isRowCheckable: Function;
425
440
  maxHeight: number;
426
441
  rowKey: ((row: import("@/index.js").CollectionItem) => string | number) | undefined;
442
+ virtualScrolling: boolean;
427
443
  data: import("@/index.js").Row[];
428
444
  visibleColumns: string[];
429
445
  }> & Omit<{
@@ -436,6 +452,7 @@ declare const _default: import("vue").DefineComponent<{
436
452
  readonly checkable: boolean;
437
453
  readonly checkedRows: import("@/index.js").Row[];
438
454
  readonly isRowCheckable: Function;
455
+ readonly virtualScrolling: boolean;
439
456
  readonly data: import("@/index.js").Row[];
440
457
  readonly rowTo?: ((row: import("@/index.js").CollectionItem) => import("vue-router").RouteLocationRaw) | undefined;
441
458
  readonly rowHref?: ((row: import("@/index.js").CollectionItem) => string) | undefined;
@@ -517,6 +534,10 @@ declare const _default: import("vue").DefineComponent<{
517
534
  default: undefined;
518
535
  type: PropType<((row: import("@/index.js").CollectionItem) => string | number) | undefined>;
519
536
  };
537
+ virtualScrolling: {
538
+ default: boolean;
539
+ type: BooleanConstructor;
540
+ };
520
541
  }>> & {
521
542
  onCheck?: ((...args: any[]) => any) | undefined;
522
543
  onSort?: ((...args: any[]) => any) | undefined;
@@ -527,7 +548,7 @@ declare const _default: import("vue").DefineComponent<{
527
548
  "onUpdate:openedDetailed"?: ((...args: any[]) => any) | undefined;
528
549
  "onCell-click"?: ((...args: any[]) => any) | undefined;
529
550
  "onRow-click"?: ((...args: any[]) => any) | undefined;
530
- }, "size" | "loading" | "sortField" | "sortDirection" | "rowTo" | "rowHref" | "onRowClick" | "detailed" | "hasDetailedVisible" | "checkable" | "checkedRows" | "isRowCheckable" | "maxHeight" | "rowKey" | "data" | "visibleColumns">;
551
+ }, "size" | "loading" | "sortField" | "sortDirection" | "rowTo" | "rowHref" | "onRowClick" | "detailed" | "hasDetailedVisible" | "checkable" | "checkedRows" | "isRowCheckable" | "maxHeight" | "rowKey" | "virtualScrolling" | "data" | "visibleColumns">;
531
552
  $attrs: {
532
553
  [x: string]: unknown;
533
554
  };
@@ -606,6 +627,10 @@ declare const _default: import("vue").DefineComponent<{
606
627
  default: undefined;
607
628
  type: PropType<((row: import("@/index.js").CollectionItem) => string | number) | undefined>;
608
629
  };
630
+ virtualScrolling: {
631
+ default: boolean;
632
+ type: BooleanConstructor;
633
+ };
609
634
  }>> & {
610
635
  onCheck?: ((...args: any[]) => any) | undefined;
611
636
  onSort?: ((...args: any[]) => any) | undefined;
@@ -667,6 +692,7 @@ declare const _default: import("vue").DefineComponent<{
667
692
  isRowCheckable: Function;
668
693
  maxHeight: number;
669
694
  rowKey: ((row: import("@/index.js").CollectionItem) => string | number) | undefined;
695
+ virtualScrolling: boolean;
670
696
  data: import("@/index.js").Row[];
671
697
  visibleColumns: string[];
672
698
  }, {}, string, {}> & {
@@ -754,6 +780,10 @@ declare const _default: import("vue").DefineComponent<{
754
780
  default: undefined;
755
781
  type: PropType<((row: import("@/index.js").CollectionItem) => string | number) | undefined>;
756
782
  };
783
+ virtualScrolling: {
784
+ default: boolean;
785
+ type: BooleanConstructor;
786
+ };
757
787
  }>> & {
758
788
  onCheck?: ((...args: any[]) => any) | undefined;
759
789
  onSort?: ((...args: any[]) => any) | undefined;
@@ -236,6 +236,13 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
236
236
  default: undefined;
237
237
  type: PropType<(row: CollectionItem) => string | number>;
238
238
  };
239
+ /**
240
+ * Virtual scrolling
241
+ */
242
+ virtualScrolling: {
243
+ default: boolean;
244
+ type: BooleanConstructor;
245
+ };
239
246
  }, {
240
247
  fetch: typeof fetch;
241
248
  fetchWithoutLoading: typeof fetchWithoutLoading;
@@ -476,6 +483,13 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
476
483
  default: undefined;
477
484
  type: PropType<(row: CollectionItem) => string | number>;
478
485
  };
486
+ /**
487
+ * Virtual scrolling
488
+ */
489
+ virtualScrolling: {
490
+ default: boolean;
491
+ type: BooleanConstructor;
492
+ };
479
493
  }>> & {
480
494
  onDelete?: ((...args: any[]) => any) | undefined;
481
495
  "onUpdate:checked-rows"?: ((...args: any[]) => any) | undefined;
@@ -515,6 +529,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
515
529
  rowActions: RowAction[];
516
530
  numberOfVisibleRowActions: number;
517
531
  rowKey: (row: CollectionItem) => string | number;
532
+ virtualScrolling: boolean;
518
533
  }, {}>, Partial<Record<string, (_: {}) => any>> & {
519
534
  default?(_: {}): any;
520
535
  detail?(_: {
@@ -82,6 +82,10 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
82
82
  default: undefined;
83
83
  type: PropType<((row: CollectionItem) => string | number) | undefined>;
84
84
  };
85
+ virtualScrolling: {
86
+ default: boolean;
87
+ type: BooleanConstructor;
88
+ };
85
89
  }, {
86
90
  newColumns: import("vue").ComputedRef<{
87
91
  id: string;
@@ -195,6 +199,10 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
195
199
  default: undefined;
196
200
  type: PropType<((row: CollectionItem) => string | number) | undefined>;
197
201
  };
202
+ virtualScrolling: {
203
+ default: boolean;
204
+ type: BooleanConstructor;
205
+ };
198
206
  }>> & {
199
207
  onCheck?: ((...args: any[]) => any) | undefined;
200
208
  onSort?: ((...args: any[]) => any) | undefined;
@@ -220,6 +228,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
220
228
  isRowCheckable: Function;
221
229
  maxHeight: number;
222
230
  rowKey: ((row: CollectionItem) => string | number) | undefined;
231
+ virtualScrolling: boolean;
223
232
  data: Row[];
224
233
  visibleColumns: string[];
225
234
  }, {}>, {
@@ -9,6 +9,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
9
9
  class?: ClassNameValue;
10
10
  maxHeight?: number | undefined;
11
11
  loading?: boolean | undefined;
12
+ virtualScrolling?: boolean | undefined;
12
13
  }>, {
13
14
  size: string;
14
15
  fixedHeader: boolean;
@@ -18,6 +19,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
18
19
  class: undefined;
19
20
  maxHeight: undefined;
20
21
  loading: boolean;
22
+ virtualScrolling: boolean;
21
23
  }>, {
22
24
  scrollTop: typeof scrollTop;
23
25
  }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<{
@@ -29,6 +31,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
29
31
  class?: ClassNameValue;
30
32
  maxHeight?: number | undefined;
31
33
  loading?: boolean | undefined;
34
+ virtualScrolling?: boolean | undefined;
32
35
  }>, {
33
36
  size: string;
34
37
  fixedHeader: boolean;
@@ -38,11 +41,13 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
38
41
  class: undefined;
39
42
  maxHeight: undefined;
40
43
  loading: boolean;
44
+ virtualScrolling: boolean;
41
45
  }>>>, {
42
46
  class: string | false | 0 | 0n | ClassNameValue[] | null;
43
47
  size: "xs" | "sm" | "md" | "lg" | "xl";
44
48
  loading: boolean;
45
49
  maxHeight: number;
50
+ virtualScrolling: boolean;
46
51
  fixedHeader: boolean;
47
52
  fixedColumn: boolean;
48
53
  striped: boolean;
@@ -6,6 +6,7 @@ export interface TableProps {
6
6
  fixedHeader?: boolean;
7
7
  fixedColumn?: boolean;
8
8
  striped?: boolean;
9
+ virtualScrolling?: boolean;
9
10
  }
10
11
  export type CellConfig = TableProps;
11
12
  export interface CellProps {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sprintify-ui",
3
- "version": "0.8.25",
3
+ "version": "0.8.27",
4
4
  "scripts": {
5
5
  "build": "rimraf dist && vue-tsc && vite build",
6
6
  "build-fast": "rimraf dist && vite build",
@@ -7,7 +7,7 @@ import BaseAppSnackbars from './BaseAppSnackbars.vue';
7
7
  import BaseAppDialogs from './BaseAppDialogs.vue';
8
8
  import { computed, onBeforeUnmount } from 'vue';
9
9
  import { DateTime } from 'luxon';
10
- import { options, templateDataTable } from '../../.storybook/utils';
10
+ import { optionsLarge, templateDataTable } from '../../.storybook/utils';
11
11
  import { cloneDeep } from 'lodash';
12
12
 
13
13
  export default {
@@ -30,7 +30,7 @@ export default {
30
30
  args: {
31
31
  url: 'https://effettandem.com/api/content/articles',
32
32
  urlQuery: {
33
- per_page: 10,
33
+ per_page: 100,
34
34
  },
35
35
  historyMode: false,
36
36
  },
@@ -240,7 +240,7 @@ const LocalTemplate = (args) => ({
240
240
  };
241
241
 
242
242
  const filteredItems = computed(() => {
243
- return options
243
+ return optionsLarge
244
244
  .filter((item) => {
245
245
  const type = baseDataTableRef.value?.query.filter?.type ?? '';
246
246
 
@@ -339,3 +339,13 @@ localProps.rowTo = undefined;
339
339
  localProps.maxHeight = undefined;
340
340
  localProps.rowKey = (row) => row.value;
341
341
  Local.args = localProps;
342
+
343
+ export const VirtualScrolling = LocalTemplate.bind({});
344
+ const localProps2 = cloneDeep(componentProps);
345
+ localProps2.url = null;
346
+ localProps2.perPage = 500;
347
+ localProps2.rowTo = undefined;
348
+ localProps2.maxHeight = undefined;
349
+ localProps2.rowKey = (row) => row.value;
350
+ localProps2.virtualScrolling = true;
351
+ VirtualScrolling.args = localProps2;
@@ -83,6 +83,7 @@
83
83
  :row-to="rowToInternal"
84
84
  :row-href="rowHref"
85
85
  :row-key="rowKey"
86
+ :virtual-scrolling="virtualScrolling"
86
87
  @update:checked-rows="onCheckedRowsUpdate"
87
88
  @sort="dataIteratorProps.onSortChange"
88
89
  @row-click="onRowClick"
@@ -542,6 +543,14 @@ const props = defineProps({
542
543
  default: undefined,
543
544
  type: Function as PropType<(row: CollectionItem) => string | number>,
544
545
  },
546
+
547
+ /**
548
+ * Virtual scrolling
549
+ */
550
+ virtualScrolling: {
551
+ default: false,
552
+ type: Boolean,
553
+ },
545
554
  });
546
555
 
547
556
  const sizeInternal = useInputSize(props.size);
@@ -20,6 +20,7 @@
20
20
  :fixed-column="true"
21
21
  :max-height="maxHeight"
22
22
  :loading="loading"
23
+ :virtual-scrolling="virtualScrolling"
23
24
  >
24
25
  <BaseTableHead v-if="newColumns.length">
25
26
  <BaseTableRow>
@@ -99,7 +100,9 @@
99
100
  </BaseTableRow>
100
101
  </BaseTableHead>
101
102
 
102
- <BaseTableBody class="bg-white">
103
+ <BaseTableBody
104
+ class="bg-white"
105
+ >
103
106
  <template
104
107
  v-for="(row, index) in data"
105
108
  :key="getRowKey(row)"
@@ -295,6 +298,10 @@ const props = defineProps({
295
298
  default: undefined,
296
299
  type: Function as PropType<((row: CollectionItem) => string | number) | undefined>,
297
300
  },
301
+ virtualScrolling: {
302
+ default: false,
303
+ type: Boolean,
304
+ },
298
305
  });
299
306
 
300
307
  const emit = defineEmits([
@@ -5,7 +5,7 @@ import BaseTableRow from './BaseTableRow.vue';
5
5
  import BaseTableCell from './BaseTableCell.vue';
6
6
  import BaseTableHeader from './BaseTableHeader.vue';
7
7
  import BaseBadge from './BaseBadge.vue';
8
- import { options } from '../../.storybook/utils';
8
+ import { options, optionsLarge } from '../../.storybook/utils';
9
9
 
10
10
  export default {
11
11
  title: 'Data/BaseTable',
@@ -47,7 +47,7 @@ const cellsTemplate = `<BaseTableCell class="font-medium whitespace-nowrap">
47
47
  {{ option.type ?? 'N/A' }}
48
48
  </BaseTableCell>
49
49
  <BaseTableCell class="whitespace-nowrap">
50
- Long description ...
50
+ Long description here to test the overflow and wrap the lorem ipsum dolor Et occaecat quis ex Lorem cupidatat deserunt culpa dolore. Est sit aliquip exercitation exercitation deserunt.
51
51
  </BaseTableCell>
52
52
  `;
53
53
 
@@ -65,7 +65,7 @@ const components = {
65
65
  const Template = (args) => ({
66
66
  components: components,
67
67
  setup() {
68
- return { args, options };
68
+ return { args, optionsLarge };
69
69
  },
70
70
  template: `
71
71
  <div class="border">
@@ -73,7 +73,7 @@ const Template = (args) => ({
73
73
  ${headTemplate}
74
74
  <BaseTableBody>
75
75
  <BaseTableRow
76
- v-for="option in options"
76
+ v-for="option in optionsLarge"
77
77
  :key="option.value"
78
78
  :href="'https://www.google.com/search?q=' + option.label"
79
79
  target="_blank"
@@ -100,6 +100,11 @@ Flush.args = {
100
100
  flush: true,
101
101
  };
102
102
 
103
+ export const VirtualScroll = Template.bind({});
104
+ VirtualScroll.args = {
105
+ virtualScrolling: true,
106
+ };
107
+
103
108
  export const FixedHeader = Template.bind({});
104
109
  FixedHeader.args = {
105
110
  fixedHeader: true,
@@ -40,6 +40,7 @@ import { ClassNameValue, twMerge } from 'tailwind-merge';
40
40
  import { useScroll } from '@vueuse/core';
41
41
  import BaseSpinnerLarge from '@/svg/BaseSpinnerLarge.vue';
42
42
  import { Size } from '@/utils/sizes';
43
+ import { Ref } from 'vue';
43
44
 
44
45
  defineOptions({
45
46
  inheritAttrs: false,
@@ -54,6 +55,7 @@ const props = withDefaults(defineProps<{
54
55
  class?: ClassNameValue,
55
56
  maxHeight?: number,
56
57
  loading?: boolean,
58
+ virtualScrolling?: boolean,
57
59
  }>(), {
58
60
  size: 'md',
59
61
  fixedHeader: false,
@@ -63,6 +65,7 @@ const props = withDefaults(defineProps<{
63
65
  class: undefined,
64
66
  maxHeight: undefined,
65
67
  loading: false,
68
+ virtualScrolling: false,
66
69
  });
67
70
 
68
71
  const classes = computed(() => {
@@ -95,8 +98,21 @@ function scrollTop() {
95
98
  }
96
99
  }
97
100
 
101
+ // Virtual Scrolling
102
+
103
+ const virtualScrollingDefaultRowHeight = ref(null) as Ref<number | null | undefined>;
104
+ function setVirtualScrollingDefaultRowHeight(height: number) {
105
+ virtualScrollingDefaultRowHeight.value = height;
106
+ }
107
+
108
+ // Provide
109
+
98
110
  provide('table:props', computed(() => props));
99
111
  provide('table:horizontalScrolling', computed(() => horizontalScrolling.value));
112
+ provide('table:virtualScrollingDefaultRowHeight', computed(() => virtualScrollingDefaultRowHeight.value));
113
+ provide('table:setVirtualScrollingDefaultRowHeight', setVirtualScrollingDefaultRowHeight);
114
+
115
+ // Expose
100
116
 
101
117
  defineExpose({
102
118
  scrollTop,
@@ -1,6 +1,5 @@
1
1
  <template>
2
2
  <td
3
- ref="tdRef"
4
3
  :align="align"
5
4
  :colspan="colspan"
6
5
  :class="classes"
@@ -131,7 +130,7 @@ const classes = computed(() => {
131
130
  const selected = baseTableRowSelected?.value;
132
131
 
133
132
  const base = cellClasses(cellConfig.value);
134
- const baseTd = 'relative border-b group-last/row:border-b-0';
133
+ const baseTd = 'relative first:border-r border-b group-last/row:border-b-0';
135
134
  const click = clickable.value ? 'cursor-pointer' : '';
136
135
 
137
136
  let backgroundColor = baseTableStriped.value ? 'group-even/row:bg-slate-100/70' : 'bg-white';
@@ -150,8 +149,14 @@ const classes = computed(() => {
150
149
  borderColor = 'border-slate-300';
151
150
  }
152
151
 
153
- const firstCol = 'first:border-r first:border-r-transparent';
154
- const horizontalScrolling = baseTable?.value.fixedColumn && baseTableHorizontalScrolling?.value ? 'first:sticky first:z-[1] first:left-0 first:border-r-slate-200' : '';
152
+ let borderColorRight = 'first:border-r-transparent';
153
+
154
+ const hasHorizontalScrolling = baseTable?.value.fixedColumn && baseTableHorizontalScrolling?.value;
155
+ if (hasHorizontalScrolling) {
156
+ borderColorRight = 'first:border-r-slate-200';
157
+ }
158
+
159
+ const horizontalScrolling = hasHorizontalScrolling ? 'first:sticky first:z-[1] first:left-0' : '';
155
160
  const flush = baseTable?.value.flush ? 'first:pl-0 last:pr-0' : '';
156
161
 
157
162
  const internalClasses = [
@@ -160,7 +165,7 @@ const classes = computed(() => {
160
165
  click,
161
166
  backgroundColor,
162
167
  borderColor,
163
- firstCol,
168
+ borderColorRight,
164
169
  horizontalScrolling,
165
170
  flush,
166
171
  ];
@@ -175,8 +180,6 @@ const classes = computed(() => {
175
180
  );
176
181
  });
177
182
 
178
- const tdRef = ref<HTMLTableCellElement | null>(null);
179
-
180
183
  function onClick(event: MouseEvent) {
181
184
  propsInternal.value.onClick?.(event);
182
185
  }
@@ -2,27 +2,114 @@
2
2
  <tr
3
3
  ref="trRef"
4
4
  :class="classes"
5
+ :style="{
6
+ height: height ? `${height}px` : undefined,
7
+ }"
5
8
  @mouseenter="onMouseEnter"
6
9
  @mouseleave="onMouseLeave"
7
10
  >
8
- <slot />
11
+ <slot v-if="visible" />
12
+ <td
13
+ v-else
14
+ :class="cellClass"
15
+ >
16
+ .
17
+ </td>
9
18
  </tr>
10
19
  </template>
11
20
 
12
21
  <script lang="ts" setup>
13
22
  import { ClassNameValue, twMerge } from 'tailwind-merge';
14
23
  import { RouteLocationRaw } from 'vue-router';
24
+ import { useIntersectionObserver } from '@vueuse/core';
25
+ import { cellClasses } from '../services/table/classes';
26
+ import { CellConfig, TableProps } from '../services/table/types';
27
+ import { ComputedRef, Ref } from 'vue';
15
28
 
16
29
  defineOptions({
17
30
  inheritAttrs: false,
18
31
  });
19
32
 
20
- const baseTable = inject('table:props');
21
-
33
+ const baseTable = inject('table:props') as ComputedRef<TableProps> | undefined;
34
+ const baseTableHead = inject('tableHead:props', undefined);
22
35
  if (!baseTable) {
23
36
  throw new Error('baseTable must be used within a BaseTable.');
24
37
  }
25
38
 
39
+ const isHead = computed(() => baseTableHead !== undefined);
40
+
41
+ // Virtual scrolling
42
+
43
+ const baseTableVirtualScrollingDefaultRowHeight = inject('table:virtualScrollingDefaultRowHeight', undefined) as ComputedRef<number> | undefined;
44
+ const setVirtualScrollingDefaultRowHeight = inject('table:setVirtualScrollingDefaultRowHeight', undefined) as ((height: number) => void) | undefined;
45
+
46
+ const inViewport = ref(false);
47
+ const trRef = ref<HTMLTableRowElement | null>(null);
48
+
49
+ const trRenderedHeight = ref(undefined) as Ref<number | undefined>;
50
+
51
+ const height = computed(() => {
52
+ if (isHead.value) {
53
+ return undefined;
54
+ }
55
+
56
+ if (trRenderedHeight.value) {
57
+ return trRenderedHeight.value;
58
+ }
59
+
60
+ return baseTableVirtualScrollingDefaultRowHeight?.value ?? undefined;
61
+ });
62
+
63
+ const visible = computed(() => {
64
+ if (isHead.value) {
65
+ return true;
66
+ }
67
+
68
+ if (baseTable.value.virtualScrolling) {
69
+ return inViewport.value;
70
+ }
71
+
72
+ return true;
73
+ });
74
+
75
+ const cellConfig = computed<CellConfig>(() => {
76
+ return {
77
+ size: baseTable?.value?.size,
78
+ flush: baseTable?.value?.flush,
79
+ head: false,
80
+ }
81
+ });
82
+
83
+ const cellClass = computed(() => {
84
+ return cellClasses(cellConfig.value) + ' text-white border-t border-gray-200';
85
+ });
86
+
87
+ if (!isHead.value && baseTable.value.virtualScrolling) {
88
+
89
+ const margin = '300px';
90
+
91
+ useIntersectionObserver(
92
+ trRef,
93
+ ([{ isIntersecting }]) => {
94
+
95
+ inViewport.value = isIntersecting;
96
+
97
+ if (isIntersecting) {
98
+ nextTick(() => {
99
+ trRenderedHeight.value = trRef.value?.offsetHeight;
100
+
101
+ if (trRenderedHeight.value && setVirtualScrollingDefaultRowHeight) {
102
+ setVirtualScrollingDefaultRowHeight(trRenderedHeight.value);
103
+ }
104
+ });
105
+ }
106
+ },
107
+ {
108
+ rootMargin: margin,
109
+ }
110
+ );
111
+ }
112
+
26
113
  const emit = defineEmits(['click', 'mouseenter', 'mouseleave']);
27
114
 
28
115
  const props = withDefaults(defineProps<{
@@ -43,13 +130,6 @@ const props = withDefaults(defineProps<{
43
130
  onClick: undefined,
44
131
  });
45
132
 
46
- const trRef = ref<null | HTMLTableRowElement>(null);
47
- const parent = ref<null | undefined | HTMLElement>(null);
48
-
49
- onMounted(() => {
50
- parent.value = trRef.value?.parentElement;
51
- });
52
-
53
133
  const classes = computed(() => {
54
134
  const base = 'group/row';
55
135
 
@@ -8,6 +8,7 @@ export interface TableProps {
8
8
  fixedHeader?: boolean;
9
9
  fixedColumn?: boolean;
10
10
  striped?: boolean;
11
+ virtualScrolling?: boolean;
11
12
  }
12
13
 
13
14
  export type CellConfig = TableProps;