@innertia-solutions/nuxt-theme-spark 0.1.110 → 0.1.111
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/Admin/Header.vue +3 -3
- package/components/Admin/Page.vue +3 -3
- package/components/Admin/PageHeader.vue +4 -4
- package/components/App/Button.vue +2 -2
- package/components/App/Dropdown.vue +5 -5
- package/components/App/EmptyState.vue +3 -3
- package/components/App/LoadingState.vue +4 -4
- package/components/App/SwitchColorTheme.vue +2 -2
- package/components/App/Tag.vue +1 -1
- package/components/DataTable.vue +40 -40
- package/components/Forms/DatePicker.vue +1 -1
- package/components/Forms/Input.vue +5 -5
- package/components/Forms/Select.vue +6 -6
- package/components/Forms/SelectServer.vue +30 -30
- package/components/Layout/Auth.vue +4 -4
- package/components/Modal/DeleteConfirm.vue +1 -1
- package/components/Modal.vue +5 -5
- package/components/Nav/Tabs.vue +2 -2
- package/components/Table/Database.vue +4 -4
- package/components/Table/DownloadDropdown.vue +10 -10
- package/components/Table/FilterDropdown.vue +10 -10
- package/components/Table/Grid.vue +1 -1
- package/components/Table/Kanban.vue +7 -7
- package/components/Table/List.vue +6 -6
- package/components/Table.vue +6 -6
- package/components/TableExportable.vue +17 -17
- package/components/TableFilter.vue +7 -7
- package/components/Toast/Alert.vue +2 -2
- package/package.json +1 -1
|
@@ -331,7 +331,7 @@ const sizeClasses = computed(() => {
|
|
|
331
331
|
// Computed classes for validation states
|
|
332
332
|
const validationClasses = computed(() => {
|
|
333
333
|
if (props.error) return "border-red-400 dark:border-red-500";
|
|
334
|
-
return "border-
|
|
334
|
+
return "border-card-line";
|
|
335
335
|
});
|
|
336
336
|
|
|
337
337
|
// Combined select classes
|
|
@@ -339,7 +339,7 @@ const selectClasses = computed(() => {
|
|
|
339
339
|
let base, focus, disabled;
|
|
340
340
|
|
|
341
341
|
base =
|
|
342
|
-
"relative w-full rounded-lg border bg-
|
|
342
|
+
"relative w-full rounded-lg border bg-card transition-colors cursor-pointer text-foreground";
|
|
343
343
|
|
|
344
344
|
if (props.multiple && props.tagsMode) {
|
|
345
345
|
base += " px-3 pe-8 min-h-[2.375rem] flex items-center flex-wrap text-nowrap";
|
|
@@ -499,7 +499,7 @@ onMounted(() => {
|
|
|
499
499
|
<template>
|
|
500
500
|
<div class="space-y-1.5">
|
|
501
501
|
<!-- Label -->
|
|
502
|
-
<label v-if="label" class="block text-sm font-medium text-
|
|
502
|
+
<label v-if="label" class="block text-sm font-medium text-foreground">
|
|
503
503
|
{{ label }}
|
|
504
504
|
</label>
|
|
505
505
|
|
|
@@ -526,7 +526,7 @@ onMounted(() => {
|
|
|
526
526
|
<!-- Tags mode for multiple selection -->
|
|
527
527
|
<div v-if="multiple && tagsMode && selectedOptions.length" class="flex flex-wrap items-center gap-1 flex-1">
|
|
528
528
|
<div v-for="option in selectedOptions" :key="option.id"
|
|
529
|
-
class="flex flex-nowrap items-center relative z-10 bg-
|
|
529
|
+
class="flex flex-nowrap items-center relative z-10 bg-card border border-card-line rounded-full p-1 m-1">
|
|
530
530
|
<!-- Avatar/Icon -->
|
|
531
531
|
<div v-if="option.avatar || option.icon" class="size-6 me-1">
|
|
532
532
|
<img v-if="option.avatar" :src="option.avatar" :alt="getOptionLabel(option)"
|
|
@@ -535,7 +535,7 @@ onMounted(() => {
|
|
|
535
535
|
</div>
|
|
536
536
|
|
|
537
537
|
<!-- Label -->
|
|
538
|
-
<div class="whitespace-nowrap text-
|
|
538
|
+
<div class="whitespace-nowrap text-foreground text-sm pl-1.5">
|
|
539
539
|
<slot name="tag" :option="option">
|
|
540
540
|
{{ getOptionLabel(option) }}
|
|
541
541
|
</slot>
|
|
@@ -543,7 +543,7 @@ onMounted(() => {
|
|
|
543
543
|
|
|
544
544
|
<!-- Remove button -->
|
|
545
545
|
<button type="button" v-if="!disabled" @click.stop="removeTag(option)"
|
|
546
|
-
class="inline-flex shrink-0 justify-center items-center size-5 ms-2 rounded-full text-
|
|
546
|
+
class="inline-flex shrink-0 justify-center items-center size-5 ms-2 rounded-full text-foreground bg-surface-1 hover:bg-surface-1 focus:outline-none focus:ring-2 focus:ring-gray-400 text-sm cursor-pointer">
|
|
547
547
|
<svg class="shrink-0 size-3" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
|
|
548
548
|
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
549
549
|
<path d="M18 6 6 18" />
|
|
@@ -551,13 +551,13 @@ onMounted(() => {
|
|
|
551
551
|
</svg>
|
|
552
552
|
</button>
|
|
553
553
|
</div>
|
|
554
|
-
<span v-if="!selectedOptions.length" class="text-
|
|
554
|
+
<span v-if="!selectedOptions.length" class="text-muted-foreground py-2.5 px-2">
|
|
555
555
|
{{ placeholder }}
|
|
556
556
|
</span>
|
|
557
557
|
</div>
|
|
558
558
|
|
|
559
559
|
<span v-else class="truncate flex-1 text-left pr-10"
|
|
560
|
-
:class="{ 'text-
|
|
560
|
+
:class="{ 'text-muted-foreground': !selectedOptions.length, 'text-foreground': selectedOptions.length }">
|
|
561
561
|
<slot name="display" :selectedOptions="selectedOptions" :displayText="displayText">
|
|
562
562
|
{{ displayText }}
|
|
563
563
|
</slot>
|
|
@@ -566,7 +566,7 @@ onMounted(() => {
|
|
|
566
566
|
<!-- Clear button -->
|
|
567
567
|
<button type="button" v-if="clearable && selectedOptions.length && !disabled && !loading"
|
|
568
568
|
@click.stop="clearSelection"
|
|
569
|
-
class="absolute end-8 top-1/2 -translate-y-1/2 hover:bg-
|
|
569
|
+
class="absolute end-8 top-1/2 -translate-y-1/2 hover:bg-muted-hover rounded-full p-1 transition-colors focus:outline-none focus:ring-1 focus:ring-slate-400">
|
|
570
570
|
<svg class="size-3.5 text-slate-400" fill="currentColor" viewBox="0 0 20 20">
|
|
571
571
|
<path fill-rule="evenodd"
|
|
572
572
|
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
|
|
@@ -576,7 +576,7 @@ onMounted(() => {
|
|
|
576
576
|
|
|
577
577
|
<!-- Dropdown arrow -->
|
|
578
578
|
<div class="absolute top-1/2 end-3 -translate-y-1/2">
|
|
579
|
-
<svg class="shrink-0 size-3.5 text-
|
|
579
|
+
<svg class="shrink-0 size-3.5 text-muted-foreground transition-transform"
|
|
580
580
|
:class="{ 'rotate-180': isOpen }" xmlns="http://www.w3.org/2000/svg" width="24" height="24"
|
|
581
581
|
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
|
582
582
|
stroke-linejoin="round">
|
|
@@ -592,12 +592,12 @@ onMounted(() => {
|
|
|
592
592
|
enter-to-class="transform opacity-100 scale-100" leave-active-class="transition ease-in duration-75"
|
|
593
593
|
leave-from-class="transform opacity-100 scale-100" leave-to-class="transform opacity-0 scale-95">
|
|
594
594
|
<div v-show="isOpen" ref="optionsListRef" @scroll="handleScroll"
|
|
595
|
-
class="absolute z-50 w-full mt-1 bg-
|
|
595
|
+
class="absolute z-50 w-full mt-1 bg-dropdown border border-dropdown-line rounded-xl shadow-xl max-h-60 overflow-auto">
|
|
596
596
|
<!-- Search input -->
|
|
597
|
-
<div v-if="searchable" class="p-2 border-b border-
|
|
597
|
+
<div v-if="searchable" class="p-2 border-b border-card-line relative">
|
|
598
598
|
<input type="text" :value="searchQuery" :placeholder="searchPlaceholder" @input="handleSearchInput"
|
|
599
599
|
@keydown.enter.prevent
|
|
600
|
-
class="w-full px-3 py-2.5 pr-8 border border-
|
|
600
|
+
class="w-full px-3 py-2.5 pr-8 border border-card-line rounded-lg focus:outline-none focus:ring-0 focus:border-gray-400 dark:bg-surface dark:text-white text-sm transition-colors" />
|
|
601
601
|
<button type="button" v-if="searchQuery" @click.prevent="clearSearch"
|
|
602
602
|
class="absolute top-1/2 right-4 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">
|
|
603
603
|
<svg class="size-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
|
@@ -607,7 +607,7 @@ onMounted(() => {
|
|
|
607
607
|
</div>
|
|
608
608
|
|
|
609
609
|
<!-- Initial Loader if list is empty -->
|
|
610
|
-
<div v-if="isFetching && filteredOptions.length === 0" class="px-3 py-6 text-center text-
|
|
610
|
+
<div v-if="isFetching && filteredOptions.length === 0" class="px-3 py-6 text-center text-muted-foreground">
|
|
611
611
|
<div class="animate-spin rounded-full h-5 w-5 border-b-2 border-current mx-auto mb-2"></div>
|
|
612
612
|
<span class="text-sm">Buscando...</span>
|
|
613
613
|
</div>
|
|
@@ -615,9 +615,9 @@ onMounted(() => {
|
|
|
615
615
|
<!-- Empty option -->
|
|
616
616
|
<button type="button" v-if="allowEmpty && !multiple && !isFetching && filteredOptions.length" @click="
|
|
617
617
|
selectOption({ id: '__empty__', value: null, label: 'Ninguno' })
|
|
618
|
-
" class="w-full px-3 py-2 text-left hover:bg-
|
|
618
|
+
" class="w-full px-3 py-2 text-left hover:bg-muted-hover text-sm">
|
|
619
619
|
<slot name="empty-option">
|
|
620
|
-
<span class="text-
|
|
620
|
+
<span class="text-muted-foreground">Ninguno</span>
|
|
621
621
|
</slot>
|
|
622
622
|
</button>
|
|
623
623
|
|
|
@@ -625,11 +625,11 @@ onMounted(() => {
|
|
|
625
625
|
<div v-if="filteredOptions.length">
|
|
626
626
|
<button type="button" v-for="(option, index) in filteredOptions" :key="option.id"
|
|
627
627
|
@click="selectOption(option)" :class="[
|
|
628
|
-
'w-full px-3 py-2 text-left hover:bg-
|
|
628
|
+
'w-full px-3 py-2 text-left hover:bg-muted-hover flex items-center text-sm',
|
|
629
629
|
{
|
|
630
|
-
'bg-
|
|
630
|
+
'bg-muted': isOptionSelected(option),
|
|
631
631
|
'opacity-50 cursor-not-allowed': option.disabled,
|
|
632
|
-
'bg-
|
|
632
|
+
'bg-surface': focusedIndex === index,
|
|
633
633
|
},
|
|
634
634
|
]" :disabled="option.disabled">
|
|
635
635
|
<!-- Multiple selection checkbox -->
|
|
@@ -638,7 +638,7 @@ onMounted(() => {
|
|
|
638
638
|
'w-4 h-4 rounded-lg border-2 flex items-center justify-center',
|
|
639
639
|
isOptionSelected(option)
|
|
640
640
|
? 'bg-slate-600 border-slate-600 text-white'
|
|
641
|
-
: 'border-
|
|
641
|
+
: 'border-card-line',
|
|
642
642
|
]">
|
|
643
643
|
<svg v-if="isOptionSelected(option)" class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
|
|
644
644
|
<path fill-rule="evenodd"
|
|
@@ -660,11 +660,11 @@ onMounted(() => {
|
|
|
660
660
|
<div class="flex-1">
|
|
661
661
|
<slot name="option" :option="option" :selected="isOptionSelected(option)">
|
|
662
662
|
<div>
|
|
663
|
-
<div class="font-bold text-
|
|
663
|
+
<div class="font-bold text-foreground">
|
|
664
664
|
{{ getOptionLabel(option) }}
|
|
665
665
|
</div>
|
|
666
666
|
<div v-if="getOptionDescription(option)"
|
|
667
|
-
class="text-[10px] text-
|
|
667
|
+
class="text-[10px] text-muted-foreground uppercase tracking-tight">
|
|
668
668
|
{{ getOptionDescription(option) }}
|
|
669
669
|
</div>
|
|
670
670
|
</div>
|
|
@@ -684,33 +684,33 @@ onMounted(() => {
|
|
|
684
684
|
</div>
|
|
685
685
|
|
|
686
686
|
<!-- Infinite Scroll Mini Loader -->
|
|
687
|
-
<div v-if="isFetching && filteredOptions.length > 0" class="py-3 text-center border-t border-
|
|
687
|
+
<div v-if="isFetching && filteredOptions.length > 0" class="py-3 text-center border-t border-card-line">
|
|
688
688
|
<div class="animate-spin rounded-full h-4 w-4 border-b-2 border-slate-400 mx-auto"></div>
|
|
689
689
|
</div>
|
|
690
690
|
|
|
691
691
|
<!-- End of list marker -->
|
|
692
|
-
<div v-else-if="!hasMorePages && filteredOptions.length > 0" class="py-2 text-center text-[10px] text-
|
|
692
|
+
<div v-else-if="!hasMorePages && filteredOptions.length > 0" class="py-2 text-center text-[10px] text-muted-foreground uppercase tracking-widest border-t border-card-line">
|
|
693
693
|
No hay más opciones
|
|
694
694
|
</div>
|
|
695
695
|
|
|
696
696
|
<!-- No options message -->
|
|
697
697
|
<div v-else-if="!isFetching && searchQuery && filteredOptions.length === 0"
|
|
698
|
-
class="px-3 py-4 text-center text-
|
|
698
|
+
class="px-3 py-4 text-center text-muted-foreground text-sm">
|
|
699
699
|
<slot name="no-options"> No se encontraron opciones </slot>
|
|
700
700
|
</div>
|
|
701
701
|
|
|
702
702
|
<!-- No data message -->
|
|
703
703
|
<div v-else-if="!serverOptions.length && !isFetching" class="px-3 py-8 text-center">
|
|
704
704
|
<div class="flex flex-col items-center gap-y-2">
|
|
705
|
-
<div class="size-10 rounded-full bg-
|
|
706
|
-
<svg class="size-5 text-
|
|
705
|
+
<div class="size-10 rounded-full bg-muted flex items-center justify-center">
|
|
706
|
+
<svg class="size-5 text-muted-foreground-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
|
707
707
|
stroke-width="1.5" stroke="currentColor">
|
|
708
708
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
709
709
|
d="M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z" />
|
|
710
710
|
</svg>
|
|
711
711
|
</div>
|
|
712
|
-
<p class="text-sm font-bold text-
|
|
713
|
-
<p class="text-[10px] text-
|
|
712
|
+
<p class="text-sm font-bold text-muted-foreground">No hay datos disponibles</p>
|
|
713
|
+
<p class="text-[10px] text-muted-foreground-2 uppercase font-black tracking-widest">Intenta refrescar la página</p>
|
|
714
714
|
</div>
|
|
715
715
|
</div>
|
|
716
716
|
</div>
|
|
@@ -721,6 +721,6 @@ onMounted(() => {
|
|
|
721
721
|
|
|
722
722
|
<!-- Error / Hint -->
|
|
723
723
|
<p v-if="error" class="text-xs text-red-500 dark:text-red-400">{{ error }}</p>
|
|
724
|
-
<p v-else-if="hint" class="text-xs text-
|
|
724
|
+
<p v-else-if="hint" class="text-xs text-muted-foreground">{{ hint }}</p>
|
|
725
725
|
</div>
|
|
726
726
|
</template>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="bg-
|
|
2
|
+
<div class="bg-muted">
|
|
3
3
|
<div class="absolute top-4 right-4 z-20">
|
|
4
4
|
<slot name="theme-switch" />
|
|
5
5
|
</div>
|
|
6
6
|
<main class="flex min-h-full">
|
|
7
7
|
<!-- Columna izquierda: imagen/bienvenida -->
|
|
8
|
-
<div class="relative hidden min-h-screen lg:w-200 xl:w-[65%] bg-
|
|
8
|
+
<div class="relative hidden min-h-screen lg:w-200 xl:w-[65%] bg-surface lg:flex flex-col justify-between p-6 overflow-hidden">
|
|
9
9
|
<slot name="background" />
|
|
10
10
|
<div class="z-0 p-20 pt-[max(180px,10vh)]">
|
|
11
11
|
<slot name="welcome" />
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
15
|
<!-- Columna derecha: formulario -->
|
|
16
|
-
<div class="grow px-12 z-10 -ml-6 pr-6 bg-
|
|
16
|
+
<div class="grow px-12 z-10 -ml-6 pr-6 bg-card rounded-tl-[1.5rem] rounded-bl-[1.5rem]">
|
|
17
17
|
<div class="h-full min-h-screen sm:w-112 flex flex-col justify-center mx-auto space-y-5 p-4">
|
|
18
18
|
<div class="flex justify-center mb-6">
|
|
19
19
|
<slot name="logo" />
|
|
20
20
|
</div>
|
|
21
21
|
<slot />
|
|
22
|
-
<div class="absolute bottom-4 right-4 text-xs text-
|
|
22
|
+
<div class="absolute bottom-4 right-4 text-xs text-muted-foreground">
|
|
23
23
|
<slot name="version" />
|
|
24
24
|
</div>
|
|
25
25
|
</div>
|
|
@@ -26,7 +26,7 @@ const close = () => {
|
|
|
26
26
|
:backdrop-dismiss="!loading"
|
|
27
27
|
@update:model-value="$emit('update:modelValue', $event)"
|
|
28
28
|
>
|
|
29
|
-
<p class="text-sm text-
|
|
29
|
+
<p class="text-sm text-muted-foreground">{{ message }}</p>
|
|
30
30
|
|
|
31
31
|
<div class="flex justify-end gap-2 mt-5">
|
|
32
32
|
<AppButton
|
package/components/Modal.vue
CHANGED
|
@@ -52,18 +52,18 @@ onUnmounted(() => {
|
|
|
52
52
|
@click="onBackdrop"
|
|
53
53
|
>
|
|
54
54
|
<div
|
|
55
|
-
:class="['bg-
|
|
55
|
+
:class="['bg-card border border-card-line rounded-xl shadow-xl w-full modal-content', sizeClass]"
|
|
56
56
|
@click.stop
|
|
57
57
|
>
|
|
58
58
|
<!-- Header -->
|
|
59
|
-
<div v-if="showHeader" class="flex items-center justify-between px-5 py-4 border-b border-
|
|
60
|
-
<h3 :id="`${modalId}-label`" class="text-sm font-semibold text-
|
|
59
|
+
<div v-if="showHeader" class="flex items-center justify-between px-5 py-4 border-b border-card-line">
|
|
60
|
+
<h3 :id="`${modalId}-label`" class="text-sm font-semibold text-foreground">
|
|
61
61
|
<slot name="header">{{ title }}</slot>
|
|
62
62
|
</h3>
|
|
63
63
|
<button
|
|
64
64
|
v-if="closable"
|
|
65
65
|
type="button"
|
|
66
|
-
class="size-7 flex items-center justify-center rounded-lg text-
|
|
66
|
+
class="size-7 flex items-center justify-center rounded-lg text-muted-foreground hover:text-muted-foreground-1 hover:bg-muted-hover transition-colors"
|
|
67
67
|
@click="close"
|
|
68
68
|
>
|
|
69
69
|
<svg class="size-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
@@ -78,7 +78,7 @@ onUnmounted(() => {
|
|
|
78
78
|
</div>
|
|
79
79
|
|
|
80
80
|
<!-- Footer -->
|
|
81
|
-
<div v-if="showFooter" class="flex items-center justify-end gap-2 px-5 py-4 border-t border-
|
|
81
|
+
<div v-if="showFooter" class="flex items-center justify-end gap-2 px-5 py-4 border-t border-card-line">
|
|
82
82
|
<slot name="footer">
|
|
83
83
|
<AppButton v-if="closable" text="Cerrar" severity="secondary" size="sm" @click="close" />
|
|
84
84
|
</slot>
|
package/components/Nav/Tabs.vue
CHANGED
|
@@ -18,8 +18,8 @@ const props = withDefaults(defineProps<{
|
|
|
18
18
|
|
|
19
19
|
const colorTextClass = computed(() => ({
|
|
20
20
|
blue: 'text-blue-600 dark:text-blue-400',
|
|
21
|
-
gray: 'text-
|
|
22
|
-
slate: 'text-
|
|
21
|
+
gray: 'text-foreground',
|
|
22
|
+
slate: 'text-foreground',
|
|
23
23
|
green: 'text-green-600 dark:text-green-400',
|
|
24
24
|
amber: 'text-amber-600 dark:text-amber-400',
|
|
25
25
|
red: 'text-red-600 dark:text-red-400',
|
|
@@ -89,12 +89,12 @@ defineExpose({ reload })
|
|
|
89
89
|
v-model="search"
|
|
90
90
|
type="search"
|
|
91
91
|
:placeholder="searchPlaceholder"
|
|
92
|
-
class="block w-full rounded-lg border border-
|
|
92
|
+
class="block w-full rounded-lg border border-card-line bg-card text-foreground py-1.5 ps-9 pe-4 text-sm focus:outline-none focus:ring-1 focus:ring-indigo-500"
|
|
93
93
|
/>
|
|
94
94
|
</div>
|
|
95
95
|
|
|
96
96
|
<!-- Dense table wrapper — override Table's default padding with compact styles -->
|
|
97
|
-
<div class="overflow-x-auto border border-
|
|
97
|
+
<div class="overflow-x-auto border border-card-line rounded-xl">
|
|
98
98
|
<Table
|
|
99
99
|
ref="tableRef"
|
|
100
100
|
:endpoint="endpoint"
|
|
@@ -122,7 +122,7 @@ defineExpose({ reload })
|
|
|
122
122
|
@blur="saveEdit(row, col)"
|
|
123
123
|
@keydown.enter="saveEdit(row, col)"
|
|
124
124
|
@keydown.escape="cancelEdit"
|
|
125
|
-
class="flex-1 min-w-0 rounded border border-indigo-400 bg-
|
|
125
|
+
class="flex-1 min-w-0 rounded border border-indigo-400 bg-card text-foreground py-0.5 px-1.5 text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500"
|
|
126
126
|
>
|
|
127
127
|
<option v-for="opt in col.options" :key="opt.value" :value="opt.value">{{ opt.label }}</option>
|
|
128
128
|
</select>
|
|
@@ -134,7 +134,7 @@ defineExpose({ reload })
|
|
|
134
134
|
@blur="saveEdit(row, col)"
|
|
135
135
|
@keydown.enter="saveEdit(row, col)"
|
|
136
136
|
@keydown.escape="cancelEdit"
|
|
137
|
-
class="flex-1 min-w-0 rounded border border-indigo-400 bg-
|
|
137
|
+
class="flex-1 min-w-0 rounded border border-indigo-400 bg-card text-foreground py-0.5 px-1.5 text-xs focus:outline-none focus:ring-1 focus:ring-indigo-500"
|
|
138
138
|
/>
|
|
139
139
|
</div>
|
|
140
140
|
|
|
@@ -31,7 +31,7 @@ const exportTable = (format) => {
|
|
|
31
31
|
<button
|
|
32
32
|
id="hs-as-table-table-export-dropdown"
|
|
33
33
|
type="button"
|
|
34
|
-
class="py-1.5 sm:py-2 px-2.5 inline-flex items-center gap-x-1.5 text-sm sm:text-xs font-medium rounded-lg border border-
|
|
34
|
+
class="py-1.5 sm:py-2 px-2.5 inline-flex items-center gap-x-1.5 text-sm sm:text-xs font-medium rounded-lg border border-card-line bg-card text-foreground shadow-2xs hover:bg-muted-hover disabled:opacity-50 disabled:pointer-events-none focus:outline-hidden focus:bg-muted-hover"
|
|
35
35
|
aria-haspopup="menu"
|
|
36
36
|
aria-expanded="false"
|
|
37
37
|
aria-label="Dropdown"
|
|
@@ -40,14 +40,14 @@ const exportTable = (format) => {
|
|
|
40
40
|
Exportar
|
|
41
41
|
</button>
|
|
42
42
|
<div
|
|
43
|
-
class="hs-dropdown-menu transition-[opacity,margin] duration hs-dropdown-open:opacity-100 opacity-0 hidden divide-y divide-
|
|
43
|
+
class="hs-dropdown-menu transition-[opacity,margin] duration hs-dropdown-open:opacity-100 opacity-0 hidden divide-y divide-card-line min-w-48 z-10 bg-dropdown shadow-md rounded-lg p-2 mt-2 dark:border dark:border-dropdown-line border-t border-card-line"
|
|
44
44
|
role="menu"
|
|
45
45
|
aria-orientation="vertical"
|
|
46
46
|
aria-labelledby="hs-as-table-table-export-dropdown"
|
|
47
47
|
>
|
|
48
48
|
<div class="py-2 first:pt-0 last:pb-0">
|
|
49
49
|
<a
|
|
50
|
-
class="flex items-center gap-x-3 py-2 px-3 rounded-lg text-sm text-
|
|
50
|
+
class="flex items-center gap-x-3 py-2 px-3 rounded-lg text-sm text-foreground hover:bg-muted-hover focus:outline-hidden focus:bg-muted-hover"
|
|
51
51
|
href="#"
|
|
52
52
|
@click="exportTable('xlsx')"
|
|
53
53
|
>
|
|
@@ -55,7 +55,7 @@ const exportTable = (format) => {
|
|
|
55
55
|
Excel
|
|
56
56
|
</a>
|
|
57
57
|
<a
|
|
58
|
-
class="flex items-center gap-x-3 py-2 px-3 rounded-lg text-sm text-
|
|
58
|
+
class="flex items-center gap-x-3 py-2 px-3 rounded-lg text-sm text-foreground hover:bg-muted-hover focus:outline-hidden focus:bg-muted-hover"
|
|
59
59
|
href="#"
|
|
60
60
|
@click="exportTable('csv')"
|
|
61
61
|
>
|
|
@@ -63,7 +63,7 @@ const exportTable = (format) => {
|
|
|
63
63
|
CSV
|
|
64
64
|
</a>
|
|
65
65
|
<a
|
|
66
|
-
class="flex items-center gap-x-3 py-2 px-3 rounded-lg text-sm text-
|
|
66
|
+
class="flex items-center gap-x-3 py-2 px-3 rounded-lg text-sm text-foreground hover:bg-muted-hover focus:outline-hidden focus:bg-muted-hover"
|
|
67
67
|
href="#"
|
|
68
68
|
@click="exportTable('pdf')"
|
|
69
69
|
>
|
|
@@ -71,7 +71,7 @@ const exportTable = (format) => {
|
|
|
71
71
|
PDF
|
|
72
72
|
</a>
|
|
73
73
|
<a
|
|
74
|
-
class="flex items-center gap-x-3 py-2 px-3 rounded-lg text-sm text-
|
|
74
|
+
class="flex items-center gap-x-3 py-2 px-3 rounded-lg text-sm text-foreground hover:bg-muted-hover focus:outline-hidden focus:bg-muted-hover"
|
|
75
75
|
href="#"
|
|
76
76
|
@click="exportTable('json')"
|
|
77
77
|
>
|
|
@@ -85,23 +85,23 @@ const exportTable = (format) => {
|
|
|
85
85
|
data-hs-dropdown-ignore-click
|
|
86
86
|
>
|
|
87
87
|
<label
|
|
88
|
-
class="inline-flex items-center gap-2 text-sm text-
|
|
88
|
+
class="inline-flex items-center gap-2 text-sm text-foreground"
|
|
89
89
|
>
|
|
90
90
|
<input
|
|
91
91
|
type="checkbox"
|
|
92
92
|
v-model="exportAllPages"
|
|
93
|
-
class="shrink-0 border-
|
|
93
|
+
class="shrink-0 border-card-line rounded-sm text-blue-600 focus:ring-blue-500 dark:bg-card"
|
|
94
94
|
/>
|
|
95
95
|
Todas las páginas
|
|
96
96
|
</label>
|
|
97
97
|
|
|
98
98
|
<label
|
|
99
|
-
class="inline-flex items-center gap-2 text-sm text-
|
|
99
|
+
class="inline-flex items-center gap-2 text-sm text-foreground"
|
|
100
100
|
>
|
|
101
101
|
<input
|
|
102
102
|
type="checkbox"
|
|
103
103
|
v-model="exportFilteredRows"
|
|
104
|
-
class="shrink-0 border-
|
|
104
|
+
class="shrink-0 border-card-line rounded-sm text-blue-600 focus:ring-blue-500 dark:bg-card"
|
|
105
105
|
/>
|
|
106
106
|
Solo filas filtradas
|
|
107
107
|
</label>
|
|
@@ -55,8 +55,8 @@ const displayText = computed(() => {
|
|
|
55
55
|
|
|
56
56
|
const selectClasses = computed(() => {
|
|
57
57
|
const base =
|
|
58
|
-
"relative w-full rounded-lg border bg-
|
|
59
|
-
const validation = "border-
|
|
58
|
+
"relative w-full rounded-lg border bg-card transition-colors cursor-pointer text-foreground py-2 px-3 text-sm focus:outline-none focus:ring-0 focus:border-gray-400";
|
|
59
|
+
const validation = "border-card-line";
|
|
60
60
|
const disabled = props.disabled ? "opacity-50 cursor-not-allowed" : "";
|
|
61
61
|
return `${base} ${validation} ${disabled}`;
|
|
62
62
|
});
|
|
@@ -110,7 +110,7 @@ onUnmounted(() => document.removeEventListener("mousedown", handleClickOutside))
|
|
|
110
110
|
<span
|
|
111
111
|
class="truncate flex-1 text-left pr-10"
|
|
112
112
|
:class="{
|
|
113
|
-
'text-
|
|
113
|
+
'text-muted-foreground': !hasSelection,
|
|
114
114
|
'text-slate-900 dark:text-white': hasSelection,
|
|
115
115
|
}"
|
|
116
116
|
>
|
|
@@ -121,7 +121,7 @@ onUnmounted(() => document.removeEventListener("mousedown", handleClickOutside))
|
|
|
121
121
|
|
|
122
122
|
<span
|
|
123
123
|
v-if="clearable && hasSelection && !disabled"
|
|
124
|
-
class="absolute end-8 top-1/2 -translate-y-1/2 hover:bg-
|
|
124
|
+
class="absolute end-8 top-1/2 -translate-y-1/2 hover:bg-muted-hover rounded-full p-1 transition-colors focus:outline-none focus:ring-1 focus:ring-slate-400"
|
|
125
125
|
role="button"
|
|
126
126
|
tabindex="0"
|
|
127
127
|
@click.stop="clearSelection"
|
|
@@ -139,7 +139,7 @@ onUnmounted(() => document.removeEventListener("mousedown", handleClickOutside))
|
|
|
139
139
|
|
|
140
140
|
<div class="absolute top-1/2 end-3 -translate-y-1/2">
|
|
141
141
|
<svg
|
|
142
|
-
class="shrink-0 size-3.5 text-
|
|
142
|
+
class="shrink-0 size-3.5 text-muted-foreground transition-transform"
|
|
143
143
|
:class="{ 'rotate-180': isOpen }"
|
|
144
144
|
xmlns="http://www.w3.org/2000/svg"
|
|
145
145
|
width="24"
|
|
@@ -169,7 +169,7 @@ onUnmounted(() => document.removeEventListener("mousedown", handleClickOutside))
|
|
|
169
169
|
<div
|
|
170
170
|
v-show="isOpen"
|
|
171
171
|
:class="[
|
|
172
|
-
'absolute z-50 w-full mt-1 bg-
|
|
172
|
+
'absolute z-50 w-full mt-1 bg-dropdown border border-dropdown-line rounded-xl shadow-xl max-h-60 overflow-auto',
|
|
173
173
|
menuClass,
|
|
174
174
|
]"
|
|
175
175
|
>
|
|
@@ -179,8 +179,8 @@ onUnmounted(() => document.removeEventListener("mousedown", handleClickOutside))
|
|
|
179
179
|
:key="getOptionValue(option)"
|
|
180
180
|
type="button"
|
|
181
181
|
:class="[
|
|
182
|
-
'w-full px-3 py-2 text-left hover:bg-
|
|
183
|
-
isOptionSelected(option) ? 'bg-
|
|
182
|
+
'w-full px-3 py-2 text-left hover:bg-muted-hover flex items-center text-sm',
|
|
183
|
+
isOptionSelected(option) ? 'bg-muted' : '',
|
|
184
184
|
]"
|
|
185
185
|
@click="selectOption(option)"
|
|
186
186
|
>
|
|
@@ -196,7 +196,7 @@ onUnmounted(() => document.removeEventListener("mousedown", handleClickOutside))
|
|
|
196
196
|
/>
|
|
197
197
|
<span :class="['relative inline-flex rounded-full size-2.5', option.dot]" />
|
|
198
198
|
</span>
|
|
199
|
-
<span class="font-bold text-
|
|
199
|
+
<span class="font-bold text-foreground truncate">
|
|
200
200
|
{{ getOptionLabel(option) }}
|
|
201
201
|
</span>
|
|
202
202
|
</div>
|
|
@@ -217,7 +217,7 @@ onUnmounted(() => document.removeEventListener("mousedown", handleClickOutside))
|
|
|
217
217
|
</button>
|
|
218
218
|
</div>
|
|
219
219
|
|
|
220
|
-
<div v-else class="px-3 py-4 text-center text-
|
|
220
|
+
<div v-else class="px-3 py-4 text-center text-muted-foreground text-sm">
|
|
221
221
|
Sin opciones
|
|
222
222
|
</div>
|
|
223
223
|
</div>
|
|
@@ -35,7 +35,7 @@ defineExpose({ reload, clearCache })
|
|
|
35
35
|
v-model="search"
|
|
36
36
|
type="search"
|
|
37
37
|
:placeholder="searchPlaceholder"
|
|
38
|
-
class="block w-full rounded-lg border border-
|
|
38
|
+
class="block w-full rounded-lg border border-card-line bg-card text-foreground py-2 ps-10 pe-4 text-sm focus:outline-none focus:ring-1 focus:ring-indigo-500"
|
|
39
39
|
/>
|
|
40
40
|
</div>
|
|
41
41
|
|
|
@@ -106,7 +106,7 @@ const onDrop = async (targetState) => {
|
|
|
106
106
|
|
|
107
107
|
// ─── Color map ────────────────────────────────────────────────────────────────
|
|
108
108
|
const colorMap = {
|
|
109
|
-
slate: { header: 'bg-
|
|
109
|
+
slate: { header: 'bg-surface text-foreground', over: 'ring-2 ring-slate-400' },
|
|
110
110
|
red: { header: 'bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300', over: 'ring-2 ring-red-400' },
|
|
111
111
|
yellow: { header: 'bg-yellow-50 dark:bg-yellow-900/20 text-yellow-700 dark:text-yellow-300', over: 'ring-2 ring-yellow-400' },
|
|
112
112
|
green: { header: 'bg-green-50 dark:bg-green-900/20 text-green-700 dark:text-green-300', over: 'ring-2 ring-green-400' },
|
|
@@ -135,7 +135,7 @@ defineExpose({ reload, rows })
|
|
|
135
135
|
<div
|
|
136
136
|
v-for="state in states"
|
|
137
137
|
:key="state.key"
|
|
138
|
-
class="flex-shrink-0 w-72 flex flex-col rounded-xl border border-
|
|
138
|
+
class="flex-shrink-0 w-72 flex flex-col rounded-xl border border-card-line overflow-hidden transition-shadow"
|
|
139
139
|
:class="dragOverState === state.key ? getColors(state).over : ''"
|
|
140
140
|
@dragover="onDragOver($event, state.key)"
|
|
141
141
|
@dragleave="onDragLeave"
|
|
@@ -150,13 +150,13 @@ defineExpose({ reload, rows })
|
|
|
150
150
|
</div>
|
|
151
151
|
|
|
152
152
|
<!-- Cards -->
|
|
153
|
-
<div class="flex-1 flex flex-col gap-2 p-3 bg-
|
|
153
|
+
<div class="flex-1 flex flex-col gap-2 p-3 bg-muted min-h-24">
|
|
154
154
|
<div
|
|
155
155
|
v-for="row in columnRows[state.key]"
|
|
156
156
|
:key="row.id"
|
|
157
157
|
draggable="true"
|
|
158
158
|
@dragstart="onDragStart(row, state.key)"
|
|
159
|
-
class="bg-
|
|
159
|
+
class="bg-card border border-card-line rounded-lg p-3 cursor-grab active:cursor-grabbing hover:shadow-md transition-shadow select-none"
|
|
160
160
|
:class="draggedId === row.id ? 'opacity-40' : ''"
|
|
161
161
|
@click="emit('card-click', row)"
|
|
162
162
|
>
|
|
@@ -168,8 +168,8 @@ defineExpose({ reload, rows })
|
|
|
168
168
|
:key="key"
|
|
169
169
|
class="text-sm"
|
|
170
170
|
>
|
|
171
|
-
<span class="text-
|
|
172
|
-
<span class="text-
|
|
171
|
+
<span class="text-muted-foreground text-xs capitalize">{{ key }}: </span>
|
|
172
|
+
<span class="text-foreground font-medium">{{ val }}</span>
|
|
173
173
|
</div>
|
|
174
174
|
</div>
|
|
175
175
|
</slot>
|
|
@@ -177,7 +177,7 @@ defineExpose({ reload, rows })
|
|
|
177
177
|
|
|
178
178
|
<div
|
|
179
179
|
v-if="!columnRows[state.key]?.length"
|
|
180
|
-
class="flex-1 flex items-center justify-center py-6 text-sm text-
|
|
180
|
+
class="flex-1 flex items-center justify-center py-6 text-sm text-muted-foreground-2"
|
|
181
181
|
>
|
|
182
182
|
Sin elementos
|
|
183
183
|
</div>
|
|
@@ -76,7 +76,7 @@ defineExpose({ reload, rows })
|
|
|
76
76
|
v-model="search"
|
|
77
77
|
type="search"
|
|
78
78
|
:placeholder="searchPlaceholder"
|
|
79
|
-
class="block w-full rounded-lg border border-
|
|
79
|
+
class="block w-full rounded-lg border border-card-line bg-card text-foreground py-2 ps-10 pe-4 text-sm focus:outline-none focus:ring-1 focus:ring-indigo-500"
|
|
80
80
|
/>
|
|
81
81
|
</div>
|
|
82
82
|
|
|
@@ -85,7 +85,7 @@ defineExpose({ reload, rows })
|
|
|
85
85
|
<div
|
|
86
86
|
v-for="i in 8"
|
|
87
87
|
:key="i"
|
|
88
|
-
class="h-16 bg-
|
|
88
|
+
class="h-16 bg-surface rounded-xl animate-pulse"
|
|
89
89
|
/>
|
|
90
90
|
</div>
|
|
91
91
|
|
|
@@ -94,7 +94,7 @@ defineExpose({ reload, rows })
|
|
|
94
94
|
<div
|
|
95
95
|
v-for="row in rows"
|
|
96
96
|
:key="row.id ?? JSON.stringify(row)"
|
|
97
|
-
class="bg-
|
|
97
|
+
class="bg-card border border-card-line rounded-xl px-4 py-3 hover:border-indigo-300 dark:hover:border-indigo-600 transition-colors cursor-pointer"
|
|
98
98
|
@click="emit('row-click', row)"
|
|
99
99
|
>
|
|
100
100
|
<slot name="item" :row="row">
|
|
@@ -105,14 +105,14 @@ defineExpose({ reload, rows })
|
|
|
105
105
|
:key="key"
|
|
106
106
|
class="text-sm"
|
|
107
107
|
>
|
|
108
|
-
<span class="text-
|
|
109
|
-
<span class="text-
|
|
108
|
+
<span class="text-muted-foreground text-xs">{{ key }}: </span>
|
|
109
|
+
<span class="text-foreground">{{ val }}</span>
|
|
110
110
|
</div>
|
|
111
111
|
</div>
|
|
112
112
|
</slot>
|
|
113
113
|
</div>
|
|
114
114
|
|
|
115
|
-
<div v-if="rows.length === 0" class="text-center py-12 text-
|
|
115
|
+
<div v-if="rows.length === 0" class="text-center py-12 text-muted-foreground text-sm">
|
|
116
116
|
Sin resultados
|
|
117
117
|
</div>
|
|
118
118
|
</div>
|