@axzydev/axzy_ui_system 1.3.2 → 1.3.3
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/dist/index.cjs +29 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +29 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/molecules/table/table.tsx +2 -1
- package/src/components/organisms/data-table/dataTable.tsx +2 -1
- package/src/components/theme-provider/themePresets.ts +6 -0
- package/src/components/theme-provider/themeProvider.doc.mdx +1 -0
- package/src/components/theme-provider/themeProvider.props.ts +2 -0
- package/src/components/theme-provider/themeProvider.tsx +13 -2
- package/src/sandbox/LandingShowcase.tsx +416 -227
- package/src/theme/theme.types.ts +2 -0
- package/src/utils/styles.ts +3 -1
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { useEffect, useRef, useState, type ReactNode } from "react";
|
|
2
2
|
import {
|
|
3
|
+
FaArrowRight,
|
|
4
|
+
FaBoxOpen,
|
|
3
5
|
FaCheck,
|
|
6
|
+
FaCode,
|
|
4
7
|
FaCopy,
|
|
5
8
|
FaCreditCard,
|
|
9
|
+
FaFolderOpen,
|
|
6
10
|
FaGithub,
|
|
7
11
|
FaHome,
|
|
8
12
|
FaKeyboard,
|
|
@@ -32,6 +36,18 @@ export interface LandingShowcaseProps {
|
|
|
32
36
|
onOpenPortfolio: () => void;
|
|
33
37
|
}
|
|
34
38
|
|
|
39
|
+
/** Props for the local `SectionHeading` helper. */
|
|
40
|
+
interface SectionHeadingProps {
|
|
41
|
+
/** Small uppercase kicker rendered above the title. */
|
|
42
|
+
eyebrow: string;
|
|
43
|
+
/** Section title, always rendered as an `<h2>`. */
|
|
44
|
+
title: string;
|
|
45
|
+
/** Optional supporting sentence rendered below the title. */
|
|
46
|
+
subtitle?: string;
|
|
47
|
+
/** Extra classes for the heading wrapper (spacing, etc.). */
|
|
48
|
+
className?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
35
51
|
/** Icon per sandbox group id. */
|
|
36
52
|
const GROUP_ICONS: Record<string, ReactNode> = {
|
|
37
53
|
general: <FaHome />,
|
|
@@ -43,8 +59,9 @@ const GROUP_ICONS: Record<string, ReactNode> = {
|
|
|
43
59
|
};
|
|
44
60
|
|
|
45
61
|
/**
|
|
46
|
-
* Literal per-index gradient classes for the family
|
|
47
|
-
* see runtime-built class names, so every gradient is written out
|
|
62
|
+
* Literal per-index gradient classes for the family and stat tiles. Tailwind
|
|
63
|
+
* v4 cannot see runtime-built class names, so every gradient is written out
|
|
64
|
+
* in full and indexed by position.
|
|
48
65
|
*/
|
|
49
66
|
const GROUP_ACCENTS = [
|
|
50
67
|
"from-primary-500 to-info-500",
|
|
@@ -90,6 +107,16 @@ const copyText = async (text: string): Promise<boolean> => {
|
|
|
90
107
|
}
|
|
91
108
|
};
|
|
92
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Clipboard button that flips to a "Copiado" confirmation for 2s.
|
|
112
|
+
*
|
|
113
|
+
* `ITButton` writes `box-shadow` as an inline style on focus, so the visible
|
|
114
|
+
* keyboard ring is owned by the wrapper element that uses `focus-within`
|
|
115
|
+
* (see `LandingShowcase`) instead of a `focus-visible:` class here.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* <CopyButton text="pnpm add @axzydev/axzy_ui_system" />
|
|
119
|
+
*/
|
|
93
120
|
const CopyButton = ({ text }: { text: string }) => {
|
|
94
121
|
const [copied, setCopied] = useState(false);
|
|
95
122
|
const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
@@ -110,19 +137,33 @@ const CopyButton = ({ text }: { text: string }) => {
|
|
|
110
137
|
};
|
|
111
138
|
|
|
112
139
|
return (
|
|
113
|
-
<
|
|
114
|
-
<
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
140
|
+
<span aria-live="polite" className="inline-flex">
|
|
141
|
+
<ITButton
|
|
142
|
+
variant="text"
|
|
143
|
+
color="gray"
|
|
144
|
+
size="sm"
|
|
145
|
+
onClick={handleCopy}
|
|
146
|
+
className="!font-semibold"
|
|
147
|
+
>
|
|
148
|
+
<ITFlex align="center" gap={1.5}>
|
|
149
|
+
{copied ? (
|
|
150
|
+
<FaCheck size={10} className="text-emerald-400" />
|
|
151
|
+
) : (
|
|
152
|
+
<FaCopy size={10} />
|
|
153
|
+
)}
|
|
154
|
+
{copied ? "Copiado" : "Copiar"}
|
|
155
|
+
</ITFlex>
|
|
156
|
+
</ITButton>
|
|
157
|
+
</span>
|
|
123
158
|
);
|
|
124
159
|
};
|
|
125
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Dark code surface with an optional filename strip.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* <CodeBlock code="pnpm add pkg" filename="terminal" />
|
|
166
|
+
*/
|
|
126
167
|
const CodeBlock = ({ code, filename }: { code: string; filename?: string }) => (
|
|
127
168
|
<div className="overflow-hidden rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900">
|
|
128
169
|
{filename && (
|
|
@@ -140,11 +181,126 @@ const CodeBlock = ({ code, filename }: { code: string; filename?: string }) => (
|
|
|
140
181
|
</div>
|
|
141
182
|
);
|
|
142
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Uniform section heading: uppercase eyebrow + `<h2>` title + subtitle.
|
|
186
|
+
* Used by every section so the document outline stays consistent.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* <SectionHeading eyebrow="Catálogo" title="Explora por familia" className="!mb-6" />
|
|
190
|
+
*/
|
|
191
|
+
const SectionHeading = ({
|
|
192
|
+
eyebrow,
|
|
193
|
+
title,
|
|
194
|
+
subtitle,
|
|
195
|
+
className = "",
|
|
196
|
+
}: SectionHeadingProps) => (
|
|
197
|
+
<ITStack spacing={1} className={className}>
|
|
198
|
+
<ITText
|
|
199
|
+
as="p"
|
|
200
|
+
className="!text-[11px] !font-bold uppercase !tracking-wider text-primary-600 dark:text-primary-400"
|
|
201
|
+
>
|
|
202
|
+
{eyebrow}
|
|
203
|
+
</ITText>
|
|
204
|
+
<ITText
|
|
205
|
+
as="h2"
|
|
206
|
+
className="!text-xl !font-bold !tracking-tight text-slate-900 dark:text-white"
|
|
207
|
+
>
|
|
208
|
+
{title}
|
|
209
|
+
</ITText>
|
|
210
|
+
{subtitle && (
|
|
211
|
+
<ITText as="p" className="!text-sm text-slate-500 dark:text-slate-400">
|
|
212
|
+
{subtitle}
|
|
213
|
+
</ITText>
|
|
214
|
+
)}
|
|
215
|
+
</ITStack>
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Purely decorative library preview card shown in the hero on `xl` screens.
|
|
220
|
+
* Hidden from assistive tech — it duplicates no real content.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* <HeroLibraryPreview />
|
|
224
|
+
*/
|
|
225
|
+
const HeroLibraryPreview = () => (
|
|
226
|
+
<div
|
|
227
|
+
aria-hidden
|
|
228
|
+
className="hidden w-[340px] shrink-0 justify-end xl:flex"
|
|
229
|
+
>
|
|
230
|
+
<div
|
|
231
|
+
className="it-landing-float w-full overflow-hidden rounded-2xl border border-slate-200/80 bg-white/85 shadow-xl backdrop-blur-sm dark:border-slate-700/70 dark:bg-slate-900/85"
|
|
232
|
+
style={{ animationDelay: "0.8s" }}
|
|
233
|
+
>
|
|
234
|
+
{/* fake toolbar */}
|
|
235
|
+
<div className="flex items-center gap-1.5 border-b border-slate-200/80 px-4 py-3 dark:border-slate-700/70">
|
|
236
|
+
<span className="h-2.5 w-2.5 rounded-full bg-danger-400/70" />
|
|
237
|
+
<span className="h-2.5 w-2.5 rounded-full bg-warning-400/70" />
|
|
238
|
+
<span className="h-2.5 w-2.5 rounded-full bg-success-400/70" />
|
|
239
|
+
<span className="ml-2 h-2 w-24 rounded-full bg-slate-200 dark:bg-slate-700" />
|
|
240
|
+
</div>
|
|
241
|
+
|
|
242
|
+
{/* mini table skeleton */}
|
|
243
|
+
<div className="px-4 pt-4">
|
|
244
|
+
<div className="flex items-center justify-between">
|
|
245
|
+
<span className="h-2.5 w-20 rounded-full bg-slate-200 dark:bg-slate-700" />
|
|
246
|
+
<span className="h-4 w-14 rounded-full bg-primary-100 dark:bg-primary-900/50" />
|
|
247
|
+
</div>
|
|
248
|
+
|
|
249
|
+
<div className="mt-4 space-y-3">
|
|
250
|
+
<div className="flex items-center gap-3">
|
|
251
|
+
<span className="h-6 w-6 flex-shrink-0 rounded-md bg-gradient-to-br from-primary-500 to-info-500 opacity-80" />
|
|
252
|
+
<span className="h-2 w-[68%] rounded-full bg-slate-200 dark:bg-slate-700" />
|
|
253
|
+
</div>
|
|
254
|
+
<div className="flex items-center gap-3">
|
|
255
|
+
<span className="h-6 w-6 flex-shrink-0 rounded-md bg-gradient-to-br from-purple-500 to-primary-500 opacity-80" />
|
|
256
|
+
<span className="h-2 w-[92%] rounded-full bg-slate-200 dark:bg-slate-700" />
|
|
257
|
+
</div>
|
|
258
|
+
<div className="flex items-center gap-3">
|
|
259
|
+
<span className="h-6 w-6 flex-shrink-0 rounded-md bg-gradient-to-br from-info-500 to-purple-500 opacity-80" />
|
|
260
|
+
<span className="h-2 w-[54%] rounded-full bg-slate-200 dark:bg-slate-700" />
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
|
|
265
|
+
{/* fake action + status */}
|
|
266
|
+
<div className="mt-5 flex items-center justify-between border-t border-slate-200/80 px-4 py-3.5 dark:border-slate-700/70">
|
|
267
|
+
<span className="inline-flex items-center rounded-lg bg-primary-500 px-3 py-1.5 text-[10px] font-bold tracking-wide text-white shadow-sm">
|
|
268
|
+
ITButton
|
|
269
|
+
</span>
|
|
270
|
+
<span className="inline-flex items-center gap-1.5 rounded-full border border-success-500/40 px-2.5 py-1 text-[10px] font-semibold text-success-600 dark:text-success-400">
|
|
271
|
+
<span className="h-1.5 w-1.5 rounded-full bg-success-500" />
|
|
272
|
+
Tipado
|
|
273
|
+
</span>
|
|
274
|
+
</div>
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
);
|
|
278
|
+
|
|
143
279
|
const STATS = [
|
|
144
|
-
{
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
280
|
+
{
|
|
281
|
+
label: "Componentes",
|
|
282
|
+
value: `${TOTAL_ITEMS}`,
|
|
283
|
+
hint: "páginas documentadas",
|
|
284
|
+
icon: <FaLayerGroup />,
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
label: "Familias",
|
|
288
|
+
value: `${SANDBOX_GROUPS.length}`,
|
|
289
|
+
hint: "grupos de navegación",
|
|
290
|
+
icon: <FaFolderOpen />,
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
label: "TypeScript",
|
|
294
|
+
value: "100%",
|
|
295
|
+
hint: "tipado estricto",
|
|
296
|
+
icon: <FaCode />,
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
label: "UI deps",
|
|
300
|
+
value: "0",
|
|
301
|
+
hint: "sin runtime extra",
|
|
302
|
+
icon: <FaBoxOpen />,
|
|
303
|
+
},
|
|
148
304
|
];
|
|
149
305
|
|
|
150
306
|
const FEATURES = [
|
|
@@ -170,15 +326,24 @@ export default function App() {
|
|
|
170
326
|
/**
|
|
171
327
|
* Sandbox landing page (`#ui-system`): a dashboard-style entry point with a
|
|
172
328
|
* hero, real derived stats, deep-linking family cards, quickstart, and links.
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* <LandingShowcase
|
|
332
|
+
* onOpenItem={(group, item) => setRoute(`${group}/${item}`)}
|
|
333
|
+
* onOpenPortfolio={() => setRoute("")}
|
|
334
|
+
* />
|
|
173
335
|
*/
|
|
174
336
|
export function LandingShowcase({
|
|
175
337
|
onOpenItem,
|
|
176
338
|
onOpenPortfolio,
|
|
177
339
|
}: LandingShowcaseProps) {
|
|
178
340
|
return (
|
|
179
|
-
<ITStack spacing={10} className="animate-fadeIn">
|
|
341
|
+
<ITStack spacing={10} className="animate-fadeIn pb-5">
|
|
180
342
|
{/* ─── HERO ─── */}
|
|
181
|
-
<section
|
|
343
|
+
<section
|
|
344
|
+
aria-labelledby="ui-system-hero-title"
|
|
345
|
+
className="relative overflow-hidden rounded-3xl bg-gradient-to-br from-primary-50 via-white to-purple-50 dark:from-primary-950/30 dark:via-slate-900 dark:to-purple-950/30 px-8 py-14 sm:px-14"
|
|
346
|
+
>
|
|
182
347
|
<div
|
|
183
348
|
aria-hidden
|
|
184
349
|
className="it-landing-float pointer-events-none absolute -top-24 -right-16 h-72 w-72 rounded-full bg-primary-400/20 blur-3xl"
|
|
@@ -193,121 +358,137 @@ export function LandingShowcase({
|
|
|
193
358
|
className="it-landing-grid pointer-events-none absolute inset-0 text-slate-400/50 dark:text-slate-600/40"
|
|
194
359
|
/>
|
|
195
360
|
|
|
196
|
-
<div className="relative z-10
|
|
197
|
-
<div
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
<ITText
|
|
210
|
-
as="h1"
|
|
211
|
-
className="it-landing-rise !mt-5 !text-4xl sm:!text-5xl !font-extrabold !tracking-tight text-slate-900 dark:text-white"
|
|
212
|
-
style={{ animationDelay: "70ms" }}
|
|
213
|
-
>
|
|
214
|
-
Componentes para{" "}
|
|
215
|
-
<span className="bg-gradient-to-r from-primary-600 via-primary-500 to-purple-500 bg-clip-text text-transparent">
|
|
216
|
-
interfaces serias
|
|
217
|
-
</span>
|
|
218
|
-
</ITText>
|
|
361
|
+
<div className="relative z-10 flex flex-col gap-12 xl:flex-row xl:items-center xl:gap-10">
|
|
362
|
+
<div className="min-w-0 max-w-3xl flex-1 xl:max-w-2xl">
|
|
363
|
+
<div
|
|
364
|
+
className="it-landing-rise"
|
|
365
|
+
style={{ animationDelay: "0ms" }}
|
|
366
|
+
>
|
|
367
|
+
<ITBadget
|
|
368
|
+
label="v1.3.0 · Tailwind v4"
|
|
369
|
+
color="primary"
|
|
370
|
+
variant="outlined"
|
|
371
|
+
className="w-fit"
|
|
372
|
+
/>
|
|
373
|
+
</div>
|
|
219
374
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
375
|
+
<ITText
|
|
376
|
+
as="h1"
|
|
377
|
+
id="ui-system-hero-title"
|
|
378
|
+
className="it-landing-rise !mt-5 !text-4xl sm:!text-5xl !font-extrabold !tracking-tight text-slate-900 dark:text-white"
|
|
379
|
+
style={{ animationDelay: "70ms" }}
|
|
380
|
+
>
|
|
381
|
+
Componentes para{" "}
|
|
382
|
+
<span className="bg-gradient-to-r from-primary-600 via-primary-500 to-purple-500 bg-clip-text text-transparent">
|
|
383
|
+
interfaces serias
|
|
384
|
+
</span>
|
|
385
|
+
</ITText>
|
|
229
386
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
className="it-landing-rise !mt-7"
|
|
235
|
-
style={{ animationDelay: "210ms" }}
|
|
236
|
-
>
|
|
237
|
-
<ITButton
|
|
238
|
-
variant="filled"
|
|
239
|
-
color="primary"
|
|
240
|
-
size="lg"
|
|
241
|
-
icon={<FaRocket size={13} />}
|
|
242
|
-
onClick={() => onOpenItem("general", "getting-started")}
|
|
387
|
+
<ITText
|
|
388
|
+
as="p"
|
|
389
|
+
className="it-landing-rise !mt-4 !text-base !leading-relaxed max-w-xl text-slate-600 dark:text-slate-300"
|
|
390
|
+
style={{ animationDelay: "140ms" }}
|
|
243
391
|
>
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
392
|
+
Una librería React + TypeScript con Tailwind CSS v4: accesible,
|
|
393
|
+
temable y lista para producción. Explora {TOTAL_ITEMS} páginas en{" "}
|
|
394
|
+
{SANDBOX_GROUPS.length} familias.
|
|
395
|
+
</ITText>
|
|
396
|
+
|
|
397
|
+
<ITFlex
|
|
398
|
+
gap={3}
|
|
399
|
+
wrap="wrap"
|
|
400
|
+
align="center"
|
|
401
|
+
className="it-landing-rise !mt-7"
|
|
402
|
+
style={{ animationDelay: "210ms" }}
|
|
252
403
|
>
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
404
|
+
<ITButton
|
|
405
|
+
variant="filled"
|
|
406
|
+
color="primary"
|
|
407
|
+
size="lg"
|
|
408
|
+
icon={<FaRocket size={13} />}
|
|
409
|
+
onClick={() => onOpenItem("general", "getting-started")}
|
|
410
|
+
>
|
|
411
|
+
Explorar componentes
|
|
412
|
+
</ITButton>
|
|
413
|
+
<ITButton
|
|
414
|
+
variant="outlined"
|
|
415
|
+
color="secondary"
|
|
416
|
+
size="lg"
|
|
417
|
+
icon={<FaLayerGroup size={13} />}
|
|
418
|
+
onClick={onOpenPortfolio}
|
|
419
|
+
>
|
|
420
|
+
Ver portafolio
|
|
421
|
+
</ITButton>
|
|
422
|
+
</ITFlex>
|
|
256
423
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
424
|
+
<div
|
|
425
|
+
className="it-landing-rise mt-7 inline-flex flex-wrap items-center gap-x-3 gap-y-2 rounded-2xl border border-primary-200 bg-gradient-to-r from-primary-50 to-purple-50 px-4 py-2 shadow-sm dark:border-primary-800/50 dark:from-primary-950/30 dark:to-purple-950/30"
|
|
426
|
+
style={{ animationDelay: "280ms" }}
|
|
427
|
+
>
|
|
428
|
+
<FaNpm size={16} className="shrink-0 text-primary-500" />
|
|
429
|
+
<code className="text-sm font-medium text-slate-800 dark:text-slate-200">
|
|
430
|
+
{INSTALL_CMD}
|
|
431
|
+
</code>
|
|
432
|
+
<span className="inline-flex items-center rounded-lg border border-primary-200/90 bg-white/85 focus-within:ring-2 focus-within:ring-inset focus-within:ring-primary-500 dark:border-primary-800/90 dark:bg-slate-900/70">
|
|
433
|
+
<CopyButton text={INSTALL_CMD} />
|
|
434
|
+
</span>
|
|
435
|
+
</div>
|
|
266
436
|
</div>
|
|
437
|
+
|
|
438
|
+
<HeroLibraryPreview />
|
|
267
439
|
</div>
|
|
268
440
|
</section>
|
|
269
441
|
|
|
270
442
|
{/* ─── STAT STRIP ─── */}
|
|
271
|
-
<
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
<
|
|
275
|
-
<
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
443
|
+
<section aria-label="Métricas de la librería">
|
|
444
|
+
<ITGrid container spacing={4}>
|
|
445
|
+
{STATS.map((stat, index) => (
|
|
446
|
+
<ITGrid item xs={6} lg={3} key={stat.label}>
|
|
447
|
+
<div className="flex h-full flex-col gap-4 rounded-2xl border border-slate-200 bg-white p-5 shadow-sm transition-all duration-300 hover:-translate-y-0.5 hover:border-primary-300 hover:shadow-lg dark:border-slate-800 dark:bg-slate-900 dark:hover:border-primary-700">
|
|
448
|
+
<div className="flex items-start justify-between gap-3">
|
|
449
|
+
<ITText
|
|
450
|
+
as="p"
|
|
451
|
+
className="!text-3xl !font-extrabold !tracking-tight !leading-none tabular-nums text-slate-900 dark:text-white"
|
|
452
|
+
>
|
|
453
|
+
{stat.value}
|
|
454
|
+
</ITText>
|
|
455
|
+
<span
|
|
456
|
+
className={`flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-xl bg-gradient-to-br text-[13px] text-white shadow-sm ${
|
|
457
|
+
GROUP_ACCENTS[index % GROUP_ACCENTS.length]
|
|
458
|
+
}`}
|
|
459
|
+
>
|
|
460
|
+
{stat.icon}
|
|
461
|
+
</span>
|
|
462
|
+
</div>
|
|
463
|
+
|
|
464
|
+
<div className="mt-auto">
|
|
465
|
+
<ITText
|
|
466
|
+
as="p"
|
|
467
|
+
className="!text-sm !font-semibold text-primary-600 dark:text-primary-400"
|
|
468
|
+
>
|
|
469
|
+
{stat.label}
|
|
470
|
+
</ITText>
|
|
471
|
+
<ITText
|
|
472
|
+
as="p"
|
|
473
|
+
className="!mt-0.5 !text-[11px] text-slate-400 dark:text-slate-500"
|
|
474
|
+
>
|
|
475
|
+
{stat.hint}
|
|
476
|
+
</ITText>
|
|
477
|
+
</div>
|
|
478
|
+
</div>
|
|
479
|
+
</ITGrid>
|
|
480
|
+
))}
|
|
481
|
+
</ITGrid>
|
|
482
|
+
</section>
|
|
297
483
|
|
|
298
484
|
{/* ─── EXPLORE BY FAMILY ─── */}
|
|
299
485
|
<section>
|
|
300
|
-
<
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
</ITText>
|
|
307
|
-
<ITText as="p" className="!text-sm text-slate-500 dark:text-slate-400">
|
|
308
|
-
Cada tarjeta te lleva directo al primer componente del grupo.
|
|
309
|
-
</ITText>
|
|
310
|
-
</ITStack>
|
|
486
|
+
<SectionHeading
|
|
487
|
+
eyebrow="Catálogo"
|
|
488
|
+
title="Explora por familia"
|
|
489
|
+
subtitle="Cada tarjeta te lleva directo al primer componente del grupo."
|
|
490
|
+
className="!mb-5"
|
|
491
|
+
/>
|
|
311
492
|
|
|
312
493
|
<ITGrid container spacing={5}>
|
|
313
494
|
{SANDBOX_GROUPS.map((group, index) => (
|
|
@@ -315,39 +496,34 @@ export function LandingShowcase({
|
|
|
315
496
|
<button
|
|
316
497
|
type="button"
|
|
317
498
|
onClick={() => onOpenItem(group.id, group.subitems[0].id)}
|
|
318
|
-
className="group flex h-full w-full flex-col gap-4 rounded-2xl border border-slate-200
|
|
499
|
+
className="group flex h-full w-full flex-col gap-4 rounded-2xl border border-slate-200 bg-white p-5 text-left transition-all duration-300 hover:-translate-y-1 hover:border-primary-300 hover:shadow-xl focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary-400 dark:border-slate-800 dark:bg-slate-900 dark:hover:border-primary-700 dark:hover:shadow-2xl"
|
|
319
500
|
>
|
|
320
501
|
<div className="flex items-center gap-3">
|
|
321
502
|
<span
|
|
322
|
-
className={`flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-xl bg-gradient-to-br ${
|
|
503
|
+
className={`flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-xl bg-gradient-to-br text-[13px] text-white shadow-sm ${
|
|
323
504
|
GROUP_ACCENTS[index % GROUP_ACCENTS.length]
|
|
324
|
-
}
|
|
505
|
+
}`}
|
|
325
506
|
>
|
|
326
507
|
{GROUP_ICONS[group.id]}
|
|
327
508
|
</span>
|
|
328
|
-
<
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
{
|
|
340
|
-
|
|
509
|
+
<ITText
|
|
510
|
+
as="span"
|
|
511
|
+
className="min-w-0 flex-1 truncate !text-[15px] !font-bold !tracking-tight text-slate-900 dark:text-white"
|
|
512
|
+
>
|
|
513
|
+
{group.label}
|
|
514
|
+
</ITText>
|
|
515
|
+
<span className="inline-flex shrink-0 items-center rounded-full bg-slate-100 px-2 py-0.5 text-[11px] font-semibold tabular-nums text-slate-500 dark:bg-slate-800 dark:text-slate-400">
|
|
516
|
+
{group.subitems.length}
|
|
517
|
+
</span>
|
|
518
|
+
<span className="flex w-4 shrink-0 items-center justify-center">
|
|
519
|
+
<FaArrowRight
|
|
520
|
+
size={12}
|
|
521
|
+
className="text-primary-500 opacity-0 -translate-x-1.5 transition-all duration-300 group-hover:translate-x-0 group-hover:opacity-100"
|
|
522
|
+
/>
|
|
341
523
|
</span>
|
|
342
|
-
<ITBadget
|
|
343
|
-
label={`${group.subitems.length}`}
|
|
344
|
-
color="secondary"
|
|
345
|
-
variant="outlined"
|
|
346
|
-
size="sm"
|
|
347
|
-
/>
|
|
348
524
|
</div>
|
|
349
525
|
|
|
350
|
-
<div className="flex flex-wrap gap-1.5">
|
|
526
|
+
<div className="mt-auto flex flex-wrap gap-1.5">
|
|
351
527
|
{group.subitems.slice(0, 4).map((sub) => (
|
|
352
528
|
<span
|
|
353
529
|
key={sub.id}
|
|
@@ -369,97 +545,110 @@ export function LandingShowcase({
|
|
|
369
545
|
</section>
|
|
370
546
|
|
|
371
547
|
{/* ─── QUICKSTART ─── */}
|
|
372
|
-
<
|
|
373
|
-
<
|
|
374
|
-
|
|
375
|
-
|
|
548
|
+
<section>
|
|
549
|
+
<SectionHeading
|
|
550
|
+
eyebrow="Puesta en marcha"
|
|
551
|
+
title="Quickstart"
|
|
552
|
+
subtitle="Un provider de tema, una hoja de estilos y tu primer botón."
|
|
553
|
+
className="!mb-5"
|
|
554
|
+
/>
|
|
555
|
+
|
|
556
|
+
<ITGrid container spacing={6}>
|
|
557
|
+
<ITGrid item xs={12} lg={7}>
|
|
558
|
+
<ITStack spacing={3}>
|
|
559
|
+
<ITFlex align="center" justify="between" gap={3}>
|
|
560
|
+
<ITText
|
|
561
|
+
as="p"
|
|
562
|
+
className="!text-[11px] !font-bold uppercase !tracking-wider text-slate-400 dark:text-slate-500"
|
|
563
|
+
>
|
|
564
|
+
Ejemplo mínimo
|
|
565
|
+
</ITText>
|
|
566
|
+
<span className="inline-flex items-center rounded-lg focus-within:ring-2 focus-within:ring-inset focus-within:ring-primary-500">
|
|
567
|
+
<CopyButton text={QUICKSTART_CODE} />
|
|
568
|
+
</span>
|
|
569
|
+
</ITFlex>
|
|
570
|
+
<CodeBlock filename="src/App.tsx" code={QUICKSTART_CODE} />
|
|
571
|
+
</ITStack>
|
|
572
|
+
</ITGrid>
|
|
573
|
+
|
|
574
|
+
<ITGrid item xs={12} lg={5}>
|
|
575
|
+
<div className="h-full rounded-2xl border border-slate-200 bg-white p-6 shadow-sm dark:border-slate-800 dark:bg-slate-900">
|
|
376
576
|
<ITText
|
|
377
|
-
as="
|
|
378
|
-
className="!text-
|
|
577
|
+
as="h3"
|
|
578
|
+
className="!mb-4 !text-sm !font-bold uppercase !tracking-wider text-slate-400 dark:text-slate-500"
|
|
379
579
|
>
|
|
380
|
-
|
|
580
|
+
Incluido de fábrica
|
|
381
581
|
</ITText>
|
|
382
|
-
<
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
582
|
+
<ul className="space-y-3">
|
|
583
|
+
{FEATURES.map((feature) => (
|
|
584
|
+
<li key={feature} className="flex items-start gap-3">
|
|
585
|
+
<span className="mt-0.5 flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-success-100 text-success-600 dark:bg-success-950/40 dark:text-success-400">
|
|
586
|
+
<FaCheck size={10} />
|
|
587
|
+
</span>
|
|
588
|
+
<span className="text-sm text-slate-600 dark:text-slate-300">
|
|
589
|
+
{feature}
|
|
590
|
+
</span>
|
|
591
|
+
</li>
|
|
592
|
+
))}
|
|
593
|
+
</ul>
|
|
594
|
+
</div>
|
|
595
|
+
</ITGrid>
|
|
386
596
|
</ITGrid>
|
|
597
|
+
</section>
|
|
387
598
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
<li key={feature} className="flex items-start gap-3">
|
|
399
|
-
<span className="mt-0.5 flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-success-100 text-success-600 dark:bg-success-950/40 dark:text-success-400">
|
|
400
|
-
<FaCheck size={10} />
|
|
401
|
-
</span>
|
|
402
|
-
<span className="text-sm text-slate-600 dark:text-slate-300">
|
|
403
|
-
{feature}
|
|
404
|
-
</span>
|
|
405
|
-
</li>
|
|
406
|
-
))}
|
|
407
|
-
</ul>
|
|
408
|
-
</div>
|
|
409
|
-
</ITGrid>
|
|
410
|
-
</ITGrid>
|
|
599
|
+
{/* ─── CLOSING CTA ─── */}
|
|
600
|
+
<section className="relative overflow-hidden rounded-3xl border border-primary-200 bg-gradient-to-br from-primary-50 via-white to-purple-50 p-6 shadow-sm dark:border-primary-900/40 dark:from-primary-950/30 dark:via-slate-900 dark:to-purple-950/30 sm:p-7">
|
|
601
|
+
<div
|
|
602
|
+
aria-hidden
|
|
603
|
+
className="it-landing-float pointer-events-none absolute -top-20 -right-16 h-56 w-56 rounded-full bg-primary-400/20 blur-3xl"
|
|
604
|
+
/>
|
|
605
|
+
<div
|
|
606
|
+
aria-hidden
|
|
607
|
+
className="it-landing-grid pointer-events-none absolute inset-0 text-slate-400/40 dark:text-slate-600/30"
|
|
608
|
+
/>
|
|
411
609
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
>
|
|
420
|
-
¿Listo para construir?
|
|
421
|
-
</ITText>
|
|
422
|
-
<ITText
|
|
423
|
-
as="p"
|
|
424
|
-
className="!text-sm text-slate-500 dark:text-slate-400"
|
|
425
|
-
>
|
|
426
|
-
Revisa el portafolio, el código fuente o levanta Storybook.
|
|
427
|
-
</ITText>
|
|
428
|
-
</ITStack>
|
|
429
|
-
|
|
430
|
-
<ITFlex gap={3} wrap="wrap" align="center">
|
|
431
|
-
<ITButton
|
|
432
|
-
variant="filled"
|
|
433
|
-
color="primary"
|
|
434
|
-
icon={<FaLayerGroup size={13} />}
|
|
435
|
-
onClick={onOpenPortfolio}
|
|
436
|
-
>
|
|
437
|
-
Portafolio
|
|
438
|
-
</ITButton>
|
|
439
|
-
<ITButton
|
|
440
|
-
variant="outlined"
|
|
441
|
-
color="secondary"
|
|
442
|
-
icon={<FaGithub size={13} />}
|
|
443
|
-
onClick={() =>
|
|
444
|
-
window.open(GITHUB_URL, "_blank", "noopener,noreferrer")
|
|
445
|
-
}
|
|
446
|
-
>
|
|
447
|
-
GitHub
|
|
448
|
-
</ITButton>
|
|
449
|
-
</ITFlex>
|
|
450
|
-
</ITFlex>
|
|
610
|
+
<div className="relative z-10">
|
|
611
|
+
<div className="flex flex-col gap-6 lg:flex-row lg:items-start lg:justify-between lg:gap-10">
|
|
612
|
+
<SectionHeading
|
|
613
|
+
eyebrow="Siguientes pasos"
|
|
614
|
+
title="¿Listo para construir?"
|
|
615
|
+
subtitle="Revisa el portafolio, el código fuente o levanta Storybook."
|
|
616
|
+
/>
|
|
451
617
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
618
|
+
<ITFlex gap={3} wrap="wrap" align="center" className="shrink-0">
|
|
619
|
+
<ITButton
|
|
620
|
+
variant="filled"
|
|
621
|
+
color="primary"
|
|
622
|
+
icon={<FaLayerGroup size={13} />}
|
|
623
|
+
onClick={onOpenPortfolio}
|
|
624
|
+
>
|
|
625
|
+
Portafolio
|
|
626
|
+
</ITButton>
|
|
627
|
+
<ITButton
|
|
628
|
+
variant="outlined"
|
|
629
|
+
color="secondary"
|
|
630
|
+
icon={<FaGithub size={13} />}
|
|
631
|
+
onClick={() =>
|
|
632
|
+
window.open(GITHUB_URL, "_blank", "noopener,noreferrer")
|
|
633
|
+
}
|
|
634
|
+
>
|
|
635
|
+
GitHub
|
|
636
|
+
</ITButton>
|
|
637
|
+
</ITFlex>
|
|
638
|
+
</div>
|
|
639
|
+
|
|
640
|
+
<ITText
|
|
641
|
+
as="p"
|
|
642
|
+
className="!mt-6 !text-xs text-slate-500 dark:text-slate-400"
|
|
643
|
+
>
|
|
644
|
+
Ejecuta{" "}
|
|
645
|
+
<code className="rounded bg-white/70 px-1.5 py-0.5 font-mono text-slate-700 dark:bg-slate-800/70 dark:text-slate-200">
|
|
646
|
+
pnpm storybook
|
|
647
|
+
</code>{" "}
|
|
648
|
+
para ver cada componente aislado.
|
|
649
|
+
</ITText>
|
|
650
|
+
</div>
|
|
651
|
+
</section>
|
|
463
652
|
</ITStack>
|
|
464
653
|
);
|
|
465
654
|
}
|