@innertia-solutions/nuxt-theme-spark 0.1.73 → 0.1.74
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/Table/Standard.vue +90 -117
- package/components/Table.vue +3 -5
- package/package.json +1 -1
|
@@ -137,138 +137,111 @@ defineExpose({ getSelectedRows, reload, clearCache, exportTable, tableRef })
|
|
|
137
137
|
|
|
138
138
|
<template>
|
|
139
139
|
<div class="relative" ref="containerRef">
|
|
140
|
-
<div :class="previewRow && previewEnabled ? 'flex items-stretch gap-3' : ''">
|
|
141
140
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
class="relative bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-2xl shadow-sm overflow-hidden"
|
|
145
|
-
:style="previewRow && previewEnabled ? { width: currentRatio + '%', minWidth: 0, flexShrink: 0 } : {}"
|
|
146
|
-
>
|
|
147
|
-
<!-- Toolbar -->
|
|
148
|
-
<div class="flex flex-wrap items-center gap-3 px-4 py-3 border-b border-slate-200 dark:border-slate-700">
|
|
149
|
-
<!-- Search -->
|
|
150
|
-
<div v-if="showSearch" class="flex-1 min-w-48">
|
|
151
|
-
<Forms.Input
|
|
152
|
-
v-model="search"
|
|
153
|
-
type="search"
|
|
154
|
-
:placeholder="searchPlaceholder"
|
|
155
|
-
:icon-left="IconSearch"
|
|
156
|
-
/>
|
|
157
|
-
</div>
|
|
141
|
+
<!-- Card único -->
|
|
142
|
+
<div class="bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-2xl shadow-sm overflow-hidden">
|
|
158
143
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
@click="showFilterPanel = !showFilterPanel"
|
|
164
|
-
:class="[
|
|
165
|
-
'py-1.5 px-3 inline-flex items-center gap-2 text-sm font-medium rounded-lg border transition-colors',
|
|
166
|
-
showFilterPanel || activeFilterCount > 0
|
|
167
|
-
? 'border-blue-500 bg-blue-50 text-blue-700 dark:bg-blue-900/20 dark:border-blue-500 dark:text-blue-300'
|
|
168
|
-
: 'border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-600 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-700'
|
|
169
|
-
]"
|
|
170
|
-
>
|
|
171
|
-
<IconAdjustmentsHorizontal class="size-4" stroke="1.5" />
|
|
172
|
-
Filtros
|
|
173
|
-
<span
|
|
174
|
-
v-if="activeFilterCount > 0"
|
|
175
|
-
class="inline-flex items-center justify-center size-5 rounded-full bg-blue-600 text-white text-xs font-bold"
|
|
176
|
-
>{{ activeFilterCount }}</span>
|
|
177
|
-
</button>
|
|
178
|
-
|
|
179
|
-
<slot name="actions" />
|
|
180
|
-
|
|
181
|
-
<!-- Column visibility toggle -->
|
|
182
|
-
<button
|
|
183
|
-
type="button"
|
|
184
|
-
@click="showColumnPanel = !showColumnPanel"
|
|
185
|
-
:class="[
|
|
186
|
-
'py-1.5 px-3 inline-flex items-center gap-2 text-sm font-medium rounded-lg border transition-colors',
|
|
187
|
-
showColumnPanel
|
|
188
|
-
? 'border-blue-500 bg-blue-50 text-blue-700 dark:bg-blue-900/20 dark:border-blue-500 dark:text-blue-300'
|
|
189
|
-
: 'border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-600 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-700'
|
|
190
|
-
]"
|
|
191
|
-
>
|
|
192
|
-
<IconLayoutColumns class="size-4" />
|
|
193
|
-
Columnas
|
|
194
|
-
</button>
|
|
195
|
-
|
|
196
|
-
<!-- Export -->
|
|
197
|
-
<TableExportable
|
|
198
|
-
v-if="showExport"
|
|
199
|
-
:table-ref="tableRef"
|
|
200
|
-
:name="name"
|
|
201
|
-
:columns="columns"
|
|
202
|
-
/>
|
|
144
|
+
<!-- Toolbar -->
|
|
145
|
+
<div class="flex flex-wrap items-center gap-3 px-4 py-3 border-b border-slate-200 dark:border-slate-700">
|
|
146
|
+
<div v-if="showSearch" class="flex-1 min-w-48">
|
|
147
|
+
<Forms.Input v-model="search" type="search" :placeholder="searchPlaceholder" :icon-left="IconSearch" />
|
|
203
148
|
</div>
|
|
204
149
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
150
|
+
<button
|
|
151
|
+
v-if="showFilters && hasFilterableColumns"
|
|
152
|
+
type="button"
|
|
153
|
+
@click="showFilterPanel = !showFilterPanel"
|
|
154
|
+
:class="[
|
|
155
|
+
'py-1.5 px-3 inline-flex items-center gap-2 text-sm font-medium rounded-lg border transition-colors',
|
|
156
|
+
showFilterPanel || activeFilterCount > 0
|
|
157
|
+
? 'border-blue-500 bg-blue-50 text-blue-700 dark:bg-blue-900/20 dark:border-blue-500 dark:text-blue-300'
|
|
158
|
+
: 'border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-600 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-700'
|
|
159
|
+
]"
|
|
213
160
|
>
|
|
214
|
-
<
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
:checkable="checkable"
|
|
231
|
-
:cached="cached"
|
|
232
|
-
:show-reload-button="showReloadButton"
|
|
233
|
-
:click-row-to-open="clickRowToOpen"
|
|
234
|
-
:preview-row-id="previewRow?.id ?? null"
|
|
235
|
-
:preview-mode="!!previewEnabled"
|
|
236
|
-
@row-click="handleRowClick"
|
|
237
|
-
@loaded="emit('loaded', $event)"
|
|
161
|
+
<IconAdjustmentsHorizontal class="size-4" stroke="1.5" />
|
|
162
|
+
Filtros
|
|
163
|
+
<span v-if="activeFilterCount > 0" class="inline-flex items-center justify-center size-5 rounded-full bg-blue-600 text-white text-xs font-bold">{{ activeFilterCount }}</span>
|
|
164
|
+
</button>
|
|
165
|
+
|
|
166
|
+
<slot name="actions" />
|
|
167
|
+
|
|
168
|
+
<button
|
|
169
|
+
type="button"
|
|
170
|
+
@click="showColumnPanel = !showColumnPanel"
|
|
171
|
+
:class="[
|
|
172
|
+
'py-1.5 px-3 inline-flex items-center gap-2 text-sm font-medium rounded-lg border transition-colors',
|
|
173
|
+
showColumnPanel
|
|
174
|
+
? 'border-blue-500 bg-blue-50 text-blue-700 dark:bg-blue-900/20 dark:border-blue-500 dark:text-blue-300'
|
|
175
|
+
: 'border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-600 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-slate-700'
|
|
176
|
+
]"
|
|
238
177
|
>
|
|
239
|
-
<
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
</Table>
|
|
243
|
-
</div>
|
|
178
|
+
<IconLayoutColumns class="size-4" />
|
|
179
|
+
Columnas
|
|
180
|
+
</button>
|
|
244
181
|
|
|
245
|
-
|
|
246
|
-
<div
|
|
247
|
-
v-if="previewRow && previewEnabled"
|
|
248
|
-
class="w-3 flex items-center justify-center cursor-col-resize shrink-0 group"
|
|
249
|
-
@mousedown="startResize"
|
|
250
|
-
>
|
|
251
|
-
<div class="w-px h-12 bg-slate-200 dark:bg-slate-600 rounded-full group-hover:bg-indigo-400 dark:group-hover:bg-indigo-500 transition-colors" />
|
|
182
|
+
<TableExportable v-if="showExport" :table-ref="tableRef" :name="name" :columns="columns" />
|
|
252
183
|
</div>
|
|
253
184
|
|
|
254
|
-
<!--
|
|
185
|
+
<!-- Filter panel -->
|
|
255
186
|
<Transition
|
|
256
|
-
enter-active-class="transition ease-out duration-
|
|
257
|
-
enter-from-class="opacity-0 translate-
|
|
258
|
-
enter-to-class="opacity-100 translate-
|
|
259
|
-
leave-active-class="transition ease-in duration-
|
|
260
|
-
leave-from-class="opacity-100 translate-
|
|
261
|
-
leave-to-class="opacity-0 translate-
|
|
187
|
+
enter-active-class="transition ease-out duration-150"
|
|
188
|
+
enter-from-class="opacity-0 -translate-y-2"
|
|
189
|
+
enter-to-class="opacity-100 translate-y-0"
|
|
190
|
+
leave-active-class="transition ease-in duration-100"
|
|
191
|
+
leave-from-class="opacity-100 translate-y-0"
|
|
192
|
+
leave-to-class="opacity-0 -translate-y-2"
|
|
262
193
|
>
|
|
194
|
+
<div v-if="showFilterPanel && hasFilterableColumns" class="px-4 py-3 border-b border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-900/50">
|
|
195
|
+
<TableFilter v-model="activeFilters" :columns="filtersConfig" />
|
|
196
|
+
</div>
|
|
197
|
+
</Transition>
|
|
198
|
+
|
|
199
|
+
<!-- Contenido: tabla + preview en flex -->
|
|
200
|
+
<div :class="previewRow && previewEnabled ? 'flex items-stretch' : ''">
|
|
201
|
+
|
|
202
|
+
<!-- Tabla -->
|
|
263
203
|
<div
|
|
264
|
-
|
|
265
|
-
class="bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-2xl shadow-sm overflow-hidden flex flex-col"
|
|
266
|
-
:style="{ width: (100 - currentRatio) + '%', minWidth: 0, flexShrink: 0 }"
|
|
204
|
+
:style="previewRow && previewEnabled ? { width: currentRatio + '%', flexShrink: 0, minWidth: 0 } : {}"
|
|
267
205
|
>
|
|
268
|
-
<
|
|
206
|
+
<Table
|
|
207
|
+
ref="tableRef"
|
|
208
|
+
:endpoint="endpoint"
|
|
209
|
+
:columns="columns"
|
|
210
|
+
:name="name"
|
|
211
|
+
:params="mergedParams"
|
|
212
|
+
:search="search"
|
|
213
|
+
:checkable="checkable"
|
|
214
|
+
:cached="cached"
|
|
215
|
+
:show-reload-button="showReloadButton"
|
|
216
|
+
:click-row-to-open="clickRowToOpen"
|
|
217
|
+
:preview-row-id="previewRow?.id ?? null"
|
|
218
|
+
:preview-mode="!!previewEnabled"
|
|
219
|
+
@row-click="handleRowClick"
|
|
220
|
+
@loaded="emit('loaded', $event)"
|
|
221
|
+
>
|
|
222
|
+
<template v-for="(_, name) in $slots" #[name]="slotProps">
|
|
223
|
+
<slot :name="name" v-bind="slotProps ?? {}" />
|
|
224
|
+
</template>
|
|
225
|
+
</Table>
|
|
269
226
|
</div>
|
|
270
|
-
</Transition>
|
|
271
227
|
|
|
228
|
+
<!-- Divider + preview -->
|
|
229
|
+
<template v-if="previewRow && previewEnabled">
|
|
230
|
+
<!-- Resize handle -->
|
|
231
|
+
<div
|
|
232
|
+
class="w-1 shrink-0 cursor-col-resize bg-slate-100 dark:bg-slate-700/60 hover:bg-indigo-300 dark:hover:bg-indigo-600 transition-colors"
|
|
233
|
+
@mousedown="startResize"
|
|
234
|
+
/>
|
|
235
|
+
<!-- Preview -->
|
|
236
|
+
<div
|
|
237
|
+
class="flex flex-col overflow-y-auto border-l border-slate-200 dark:border-slate-700"
|
|
238
|
+
:style="{ width: (100 - currentRatio) + '%', flexShrink: 0, minWidth: 0 }"
|
|
239
|
+
>
|
|
240
|
+
<slot name="preview" :row="previewRow" :close="closePreview" />
|
|
241
|
+
</div>
|
|
242
|
+
</template>
|
|
243
|
+
|
|
244
|
+
</div>
|
|
272
245
|
</div>
|
|
273
246
|
|
|
274
247
|
<!-- Column panel — outside overflow-hidden so never clipped -->
|
package/components/Table.vue
CHANGED
|
@@ -318,13 +318,11 @@ const measureText = (text, font) => {
|
|
|
318
318
|
|
|
319
319
|
const autoSizeColumn = (header) => {
|
|
320
320
|
const colId = header.column.id
|
|
321
|
-
const pad = 32
|
|
321
|
+
const pad = 32
|
|
322
322
|
|
|
323
|
-
// Measure header label
|
|
324
323
|
const label = header.column.columnDef.meta?.label ?? header.id
|
|
325
|
-
let max = measureText(label, '500 12px ui-sans-serif,system-ui,sans-serif') + pad + 20
|
|
324
|
+
let max = measureText(label, '500 12px ui-sans-serif,system-ui,sans-serif') + pad + 20
|
|
326
325
|
|
|
327
|
-
// Measure all visible data cells
|
|
328
326
|
if (tableBodyRef.value) {
|
|
329
327
|
tableBodyRef.value.querySelectorAll(`td[data-col-id="${colId}"]`).forEach(td => {
|
|
330
328
|
const w = measureText(td.textContent?.trim(), '14px ui-sans-serif,system-ui,sans-serif') + pad
|
|
@@ -332,7 +330,7 @@ const autoSizeColumn = (header) => {
|
|
|
332
330
|
})
|
|
333
331
|
}
|
|
334
332
|
|
|
335
|
-
|
|
333
|
+
table.setColumnSizing(prev => ({ ...prev, [colId]: Math.ceil(max) }))
|
|
336
334
|
}
|
|
337
335
|
|
|
338
336
|
const onHeaderDragStart = (colId) => { draggedHeaderId = colId }
|