@adamosuiteservices/ui 1.7.8 → 1.7.9

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.
@@ -68,19 +68,17 @@ import { Combobox } from "@adamosuiteservices/ui/combobox";
68
68
 
69
69
  Funciones de renderizado personalizadas para control total sobre la UI. Todas son opcionales y reciben props relevantes.
70
70
 
71
- **Patrón Original Component**: Cada render prop recibe un componente `Original` que renderiza la implementación por defecto, permitiendo envolver o mejorar el renderizado sin reimplementar toda la lógica.
72
-
73
- | Prop | Parámetros | Descripción |
74
- | ------------------ | --------------------------------------------------------------------- | --------------------------------------- |
75
- | `trigger` | `{ Original, open, value, displayText, placeholder, hasValue, icon }` | Renderiza el botón trigger completo |
76
- | `triggerIcon` | `{ Original, open }` | Renderiza el icono del dropdown |
77
- | `placeholder` | `{ Original, text, hasValue }` | Renderiza el texto del placeholder |
78
- | `displayValue` | `{ Original, text, value }` | Renderiza el valor seleccionado |
79
- | `option` | `{ Original, option, isSelected, selectedFeedback }` | Renderiza una opción completa |
80
- | `optionLabel` | `{ Original, option }` | Renderiza solo la etiqueta de la opción |
81
- | `selectedFeedback` | `{ Original, option, isSelected, type }` | Renderiza el indicador de selección |
82
- | `empty` | `{ Original, text }` | Renderiza el estado vacío |
83
- | `searchInput` | `{ Original, placeholder }` | Renderiza el input de búsqueda |
71
+ | Prop | Parámetros | Descripción |
72
+ | ------------------ | ----------------------------------------------------------- | --------------------------------------- |
73
+ | `trigger` | `{ open, value, displayText, placeholder, hasValue, icon }` | Renderiza el botón trigger completo |
74
+ | `triggerIcon` | `{ open }` | Renderiza el icono del dropdown |
75
+ | `placeholder` | `{ text, hasValue }` | Renderiza el texto del placeholder |
76
+ | `displayValue` | `{ text, value }` | Renderiza el valor seleccionado |
77
+ | `option` | `{ option, isSelected, selectedFeedback }` | Renderiza una opción completa |
78
+ | `optionLabel` | `{ option }` | Renderiza solo la etiqueta de la opción |
79
+ | `selectedFeedback` | `{ option, isSelected, type }` | Renderiza el indicador de selección |
80
+ | `empty` | `{ text }` | Renderiza el estado vacío |
81
+ | `searchInput` | `{ placeholder }` | Renderiza el input de búsqueda |
84
82
 
85
83
  ## Patrones de Uso
86
84
 
@@ -347,18 +345,9 @@ const [values, setValues] = useState<string[]>([]);
347
345
 
348
346
  ## Renderizado Personalizado
349
347
 
350
- El prop `renders` permite personalizar completamente la UI usando el patrón render prop. Todas las funciones son opcionales.
348
+ El prop `renders` permite personalizar completamente la UI usando el patrón render prop. Todas las funciones son opcionales y permiten reemplazar completamente el renderizado por defecto de cada parte del componente.
351
349
 
352
- ### Patrón Original Component
353
-
354
- Cada render prop recibe un componente `Original` que renderiza la implementación por defecto. Esto permite:
355
-
356
- - **Envolver**: Agregar contenedores o elementos adicionales
357
- - **Mejorar**: Añadir badges, iconos o decoraciones junto al original
358
- - **Condicional**: Usar el original como fallback para ciertos estados
359
- - **Componer**: Mezclar renderizado custom y default según condiciones
360
-
361
- ### Envolver el Trigger con Label
350
+ ### Custom Trigger
362
351
 
363
352
  ```tsx
364
353
  <Combobox
@@ -367,13 +356,16 @@ Cada render prop recibe un componente `Original` que renderiza la implementació
367
356
  value={value}
368
357
  onValueChange={setValue}
369
358
  renders={{
370
- trigger: ({ Original }) => (
371
- <div className="border border-purple-300 p-2 rounded-lg bg-purple-50">
372
- <label className="text-xs font-medium text-purple-700 mb-1 block">
373
- Choose your framework:
374
- </label>
375
- <Original />
376
- </div>
359
+ trigger: ({ open, displayText, placeholder, hasValue }) => (
360
+ <button
361
+ type="button"
362
+ className="flex items-center justify-between w-full px-4 py-2 text-sm bg-gradient-to-r from-purple-500 to-pink-500 text-white rounded-lg shadow-md hover:shadow-lg transition-all"
363
+ >
364
+ <span>{hasValue ? displayText : placeholder}</span>
365
+ <span className={`transition-transform ${open ? "rotate-180" : ""}`}>
366
+
367
+ </span>
368
+ </button>
377
369
  ),
378
370
  }}
379
371
  />
@@ -382,53 +374,10 @@ Cada render prop recibe un componente `Original` que renderiza la implementació
382
374
  ### Mejorar Display Value con Badge
383
375
 
384
376
  ```tsx
385
- <Combobox
386
- searchable
387
- options={frameworks}
388
- value={value}
389
- onValueChange={setValue}
390
- renders={{
391
- displayValue: ({ Original, text }) => (
392
- <div className="flex items-center gap-2">
393
- <Original />
394
- {text && (
395
- <span className="px-1.5 py-0.5 text-xs bg-green-100 text-green-700 rounded">
396
- Active
397
- </span>
398
- )}
399
- </div>
400
- ),
401
- }}
402
- />
403
- ```
404
377
 
405
- ### Fallback Condicional
406
-
407
- ```tsx
408
- <Combobox
409
- searchable
410
- options={frameworks}
411
- value={value}
412
- onValueChange={setValue}
413
- renders={{
414
- trigger: ({ Original, hasValue, displayText }) => {
415
- // Custom cuando hay valor
416
- if (hasValue) {
417
- return (
418
- <button className="w-full px-4 py-2 bg-green-600 text-white rounded-md">
419
- ✓ {displayText}
420
- </button>
421
- );
422
- }
423
-
424
- // Fallback al original cuando está vacío
425
- return <Original />;
426
- },
427
- }}
428
- />
429
378
  ```
430
379
 
431
- ### Envolver Options con Styling
380
+ ### Custom Display Value con Badge
432
381
 
433
382
  ```tsx
434
383
  <Combobox
@@ -436,46 +385,22 @@ Cada render prop recibe un componente `Original` que renderiza la implementació
436
385
  options={frameworks}
437
386
  value={value}
438
387
  onValueChange={setValue}
439
- selectedFeedback="check"
440
388
  renders={{
441
- option: ({ Original, isSelected }) => (
442
- <div
443
- className={`border-l-4 ${
444
- isSelected ? "border-l-blue-500 bg-blue-50" : "border-l-transparent"
445
- }`}
446
- >
447
- <Original />
448
- </div>
449
- ),
450
- }}
451
- />
452
- ```
453
-
454
- ### Mejorar Empty State con Acción
455
-
456
- ```tsx
457
- <Combobox
458
- searchable
459
- options={[]}
460
- renders={{
461
- empty: ({ Original }) => (
462
- <div className="space-y-3">
463
- <Original />
464
- <div className="px-4 pb-3">
465
- <button
466
- onClick={() => console.log("Add new")}
467
- className="w-full px-3 py-1.5 text-xs text-blue-600 border border-blue-200 rounded hover:bg-blue-50"
468
- >
469
- + Create new item
470
- </button>
471
- </div>
389
+ displayValue: ({ text }) => (
390
+ <div className="flex items-center gap-2">
391
+ <span>{text}</span>
392
+ {text && (
393
+ <span className="px-1.5 py-0.5 text-xs bg-green-100 text-green-700 rounded font-medium">
394
+ Active
395
+ </span>
396
+ )}
472
397
  </div>
473
398
  ),
474
399
  }}
475
400
  />
476
401
  ```
477
402
 
478
- ### Custom Option Label (Sin Original)
403
+ ### Custom Option Label
479
404
 
480
405
  ```tsx
481
406
  <Combobox
@@ -494,63 +419,23 @@ Cada render prop recibe un componente `Original` que renderiza la implementació
494
419
  />
495
420
  ```
496
421
 
497
- ### Custom Trigger Completo (Sin Original)
422
+ ### Custom Empty State
498
423
 
499
424
  ```tsx
500
425
  <Combobox
501
426
  searchable
502
- options={frameworks}
503
- value={value}
504
- onValueChange={setValue}
505
- renders={{
506
- trigger: ({ open, displayText, placeholder, hasValue }) => (
507
- <button
508
- type="button"
509
- className="flex items-center justify-between w-full px-4 py-2 text-sm bg-gradient-to-r from-purple-500 to-pink-500 text-white rounded-lg shadow-md hover:shadow-lg transition-all"
510
- >
511
- <span>{hasValue ? displayText : placeholder}</span>
512
- <span className={`transition-transform ${open ? "rotate-180" : ""}`}>
513
-
514
- </span>
515
- </button>
516
- ),
427
+ options={[]}
428
+ labels={{
429
+ noItemsFound: "No items found.",
517
430
  }}
518
- />
519
- ```
520
-
521
- ### Combinando Original y Custom
522
-
523
- ```tsx
524
- <Combobox
525
- searchable
526
- multiple
527
- options={frameworks}
528
- value={values}
529
- onValueChange={setValues}
530
431
  renders={{
531
- // Usa Original para envolver
532
- trigger: ({ Original }) => (
533
- <div className="relative">
534
- <Original />
535
- {values.length > 0 && (
536
- <span className="absolute -top-2 -right-2 bg-red-500 text-white text-xs rounded-full w-5 h-5 flex items-center justify-center">
537
- {values.length}
538
- </span>
539
- )}
540
- </div>
541
- ),
542
- // Custom completo sin Original
543
- optionLabel: ({ option }) => (
544
- <div className="flex items-center gap-2">
545
- <span>🚀</span>
546
- <span className="font-medium">{option.label}</span>
547
- </div>
548
- ),
549
- // Mejora el Original
550
- displayValue: ({ Original, text }) => (
551
- <div className="flex items-center gap-2">
552
- <Original />
553
- {text && <span className="text-xs opacity-50">selected</span>}
432
+ empty: ({ text }) => (
433
+ <div className="py-8 text-center">
434
+ <div className="text-4xl mb-2">🔍</div>
435
+ <p className="text-sm font-medium text-muted-foreground">{text}</p>
436
+ <p className="text-xs text-muted-foreground mt-1">
437
+ Try adjusting your search criteria
438
+ </p>
554
439
  </div>
555
440
  ),
556
441
  }}
@@ -629,7 +514,6 @@ Cada render prop recibe un componente `Original` que renderiza la implementació
629
514
  - **icon**: Se muestra con `opacity-50` por defecto cuando se proporciona el prop `icon`
630
515
  - **Render props**: Tienen prioridad sobre renderizado por defecto, permiten personalización completa
631
516
  - **Composición de renders**: Puedes combinar múltiples render props para personalización granular
632
- - **Original component**: Cada render prop recibe un componente `Original` para renderizar la implementación por defecto, permitiendo envolver o mejorar sin reimplementar
633
517
 
634
518
  ## Troubleshooting
635
519
 
@@ -643,9 +527,7 @@ Cada render prop recibe un componente `Original` que renderiza la implementació
643
527
  **Icon no se muestra**: Asegúrate de pasar el prop `icon` con un componente válido
644
528
  **Placeholder desaparece al seleccionar**: Si quieres mantenerlo visible, usa `alwaysShowPlaceholder={true}`
645
529
  **Render prop no funciona**: Verifica que el render prop retorne un `ReactNode` válido
646
- **Custom trigger pierde funcionalidad**: Cuando usas `renders.trigger`, debes manejar el click manualmente o envolver en `PopoverTrigger`
647
- **Original component no renderiza**: Asegúrate de usar `<Original />` como componente JSX, no como función
648
- **Quiero envolver sin reimplementar**: Usa el componente `Original` que recibe cada render prop para mantener la funcionalidad por defecto
530
+ **Custom trigger pierde funcionalidad**: Cuando usas `renders.trigger`, debes manejar el click manualmente o envolver en `PopoverTrigger`
649
531
 
650
532
  ## Referencias
651
533
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adamosuiteservices/ui",
3
- "version": "1.7.8",
3
+ "version": "1.7.9",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",