carconnect-gatherleads-ui-lib 3.0.0 → 3.1.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.
package/README.md
CHANGED
|
@@ -3025,166 +3025,232 @@ const DetailsSidebar = ({ user, isOpen, onClose }) => (
|
|
|
3025
3025
|
|
|
3026
3026
|
Esta guía cubre los aspectos principales de GatherModal, proporcionando ejemplos prácticos para implementaciones comunes desde modales simples hasta paneles laterales complejos.
|
|
3027
3027
|
|
|
3028
|
-
# 📅 Guía Completa de
|
|
3028
|
+
# 📅 Guía Completa de GatherCalendar y DatePicker
|
|
3029
3029
|
|
|
3030
3030
|
## 🎯 Introducción
|
|
3031
3031
|
|
|
3032
|
-
|
|
3032
|
+
El sistema de fechas de `carconnect-gatherleads-ui-lib` incluye tres componentes principales robustos y flexibles:
|
|
3033
|
+
1. **GatherDatePicker**: Botón que abre un popover con calendario.
|
|
3034
|
+
2. **GatherDatePickerInput**: Input de texto que abre un popover, ideal para formularios.
|
|
3035
|
+
3. **GatherCalendar**: Componente de calendario visual para incrustar directamente.
|
|
3033
3036
|
|
|
3034
|
-
|
|
3037
|
+
> **⚠️ CAMBIO IMPORTANTE (v3.0)**: Para garantizar consistencia, la propiedad `selected` y el callback `onSelect` ahora utilizan **SIEMPRE** el tipo `DateRange` (de `react-day-picker`), incluso si `mode='single'`.
|
|
3038
|
+
>
|
|
3039
|
+
> - **Modo Single**: La fecha seleccionada estará en `selected.from` (con `to: undefined`).
|
|
3040
|
+
> - **Modo Range**: Fecha inicio en `selected.from`, fecha fin en `selected.to`.
|
|
3041
|
+
|
|
3042
|
+
## 📦 GatherDatePicker (Botón)
|
|
3035
3043
|
|
|
3036
|
-
###
|
|
3044
|
+
### Uso Básico
|
|
3037
3045
|
|
|
3038
3046
|
```tsx
|
|
3039
3047
|
import { GatherDatePicker } from '@/base/date-picker/gather-date-picker';
|
|
3048
|
+
import type { DateRange } from 'react-day-picker';
|
|
3040
3049
|
|
|
3041
3050
|
const SimpleDatePicker = () => {
|
|
3042
|
-
|
|
3051
|
+
// Inicializamos el estado compatible con DateRange
|
|
3052
|
+
const [selected, setSelected] = React.useState<DateRange | undefined>({
|
|
3053
|
+
from: new Date(),
|
|
3054
|
+
to: undefined // En modo single, 'to' se ignora o es undefined
|
|
3055
|
+
});
|
|
3043
3056
|
|
|
3044
3057
|
return (
|
|
3045
3058
|
<GatherDatePicker
|
|
3046
3059
|
mode='single'
|
|
3047
|
-
selected={
|
|
3048
|
-
onSelect={
|
|
3060
|
+
selected={selected}
|
|
3061
|
+
onSelect={setSelected}
|
|
3049
3062
|
placeholder='Seleccionar fecha'
|
|
3050
3063
|
/>
|
|
3051
3064
|
);
|
|
3052
3065
|
};
|
|
3053
3066
|
```
|
|
3054
3067
|
|
|
3055
|
-
###
|
|
3068
|
+
### Uso Avanzado con Selectores de Año (Dropdown)
|
|
3069
|
+
|
|
3070
|
+
```tsx
|
|
3071
|
+
<GatherDatePicker
|
|
3072
|
+
mode="single"
|
|
3073
|
+
layout="dropdown" // Habilita navegación por selects
|
|
3074
|
+
selectProps={{
|
|
3075
|
+
pastYearsCount: 100, // Años hacia el pasado (ej: nacimientos)
|
|
3076
|
+
futureYearsCount: 10 // Años hacia el futuro (ej: vencimientos)
|
|
3077
|
+
}}
|
|
3078
|
+
selected={selected}
|
|
3079
|
+
onSelect={setSelected}
|
|
3080
|
+
/>
|
|
3081
|
+
```
|
|
3082
|
+
|
|
3083
|
+
## 📦 GatherDatePickerInput
|
|
3084
|
+
|
|
3085
|
+
Componente optimizado para formularios, con manejo de etiquetas, errores y descripciones.
|
|
3056
3086
|
|
|
3057
3087
|
```tsx
|
|
3058
3088
|
import { GatherDatePickerInput } from '@/base/date-picker/gather-date-picker-input';
|
|
3059
3089
|
|
|
3060
3090
|
const InputDatePicker = () => {
|
|
3061
|
-
const [
|
|
3091
|
+
const [selected, setSelected] = React.useState<DateRange | undefined>();
|
|
3062
3092
|
|
|
3063
3093
|
return (
|
|
3064
3094
|
<GatherDatePickerInput
|
|
3065
3095
|
mode='single'
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3096
|
+
label='Fecha de Nacimiento'
|
|
3097
|
+
placeholder='dd/mm/aaaa'
|
|
3098
|
+
selected={selected}
|
|
3099
|
+
onSelect={setSelected}
|
|
3100
|
+
// Validación
|
|
3101
|
+
required
|
|
3102
|
+
error={!selected?.from}
|
|
3103
|
+
helperText={!selected?.from ? "Campo requerido" : "Formato válido"}
|
|
3104
|
+
// Comportamiento
|
|
3105
|
+
autoClose={true}
|
|
3070
3106
|
/>
|
|
3071
3107
|
);
|
|
3072
3108
|
};
|
|
3073
3109
|
```
|
|
3074
3110
|
|
|
3075
|
-
##
|
|
3111
|
+
## 📦 GatherCalendar (Standalone)
|
|
3076
3112
|
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
Ambos componentes comparten la mayoría de las props, heredando de una base común:
|
|
3113
|
+
Para cuando necesitas mostrar el calendario directamente en la interfaz (sin popover).
|
|
3080
3114
|
|
|
3081
3115
|
```tsx
|
|
3082
|
-
|
|
3083
|
-
// CONFIGURACIÓN
|
|
3084
|
-
mode?: 'single' | 'range'; // Modo de selección
|
|
3085
|
-
selected?: Date | DateRange; // Valor seleccionado
|
|
3086
|
-
onSelect?: (date: any) => void; // Callback de selección
|
|
3087
|
-
timeZone?: string; // Zona horaria (default: 'America/Guayaquil')
|
|
3116
|
+
import { GatherCalendar } from '@/base/calendar/gather-calendar';
|
|
3088
3117
|
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3118
|
+
const DashboardCalendar = () => {
|
|
3119
|
+
const [range, setRange] = React.useState<DateRange | undefined>();
|
|
3120
|
+
|
|
3121
|
+
return (
|
|
3122
|
+
<div className="p-4 border rounded-xl bg-white shadow-sm">
|
|
3123
|
+
<h3 className="mb-4 font-bold">Seleccionar Periodo</h3>
|
|
3124
|
+
<GatherCalendar
|
|
3125
|
+
mode="range"
|
|
3126
|
+
selected={range}
|
|
3127
|
+
onSelect={setRange}
|
|
3128
|
+
layout="default"
|
|
3129
|
+
/>
|
|
3130
|
+
</div>
|
|
3131
|
+
);
|
|
3132
|
+
};
|
|
3133
|
+
```
|
|
3093
3134
|
|
|
3094
|
-
|
|
3095
|
-
minDate?: Date; // Fecha mínima
|
|
3096
|
-
maxDate?: Date; // Fecha máxima
|
|
3097
|
-
disabledDates?: Date[]; // Fechas deshabilitadas específicas
|
|
3098
|
-
pastYearsCount?: number; // Años pasados a mostrar en selector
|
|
3135
|
+
## ⚙️ Props Principales (Comunes)
|
|
3099
3136
|
|
|
3100
|
-
|
|
3101
|
-
dateFormat?: string; // Formato de fecha (ej: 'dd MMM yyyy')
|
|
3102
|
-
rangeFromFormat?: string; // Formato inicio rango
|
|
3103
|
-
rangeToFormat?: string; // Formato fin rango
|
|
3137
|
+
Estas props aplican a `GatherDatePicker`, `GatherDatePickerInput` y `GatherCalendar` (vía `GatherBaseCalendarProps`).
|
|
3104
3138
|
|
|
3105
|
-
|
|
3106
|
-
|
|
3139
|
+
| Prop | Tipo | Descripción |
|
|
3140
|
+
|------|------|-------------|
|
|
3141
|
+
| `mode` | `'single' \| 'range'` | Modo de selección. |
|
|
3142
|
+
| `selected` | `DateRange` | **Siempre** es `{ from: Date, to?: Date }`. |
|
|
3143
|
+
| `onSelect` | `(range: DateRange) => void` | Callback con la selección actualizada. |
|
|
3144
|
+
| `layout` | `'default' \| 'dropdown'` | Estilo de navegación (flechas vs selects). |
|
|
3145
|
+
| `selectProps` | `{ pastYearsCount, futureYearsCount }` | Configuración de años para `layout='dropdown'`. |
|
|
3146
|
+
| `minDate` | `Date` | Fecha mínima seleccionable. |
|
|
3147
|
+
| `maxDate` | `Date` | Fecha máxima seleccionable. |
|
|
3148
|
+
| `disabled` | `boolean` | Deshabilita la interacción. |
|
|
3149
|
+
| `timeZone` | `string` | Zona horaria (default: 'America/Guayaquil'). |
|
|
3107
3150
|
|
|
3108
|
-
|
|
3109
|
-
error?: boolean; // Estado de error (borde rojo)
|
|
3110
|
-
helperText?: string; // Texto de ayuda/error
|
|
3111
|
-
required?: boolean; // Marca de campo requerido (*)
|
|
3112
|
-
}
|
|
3113
|
-
```
|
|
3151
|
+
### Props específicas de DatePicker / Input
|
|
3114
3152
|
|
|
3115
|
-
|
|
3153
|
+
| Prop | Tipo | Componente | Descripción |
|
|
3154
|
+
|------|------|------------|-------------|
|
|
3155
|
+
| `placeholder` | `string` | Ambos | Texto cuando no hay selección. |
|
|
3156
|
+
| `autoClose` | `boolean` | Ambos | Cerrar popover al seleccionar (single). |
|
|
3157
|
+
| `showPresets` | `boolean` | DatePicker | Muestra panel lateral de opciones rápidas. |
|
|
3158
|
+
| `label` | `string` | Input | Etiqueta superior del campo. |
|
|
3159
|
+
| `error` | `boolean` | Ambos | Estado visual de error. |
|
|
3160
|
+
| `helperText` | `string` | Input | Texto de ayuda o mensaje de error. |
|
|
3161
|
+
| `applyButtonText` | `string` | DatePicker | Texto botón aceptar. |
|
|
3116
3162
|
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
}
|
|
3127
|
-
```
|
|
3163
|
+
---
|
|
3164
|
+
|
|
3165
|
+
# ⏳ Guía Completa de GatherLoader
|
|
3166
|
+
|
|
3167
|
+
## 🎯 Introducción
|
|
3168
|
+
|
|
3169
|
+
`GatherLoader` es un componente unificado para indicar estados de carga, espera o procesamiento. Está diseñado para ser flexible y adaptarse a diferentes contextos, desde spinners simples hasta overlays de pantalla completa y esqueletos de contenido.
|
|
3170
|
+
|
|
3171
|
+
## 📦 Uso Básico
|
|
3128
3172
|
|
|
3129
|
-
###
|
|
3173
|
+
### Spinner por Defecto
|
|
3174
|
+
|
|
3175
|
+
Muestra un spinner circular con el color principal de Gather (verde).
|
|
3130
3176
|
|
|
3131
3177
|
```tsx
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3178
|
+
import { GatherLoader } from '@/components/loader';
|
|
3179
|
+
|
|
3180
|
+
const LoadingState = () => (
|
|
3181
|
+
<div className="flex justify-center p-4">
|
|
3182
|
+
<GatherLoader />
|
|
3183
|
+
</div>
|
|
3184
|
+
);
|
|
3139
3185
|
```
|
|
3140
3186
|
|
|
3141
|
-
##
|
|
3187
|
+
## 🎨 Variantes
|
|
3142
3188
|
|
|
3143
|
-
|
|
3189
|
+
### Default (Spinner)
|
|
3144
3190
|
|
|
3145
|
-
|
|
3191
|
+
La variante estándar. Soporta diferentes tamaños y colores.
|
|
3146
3192
|
|
|
3147
3193
|
```tsx
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
/>
|
|
3194
|
+
// Tamaños
|
|
3195
|
+
<GatherLoader size="sm" /> // Pequeño (16px)
|
|
3196
|
+
<GatherLoader size="md" /> // Mediano (24px) - Default
|
|
3197
|
+
<GatherLoader size="lg" /> // Grande (32px)
|
|
3198
|
+
<GatherLoader size="xl" /> // Extra Grande (48px)
|
|
3199
|
+
|
|
3200
|
+
// Colores personalizados
|
|
3201
|
+
<GatherLoader className="text-blue-500" />
|
|
3202
|
+
<GatherLoader className="text-white" />
|
|
3157
3203
|
```
|
|
3158
3204
|
|
|
3159
|
-
###
|
|
3205
|
+
### Floating (Overlay)
|
|
3206
|
+
|
|
3207
|
+
Crea un overlay sobre el contenedor padre (o toda la pantalla si se usa en un portal o fixed container) para bloquear la interacción durante procesos críticos.
|
|
3160
3208
|
|
|
3161
3209
|
```tsx
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
);
|
|
3176
|
-
}
|
|
3210
|
+
const SubmitButton = ({ isLoading }) => (
|
|
3211
|
+
<div className="relative">
|
|
3212
|
+
<button>Guardar Cambios</button>
|
|
3213
|
+
|
|
3214
|
+
{/* Overlay de carga sobre el botón/contenedor */}
|
|
3215
|
+
{isLoading && (
|
|
3216
|
+
<GatherLoader
|
|
3217
|
+
variant="floating"
|
|
3218
|
+
className="bg-white/50 backdrop-blur-sm" // Fondo semitransparente con blur
|
|
3219
|
+
/>
|
|
3220
|
+
)}
|
|
3221
|
+
</div>
|
|
3222
|
+
);
|
|
3177
3223
|
```
|
|
3178
3224
|
|
|
3179
|
-
|
|
3225
|
+
### Skeleton (Esqueleto de Contenido)
|
|
3180
3226
|
|
|
3181
|
-
|
|
3227
|
+
Utilizado para simular la estructura del contenido mientras se cargan los datos, mejorando la percepción de velocidad (Perceived Performance).
|
|
3182
3228
|
|
|
3183
3229
|
```tsx
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3230
|
+
const CardSkeleton = () => (
|
|
3231
|
+
<div className="border rounded-lg p-4 space-y-3">
|
|
3232
|
+
{/* Imagen hero */}
|
|
3233
|
+
<GatherLoader variant="skeleton" className="h-32 w-full rounded-md" />
|
|
3234
|
+
|
|
3235
|
+
{/* Título */}
|
|
3236
|
+
<GatherLoader variant="skeleton" className="h-6 w-3/4 rounded" />
|
|
3237
|
+
|
|
3238
|
+
{/* Líneas de texto */}
|
|
3239
|
+
<div className="space-y-2">
|
|
3240
|
+
<GatherLoader variant="skeleton" className="h-4 w-full rounded" />
|
|
3241
|
+
<GatherLoader variant="skeleton" className="h-4 w-5/6 rounded" />
|
|
3242
|
+
</div>
|
|
3243
|
+
</div>
|
|
3244
|
+
);
|
|
3190
3245
|
```
|
|
3246
|
+
|
|
3247
|
+
## ⚙️ Props
|
|
3248
|
+
|
|
3249
|
+
| Prop | Tipo | Default | Descripción |
|
|
3250
|
+
|------|------|---------|-------------|
|
|
3251
|
+
| `variant` | `'default' \| 'floating' \| 'skeleton'` | `'default'` | El estilo visual del loader. |
|
|
3252
|
+
| `size` | `'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | El tamaño del spinner (solo aplica a variants `default` y `floating`). |
|
|
3253
|
+
| `className` | `string` | `''` | Clases CSS adicionales. Para `skeleton`, usa esto para definir dimensions (w/h). |
|
|
3254
|
+
| `color` | `string` | `undefined` | (Legacy) Color del spinner. Se recomienda usar clases de Tailwind en `className` (ej: `text-red-500`). |
|
|
3255
|
+
|
|
3256
|
+
---
|