@datosgeo-atdt/geo-ui 0.10.2 → 0.11.2

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
@@ -6,6 +6,7 @@ Librería de componentes reutilizables en React para aplicaciones geoespaciales.
6
6
 
7
7
  - **MapaPMTiles**: Componente para renderizar mapas vectoriales usando MapLibre GL y PMTiles
8
8
  - **TotalesDisplay**: Componente para mostrar totales y estadísticas con soporte responsive
9
+ - **DataTable**: Componente de tabla flexible con carga automática de CSV
9
10
  - **Join CSV**: Unión automática de datos tabulares con geometrías vectoriales
10
11
  - **Estilos temáticos**: Soporte para modo booleano y clasificación Jenks
11
12
  - **TypeScript**: Completamente tipado para mejor experiencia de desarrollo
@@ -605,6 +606,323 @@ Puedes sobrescribir los estilos usando tu propio CSS:
605
606
 
606
607
  ---
607
608
 
609
+ ## DataTable
610
+
611
+ Componente de tabla genérico y flexible para mostrar datos tabulares con soporte para carga automática de CSV desde la carpeta `public`.
612
+
613
+ ### Características
614
+
615
+ - **Carga automática de CSV**: Lee archivos CSV desde la carpeta `public` y parsea los datos
616
+ - **Detección automática de columnas**: Extrae los nombres de las columnas directamente del CSV
617
+ - **Columnas personalizables**: Define qué columnas mostrar y su ancho
618
+ - **Tamaño ajustable**: Props `width` y `height` para controlar dimensiones
619
+ - **Formato automático de números**: Formatea números con separadores de miles (estilo mexicano)
620
+ - **Índice opcional**: Puede mostrar numeración de filas
621
+ - **Responsive**: Se adapta automáticamente a móvil
622
+ - **Estados de carga**: Muestra "Cargando datos..." mientras procesa el CSV
623
+ - **Manejo de errores**: Muestra mensajes descriptivos si falla la carga
624
+ - **TypeScript**: Completamente tipado
625
+
626
+ ### Uso Básico
627
+
628
+ #### Importar el componente
629
+
630
+ ```tsx
631
+ import { DataTable } from '@atdt/geo-ui';
632
+ import '@atdt/geo-ui/style.css';
633
+ ```
634
+
635
+ #### Ejemplo 1: Cargar CSV automáticamente desde public/
636
+
637
+ Si tienes un archivo `alcaldias.csv` en la carpeta `public/` de tu proyecto:
638
+
639
+ ```csv
640
+ alcaldia,poblacion
641
+ Iztapalapa,1815786
642
+ Gustavo A. Madero,1185772
643
+ Álvaro Obregón,749982
644
+ Tlalpan,677104
645
+ ```
646
+
647
+ Simplemente especifica la ruta del archivo:
648
+
649
+ ```tsx
650
+ import { DataTable } from '@atdt/geo-ui';
651
+
652
+ function App() {
653
+ return (
654
+ <DataTable csvPath="/alcaldias.csv" />
655
+ );
656
+ }
657
+ ```
658
+
659
+ **El componente automáticamente:**
660
+ - Carga el CSV desde `public/alcaldias.csv`
661
+ - Detecta los nombres de las columnas (`alcaldia`, `poblacion`)
662
+ - Los usa como headers de la tabla
663
+ - Parsea los datos y los muestra
664
+ - Formatea números con separadores de miles (1,815,786)
665
+ - Distribuye las columnas equitativamente (50% cada una en este caso)
666
+
667
+ #### Ejemplo 2: Personalizar nombres de columnas
668
+
669
+ Puedes sobrescribir los nombres de las columnas del CSV:
670
+
671
+ ```tsx
672
+ import { DataTable } from '@atdt/geo-ui';
673
+
674
+ function App() {
675
+ return (
676
+ <DataTable
677
+ csvPath="/alcaldias.csv"
678
+ columns={[
679
+ { key: 'alcaldia', label: 'Alcaldía', width: '60%' },
680
+ { key: 'poblacion', label: 'Población Total', width: '40%' }
681
+ ]}
682
+ showIndex={true}
683
+ indexLabel="#"
684
+ />
685
+ );
686
+ }
687
+ ```
688
+
689
+ #### Ejemplo 3: Datos directos (sin CSV)
690
+
691
+ También puedes pasar datos directamente sin cargar un CSV:
692
+
693
+ ```tsx
694
+ import { DataTable } from '@atdt/geo-ui';
695
+
696
+ function App() {
697
+ const datos = [
698
+ { nombre: 'Ciudad de México', habitantes: 9209944 },
699
+ { nombre: 'Guadalajara', habitantes: 1495189 },
700
+ { nombre: 'Monterrey', habitantes: 1142994 }
701
+ ];
702
+
703
+ return (
704
+ <DataTable
705
+ data={datos}
706
+ columns={[
707
+ { key: 'nombre', label: 'Ciudad' },
708
+ { key: 'habitantes', label: 'Habitantes' }
709
+ ]}
710
+ />
711
+ );
712
+ }
713
+ ```
714
+
715
+ #### Ejemplo 4: Múltiples columnas con distribución automática
716
+
717
+ ```tsx
718
+ // Con 4 columnas, cada una ocupa automáticamente 25% del ancho
719
+ <DataTable
720
+ csvPath="/productos.csv"
721
+ columns={[
722
+ { key: 'nombre', label: 'Producto' },
723
+ { key: 'categoria', label: 'Categoría' },
724
+ { key: 'precio', label: 'Precio' },
725
+ { key: 'stock', label: 'Stock' }
726
+ ]}
727
+ showIndex={true}
728
+ />
729
+ ```
730
+
731
+ #### Ejemplo 5: Control manual de anchos de columnas
732
+
733
+ ```tsx
734
+ // Especifica anchos personalizados cuando necesites distribución no equitativa
735
+ <DataTable
736
+ csvPath="/datos.csv"
737
+ columns={[
738
+ { key: 'nombre', label: 'Nombre', width: '50%' },
739
+ { key: 'valor1', label: 'Valor 1', width: '25%' },
740
+ { key: 'valor2', label: 'Valor 2', width: '25%' }
741
+ ]}
742
+ />
743
+ ```
744
+
745
+ ### Props de DataTable
746
+
747
+ #### Props de Datos (al menos una opción es requerida)
748
+
749
+ | Prop | Tipo | Descripción |
750
+ |------|------|-------------|
751
+ | `data` | `Record<string, any>[]` | Array de objetos con los datos a mostrar |
752
+ | `csvPath` | `string` | Ruta del archivo CSV en la carpeta `public` (ej: `/datos.csv`) |
753
+
754
+ #### Props de Configuración
755
+
756
+ | Prop | Tipo | Default | Descripción |
757
+ |------|------|---------|-------------|
758
+ | `columns` | `DataTableColumn[]` | Auto-detectado | Definición de columnas a mostrar |
759
+ | `width` | `string` | Controlado por CSS | Ancho del contenedor (por defecto 50% del viewport en desktop, 100% en móvil) |
760
+ | `height` | `string` | Controlado por CSS | Alto del contenedor (por defecto 100% con scroll interno cuando excede 70vh) |
761
+ | `className` | `string` | `""` | Clases CSS adicionales |
762
+ | `showIndex` | `boolean` | `false` | Mostrar columna con índice numérico |
763
+ | `indexLabel` | `string` | `"#"` | Etiqueta para la columna de índice |
764
+
765
+ #### Tipo DataTableColumn
766
+
767
+ ```tsx
768
+ interface DataTableColumn {
769
+ key: string; // Campo del objeto/CSV
770
+ label: string; // Texto a mostrar en el header
771
+ width?: string; // Ancho de la columna (ej: "40%", "200px")
772
+ }
773
+ ```
774
+
775
+ ### Ejemplos Completos
776
+
777
+ #### Ejemplo con CSV de productos
778
+
779
+ ```tsx
780
+ import { DataTable } from '@atdt/geo-ui';
781
+
782
+ // public/productos.csv
783
+ // nombre,categoria,precio,stock
784
+ // Laptop Dell,Electrónica,15999,50
785
+ // Mouse Logitech,Accesorios,299,150
786
+ // Monitor Samsung,Electrónica,4599,30
787
+
788
+ function App() {
789
+ return (
790
+ <DataTable
791
+ csvPath="/productos.csv"
792
+ columns={[
793
+ { key: 'nombre', label: 'Producto', width: '30%' },
794
+ { key: 'categoria', label: 'Categoría', width: '25%' },
795
+ { key: 'precio', label: 'Precio', width: '25%' },
796
+ { key: 'stock', label: 'Stock', width: '20%' }
797
+ ]}
798
+ width="900px"
799
+ height="500px"
800
+ showIndex={true}
801
+ />
802
+ );
803
+ }
804
+ ```
805
+
806
+ #### Ejemplo con datos dinámicos
807
+
808
+ ```tsx
809
+ import { DataTable } from '@atdt/geo-ui';
810
+ import { useState, useEffect } from 'react';
811
+
812
+ function App() {
813
+ const [datos, setDatos] = useState([]);
814
+
815
+ useEffect(() => {
816
+ // Cargar datos desde una API
817
+ fetch('https://api.example.com/estadisticas')
818
+ .then(res => res.json())
819
+ .then(data => setDatos(data));
820
+ }, []);
821
+
822
+ return (
823
+ <DataTable
824
+ data={datos}
825
+ columns={[
826
+ { key: 'region', label: 'Región' },
827
+ { key: 'total', label: 'Total' }
828
+ ]}
829
+ />
830
+ );
831
+ }
832
+ ```
833
+
834
+ #### Ejemplo integrando con MapaPMTiles
835
+
836
+ Layout tipo dashboard con mapa y tabla lado a lado:
837
+
838
+ ```tsx
839
+ import { MapaPMTiles, DataTable } from '@atdt/geo-ui';
840
+ import '@atdt/geo-ui/style.css';
841
+
842
+ function App() {
843
+ return (
844
+ <div style={{ display: 'flex', width: '100%', height: '100vh' }}>
845
+ {/* Mapa ocupa 50% */}
846
+ <MapaPMTiles
847
+ csvPath="/datos_entidades.csv"
848
+ fitToIds={["09", "15", "14"]}
849
+ mode="jenks"
850
+ enablePopup={true}
851
+ />
852
+
853
+ {/* DataTable ocupa 50% automáticamente */}
854
+ <DataTable
855
+ csvPath="/datos_entidades.csv"
856
+ columns={[
857
+ { key: 'entidad', label: 'Entidad' },
858
+ { key: 'valor', label: 'Valor' }
859
+ ]}
860
+ />
861
+ </div>
862
+ );
863
+ }
864
+ ```
865
+
866
+ ### Formato de Números
867
+
868
+ Los números se formatean automáticamente con separadores de miles usando el formato mexicano:
869
+
870
+ - `1815786` → `1,815,786`
871
+ - `9209944` → `9,209,944`
872
+ - `150` → `150`
873
+
874
+ ### Estados de Carga
875
+
876
+ El componente muestra diferentes estados:
877
+
878
+ 1. **Cargando**: "Cargando datos..." mientras lee el CSV
879
+ 2. **Error**: Mensaje de error en rojo si falla la carga
880
+ 3. **Vacío**: "No hay datos para mostrar" si el CSV está vacío
881
+ 4. **Datos**: Tabla renderizada con los datos
882
+
883
+ ### Diseño y Layout
884
+
885
+ El componente está diseñado para integrarse con layouts tipo dashboard:
886
+
887
+ - **Desktop**:
888
+ - Ocupa **50% del ancho** del contenedor padre por defecto
889
+ - Centrado vertical y horizontal
890
+ - Scroll interno cuando el contenido excede **70vh**
891
+ - Headers y celdas con tamaño `1.11vw`
892
+ - Columnas se distribuyen automáticamente usando flexbox
893
+
894
+ - **Mobile** (≤600px):
895
+ - Ocupa **100% del ancho**
896
+ - Headers con tamaño `3.5vw`
897
+ - Celdas con tamaño `4vw`
898
+ - Padding ajustado para pantallas pequeñas
899
+ - Box shadow más pronunciado
900
+
901
+ ### Personalización de Estilos
902
+
903
+ Puedes sobrescribir los estilos usando la clase `className`:
904
+
905
+ ```tsx
906
+ <DataTable
907
+ csvPath="/datos.csv"
908
+ className="mi-tabla-custom"
909
+ />
910
+ ```
911
+
912
+ ```css
913
+ .mi-tabla-custom {
914
+ border: 2px solid #66827f;
915
+ box-shadow: 0 4px 8px rgba(0,0,0,0.2);
916
+ }
917
+
918
+ .mi-tabla-custom .tableHeader {
919
+ background-color: #66827f;
920
+ color: white;
921
+ }
922
+ ```
923
+
924
+ ---
925
+
608
926
  ## Props de MapaPMTiles
609
927
 
610
928
  ### Props Obligatorias
@@ -0,0 +1,19 @@
1
+ import { default as React } from 'react';
2
+ export interface DataTableColumn {
3
+ key: string;
4
+ label: string;
5
+ width?: string;
6
+ }
7
+ export interface DataTableProps {
8
+ data?: Record<string, any>[];
9
+ columns?: DataTableColumn[];
10
+ csvPath?: string;
11
+ width?: string;
12
+ height?: string;
13
+ className?: string;
14
+ showIndex?: boolean;
15
+ indexLabel?: string;
16
+ }
17
+ declare const DataTable: React.FC<DataTableProps>;
18
+ export default DataTable;
19
+ //# sourceMappingURL=DataTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../src/components/DataTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,MAAM,WAAW,eAAe;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,QAAA,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAqKvC,CAAC;AAEF,eAAe,SAAS,CAAC"}