@stonecrop/atable 0.2.16 → 0.2.18
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/atable.js +942 -0
- package/dist/atable.js.map +1 -0
- package/dist/atable.umd.cjs +2 -0
- package/dist/atable.umd.cjs.map +1 -0
- package/dist/style.css +1 -0
- package/package.json +13 -11
- package/src/components/ACell.vue +6 -13
- package/src/components/ARow.vue +16 -15
- package/src/components/ATable.vue +57 -62
package/src/components/ARow.vue
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<tr ref="rowEl" :tabindex="tabIndex" v-show="
|
|
2
|
+
<tr ref="rowEl" :tabindex="tabIndex" v-show="isRowVisible" class="table-row">
|
|
3
3
|
<!-- render numbered/tree view index -->
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
<slot name="index">
|
|
5
|
+
<td v-if="tableData.config.view === 'list'" :tabIndex="-1" class="list-index">
|
|
6
|
+
{{ rowIndex + 1 }}
|
|
7
|
+
</td>
|
|
8
|
+
<td
|
|
9
|
+
v-else-if="tableData.config.view === 'tree'"
|
|
10
|
+
:tabIndex="-1"
|
|
11
|
+
class="tree-index"
|
|
12
|
+
@click="toggleRowExpand(rowIndex)">
|
|
13
|
+
{{ getRowExpandSymbol() }}
|
|
14
|
+
</td>
|
|
15
|
+
</slot>
|
|
15
16
|
|
|
16
17
|
<!-- render cell content -->
|
|
17
18
|
<slot></slot>
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
|
|
21
22
|
<script setup lang="ts">
|
|
22
23
|
import { TableRow } from 'types'
|
|
23
|
-
import { inject, ref } from 'vue'
|
|
24
|
+
import { computed, inject, ref } from 'vue'
|
|
24
25
|
import { type KeypressHandlers, useKeyboardNav, defaultKeypressHandlers } from '@stonecrop/utilities'
|
|
25
26
|
|
|
26
27
|
import TableDataStore from '.'
|
|
@@ -67,13 +68,13 @@ const getRowExpandSymbol = () => {
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
const
|
|
71
|
+
const isRowVisible = computed(() => {
|
|
71
72
|
return (
|
|
72
73
|
tableData.config.view !== 'tree' ||
|
|
73
74
|
tableData.display[props.rowIndex].isRoot ||
|
|
74
75
|
tableData.display[props.rowIndex].open
|
|
75
76
|
)
|
|
76
|
-
}
|
|
77
|
+
})
|
|
77
78
|
|
|
78
79
|
const toggleRowExpand = (rowIndex: number) => {
|
|
79
80
|
tableData.toggleRowExpand(rowIndex)
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<table
|
|
2
|
+
<table
|
|
3
|
+
class="atable"
|
|
4
|
+
:style="{ width: tableData.config.fullWidth ? '100%' : 'auto' }"
|
|
5
|
+
v-on-click-outside="closeModal">
|
|
3
6
|
<slot name="header" :data="tableData">
|
|
4
7
|
<ATableHeader :columns="tableData.columns" :config="tableData.config" :tableid="tableData.id" />
|
|
5
8
|
</slot>
|
|
@@ -59,6 +62,7 @@
|
|
|
59
62
|
<script setup lang="ts">
|
|
60
63
|
import { v4 } from 'uuid'
|
|
61
64
|
import { nextTick, provide, watch } from 'vue'
|
|
65
|
+
import { vOnClickOutside } from '@vueuse/components'
|
|
62
66
|
|
|
63
67
|
import { TableColumn, TableConfig, TableRow } from 'types'
|
|
64
68
|
import TableDataStore from '.'
|
|
@@ -85,7 +89,6 @@ const props = withDefaults(
|
|
|
85
89
|
const emit = defineEmits(['update:modelValue'])
|
|
86
90
|
|
|
87
91
|
let rows = props.modelValue ? props.modelValue : props.rows
|
|
88
|
-
|
|
89
92
|
let tableData = new TableDataStore(props.id, props.columns, rows, props.config)
|
|
90
93
|
provide(tableData.id, tableData)
|
|
91
94
|
|
|
@@ -97,47 +100,47 @@ watch(
|
|
|
97
100
|
{ deep: true }
|
|
98
101
|
)
|
|
99
102
|
|
|
100
|
-
const formatCell = (event?: KeyboardEvent, column?: TableColumn, cellData?: any) => {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
103
|
+
// const formatCell = (event?: KeyboardEvent, column?: TableColumn, cellData?: any) => {
|
|
104
|
+
// let colIndex: number
|
|
105
|
+
// const target = event?.target as HTMLTableCellElement
|
|
106
|
+
// if (event) {
|
|
107
|
+
// colIndex = target.cellIndex + (tableData.zeroColumn ? -1 : 0)
|
|
108
|
+
// } else if (column && cellData) {
|
|
109
|
+
// colIndex = tableData.columns.indexOf(column)
|
|
110
|
+
// }
|
|
111
|
+
|
|
112
|
+
// if (!column && 'format' in tableData.columns[colIndex]) {
|
|
113
|
+
// // TODO: (utils) create helper to extract format from string
|
|
114
|
+
// const format = tableData.columns[colIndex].format
|
|
115
|
+
// if (typeof format === 'function') {
|
|
116
|
+
// return format(target.innerHTML)
|
|
117
|
+
// } else if (typeof format === 'string') {
|
|
118
|
+
// // parse format function from string
|
|
119
|
+
// // eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
120
|
+
// const formatFn: (args: any) => any = Function(`"use strict";return (${format})`)()
|
|
121
|
+
// return formatFn(target.innerHTML)
|
|
122
|
+
// } else {
|
|
123
|
+
// return target.innerHTML
|
|
124
|
+
// }
|
|
125
|
+
// } else if (cellData && 'format' in column) {
|
|
126
|
+
// const format = column.format
|
|
127
|
+
// if (typeof format === 'function') {
|
|
128
|
+
// return format(cellData)
|
|
129
|
+
// } else if (typeof format === 'string') {
|
|
130
|
+
// // parse format function from string
|
|
131
|
+
// // eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
132
|
+
// const formatFn: (args: any) => any = Function(`"use strict";return (${format})`)()
|
|
133
|
+
// return formatFn(cellData)
|
|
134
|
+
// } else {
|
|
135
|
+
// return cellData
|
|
136
|
+
// }
|
|
137
|
+
// } else if (cellData && column.type.toLowerCase() in ['int', 'decimal', 'float', 'number', 'percent']) {
|
|
138
|
+
// return cellData
|
|
139
|
+
// // TODO: number formatting
|
|
140
|
+
// } else {
|
|
141
|
+
// return cellData
|
|
142
|
+
// }
|
|
143
|
+
// }
|
|
141
144
|
|
|
142
145
|
// const moveCursorToEnd = (target: HTMLElement) => {
|
|
143
146
|
// target.focus()
|
|
@@ -145,17 +148,17 @@ const formatCell = (event?: KeyboardEvent, column?: TableColumn, cellData?: any)
|
|
|
145
148
|
// document.getSelection().collapseToEnd()
|
|
146
149
|
// }
|
|
147
150
|
|
|
148
|
-
const
|
|
149
|
-
if (!
|
|
150
|
-
if
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
const closeModal = (event: MouseEvent) => {
|
|
152
|
+
if (!(event.target instanceof Node)) {
|
|
153
|
+
// if the target is not a node, it's probably a custom click event to Document or Window
|
|
154
|
+
// err on the side of closing the modal in that case
|
|
155
|
+
if (tableData.modal.visible) tableData.modal.visible = false
|
|
156
|
+
} else if (!tableData.modal.parent?.contains(event.target)) {
|
|
157
|
+
if (tableData.modal.visible) tableData.modal.visible = false
|
|
154
158
|
}
|
|
155
159
|
}
|
|
156
160
|
|
|
157
|
-
window.addEventListener('
|
|
158
|
-
window.addEventListener('keydown', (event: KeyboardEvent) => {
|
|
161
|
+
window.addEventListener('keydown', async (event: KeyboardEvent) => {
|
|
159
162
|
if (event.key === 'Escape') {
|
|
160
163
|
if (tableData.modal.visible) {
|
|
161
164
|
tableData.modal.visible = false
|
|
@@ -163,17 +166,9 @@ window.addEventListener('keydown', (event: KeyboardEvent) => {
|
|
|
163
166
|
// focus on the parent cell again
|
|
164
167
|
const $parent = tableData.modal.parent
|
|
165
168
|
if ($parent) {
|
|
166
|
-
// wait for the modal to close
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
// re-fetching the cell to add focus instead
|
|
170
|
-
const rowIndex = $parent.dataset.rowindex
|
|
171
|
-
const colIndex = $parent.dataset.colindex
|
|
172
|
-
const $parentCell = document.querySelectorAll(`[data-rowindex='${rowIndex}'][data-colindex='${colIndex}']`)
|
|
173
|
-
if ($parentCell) {
|
|
174
|
-
;($parentCell[0] as HTMLTableCellElement).focus()
|
|
175
|
-
}
|
|
176
|
-
})
|
|
169
|
+
// wait for the modal to close before focusing
|
|
170
|
+
await nextTick()
|
|
171
|
+
$parent.focus()
|
|
177
172
|
}
|
|
178
173
|
}
|
|
179
174
|
}
|