@bagelink/vue 1.15.209 → 1.15.211
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/components/dataTable/DataTable.vue.d.ts.map +1 -1
- package/dist/composables/useSchemaField.d.ts.map +1 -1
- package/dist/index.cjs +27 -27
- package/dist/index.mjs +3294 -3279
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/dataTable/DataTable.vue +28 -15
- package/src/composables/useSchemaField.ts +13 -0
package/package.json
CHANGED
|
@@ -128,9 +128,14 @@ const computedItemHeight = computed(() => `${itemHeight.value}px`)
|
|
|
128
128
|
|
|
129
129
|
watch(
|
|
130
130
|
() => loading.value,
|
|
131
|
-
(newLoadingVal, oldLoadingVal) => {
|
|
131
|
+
async (newLoadingVal, oldLoadingVal) => {
|
|
132
132
|
if (newLoadingVal === oldLoadingVal) { return }
|
|
133
|
-
if (!newLoadingVal) {
|
|
133
|
+
if (!newLoadingVal) {
|
|
134
|
+
registerLastItemObserver()
|
|
135
|
+
scrollTo(0)
|
|
136
|
+
await nextTick()
|
|
137
|
+
scrollTo(0)
|
|
138
|
+
}
|
|
134
139
|
},
|
|
135
140
|
{ immediate: true }
|
|
136
141
|
)
|
|
@@ -141,9 +146,14 @@ watch(
|
|
|
141
146
|
)
|
|
142
147
|
|
|
143
148
|
watch(
|
|
144
|
-
() => computedData.value,
|
|
145
|
-
(
|
|
146
|
-
|
|
149
|
+
() => computedData.value.length,
|
|
150
|
+
async (newLen, oldLen) => {
|
|
151
|
+
// Infinite-scroll appends: keep position. First load (0 → n) still resets.
|
|
152
|
+
const isAppend = props.onLastItemVisible !== undefined && (oldLen ?? 0) > 0
|
|
153
|
+
if (newLen === oldLen || isAppend) return
|
|
154
|
+
|
|
155
|
+
scrollTo(0)
|
|
156
|
+
await nextTick()
|
|
147
157
|
scrollTo(0)
|
|
148
158
|
}
|
|
149
159
|
)
|
|
@@ -171,7 +181,7 @@ const headerFontSize = computed(() => {
|
|
|
171
181
|
<template>
|
|
172
182
|
<div class="table-list-wrap h-100p" v-bind="containerProps" :class="{ overflowHiddenLoading: showLoading }">
|
|
173
183
|
<Loading v-if="showLoading" class="h100p" />
|
|
174
|
-
<div v-bind="wrapperProps" :class="{ 'pointer-events-none': showLoading }">
|
|
184
|
+
<div v-if="!isEmpty" v-bind="wrapperProps" :class="{ 'pointer-events-none': showLoading }">
|
|
175
185
|
<table class="infinite-wrapper" :class="{ selecting: computedSelectedItems.length }">
|
|
176
186
|
<thead class="row first-row">
|
|
177
187
|
<th v-if="isSortable" class="col-drag" />
|
|
@@ -218,16 +228,16 @@ const headerFontSize = computed(() => {
|
|
|
218
228
|
<tr v-if="props.onLastItemVisible !== undefined" ref="lastItemEl" style="height: 1px;" />
|
|
219
229
|
</tbody>
|
|
220
230
|
</table>
|
|
221
|
-
<!-- Built-in empty state (overridable via the #empty slot) -->
|
|
222
|
-
<slot v-if="isEmpty" name="empty">
|
|
223
|
-
<EmptyState
|
|
224
|
-
:icon="props.emptyIcon ?? 'inbox'"
|
|
225
|
-
:title="props.emptyTitle ?? 'No results'"
|
|
226
|
-
:description="props.emptyDescription"
|
|
227
|
-
compact
|
|
228
|
-
/>
|
|
229
|
-
</slot>
|
|
230
231
|
</div>
|
|
232
|
+
<!-- Outside the virtualized wrapper so EmptyState doesn't inflate scroll height -->
|
|
233
|
+
<slot v-if="isEmpty" name="empty">
|
|
234
|
+
<EmptyState
|
|
235
|
+
:icon="props.emptyIcon ?? 'inbox'"
|
|
236
|
+
:title="props.emptyTitle ?? 'No results'"
|
|
237
|
+
:description="props.emptyDescription"
|
|
238
|
+
compact
|
|
239
|
+
/>
|
|
240
|
+
</slot>
|
|
231
241
|
</div>
|
|
232
242
|
</template>
|
|
233
243
|
|
|
@@ -254,6 +264,9 @@ cursor: grab;
|
|
|
254
264
|
|
|
255
265
|
.table-list-wrap {
|
|
256
266
|
min-height: 150px;
|
|
267
|
+
/* Prevent browser scroll anchoring from pushing content to the bottom
|
|
268
|
+
when rows mount and the virtual list height jumps. */
|
|
269
|
+
overflow-anchor: none;
|
|
257
270
|
}
|
|
258
271
|
|
|
259
272
|
.selected {
|
|
@@ -26,6 +26,16 @@ const SLOT_VALUE_COMPONENTS = new Set(['div', 'span', 'p'])
|
|
|
26
26
|
|
|
27
27
|
const SRC_VALUE_COMPONENTS = new Set(['img', 'iframe'])
|
|
28
28
|
|
|
29
|
+
/** Display components that take content via `value` (not `modelValue`). */
|
|
30
|
+
const VALUE_PROP_NAMES = new Set(['BglBadge', 'Badge', 'BglPill', 'Pill'])
|
|
31
|
+
|
|
32
|
+
function usesValueProp(Component: unknown): boolean {
|
|
33
|
+
if (!Component || typeof Component === 'string') return false
|
|
34
|
+
const name = (Component as { name?: string, __name?: string }).name
|
|
35
|
+
?? (Component as { __name?: string }).__name
|
|
36
|
+
return !!name && VALUE_PROP_NAMES.has(name)
|
|
37
|
+
}
|
|
38
|
+
|
|
29
39
|
export interface UseSchemaFieldOptions<T, SFP extends Path<T>> {
|
|
30
40
|
mode?: 'form' | 'preview' | 'table'
|
|
31
41
|
getFormData?: () => T
|
|
@@ -217,6 +227,9 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
|
|
|
217
227
|
// Slot components don't need a value prop
|
|
218
228
|
} else if (isSrcValueComponent) {
|
|
219
229
|
props.src = transformedValue
|
|
230
|
+
} else if (usesValueProp(Component)) {
|
|
231
|
+
// Badge etc. read `value`, not modelValue — empty outline pills otherwise
|
|
232
|
+
props.value = transformedValue != null ? String(transformedValue) : transformedValue
|
|
220
233
|
} else {
|
|
221
234
|
props.modelValue = transformedValue
|
|
222
235
|
}
|