@stonecrop/atable 0.31.0 → 0.33.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.
Files changed (79) hide show
  1. package/dist/assets/index.css +804 -1
  2. package/dist/atable.js +2809 -1944
  3. package/dist/atable.js.map +1 -1
  4. package/dist/src/components/ACell.vue.d.ts +17 -0
  5. package/dist/src/components/ACell.vue.d.ts.map +1 -0
  6. package/dist/src/components/AGanttCell.vue.d.ts +34 -0
  7. package/dist/src/components/AGanttCell.vue.d.ts.map +1 -0
  8. package/dist/src/components/AGanttConnection.vue.d.ts +13 -0
  9. package/dist/src/components/AGanttConnection.vue.d.ts.map +1 -0
  10. package/dist/src/components/ARow.vue.d.ts +2693 -0
  11. package/dist/src/components/ARow.vue.d.ts.map +1 -0
  12. package/dist/src/components/ARowActions.vue.d.ts +16 -0
  13. package/dist/src/components/ARowActions.vue.d.ts.map +1 -0
  14. package/dist/src/components/ATable.vue.d.ts +13358 -0
  15. package/dist/src/components/ATable.vue.d.ts.map +1 -0
  16. package/dist/src/components/ATableColumnFilter.vue.d.ts +11 -0
  17. package/dist/src/components/ATableColumnFilter.vue.d.ts.map +1 -0
  18. package/dist/src/components/ATableHeader.vue.d.ts +20 -0
  19. package/dist/src/components/ATableHeader.vue.d.ts.map +1 -0
  20. package/dist/src/components/ATableLoading.vue.d.ts +14 -0
  21. package/dist/src/components/ATableLoading.vue.d.ts.map +1 -0
  22. package/dist/src/components/ATableLoadingBar.vue.d.ts +14 -0
  23. package/dist/src/components/ATableLoadingBar.vue.d.ts.map +1 -0
  24. package/dist/src/components/ATableModal.vue.d.ts +18 -0
  25. package/dist/src/components/ATableModal.vue.d.ts.map +1 -0
  26. package/dist/src/components/ATablePaginationFooter.vue.d.ts +17 -0
  27. package/dist/src/components/ATablePaginationFooter.vue.d.ts.map +1 -0
  28. package/dist/src/icons/index.d.ts +14 -7
  29. package/dist/src/icons/index.d.ts.map +1 -1
  30. package/dist/{tsdoc-metadata.json → src/tsdoc-metadata.json} +1 -1
  31. package/dist/src/types/index.d.ts.map +1 -1
  32. package/package.json +35 -29
  33. package/dist/atable.d.ts +0 -3560
  34. package/dist/atable.tsbuildinfo +0 -1
  35. package/dist/icons/stonecrop-ui-icon-add.svg +0 -5
  36. package/dist/icons/stonecrop-ui-icon-delete.svg +0 -5
  37. package/dist/icons/stonecrop-ui-icon-duplicate.svg +0 -5
  38. package/dist/icons/stonecrop-ui-icon-insert-above.svg +0 -15
  39. package/dist/icons/stonecrop-ui-icon-insert-below.svg +0 -15
  40. package/dist/icons/stonecrop-ui-icon-move.svg +0 -4
  41. package/dist/icons/stonecrop-ui-icon-open.svg +0 -5
  42. package/dist/src/composables/table-pagination.js +0 -108
  43. package/dist/src/icons/index.js +0 -32
  44. package/dist/src/index.js +0 -33
  45. package/dist/src/linkSearchableText.js +0 -44
  46. package/dist/src/resolveFilterType.js +0 -27
  47. package/dist/src/schemaToColumns.js +0 -59
  48. package/dist/src/stores/table.js +0 -833
  49. package/dist/src/types/index.js +0 -0
  50. package/dist/src/utils.js +0 -39
  51. package/src/components/ACell.vue +0 -410
  52. package/src/components/AGanttCell.vue +0 -638
  53. package/src/components/AGanttConnection.vue +0 -164
  54. package/src/components/ARow.vue +0 -251
  55. package/src/components/ARowActions.vue +0 -407
  56. package/src/components/ATable.vue +0 -538
  57. package/src/components/ATableColumnFilter.vue +0 -216
  58. package/src/components/ATableHeader.vue +0 -141
  59. package/src/components/ATableLoading.vue +0 -86
  60. package/src/components/ATableLoadingBar.vue +0 -81
  61. package/src/components/ATableModal.vue +0 -52
  62. package/src/components/ATablePaginationFooter.vue +0 -100
  63. package/src/composables/table-pagination.ts +0 -172
  64. package/src/icons/index.ts +0 -38
  65. package/src/icons/stonecrop-ui-icon-add.svg +0 -5
  66. package/src/icons/stonecrop-ui-icon-delete.svg +0 -5
  67. package/src/icons/stonecrop-ui-icon-duplicate.svg +0 -5
  68. package/src/icons/stonecrop-ui-icon-insert-above.svg +0 -15
  69. package/src/icons/stonecrop-ui-icon-insert-below.svg +0 -15
  70. package/src/icons/stonecrop-ui-icon-move.svg +0 -4
  71. package/src/icons/stonecrop-ui-icon-open.svg +0 -5
  72. package/src/index.ts +0 -62
  73. package/src/linkSearchableText.ts +0 -42
  74. package/src/resolveFilterType.ts +0 -32
  75. package/src/schemaToColumns.ts +0 -67
  76. package/src/shims-vue.d.ts +0 -10
  77. package/src/stores/table.ts +0 -978
  78. package/src/types/index.ts +0 -794
  79. package/src/utils.ts +0 -40
@@ -1,164 +0,0 @@
1
- <template>
2
- <div class="gantt-connection-overlay">
3
- <svg
4
- class="connection-svg"
5
- :style="{
6
- position: 'absolute',
7
- top: 0,
8
- left: 0,
9
- width: '100%',
10
- height: '100%',
11
- pointerEvents: 'none',
12
- zIndex: 1,
13
- }">
14
- <defs>
15
- <!-- Define arrowhead marker for connections -->
16
- <path id="arrowhead" d="M 0 -7 L 20 0 L 0 7Z" stroke="black" stroke-width="1" fill="currentColor"></path>
17
- <marker
18
- id="arrowhead-marker"
19
- markerWidth="10"
20
- markerHeight="7"
21
- refX="5"
22
- refY="3.5"
23
- orient="auto"
24
- markerUnits="strokeWidth">
25
- <polygon points="0 0, 10 3.5, 0 7" fill="currentColor" />
26
- </marker>
27
- </defs>
28
-
29
- <!-- Invisible wider path for easier double-click interaction -->
30
- <path
31
- v-for="connection in visibleConnections"
32
- :key="`${connection.id}-hitbox`"
33
- :d="getPathData(connection)"
34
- stroke="transparent"
35
- :stroke-width="(connection.style?.width || 2) + 10"
36
- fill="none"
37
- class="connection-hitbox"
38
- @dblclick="handleConnectionDelete(connection)" />
39
-
40
- <!-- Visible connection path -->
41
- <path
42
- v-for="connection in visibleConnections"
43
- :id="connection.id"
44
- :key="connection.id"
45
- :d="getPathData(connection)"
46
- :stroke="connection.style?.color || '#666'"
47
- :stroke-width="connection.style?.width || 2"
48
- fill="none"
49
- marker-mid="url(#arrowhead-marker)"
50
- class="connection-path animated-path"
51
- @dblclick="handleConnectionDelete(connection)" />
52
- </svg>
53
- </div>
54
- </template>
55
-
56
- <script setup lang="ts">
57
- import { computed } from 'vue'
58
-
59
- import { createTableStore } from '../stores/table'
60
- import type { ConnectionPath } from '../types'
61
-
62
- const { store } = defineProps<{
63
- store: ReturnType<typeof createTableStore>
64
- }>()
65
-
66
- const emit = defineEmits<{
67
- 'connection:delete': [connection: ConnectionPath]
68
- }>()
69
-
70
- const BEZIER_CURVE_FACTOR = 0.25 // Control point offset factor for bezier curves
71
- const CONNECTION_HANDLE_SIZE = 16 // Width of the connection handles; this should match the handle size in the AGanttCell component
72
-
73
- const visibleConnections = computed(() => {
74
- return store.connectionPaths.filter(connection => {
75
- const fromBar = store.ganttBars.find(bar => bar.id === connection.from.barId)
76
- const toBar = store.ganttBars.find(bar => bar.id === connection.to.barId)
77
- return fromBar && toBar
78
- })
79
- })
80
-
81
- const getPathData = (connection: ConnectionPath) => {
82
- const fromHandle = store.connectionHandles.find(
83
- handle => handle.barId === connection.from.barId && handle.side === connection.from.side
84
- )
85
- const toHandle = store.connectionHandles.find(
86
- handle => handle.barId === connection.to.barId && handle.side === connection.to.side
87
- )
88
-
89
- if (!fromHandle || !toHandle) return ''
90
-
91
- const fromX = fromHandle.position.x + CONNECTION_HANDLE_SIZE / 2 // Center of the handle
92
- const fromY = fromHandle.position.y + CONNECTION_HANDLE_SIZE / 2
93
- const toX = toHandle.position.x + CONNECTION_HANDLE_SIZE / 2
94
- const toY = toHandle.position.y + CONNECTION_HANDLE_SIZE / 2
95
-
96
- // Calculate control points for smooth bezier curve
97
- const deltaX = Math.abs(toX - fromX)
98
- const controlPointOffset = Math.max(deltaX * BEZIER_CURVE_FACTOR, 50) // Minimum offset for better curves
99
- const cp1X = fromX + (connection.from.side === 'left' ? -controlPointOffset : controlPointOffset)
100
- const cp2X = toX + (connection.to.side === 'left' ? -controlPointOffset : controlPointOffset)
101
-
102
- // Use cubic bezier curve for smooth connections
103
-
104
- //calculate the mid point of the curve
105
- const m0 = { x: 0.5 * fromX + 0.5 * cp1X, y: 0.5 * fromY + 0.5 * fromY }
106
- const m1 = { x: 0.5 * cp1X + 0.5 * cp2X, y: 0.5 * fromY + 0.5 * toY }
107
- const m2 = { x: 0.5 * cp2X + 0.5 * toX, y: 0.5 * toY + 0.5 * toY }
108
- const m3 = { x: 0.5 * m0.x + 0.5 * m1.x, y: 0.5 * m0.y + 0.5 * m1.y }
109
- const m4 = { x: 0.5 * m1.x + 0.5 * m2.x, y: 0.5 * m1.y + 0.5 * m2.y }
110
- const midpoint = { x: 0.5 * m3.x + 0.5 * m4.x, y: 0.5 * m3.y + 0.5 * m4.y }
111
-
112
- // Calculate the bezier curve using two arcs
113
- return `M ${fromX} ${fromY} Q ${cp1X} ${fromY}, ${midpoint.x} ${midpoint.y} Q ${cp2X} ${toY}, ${toX} ${toY}`
114
- }
115
-
116
- const handleConnectionDelete = (connection: ConnectionPath) => {
117
- if (store.deleteConnection(connection.id)) {
118
- emit('connection:delete', connection)
119
- }
120
- }
121
- </script>
122
-
123
- <style scoped>
124
- .gantt-connection-overlay {
125
- position: absolute;
126
- top: 0;
127
- left: 0;
128
- width: 100%;
129
- height: 100%;
130
- pointer-events: none;
131
- z-index: 15;
132
- }
133
-
134
- .connection-path {
135
- transition: stroke-width 0.2s ease;
136
- pointer-events: auto;
137
- cursor: pointer;
138
- stroke-dasharray: 5px;
139
- stroke: var(--sc-cell-text-color);
140
- }
141
- #arrowhead-marker polygon {
142
- fill: var(--sc-cell-text-color);
143
- }
144
- .animated-path {
145
- animation: animated-dash infinite 1.5s linear;
146
- }
147
-
148
- .connection-path:hover {
149
- stroke-width: 3px;
150
- }
151
-
152
- .connection-hitbox {
153
- pointer-events: auto;
154
- cursor: pointer;
155
- }
156
- @keyframes animated-dash {
157
- 0% {
158
- stroke-dashoffset: 0px;
159
- }
160
- 100% {
161
- stroke-dashoffset: -10px;
162
- }
163
- }
164
- </style>
@@ -1,251 +0,0 @@
1
- <template>
2
- <tr
3
- v-show="isRowVisible"
4
- v-bind="$attrs"
5
- ref="rowEl"
6
- :tabindex="tabIndex"
7
- class="atable-row"
8
- :class="{ 'atable-row-clickable': isClickable }"
9
- @click="onRowClick">
10
- <!-- Row actions before index (default position) -->
11
- <ARowActions
12
- v-if="showRowActions && actionsPosition === 'before-index'"
13
- :row-index="rowIndex"
14
- :store="store"
15
- :config="rowActionsConfig"
16
- :position="actionsPosition"
17
- @action="onRowAction" />
18
-
19
- <!-- render numbered/tree view index; skip render for uncounted lists -->
20
- <slot v-if="store.config.view !== 'uncounted'" name="index">
21
- <td
22
- v-if="store.config.view === 'list'"
23
- :tabIndex="-1"
24
- class="list-index"
25
- :class="store.hasPinnedColumns ? 'sticky-index' : ''">
26
- {{ rowIndex + 1 }}
27
- </td>
28
- <td
29
- v-else-if="store.isTreeView"
30
- :tabIndex="-1"
31
- class="tree-index"
32
- :class="store.hasPinnedColumns ? 'sticky-index' : ''"
33
- @click="store.toggleRowExpand(rowIndex)">
34
- {{ rowExpandSymbol }}
35
- </td>
36
- <td
37
- v-else-if="store.config.view === 'list-expansion'"
38
- :tabIndex="-1"
39
- class="expansion-index"
40
- :class="store.hasPinnedColumns ? 'sticky-index' : ''"
41
- @click="store.toggleRowExpand(rowIndex)">
42
- {{ rowExpandSymbol }}
43
- </td>
44
- </slot>
45
-
46
- <!-- Row actions after index -->
47
- <ARowActions
48
- v-if="showRowActions && actionsPosition === 'after-index'"
49
- :row-index="rowIndex"
50
- :store="store"
51
- :config="rowActionsConfig"
52
- :position="actionsPosition"
53
- @action="onRowAction" />
54
-
55
- <!-- render cell content -->
56
- <slot></slot>
57
-
58
- <!-- Row actions at end -->
59
- <ARowActions
60
- v-if="showRowActions && actionsPosition === 'end'"
61
- :row-index="rowIndex"
62
- :store="store"
63
- :config="rowActionsConfig"
64
- :position="actionsPosition"
65
- @action="onRowAction" />
66
- </tr>
67
-
68
- <!-- list-expansion content panel: a second row spanning the whole width -->
69
- <tr v-if="isExpanded" :tabindex="tabIndex" class="atable-expanded-row">
70
- <td :tabIndex="-1" :colspan="expandedColspan" class="atable-expanded-content">
71
- <slot name="content" :row="store.rows[rowIndex]" :row-index="rowIndex" :store="store" />
72
- </td>
73
- </tr>
74
- </template>
75
-
76
- <script setup lang="ts">
77
- import { type KeypressHandlers, useKeyboardNav, defaultKeypressHandlers } from '@stonecrop/utilities'
78
- import { computed, useTemplateRef } from 'vue'
79
-
80
- import ARowActions from './ARowActions.vue'
81
- import { createTableStore } from '../stores/table'
82
- import type { RowActionsConfig, RowActionType } from '../types'
83
-
84
- const {
85
- rowIndex,
86
- store,
87
- tabIndex = -1,
88
- addNavigation = false, // default to allowing cell navigation
89
- } = defineProps<{
90
- rowIndex: number
91
- store: ReturnType<typeof createTableStore>
92
- tabIndex?: number
93
- addNavigation?: boolean | KeypressHandlers
94
- }>()
95
-
96
- const emit = defineEmits<{
97
- 'row:action': [type: RowActionType, rowIndex: number, event?: MouseEvent]
98
- 'row:click': [rowIndex: number, event: MouseEvent]
99
- }>()
100
-
101
- const rowRef = useTemplateRef<HTMLTableRowElement>('rowEl')
102
-
103
- const isRowVisible = computed(() => store.isRowVisible(rowIndex))
104
- const rowExpandSymbol = computed(() => store.getRowExpandSymbol(rowIndex))
105
- const isClickable = computed(() => store.config.clickable ?? false)
106
-
107
- // Row actions configuration
108
- const rowActionsConfig = computed((): RowActionsConfig => {
109
- return store.config.rowActions || { enabled: false }
110
- })
111
-
112
- const showRowActions = computed(() => {
113
- return rowActionsConfig.value.enabled
114
- })
115
-
116
- const actionsPosition = computed(() => {
117
- return rowActionsConfig.value.position || 'before-index'
118
- })
119
-
120
- // list-expansion: this row owns an expandable content panel (a second <tr>).
121
- const isExpanded = computed(() => store.config.view === 'list-expansion' && Boolean(store.display[rowIndex]?.expanded))
122
-
123
- // The content panel spans every column the main row occupies: data columns + the
124
- // index/chevron column (absent only in uncounted) + the row-actions column when enabled.
125
- const expandedColspan = computed(() => {
126
- const indexCol = store.config.view === 'uncounted' ? 0 : 1
127
- const actionsCol = showRowActions.value ? 1 : 0
128
- return store.columns.length + indexCol + actionsCol
129
- })
130
-
131
- const onRowAction = (actionType: RowActionType, index: number, event?: MouseEvent) => {
132
- emit('row:action', actionType, index, event)
133
- }
134
-
135
- const onRowClick = (event: MouseEvent) => {
136
- // Ignore clicks on the row actions cell or an expand/collapse chevron (tree or list-expansion),
137
- // so toggling a chevron never doubles as a row-click navigation.
138
- const target = event.target as HTMLElement
139
- if (target.closest('.atable-row-actions') || target.closest('.tree-index') || target.closest('.expansion-index'))
140
- return
141
- emit('row:click', rowIndex, event)
142
- }
143
-
144
- // A list-expansion row always binds Ctrl+G to toggle its own panel while opt-in
145
- // cell navigation stays gated on `addNavigation` (default off), so other view
146
- // types are unchanged.
147
- const isListExpansion = store.config.view === 'list-expansion'
148
-
149
- if (addNavigation || isListExpansion) {
150
- let handlers: KeypressHandlers = {}
151
-
152
- if (addNavigation === true) {
153
- handlers = { ...defaultKeypressHandlers }
154
- } else if (typeof addNavigation === 'object') {
155
- handlers = { ...defaultKeypressHandlers, ...addNavigation }
156
- }
157
-
158
- if (isListExpansion && !handlers['keydown.control.g']) {
159
- handlers['keydown.control.g'] = (event: KeyboardEvent) => {
160
- event.stopPropagation()
161
- event.preventDefault()
162
- store.toggleRowExpand(rowIndex)
163
- }
164
- }
165
-
166
- useKeyboardNav([
167
- {
168
- selectors: rowRef,
169
- handlers: handlers,
170
- },
171
- ])
172
- }
173
- </script>
174
-
175
- <style>
176
- .atable-row {
177
- background-color: white;
178
- }
179
-
180
- .atable-row-clickable {
181
- cursor: pointer;
182
- }
183
-
184
- .atable-row-clickable:hover > td {
185
- background-color: var(--sc-row-hover-color);
186
- }
187
-
188
- .atable-row:last-child > td {
189
- border-bottom: 1px solid var(--sc-row-border-color);
190
- }
191
-
192
- .atable-row > td:first-child {
193
- border-left: 4px solid var(--sc-row-border-color);
194
- }
195
-
196
- .atable-row > td:last-child {
197
- border-right: 1px solid var(--sc-row-border-color);
198
- }
199
-
200
- .list-index {
201
- color: var(--sc-header-text-color);
202
- font-weight: bold;
203
- padding-left: var(--sc-atable-row-padding);
204
- padding-right: 0.5em;
205
- text-align: left;
206
- user-select: none;
207
- /* width: 7ch; */
208
- border-top: 1px solid var(--sc-row-border-color);
209
- text-overflow: ellipsis;
210
- overflow: hidden;
211
- box-sizing: border-box;
212
- padding-top: var(--sc-atable-row-padding);
213
- padding-bottom: var(--sc-atable-row-padding);
214
- }
215
-
216
- .tree-index,
217
- .expansion-index {
218
- color: var(--sc-header-text-color);
219
- font-weight: bold;
220
- text-align: center;
221
- user-select: none;
222
- width: 2ch;
223
- box-sizing: border-box;
224
- cursor: pointer;
225
- padding-top: var(--sc-atable-row-padding);
226
- padding-bottom: var(--sc-atable-row-padding);
227
- }
228
-
229
- .atable-expanded-row {
230
- border-left: 2px solid var(--sc-row-border-color);
231
- }
232
-
233
- .atable-expanded-content {
234
- border-top: 1px solid var(--sc-row-border-color);
235
- padding: 1.5rem;
236
- }
237
- /* sticky cells in modified rows should be a solid color to properly hide non-sticky cells */
238
- .atable-row:has(td.cell-modified) > td.sticky-column,
239
- .atable-row:has(td.cell-modified) > th.sticky-column,
240
- .atable-row:has(td.cell-modified) > td.sticky-index,
241
- .atable-row:has(td.cell-modified) > th.sticky-index {
242
- background: var(--sc-cell-changed-color);
243
- }
244
- </style>
245
- <style scoped>
246
- .atable-row.changed-row-gradient:has(td.cell-modified) {
247
- --cell-color-start: color-mix(in srgb, var(--sc-cell-changed-color), #fff 20%);
248
- --cell-color-end: color-mix(in srgb, var(--sc-cell-changed-color), #fff 60%);
249
- background: linear-gradient(90deg, var(--cell-color-start), var(--cell-color-end));
250
- }
251
- </style>