From 3e64837dd3fc263ec883d462a9de0ae80eb70410 Mon Sep 17 00:00:00 2001 From: jalvarado Date: Thu, 29 May 2025 10:37:10 -0600 Subject: [PATCH] feat: Add ProgressBar component with skeleton status and documentation - Implemented ProgressBar component to display progress based on states. - Added EstatusEskeleton for loading state indication. - Created documentation page for ProgressBar with examples and props table. - Developed reusable CodeBlock and VistaComponente components for code display. - Introduced IndiceContenido for navigation within documentation. - Styled ProgressBar and related components with SCSS. --- public/progress-bar.png | Bin 0 -> 6965 bytes public/tabs.png | Bin 0 -> 11371 bytes src/app/(components)/button/page.tsx | 4 +- src/app/(components)/input/page.tsx | 4 +- src/app/(components)/options/page.tsx | 102 ++++---- src/app/(components)/pagination/page.tsx | 50 ++-- src/app/(components)/popover/page.tsx | 4 +- src/app/(components)/progress-bar/page.tsx | 102 ++++++++ src/app/(components)/select/page.tsx | 83 ++++--- src/app/(components)/sidebar/page.tsx | 194 ++++++++------- src/app/(components)/styles/page.tsx | 114 ++++----- src/app/(components)/table/page.tsx | 6 +- src/app/(components)/tabs/page.tsx | 232 ++++++++++++------ src/app/page.tsx | 11 +- src/components/{ => docs}/code-block.tsx | 0 src/components/{ => docs}/component-card.tsx | 0 src/components/{ => docs}/content-index.tsx | 0 .../{ => docs}/vista-componente.tsx | 2 +- src/components/progress-bar.tsx | 43 ++++ src/components/tabs.tsx | 47 ++-- src/styles/sass/_progress-bar.scss | 57 +++++ src/styles/sass/_tabs.scss | 2 +- src/styles/sass/bootstrap.scss | 1 + 23 files changed, 681 insertions(+), 377 deletions(-) create mode 100644 public/progress-bar.png create mode 100644 public/tabs.png create mode 100644 src/app/(components)/progress-bar/page.tsx rename src/components/{ => docs}/code-block.tsx (100%) rename src/components/{ => docs}/component-card.tsx (100%) rename src/components/{ => docs}/content-index.tsx (100%) rename src/components/{ => docs}/vista-componente.tsx (97%) create mode 100644 src/components/progress-bar.tsx create mode 100644 src/styles/sass/_progress-bar.scss diff --git a/public/progress-bar.png b/public/progress-bar.png new file mode 100644 index 0000000000000000000000000000000000000000..10ebac606acea0ff27995fe666d3fa86e478b3b6 GIT binary patch literal 6965 zcmeHMTR59(yH2Z9)6udzowlR4Q_9~et$oFA)Tm|@|5R1&Yiy#mD?v(-&b0rSL8%xt z2yH2~iKq}Ih|#INpf*87C=!GO5!-Cmn_1U7SnFUNtb_k(obdVHROE*luD>tBW%m_iNp)omQrZC!3{zN$PAft*Q)eP?s)VZkaRE;?866K~!5 z%P%tzef~oI=Bd*ouSQSdiXY!p>Gb&LR3`NnXY5sRx@SnlXu7A}%k%Jf4PEZBt&r z14dq&a*bB8EPjr1~Rg#fy5bvt;^7Fkp#(}#V3-`jqsTHo3wLy-Yw>7U`8Cb?| zUUzhKjNe+p>Nc!o`?SQz@PB>TlJeRi7r(@{so8zFj!&7|3UCdw^v-UKa0?x5vfZod zF8M*%YZzdhPYuMVg`Q&`4NXnZ7SuM3*(xXp&o;Vx2Yoe5 zZ>Xm3tXuz5X1*F>`S(>vRR$)tqq?WfgW1|v`ttSbb5Ec0i4SIfcAD@>Or(U?kB*gB zEEmk_C46-?>r;@0Yqp$fHI=RdMUoRq*GpCE479mJ9~+epFaDT%O817Xt?g|BcWTZ( zFwpg|yz=wbM2>k3xu*4rmK|>YZcJJKkJY{NL%LY2@b^xa4uoEuemIwbGf8dK69_~G z!Gk7t+Xr~|!8iL(bMf6POl1G#V_GY9P(y7KWOpkB+B?;V?!uf)B?tJ%#IzU&bZIvQ z_^!!kn7;b8I;~F=E86c#nDsf`Dx;?6t%!xy26TVw!|f;Q(bY7sW*wv^)-*Y2@KuOt zUo1kcin}2?82ZL^ddENa8p}NAqI=m!cP z52+EZ(VX-A?WW!JisqdhcgMSPLsL^z__97`$ZY#(_rka8S%k*o!SEB(~ zxinhomfUfe^W(KF`TY+eDiV{XmA0|2gb;V_ql?~9|4@iZeW<%j@)&P|2;bXU&F|>w z=*u^~BzNj!S0$k}@0>$U30fj%KuvbkgN&AHI@vK6EbeaDM#g|<_Q~#*OEK*)#18PZ zV=s!q9;ROkDk~~Jj*R@?zzj!MpcZ1t)$2zLST>AtTH*!YySQ`)X)@xRV5?V&TNQ;2WBGr4YBbeJ@a1P( zCiR_QSRT4l_Koc?C7{*NLjTUB*8vEAipBPnA*UOpGElI{1u|((w5B zIOF|Kv8OHqB^-P`R^>i?o(>wi``6;m)@0SCmh@V$iry*+&^a&Av~Dr|Ocr)WmDan_LE&QM=Ha3;&RE zl5^)olM^LrHRAA>d61e+&QP)aGKZ6;`TmzCk_B4>V(n${wM6en`oAT*_=Jdl3m`{Ga;W z93A^TOuvsV+uKVjFQ2$VAi#&eF*6og{0<+R)B^NoEqscrs;)+Y%hKNMUY0}f%|H8o>-RpBe`v2C4HQDU;1!USwKKxI?fl&u$;#sa zb#-+mZzGdV>3I#Fr&khqxp>m#Bx503=OrvR{{K)d)eia4ro8-oV(?J=MIT}8?dqu- zCFRP>%3(6HXmiz*=eH92)e|iS>#ds(Kb3ZYzth}fAqlc$>6Uk4Buyi=)mn;P4O$wq zRo#n!R1%qkqZ7zGG-kK_ATBR2uNH8Ll#5s_R+UHng^;m2RXLpt7lw=NGe$;6O5g*9 z6H&cBQc^O__XrNgA%9vwo!$Qy411gq-C^9Ogz z!cLDzx9q>$2`>`P>oG2$*?D+8ug>t{8cET7ix}psmbf`Wth8>v$yKJ=OV_5}m z?OWx@KaZPz`c9o5mGK--mLpQoKvg)XZwYpPI>O_sXqj3x*Q;JlR<32J^{5sdCrv%m+G+yHzFyEyT)pK4O z-i`TyTU$DiUwhg&LBGDc=YP{K3`Py8Ap5R|t>$2@M7&yhcyW|)-S-Bj3aHv?uQlu1PSv8G7dA5d zi2-hIvTFPTe4-bkpBY4G+3F+F<*8sxtW5i)$?#o`4586nhf0CXs=WMD}Wy zf?zU)a1OR7sC35Mz(&~x4J4`i?)J>z$T!jDv-*2~uvftb_U6>%4dK**;i=}cG;gGL z($0Hxem+yEb=qg=DQSV`i%x9i<3jkS(d)U5OQmW7Ycqdf&G>3o50rsmC@j26)$1F7 zTh#ApDjFD}ZTGHsqV*}F)d>3ZFz}gJL&-PHy|I&x+taAwhKNKbi**O7sWoklvGA%B2P zXNu_w0D|4#NCwtcL4`@mFy{&Vs8{ATl^@Rh)F|3g#9oQ~5j?5scFoT&?1UHEMF|GE z-m&+#n36{;&3wJMtqHh6;vO@Q)#q+D|I9W^69q(4Jny{KBcovP43?#J4n|@oC4=X? z0(rq`b}Ad{gHSy&CBU77x_JZe&wE96zlLFK<;{#LZ{vF?!ro$@c{;G11<2_}Gkzb1 z>IyUulcr{Eg<3U+HcZDmlsZ%NU^l(JaUs=>CP2*{K0^27|2&?|-lm}S$g5lBo6D~G znxHGaYe7-9?}^HVpaHrJ2P|?yHleVO1Yb%4ifh)mTyam)AmBPX=}lW_&r{RsXG#&x zFBu`A$zXc#X4*-FOHGUUW;-(j+OVxD1OcGZ7{Ti6t|oK04$wtDKYH$>ak>e7Ibt%xuu zOF~Vj?yD-I4PGZ zSX?%jRo!93Fj6P9x49IzziJ0eY;U%kQ+H&iillmO{TuiC`>v(V5;DLlc4@ebXD?}+ zD0x0qg8M6C@9ZLpkZlmu_k1drz6!$>iB{miH1x5pkPqlkKzMnK*!^3oXrc9_574!+ z)IQB6Ci+{}Kv9vV6a*W490I%M{UkGOxXhUslg^od7j=U`3nJ$_>RZN$@PPy|e{Mrf zvd$sVZdZF@#iIQNdIaX;otg(YdeY{QeeHl1dh!$&7WL>wla^x`?NHzG6e#`1Y)3NqtaJY!9W34B&{+P ztc4FMDk~8yZ?h&_*r~o2dKs2mcR<7a4&)1YFErGP6Vw?(5INBmwyZ@g{1(|UdK<}1%YQrXLu6r4LTh=qk0Qf*`t^@woEmBhWx{$Xc{9-(#be!4mL zT`c_y_uU+*5T*}n$d-{XLw)*!KT^rO>MBqR!2N})mg0T-JV0O%7?^MRGU50bBr|ba zFxmO(g9Ap0JXD=w%1khX86*kc)#n^jvr4ce)v#npqT8y8o0%hH;f-UppUF*o@bnMn zmuAEp4(1tithmiZO-)T8k#}*uOaP4$8V%m7OINFux;V{y!NFba|H5-i~Q!m_#kB#lEs5IZ&DW061Txs1`ZQNU~qb!INgkBPy?W#X19~_)Of2wK>m7gVPxtX9h3-OW6EQUJVKC%0i}$7gFPnuCF1go& zP&vuvZ{FPD)VFL;n@hnnajy&qg#87HW;!o9RP$15*_xWh)Ls>##k)c}MdYdFxYrJ4 zq6ckc7leE_mc4b}XzbG<%v9pGx1wRt4KSLxxVimBPzqK%S!s%frK^@%+URq~jvd=A zL+>#s09g1_hykgvlgzcKMb_3}tm{eKX5=awh7SNclLe5Freba)TdgK$A(h_&7qLC5nY{(Cc@j z#QWSP_+%Y9p#{)>YM#u*6CXY8j=d)z3-<@~16rew7g|b-vC`$xOn1H8QFJ3DWL~e9zFBBlCFb4;R z>gK5LNt5?0>#Icx4VfCqo+H`?&r>gn^EIV|r9sG8l?8|gYq{SE!>C%u&o}d1^Uk|e zcg_6qmIvFl-O@F5!smu4hniqDZ8eCpIr>27YA1;5^>yeIg{1IDP@QF z0-)>(ID_o=QoG>VKf)UqNC_OzTy~01YxX&ZQ}8leER{wPTaW1&FeAs@;S2qyN{F>T zWM4Nnn#rmOca>2qC9xTc4++3{ID(U~#+^?QEZ{h=OT;2X`w?wcyWAxYo@i`rj8)sK zHvr@>&sVgZ8@JKTENyMI0;u{Yh^7E!8|Ds<<)ml;;Ilk?q6-9Hw9liU@iZQpCnlM< zTc_yzcg&|5It@%UB8czh&F97Y68*&eq&3DQAWy*(y}`M4tDaB_4&&%y4c^?A?bcYs zRCWO(TuSfK)74TO-BZzHUTIWL!|C;n%6soBo}r~`Nl(y{~m~DN6f%!{PUr|Pu~B2 i-|+8w9rLS1L4g<<9qGB}30?<5V0KR5RbRdP^M3;Vq)5*I literal 0 HcmV?d00001 diff --git a/public/tabs.png b/public/tabs.png new file mode 100644 index 0000000000000000000000000000000000000000..b917a93f17ec09fcc351731ca24fefe50ebc0244 GIT binary patch literal 11371 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 literal 0 HcmV?d00001 diff --git a/src/app/(components)/button/page.tsx b/src/app/(components)/button/page.tsx index 52251c4..7fddf5a 100644 --- a/src/app/(components)/button/page.tsx +++ b/src/app/(components)/button/page.tsx @@ -1,7 +1,7 @@ 'use client'; -import IndiceContenido from '@/components/content-index'; -import VistaComponente from '@/components/vista-componente'; +import IndiceContenido from '@/components/docs/content-index'; +import VistaComponente from '@/components/docs/vista-componente'; import Button from '@/components/button'; export default function Page() { diff --git a/src/app/(components)/input/page.tsx b/src/app/(components)/input/page.tsx index 3d16e21..f9778ea 100644 --- a/src/app/(components)/input/page.tsx +++ b/src/app/(components)/input/page.tsx @@ -1,9 +1,9 @@ 'use client'; -import IndiceContenido from '@/components/content-index'; +import IndiceContenido from '@/components/docs/content-index'; import Input from '@/components/input'; import PasswordInput from '@/components/password'; -import VistaComponente from '@/components/vista-componente'; +import VistaComponente from '@/components/docs/vista-componente'; import { inputBasicExample, inputPasswordExample, diff --git a/src/app/(components)/options/page.tsx b/src/app/(components)/options/page.tsx index 4d9a7ff..d38016f 100644 --- a/src/app/(components)/options/page.tsx +++ b/src/app/(components)/options/page.tsx @@ -1,40 +1,40 @@ -"use client"; +'use client'; -import React, { useState } from "react"; -import RadioOptionGroup, { RadioOption } from "@/components/radio-option-group"; +import React, { useState } from 'react'; +import RadioOptionGroup, { RadioOption } from '@/components/radio-option-group'; import CheckboxOptionGroup, { CheckboxOption, -} from "@/components/checkbox-option-group"; -import VistaComponente from "@/components/vista-componente"; -import { CodeBlock } from "@/components/code-block"; +} from '@/components/checkbox-option-group'; +import VistaComponente from '@/components/docs/vista-componente'; +import { CodeBlock } from '@/components/docs/code-block'; import { checkboxBasicExample, checkboxLimitExample, radioBasicExample, radioDisabledExample, -} from "@/snippets/options/option-examples"; -import IndiceContenido from "@/components/content-index"; +} from '@/snippets/options/option-examples'; +import IndiceContenido from '@/components/docs/content-index'; export default function RadioCheckboxDocs() { - const [selectedRadio, setSelectedRadio] = useState("op1"); + const [selectedRadio, setSelectedRadio] = useState('op1'); const [checkboxBasicSelected, setCheckboxBasicSelected] = useState([ - "a", + 'a', ]); const [checkboxLimitSelected, setCheckboxLimitSelected] = useState( [] ); const radioOptions: RadioOption[] = [ - { label: "Opción 1", value: "op1" }, - { label: "Opción 2", value: "op2" }, - { label: "Opción 3", value: "op3" }, + { label: 'Opción 1', value: 'op1' }, + { label: 'Opción 2', value: 'op2' }, + { label: 'Opción 3', value: 'op3' }, ]; const checkboxOptions: CheckboxOption[] = [ - { label: "Activo", value: "a" }, - { label: "Inactivo", value: "b" }, - { label: "Pendiente", value: "c" }, + { label: 'Activo', value: 'a' }, + { label: 'Inactivo', value: 'b' }, + { label: 'Pendiente', value: 'c' }, ]; const handleCheckboxChange = ( @@ -51,24 +51,24 @@ export default function RadioCheckboxDocs() { <> -
-

- Componentes: RadioOptionGroup y{" "} +
+

+ Componentes: RadioOptionGroup y{' '} CheckboxOptionGroup

-

+

Estos componentes permiten mostrar grupos de opciones radio o checkbox, para seleccionar una o varias opciones respectivamente. Son útiles en formularios, encuestas o filtros. Los estilos de estos - componentes se basan en Bootstrap y se encuentran el el archivo{" "} - @/styles/sass/_extneds.scss y es el selector{" "} + componentes se basan en Bootstrap y se encuentran el el archivo{' '} + @/styles/sass/_extneds.scss y es el selector{' '} .option.

@@ -77,16 +77,16 @@ export default function RadioCheckboxDocs() { import CheckboxOptionGroup, { CheckboxOption } from "@/components/checkbox-option-group";`} /> -
+
{}} /> @@ -127,13 +127,13 @@ import CheckboxOptionGroup, { CheckboxOption } from "@/components/checkbox-optio @@ -143,14 +143,14 @@ import CheckboxOptionGroup, { CheckboxOption } from "@/components/checkbox-optio /> -
-

Props comunes

+
+

Props comunes

  • name: Nombre del grupo de inputs.
  • - options: Lista de opciones con label,{" "} + options: Lista de opciones con label,{' '} value y opcionalmente disabled.
  • @@ -158,7 +158,7 @@ import CheckboxOptionGroup, { CheckboxOption } from "@/components/checkbox-optio
-

+

Props de RadioOptionGroup

    @@ -174,7 +174,7 @@ import CheckboxOptionGroup, { CheckboxOption } from "@/components/checkbox-optio
-

+

☑️ Props de CheckboxOptionGroup

    diff --git a/src/app/(components)/pagination/page.tsx b/src/app/(components)/pagination/page.tsx index 5609caf..97803ce 100644 --- a/src/app/(components)/pagination/page.tsx +++ b/src/app/(components)/pagination/page.tsx @@ -1,14 +1,14 @@ -"use client"; +'use client'; -import React, { useState } from "react"; -import VistaComponente from "@/components/vista-componente"; -import { CodeBlock } from "@/components/code-block"; -import Pagination from "@/components/pagination"; +import React, { useState } from 'react'; +import VistaComponente from '@/components/docs/vista-componente'; +import { CodeBlock } from '@/components/docs/code-block'; +import Pagination from '@/components/pagination'; import { paginationBasic, paginationWithDelta, -} from "@/snippets/pagination/pagination-example"; -import IndiceContenido from "@/components/content-index"; +} from '@/snippets/pagination/pagination-example'; +import IndiceContenido from '@/components/docs/content-index'; export default function Page() { const [currentPage1, setCurrentPage1] = useState(1); @@ -18,20 +18,20 @@ export default function Page() { <> -
    -

    +
    +

    📄 Componente: Pagination

    -

    +

    El componente <Pagination /> permite navegar entre páginas de forma controlada. Es completamente reutilizable y permite mostrar botones de anterior/siguiente y paginación con saltos. @@ -39,31 +39,31 @@ export default function Page() { -


    +
    {/* Ejemplo básico */} -

    +

    Página actual: {currentPage1}

    {/* Ejemplo con delta */} -

    +

    Página actual: {currentPage2}

    {/* Props */} -
    -

    ⚙️ Props del componente

    +
    +

    ⚙️ Props del componente

    • totalPages: number — Total de páginas diff --git a/src/app/(components)/popover/page.tsx b/src/app/(components)/popover/page.tsx index 9a408ab..334030e 100644 --- a/src/app/(components)/popover/page.tsx +++ b/src/app/(components)/popover/page.tsx @@ -1,7 +1,7 @@ 'use client'; -import IndiceContenido from '@/components/content-index'; -import VistaComponente from '@/components/vista-componente'; +import IndiceContenido from '@/components/docs/content-index'; +import VistaComponente from '@/components/docs/vista-componente'; import Popover from '@/components/popover'; export default function Page() { diff --git a/src/app/(components)/progress-bar/page.tsx b/src/app/(components)/progress-bar/page.tsx new file mode 100644 index 0000000..2df0be0 --- /dev/null +++ b/src/app/(components)/progress-bar/page.tsx @@ -0,0 +1,102 @@ +'use client'; + +import { CodeBlock } from '@/components/docs/code-block'; +import IndiceContenido from '@/components/docs/content-index'; +import VistaComponente from '@/components/docs/vista-componente'; +import ProgressBar, { EstatusEskeleton } from '@/components/progress-bar'; + +export default function Page() { + const estados = ['Pendiente', 'En proceso', 'Completado', 'Entregado']; + return ( + <> + + +
      +

      + 🚀 Componente: ProgressBar +

      + +

      + El componente <ProgressBar /> muestra una barra de + progreso basada en una lista de estados y el índice del estado activo. + Incluye vista responsiva: multistep en pantallas md+ y paso único en + móvil. +

      + + + +
      + + `} + > + + + + `} + > + + + + {/* PROPS */} +
      +

      + ⚙️ Props de ProgressBar +

      + + + + + + + + + + + + + + + + + + + + +
      PropTipoDescripción
      + estados + + string[] + Listado de etiquetas para cada paso.
      + estadoActivo + + number + Índice (0-based) del paso actualmente activo.
      + +

      + ⚙️ Props de EstatusEskeleton +

      +

      Este componente no recibe props.

      +
      +
      + + ); +} diff --git a/src/app/(components)/select/page.tsx b/src/app/(components)/select/page.tsx index 52a9676..d678f75 100644 --- a/src/app/(components)/select/page.tsx +++ b/src/app/(components)/select/page.tsx @@ -1,52 +1,55 @@ -"use client"; +'use client'; -import IndiceContenido from "@/components/content-index"; -import Select from "@/components/select"; -import VistaComponente from "@/components/vista-componente"; -import { countrySelectSnippet, languageSelectSnippet } from "@/snippets/select/select"; -import { useState } from "react"; +import IndiceContenido from '@/components/docs/content-index'; +import Select from '@/components/select'; +import VistaComponente from '@/components/docs/vista-componente'; +import { + countrySelectSnippet, + languageSelectSnippet, +} from '@/snippets/select/select'; +import { useState } from 'react'; export default function Page() { - const [pais, setPais] = useState(""); + const [pais, setPais] = useState(''); const opcionesPais = [ - { value: "mx", label: "México" }, - { value: "us", label: "Estados Unidos" }, - { value: "ca", label: "Canadá" }, + { value: 'mx', label: 'México' }, + { value: 'us', label: 'Estados Unidos' }, + { value: 'ca', label: 'Canadá' }, ]; return ( <> -
      -

      +
      +

      Componente: Select

      -

      +

      El componente <Select /> permite mostrar una lista desplegable con opciones personalizables, soporta etiquetas, estilos por clase, y es compatible con formularios.

      -
      +
      -
      -

      Props del componente

      +
      +

      Props del componente

      • label: string – Etiqueta visible del campo. @@ -86,7 +89,7 @@ export default function Page() { options: { value: string | number; label: string }[] - {" "} + {' '} – Opciones a mostrar.
      • @@ -108,11 +111,11 @@ export default function Page() { (modo controlado).
      • - className?: { container?, label?, input? }{" "} + className?: { container?, label?, input? }{' '} – Clases personalizadas.
      • - ...rest – Cualquier otra prop válida de{" "} + ...rest – Cualquier otra prop válida de{' '} <select>.
      diff --git a/src/app/(components)/sidebar/page.tsx b/src/app/(components)/sidebar/page.tsx index 6eac9c2..50ec21e 100644 --- a/src/app/(components)/sidebar/page.tsx +++ b/src/app/(components)/sidebar/page.tsx @@ -1,64 +1,64 @@ -"use client"; -import IndiceContenido from "@/components/content-index"; -import Sidebar, { SidebarLink } from "@/components/sidebar"; -import VistaComponente from "@/components/vista-componente"; -import React from "react"; +'use client'; +import IndiceContenido from '@/components/docs/content-index'; +import Sidebar, { SidebarLink } from '@/components/sidebar'; +import VistaComponente from '@/components/docs/vista-componente'; +import React from 'react'; const basicLinks: SidebarLink[] = [ - { icon: "bi-house", text: "Inicio", href: "/inicio" }, + { icon: 'bi-house', text: 'Inicio', href: '/inicio' }, { - icon: "bi-person", - text: "Perfil", - href: "/perfil", - className: "hover-bg-success", + icon: 'bi-person', + text: 'Perfil', + href: '/perfil', + className: 'hover-bg-success', }, { - icon: "bi-envelope", - text: "Mensajes", - href: "/mensajes", - className: "hover-bg-info", + icon: 'bi-envelope', + text: 'Mensajes', + href: '/mensajes', + className: 'hover-bg-info', }, { - icon: "bi-gear", - text: "Configuración", - href: "/configuracion", - className: "hover-bg-warning", + icon: 'bi-gear', + text: 'Configuración', + href: '/configuracion', + className: 'hover-bg-warning', }, { - icon: "bi-bar-chart", - text: "Reportes", - href: "/reportes", - className: "hover-bg-danger", + icon: 'bi-bar-chart', + text: 'Reportes', + href: '/reportes', + className: 'hover-bg-danger', }, ]; const onClickLinks: SidebarLink[] = [ { - icon: "bi-lightning", - text: "Acción rápida", - onClick: () => alert("¡Ejecutando acción rápida!"), - className: "hover-bg-warning text-warning", + icon: 'bi-lightning', + text: 'Acción rápida', + onClick: () => alert('¡Ejecutando acción rápida!'), + className: 'hover-bg-warning text-warning', }, { - icon: "bi-question-circle", - text: "Ayuda", - onClick: () => alert("Mostrando ayuda..."), - className: "hover-bg-info text-info", + icon: 'bi-question-circle', + text: 'Ayuda', + onClick: () => alert('Mostrando ayuda...'), + className: 'hover-bg-info text-info', }, { - icon: "bi-bell", - text: "Notificaciones", - onClick: () => alert("Mostrando notificaciones..."), - className: "hover-bg-primary text-primary", + icon: 'bi-bell', + text: 'Notificaciones', + onClick: () => alert('Mostrando notificaciones...'), + className: 'hover-bg-primary text-primary', }, ]; const renderItems: SidebarLink[] = [ { render: () => ( -
    • -
      - +
    • +
      + Componente especial
    • @@ -66,9 +66,9 @@ const renderItems: SidebarLink[] = [ }, { render: () => ( -
    • -
      - +
    • +
      + Favoritos
    • @@ -76,9 +76,9 @@ const renderItems: SidebarLink[] = [ }, { render: () => ( -
    • -
      - +
    • +
      + Alertas
    • @@ -86,9 +86,9 @@ const renderItems: SidebarLink[] = [ }, { render: () => ( -
    • -
      - +
    • +
      + Ideas
    • @@ -101,25 +101,25 @@ export default function Page() { <> -
      -

      +
      +

      Componente: Sidebar

      -

      +

      El Sidebar es un componente versátil que funciona como un menú lateral adaptable, diseñado para ser accesible tanto en dispositivos móviles como en pantallas de escritorio. Permite incluir @@ -127,43 +127,41 @@ export default function Page() { elementos renderizados dinámicamente.

      -
      +
      -
      +
      -
      - -
      +
      -
      +
      -
      +

      Contenido interactivo

      Cada enlace ejecuta una acción mediante onClick. @@ -175,20 +173,20 @@ export default function Page() { -

      +
      -
      +

      Elementos renderizados

      La propiedad render permite insertar cualquier JSX @@ -200,20 +198,20 @@ export default function Page() { -

      +
      -
      +

      Hover personalizados

      Gracias a las clases hover-bg-COLOR generadas a diff --git a/src/app/(components)/styles/page.tsx b/src/app/(components)/styles/page.tsx index 2f6330a..0635e0b 100644 --- a/src/app/(components)/styles/page.tsx +++ b/src/app/(components)/styles/page.tsx @@ -1,123 +1,125 @@ -"use client"; -import React from "react"; -import IndiceContenido from "@/components/content-index"; -import VistaComponente from "@/components/vista-componente"; +'use client'; +import React from 'react'; +import IndiceContenido from '@/components/docs/content-index'; +import VistaComponente from '@/components/docs/vista-componente'; export default function Page() { return ( <> -

      -

      Estilos

      +
      +

      Estilos

      -

      +

      Los estilos de la aplicación se basan en Bootstrap 5 y se personalizan mediante clases SCSS para mantener una apariencia coherente y flexible.

      -
      +
      -
      - +
      + Leer la documentación de .box

      div con className .box

      `} > -
      -

      +
      +

      div con className .box

      div con className .box

      `} > -
      -

      - div con className .box .active +
      +

      + div con className .box{' '} + .active

      div con className .box

      `} > -
      -

      - div con className .box .disabled +
      +

      + div con className .box{' '} + .disabled

      Gradiente desde arriba (top) con color primario

      `} > -
      +
      Gradiente desde arriba (top) con color primario
      -
      +
      Gradiente desde la derecha (right) con color success
      -
      +
      Gradiente desde abajo (bottom) con color warning
      -
      +
      Gradiente desde la izquierda (left) con color info
      -

      Ejemplo de gradiente de Bootstrap 5

      -

      +

      Ejemplo de gradiente de Bootstrap 5

      +

      Bootstrap incluye su propio estilo .bg-gradient que aplica un efecto sutil sobre el fondo.

      -
      +
      Fondo con .bg-primary.bg-gradient
      Escala 1.05
      Escala 1.15
      Escala 1.25
      `} > -
      +
      {[1, 2, 3, 4, 5].map((scale) => (
      {`scale-hover-${scale}`}
      ({(1 + scale * 0.05).toFixed(2)}x) @@ -127,33 +129,33 @@ export default function Page() { Hover primario
      Elemento activo con fondo success
      `} > -
      - {["primary", "success", "warning", "danger", "azul"].map( +
      + {['primary', 'success', 'warning', 'danger', 'azul'].map( (color) => (
      {`hover-bg-${color}`}
      - {color === "primary" && "(hover o active)"} + {color === 'primary' && '(hover o active)'}
      ) )}
      -

      +

      Ejemplo con .nav-link

      -
      - + diff --git a/src/app/(components)/table/page.tsx b/src/app/(components)/table/page.tsx index ccf4e9c..13a3d15 100644 --- a/src/app/(components)/table/page.tsx +++ b/src/app/(components)/table/page.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import Table, { Header, TableSkeleton } from '@/components/table'; -import VistaComponente from '@/components/vista-componente'; +import VistaComponente from '@/components/docs/vista-componente'; import { tableBasicExample, tableSkeletonExample, @@ -12,10 +12,10 @@ import { tableAutoPagination } from '@/snippets/table/table-auto-pagination'; import { tableCustomPagination } from '@/snippets/table/table-custom-pagination'; import { tableCustomCellRender } from '@/snippets/table/table-custom-cell-render'; import { tableColumnWidth } from '@/snippets/table/table-column-width'; -import { CodeBlock } from '@/components/code-block'; +import { CodeBlock } from '@/components/docs/code-block'; import Input from '@/components/input'; import { tableFilter } from '@/snippets/table/table-filter'; -import IndiceContenido from '@/components/content-index'; +import IndiceContenido from '@/components/docs/content-index'; export default function Page() { const headers: Header<{ diff --git a/src/app/(components)/tabs/page.tsx b/src/app/(components)/tabs/page.tsx index c6df03d..ce42990 100644 --- a/src/app/(components)/tabs/page.tsx +++ b/src/app/(components)/tabs/page.tsx @@ -1,44 +1,74 @@ -"use client"; +'use client'; -import { CodeBlock } from "@/components/code-block"; -import IndiceContenido from "@/components/content-index"; -import Tabs from "@/components/tabs"; -import VistaComponente from "@/components/vista-componente"; +import { CodeBlock } from '@/components/docs/code-block'; +import IndiceContenido from '@/components/docs/content-index'; +import Tabs from '@/components/tabs'; +import VistaComponente from '@/components/docs/vista-componente'; export default function Page() { return ( <> -
      -

      +
      +

      🧩 Componente: Tabs

      -

      - El componente <Tabs /> permite organizar contenido - en pestañas, ofreciendo opciones de estilos y soporte para pestañas - desactivadas. -
      - El tiempo de animacion de las pestañas es de 0.3s. pero se puede - modificar en el archivo src/styles/sass/_tabs.scss +

      + Inicio

      }, + { id: 'profile-4', title: 'Perfil', content:

      Perfil

      }, + { + id: 'settings-4', + title: 'Configuraciones', + content:

      Configuraciones

      , + }, + ]} + /> + Contenido de inicio

      , + }, + { + id: 'profile-3', + title: 'Perfil', + content:

      Contenido del perfil

      , + }, + ]} + /> +
      + +

      + El componente <Tabs /> organiza contenido en + pestañas, con opciones de estilo (default y{' '} + box), soporte para pestañas deshabilitadas y pestaña + activa inicial via + defaultActiveTab.

      -
      +
      Contenido de inicio

      }, @@ -50,45 +80,45 @@ export default function Page() { Contenido de inicio

      , }, { - id: "profile-1", - title: "Perfil", + id: 'profile-1', + title: 'Perfil', content:

      Contenido del perfil

      , }, { - id: "settings-1", - title: "Configuraciones", - content:

      Contenido de configuraciones

      , + id: 'settings-1', + title: 'Configuraciones', + content:

      Configuraciones

      , }, ]} />
      Contenido de inicio

      }, - { id: "disabled", title: "Desactivado", content:

      No seleccionable

      , disabled: true }, + { id: "home", title: "Inicio", content:

      ...

      }, + { id: "disabled", title: "Desactivado", content:

      ...

      , disabled: true }, ] />`} > Contenido de inicio

      , }, { - id: "disabled-2", - title: "Desactivado", + id: 'disabled-2', + title: 'Desactivado', content:

      No seleccionable

      , disabled: true, }, @@ -97,49 +127,64 @@ export default function Page() {
      Contenido de inicio

      }, - { id: "profile", title: "Perfil", content:

      Contenido del perfil

      }, - ] style="box" + tabs=[ + { id: "home", title: "Inicio", content:

      ...

      }, + { id: "profile", title: "Perfil", content:

      ...

      }, + ] />`} > Contenido de inicio

      , }, { - id: "profile-3", - title: "Perfil", + id: 'profile-3', + title: 'Perfil', content:

      Contenido del perfil

      , }, - { - id: "settings-3", - title: "Configuraciones", - content:

      Contenido del perfil

      , - disabled: true, - }, + ]} + /> +
      + + ...

      }, + { id: "profile", title: "Perfil", content:

      ...

      }, + ] +/>`} + > + Inicio

      }, + { id: 'profile-4', title: 'Perfil', content:

      Perfil

      }, ]} />
      {/* PROPS */} -
      -

      ⚙️ Props del componente

      - +
      +

      ⚙️ Props del componente

      +
      - - - + + + @@ -150,14 +195,14 @@ export default function Page() { - + @@ -167,49 +212,82 @@ export default function Page() { - + - + + + +
      PropTipoDescripciónPropTipoDescripción
      Tab[] Lista de pestañas con ID, título y contenido.Lista de pestañas con id, título y contenido.
      style? - "default" | "box" + "default" | "box" Estilo de las pestañas.
      - {"{ container?: string; tab?: string; content?: string; }"} + {'{ container?: string; tab?: string; content?: string; }'} - Clases CSS personalizables para diferentes partes del - componente. - Clases CSS personalizables.
      - Tab.id + defaultActiveTab? string Identificador único de la pestaña. + ID de la pestaña que se muestra inicialmente si no está + deshabilitada. +
      + +

      + Props de cada pestaña (Tab) +

      + + + + + + + + + + + + + - + + + + + + - + - +
      PropTipoDescripción
      + id + + string + Identificador único.
      - Tab.title + title string | JSX.Element Título de la pestaña.Título mostrado en la pestaña.
      - Tab.content + titleText? + + string + Texto alternativo para tooltips si el título se trunca.
      + content JSX.Element Contenido dentro de la pestaña.Contenido renderizado al activar la pestaña.
      - Tab.disabled? + disabled? boolean Si la pestaña debe estar deshabilitada.Deshabilita la pestaña.
      diff --git a/src/app/page.tsx b/src/app/page.tsx index b14bd40..06eb5a6 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,6 +1,6 @@ 'use client'; -import ComponentCard from '@/components/component-card'; +import ComponentCard from '@/components/docs/component-card'; import Image from 'next/image'; import React from 'react'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; @@ -46,7 +46,7 @@ export default function Page() { customStyle={{ borderRadius: '10px' }} > {`npm i bootstrap bootstrap-icons -npm i --save-dev sass +npm i --save-dev sass@1.32.13 npm i --save-dev @types/bootstrap`} @@ -126,6 +126,13 @@ import BootstrapClient from "@/components/bootstrap-client";`}
      +
      + +

      diff --git a/src/components/code-block.tsx b/src/components/docs/code-block.tsx similarity index 100% rename from src/components/code-block.tsx rename to src/components/docs/code-block.tsx diff --git a/src/components/component-card.tsx b/src/components/docs/component-card.tsx similarity index 100% rename from src/components/component-card.tsx rename to src/components/docs/component-card.tsx diff --git a/src/components/content-index.tsx b/src/components/docs/content-index.tsx similarity index 100% rename from src/components/content-index.tsx rename to src/components/docs/content-index.tsx diff --git a/src/components/vista-componente.tsx b/src/components/docs/vista-componente.tsx similarity index 97% rename from src/components/vista-componente.tsx rename to src/components/docs/vista-componente.tsx index b8f75bf..aa8fd6d 100644 --- a/src/components/vista-componente.tsx +++ b/src/components/docs/vista-componente.tsx @@ -1,5 +1,5 @@ import { CodeBlock } from './code-block'; -import Button from './button'; +import Button from '../button'; import { useState } from 'react'; interface VistaComponenteProps { diff --git a/src/components/progress-bar.tsx b/src/components/progress-bar.tsx new file mode 100644 index 0000000..cd0ef72 --- /dev/null +++ b/src/components/progress-bar.tsx @@ -0,0 +1,43 @@ +import React from 'react'; + +interface EstatusProps { + estados: string[]; + estadoActivo: number; +} + +export default function ProgressBar({ estados, estadoActivo }: EstatusProps) { + return ( + <> +
      + {estados.map((label, index) => ( +
      + {index + 1} + {label} +
      + ))} +
      +
      +
      + {estadoActivo + 1} + {estados[estadoActivo]} +
      +
      + + ); +} + +function EstatusEskeleton() { + return ( +
      + Estatus: +
      + +
      +
      + ); +} + +export { EstatusEskeleton }; diff --git a/src/components/tabs.tsx b/src/components/tabs.tsx index 2be6821..2ae35de 100644 --- a/src/components/tabs.tsx +++ b/src/components/tabs.tsx @@ -1,48 +1,61 @@ -import React, { useState, JSX } from "react"; +import React, { useState, JSX } from 'react'; interface Tab { id: string; title: string | JSX.Element; + titleText?: string; content: JSX.Element; disabled?: boolean; } - interface TabsProps { tabs: Tab[]; - style?: "default" | "box"; + style?: 'default' | 'box'; className?: { container?: string; tab?: string; content?: string; }; + defaultActiveTab?: string; } export default function Tabs({ tabs, - style = "default", + style = 'default', className, + defaultActiveTab, }: TabsProps) { - const [activeTab, setActiveTab] = useState(tabs[0]?.id || ""); + const [activeTab, setActiveTab] = useState(() => { + // 1) si se pasó defaultActiveTab y existe en tabs (y no está disabled), úsala + if (defaultActiveTab) { + const found = tabs.find((t) => t.id === defaultActiveTab && !t.disabled); + if (found) return found.id; + } + // 2) si no, buscar el primer tab habilitado + const firstEnabled = tabs.find((t) => !t.disabled); + return firstEnabled ? firstEnabled.id : tabs[0]?.id || ''; + }); return ( <> -
        +
          {tabs.map((tab) => (
        • ))}
        -
        +
        {tabs.map((tab) => (
        {activeTab === tab.id && tab.content} diff --git a/src/styles/sass/_progress-bar.scss b/src/styles/sass/_progress-bar.scss new file mode 100644 index 0000000..cb09728 --- /dev/null +++ b/src/styles/sass/_progress-bar.scss @@ -0,0 +1,57 @@ +.track { + position: relative; + background-color: #cecece; + height: 7px; + display: flex; + color: #fff; + border-radius: 10px; + + .step { + flex-grow: 1; + margin-top: -18px; + text-align: center; + position: relative; + + .icon { + display: inline-block; + width: 40px; + height: 40px; + line-height: 40px; + position: relative; + border-radius: 100%; + background: #cecece; + } + + .text { + color: #000; + display: block; + margin-top: 7px; + } + + &.active::before { + background: #007bff; + height: 7px; + position: absolute; + content: ''; + width: 100%; + left: 0; + top: 18px; + } + + &.active .icon { + background: #007bff; + color: #fff; + font-weight: bold; + } + } +} + +.heatmap-legend { + width: 40px; + height: 20px; + display: flex; + align-items: center; + justify-content: center; + font-size: 10px; + border: 1px solid #dee2e6; +} diff --git a/src/styles/sass/_tabs.scss b/src/styles/sass/_tabs.scss index b864ca3..318231a 100644 --- a/src/styles/sass/_tabs.scss +++ b/src/styles/sass/_tabs.scss @@ -1,5 +1,5 @@ .tab-pane.fade { - transition: opacity 10s linear !important; + transition: opacity 0.4s linear !important; } .nav-tabs.style-box { diff --git a/src/styles/sass/bootstrap.scss b/src/styles/sass/bootstrap.scss index e4cbffe..b56655b 100644 --- a/src/styles/sass/bootstrap.scss +++ b/src/styles/sass/bootstrap.scss @@ -27,6 +27,7 @@ $theme-colors: map-merge($theme-colors, $custom-colors); @import 'sidebar'; @import 'hover'; @import 'tabs'; +@import 'progress-bar'; //Add additional custom code here