@meistrari/tela-build 1.3.0 → 1.4.0
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/components/tela/badge/badge.vue +1 -1
- package/components/tela/button/button.vue +0 -1
- package/components/tela/collapsible/CollapsibleContent.vue +2 -2
- package/components/tela/combobox/combobox-list.vue +0 -2
- package/components/tela/complex-table/complex-table-cell.stories.ts +1 -2
- package/components/tela/complex-table/complex-table-cell.vue +8 -7
- package/components/tela/complex-table/complex-table-header-cell.stories.ts +1 -2
- package/components/tela/complex-table/complex-table-header.stories.ts +1 -2
- package/components/tela/complex-table/complex-table-virtualized.vue +3 -7
- package/components/tela/complex-table/complex-table.mdx +490 -0
- package/components/tela/complex-table/complex-table.stories.ts +1 -2
- package/components/tela/complex-table/complex-table.vue +3 -6
- package/components/tela/icon/custom.vue +23 -43
- package/components/tela/input/tela-input.vue +1 -1
- package/components/tela/modal/modal.vue +4 -29
- package/components/tela/scroll-area/scroll-area.vue +2 -9
- package/components/tela/segment-toggle.vue +1 -1
- package/components/tela/status/status.mdx +0 -5
- package/components/tela/status/status.stories.ts +0 -12
- package/components/tela/status/status.vue +16 -3
- package/css/text.css +0 -13
- package/package.json +8 -8
- package/utils/empty-or-null.ts +30 -0
- package/components/tela/todo-list/todo-list.vue +0 -130
- package/components/tela/tool-use-display/tool-use-display-details-modal.vue +0 -182
- package/components/tela/tool-use-display/tool-use-display.vue +0 -145
|
@@ -22,7 +22,7 @@ const tag = computed(() => props.to ? NuxtLink : 'div')
|
|
|
22
22
|
:class="cn(
|
|
23
23
|
'inline-block px-[5px] rounded-[5px] select-none',
|
|
24
24
|
variant === 'outline' && 'border-[0.5px] ring-border-strong',
|
|
25
|
-
variant === 'filled' && 'bg-lowered',
|
|
25
|
+
variant === 'filled' && 'bg-background-lowered',
|
|
26
26
|
props.class,
|
|
27
27
|
)"
|
|
28
28
|
>
|
|
@@ -21,10 +21,10 @@ function handleOpenAutoComplete() {
|
|
|
21
21
|
<CollapsibleContent
|
|
22
22
|
v-bind="props"
|
|
23
23
|
data-collapsible-content
|
|
24
|
-
class="overflow-hidden collapsible-content
|
|
24
|
+
class="overflow-hidden collapsible-content"
|
|
25
25
|
@animation-start="handleOpenAutoComplete"
|
|
26
26
|
>
|
|
27
|
-
<div ref="containerEl"
|
|
27
|
+
<div ref="containerEl">
|
|
28
28
|
<slot />
|
|
29
29
|
</div>
|
|
30
30
|
</CollapsibleContent>
|
|
@@ -10,8 +10,6 @@ import {
|
|
|
10
10
|
} from 'reka-ui'
|
|
11
11
|
import type { ComboboxContentEmits, ComboboxContentProps } from 'reka-ui'
|
|
12
12
|
|
|
13
|
-
import { cn } from '@/lib/utils'
|
|
14
|
-
|
|
15
13
|
const props = withDefaults(
|
|
16
14
|
defineProps<ComboboxContentProps & { class?: HTMLAttributes['class'], hasAnimate?: boolean, disablePortal?: boolean }>(),
|
|
17
15
|
{
|
|
@@ -2,9 +2,8 @@ import type { Meta, StoryObj } from '@storybook/vue3'
|
|
|
2
2
|
import TelaComplexTableCell from './complex-table-cell.vue'
|
|
3
3
|
|
|
4
4
|
const meta = {
|
|
5
|
-
title: 'Components/
|
|
5
|
+
title: 'Components/ComplexTable/ComplexTableCell',
|
|
6
6
|
component: TelaComplexTableCell,
|
|
7
|
-
tags: ['autodocs'],
|
|
8
7
|
parameters: {
|
|
9
8
|
layout: 'centered',
|
|
10
9
|
docs: {
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import { hasEmptyOrNull } from '
|
|
2
|
+
import { hasEmptyOrNull } from '~/utils/empty-or-null'
|
|
3
3
|
import type { Column, Row } from './types'
|
|
4
4
|
import { hasError } from './utils'
|
|
5
|
-
import { useI18n } from 'vue-i18n'
|
|
6
5
|
|
|
7
6
|
defineOptions({
|
|
8
7
|
name: 'TelaComplexTableCell',
|
|
9
8
|
})
|
|
10
|
-
|
|
9
|
+
|
|
10
|
+
const props = withDefaults(defineProps<{
|
|
11
11
|
column: Column
|
|
12
12
|
row: Row
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
itemsLabel?: string
|
|
14
|
+
}>(), {
|
|
15
|
+
itemsLabel: 'items',
|
|
16
|
+
})
|
|
16
17
|
|
|
17
18
|
const content = computed(() => {
|
|
18
19
|
const data = props.row.data ?? {}
|
|
@@ -37,7 +38,7 @@ const icon = computed(() => props.row.icons?.find(icon => icon?.key === props.co
|
|
|
37
38
|
{{ content }}
|
|
38
39
|
</p>
|
|
39
40
|
<p v-else line-clamp-2 flex items-center gap-4px text-nowrap>
|
|
40
|
-
<span>{{ content.length }} {{
|
|
41
|
+
<span>{{ content.length }} {{ itemsLabel }} </span>
|
|
41
42
|
<TelaIcon name="i-ph-sort-ascending" size="md" mr-2px shrink-0 />
|
|
42
43
|
</p>
|
|
43
44
|
</div>
|
|
@@ -2,9 +2,8 @@ import type { Meta, StoryObj } from '@storybook/vue3'
|
|
|
2
2
|
import TelaComplexTableHeaderCell from './complex-table-header-cell.vue'
|
|
3
3
|
|
|
4
4
|
const meta = {
|
|
5
|
-
title: 'Components/
|
|
5
|
+
title: 'Components/ComplexTable/ComplexTableHeaderCell',
|
|
6
6
|
component: TelaComplexTableHeaderCell,
|
|
7
|
-
tags: ['autodocs'],
|
|
8
7
|
parameters: {
|
|
9
8
|
layout: 'centered',
|
|
10
9
|
docs: {
|
|
@@ -15,9 +15,8 @@ const sampleRows = [
|
|
|
15
15
|
]
|
|
16
16
|
|
|
17
17
|
const meta = {
|
|
18
|
-
title: 'Components/
|
|
18
|
+
title: 'Components/ComplexTable/ComplexTableHeader',
|
|
19
19
|
component: TelaComplexTableHeader,
|
|
20
|
-
tags: ['autodocs'],
|
|
21
20
|
parameters: {
|
|
22
21
|
layout: 'centered',
|
|
23
22
|
docs: {
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { ref, watch, onMounted, onUnmounted, nextTick, defineProps, defineEmits } from 'vue'
|
|
3
|
-
import { useNotification } from '../../../../application/composables/notification'
|
|
4
2
|
import type { Column, Row, ComplexTableType } from './types'
|
|
5
3
|
import { HoverMechanismTypes } from './types'
|
|
6
4
|
import TelaTableHeader from './complex-table-header.vue'
|
|
@@ -17,13 +15,12 @@ const emit = defineEmits<{
|
|
|
17
15
|
(event: 'loadMore'): void
|
|
18
16
|
(event: 'open', id: string): void
|
|
19
17
|
(event: 'scroll', scrollEvent: Event): void
|
|
18
|
+
(event: 'error', error: Error): void
|
|
20
19
|
}>()
|
|
21
20
|
|
|
22
|
-
const notification = useNotification()
|
|
23
21
|
const slots = useSlots()
|
|
24
22
|
|
|
25
23
|
const mainTableEl = ref<HTMLElement>()
|
|
26
|
-
const containerEl = ref<HTMLElement>()
|
|
27
24
|
|
|
28
25
|
// Use table composables
|
|
29
26
|
const {
|
|
@@ -126,8 +123,8 @@ watch(() => virtualScroll?.range.value, async (newRange) => {
|
|
|
126
123
|
}, 300)
|
|
127
124
|
}
|
|
128
125
|
catch (error) {
|
|
129
|
-
notification.error('Load More Failed', (error as Error).message)
|
|
130
126
|
isLoadingMore.value = false
|
|
127
|
+
emit('error', error instanceof Error ? error : new Error(String(error)))
|
|
131
128
|
}
|
|
132
129
|
}
|
|
133
130
|
}, { deep: true })
|
|
@@ -139,7 +136,7 @@ if (!virtualScroll) {
|
|
|
139
136
|
emit('loadMore')
|
|
140
137
|
}
|
|
141
138
|
catch (error) {
|
|
142
|
-
|
|
139
|
+
emit('error', error instanceof Error ? error : new Error(String(error)))
|
|
143
140
|
}
|
|
144
141
|
}, { distance: 100, direction: 'bottom' })
|
|
145
142
|
}
|
|
@@ -183,7 +180,6 @@ watch([hasRowIndex, hasSelect, mainTableEl], () => {
|
|
|
183
180
|
|
|
184
181
|
<template>
|
|
185
182
|
<div
|
|
186
|
-
ref="containerEl"
|
|
187
183
|
rounded-12px flex="~"
|
|
188
184
|
b="0.5px gray-300"
|
|
189
185
|
overflow-hidden
|
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
|
|
2
|
+
import * as ComplexTableStories from './complex-table.stories.ts';
|
|
3
|
+
|
|
4
|
+
<Meta of={ComplexTableStories} />
|
|
5
|
+
|
|
6
|
+
# TelaComplexTable
|
|
7
|
+
|
|
8
|
+
A powerful and flexible table component with advanced features including column management, row selection, sorting, status indicators, custom cell rendering, hover interactions, and virtualized rendering for large datasets. Perfect for data-heavy applications requiring sophisticated table functionality.
|
|
9
|
+
|
|
10
|
+
## Examples
|
|
11
|
+
|
|
12
|
+
### Basic Usage
|
|
13
|
+
|
|
14
|
+
```vue
|
|
15
|
+
<script setup>
|
|
16
|
+
import { ref } from 'vue'
|
|
17
|
+
|
|
18
|
+
const columns = [
|
|
19
|
+
{ title: 'Name', key: 'name', isDefault: false },
|
|
20
|
+
{ title: 'Status', key: 'status', isDefault: false },
|
|
21
|
+
{ title: 'Created', key: 'created', isDefault: true },
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
const rows = [
|
|
25
|
+
{
|
|
26
|
+
id: '1',
|
|
27
|
+
index: 1,
|
|
28
|
+
status: 'success',
|
|
29
|
+
name: 'Project Alpha',
|
|
30
|
+
data: {
|
|
31
|
+
name: 'Project Alpha',
|
|
32
|
+
status: 'Active',
|
|
33
|
+
created: '2024-01-15',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: '2',
|
|
38
|
+
index: 2,
|
|
39
|
+
status: 'success',
|
|
40
|
+
name: 'Project Beta',
|
|
41
|
+
data: {
|
|
42
|
+
name: 'Project Beta',
|
|
43
|
+
status: 'Pending',
|
|
44
|
+
created: '2024-01-16',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
]
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<template>
|
|
51
|
+
<TelaComplexTable
|
|
52
|
+
:columns="columns"
|
|
53
|
+
:rows="rows"
|
|
54
|
+
row-title-path="data.name"
|
|
55
|
+
row-index-path="index"
|
|
56
|
+
:allow-row-index="true"
|
|
57
|
+
/>
|
|
58
|
+
</template>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### With Row Selection
|
|
62
|
+
|
|
63
|
+
```vue
|
|
64
|
+
<script setup>
|
|
65
|
+
import { ref } from 'vue'
|
|
66
|
+
|
|
67
|
+
const selectedRows = ref<string[]>([])
|
|
68
|
+
const columns = [
|
|
69
|
+
{ title: 'Name', key: 'name' },
|
|
70
|
+
{ title: 'Status', key: 'status' },
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
const rows = [
|
|
74
|
+
{
|
|
75
|
+
id: '1',
|
|
76
|
+
index: 1,
|
|
77
|
+
status: 'success',
|
|
78
|
+
name: 'Item 1',
|
|
79
|
+
data: { name: 'Item 1', status: 'Active' },
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: '2',
|
|
83
|
+
index: 2,
|
|
84
|
+
status: 'success',
|
|
85
|
+
name: 'Item 2',
|
|
86
|
+
data: { name: 'Item 2', status: 'Pending' },
|
|
87
|
+
},
|
|
88
|
+
]
|
|
89
|
+
</script>
|
|
90
|
+
|
|
91
|
+
<template>
|
|
92
|
+
<TelaComplexTable
|
|
93
|
+
v-model:selected-rows="selectedRows"
|
|
94
|
+
:columns="columns"
|
|
95
|
+
:rows="rows"
|
|
96
|
+
row-title-path="data.name"
|
|
97
|
+
row-index-path="index"
|
|
98
|
+
:allow-select="true"
|
|
99
|
+
:allow-row-index="true"
|
|
100
|
+
@select="(ids, isAll) => console.log('Selected:', ids, isAll)"
|
|
101
|
+
/>
|
|
102
|
+
</template>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### With Custom Headers
|
|
106
|
+
|
|
107
|
+
```vue
|
|
108
|
+
<template>
|
|
109
|
+
<TelaComplexTable
|
|
110
|
+
:columns="columns"
|
|
111
|
+
:rows="rows"
|
|
112
|
+
row-title-path="data.name"
|
|
113
|
+
row-index-path="index"
|
|
114
|
+
>
|
|
115
|
+
<template #header-name="{ column }">
|
|
116
|
+
<div class="flex items-center gap-2 px-4 py-2">
|
|
117
|
+
<span class="font-medium">{{ column.title }}</span>
|
|
118
|
+
<button @click="sortByName">Sort</button>
|
|
119
|
+
</div>
|
|
120
|
+
</template>
|
|
121
|
+
|
|
122
|
+
<template #leading-header>
|
|
123
|
+
<div class="flex items-center px-4 h-56px w-full">
|
|
124
|
+
Custom Leading Header
|
|
125
|
+
</div>
|
|
126
|
+
</template>
|
|
127
|
+
</TelaComplexTable>
|
|
128
|
+
</template>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### With Custom Cell Content
|
|
132
|
+
|
|
133
|
+
```vue
|
|
134
|
+
<template>
|
|
135
|
+
<TelaComplexTable
|
|
136
|
+
:columns="columns"
|
|
137
|
+
:rows="rows"
|
|
138
|
+
row-title-path="data.name"
|
|
139
|
+
row-index-path="index"
|
|
140
|
+
>
|
|
141
|
+
<template #name="{ rowData }">
|
|
142
|
+
<div class="px-4 py-2 text-blue-600 font-semibold">
|
|
143
|
+
{{ rowData.data.name }}
|
|
144
|
+
</div>
|
|
145
|
+
</template>
|
|
146
|
+
|
|
147
|
+
<template #status="{ rowData }">
|
|
148
|
+
<div class="px-4 py-2">
|
|
149
|
+
<span :class="getStatusClass(rowData.data.status)">
|
|
150
|
+
{{ rowData.data.status }}
|
|
151
|
+
</span>
|
|
152
|
+
</div>
|
|
153
|
+
</template>
|
|
154
|
+
</TelaComplexTable>
|
|
155
|
+
</template>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### With Row Hover
|
|
159
|
+
|
|
160
|
+
```vue
|
|
161
|
+
<template>
|
|
162
|
+
<TelaComplexTable
|
|
163
|
+
:columns="columns"
|
|
164
|
+
:rows="rows"
|
|
165
|
+
row-title-path="data.name"
|
|
166
|
+
row-index-path="index"
|
|
167
|
+
hover-mechanism="row"
|
|
168
|
+
@open="(id) => console.log('Opening row:', id)"
|
|
169
|
+
/>
|
|
170
|
+
</template>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### With Loading States
|
|
174
|
+
|
|
175
|
+
```vue
|
|
176
|
+
<template>
|
|
177
|
+
<TelaComplexTable
|
|
178
|
+
:columns="columns"
|
|
179
|
+
:rows="rows"
|
|
180
|
+
row-title-path="data.name"
|
|
181
|
+
row-index-path="index"
|
|
182
|
+
:loading="true"
|
|
183
|
+
/>
|
|
184
|
+
</template>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### With Error States
|
|
188
|
+
|
|
189
|
+
```vue
|
|
190
|
+
<script setup>
|
|
191
|
+
const rows = [
|
|
192
|
+
{
|
|
193
|
+
id: '1',
|
|
194
|
+
index: 1,
|
|
195
|
+
status: 'failed',
|
|
196
|
+
name: 'Failed Item',
|
|
197
|
+
errorMessage: 'Something went wrong loading this row',
|
|
198
|
+
data: {},
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
id: '2',
|
|
202
|
+
index: 2,
|
|
203
|
+
status: 'success',
|
|
204
|
+
name: 'Success Item',
|
|
205
|
+
data: { name: 'Success Item', status: 'Active' },
|
|
206
|
+
},
|
|
207
|
+
]
|
|
208
|
+
</script>
|
|
209
|
+
|
|
210
|
+
<template>
|
|
211
|
+
<TelaComplexTable
|
|
212
|
+
:columns="columns"
|
|
213
|
+
:rows="rows"
|
|
214
|
+
row-title-path="data.name"
|
|
215
|
+
row-index-path="index"
|
|
216
|
+
/>
|
|
217
|
+
</template>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### With Infinite Scroll
|
|
221
|
+
|
|
222
|
+
```vue
|
|
223
|
+
<script setup>
|
|
224
|
+
const handleLoadMore = async () => {
|
|
225
|
+
try {
|
|
226
|
+
// Load more data
|
|
227
|
+
await fetchMoreData()
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
// Handle error - the component will also emit an @error event
|
|
231
|
+
console.error('Failed to load more items:', error)
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const handleError = (error) => {
|
|
236
|
+
// Handle errors from loadMore operations
|
|
237
|
+
console.error('Load more error:', error)
|
|
238
|
+
// Show user notification, update UI, etc.
|
|
239
|
+
}
|
|
240
|
+
</script>
|
|
241
|
+
|
|
242
|
+
<template>
|
|
243
|
+
<TelaComplexTable
|
|
244
|
+
:columns="columns"
|
|
245
|
+
:rows="rows"
|
|
246
|
+
row-title-path="data.name"
|
|
247
|
+
row-index-path="index"
|
|
248
|
+
@load-more="handleLoadMore"
|
|
249
|
+
@error="handleError"
|
|
250
|
+
>
|
|
251
|
+
<template #footer>
|
|
252
|
+
<div class="px-4 text-gray-500">
|
|
253
|
+
Loading more items...
|
|
254
|
+
</div>
|
|
255
|
+
</template>
|
|
256
|
+
</TelaComplexTable>
|
|
257
|
+
</template>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### With Virtualization
|
|
261
|
+
|
|
262
|
+
```vue
|
|
263
|
+
<template>
|
|
264
|
+
<TelaComplexTable
|
|
265
|
+
:columns="columns"
|
|
266
|
+
:rows="rows"
|
|
267
|
+
row-title-path="data.name"
|
|
268
|
+
row-index-path="index"
|
|
269
|
+
:use-virtualization="true"
|
|
270
|
+
:virtualized-row-height="64"
|
|
271
|
+
:virtualized-overscan="5"
|
|
272
|
+
:virtualized-initial-batch-size="30"
|
|
273
|
+
/>
|
|
274
|
+
</template>
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### With Row Actions
|
|
278
|
+
|
|
279
|
+
```vue
|
|
280
|
+
<template>
|
|
281
|
+
<TelaComplexTable
|
|
282
|
+
:columns="columns"
|
|
283
|
+
:rows="rows"
|
|
284
|
+
row-title-path="data.name"
|
|
285
|
+
row-index-path="index"
|
|
286
|
+
>
|
|
287
|
+
<template #row-action="{ row }">
|
|
288
|
+
<button
|
|
289
|
+
class="px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600"
|
|
290
|
+
@click="handleAction(row.id)"
|
|
291
|
+
>
|
|
292
|
+
Action
|
|
293
|
+
</button>
|
|
294
|
+
</template>
|
|
295
|
+
</TelaComplexTable>
|
|
296
|
+
</template>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### With Custom Styling
|
|
300
|
+
|
|
301
|
+
```vue
|
|
302
|
+
<template>
|
|
303
|
+
<TelaComplexTable
|
|
304
|
+
:columns="columns"
|
|
305
|
+
:rows="rows"
|
|
306
|
+
row-title-path="data.name"
|
|
307
|
+
row-index-path="index"
|
|
308
|
+
:max-height="300"
|
|
309
|
+
header-class="bg-gray-50"
|
|
310
|
+
:row-class="(row) => row.status === 'success' ? 'bg-green-50' : ''"
|
|
311
|
+
columns-class="text-sm"
|
|
312
|
+
/>
|
|
313
|
+
</template>
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Empty State
|
|
317
|
+
|
|
318
|
+
```vue
|
|
319
|
+
<template>
|
|
320
|
+
<TelaComplexTable
|
|
321
|
+
:columns="columns"
|
|
322
|
+
:rows="[]"
|
|
323
|
+
row-title-path="data.name"
|
|
324
|
+
row-index-path="index"
|
|
325
|
+
>
|
|
326
|
+
<template #empty-state>
|
|
327
|
+
<div class="text-gray-500">
|
|
328
|
+
No data available
|
|
329
|
+
</div>
|
|
330
|
+
</template>
|
|
331
|
+
</TelaComplexTable>
|
|
332
|
+
</template>
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### With Leading Content
|
|
336
|
+
|
|
337
|
+
```vue
|
|
338
|
+
<template>
|
|
339
|
+
<TelaComplexTable
|
|
340
|
+
:columns="columns"
|
|
341
|
+
:rows="rows"
|
|
342
|
+
row-title-path="data.name"
|
|
343
|
+
row-index-path="index"
|
|
344
|
+
>
|
|
345
|
+
<template #leading="{ rowData, isLoading, rowTitle }">
|
|
346
|
+
<td>
|
|
347
|
+
<div class="px-4 py-2">
|
|
348
|
+
{{ isLoading ? 'Loading...' : rowTitle }}
|
|
349
|
+
</div>
|
|
350
|
+
</td>
|
|
351
|
+
</template>
|
|
352
|
+
</TelaComplexTable>
|
|
353
|
+
</template>
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## Props
|
|
357
|
+
|
|
358
|
+
<ArgTypes />
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
interface Column {
|
|
362
|
+
key?: string
|
|
363
|
+
title: string
|
|
364
|
+
isDefault?: boolean
|
|
365
|
+
icon?: {
|
|
366
|
+
name: string
|
|
367
|
+
size?: string
|
|
368
|
+
style?: string
|
|
369
|
+
}
|
|
370
|
+
color?: string
|
|
371
|
+
style?: string
|
|
372
|
+
class?: string
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
interface Row {
|
|
376
|
+
id?: string
|
|
377
|
+
index?: number
|
|
378
|
+
status: string
|
|
379
|
+
name: string
|
|
380
|
+
errorMessage?: string
|
|
381
|
+
data: Record<string, unknown>
|
|
382
|
+
isLoading?: boolean
|
|
383
|
+
isNew?: boolean
|
|
384
|
+
icons?: {
|
|
385
|
+
key: string
|
|
386
|
+
type?: string
|
|
387
|
+
name: string
|
|
388
|
+
size?: string
|
|
389
|
+
style?: string
|
|
390
|
+
}[]
|
|
391
|
+
color?: string
|
|
392
|
+
style?: string
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
type ComplexTableProps = {
|
|
396
|
+
columns: Column[]
|
|
397
|
+
rows: Row[]
|
|
398
|
+
rowTitlePath: string
|
|
399
|
+
rowIndexPath: string
|
|
400
|
+
allowSelect?: boolean
|
|
401
|
+
allowRowIndex?: boolean
|
|
402
|
+
loading?: boolean
|
|
403
|
+
maxHeight?: number
|
|
404
|
+
hoverMechanism?: 'row' | 'cell'
|
|
405
|
+
disableRowClick?: (row: Row) => boolean
|
|
406
|
+
selectedRows?: string[]
|
|
407
|
+
columnsClass?: string
|
|
408
|
+
rowClass?: string | ((row: Row) => string)
|
|
409
|
+
rowIndexClass?: string
|
|
410
|
+
headerClass?: string
|
|
411
|
+
hideScrollbar?: boolean
|
|
412
|
+
hideError?: boolean
|
|
413
|
+
useVirtualization?: boolean
|
|
414
|
+
virtualizedOverscan?: number
|
|
415
|
+
virtualizedRowHeight?: number
|
|
416
|
+
virtualizedInitialBatchSize?: number
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## Slots
|
|
421
|
+
|
|
422
|
+
- `leading` - Custom leading content for each row (receives `rowData`, `isLoading`, `rowTitle`, `rowEmit` as slot props)
|
|
423
|
+
- `leading-header` - Custom leading header content
|
|
424
|
+
- `header-{columnKey}` - Custom header for a specific column (receives `column` as slot prop)
|
|
425
|
+
- `{columnKey}` - Custom cell content for a specific column (receives `rowData`, `isLoading`, `rowTitle`, `rowEmit` as slot props)
|
|
426
|
+
- `row-action` - Custom action button/content for each row (receives `row` as slot prop)
|
|
427
|
+
- `footer` - Footer content displayed at the bottom of the table
|
|
428
|
+
- `empty-state` - Content displayed when there are no rows
|
|
429
|
+
|
|
430
|
+
## Components
|
|
431
|
+
|
|
432
|
+
The ComplexTable system consists of these sub-components:
|
|
433
|
+
- `TelaComplexTable` - Main table component
|
|
434
|
+
- `TelaComplexTableVirtualized` - Virtualized version for large datasets
|
|
435
|
+
- `TelaComplexTableHeader` - Table header component
|
|
436
|
+
- `TelaComplexTableRow` - Individual row component
|
|
437
|
+
- `TelaComplexTableCell` - Default cell component
|
|
438
|
+
- `TelaComplexTableHeaderCell` - Header cell component
|
|
439
|
+
|
|
440
|
+
## Features
|
|
441
|
+
|
|
442
|
+
- **Column Management**: Flexible column configuration with custom headers and cell rendering
|
|
443
|
+
- **Row Selection**: Single and multi-select with select-all functionality
|
|
444
|
+
- **Row Indexing**: Optional row numbering/indexing
|
|
445
|
+
- **Hover Interactions**: Row-level or cell-level hover mechanisms
|
|
446
|
+
- **Status Indicators**: Built-in support for loading, success, and error states
|
|
447
|
+
- **Custom Rendering**: Slot-based customization for headers, cells, and rows
|
|
448
|
+
- **Virtualization**: Automatic virtualization for large datasets with configurable options
|
|
449
|
+
- **Infinite Scroll**: Built-in infinite scroll support for lazy loading
|
|
450
|
+
- **Error Handling**: Display error messages for failed rows
|
|
451
|
+
- **Empty States**: Customizable empty state when no data is available
|
|
452
|
+
- **Sticky Headers**: Headers remain visible while scrolling
|
|
453
|
+
- **Sticky Columns**: Select and index columns remain visible horizontally
|
|
454
|
+
- **Custom Styling**: Flexible class and style customization
|
|
455
|
+
- **Row Actions**: Optional action column for row-specific actions
|
|
456
|
+
- **Footer Support**: Custom footer content
|
|
457
|
+
- **Keyboard Navigation**: Full keyboard support for accessibility
|
|
458
|
+
- **Responsive**: Adapts to different screen sizes
|
|
459
|
+
|
|
460
|
+
## Events
|
|
461
|
+
|
|
462
|
+
- `select` - Emitted when rows are selected/deselected with `(ids: string[], isAll: boolean)`
|
|
463
|
+
- `loadMore` - Emitted when user scrolls near the bottom (for infinite scroll). **Important**: Parent components should handle errors in their `@load-more` handler. If the handler is async and throws an error, it should be caught within the handler itself. The component provides an `@error` event for error communication, but errors from async parent handlers won't be automatically caught.
|
|
464
|
+
- `open` - Emitted when a row is clicked/opened with `(id: string)`
|
|
465
|
+
- `scroll` - Emitted when table is scrolled with `(scrollEvent: Event)`
|
|
466
|
+
- `error` - Emitted when an error occurs during loadMore operations with `(error: Error)`. Consumers should handle this event to display error notifications or update UI state. Note: This event is primarily for errors that occur within the component itself. For errors in async `@load-more` handlers, catch them within the handler and optionally emit them via a custom mechanism or handle them directly.
|
|
467
|
+
|
|
468
|
+
## Hover Mechanisms
|
|
469
|
+
|
|
470
|
+
- `row` - Entire row is hoverable and clickable
|
|
471
|
+
- `cell` - Individual cells are hoverable and clickable (default)
|
|
472
|
+
|
|
473
|
+
## Virtualization
|
|
474
|
+
|
|
475
|
+
When `useVirtualization` is enabled, the table automatically switches to a virtualized rendering mode that only renders visible rows. This is ideal for large datasets (1000+ rows) to maintain performance.
|
|
476
|
+
|
|
477
|
+
### Virtualization Props
|
|
478
|
+
|
|
479
|
+
- `virtualizedRowHeight` - Height of each row in pixels (default: 64)
|
|
480
|
+
- `virtualizedOverscan` - Number of rows to render outside the visible area (default: 5)
|
|
481
|
+
- `virtualizedInitialBatchSize` - Initial number of rows to render (default: 30)
|
|
482
|
+
|
|
483
|
+
## Accessibility
|
|
484
|
+
|
|
485
|
+
- Semantic HTML table structure
|
|
486
|
+
- Keyboard navigation support
|
|
487
|
+
- ARIA attributes for screen readers
|
|
488
|
+
- Focus management
|
|
489
|
+
- Proper table headers and relationships
|
|
490
|
+
|
|
@@ -4,9 +4,8 @@ import TelaComplexTable from './complex-table.vue'
|
|
|
4
4
|
import { HoverMechanismTypes } from './types'
|
|
5
5
|
|
|
6
6
|
const meta = {
|
|
7
|
-
title: 'Components/
|
|
7
|
+
title: 'Components/ComplexTable/ComplexTable',
|
|
8
8
|
component: TelaComplexTable,
|
|
9
|
-
tags: ['autodocs'],
|
|
10
9
|
parameters: {
|
|
11
10
|
layout: 'centered',
|
|
12
11
|
docs: {
|