@axzydev/axzy_ui_system 1.2.8 → 1.2.11
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 +109 -51
- package/dist/index.cjs +141 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +141 -5
- package/dist/index.d.ts +141 -5
- package/dist/index.js +141 -73
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/snippets/axzy-ui-system.code-snippets +547 -0
- package/src/App.tsx +43 -33
- package/src/components/avatar/avatar.props.ts +12 -1
- package/src/components/avatar/avatar.stories.tsx +19 -0
- package/src/components/avatar/avatar.tsx +26 -3
- package/src/components/confirm-dialog/confirm-dialog.tsx +1 -1
- package/src/components/data-table/dataTable.props.ts +10 -0
- package/src/components/data-table/dataTable.tsx +24 -13
- package/src/components/date-picker/datePicker.tsx +1 -1
- package/src/components/dialog/dialog.tsx +2 -1
- package/src/components/drawer/drawer.tsx +1 -1
- package/src/components/dropfile/dropfile.props.ts +6 -0
- package/src/components/dropfile/dropfile.tsx +51 -16
- package/src/components/layout/layout.tsx +1 -1
- package/src/components/navbar/navbar.tsx +2 -2
- package/src/components/popover/popover.tsx +1 -1
- package/src/components/search-select/search-select.tsx +4 -4
- package/src/components/select/select.tsx +6 -8
- package/src/components/sidebar/sidebar.tsx +15 -15
- package/src/components/stepper/stepper.props.ts +4 -0
- package/src/components/table/table.props.ts +21 -3
- package/src/components/table/table.tsx +24 -13
- package/src/components/theme-provider/themeProvider.props.ts +21 -3
- package/src/components/time-picker/timePicker.tsx +1 -1
- package/src/components/toast/toast.tsx +1 -1
- package/src/components/tooltip/tooltip.tsx +1 -1
- package/src/components/topbar/topbar.tsx +1 -1
- package/src/dev.css +1 -1
- package/src/hooks/useClickOutside.ts +8 -0
- package/src/hooks/useTableState.ts +5 -2
- package/src/index.css +1 -1
- package/src/showcases/GettingStartedShowcase.tsx +207 -0
- package/src/showcases/HomeShowcase.tsx +95 -3
- package/src/theme/theme.ts +21 -0
- package/src/types/field.types.ts +70 -7
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { FaNpm, FaReact, FaCheck } from "react-icons/fa";
|
|
2
|
+
import { SiTailwindcss, SiTypescript, SiVite } from "react-icons/si";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import ITBadget from "../components/badget/badget";
|
|
5
|
+
import ITButton from "../components/button/button";
|
|
6
|
+
import ITCard from "../components/card/card";
|
|
7
|
+
import ITDivider from "../components/divider/divider";
|
|
8
|
+
import ITFlex from "../components/flex/flex";
|
|
9
|
+
import ITGrid from "../components/grid/grid";
|
|
10
|
+
import ITStack from "../components/stack/stack";
|
|
11
|
+
import ITText from "../components/text/text";
|
|
12
|
+
|
|
13
|
+
const CopyButton = ({ text }: { text: string }) => {
|
|
14
|
+
const [copied, setCopied] = useState(false);
|
|
15
|
+
return (
|
|
16
|
+
<ITButton
|
|
17
|
+
variant="text"
|
|
18
|
+
color="gray"
|
|
19
|
+
size="small"
|
|
20
|
+
onClick={() => { navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 2000); }}
|
|
21
|
+
>
|
|
22
|
+
<ITFlex align="center" gap={1.5}>
|
|
23
|
+
{copied ? <FaCheck size={10} className="text-emerald-400" /> : <FaNpm size={10} />}
|
|
24
|
+
{copied ? "Copiado" : "Copiar"}
|
|
25
|
+
</ITFlex>
|
|
26
|
+
</ITButton>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const CodeBlock = ({ code, filename, color }: { code: string; filename?: string; color?: string }) => (
|
|
31
|
+
<div className="overflow-hidden rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900">
|
|
32
|
+
{filename && (
|
|
33
|
+
<div className={`px-4 py-2 border-b border-slate-200 dark:border-slate-700 ${color || "bg-slate-50 dark:bg-slate-800/80"}`}>
|
|
34
|
+
<ITText as="span" className="!text-xs !font-mono !text-slate-400">{filename}</ITText>
|
|
35
|
+
</div>
|
|
36
|
+
)}
|
|
37
|
+
<div className="relative bg-slate-950">
|
|
38
|
+
<pre className="p-4 text-xs font-mono overflow-x-auto leading-relaxed text-slate-200">
|
|
39
|
+
<code>{code}</code>
|
|
40
|
+
</pre>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const codeFileColors = [
|
|
46
|
+
"bg-emerald-50 dark:bg-emerald-950/30",
|
|
47
|
+
"bg-blue-50 dark:bg-blue-950/30",
|
|
48
|
+
"bg-cyan-50 dark:bg-cyan-950/30",
|
|
49
|
+
"bg-violet-50 dark:bg-violet-950/30",
|
|
50
|
+
"bg-amber-50 dark:bg-amber-950/30",
|
|
51
|
+
"bg-rose-50 dark:bg-rose-950/30",
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
const stepStyles = [
|
|
55
|
+
{ iconBg: "bg-emerald-100 dark:bg-emerald-950/40 text-emerald-600 dark:text-emerald-400" },
|
|
56
|
+
{ iconBg: "bg-blue-100 dark:bg-blue-950/40 text-blue-600 dark:text-blue-400" },
|
|
57
|
+
{ iconBg: "bg-cyan-100 dark:bg-cyan-950/40 text-cyan-600 dark:text-cyan-400" },
|
|
58
|
+
{ iconBg: "bg-violet-100 dark:bg-violet-950/40 text-violet-600 dark:text-violet-400" },
|
|
59
|
+
{ iconBg: "bg-amber-100 dark:bg-amber-950/40 text-amber-600 dark:text-amber-400" },
|
|
60
|
+
{ iconBg: "bg-rose-100 dark:bg-rose-950/40 text-rose-600 dark:text-rose-400" },
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
const steps = [
|
|
64
|
+
{
|
|
65
|
+
icon: <FaNpm size={14} />,
|
|
66
|
+
title: "Instalar dependencias",
|
|
67
|
+
desc: "Tailwind v4 y su plugin para Vite.",
|
|
68
|
+
filename: "terminal",
|
|
69
|
+
code: "npm install @axzydev/axzy_ui_system\nnpm install -D tailwindcss @tailwindcss/vite @vitejs/plugin-react-swc",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
icon: <SiVite size={14} />,
|
|
73
|
+
title: "Configurar Vite",
|
|
74
|
+
desc: "Agrega Tailwind como plugin de Vite.",
|
|
75
|
+
filename: "vite.config.ts",
|
|
76
|
+
code: `import { defineConfig } from "vite"
|
|
77
|
+
import react from "@vitejs/plugin-react-swc"
|
|
78
|
+
import tailwindcss from "@tailwindcss/vite"
|
|
79
|
+
|
|
80
|
+
export default defineConfig({
|
|
81
|
+
plugins: [tailwindcss(), react()],
|
|
82
|
+
})`,
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
icon: <SiTailwindcss size={14} />,
|
|
86
|
+
title: "Agregar Tailwind",
|
|
87
|
+
desc: "Importa Tailwind en tu archivo CSS.",
|
|
88
|
+
filename: "src/index.css",
|
|
89
|
+
code: `@import "tailwindcss";
|
|
90
|
+
@variant dark (&:is(.dark &));`,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
icon: <FaReact size={14} />,
|
|
94
|
+
title: "Importar estilos",
|
|
95
|
+
desc: "Envuelve tu app con el provider.",
|
|
96
|
+
filename: "src/main.tsx",
|
|
97
|
+
code: `import { ITThemeProvider } from "@axzydev/axzy_ui_system"
|
|
98
|
+
import "@axzydev/axzy_ui_system/dist/index.css"
|
|
99
|
+
|
|
100
|
+
<ITThemeProvider>
|
|
101
|
+
<App />
|
|
102
|
+
</ITThemeProvider>`,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
icon: <SiTypescript size={14} />,
|
|
106
|
+
title: "Declaración de tipos",
|
|
107
|
+
desc: "Para que TS acepte imports CSS.",
|
|
108
|
+
filename: "src/vite-env.d.ts",
|
|
109
|
+
code: `/// <reference types="vite/client" />
|
|
110
|
+
|
|
111
|
+
declare module "*.css" {
|
|
112
|
+
const content: string
|
|
113
|
+
export default content
|
|
114
|
+
}`,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
icon: <FaReact size={14} />,
|
|
118
|
+
title: "Primer componente",
|
|
119
|
+
desc: "Ya puedes usar cualquier componente.",
|
|
120
|
+
filename: "src/App.tsx",
|
|
121
|
+
code: `import { ITButton } from "@axzydev/axzy_ui_system"
|
|
122
|
+
|
|
123
|
+
export default function App() {
|
|
124
|
+
return <ITButton variant="rounded">Empezar</ITButton>
|
|
125
|
+
}`,
|
|
126
|
+
},
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
export const GettingStartedShowcase = () => {
|
|
130
|
+
return (
|
|
131
|
+
<ITStack spacing={10}>
|
|
132
|
+
{/* ─── HERO ─── */}
|
|
133
|
+
<ITCard className="overflow-hidden border-0 bg-gradient-to-br from-primary-50 via-white to-purple-50 dark:from-primary-950/20 dark:via-slate-900 dark:to-purple-950/20 shadow-sm">
|
|
134
|
+
<div className="relative">
|
|
135
|
+
<div className="absolute -top-40 -right-40 w-[500px] h-[500px] bg-primary-500/10 rounded-full blur-[120px] pointer-events-none" />
|
|
136
|
+
<div className="absolute -bottom-40 -left-40 w-[500px] h-[500px] bg-purple-500/10 rounded-full blur-[120px] pointer-events-none" />
|
|
137
|
+
|
|
138
|
+
<ITStack spacing={5} className="relative z-10">
|
|
139
|
+
<ITStack spacing={2}>
|
|
140
|
+
<ITBadget label="v1.0.0" color="primary" variant="outlined" className="w-fit" />
|
|
141
|
+
<ITText as="h1" className="!text-4xl !font-bold !tracking-tight">
|
|
142
|
+
AXZY UI System
|
|
143
|
+
</ITText>
|
|
144
|
+
<ITText as="p" muted className="!text-base !leading-relaxed max-w-xl">
|
|
145
|
+
Librería de componentes React con Tailwind CSS v4. Diseñada para apps enterprise con experiencia de desarrollo fluida.
|
|
146
|
+
</ITText>
|
|
147
|
+
</ITStack>
|
|
148
|
+
|
|
149
|
+
<ITFlex gap={3} wrap="wrap" align="center">
|
|
150
|
+
<div className="px-4 py-2 rounded-xl bg-gradient-to-r from-primary-50 to-purple-50 dark:from-primary-950/30 dark:to-purple-950/30 border border-primary-200 dark:border-primary-800/50 shadow-sm">
|
|
151
|
+
<ITFlex align="center" gap={2}>
|
|
152
|
+
<FaNpm size={16} className="text-primary-500" />
|
|
153
|
+
<code className="text-sm font-mono text-slate-800 dark:text-slate-200">npm install @axzydev/axzy_ui_system</code>
|
|
154
|
+
<CopyButton text="npm install @axzydev/axzy_ui_system" />
|
|
155
|
+
</ITFlex>
|
|
156
|
+
</div>
|
|
157
|
+
</ITFlex>
|
|
158
|
+
</ITStack>
|
|
159
|
+
</div>
|
|
160
|
+
</ITCard>
|
|
161
|
+
|
|
162
|
+
{/* ─── SETUP STEPS ─── */}
|
|
163
|
+
<ITGrid container spacing={6}>
|
|
164
|
+
{steps.map((step, i) => (
|
|
165
|
+
<ITGrid item xs={12} md={6} key={i}>
|
|
166
|
+
<ITCard className="border-slate-200/60 dark:border-slate-800/60 shadow-sm h-full">
|
|
167
|
+
<ITStack spacing={4}>
|
|
168
|
+
<ITFlex align="center" gap={2.5}>
|
|
169
|
+
<div className={`w-8 h-8 rounded-lg ${stepStyles[i].iconBg} flex items-center justify-center`}>
|
|
170
|
+
{step.icon}
|
|
171
|
+
</div>
|
|
172
|
+
<div>
|
|
173
|
+
<ITText as="p" className="!text-sm !font-semibold">{step.title}</ITText>
|
|
174
|
+
<ITText as="p" className="!text-xs !text-slate-400">{step.desc}</ITText>
|
|
175
|
+
</div>
|
|
176
|
+
</ITFlex>
|
|
177
|
+
<CodeBlock code={step.code} filename={step.filename} color={codeFileColors[i]} />
|
|
178
|
+
</ITStack>
|
|
179
|
+
</ITCard>
|
|
180
|
+
</ITGrid>
|
|
181
|
+
))}
|
|
182
|
+
</ITGrid>
|
|
183
|
+
|
|
184
|
+
{/* ─── THEMING ─── */}
|
|
185
|
+
<ITCard title="Theming" className="border-purple-200/60 dark:border-purple-800/60 shadow-sm">
|
|
186
|
+
<ITStack spacing={4}>
|
|
187
|
+
<ITText as="p" className="!text-sm" muted>
|
|
188
|
+
Personaliza colores en runtime. Solo necesitas los que quieras cambiar.
|
|
189
|
+
</ITText>
|
|
190
|
+
<div className="bg-gradient-to-r from-purple-50 via-fuchsia-50 to-pink-50 dark:from-purple-950/20 dark:via-fuchsia-950/20 dark:to-pink-950/20 rounded-xl p-5 border border-purple-200 dark:border-purple-800/30">
|
|
191
|
+
<CodeBlock
|
|
192
|
+
code={`const myTheme = {
|
|
193
|
+
colors: {
|
|
194
|
+
primary: { 50: "#fef2f2", 500: "#ef4444" },
|
|
195
|
+
},
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
<ITThemeProvider theme={myTheme}>
|
|
199
|
+
<App />
|
|
200
|
+
</ITThemeProvider>`}
|
|
201
|
+
/>
|
|
202
|
+
</div>
|
|
203
|
+
</ITStack>
|
|
204
|
+
</ITCard>
|
|
205
|
+
</ITStack>
|
|
206
|
+
);
|
|
207
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
import { FaCloud, FaCode, FaDatabase, FaDownload, FaGithub, FaLayerGroup, FaLinkedin, FaMapMarkerAlt, FaMobileAlt, FaSearch, FaServer, FaMedium } from "react-icons/fa";
|
|
2
|
+
import { FaArrowRight, FaCheck, FaCloud, FaCode, FaDatabase, FaDownload, FaExternalLinkAlt, FaGithub, FaLayerGroup, FaLinkedin, FaMapMarkerAlt, FaMobileAlt, FaSearch, FaServer, FaMedium } from "react-icons/fa";
|
|
3
|
+
import { SiReact, SiNodedotjs } from "react-icons/si";
|
|
3
4
|
import ITBadget from "../components/badget/badget";
|
|
4
5
|
import ITButton from "../components/button/button";
|
|
5
6
|
import ITCard from "../components/card/card";
|
|
@@ -94,7 +95,7 @@ export const HomeShowcase = () => {
|
|
|
94
95
|
<div className="w-56 h-56 md:w-64 md:h-64 rounded-full shadow-xl overflow-hidden ring-2 ring-slate-200 dark:ring-slate-700">
|
|
95
96
|
<img
|
|
96
97
|
src="/personalFoto.jpg"
|
|
97
|
-
alt="Asael
|
|
98
|
+
alt="Asael Amaro"
|
|
98
99
|
className="w-full h-full object-cover"
|
|
99
100
|
/>
|
|
100
101
|
</div>
|
|
@@ -109,7 +110,7 @@ export const HomeShowcase = () => {
|
|
|
109
110
|
<ITStack spacing={2}>
|
|
110
111
|
<ITBadget label="Portafolio Personal" color="primary" variant="outlined" className="w-fit" />
|
|
111
112
|
<ITText as="h1" className="text-4xl md:text-5xl font-bold tracking-tight text-slate-900 dark:text-white">
|
|
112
|
-
Hola, soy <span className="text-primary-600 dark:text-primary-400">Asael
|
|
113
|
+
Hola, soy <span className="text-primary-600 dark:text-primary-400">Asael Amaro</span>
|
|
113
114
|
</ITText>
|
|
114
115
|
<ITText as="p" muted className="text-base leading-relaxed max-w-xl">
|
|
115
116
|
Fullstack Developer con 4+ años de experiencia creando aplicaciones web modernas.
|
|
@@ -299,6 +300,97 @@ export const HomeShowcase = () => {
|
|
|
299
300
|
</ITText>
|
|
300
301
|
</ITStack>
|
|
301
302
|
</ITCard>
|
|
303
|
+
|
|
304
|
+
{/* ─── MIS PRODUCTOS ─── */}
|
|
305
|
+
<ITCard
|
|
306
|
+
title="Mis Productos"
|
|
307
|
+
className="border-slate-200/60 dark:border-slate-800/60 shadow-sm"
|
|
308
|
+
>
|
|
309
|
+
<ITText as="p" muted className="!text-sm !mb-4">
|
|
310
|
+
Productos destacados que he construido.
|
|
311
|
+
</ITText>
|
|
312
|
+
<ITGrid container spacing={5}>
|
|
313
|
+
{/* AXZY UI System */}
|
|
314
|
+
<ITGrid item xs={12} md={6}>
|
|
315
|
+
<a
|
|
316
|
+
href="#ui-system"
|
|
317
|
+
className="group block h-full rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900/50 p-6 hover:border-primary-400/40 hover:shadow-lg hover:-translate-y-1 transition-all duration-200"
|
|
318
|
+
>
|
|
319
|
+
<ITStack spacing={4} className="h-full" justifyContent="between">
|
|
320
|
+
<ITStack spacing={3}>
|
|
321
|
+
<ITFlex align="center" justify="between">
|
|
322
|
+
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-primary-500 to-purple-500 text-white flex items-center justify-center shadow-md">
|
|
323
|
+
<FaLayerGroup size={20} />
|
|
324
|
+
</div>
|
|
325
|
+
<ITBadget label="Propio" color="primary" variant="filled" />
|
|
326
|
+
</ITFlex>
|
|
327
|
+
<div>
|
|
328
|
+
<ITText as="h3" className="!text-lg !font-bold flex items-center gap-2">
|
|
329
|
+
AXZY UI System
|
|
330
|
+
<FaArrowRight size={14} className="text-primary-500 opacity-0 -translate-x-1 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-200" />
|
|
331
|
+
</ITText>
|
|
332
|
+
<ITText as="p" muted className="!text-sm !leading-relaxed mt-1.5">
|
|
333
|
+
Librería de componentes React con Tailwind CSS v4. Más de 50
|
|
334
|
+
componentes enterprise con theming en runtime, TypeScript nativo y
|
|
335
|
+
accesibilidad.
|
|
336
|
+
</ITText>
|
|
337
|
+
</div>
|
|
338
|
+
<ITFlex gap={2} wrap="wrap">
|
|
339
|
+
<ITBadget label="React" color="gray" variant="outlined" />
|
|
340
|
+
<ITBadget label="TypeScript" color="gray" variant="outlined" />
|
|
341
|
+
<ITBadget label="Tailwind" color="gray" variant="outlined" />
|
|
342
|
+
<ITBadget label="npm" color="gray" variant="outlined" />
|
|
343
|
+
</ITFlex>
|
|
344
|
+
</ITStack>
|
|
345
|
+
<ITText as="span" className="!text-xs !font-semibold !text-primary-600 dark:!text-primary-400 inline-flex items-center gap-1.5">
|
|
346
|
+
<SiReact size={12} />
|
|
347
|
+
Ver proyecto
|
|
348
|
+
</ITText>
|
|
349
|
+
</ITStack>
|
|
350
|
+
</a>
|
|
351
|
+
</ITGrid>
|
|
352
|
+
|
|
353
|
+
{/* CheckApp */}
|
|
354
|
+
<ITGrid item xs={12} md={6}>
|
|
355
|
+
<a
|
|
356
|
+
href="https://checkapp.axzy.dev/"
|
|
357
|
+
target="_blank"
|
|
358
|
+
rel="noopener noreferrer"
|
|
359
|
+
className="group block h-full rounded-2xl border border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900/50 p-6 hover:border-emerald-400/40 hover:shadow-lg hover:-translate-y-1 transition-all duration-200"
|
|
360
|
+
>
|
|
361
|
+
<ITStack spacing={4} className="h-full" justifyContent="between">
|
|
362
|
+
<ITStack spacing={3}>
|
|
363
|
+
<ITFlex align="center" justify="between">
|
|
364
|
+
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-emerald-500 to-cyan-500 text-white flex items-center justify-center shadow-md">
|
|
365
|
+
<FaCheck size={20} />
|
|
366
|
+
</div>
|
|
367
|
+
<ITBadget label="En vivo" color="gray" variant="outlined" />
|
|
368
|
+
</ITFlex>
|
|
369
|
+
<div>
|
|
370
|
+
<ITText as="h3" className="!text-lg !font-bold flex items-center gap-2">
|
|
371
|
+
CheckApp
|
|
372
|
+
<FaExternalLinkAlt size={12} className="text-slate-400 opacity-0 -translate-x-1 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-200" />
|
|
373
|
+
</ITText>
|
|
374
|
+
<ITText as="p" muted className="!text-sm !leading-relaxed mt-1.5">
|
|
375
|
+
Aplicación web para consultar información de manera rápida y
|
|
376
|
+
sencilla. Desplegada y disponible en línea.
|
|
377
|
+
</ITText>
|
|
378
|
+
</div>
|
|
379
|
+
<ITFlex gap={2} wrap="wrap">
|
|
380
|
+
<ITBadget label="Node.js" color="gray" variant="outlined" />
|
|
381
|
+
<ITBadget label="React" color="gray" variant="outlined" />
|
|
382
|
+
<ITBadget label="Deploy" color="gray" variant="outlined" />
|
|
383
|
+
</ITFlex>
|
|
384
|
+
</ITStack>
|
|
385
|
+
<ITText as="span" className="!text-xs !font-semibold !text-emerald-600 dark:!text-emerald-400 inline-flex items-center gap-1.5">
|
|
386
|
+
<SiNodedotjs size={12} />
|
|
387
|
+
Abrir CheckApp
|
|
388
|
+
</ITText>
|
|
389
|
+
</ITStack>
|
|
390
|
+
</a>
|
|
391
|
+
</ITGrid>
|
|
392
|
+
</ITGrid>
|
|
393
|
+
</ITCard>
|
|
302
394
|
</ITStack>
|
|
303
395
|
);
|
|
304
396
|
};
|
package/src/theme/theme.ts
CHANGED
|
@@ -452,6 +452,26 @@ export const typography = {
|
|
|
452
452
|
},
|
|
453
453
|
};
|
|
454
454
|
|
|
455
|
+
/**
|
|
456
|
+
* 4.5. Escala de Z-Index (capas de UI global)
|
|
457
|
+
* Fuente de verdad documentada para las clases z-[N] usadas en overlays fixed/absolute.
|
|
458
|
+
* Tailwind JIT requiere clases estáticas en el JSX, así que los componentes aplican
|
|
459
|
+
* el valor literal correspondiente, pero SIEMPRE debe coincidir con esta escala.
|
|
460
|
+
* Orden ascendente = se pinta más arriba.
|
|
461
|
+
*/
|
|
462
|
+
export const zIndex = {
|
|
463
|
+
/** Barras sticky (ITTopbar) y overlays de navegación (sidebar/aside móvil). */
|
|
464
|
+
navOverlay: 40,
|
|
465
|
+
/** Paneles deslizantes (ITDrawer). */
|
|
466
|
+
drawer: 50,
|
|
467
|
+
/** Diálogos modales (ITDialog, ITConfirmDialog). */
|
|
468
|
+
modal: 60,
|
|
469
|
+
/** UI flotante contextual: dropdowns, ITPopover, ITTooltip, ITDatePicker/ITTimePicker. */
|
|
470
|
+
floating: 70,
|
|
471
|
+
/** Notificaciones globales (ITToast) — siempre por encima de todo lo demás. */
|
|
472
|
+
toast: 80,
|
|
473
|
+
} as const;
|
|
474
|
+
|
|
455
475
|
/**
|
|
456
476
|
* 5. Theme final exportado
|
|
457
477
|
*/
|
|
@@ -459,5 +479,6 @@ export const theme = {
|
|
|
459
479
|
palette,
|
|
460
480
|
colors: semanticColors,
|
|
461
481
|
typography,
|
|
482
|
+
zIndex,
|
|
462
483
|
...components,
|
|
463
484
|
};
|
package/src/types/field.types.ts
CHANGED
|
@@ -2,26 +2,47 @@ import React from "react";
|
|
|
2
2
|
import * as Yup from "yup";
|
|
3
3
|
|
|
4
4
|
// Legacy FieldConfig (kept for backward compatibility during migration)
|
|
5
|
+
/** @deprecated Legacy (V1) field definition consumed by `ITFormBuilder`'s `fields` prop. Prefer `FieldConfigV2` via the `config` prop for new forms. */
|
|
5
6
|
export interface FieldConfig {
|
|
7
|
+
/** Field name, matches the key in Formik's `values`/`errors`/`touched` objects. */
|
|
6
8
|
name: string;
|
|
9
|
+
/** Label text rendered above the field. */
|
|
7
10
|
label: string;
|
|
11
|
+
/** Input type. @default "text" */
|
|
8
12
|
type?: "text" | "select" | "date" | "password" | "number";
|
|
13
|
+
/** Formats a numeric field with thousands separators/currency styling as the user types. @default false */
|
|
9
14
|
currencyFormat?: boolean;
|
|
15
|
+
/** Placeholder text shown when the field is empty. */
|
|
10
16
|
placeholder?: string;
|
|
17
|
+
/** Disables the field. @default false */
|
|
11
18
|
disabled?: boolean;
|
|
19
|
+
/** Marks the field as required (shows an asterisk and enables the built-in required message). @default false */
|
|
12
20
|
required?: boolean;
|
|
21
|
+
/** Yup schema used to validate this field. */
|
|
13
22
|
validation?: Yup.AnySchema;
|
|
23
|
+
/** Grid column span (1-12), or `[sm, md, lg]` breakpoint-specific spans. */
|
|
14
24
|
column?: number | number[];
|
|
25
|
+
/** Options for `type: "select"`. */
|
|
15
26
|
options?: { value: string; label: string }[];
|
|
27
|
+
/** Icon element rendered on the right side of the field. */
|
|
16
28
|
rightIcon?: React.ReactNode;
|
|
29
|
+
/** Icon element rendered on the left side of the field. */
|
|
17
30
|
leftIcon?: React.ReactNode;
|
|
31
|
+
/** Key read from each option object as its value. @default "value" */
|
|
18
32
|
valueField?: string;
|
|
33
|
+
/** Shows a live character-count hint below the field. @default false */
|
|
19
34
|
showHintLength?: boolean;
|
|
35
|
+
/** Key read from each option object as its display label. @default "label" */
|
|
20
36
|
labelField?: string;
|
|
37
|
+
/** Maximum character length allowed. */
|
|
21
38
|
maxLength?: number;
|
|
39
|
+
/** Minimum character length required. */
|
|
22
40
|
minLength?: number;
|
|
41
|
+
/** Number of visible text rows for a multi-line field. */
|
|
23
42
|
rows?: number;
|
|
43
|
+
/** Applies number formatting (thousand separators) as the user types. @default false */
|
|
24
44
|
formatNumber?: boolean;
|
|
45
|
+
/** Custom side-effect fired on change, in addition to the normal Formik update. Receives the new value and Formik's `setFieldValue`. */
|
|
25
46
|
onChangeAction?: (value: any, setFieldValue: any) => void;
|
|
26
47
|
}
|
|
27
48
|
|
|
@@ -29,6 +50,7 @@ export interface FieldConfig {
|
|
|
29
50
|
// V2: ENTERPRISE FORM BUILDER ARCHITECTURE
|
|
30
51
|
// -------------------------------------------------------------
|
|
31
52
|
|
|
53
|
+
/** Supported field kinds for `FieldConfigV2`. */
|
|
32
54
|
export type FieldTypeV2 =
|
|
33
55
|
| "text"
|
|
34
56
|
| "number"
|
|
@@ -43,61 +65,102 @@ export type FieldTypeV2 =
|
|
|
43
65
|
| "section" // For grouping fields or wizard steps
|
|
44
66
|
| "custom"; // For inversion of control (injecting external components)
|
|
45
67
|
|
|
68
|
+
/** Form state/helpers passed into `dynamicProps`, `renderWhen`, and `onChangeAction` callbacks for `FieldConfigV2`. */
|
|
46
69
|
export interface FieldContextV2 {
|
|
70
|
+
/** Current values for every field in the form, keyed by field `name`. */
|
|
47
71
|
values: Record<string, any>;
|
|
72
|
+
/** Programmatically sets a field's value (mirrors Formik's `setFieldValue`). */
|
|
48
73
|
setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void;
|
|
74
|
+
/** Programmatically sets a field-level error message. */
|
|
49
75
|
setFieldError: (field: string, error: string) => void;
|
|
76
|
+
/** Programmatically marks a field as touched, e.g. to surface its validation error. */
|
|
50
77
|
setFieldTouched: (field: string, touched?: boolean, shouldValidate?: boolean) => void;
|
|
51
78
|
}
|
|
52
79
|
|
|
80
|
+
/**
|
|
81
|
+
* V2 field definition consumed by `ITFormBuilder`'s `config` prop. Supports
|
|
82
|
+
* conditional rendering/props, nested sections and repeatable arrays, async
|
|
83
|
+
* options, and custom-component injection.
|
|
84
|
+
*/
|
|
53
85
|
export interface FieldConfigV2 {
|
|
86
|
+
/** Field name, matches the key in Formik's `values`/`errors`/`touched` objects. For `type: "array"`/`"section"`, this is the key under which the nested `fields` values are grouped. */
|
|
54
87
|
name: string;
|
|
88
|
+
/** Label text rendered above the field (or as the section/array heading). */
|
|
55
89
|
label?: string;
|
|
90
|
+
/** Field kind. Determines which input is rendered and which of the props below apply. */
|
|
56
91
|
type: FieldTypeV2;
|
|
57
|
-
|
|
92
|
+
|
|
58
93
|
// 1. Layout & Structure
|
|
94
|
+
/** Grid column span (1-12), or an object with per-breakpoint spans (`sm`/`md`/`lg`/`xl`). */
|
|
59
95
|
column?: number | { sm?: number; md?: number; lg?: number; xl?: number };
|
|
96
|
+
/** Nested field definitions. Required when `type` is `"array"` (the repeatable item shape) or `"section"` (the grouped fields). */
|
|
60
97
|
fields?: FieldConfigV2[]; // REQUIRED if type is "array" or "section"
|
|
98
|
+
/** For `type: "section"`, allows the section to be collapsed/expanded by the user. @default false */
|
|
61
99
|
collapsible?: boolean; // Optional for "section", default false
|
|
100
|
+
/** For a `collapsible` section, whether it starts collapsed. @default false */
|
|
62
101
|
defaultCollapsed?: boolean;
|
|
63
|
-
|
|
102
|
+
|
|
64
103
|
// 2. Rules Engine & Dynamic Behavior
|
|
104
|
+
/** Sibling field names this field depends on; changes to any of them re-evaluate `renderWhen`/`dynamicProps`. */
|
|
65
105
|
dependsOn?: string[]; // Array of sibling field names to listen to for re-evaluation
|
|
106
|
+
/** Determines whether this field is rendered (and included in submission) based on current form values. Re-evaluated when any field in `dependsOn` changes. Field is shown when omitted. */
|
|
66
107
|
renderWhen?: (values: Record<string, any>) => boolean; // If false, field isn't rendered or submitted
|
|
108
|
+
/** Computes a partial override of this field's own config from current form values (e.g. make it `required` once another field exceeds a threshold). Re-evaluated when any field in `dependsOn` changes. */
|
|
67
109
|
dynamicProps?: (values: Record<string, any>) => Partial<FieldConfigV2>; // E.g: if A > 100, make this required
|
|
68
|
-
|
|
110
|
+
|
|
69
111
|
// 3. Advanced Validations
|
|
112
|
+
/** Yup schema used to validate this field. */
|
|
70
113
|
validation?: Yup.AnySchema;
|
|
114
|
+
/** Async validator (e.g. a uniqueness check against an API). Return an error string when invalid, or `null`/`undefined` when valid. */
|
|
71
115
|
asyncValidation?: (value: any, values: Record<string, any>) => Promise<string | null | undefined>; // Returns error string if invalid
|
|
72
|
-
|
|
116
|
+
|
|
73
117
|
// 4. Base Props
|
|
118
|
+
/** Initial value used when the form is first initialized/reset. */
|
|
74
119
|
defaultValue?: any;
|
|
120
|
+
/** Placeholder text shown when the field is empty. */
|
|
75
121
|
placeholder?: string;
|
|
122
|
+
/** Disables the field, either statically or computed from current form values. @default false */
|
|
76
123
|
disabled?: boolean | ((values: Record<string, any>) => boolean);
|
|
124
|
+
/** Renders the field as read-only (visible but not editable). @default false */
|
|
77
125
|
readOnly?: boolean;
|
|
126
|
+
/** Marks the field as required, either statically or computed from current form values. @default false */
|
|
78
127
|
required?: boolean | ((values: Record<string, any>) => boolean);
|
|
79
|
-
|
|
128
|
+
|
|
80
129
|
// 5. Data Support (Sync & Async)
|
|
130
|
+
/** Options for `"select"`/`"radio"` fields: a static array, or an async loader function called once the field mounts. */
|
|
81
131
|
options?:
|
|
82
132
|
| { value: string | number; label: string }[]
|
|
83
133
|
| (() => Promise<{ value: string | number; label: string }[]>);
|
|
134
|
+
/** Key read from each option object as its value. @default "value" */
|
|
84
135
|
valueField?: string;
|
|
136
|
+
/** Key read from each option object as its display label. @default "label" */
|
|
85
137
|
labelField?: string;
|
|
86
|
-
|
|
138
|
+
|
|
87
139
|
// 6. Extensibility & UI
|
|
140
|
+
/** Icon element rendered on the left side of the field. */
|
|
88
141
|
leftIcon?: React.ReactNode;
|
|
142
|
+
/** Icon element rendered on the right side of the field. */
|
|
89
143
|
rightIcon?: React.ReactNode;
|
|
144
|
+
/** Custom component rendered instead of a built-in input when `type` is `"custom"`. */
|
|
90
145
|
component?: React.ComponentType<any>; // Custom component for type === "custom"
|
|
146
|
+
/** Additional CSS class applied to the field's container. */
|
|
91
147
|
className?: string; // Custom container class
|
|
92
|
-
|
|
148
|
+
|
|
93
149
|
// Legacy specific overrides
|
|
150
|
+
/** Formats a numeric field with thousands separators/currency styling as the user types. @default false */
|
|
94
151
|
currencyFormat?: boolean;
|
|
152
|
+
/** Shows a live character-count hint below the field. @default false */
|
|
95
153
|
showHintLength?: boolean;
|
|
154
|
+
/** Maximum character length allowed. */
|
|
96
155
|
maxLength?: number;
|
|
156
|
+
/** Minimum character length required. */
|
|
97
157
|
minLength?: number;
|
|
158
|
+
/** Number of visible text rows for a multi-line field. */
|
|
98
159
|
rows?: number;
|
|
160
|
+
/** Applies number formatting (thousand separators) as the user types. @default false */
|
|
99
161
|
formatNumber?: boolean;
|
|
100
162
|
|
|
101
163
|
// Lifecycle hook
|
|
164
|
+
/** Custom side-effect fired whenever this field's value changes. Receives the new value and the shared `FieldContextV2` helpers. */
|
|
102
165
|
onChangeAction?: (val: any, context: FieldContextV2) => void | Promise<void>;
|
|
103
166
|
}
|