@innertia-solutions/nuxt-theme-spark 0.1.116 → 0.1.118

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.
@@ -11,6 +11,7 @@ const props = defineProps<{
11
11
  hint?: string
12
12
  iconLeft?: object | Function | null
13
13
  autocomplete?: string
14
+ size?: 'sm' | 'md'
14
15
  }>()
15
16
 
16
17
  const modelValue = defineModel<string | number | null>({ default: '' })
@@ -22,7 +23,9 @@ const inputType = computed(() => {
22
23
  return props.type ?? 'text'
23
24
  })
24
25
 
25
- const baseClasses = 'py-2 px-3 block w-full rounded-lg text-sm text-slate-800 border border-card-line focus:ring-0 focus:border-gray-400 focus:outline-none disabled:opacity-50 dark:bg-transparent dark:text-muted-foreground-1 transition-colors placeholder:text-muted-foreground dark:placeholder:text-muted-foreground'
26
+ const baseClasses = computed(() =>
27
+ `${props.size === 'sm' ? 'py-1.5' : 'py-2'} px-3 block w-full rounded-lg text-sm text-slate-800 border border-card-line focus:ring-0 focus:border-gray-400 focus:outline-none disabled:opacity-50 dark:bg-transparent dark:text-muted-foreground-1 transition-colors placeholder:text-muted-foreground dark:placeholder:text-muted-foreground`
28
+ )
26
29
  </script>
27
30
 
28
31
  <template>
@@ -140,8 +140,10 @@ onBeforeUnmount(() => {
140
140
  })
141
141
 
142
142
  // ─── Column panel ─────────────────────────────────────────────────────────────
143
- const showColumnPanel = ref(false)
144
- const columnPanelRef = ref(null)
143
+ const showColumnPanel = ref(false)
144
+ const columnPanelRef = ref(null)
145
+ const columnButtonRef = ref(null)
146
+ const columnPanelStyle = ref({})
145
147
 
146
148
  const orderedColumns = computed(() => {
147
149
  if (!tableRef.value) return props.columns.filter(c => c.label)
@@ -171,7 +173,10 @@ const onDrop = (key) => {
171
173
  }
172
174
 
173
175
  const onColumnPanelOutsideClick = (e) => {
174
- if (columnPanelRef.value && !columnPanelRef.value.contains(e.target)) {
176
+ if (
177
+ columnPanelRef.value && !columnPanelRef.value.contains(e.target) &&
178
+ columnButtonRef.value && !columnButtonRef.value.contains(e.target)
179
+ ) {
175
180
  showColumnPanel.value = false
176
181
  }
177
182
  }
@@ -181,9 +186,20 @@ const onFilterPanelOutsideClick = (e) => {
181
186
  }
182
187
  }
183
188
 
184
- watch(showColumnPanel, (v) => {
185
- if (v) document.addEventListener('mousedown', onColumnPanelOutsideClick)
186
- else document.removeEventListener('mousedown', onColumnPanelOutsideClick)
189
+ watch(showColumnPanel, async (v) => {
190
+ if (v) {
191
+ await nextTick()
192
+ const rect = columnButtonRef.value?.getBoundingClientRect()
193
+ if (rect) {
194
+ columnPanelStyle.value = {
195
+ top: rect.bottom + 6 + 'px',
196
+ right: window.innerWidth - rect.right + 'px',
197
+ }
198
+ }
199
+ document.addEventListener('mousedown', onColumnPanelOutsideClick)
200
+ } else {
201
+ document.removeEventListener('mousedown', onColumnPanelOutsideClick)
202
+ }
187
203
  })
188
204
  watch(showFilterPanel, (v) => {
189
205
  if (v) document.addEventListener('mousedown', onFilterPanelOutsideClick)
@@ -208,7 +224,7 @@ defineExpose({ getSelectedRows, reload, clearCache, exportTable, tableRef })
208
224
  <!-- Toolbar -->
209
225
  <div class="flex flex-wrap items-center gap-3 px-4 py-3 border-b border-card-line">
210
226
  <div v-if="showSearch" class="flex-1 min-w-48">
211
- <Forms.Input v-model="search" type="search" :placeholder="searchPlaceholder" :icon-left="IconSearch" />
227
+ <Forms.Input v-model="search" type="search" :placeholder="searchPlaceholder" :icon-left="IconSearch" size="sm" />
212
228
  </div>
213
229
 
214
230
  <div v-if="showFilters && hasFilterableColumns" class="relative">
@@ -249,6 +265,7 @@ defineExpose({ getSelectedRows, reload, clearCache, exportTable, tableRef })
249
265
  <slot name="toolbar" />
250
266
 
251
267
  <button
268
+ ref="columnButtonRef"
252
269
  type="button"
253
270
  @click="showColumnPanel = !showColumnPanel"
254
271
  :class="[
@@ -321,47 +338,50 @@ defineExpose({ getSelectedRows, reload, clearCache, exportTable, tableRef })
321
338
  </div>
322
339
  </div>
323
340
 
324
- <!-- Column panel — outside overflow-hidden so never clipped -->
325
- <Transition
326
- enter-active-class="transition ease-out duration-150"
327
- enter-from-class="opacity-0 translate-y-1 scale-95"
328
- enter-to-class="opacity-100 translate-y-0 scale-100"
329
- leave-active-class="transition ease-in duration-100"
330
- leave-from-class="opacity-100 translate-y-0 scale-100"
331
- leave-to-class="opacity-0 translate-y-1 scale-95"
332
- >
333
- <div
334
- v-if="showColumnPanel"
335
- ref="columnPanelRef"
336
- class="absolute top-12 right-0 z-50 bg-dropdown border border-dropdown-line rounded-xl shadow-2xl p-3 min-w-56 max-h-80 overflow-y-auto"
341
+ <!-- Column panel — teleported to body to escape overflow-hidden -->
342
+ <Teleport to="body">
343
+ <Transition
344
+ enter-active-class="transition ease-out duration-150"
345
+ enter-from-class="opacity-0 translate-y-1 scale-95"
346
+ enter-to-class="opacity-100 translate-y-0 scale-100"
347
+ leave-active-class="transition ease-in duration-100"
348
+ leave-from-class="opacity-100 translate-y-0 scale-100"
349
+ leave-to-class="opacity-0 translate-y-1 scale-95"
337
350
  >
338
- <p class="text-[10px] font-bold text-muted-foreground uppercase tracking-widest mb-2 px-1">
339
- Columnas visibles
340
- </p>
341
351
  <div
342
- v-for="col in orderedColumns"
343
- :key="col.key"
344
- draggable="true"
345
- @dragstart="onDragStart(col.key)"
346
- @dragover="(e) => onDragOver(e, col.key)"
347
- @dragleave="onDragLeave"
348
- @drop="onDrop(col.key)"
349
- class="flex items-center gap-2 py-1.5 px-2 rounded-lg select-none transition-colors"
350
- :class="dragOverKey === col.key
351
- ? 'bg-blue-50 dark:bg-blue-900/20 ring-1 ring-blue-300 dark:ring-blue-700'
352
- : 'hover:bg-muted-hover cursor-grab'"
352
+ v-if="showColumnPanel"
353
+ ref="columnPanelRef"
354
+ class="fixed z-50 bg-dropdown border border-dropdown-line rounded-xl shadow-2xl p-3 min-w-56 max-h-80 overflow-y-auto"
355
+ :style="columnPanelStyle"
353
356
  >
354
- <IconGripVertical class="size-4 text-muted-foreground-2 shrink-0" />
355
- <input
356
- type="checkbox"
357
- :checked="tableRef?.table.getColumn(col.key)?.getIsVisible() ?? true"
358
- @change="tableRef?.table.getColumn(col.key)?.toggleVisibility()"
359
- @click.stop
360
- class="rounded border-card-line bg-surface shrink-0 cursor-pointer"
361
- />
362
- <span class="text-sm text-foreground truncate">{{ col.label }}</span>
357
+ <p class="text-[10px] font-bold text-muted-foreground uppercase tracking-widest mb-2 px-1">
358
+ Columnas visibles
359
+ </p>
360
+ <div
361
+ v-for="col in orderedColumns"
362
+ :key="col.key"
363
+ draggable="true"
364
+ @dragstart="onDragStart(col.key)"
365
+ @dragover="(e) => onDragOver(e, col.key)"
366
+ @dragleave="onDragLeave"
367
+ @drop="onDrop(col.key)"
368
+ class="flex items-center gap-2 py-1.5 px-2 rounded-lg select-none transition-colors"
369
+ :class="dragOverKey === col.key
370
+ ? 'bg-blue-50 dark:bg-blue-900/20 ring-1 ring-blue-300 dark:ring-blue-700'
371
+ : 'hover:bg-muted-hover cursor-grab'"
372
+ >
373
+ <IconGripVertical class="size-4 text-muted-foreground-2 shrink-0" />
374
+ <input
375
+ type="checkbox"
376
+ :checked="tableRef?.table.getColumn(col.key)?.getIsVisible() ?? true"
377
+ @change="tableRef?.table.getColumn(col.key)?.toggleVisibility()"
378
+ @click.stop
379
+ class="rounded border-card-line bg-surface shrink-0 cursor-pointer"
380
+ />
381
+ <span class="text-sm text-foreground truncate">{{ col.label }}</span>
382
+ </div>
363
383
  </div>
364
- </div>
365
- </Transition>
384
+ </Transition>
385
+ </Teleport>
366
386
  </div>
367
387
  </template>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@innertia-solutions/nuxt-theme-spark",
3
- "version": "0.1.116",
3
+ "version": "0.1.118",
4
4
  "description": "Innertia Solutions — Spark theme: backoffice, landing and mobile components and layouts",
5
5
  "keywords": [
6
6
  "nuxt",