@axzydev/axzy_ui_system 1.5.0 → 1.5.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.
@@ -65,6 +65,26 @@ export const TabsShowcase = () => {
65
65
  />
66
66
  </>
67
67
  }
68
+ doc={{
69
+ summary:
70
+ "Navegación por pestañas con dos variantes visuales (`line` y `pill`) que gestiona internamente cuál está activa.",
71
+ examples: [
72
+ '<ITTabs items={[{ id: "general", label: "General", content: <GeneralPanel /> }]} />',
73
+ '<ITTabs variant="pill" defaultActiveId="security" onChange={setActive} items={tabs} />',
74
+ ],
75
+ props: [
76
+ { name: "items", type: "ITTabItem[]", required: true, description: "Pestañas a renderizar: { id, label, content, icon?, disabled? }." },
77
+ { name: "defaultActiveId", type: "string", default: "primer item", description: "`id` de la pestaña activa al montar." },
78
+ { name: "onChange", type: "(id: string) => void", description: "Se dispara al cambiar de pestaña, con el nuevo `id`." },
79
+ { name: "variant", type: '"line" | "pill"', default: '"line"', description: "`line` = indicador inferior; `pill` = fondo redondeado." },
80
+ { name: "className", type: "string", default: '""', description: "Clases adicionales de la fila de pestañas." },
81
+ { name: "containerClassName", type: "string", default: '""', description: "Clases adicionales del contenedor externo." },
82
+ ],
83
+ notes: [
84
+ "Estado no controlado: no existe `activeId`; si el `id` activo desaparece de `items`, el contenido queda vacío.",
85
+ 'Los botones son `<button>` nativos, pero sin roles de pestañas (`role="tab"`, `aria-selected`) ni navegación con flechas.',
86
+ ],
87
+ }}
68
88
  />
69
89
  );
70
90
  };
@@ -115,6 +135,35 @@ export const StepperShowcase = () => {
115
135
  </div>
116
136
  </>
117
137
  }
138
+ doc={{
139
+ summary:
140
+ "Asistente paso a paso (wizard) con indicador de progreso, panel de contenido y botones Atrás / Siguiente (Finalizar en el último paso).",
141
+ description:
142
+ "El paso activo es controlado (`currentStep`): cada paso define su propio contenido y el panel lo monta con transición.",
143
+ examples: [
144
+ "<ITStepper steps={steps} currentStep={step} onStepChange={setStep} onFinish={save} />",
145
+ '<ITStepper steps={steps} currentStep={0} useIcons scrollableContent maxContentHeight="320px" />',
146
+ ],
147
+ props: [
148
+ { name: "steps", type: "Step[]", required: true, description: "Pasos del flujo: { label, content, icon? }." },
149
+ { name: "currentStep", type: "number", required: true, description: "Índice base 0 del paso activo." },
150
+ { name: "onFinish", type: "() => void", description: "Se llama al pulsar «Finalizar» en el último paso." },
151
+ { name: "onStepChange", type: "(step: number) => void", description: "Se dispara en cada cambio de paso, con el nuevo índice." },
152
+ { name: "allowClickToJump", type: "boolean", default: "true", description: "Permite saltar a pasos completados o al actual desde sus indicadores." },
153
+ { name: "useIcons", type: "boolean", default: "false", description: "Muestra el icono de cada paso en lugar del número." },
154
+ { name: "disableNext", type: "boolean", default: "false", description: "Deshabilita «Siguiente» / «Finalizar»." },
155
+ { name: "scrollableContent", type: "boolean", default: "false", description: "Hace desplazable el panel de contenido." },
156
+ { name: "maxContentHeight", type: "string", default: '"400px"', description: "Altura máxima del panel desplazable (valor CSS)." },
157
+ { name: "color", type: "string", default: '"primary"', description: "Color semántico del tema para paso activo y botones; acepta también un color crudo." },
158
+ { name: "containerClassName", type: "string", description: "Clases adicionales del contenedor externo." },
159
+ { name: "stepClassName", type: "string", description: "Clases adicionales del panel de contenido." },
160
+ ],
161
+ notes: [
162
+ "«Atrás» se deshabilita en el primer paso; en el último, «Siguiente» pasa a «Finalizar» y dispara `onFinish`.",
163
+ "El contador «Paso N de M» se oculta por debajo del breakpoint `sm`.",
164
+ 'El panel usa `role="region"` con `aria-labelledby` y los indicadores `aria-current="step"`.',
165
+ ],
166
+ }}
118
167
  />
119
168
  );
120
169
  };
@@ -162,6 +211,32 @@ export const PaginationShowcase = () => {
162
211
  />
163
212
  </>
164
213
  }
214
+ doc={{
215
+ summary:
216
+ "Paginador con anterior/siguiente, números de página (con elipsis si hay muchas) y selector opcional de filas por página.",
217
+ examples: [
218
+ "<ITPagination currentPage={page} totalPages={10} onPageChange={setPage} />",
219
+ '<ITPagination currentPage={page} totalPages={20} onPageChange={setPage} color="secondary" siblingCount={2} />',
220
+ "<ITPagination currentPage={page} totalPages={20} onPageChange={setPage} itemsPerPageOptions={[10, 25, 50]} itemsPerPage={10} onItemsPerPageChange={setSize} totalItems={95} />",
221
+ ],
222
+ props: [
223
+ { name: "currentPage", type: "number", required: true, description: "Página activa (indexada en 1)." },
224
+ { name: "totalPages", type: "number", required: true, description: "Número total de páginas." },
225
+ { name: "onPageChange", type: "(page: number) => void", required: true, description: "Se dispara al pulsar una página o anterior/siguiente." },
226
+ { name: "siblingCount", type: "number", default: "1", description: "Páginas visibles antes y después de la actual." },
227
+ { name: "color", type: "string", default: '"primary"', description: "Color semántico del tema (primary, secondary, success, danger, warning, info, purple) o un valor crudo." },
228
+ { name: "className", type: "string", description: "Clases adicionales del contenedor." },
229
+ { name: "itemsPerPageOptions", type: "number[]", description: "Opciones del selector de filas por página; activa la variante con resumen." },
230
+ { name: "itemsPerPage", type: "number", description: "Valor actual de filas por página. Requerido junto a `itemsPerPageOptions`." },
231
+ { name: "onItemsPerPageChange", type: "(value: number) => void", description: "Se dispara al cambiar las filas por página." },
232
+ { name: "totalItems", type: "number", description: "Total de elementos; alimenta el resumen «X - Y de Z»." },
233
+ ],
234
+ notes: [
235
+ "Se auto-oculta (devuelve `null`) si `currentPage === 0` o si, sin selector, el rango tiene menos de 2 páginas.",
236
+ "La variante con `itemsPerPageOptions` monta un `ITSelect` y el resumen «X - Y de Z», que solo aparece si se pasa `totalItems`.",
237
+ 'Se envuelve en `<nav aria-label>`; anterior/siguiente usan `role="button"` con `aria-disabled` en los extremos.',
238
+ ],
239
+ }}
165
240
  />
166
241
  );
167
242
  };
@@ -197,6 +272,25 @@ export const TripleFilterShowcase = () => {
197
272
  <p className="text-slate-500">{t("showcase.nav.tripleFilterHint")}</p>
198
273
  </div>
199
274
  }
275
+ doc={{
276
+ summary:
277
+ "Filtro segmentado genérico estilo pill: solo una opción está activa y admite valores `string` o `boolean`.",
278
+ examples: [
279
+ '<ITTripleFilter value={filter} onChange={setFilter} options={[{ label: "Todos", value: "all" }, { label: "Activos", value: "active" }]} />',
280
+ '<ITTripleFilter value={onlyActive} onChange={setOnlyActive} options={[{ label: "Sí", value: true }, { label: "No", value: false }]} color="success" />',
281
+ ],
282
+ props: [
283
+ { name: "value", type: "T", required: true, description: "Valor seleccionado; debe coincidir con uno de `options[].value`." },
284
+ { name: "onChange", type: "(value: T) => void", required: true, description: "Se dispara al elegir otra opción, con el nuevo valor." },
285
+ { name: "options", type: "ITTripleFilterOption<T>[]", required: true, description: "Opciones a renderizar: { label, value }." },
286
+ { name: "color", type: "ColorsTypes", default: '"primary"', description: "Color del botón activo (primary, secondary, success, danger, warning, info, purple, error, gray)." },
287
+ { name: "className", type: "string", description: "Clases adicionales del contenedor." },
288
+ ],
289
+ notes: [
290
+ "Genérico sobre `T extends string | boolean`, así que el mismo componente sirve para estados y para banderas true/false.",
291
+ "Los botones no exponen `aria-pressed` ni `role`, por lo que el estado activo no se anuncia a lectores de pantalla.",
292
+ ],
293
+ }}
200
294
  />
201
295
  );
202
296
  };
@@ -219,7 +219,7 @@ export const PageHeaderShowcase = () => {
219
219
  <ITStack spacing={6}>
220
220
  {/* 1. Team management — full header + search + filter bar + user rows */}
221
221
  <div>
222
- <h3 className="mb-3 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.pages.galleryTeamManagement")}</h3>
222
+ <h3 className="mb-3 w-fit border-l-2 border-primary-700 pl-2.5 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-700 dark:border-primary-500 dark:text-slate-200">{t("showcase.pages.galleryTeamManagement")}</h3>
223
223
  <div className="overflow-hidden rounded-[10px] border border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-950">
224
224
  <div className="p-5 pb-3">
225
225
  <ITPageHeader
@@ -282,7 +282,7 @@ export const PageHeaderShowcase = () => {
282
282
 
283
283
  {/* 2. Detail page — back + breadcrumbs + back button + save/cancel */}
284
284
  <div>
285
- <h3 className="mb-3 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.pages.galleryDetailEdit")}</h3>
285
+ <h3 className="mb-3 w-fit border-l-2 border-primary-700 pl-2.5 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-700 dark:border-primary-500 dark:text-slate-200">{t("showcase.pages.galleryDetailEdit")}</h3>
286
286
  <div className="overflow-hidden rounded-[10px] border border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-950">
287
287
  <div className="p-5 pb-3">
288
288
  <ITPageHeader
@@ -319,7 +319,7 @@ export const PageHeaderShowcase = () => {
319
319
 
320
320
  {/* 3. Dashboard header — icon + title + desc + date range + refresh */}
321
321
  <div>
322
- <h3 className="mb-3 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.pages.galleryDashboard")}</h3>
322
+ <h3 className="mb-3 w-fit border-l-2 border-primary-700 pl-2.5 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-700 dark:border-primary-500 dark:text-slate-200">{t("showcase.pages.galleryDashboard")}</h3>
323
323
  <div className="overflow-hidden rounded-[10px] border border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-950">
324
324
  <div className="p-5">
325
325
  <ITPageHeader
@@ -345,7 +345,7 @@ export const PageHeaderShowcase = () => {
345
345
 
346
346
  {/* 4. Settings header — no icon, no breadcrumbs, just title + desc + save */}
347
347
  <div>
348
- <h3 className="mb-3 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.pages.gallerySettingsPrefs")}</h3>
348
+ <h3 className="mb-3 w-fit border-l-2 border-primary-700 pl-2.5 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-700 dark:border-primary-500 dark:text-slate-200">{t("showcase.pages.gallerySettingsPrefs")}</h3>
349
349
  <div className="overflow-hidden rounded-[10px] border border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-950">
350
350
  <div className="p-5">
351
351
  <ITPageHeader
@@ -364,7 +364,7 @@ export const PageHeaderShowcase = () => {
364
364
 
365
365
  {/* 5. Users list — icon + breadcrumbs + search in actions + add button */}
366
366
  <div>
367
- <h3 className="mb-3 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.pages.galleryUsersList")}</h3>
367
+ <h3 className="mb-3 w-fit border-l-2 border-primary-700 pl-2.5 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-700 dark:border-primary-500 dark:text-slate-200">{t("showcase.pages.galleryUsersList")}</h3>
368
368
  <div className="overflow-hidden rounded-[10px] border border-slate-200 bg-white dark:border-slate-800 dark:bg-slate-950">
369
369
  <div className="p-5">
370
370
  <ITPageHeader
@@ -389,6 +389,30 @@ export const PageHeaderShowcase = () => {
389
389
  </div>
390
390
  </ITStack>
391
391
  }
392
+ doc={{
393
+ summary: "Barra de título de página con breadcrumbs, descripción, botón de volver y acciones.",
394
+ description:
395
+ "Es la cabecera que ITPage delega por defecto. Cuando hay breadcrumbs o backAction dibuja una fila superior con el botón de volver y las migas a la izquierda, y mueve `actions` a esa fila; sin fila superior las acciones quedan en la fila del título.",
396
+ examples: [
397
+ '<ITPageHeader title="Team members" description="Manage invitations, roles and permissions" />',
398
+ '<ITPageHeader\n title="Usuarios"\n icon={<FaUsers size={20} />}\n iconColor="#6366f1"\n breadcrumbs={[{ label: "Admin", href: "#" }, { label: "Usuarios" }]}\n backAction={() => history.back()}\n actions={<ITButton label="Invitar" size="sm" />}\n/>',
399
+ '<ITPageHeader title="Reportes" actions={<ITButton label="Exportar" variant="outlined" size="sm" />} />',
400
+ ],
401
+ props: [
402
+ { name: "title", type: "string", required: true, description: "Título principal, renderizado como <h1>." },
403
+ { name: "description", type: "string", description: "Texto descriptivo bajo el título." },
404
+ { name: "breadcrumbs", type: "ITBreadcrumbItem[]", description: "Migas de pan ({ label, href?, onClick? }); el último ítem se pinta como texto plano." },
405
+ { name: "actions", type: "ReactNode", description: "Botones o elementos alineados a la derecha." },
406
+ { name: "backAction", type: "() => void", description: "Se dispara al pulsar el botón de volver; su presencia basta para mostrar la fila superior." },
407
+ { name: "icon", type: "ReactNode", description: "Icono mostrado dentro del recuadro redondo junto al título." },
408
+ { name: "iconColor", type: "string", description: "Color CSS aplicado al recuadro del icono (style.color)." },
409
+ { name: "className", type: "string", description: "Clases adicionales del contenedor." },
410
+ ],
411
+ notes: [
412
+ "El recuadro del icono (w-12 h-12 redondo) no se renderiza en aspecto flat (`useITFlatAppearance()`); con ese aspecto el título se reduce y `iconColor` deja de tener efecto.",
413
+ "El botón de volver es un círculo de 9×9 con aria-label \"Volver\" (i18n `pageHeader.back`).",
414
+ ],
415
+ }}
392
416
  />
393
417
  );
394
418
  };
@@ -712,7 +736,7 @@ export const PageShowcase = () => {
712
736
  <ITStack spacing={6}>
713
737
  {/* 1. Users list with ITTable */}
714
738
  <div>
715
- <h3 className="mb-3 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.pages.galleryUsersTable")}</h3>
739
+ <h3 className="mb-3 w-fit border-l-2 border-primary-700 pl-2.5 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-700 dark:border-primary-500 dark:text-slate-200">{t("showcase.pages.galleryUsersTable")}</h3>
716
740
  <div className="overflow-hidden rounded-[10px] border border-slate-200 dark:border-slate-800">
717
741
  <ITPage
718
742
  horizontalPadding={hPaddingValue}
@@ -740,7 +764,7 @@ export const PageShowcase = () => {
740
764
 
741
765
  {/* 2. Product detail */}
742
766
  <div>
743
- <h3 className="mb-3 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.pages.galleryProductDetail")}</h3>
767
+ <h3 className="mb-3 w-fit border-l-2 border-primary-700 pl-2.5 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-700 dark:border-primary-500 dark:text-slate-200">{t("showcase.pages.galleryProductDetail")}</h3>
744
768
  <div className="overflow-hidden rounded-[10px] border border-slate-200 dark:border-slate-800">
745
769
  <ITPage
746
770
  horizontalPadding={hPaddingValue}
@@ -788,7 +812,7 @@ export const PageShowcase = () => {
788
812
 
789
813
  {/* 3. Edit profile form */}
790
814
  <div>
791
- <h3 className="mb-3 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.pages.galleryEditProfile")}</h3>
815
+ <h3 className="mb-3 w-fit border-l-2 border-primary-700 pl-2.5 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-700 dark:border-primary-500 dark:text-slate-200">{t("showcase.pages.galleryEditProfile")}</h3>
792
816
  <div className="overflow-hidden rounded-[10px] border border-slate-200 dark:border-slate-800">
793
817
  <ITPage
794
818
  horizontalPadding={hPaddingValue}
@@ -839,7 +863,7 @@ export const PageShowcase = () => {
839
863
 
840
864
  {/* 4. Orders with table */}
841
865
  <div>
842
- <h3 className="mb-3 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.pages.galleryOrdersTable")}</h3>
866
+ <h3 className="mb-3 w-fit border-l-2 border-primary-700 pl-2.5 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-700 dark:border-primary-500 dark:text-slate-200">{t("showcase.pages.galleryOrdersTable")}</h3>
843
867
  <div className="overflow-hidden rounded-[10px] border border-slate-200 dark:border-slate-800">
844
868
  <ITPage
845
869
  horizontalPadding={hPaddingValue}
@@ -892,7 +916,7 @@ export const PageShowcase = () => {
892
916
 
893
917
  {/* 5. Settings with tabs */}
894
918
  <div>
895
- <h3 className="mb-3 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.pages.gallerySettings")}</h3>
919
+ <h3 className="mb-3 w-fit border-l-2 border-primary-700 pl-2.5 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-700 dark:border-primary-500 dark:text-slate-200">{t("showcase.pages.gallerySettings")}</h3>
896
920
  <div className="overflow-hidden rounded-[10px] border border-slate-200 dark:border-slate-800">
897
921
  <ITPage
898
922
  horizontalPadding={hPaddingValue}
@@ -957,6 +981,44 @@ export const PageShowcase = () => {
957
981
  </div>
958
982
  </ITStack>
959
983
  }
984
+ doc={{
985
+ summary: "Plantilla de página: ancho máximo, cabecera opcional (ITPageHeader) y estados integrados de carga, error y vacío.",
986
+ description:
987
+ "Envuelve el contenido con el ancho y el padding de página y, si hay algo que mostrar, delega la cabecera en ITPageHeader. Los tres estados sustituyen a los children y también conservan la cabecera.",
988
+ examples: [
989
+ '<ITPage title="Team members" description="Manage your organization workspace" actions={<ITButton label="Invite" size="sm" />}>\n <ITTable columns={columns} data={users} />\n</ITPage>',
990
+ '<ITPage title="Reportes" loading={loading} error={error} errorTitle="Error de carga" onRetry={refetch} maxWidth="6xl">\n <ReportBody />\n</ITPage>',
991
+ '<ITPage title="Tablero" horizontalPadding="px-0">\n <div>Contenido a sangre</div>\n</ITPage>',
992
+ ],
993
+ props: [
994
+ { name: "title", type: "string", description: "Título de la página, se pasa a la cabecera." },
995
+ { name: "description", type: "string", description: "Descripción bajo el título." },
996
+ { name: "breadcrumbs", type: "ITBreadcrumbItem[]", description: "Migas de pan para dar contexto de navegación." },
997
+ { name: "actions", type: "ReactNode", description: "Botones de acción de la cabecera." },
998
+ { name: "backAction", type: "() => void", description: "Callback del botón de volver." },
999
+ { name: "icon", type: "ReactNode", description: "Icono opcional junto al título." },
1000
+ { name: "iconColor", type: "string", description: "Color CSS del icono." },
1001
+ { name: "loading", type: "boolean", default: "false", description: "Muestra placeholders de esqueleto (tres skeletons rectangulares)." },
1002
+ { name: "error", type: "string | null", default: "null", description: "Mensaje del estado de error; dibuja un ITEmptyState con botón de reintento si hay onRetry." },
1003
+ { name: "errorTitle", type: "string", default: 'i18n common.error ("Error")', description: "Título del estado de error." },
1004
+ { name: "errorActionLabel", type: "string", default: 'i18n common.retry ("Reintentar")', description: "Etiqueta del botón de reintento." },
1005
+ { name: "onRetry", type: "() => void", description: "Callback del botón de reintento; solo se pinta si hay error." },
1006
+ { name: "empty", type: "boolean", default: "false", description: "Muestra el estado vacío." },
1007
+ { name: "emptyTitle", type: "string", default: 'i18n common.noData ("Sin datos")', description: "Título del estado vacío." },
1008
+ { name: "emptyDescription", type: "string", default: 'i18n common.empty ("No hay información para mostrar")', description: "Descripción del estado vacío." },
1009
+ { name: "emptyAction", type: "ReactNode", description: "Acción personalizada del estado vacío." },
1010
+ { name: "children", type: "ReactNode", required: true, description: "Contenido renderizado dentro del wrapper." },
1011
+ { name: "maxWidth", type: '"2xl" | "3xl" | "4xl" | "5xl" | "6xl" | "7xl"', default: '"7xl"', description: "Ancho máximo del contenido." },
1012
+ { name: "noPadding", type: "boolean", default: "false", description: "Quita el padding por defecto y gana sobre horizontalPadding (también omite el py-6)." },
1013
+ { name: "horizontalPadding", type: "string", default: '"px-4 sm:px-6 lg:px-8"', description: "Clases Tailwind del gutter horizontal; debe ser un literal que Tailwind pueda escanear." },
1014
+ { name: "className", type: "string", description: "Clases adicionales del wrapper." },
1015
+ ],
1016
+ notes: [
1017
+ "Prioridad de estados: loading > error > empty; si ninguno aplica se renderizan los children. La cabecera se incluye en los cuatro casos si hay título, descripción, breadcrumbs, acciones, backAction o icono.",
1018
+ "Con noPadding se omiten a la vez el gutter horizontal y el py-6; horizontalPadding montado en runtime no llega al CSS generado por Tailwind, así que pásalo siempre literal.",
1019
+ "maxWidth se compone como `max-w-${maxWidth}` en runtime; los literales max-w-2xl…max-w-7xl están en el código fuente y Tailwind los genera.",
1020
+ ],
1021
+ }}
960
1022
  />
961
1023
  );
962
1024
  };