@dropi/react-native-design-system 0.2.21 → 0.2.23

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.
Files changed (2) hide show
  1. package/README.md +221 -0
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -34,10 +34,13 @@ El **Design System de Dropi** para aplicaciones **React Native**. Este paquete r
34
34
 
35
35
  - [🧪 Moléculas](#moléculas)
36
36
  - [Alert](#alert)
37
+ - [Bottom Sheet](#bottom-sheet)
38
+ - [Chip](#chip)
37
39
  - [Empty State](#empty-state)
38
40
  - [Radio Buttons](#radio-buttons)
39
41
  - [Title Description](#title-description)
40
42
  - [Search](#search)
43
+ - [Select](#select)
41
44
  - [Tooltip](#tooltip)
42
45
  - [Tags](#tags)
43
46
  - [Order Tag](#order-tag)
@@ -449,6 +452,224 @@ import { Alert } from "@dropi/react-native-design-system";
449
452
 
450
453
  ```
451
454
 
455
+ ## Chip
456
+
457
+ El `Chip` es un componente compacto utilizado para mostrar **etiquetas, identificadores o categorías** de manera visual. Combina texto, íconos opcionales y un estilo diferenciado por variantes (`primary` / `tertiary`) para adaptarse a distintos contextos. Además, puede configurarse como **descartable** (`isDismissable`), mostrando un ícono de cierre que ejecuta una acción personalizada. Es ideal para mostrar información resumida como IDs de producto, estados, tags o filtros activos.
458
+
459
+ ### 📦 Importación:
460
+ ```Typescript
461
+ import { Chip } from "@dropi/react-native-design-system";
462
+ ```
463
+
464
+ ### ⚙️ Props:
465
+ | Prop | Tipo | Descripción |
466
+ | :------------- | :------------------------- | :--------------------------------------------------------------------------- |
467
+ | variant | 'primary' \| 'tertiary' | *(Opcional)* Define el estilo visual. Por defecto es `'tertiary'`. |
468
+ | preIcon | IconName | *(Opcional)* Ícono que aparece antes del texto. |
469
+ | label | string | Texto que se muestra en el chip. |
470
+ | isDismissable | boolean | *(Opcional)* Muestra un ícono de cierre (`cross-circle`) a la derecha. |
471
+ | onDismiss | () => void | *(Opcional)* Callback ejecutado al presionar el ícono de cierre. |
472
+
473
+ ### 🧩 Ejemplos de uso:
474
+ ```Typescript
475
+ <Chip label="ID: 12345" variant="tertiary" />
476
+
477
+ <Chip
478
+ label="VARIABLE"
479
+ variant="primary"
480
+ />
481
+
482
+ <Chip
483
+ label="Promo activa"
484
+ variant="primary"
485
+ preIcon="tag-outline"
486
+ />
487
+
488
+ <Chip
489
+ label="Filtro aplicado"
490
+ variant="tertiary"
491
+ isDismissable
492
+ onDismiss={() => console.log("Filtro eliminado")}
493
+ />
494
+ ```
495
+
496
+ ## Bottom Sheet
497
+
498
+ El `BottomSheetComponent` es un modal que se desliza desde la parte inferior de la pantalla, diseñado para mostrar contenido contextual sin interrumpir completamente la experiencia del usuario. Incluye un **backdrop semitransparente**, un **header con título opcional y botón de cierre**, soporte para **footer personalizado** y **snap points configurables** para controlar las alturas disponibles del sheet. El componente expone métodos imperativos (`present`, `close`, `dismiss`) mediante `forwardRef`, permitiendo un control programático completo desde el componente padre. Internamente usa `@gorhom/bottom-sheet` y mantiene la coherencia visual con los tokens del design system.
499
+
500
+ ### 📦 Importación:
501
+ ```Typescript
502
+ import { BottomSheetComponent, BottomSheetComponentRef } from "@dropi/react-native-design-system";
503
+ ```
504
+
505
+ ### ⚙️ Props:
506
+ | Prop | Tipo | Descripción |
507
+ | :----------- | :------------- | :----------------------------------------------------------------------------- |
508
+ | children | ReactNode | Contenido principal que se muestra dentro del bottom sheet. |
509
+ | footer | ReactNode | *(Opcional)* Contenido del footer fijo en la parte inferior del sheet. |
510
+ | title | string | *(Opcional)* Título mostrado en el header. Si no se provee, solo se muestra el botón de cierre. |
511
+ | snapPoints | string[] | *(Opcional)* Array de alturas disponibles (ej: `['50%', '90%']`). Por defecto: `['70%', '90%']`. |
512
+ | onDismiss | () => void | *(Opcional)* Callback ejecutado cuando el sheet se cierra completamente. |
513
+ | ref | BottomSheetComponentRef | Referencia para controlar el sheet imperativamente (`present`, `close`, `dismiss`). |
514
+
515
+ ### 🔧 Métodos expuestos (via ref):
516
+ | Método | Descripción |
517
+ | :---------- | :----------------------------------------------------------------------------- |
518
+ | present() | Abre el bottom sheet desde la parte inferior. |
519
+ | close() | Cierra el sheet de forma animada. |
520
+ | dismiss() | Descarta el sheet inmediatamente. |
521
+
522
+ ### 🧩 Ejemplos de uso:
523
+ ```Typescript
524
+ import { useRef } from 'react';
525
+ import { Button, View } from 'react-native';
526
+ import { BottomSheetComponent, BottomSheetComponentRef, Body, DefaultButton } from '@dropi/react-native-design-system';
527
+
528
+ const MyScreen = () => {
529
+ const bottomSheetRef = useRef<BottomSheetComponentRef>(null);
530
+
531
+ return (
532
+ <View>
533
+ <Button
534
+ title="Abrir opciones"
535
+ onPress={() => bottomSheetRef.current?.present()}
536
+ />
537
+
538
+ <BottomSheetComponent
539
+ ref={bottomSheetRef}
540
+ title="Opciones de envío"
541
+ snapPoints={['50%', '80%']}
542
+ onDismiss={() => console.log('Sheet cerrado')}
543
+ >
544
+ <View style={{ padding: 20 }}>
545
+ <Body type="m-regular">Selecciona tu método de envío preferido</Body>
546
+ </View>
547
+ </BottomSheetComponent>
548
+ </View>
549
+ );
550
+ };
551
+
552
+ // Con footer personalizado
553
+ <BottomSheetComponent
554
+ ref={sheetRef}
555
+ title="Confirmar pedido"
556
+ footer={
557
+ <DefaultButton
558
+ label="Confirmar"
559
+ variant="primary"
560
+ size="normal"
561
+ onPress={handleConfirm}
562
+ />
563
+ }
564
+ >
565
+ <Body type="m-regular">Revisa los detalles antes de continuar</Body>
566
+ </BottomSheetComponent>
567
+
568
+ // Sin título (solo botón de cierre)
569
+ <BottomSheetComponent
570
+ ref={sheetRef}
571
+ snapPoints={['40%']}
572
+ >
573
+ <Body type="m-regular">Contenido simple sin título</Body>
574
+ </BottomSheetComponent>
575
+ ```
576
+
577
+ ## Select
578
+
579
+ El `Select` es un componente de selección que muestra un campo tipo dropdown con un **bottom sheet modal** para elegir entre múltiples opciones. Incluye soporte para **label**, **placeholder**, **helper text**, **estados de error** y **validación con bordes dinámicos**. El usuario puede explorar las opciones en un modal con scroll, seleccionar una de manera temporal (draft) y confirmar el cambio presionando el botón "Guardar" del footer, que solo se habilita si hubo cambios. Internamente usa `TitleDescription` para renderizar cada opción y `BottomSheetComponent` para la interfaz modal.
580
+
581
+ ### 📦 Importación:
582
+ ```Typescript
583
+ import { Select, SelectOption } from "@dropi/react-native-design-system";
584
+ ```
585
+
586
+ ### ⚙️ Props:
587
+ | Prop | Tipo | Descripción |
588
+ | :------------ | :-------------------- | :------------------------------------------------------------------------------- |
589
+ | options | SelectOption[] | Array de opciones disponibles. Cada una tiene `label` y `value`. |
590
+ | value | SelectOption \| null | *(Opcional)* Opción actualmente seleccionada. |
591
+ | onChange | (option: SelectOption) => void | Callback ejecutado cuando el usuario confirma una nueva selección. |
592
+ | label | string | *(Opcional)* Etiqueta que aparece sobre el campo. |
593
+ | placeholder | string | *(Opcional)* Texto mostrado cuando no hay selección. Por defecto: `'Seleccionar'`. |
594
+ | helper | string | *(Opcional)* Texto de ayuda bajo el campo (no se muestra si hay error). |
595
+ | hasError | boolean | *(Opcional)* Indica si el campo tiene un error. Cambia el color del borde. |
596
+ | errorMessage | string | *(Opcional)* Mensaje de error mostrado con ícono. |
597
+ | title | string | *(Opcional)* Título del bottom sheet. Si no se provee, usa `label` o "Seleccionar". |
598
+ | disabled | boolean | *(Opcional)* Desactiva el campo y reduce la opacidad. |
599
+
600
+ ### 🔧 Tipo SelectOption:
601
+ ```Typescript
602
+ type SelectOption = {
603
+ label: string
604
+ value: string | number
605
+ }
606
+ ```
607
+
608
+ ### 🧩 Ejemplos de uso:
609
+ ```Typescript
610
+ import { useState } from 'react';
611
+ import { Select, SelectOption } from '@dropi/react-native-design-system';
612
+
613
+ const MyForm = () => {
614
+ const [country, setCountry] = useState<SelectOption | null>(null);
615
+
616
+ const countries: SelectOption[] = [
617
+ { label: 'Colombia', value: 'CO' },
618
+ { label: 'México', value: 'MX' },
619
+ { label: 'Argentina', value: 'AR' },
620
+ ];
621
+
622
+ return (
623
+ <Select
624
+ label="País"
625
+ placeholder="Selecciona tu país"
626
+ options={countries}
627
+ value={country}
628
+ onChange={setCountry}
629
+ />
630
+ );
631
+ };
632
+
633
+ // Con helper text
634
+ <Select
635
+ label="Método de pago"
636
+ placeholder="Selecciona un método"
637
+ options={paymentMethods}
638
+ value={selectedMethod}
639
+ onChange={setSelectedMethod}
640
+ helper="Puedes cambiar esto más tarde"
641
+ />
642
+
643
+ // Con estado de error
644
+ <Select
645
+ label="Ciudad"
646
+ placeholder="Selecciona tu ciudad"
647
+ options={cities}
648
+ value={selectedCity}
649
+ onChange={setSelectedCity}
650
+ hasError={!selectedCity}
651
+ errorMessage="Debes seleccionar una ciudad"
652
+ />
653
+
654
+ // Con título personalizado en el modal
655
+ <Select
656
+ label="Categoría"
657
+ title="Elige una categoría de producto"
658
+ options={categories}
659
+ value={category}
660
+ onChange={setCategory}
661
+ />
662
+
663
+ // Deshabilitado
664
+ <Select
665
+ label="Región"
666
+ options={regions}
667
+ value={region}
668
+ onChange={setRegion}
669
+ disabled={true}
670
+ />
671
+ ```
672
+
452
673
  ## Empty State
453
674
 
454
675
  El EmptyState es un componente visual diseñado para mostrar pantallas vacías en escenarios donde no hay datos disponibles, ocurrió un estado inicial o se requiere una primera acción del usuario. Puede incluir una imagen, un título opcional, un mensaje descriptivo y un botón configurable. Mantiene una composición centrada y un diseño minimalista, usando automáticamente tamaños distintos para tablet gracias a isTablet.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dropi/react-native-design-system",
3
- "version": "0.2.21",
3
+ "version": "0.2.23",
4
4
  "description": "A React Native package built from scratch",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",