@v1nt1248/3nclient-lib 0.1.1 → 0.1.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.
Files changed (55) hide show
  1. package/README.md +2 -0
  2. package/dist/components/index.d.ts +3 -3
  3. package/dist/components/ui3n-badge-simple.vue.d.ts +13 -13
  4. package/dist/components/ui3n-badge.vue.d.ts +18 -16
  5. package/dist/components/ui3n-breadcrumb.vue.d.ts +15 -13
  6. package/dist/components/ui3n-breadcrumbs.vue.d.ts +17 -15
  7. package/dist/components/ui3n-button.vue.d.ts +22 -19
  8. package/dist/components/ui3n-checkbox.vue.d.ts +17 -15
  9. package/dist/components/ui3n-chip.vue.d.ts +18 -16
  10. package/dist/components/ui3n-dialog.vue.d.ts +4 -5
  11. package/dist/components/ui3n-drop-files.vue.d.ts +16 -14
  12. package/dist/components/ui3n-emoji.vue.d.ts +11 -11
  13. package/dist/components/ui3n-icon.vue.d.ts +12 -12
  14. package/dist/components/ui3n-input.vue.d.ts +4 -4
  15. package/dist/components/ui3n-list.vue.d.ts +12 -39
  16. package/dist/components/ui3n-menu.vue.d.ts +14 -12
  17. package/dist/components/ui3n-notification.vue.d.ts +14 -15
  18. package/dist/components/ui3n-progress-circular.vue.d.ts +13 -13
  19. package/dist/components/ui3n-progress-linear.vue.d.ts +13 -13
  20. package/dist/components/ui3n-step-line-bar.vue.d.ts +11 -11
  21. package/dist/components/ui3n-switch.vue.d.ts +15 -13
  22. package/dist/components/ui3n-table/composables/useTable.d.ts +26 -0
  23. package/dist/components/ui3n-table/types.d.ts +65 -0
  24. package/dist/components/ui3n-table/ui3n-table.vue.d.ts +22 -0
  25. package/dist/components/ui3n-table-sort-icon.vue.d.ts +2 -2
  26. package/dist/components/ui3n-tabs.vue.d.ts +18 -16
  27. package/dist/components/ui3n-text.vue.d.ts +13 -13
  28. package/dist/components/ui3n-virtual-scroll.vue.d.ts +6 -28
  29. package/dist/directives/index.d.ts +0 -1
  30. package/dist/directives/ui3n-click-outside.d.ts +0 -1
  31. package/dist/directives/ui3n-html.d.ts +0 -1
  32. package/dist/index.d.ts +4 -1
  33. package/dist/plugins/dialogs.d.ts +0 -1
  34. package/dist/plugins/i18n.d.ts +0 -1
  35. package/dist/plugins/icons.d.ts +0 -1
  36. package/dist/plugins/index.d.ts +0 -1
  37. package/dist/plugins/notifications.d.ts +0 -1
  38. package/dist/plugins/store-dialogs.d.ts +0 -1
  39. package/dist/plugins/store-notifications.d.ts +0 -1
  40. package/dist/plugins/store-vue-bus.d.ts +0 -1
  41. package/dist/plugins/vue-bus.d.ts +0 -1
  42. package/dist/style.css +1 -1
  43. package/dist/tools/sqlite-on-3nstorage/index.d.ts +0 -1
  44. package/dist/tools/ui.helpers.d.ts +0 -1
  45. package/dist/ui-3n-lib.js +5471 -5634
  46. package/package.json +28 -27
  47. package/src/components/index.ts +34 -4
  48. package/src/components/ui3n-checkbox.vue +1 -1
  49. package/src/components/ui3n-dialog.vue +6 -1
  50. package/src/components/ui3n-table/composables/useTable.ts +206 -0
  51. package/src/components/ui3n-table/types.ts +80 -0
  52. package/src/components/ui3n-table/ui3n-table.vue +319 -0
  53. package/src/components/ui3n-table-sort-icon.vue +9 -6
  54. package/dist/components/ui3n-table.vue.d.ts +0 -36
  55. /package/src/components/{ui3n-table.vue → ui3n-table-simple.vue} +0 -0
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@v1nt1248/3nclient-lib",
3
3
  "license": "AGPL-3.0-or-later",
4
4
  "author": "v1nt1248",
5
- "version": "0.1.1",
5
+ "version": "0.1.2",
6
6
  "description": "Library for 3NWeb clients",
7
7
  "type": "module",
8
8
  "files": [
@@ -36,7 +36,7 @@
36
36
  "dependencies": {
37
37
  "@iconify-icons/ic": "1.2.13",
38
38
  "@iconify/vue": "4.1.2",
39
- "dayjs": "1.11.11",
39
+ "dayjs": "1.11.12",
40
40
  "lodash": "4.17.21",
41
41
  "mitt": "3.0.1",
42
42
  "sanitize-html": "2.13.0",
@@ -44,47 +44,48 @@
44
44
  "vuedraggable": "^4.1.0"
45
45
  },
46
46
  "peerDependencies": {
47
- "pinia": "2.1.7",
48
- "vue": "3.4.27"
47
+ "pinia": "2.2.1",
48
+ "vue": "3.4.37"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/lodash": "4.17.5",
52
52
  "@types/node": "20.14.2",
53
53
  "@types/sanitize-html": "2.11.0",
54
- "@typescript-eslint/eslint-plugin": "7.13.0",
55
- "@typescript-eslint/parser": "7.13.0",
56
- "@vitejs/plugin-vue": "5.0.5",
57
- "@vue/compiler-core": "3.4.27",
54
+ "@typescript-eslint/eslint-plugin": "8.0.1",
55
+ "@typescript-eslint/parser": "8.0.1",
56
+ "@vitejs/plugin-vue": "5.1.2",
57
+ "@vue/compiler-core": "3.4.37",
58
58
  "@vue/eslint-config-typescript": "13.0.0",
59
- "@vue/runtime-core": "3.4.27",
59
+ "@vue/runtime-core": "3.4.37",
60
60
  "@vuedx/typescript-plugin-vue": "0.7.6",
61
- "eslint": "9.4.0",
61
+ "eslint": "9.9.0",
62
62
  "eslint-config-prettier": "^9.1.0",
63
63
  "eslint-plugin-import": "2.29.1",
64
64
  "eslint-plugin-node": "11.1.0",
65
- "eslint-plugin-prettier": "^5.1.3",
66
- "eslint-plugin-promise": "6.2.0",
67
- "eslint-plugin-vue": "9.26.0",
68
- "jackspeak": "3.4.0",
65
+ "eslint-plugin-prettier": "^5.2.1",
66
+ "eslint-plugin-promise": "7.1.0",
67
+ "eslint-plugin-vue": "9.27.0",
68
+ "jackspeak": "4.0.1",
69
69
  "path": "0.12.7",
70
- "pinia": "2.1.7",
70
+ "pinia": "2.2.1",
71
71
  "postcss-html": "1.7.0",
72
72
  "prettier": "^3.3.3",
73
- "sass": "1.77.5",
74
- "stylelint": "16.6.1",
75
- "stylelint-config-recommended-scss": "14.0.0",
73
+ "sass": "1.77.8",
74
+ "stylelint": "16.8.1",
75
+ "stylelint-config-recommended-scss": "14.1.0",
76
76
  "stylelint-config-recommended-vue": "1.5.0",
77
- "stylelint-config-standard": "36.0.0",
78
- "stylelint-scss": "6.3.1",
79
- "typescript": "5.4.5",
80
- "vite": "5.2.13",
77
+ "stylelint-config-standard": "36.0.1",
78
+ "stylelint-scss": "6.5.0",
79
+ "typescript": "5.5.4",
80
+ "vite": "5.4.0",
81
81
  "vite-plugin-css-injected-by-js": "3.5.1",
82
- "vite-plugin-dts": "3.9.1",
83
- "vitepress": "1.2.3",
84
- "vue": "3.4.27",
85
- "vue-tsc": "2.0.21"
82
+ "vite-plugin-dts": "4.0.2",
83
+ "vite-plugin-vue-devtools": "^7.3.7",
84
+ "vitepress": "1.3.2",
85
+ "vue": "3.4.37",
86
+ "vue-tsc": "2.0.29"
86
87
  },
87
- "packageManager": "pnpm@9.5.0",
88
+ "packageManager": "pnpm@9.7.0",
88
89
  "pnpm": {
89
90
  "peerDependencyRules": {
90
91
  "ignoreMissing": [
@@ -17,10 +17,29 @@ import type { Ui3nCheckboxProps, Ui3nCheckboxEmits, Ui3nCheckboxSlots } from './
17
17
  import Ui3nNotification from './ui3n-notification.vue';
18
18
  import Ui3nTableSortIcon from './ui3n-table-sort-icon.vue';
19
19
  import type { Ui3nTableSortIconProps } from './ui3n-table-sort-icon.vue';
20
- import Ui3nTable from './ui3n-table.vue';
21
- import type { Ui3nTableProps, Ui3nTableEmits } from './ui3n-table.vue';
20
+ import Ui3nTable from './ui3n-table/ui3n-table.vue';
21
+ import type {
22
+ Ui3nTableSort,
23
+ Ui3nTableConfig,
24
+ Ui3nTableHeadProps,
25
+ Ui3nTableBodyProps,
26
+ Ui3nTableGroupActionsSlot,
27
+ Ui3nTableHeaderCellSlot,
28
+ Ui3nTableBodyRowSlotScope,
29
+ Ui3nTableBodyRowSlot,
30
+ Ui3nTableBodyRowCellSlotScope,
31
+ Ui3nTableBodyRowCellSlot,
32
+ Ui3nTableSlots,
33
+ Ui3nTableProps,
34
+ Ui3nTableEmits,
35
+ } from './ui3n-table/types';
22
36
  import Ui3nDialog from './ui3n-dialog.vue';
23
- import type { Ui3nDialogComponentProps, Ui3nDialogComponentEmits, Ui3nDialogProps, Ui3nDialogEvent } from './ui3n-dialog.vue';
37
+ import type {
38
+ Ui3nDialogComponentProps,
39
+ Ui3nDialogComponentEmits,
40
+ Ui3nDialogProps,
41
+ Ui3nDialogEvent,
42
+ } from './ui3n-dialog.vue';
24
43
  import Ui3nMenu from './ui3n-menu.vue';
25
44
  import type { Ui3nMenuProps, Ui3nMenuEmits, Ui3nMenuSlots } from './ui3n-menu.vue';
26
45
  import Ui3nList from './ui3n-list.vue';
@@ -75,6 +94,17 @@ export {
75
94
  Ui3nTableSortIcon,
76
95
  Ui3nTableSortIconProps,
77
96
  Ui3nTable,
97
+ Ui3nTableSort,
98
+ Ui3nTableConfig,
99
+ Ui3nTableHeadProps,
100
+ Ui3nTableBodyProps,
101
+ Ui3nTableGroupActionsSlot,
102
+ Ui3nTableHeaderCellSlot,
103
+ Ui3nTableBodyRowSlotScope,
104
+ Ui3nTableBodyRowSlot,
105
+ Ui3nTableBodyRowCellSlotScope,
106
+ Ui3nTableBodyRowCellSlot,
107
+ Ui3nTableSlots,
78
108
  Ui3nTableProps,
79
109
  Ui3nTableEmits,
80
110
  Ui3nDialog,
@@ -115,4 +145,4 @@ export {
115
145
  Ui3nProgressLinearProps,
116
146
  Ui3nProgressCircular,
117
147
  Ui3nProgressCircularProps,
118
- }
148
+ };
@@ -1,7 +1,7 @@
1
1
  <script lang="ts" setup>
2
2
  import { computed, onMounted, watch, onBeforeMount, ref, useSlots } from 'vue';
3
3
 
4
- type Ui3nCheckboxValue = boolean | string | number;
4
+ export type Ui3nCheckboxValue = boolean | string | number;
5
5
 
6
6
  export interface Ui3nCheckboxProps {
7
7
  modelValue: Ui3nCheckboxValue;
@@ -36,10 +36,15 @@ export interface Ui3nDialogComponentProps {
36
36
 
37
37
  export interface Ui3nDialogComponentEmits {
38
38
  (ev: 'open', value?: any): void;
39
+
39
40
  (ev: 'before-close', value?: any): void;
41
+
40
42
  (ev: 'close', value?: any): void;
43
+
41
44
  (ev: 'confirm', value?: any): void;
45
+
42
46
  (ev: 'cancel', value?: any): void;
47
+
43
48
  (ev: 'click-overlay', value?: any): void;
44
49
  }
45
50
 
@@ -52,7 +57,7 @@ const data = ref(null);
52
57
  const isValid = ref(true);
53
58
  const dialogElement = ref<HTMLDivElement | null>(null);
54
59
 
55
- const dialogProps = computed<Ui3nDialogProps>(() => ({
60
+ const dialogProps = computed<Required<Omit<Ui3nDialogProps, 'onClose' | 'onConfirm' | 'onCancel'>>>(() => ({
56
61
  teleport: props.dialogProps?.teleport ?? 'body',
57
62
  title: props.dialogProps?.title ?? '',
58
63
  width: props.dialogProps?.width ?? 380,
@@ -0,0 +1,206 @@
1
+ import { computed, onMounted, type Ref, ref, watch, UnwrapRef } from 'vue';
2
+ import { get, isEmpty, size } from 'lodash';
3
+ import {
4
+ Ui3nTableBodyBaseItem,
5
+ Ui3nTableConfig,
6
+ Ui3nTableEmits,
7
+ Ui3nTableProps,
8
+ Ui3nTableSort,
9
+ } from '@/components/ui3n-table/types';
10
+ import type { Ui3nCheckboxValue } from '../../ui3n-checkbox.vue';
11
+
12
+ export function useTable<T extends Ui3nTableBodyBaseItem>(props: Ui3nTableProps<T>, emits: Ui3nTableEmits<T>) {
13
+ const tableEl = ref<HTMLDivElement | null>(null);
14
+ const currentConfig = ref<Pick<Ui3nTableConfig<T>, 'sortOrder' | 'fieldAsRowKey'>>({
15
+ sortOrder: setInitialSortOrder(),
16
+ fieldAsRowKey: setFieldAsRowKey(),
17
+ });
18
+ const selectedRows: Ref<Set<T> | Array<T[keyof T]>> = !!currentConfig.value?.fieldAsRowKey
19
+ ? ref([])
20
+ : (ref(new Set()) as Ref<Set<T>>);
21
+ const hasGroupActionsRow = ref(false);
22
+
23
+ const isRowKeyUsed = computed(() => !!currentConfig.value.fieldAsRowKey);
24
+ const visibleColumns = computed(() => props.head.filter(h => !h.hidden));
25
+ const selectedRowsArray = computed(() =>
26
+ isRowKeyUsed.value
27
+ ? props.body.content.filter(row =>
28
+ (selectedRows.value as Array<T[keyof T]>).includes(row[currentConfig.value.fieldAsRowKey as keyof T]),
29
+ )
30
+ : Array.from(selectedRows.value as Set<T>),
31
+ );
32
+ const selectedRowsSize = computed(() =>
33
+ isRowKeyUsed.value ? size(selectedRows.value) : (selectedRows.value as Set<T>).size,
34
+ );
35
+ const showGroupActionsRow = computed(() => props.config?.selectable === 'multiple' && hasGroupActionsRow.value);
36
+
37
+ onMounted(() => {
38
+ tableEl.value && setColumnWidth(tableEl.value);
39
+ });
40
+
41
+ function setColumnWidth(el: HTMLDivElement) {
42
+ const { config = {}, head } = props;
43
+ const { columnStyle } = config;
44
+ const keys = head.map(h => h.key);
45
+ const columnsWidthValue = keys.reduce((res, key, index) => {
46
+ const width = get(columnStyle, [key, 'width'], '1fr');
47
+ res = index === 0 ? `${width}` : `${res} ${width}`;
48
+ return res;
49
+ }, '');
50
+ el && el.style.setProperty('--ui3n-table-columns-width', columnsWidthValue);
51
+ }
52
+
53
+ function setFieldAsRowKey() {
54
+ const { config = {}, body } = props;
55
+ const { fieldAsRowKey } = config;
56
+ if (fieldAsRowKey && fieldAsRowKey in get(body, ['content', 0], {})) return fieldAsRowKey;
57
+
58
+ if ('id' in get(body, ['content', 0], {})) return 'id';
59
+
60
+ return undefined;
61
+ }
62
+
63
+ function setInitialSortOrder(): Ui3nTableSort<T> {
64
+ const { config = {}, head } = props;
65
+ const { sortOrder } = config;
66
+ if (!isEmpty(sortOrder)) {
67
+ return sortOrder;
68
+ }
69
+
70
+ for (const h of head) {
71
+ const { key, sortable } = h;
72
+ if (sortable) {
73
+ return {
74
+ field: key,
75
+ direction: 'desc',
76
+ };
77
+ }
78
+ }
79
+
80
+ return {} as Ui3nTableSort<T>;
81
+ }
82
+
83
+ function getRowKey(row: T, index: number) {
84
+ return isRowKeyUsed.value ? (row[currentConfig.value.fieldAsRowKey as keyof T] as string | number) : index;
85
+ }
86
+
87
+ function isRowSelected(row: T): boolean {
88
+ if (isRowKeyUsed.value) {
89
+ return !!(selectedRows.value as Array<T[keyof T]>).find(
90
+ keyValue => keyValue === row[currentConfig.value.fieldAsRowKey as keyof T],
91
+ );
92
+ }
93
+
94
+ return (selectedRows.value as Set<T>).has(row);
95
+ }
96
+
97
+ function getRowStyle(row: T): Record<string, string> {
98
+ if (isEmpty(props.body.rowsStyle) || !isRowKeyUsed.value) return {};
99
+
100
+ const rowKey = row[currentConfig.value.fieldAsRowKey as keyof T] as string | number;
101
+ return get(props, ['body', 'rowsStyle', rowKey], {});
102
+ }
103
+
104
+ function closeGroupActionsRow() {
105
+ hasGroupActionsRow.value = false;
106
+ toggleSelectedRows(false);
107
+ }
108
+
109
+ function selectInSingleMode(row: T) {
110
+ if (isRowSelected(row)) {
111
+ isRowKeyUsed.value && ((selectedRows.value as Array<T[keyof T]>) = []);
112
+ !isRowKeyUsed.value && (selectedRows.value as Set<T>).clear();
113
+ } else {
114
+ if (isRowKeyUsed.value) {
115
+ (selectedRows.value as Array<T[keyof T]>) = [row[currentConfig.value?.fieldAsRowKey as keyof T]];
116
+ } else {
117
+ (selectedRows.value as Set<T>).clear();
118
+ (selectedRows.value as Set<T>).add(row);
119
+ }
120
+ }
121
+ }
122
+
123
+ function selectInMultipleMode(row: T) {
124
+ if (isRowSelected(row)) {
125
+ if (!isRowKeyUsed.value) {
126
+ (selectedRows.value as Set<T>).delete(row);
127
+ } else {
128
+ const index = (selectedRows.value as Array<T[keyof T]>).findIndex(
129
+ keyValue => keyValue === row[currentConfig.value.fieldAsRowKey as keyof T],
130
+ );
131
+ (selectedRows.value as Array<T[keyof T]>).splice(index, 1);
132
+ }
133
+ } else {
134
+ isRowKeyUsed.value &&
135
+ (selectedRows.value as Array<T[keyof T]>).push(row[currentConfig.value.fieldAsRowKey as keyof T]);
136
+ !isRowKeyUsed.value && (selectedRows.value as Set<T>).add(row);
137
+ }
138
+ }
139
+
140
+ function processSelection(row: T, withoutEvents?: boolean) {
141
+ const { selectable } = props.config;
142
+
143
+ if (selectable === 'single') {
144
+ selectInSingleMode(row);
145
+ } else {
146
+ selectInMultipleMode(row);
147
+ }
148
+
149
+ !withoutEvents && emits('select:row', selectedRowsArray.value);
150
+ }
151
+
152
+ function toggleSelectedRows(val: Ui3nCheckboxValue) {
153
+ if (props.config.selectable !== 'multiple') return;
154
+
155
+ if (!!val) {
156
+ for (const item of props.body.content) {
157
+ if (!isRowSelected(item)) {
158
+ processSelection(item, true);
159
+ }
160
+ }
161
+ } else {
162
+ isRowKeyUsed.value && ((selectedRows.value as Array<T[keyof T]>) = []);
163
+ !isRowKeyUsed.value && (selectedRows.value as Set<T>).clear();
164
+ }
165
+
166
+ emits('select:row', selectedRowsArray.value);
167
+ }
168
+
169
+ function changeSortOrder(field: keyof T) {
170
+ if (currentConfig.value.sortOrder?.field === field) {
171
+ currentConfig.value.sortOrder.direction = currentConfig.value.sortOrder?.direction === 'asc' ? 'desc' : 'asc';
172
+ } else {
173
+ currentConfig.value.sortOrder!.field = field as UnwrapRef<keyof T>;
174
+ currentConfig.value.sortOrder!.direction = 'desc';
175
+ }
176
+
177
+ currentConfig.value.sortOrder?.field && emits('change:sort', currentConfig.value.sortOrder as Ui3nTableSort<T>);
178
+ }
179
+
180
+ watch(
181
+ () => selectedRowsSize.value,
182
+ (val, oldVal) => {
183
+ if (val && val > oldVal && props.config.selectable === 'multiple' && !showGroupActionsRow.value) {
184
+ hasGroupActionsRow.value = true;
185
+ }
186
+ },
187
+ );
188
+
189
+ return {
190
+ tableEl,
191
+ currentConfig,
192
+ visibleColumns,
193
+ hasGroupActionsRow,
194
+ showGroupActionsRow,
195
+ selectedRows,
196
+ selectedRowsArray,
197
+ selectedRowsSize,
198
+ closeGroupActionsRow,
199
+ getRowKey,
200
+ isRowSelected,
201
+ getRowStyle,
202
+ processSelection,
203
+ toggleSelectedRows,
204
+ changeSortOrder,
205
+ };
206
+ }
@@ -0,0 +1,80 @@
1
+ import { VNode } from 'vue';
2
+
3
+ export interface Ui3nTableBodyBaseItem {
4
+ id?: string | number | symbol;
5
+ }
6
+
7
+ export type Ui3nTableSort<T extends Ui3nTableBodyBaseItem> = {
8
+ field: keyof T;
9
+ direction: 'asc' | 'desc';
10
+ };
11
+
12
+ export type Ui3nTableConfig<T extends Ui3nTableBodyBaseItem, K extends keyof T = keyof T> = {
13
+ tableName?: string;
14
+ sortOrder?: Ui3nTableSort<T>;
15
+ selectable?: 'single' | 'multiple';
16
+ // draggebleRows?: boolean; // ToDo this will be done in the next version
17
+ // draggebleColumns?: boolean; // ToDo this will be done in the next version
18
+ columnStyle?: { [P in Omit<K, 'id'> as string | number]: Record<string, string> };
19
+ fieldAsRowKey?: keyof T;
20
+ };
21
+
22
+ export type Ui3nTableHeadProps<T extends Ui3nTableBodyBaseItem> = {
23
+ key: keyof T;
24
+ text: string;
25
+ sortable?: boolean;
26
+ headCellStyle?: Record<string, string>;
27
+ format?: (content: unknown) => string;
28
+ hidden?: boolean;
29
+ index?: number;
30
+ };
31
+
32
+ export type Ui3nTableBodyProps<T extends Ui3nTableBodyBaseItem, K extends keyof T = keyof T> = {
33
+ content: T[];
34
+ rowsStyle?: { [P in T[K] as string | number]: Record<string, string> };
35
+ };
36
+
37
+ export interface Ui3nTableProps<T extends Ui3nTableBodyBaseItem> {
38
+ config: Ui3nTableConfig<T>;
39
+ head: Ui3nTableHeadProps<T>[];
40
+ body: Ui3nTableBodyProps<T>;
41
+ }
42
+
43
+ export interface Ui3nTableEmits<T extends Ui3nTableBodyBaseItem> {
44
+ (ev: 'change:sort', val: Ui3nTableSort<T>): void;
45
+ (ev: 'select:row', val: T[]): void;
46
+ }
47
+
48
+ export type Ui3nTableGroupActionsSlot = {
49
+ 'group-actions': () => VNode;
50
+ };
51
+
52
+ export type Ui3nTableHeaderCellSlot<T extends Ui3nTableBodyBaseItem, K extends string & keyof T> = {
53
+ [p in `header-cell-${K}`]: () => VNode;
54
+ };
55
+
56
+ export type Ui3nTableBodyRowSlotScope<T extends Ui3nTableBodyBaseItem> = {
57
+ row: T;
58
+ rowStyle?: Record<string, string>;
59
+ rowIndex: number;
60
+ events?: Record<string, (value: unknown) => unknown>;
61
+ };
62
+
63
+ export type Ui3nTableBodyRowSlot<T extends Ui3nTableBodyBaseItem> = {
64
+ 'body-row': (scope: Ui3nTableBodyRowSlotScope<T>) => VNode;
65
+ };
66
+
67
+ export type Ui3nTableBodyRowCellSlotScope<T extends Ui3nTableBodyBaseItem, K extends string & keyof T> = {
68
+ row: T;
69
+ rowIndex: number;
70
+ cell: T[K];
71
+ };
72
+
73
+ export type Ui3nTableBodyRowCellSlot<T extends Ui3nTableBodyBaseItem, K extends string & keyof T> = {
74
+ [p in `body-row-cell-${K}`]: (scope: Ui3nTableBodyRowCellSlotScope<T, K>) => VNode;
75
+ };
76
+
77
+ export type Ui3nTableSlots<T extends Ui3nTableBodyBaseItem, K extends string & keyof T> = Ui3nTableGroupActionsSlot &
78
+ Ui3nTableHeaderCellSlot<T, K> &
79
+ Ui3nTableBodyRowSlot<T> &
80
+ Ui3nTableBodyRowCellSlot<T, K>;