@axzydev/axzy_ui_system 1.2.6 → 1.2.8

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.
Files changed (185) hide show
  1. package/dist/index.cjs +777 -535
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +1 -1
  4. package/dist/index.css.map +1 -1
  5. package/dist/index.d.cts +1470 -87
  6. package/dist/index.d.ts +1470 -87
  7. package/dist/index.js +799 -555
  8. package/dist/index.js.map +1 -1
  9. package/package.json +1 -1
  10. package/src/App.tsx +19 -54
  11. package/src/components/alert/alert.doc.mdx +48 -0
  12. package/src/components/alert/alert.props.ts +7 -0
  13. package/src/components/alert/alert.tsx +8 -0
  14. package/src/components/avatar/avatar.doc.mdx +48 -0
  15. package/src/components/avatar/avatar.props.ts +8 -0
  16. package/src/components/avatar/avatar.tsx +25 -5
  17. package/src/components/badget/badget.doc.mdx +46 -0
  18. package/src/components/badget/badget.props.ts +6 -0
  19. package/src/components/badget/badget.tsx +11 -0
  20. package/src/components/breadcrumbs/breadcrumbs.doc.mdx +57 -0
  21. package/src/components/breadcrumbs/breadcrumbs.props.ts +6 -0
  22. package/src/components/breadcrumbs/breadcrumbs.tsx +12 -0
  23. package/src/components/button/button.doc.mdx +59 -0
  24. package/src/components/button/button.props.ts +12 -0
  25. package/src/components/button/button.tsx +11 -0
  26. package/src/components/calendar/calendar.doc.mdx +75 -0
  27. package/src/components/calendar/calendar.props.ts +27 -7
  28. package/src/components/calendar/calendar.tsx +13 -0
  29. package/src/components/card/card.doc.mdx +54 -0
  30. package/src/components/card/card.props.ts +11 -0
  31. package/src/components/card/card.tsx +13 -0
  32. package/src/components/checkbox/checkbox.doc.mdx +54 -0
  33. package/src/components/checkbox/checkbox.props.ts +7 -0
  34. package/src/components/checkbox/checkbox.tsx +9 -0
  35. package/src/components/confirm-dialog/confirm-dialog.doc.mdx +60 -0
  36. package/src/components/confirm-dialog/confirm-dialog.props.ts +9 -0
  37. package/src/components/confirm-dialog/confirm-dialog.tsx +19 -0
  38. package/src/components/data-table/ITDataTable.doc.mdx +59 -0
  39. package/src/components/data-table/dataTable.props.ts +15 -0
  40. package/src/components/data-table/dataTable.tsx +178 -73
  41. package/src/components/date-picker/date-picker.doc.mdx +65 -0
  42. package/src/components/date-picker/date-picker.props.ts +17 -0
  43. package/src/components/date-picker/datePicker.tsx +31 -1
  44. package/src/components/dialog/dialog.doc.mdx +54 -0
  45. package/src/components/dialog/dialog.props.ts +7 -0
  46. package/src/components/dialog/dialog.tsx +26 -0
  47. package/src/components/divider/divider.doc.mdx +42 -0
  48. package/src/components/divider/divider.props.ts +5 -0
  49. package/src/components/divider/divider.tsx +16 -0
  50. package/src/components/drawer/drawer.doc.mdx +59 -0
  51. package/src/components/drawer/drawer.props.ts +9 -0
  52. package/src/components/drawer/drawer.tsx +20 -0
  53. package/src/components/dropfile/dropfile.doc.mdx +59 -0
  54. package/src/components/dropfile/dropfile.props.ts +41 -0
  55. package/src/components/dropfile/dropfile.tsx +21 -33
  56. package/src/components/empty-state/empty-state.doc.mdx +50 -0
  57. package/src/components/empty-state/empty-state.props.ts +5 -0
  58. package/src/components/empty-state/empty-state.tsx +16 -0
  59. package/src/components/flex/flex.doc.mdx +59 -0
  60. package/src/components/flex/flex.props.ts +13 -0
  61. package/src/components/flex/flex.tsx +15 -0
  62. package/src/components/form-builder/fieldRenderer.tsx +52 -2
  63. package/src/components/form-builder/formBuilder.doc.mdx +124 -0
  64. package/src/components/form-builder/formBuilder.props.ts +12 -2
  65. package/src/components/form-builder/formBuilder.tsx +31 -0
  66. package/src/components/form-header/form-header.doc.mdx +38 -0
  67. package/src/components/form-header/form-header.props.ts +3 -0
  68. package/src/components/form-header/form-header.stories.tsx +53 -0
  69. package/src/components/form-header/form-header.tsx +11 -0
  70. package/src/components/grid/grid.doc.mdx +54 -0
  71. package/src/components/grid/grid.props.ts +13 -0
  72. package/src/components/grid/grid.tsx +26 -2
  73. package/src/components/image/image.doc.mdx +44 -0
  74. package/src/components/image/image.props.ts +5 -0
  75. package/src/components/image/image.stories.tsx +49 -0
  76. package/src/components/image/image.tsx +19 -0
  77. package/src/components/input/input.doc.mdx +70 -0
  78. package/src/components/input/input.props.ts +34 -2
  79. package/src/components/input/input.tsx +29 -0
  80. package/src/components/layout/layout.doc.mdx +51 -0
  81. package/src/components/layout/layout.props.ts +5 -0
  82. package/src/components/layout/layout.tsx +41 -17
  83. package/src/components/loader/loader.doc.mdx +43 -0
  84. package/src/components/loader/loader.props.ts +4 -0
  85. package/src/components/loader/loader.tsx +17 -0
  86. package/src/components/navbar/navbar.doc.mdx +77 -0
  87. package/src/components/navbar/navbar.props.ts +37 -1
  88. package/src/components/navbar/navbar.stories.tsx +84 -0
  89. package/src/components/navbar/navbar.tsx +78 -46
  90. package/src/components/page/page.doc.mdx +80 -0
  91. package/src/components/page/page.props.ts +25 -0
  92. package/src/components/page/page.tsx +35 -7
  93. package/src/components/page-header/page-header.doc.mdx +54 -0
  94. package/src/components/page-header/page-header.props.ts +11 -0
  95. package/src/components/page-header/page-header.stories.tsx +14 -0
  96. package/src/components/page-header/page-header.tsx +50 -15
  97. package/src/components/pagination/pagination.doc.mdx +62 -0
  98. package/src/components/pagination/pagination.props.ts +11 -32
  99. package/src/components/pagination/pagination.tsx +17 -0
  100. package/src/components/popover/popover.doc.mdx +53 -0
  101. package/src/components/popover/popover.props.ts +8 -0
  102. package/src/components/popover/popover.tsx +13 -0
  103. package/src/components/progress/progress.doc.mdx +48 -0
  104. package/src/components/progress/progress.props.ts +8 -0
  105. package/src/components/progress/progress.tsx +9 -0
  106. package/src/components/radio/radio.doc.mdx +62 -0
  107. package/src/components/radio/radio.props.ts +11 -0
  108. package/src/components/radio/radio.tsx +18 -0
  109. package/src/components/search-select/search-select.doc.mdx +72 -0
  110. package/src/components/search-select/search-select.props.ts +23 -18
  111. package/src/components/search-select/search-select.tsx +27 -2
  112. package/src/components/searchTable/searchTable.doc.mdx +79 -0
  113. package/src/components/searchTable/searchTable.props.ts +42 -3
  114. package/src/components/searchTable/searchTable.stories.tsx +74 -0
  115. package/src/components/searchTable/searchTable.tsx +23 -0
  116. package/src/components/segmented-control/segmented-control.doc.mdx +60 -0
  117. package/src/components/segmented-control/segmented-control.props.ts +12 -0
  118. package/src/components/segmented-control/segmented-control.tsx +15 -0
  119. package/src/components/select/select.doc.mdx +75 -0
  120. package/src/components/select/select.props.ts +22 -0
  121. package/src/components/select/select.tsx +2 -5
  122. package/src/components/sidebar/sidebar.doc.mdx +86 -0
  123. package/src/components/sidebar/sidebar.props.ts +22 -0
  124. package/src/components/sidebar/sidebar.tsx +22 -0
  125. package/src/components/skeleton/skeleton.doc.mdx +43 -0
  126. package/src/components/skeleton/skeleton.props.ts +8 -0
  127. package/src/components/skeleton/skeleton.tsx +10 -0
  128. package/src/components/slide/slide.doc.mdx +46 -0
  129. package/src/components/slide/slide.props.ts +11 -24
  130. package/src/components/slide/slide.tsx +10 -1
  131. package/src/components/slider/slider.doc.mdx +49 -0
  132. package/src/components/slider/slider.props.ts +9 -0
  133. package/src/components/slider/slider.tsx +15 -0
  134. package/src/components/stack/stack.doc.mdx +126 -0
  135. package/src/components/stack/stack.props.ts +18 -0
  136. package/src/components/stack/stack.stories.tsx +221 -16
  137. package/src/components/stack/stack.tsx +21 -0
  138. package/src/components/stat-card/stat-card.doc.mdx +48 -0
  139. package/src/components/stat-card/stat-card.props.ts +9 -0
  140. package/src/components/stat-card/stat-card.tsx +10 -0
  141. package/src/components/stepper/stepper.doc.mdx +54 -0
  142. package/src/components/stepper/stepper.props.ts +11 -1
  143. package/src/components/stepper/stepper.tsx +15 -0
  144. package/src/components/table/table.doc.mdx +58 -0
  145. package/src/components/table/table.props.ts +17 -0
  146. package/src/components/table/table.tsx +199 -84
  147. package/src/components/tabs/tabs.doc.mdx +52 -0
  148. package/src/components/tabs/tabs.props.ts +11 -0
  149. package/src/components/tabs/tabs.tsx +14 -0
  150. package/src/components/text/text.doc.mdx +41 -0
  151. package/src/components/text/text.props.ts +5 -0
  152. package/src/components/text/text.stories.tsx +67 -0
  153. package/src/components/text/text.tsx +10 -0
  154. package/src/components/textarea/textarea.doc.mdx +64 -0
  155. package/src/components/textarea/textarea.props.ts +11 -0
  156. package/src/components/textarea/textarea.tsx +16 -0
  157. package/src/components/theme-provider/themeProvider.doc.mdx +75 -0
  158. package/src/components/theme-provider/themeProvider.props.ts +3 -0
  159. package/src/components/theme-provider/themeProvider.stories.tsx +59 -0
  160. package/src/components/theme-provider/themeProvider.tsx +14 -0
  161. package/src/components/time-picker/timePicker.doc.mdx +68 -0
  162. package/src/components/time-picker/timePicker.props.ts +14 -0
  163. package/src/components/time-picker/timePicker.tsx +22 -1
  164. package/src/components/toast/toast.doc.mdx +50 -0
  165. package/src/components/toast/toast.props.ts +5 -0
  166. package/src/components/toast/toast.tsx +21 -0
  167. package/src/components/tooltip/tooltip.doc.mdx +47 -0
  168. package/src/components/tooltip/tooltip.props.ts +6 -0
  169. package/src/components/tooltip/tooltip.tsx +19 -0
  170. package/src/components/topbar/topbar.doc.mdx +69 -0
  171. package/src/components/topbar/topbar.props.ts +15 -0
  172. package/src/components/topbar/topbar.tsx +38 -0
  173. package/src/components/triple-filter/tripleFilter.doc.mdx +62 -0
  174. package/src/components/triple-filter/tripleFilter.props.ts +7 -0
  175. package/src/components/triple-filter/tripleFilter.tsx +32 -0
  176. package/src/index.css +17 -0
  177. package/src/showcases/DataShowcases.tsx +529 -45
  178. package/src/showcases/FormShowcases.tsx +399 -29
  179. package/src/showcases/HomeShowcase.tsx +252 -272
  180. package/src/showcases/LayoutPrimitivesShowcases.tsx +1224 -248
  181. package/src/showcases/PageShowcases.tsx +868 -151
  182. package/src/showcases/ShowcaseLayout.tsx +237 -73
  183. package/src/showcases/StructureShowcases.tsx +1039 -97
  184. package/src/types/table.types.ts +1 -1
  185. package/src/utils/styles.ts +2 -1
@@ -1,4 +1,5 @@
1
1
  import React, { useState, ReactNode } from "react";
2
+ import { FaCode, FaTimes } from "react-icons/fa";
2
3
  import ITStack from "../components/stack/stack";
3
4
  import ITFlex from "../components/flex/flex";
4
5
  import ITGrid from "../components/grid/grid";
@@ -9,6 +10,9 @@ import ITAvatar from "../components/avatar/avatar";
9
10
  import ITSlider from "../components/slider/slider";
10
11
  import ITSegmentedControl from "../components/segmented-control/segmented-control";
11
12
  import ITSlideToggle from "../components/slide/slide";
13
+ import ITSelect from "../components/select/select";
14
+ import ITInput from "../components/input/input";
15
+ import ITText from "../components/text/text";
12
16
  import { ShowcaseLayout, CodeViewer } from "./ShowcaseLayout";
13
17
 
14
18
  const DemoBox = ({ children, className = "" }: { children: ReactNode; className?: string }) => (
@@ -28,84 +32,628 @@ const DemoCard = ({ children, className = "" }: { children: ReactNode; className
28
32
  // ─────────────────────────────────────────
29
33
  // 1. ITStack Showcase
30
34
  // ─────────────────────────────────────────
35
+
36
+ const alignOptions: { value: string; label: string }[] = [
37
+ { value: "start", label: "Start" },
38
+ { value: "center", label: "Center" },
39
+ { value: "end", label: "End" },
40
+ { value: "stretch", label: "Stretch" },
41
+ { value: "baseline", label: "Baseline" },
42
+ ];
43
+
44
+ const justifyOptions: { value: string; label: string }[] = [
45
+ { value: "start", label: "Start" },
46
+ { value: "center", label: "Center" },
47
+ { value: "end", label: "End" },
48
+ { value: "between", label: "Between" },
49
+ { value: "around", label: "Around" },
50
+ { value: "evenly", label: "Evenly" },
51
+ ];
52
+
53
+ // Cleaner demo box using inline gradient + soft shadow + numbered
54
+ const StackDemoItem = ({ index, size = "md" }: { index: number; size?: "sm" | "md" | "lg" }) => {
55
+ const sizeClasses = {
56
+ sm: "min-w-[48px] h-10 px-3 text-xs",
57
+ md: "min-w-[64px] h-14 px-4 text-sm",
58
+ lg: "min-w-[80px] h-20 px-5 text-base",
59
+ };
60
+ return (
61
+ <div
62
+ className={`${sizeClasses[size]} rounded-xl text-white font-semibold flex items-center justify-center`}
63
+ style={{
64
+ background: 'linear-gradient(135deg, var(--color-primary-500, #3b82f6) 0%, var(--color-primary-700, #1d4ed8) 100%)',
65
+ boxShadow: '0 4px 14px 0 rgba(59, 130, 246, 0.3)',
66
+ }}
67
+ >
68
+ Item {index}
69
+ </div>
70
+ );
71
+ };
72
+
73
+ // Soft chip-like demo for tag-cloud style
74
+ const StackChip = ({ label, color = "primary" }: { label: string; color?: "primary" | "success" | "warning" | "info" }) => {
75
+ const palettes = {
76
+ primary: "bg-primary-50 text-primary-700 border-primary-200 dark:bg-primary-900/30 dark:text-primary-300 dark:border-primary-800",
77
+ success: "bg-emerald-50 text-emerald-700 border-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-300 dark:border-emerald-800",
78
+ warning: "bg-amber-50 text-amber-700 border-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:border-amber-800",
79
+ info: "bg-sky-50 text-sky-700 border-sky-200 dark:bg-sky-900/30 dark:text-sky-300 dark:border-sky-800",
80
+ };
81
+ return (
82
+ <span className={`px-3 py-1.5 rounded-lg border text-xs font-medium ${palettes[color]}`}>
83
+ {label}
84
+ </span>
85
+ );
86
+ };
87
+
31
88
  export const StackShowcase = () => {
32
89
  const [direction, setDirection] = useState<"row" | "column">("column");
33
90
  const [spacing, setSpacing] = useState(3);
34
91
  const [withDivider, setWithDivider] = useState(false);
92
+ const [align, setAlign] = useState<string>("start");
93
+ const [justify, setJustify] = useState<string>("start");
94
+ const [wrapMode, setWrapMode] = useState<string>("nowrap");
35
95
 
36
- const code = `<ITStack direction="${direction}" spacing={${spacing}}${withDivider ? '\n divider={<div className="w-px h-8 bg-slate-200" />}' : ""}>\n <Demo>Item 1</Demo>\n <Demo>Item 2</Demo>\n <Demo>Item 3</Demo>\n</ITStack>`;
96
+ const PATTERN_CODES = {
97
+ pageHeader: `<ITStack
98
+ direction="row"
99
+ spacing={3}
100
+ justifyContent="between"
101
+ alignItems="center"
102
+ >
103
+ <div>
104
+ <p className="text-sm font-bold">Patient Records</p>
105
+ <p className="text-xs text-slate-500">128 active records</p>
106
+ </div>
107
+ <ITStack direction="row" spacing={2}>
108
+ <button className="px-3 py-1.5 rounded-lg border ...">
109
+ Export
110
+ </button>
111
+ <button className="px-3 py-1.5 rounded-lg bg-primary-600 ...">
112
+ + New Record
113
+ </button>
114
+ </ITStack>
115
+ </ITStack>`,
116
+ tagCloud: `<ITStack
117
+ direction="row"
118
+ spacing={2}
119
+ flexWrap="wrap"
120
+ >
121
+ {tags.map((tag) => (
122
+ <span
123
+ key={tag}
124
+ className="px-3 py-1.5 rounded-lg border ..."
125
+ >
126
+ {tag}
127
+ </span>
128
+ ))}
129
+ </ITStack>`,
130
+ sectionList: `<ITStack
131
+ spacing={0}
132
+ divider={
133
+ <div className="h-px bg-slate-200 dark:bg-slate-700 mx-3" />
134
+ }
135
+ >
136
+ {users.map((user) => (
137
+ <div
138
+ key={user.email}
139
+ className="flex items-center gap-3 py-3 px-4 ..."
140
+ >
141
+ <div className="w-9 h-9 rounded-full ...">{user.initial}</div>
142
+ <div className="flex-1 min-w-0">
143
+ <p className="text-sm font-semibold ...">{user.name}</p>
144
+ <p className="text-xs ...">{user.email}</p>
145
+ </div>
146
+ <span className="...">{user.status}</span>
147
+ </div>
148
+ ))}
149
+ </ITStack>`,
150
+ notification: `<ITStack
151
+ direction="row"
152
+ spacing={3}
153
+ alignItems="center"
154
+ className="p-4"
155
+ >
156
+ <div className="w-9 h-9 rounded-full bg-emerald-500 ... shrink-0">
157
+
158
+ </div>
159
+ <div className="flex-1 min-w-0">
160
+ <p className="text-sm font-semibold ...">Deployment successful</p>
161
+ <p className="text-xs ...">Your changes are live in production.</p>
162
+ </div>
163
+ <button className="w-7 h-7 ... shrink-0">×</button>
164
+ </ITStack>`,
165
+ statsRow: `<ITStack direction="row" spacing={3}>
166
+ {stats.map((stat) => (
167
+ <div
168
+ key={stat.label}
169
+ className="flex-1 min-w-0 rounded-xl p-3 ..."
170
+ >
171
+ <p className="text-[10px] uppercase ...">{stat.label}</p>
172
+ <p className="text-xl font-bold font-mono">{stat.value}</p>
173
+ <p className="text-[10px] ...">{stat.delta}</p>
174
+ </div>
175
+ ))}
176
+ </ITStack>`,
177
+ };
178
+
179
+ const buildCode = () => {
180
+ const props = [`direction="${direction}"`, `spacing={${spacing}}`];
181
+ if (align !== "start") props.push(`alignItems="${align}"`);
182
+ if (justify !== "start") props.push(`justifyContent="${justify}"`);
183
+ if (wrapMode !== "nowrap") props.push(`flexWrap="${wrapMode}"`);
184
+ if (withDivider) props.push(`divider={<hr className="border-slate-200 dark:border-slate-700" />}`);
185
+ return `<ITStack\n ${props.join("\n ")}\n>\n <Card>Item 1</Card>\n <Card>Item 2</Card>\n <Card>Item 3</Card>\n</ITStack>`;
186
+ };
37
187
 
38
188
  return (
39
189
  <ShowcaseLayout
40
190
  title="ITStack"
41
- description="Layout basado en flexbox con dirección y spacing uniforme. Ideal para secciones verticales, toolbars horizontales, y listas de items."
42
- code={code}
191
+ description="Layout basado en flexbox con dirección, spacing uniforme, alineación y distribución. Ideal para secciones verticales, toolbars horizontales, listas de items y form rows."
192
+ code={buildCode()}
193
+ doc={{
194
+ summary:
195
+ "ITStack is a simplified flexbox layout primitive that controls direction, spacing, alignment, and justification in a single component. Supports optional dividers between children and renders as any HTML element.",
196
+ description:
197
+ "Use ITStack everywhere you need consistent vertical or horizontal spacing. The gap is measured in 0.25rem units (Tailwind spacing scale). Combine with align and justify for centering, space-between distribution, or baseline alignment. Wrap mode enables responsive wrapping for tag clouds, filter chips, or toolbar buttons.",
198
+ examples: [
199
+ "<ITStack direction=\"row\" spacing={2} alignItems=\"center\">\n <ITButton>Cancel</ITButton>\n <ITButton color=\"primary\">Save</ITButton>\n</ITStack>",
200
+ "<ITStack spacing={4} divider={<hr />}>\n <div>Section A</div>\n <div>Section B</div>\n</ITStack>",
201
+ "<ITStack direction=\"row\" spacing={1} flexWrap=\"wrap\">\n {tags.map(t => <ITBadget key={t} label={t} />)}\n</ITStack>",
202
+ "<ITStack direction=\"row\" spacing={4} justifyContent=\"between\" alignItems=\"center\" className=\"w-full\">\n <h2>Page Title</h2>\n <ITButton label=\"Action\" />\n</ITStack>",
203
+ ],
204
+ props: [
205
+ { name: "children", type: "ReactNode", description: "Stack children elements." },
206
+ { name: "direction", type: '"row" | "column" | "row-reverse" | "column-reverse"', default: '"column"', description: "Flex direction." },
207
+ { name: "spacing", type: "number", default: "0", description: "Gap between children in 0.25rem units (0–12)." },
208
+ { name: "alignItems", type: '"start" | "end" | "center" | "stretch" | "baseline"', description: "Cross-axis (vertical in row, horizontal in column) alignment." },
209
+ { name: "justifyContent", type: '"start" | "end" | "center" | "between" | "around" | "evenly"', description: "Main-axis distribution of children." },
210
+ { name: "flexWrap", type: '"nowrap" | "wrap" | "wrap-reverse"', default: '"nowrap"', description: "Whether children wrap to the next line." },
211
+ { name: "divider", type: "ReactNode", description: "Optional element rendered between each pair of children." },
212
+ { name: "className", type: "string", description: "Additional CSS classes on the container." },
213
+ { name: "style", type: "CSSProperties", description: "Inline styles on the container." },
214
+ { name: "as", type: "ElementType", default: '"div"', description: "HTML element to render as (e.g. \"section\", \"nav\", \"ul\")." },
215
+ ],
216
+ notes: [
217
+ "Spacing is multiplied by 0.25rem internally — spacing={4} equals gap: 1rem.",
218
+ "The container is always display: flex — use direction to switch between vertical and horizontal.",
219
+ "Divider is cloned between children via React.cloneElement — it must be a single valid React element.",
220
+ "Set as=\"ul\" and wrap children in <li> for semantic list layouts.",
221
+ "For complex multi-axis layouts, use ITFlex instead of ITStack.",
222
+ ],
223
+ }}
43
224
  demo={
44
- <div className="w-full max-w-lg">
45
- <ITStack direction={direction} spacing={spacing} className="w-full" divider={withDivider ? <div className={`${direction === "row" ? "w-px h-8" : "h-px w-8"} bg-slate-200 dark:bg-slate-600 self-center`} /> : undefined}>
46
- <DemoBox>Item 1</DemoBox>
47
- <DemoBox>Item 2</DemoBox>
48
- <DemoBox>Item 3</DemoBox>
49
- </ITStack>
225
+ <div className="w-full max-w-xl flex flex-col">
226
+ <div className="min-h-[360px]">
227
+ <ITStack
228
+ direction={direction as any}
229
+ spacing={spacing}
230
+ className="w-full"
231
+ alignItems={align as any}
232
+ justifyContent={justify as any}
233
+ flexWrap={wrapMode as any}
234
+ divider={withDivider ? <div className={`${direction === "row" ? "w-px h-8" : "h-px w-full"} bg-slate-200 dark:bg-slate-700 self-stretch`} /> : undefined}
235
+ >
236
+ {[1, 2, 3, 4, 5, 6, 7, 8].map((i) => (
237
+ <div
238
+ key={i}
239
+ className="min-w-[80px] h-8 px-3 rounded-lg text-white text-xs font-semibold flex items-center justify-center shrink-0"
240
+ style={{
241
+ background: 'linear-gradient(135deg, var(--color-primary-500, #3b82f6) 0%, var(--color-primary-700, #1d4ed8) 100%)',
242
+ boxShadow: '0 4px 14px 0 rgba(59, 130, 246, 0.3)',
243
+ }}
244
+ >
245
+ Item {i}
246
+ </div>
247
+ ))}
248
+ </ITStack>
249
+ </div>
250
+
251
+ {/* Fixed footer with active-property badges */}
252
+ <div className="sticky bottom-0 mt-4 -mx-6 -mb-6 px-6 py-3 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-t border-slate-200 dark:border-slate-700 flex items-center flex-wrap gap-1.5 text-[10px] font-mono">
253
+ <span className="text-[9px] uppercase tracking-wider font-bold text-slate-400 dark:text-slate-500 mr-1">Active:</span>
254
+ <span className="px-2 py-0.5 rounded-md bg-slate-900 text-white dark:bg-white dark:text-slate-900 font-semibold">{direction}</span>
255
+ <span className="px-2 py-0.5 rounded-md bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300">gap:{spacing}</span>
256
+ {align !== "start" && <span className="px-2 py-0.5 rounded-md bg-primary-100 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300">align:{align}</span>}
257
+ {justify !== "start" && <span className="px-2 py-0.5 rounded-md bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300">justify:{justify}</span>}
258
+ {wrapMode !== "nowrap" && <span className="px-2 py-0.5 rounded-md bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-300">{wrapMode}</span>}
259
+ {withDivider && <span className="px-2 py-0.5 rounded-md bg-sky-100 dark:bg-sky-900/30 text-sky-700 dark:text-sky-300">divider</span>}
260
+ </div>
50
261
  </div>
51
262
  }
52
263
  controls={
53
264
  <>
54
- <ITSegmentedControl
55
- options={[
56
- { value: "column", label: "Column" },
57
- { value: "row", label: "Row" },
58
- ]}
59
- value={direction}
60
- onChange={(v) => setDirection(v as "row" | "column")}
265
+ <div>
266
+ <p className="text-xs font-semibold text-slate-500 dark:text-slate-400 mb-1.5 uppercase tracking-wider">Direction</p>
267
+ <ITSegmentedControl
268
+ options={[
269
+ { value: "column", label: "Column" },
270
+ { value: "row", label: "Row" },
271
+ { value: "row-reverse", label: "Row ↩" },
272
+ { value: "column-reverse", label: "Column ↩" },
273
+ ]}
274
+ value={direction}
275
+ onChange={(v) => setDirection(v as any)}
276
+ />
277
+ </div>
278
+ <ITSlider label="Spacing (0.25rem units)" value={spacing} onChange={setSpacing} min={0} max={12} />
279
+ <ITSelect
280
+ name="align_items"
281
+ label="Align Items"
282
+ value={align}
283
+ onChange={(e) => setAlign(e.target.value)}
284
+ options={alignOptions}
61
285
  />
62
- <ITSlider label="Spacing" value={spacing} onChange={setSpacing} min={0} max={10} />
286
+ <ITSelect
287
+ name="justify_content"
288
+ label="Justify Content"
289
+ value={justify}
290
+ onChange={(e) => setJustify(e.target.value)}
291
+ options={justifyOptions}
292
+ />
293
+ <div>
294
+ <p className="text-xs font-semibold text-slate-500 dark:text-slate-400 mb-1.5 uppercase tracking-wider">Flex Wrap</p>
295
+ <ITSegmentedControl
296
+ options={[
297
+ { value: "nowrap", label: "Nowrap" },
298
+ { value: "wrap", label: "Wrap" },
299
+ { value: "wrap-reverse", label: "Reverse" },
300
+ ]}
301
+ value={wrapMode}
302
+ onChange={(v) => setWrapMode(v as string)}
303
+ />
304
+ </div>
63
305
  <ITFlex justify="between" align="center">
64
- <span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Con Divisor</span>
306
+ <span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Show divider</span>
65
307
  <ITSlideToggle isOn={withDivider} onToggle={setWithDivider} size="sm" />
66
308
  </ITFlex>
67
309
  </>
68
310
  }
69
311
  gallery={
70
- <ITStack spacing={4}>
71
- {/* Row examples */}
72
- <div>
73
- <p className="text-xs font-semibold text-slate-400 mb-2 uppercase tracking-wider">Horizontal — spacing=2</p>
74
- <ITStack direction="row" spacing={2}>
75
- <DemoBox>Uno</DemoBox><DemoBox>Dos</DemoBox><DemoBox>Tres</DemoBox>
76
- </ITStack>
77
- </div>
78
- {/* Center aligned row */}
79
- <div>
80
- <p className="text-xs font-semibold text-slate-400 mb-2 uppercase tracking-wider">Row + center alignment</p>
81
- <ITStack direction="row" spacing={4} alignItems="center" justifyContent="center" className="bg-slate-50 dark:bg-slate-900/50 rounded-xl p-4">
82
- <DemoBox className="!bg-emerald-100 !text-emerald-700">Item A</DemoBox>
83
- <DemoBox className="!bg-purple-100 !text-purple-700">Item B</DemoBox>
84
- <DemoBox className="!bg-amber-100 !text-amber-700">Item C</DemoBox>
85
- </ITStack>
86
- </div>
87
- {/* Vertical with divider */}
88
- <div>
89
- <p className="text-xs font-semibold text-slate-400 mb-2 uppercase tracking-wider">Vertical + divider</p>
90
- <ITStack spacing={2} divider={<div className="h-px bg-slate-200 dark:bg-slate-700" />}>
91
- <DemoBox>Sección 1</DemoBox>
92
- <DemoBox>Sección 2</DemoBox>
93
- <DemoBox>Sección 3</DemoBox>
94
- </ITStack>
95
- </div>
312
+ <ITStack spacing={8}>
313
+ {/* ── Section 1: Spacing Scale ── */}
314
+ <GallerySection
315
+ title="Spacing Scale"
316
+ subtitle="Try different gap values to feel the rhythm"
317
+ >
318
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
319
+ {[
320
+ { gap: 1, label: "Tight", desc: "Compact UI" },
321
+ { gap: 3, label: "Default", desc: "Comfortable" },
322
+ { gap: 6, label: "Relaxed", desc: "Breathing room" },
323
+ { gap: 10, label: "Spacious", desc: "Hero sections" },
324
+ ].map((s) => (
325
+ <div key={s.gap} className="bg-white dark:bg-slate-800/60 rounded-2xl border border-slate-200 dark:border-slate-700 p-5 shadow-sm">
326
+ <div className="flex items-center justify-between mb-3">
327
+ <span className="text-xs font-semibold text-slate-700 dark:text-slate-200">{s.label}</span>
328
+ <span className="text-[10px] font-mono text-slate-400">spacing={s.gap} • {(s.gap * 0.25).toFixed(2)}rem</span>
329
+ </div>
330
+ <p className="text-[11px] text-slate-400 mb-4">{s.desc}</p>
331
+ <ITStack direction="row" spacing={s.gap}>
332
+ <StackDemoItem index={1} size="sm" />
333
+ <StackDemoItem index={2} size="sm" />
334
+ <StackDemoItem index={3} size="sm" />
335
+ </ITStack>
336
+ </div>
337
+ ))}
338
+ </div>
339
+ </GallerySection>
340
+
341
+ {/* ── Section 2: Justify Content ── */}
342
+ <GallerySection
343
+ title="Justify Content"
344
+ subtitle="How children are distributed along the main axis"
345
+ >
346
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
347
+ {[
348
+ { label: "start", desc: "Children packed at the start" },
349
+ { label: "center", desc: "Children centered on the axis" },
350
+ { label: "end", desc: "Children packed at the end" },
351
+ { label: "between", desc: "First/last at edges, rest spread evenly" },
352
+ { label: "around", desc: "Equal space around each child" },
353
+ { label: "evenly", desc: "Equal space everywhere" },
354
+ ].map((j) => (
355
+ <div key={j.label} className="bg-white dark:bg-slate-800/60 rounded-2xl border border-slate-200 dark:border-slate-700 p-5 shadow-sm">
356
+ <div className="flex items-center justify-between mb-1">
357
+ <code className="text-xs font-mono font-bold text-primary-600 dark:text-primary-400">justifyContent="{j.label}"</code>
358
+ </div>
359
+ <p className="text-[11px] text-slate-400 mb-3">{j.desc}</p>
360
+ <div className="bg-slate-50 dark:bg-slate-900/50 rounded-lg p-3 border border-dashed border-slate-200 dark:border-slate-700">
361
+ <ITStack direction="row" spacing={2} justifyContent={j.label as any} className="w-full">
362
+ <StackDemoItem index={1} size="sm" />
363
+ <StackDemoItem index={2} size="sm" />
364
+ <StackDemoItem index={3} size="sm" />
365
+ </ITStack>
366
+ </div>
367
+ </div>
368
+ ))}
369
+ </div>
370
+ </GallerySection>
371
+
372
+ {/* ── Section 3: Align Items ── */}
373
+ <GallerySection
374
+ title="Align Items"
375
+ subtitle="How children are aligned on the cross axis"
376
+ >
377
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
378
+ {[
379
+ { label: "start", desc: "Aligned to top (in row)" },
380
+ { label: "center", desc: "Centered on cross axis" },
381
+ { label: "end", desc: "Aligned to bottom (in row)" },
382
+ { label: "stretch", desc: "Children fill cross axis" },
383
+ { label: "baseline", desc: "Text baselines align" },
384
+ ].map((a) => (
385
+ <div key={a.label} className="bg-white dark:bg-slate-800/60 rounded-2xl border border-slate-200 dark:border-slate-700 p-5 shadow-sm">
386
+ <div className="flex items-center justify-between mb-1">
387
+ <code className="text-xs font-mono font-bold text-emerald-600 dark:text-emerald-400">alignItems="{a.label}"</code>
388
+ </div>
389
+ <p className="text-[11px] text-slate-400 mb-3">{a.desc}</p>
390
+ <div className="bg-slate-50 dark:bg-slate-900/50 rounded-lg p-3 border border-dashed border-slate-200 dark:border-slate-700">
391
+ <ITStack direction="row" spacing={3} alignItems={a.label as any} className="h-24">
392
+ <StackDemoItem index={1} size="sm" />
393
+ <div className="min-w-[64px] h-14 px-4 text-white rounded-xl flex items-center justify-center font-semibold text-sm"
394
+ style={{
395
+ background: 'linear-gradient(135deg, var(--color-success-500, #10b981) 0%, var(--color-success-700, #047857) 100%)',
396
+ boxShadow: '0 4px 14px 0 rgba(16, 185, 129, 0.3)',
397
+ }}
398
+ >
399
+ Mid
400
+ </div>
401
+ <StackDemoItem index={3} size="sm" />
402
+ </ITStack>
403
+ </div>
404
+ </div>
405
+ ))}
406
+ </div>
407
+ </GallerySection>
408
+
409
+ {/* ── Section 4: Real UI cases ── */}
410
+ <GallerySection
411
+ title="Real UI cases"
412
+ subtitle="Production-ready UI built entirely with ITStack"
413
+ >
414
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-5">
415
+ {/* Page header with actions */}
416
+ <PatternCard title="Page Header" desc="Title + actions on the right" code={PATTERN_CODES.pageHeader}>
417
+ <div className="rounded-xl p-4 border border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-800/80">
418
+ <ITStack direction="row" spacing={3} justifyContent="between" alignItems="center">
419
+ <div>
420
+ <p className="text-sm font-bold text-slate-800 dark:text-slate-100">Patient Records</p>
421
+ <p className="text-xs text-slate-500 dark:text-slate-400">128 active records</p>
422
+ </div>
423
+ <ITStack direction="row" spacing={2}>
424
+ <ITButton variant="outlined" color="gray" size="small">
425
+ Export
426
+ </ITButton>
427
+ <ITButton variant="filled" color="primary" size="small">
428
+ + New Record
429
+ </ITButton>
430
+ </ITStack>
431
+ </ITStack>
432
+ </div>
433
+ </PatternCard>
434
+
435
+ {/* Tag cloud */}
436
+ <PatternCard title="Tag Cloud" desc="Wrap enabled for flowing tags" code={PATTERN_CODES.tagCloud}>
437
+ <div className="rounded-xl p-4 border border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-800/80">
438
+ <ITStack direction="row" spacing={2} flexWrap="wrap">
439
+ <StackChip label="React" color="primary" />
440
+ <StackChip label="TypeScript" color="success" />
441
+ <StackChip label="Tailwind" color="info" />
442
+ <StackChip label="Storybook" color="warning" />
443
+ <StackChip label="Vite" color="primary" />
444
+ <StackChip label="CSS Vars" color="info" />
445
+ <StackChip label="Flexbox" color="success" />
446
+ <StackChip label="Accessibility" color="warning" />
447
+ </ITStack>
448
+ </div>
449
+ </PatternCard>
450
+
451
+ {/* Section list with dividers */}
452
+ <PatternCard title="Section List" desc="Subtle divider between items" code={PATTERN_CODES.sectionList}>
453
+ <div className="rounded-xl p-2 border border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-800/80">
454
+ <ITStack spacing={0} divider={<div className="h-px bg-slate-200 dark:bg-slate-700 mx-3" />}>
455
+ {[
456
+ { initial: "JD", name: "John Doe", email: "john@axzy.dev", status: "Active", color: "primary" },
457
+ { initial: "AS", name: "Anna Smith", email: "anna@axzy.dev", status: "Pending", color: "warning" },
458
+ { initial: "MK", name: "Mike Kim", email: "mike@axzy.dev", status: "Active", color: "success" },
459
+ ].map((user) => (
460
+ <div key={user.email} className="flex items-center gap-3 py-3 px-4 hover:bg-white/60 dark:hover:bg-slate-800/60 rounded-lg transition-colors">
461
+ <div className="w-9 h-9 rounded-full flex items-center justify-center text-white font-semibold text-xs"
462
+ style={{
463
+ background: 'linear-gradient(135deg, var(--color-primary-500, #3b82f6) 0%, var(--color-primary-700, #1d4ed8) 100%)',
464
+ boxShadow: '0 2px 8px 0 rgba(59, 130, 246, 0.25)',
465
+ }}
466
+ >
467
+ {user.initial}
468
+ </div>
469
+ <div className="flex-1 min-w-0">
470
+ <p className="text-sm font-semibold text-slate-800 dark:text-slate-100 truncate">{user.name}</p>
471
+ <p className="text-xs text-slate-500 dark:text-slate-400 truncate">{user.email}</p>
472
+ </div>
473
+ <span className={`px-2.5 py-1 rounded-md text-[10px] font-semibold uppercase tracking-wider ${
474
+ user.color === "primary" ? "bg-primary-100 text-primary-700 dark:bg-primary-900/40 dark:text-primary-300" :
475
+ user.color === "warning" ? "bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300" :
476
+ "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300"
477
+ }`}>
478
+ {user.status}
479
+ </span>
480
+ </div>
481
+ ))}
482
+ </ITStack>
483
+ </div>
484
+ </PatternCard>
485
+
486
+ {/* Notification banner */}
487
+ <PatternCard title="Notification banner" desc="Icon + message + dismiss" code={PATTERN_CODES.notification}>
488
+ <div className="rounded-xl border border-emerald-200 dark:border-emerald-800/50 overflow-hidden bg-emerald-50 dark:bg-emerald-950/40">
489
+ <ITStack direction="row" spacing={3} alignItems="center" className="p-4">
490
+ <div className="w-9 h-9 rounded-full bg-emerald-500 flex items-center justify-center text-white shrink-0 shadow-sm">
491
+ <span className="text-base font-bold leading-none">✓</span>
492
+ </div>
493
+ <div className="flex-1 min-w-0">
494
+ <p className="text-sm font-semibold text-emerald-900 dark:text-emerald-200">Deployment successful</p>
495
+ <p className="text-xs text-emerald-700 dark:text-emerald-400 mt-0.5">Your changes are live in production.</p>
496
+ </div>
497
+ <ITButton variant="icon-only" color="gray" size="small">
498
+ <span className="text-lg leading-none">×</span>
499
+ </ITButton>
500
+ </ITStack>
501
+ </div>
502
+ </PatternCard>
503
+
504
+ {/* Stats row */}
505
+ <PatternCard title="Stats row" desc="3 metric cards in one row" code={PATTERN_CODES.statsRow}>
506
+ <div className="rounded-xl p-4 border border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-800/80">
507
+ <ITStack direction="row" spacing={3}>
508
+ {[
509
+ { label: "Revenue", value: "$48.2k", delta: "+12.4%", color: "emerald" },
510
+ { label: "Active users", value: "2,847", delta: "+5.1%", color: "primary" },
511
+ { label: "Conversion", value: "3.24%", delta: "−0.8%", color: "amber" },
512
+ ].map((stat) => (
513
+ <div key={stat.label} className="flex-1 min-w-0 bg-white dark:bg-slate-800 rounded-xl p-3 border border-slate-200 dark:border-slate-700 shadow-sm">
514
+ <p className="text-[10px] uppercase tracking-wider font-semibold text-slate-500 dark:text-slate-400">{stat.label}</p>
515
+ <p className="text-xl font-bold text-slate-800 dark:text-slate-100 mt-1 font-mono">{stat.value}</p>
516
+ <p className={`text-[10px] font-semibold mt-0.5 ${
517
+ stat.color === "emerald" ? "text-emerald-600 dark:text-emerald-400" :
518
+ stat.color === "amber" ? "text-amber-600 dark:text-amber-400" :
519
+ "text-primary-600 dark:text-primary-400"
520
+ }`}>{stat.delta}</p>
521
+ </div>
522
+ ))}
523
+ </ITStack>
524
+ </div>
525
+ </PatternCard>
526
+ </div>
527
+ </GallerySection>
96
528
  </ITStack>
97
529
  }
98
530
  />
99
531
  );
100
532
  };
101
533
 
534
+ // ── Helper components ──
535
+
536
+ const GallerySection = ({ title, subtitle, children }: { title: string; subtitle?: string; children: React.ReactNode }) => (
537
+ <div>
538
+ <div className="mb-5">
539
+ <h3 className="text-base font-bold text-slate-800 dark:text-slate-100 flex items-center gap-2">
540
+ <span className="w-1 h-5 rounded-full bg-gradient-to-b from-primary-500 to-primary-700" />
541
+ {title}
542
+ </h3>
543
+ {subtitle && <p className="text-xs text-slate-500 dark:text-slate-400 mt-1 ml-3">{subtitle}</p>}
544
+ </div>
545
+ {children}
546
+ </div>
547
+ );
548
+
549
+ const PatternCard = ({ title, desc, code, children }: { title: string; desc?: string; code?: string; children: React.ReactNode }) => {
550
+ const [showCode, setShowCode] = useState(false);
551
+ return (
552
+ <div className="bg-white dark:bg-slate-900/60 rounded-2xl border border-slate-200 dark:border-slate-700 shadow-sm hover:shadow-md transition-shadow overflow-hidden">
553
+ <div className="flex items-start justify-between gap-2 p-4 pb-3">
554
+ <div className="min-w-0">
555
+ <p className="text-sm font-semibold text-slate-800 dark:text-slate-100">{title}</p>
556
+ {desc && <p className="text-[11px] text-slate-500 dark:text-slate-400 mt-0.5">{desc}</p>}
557
+ </div>
558
+ {code && (
559
+ <ITButton variant="outlined" color="gray" size="small" onClick={() => setShowCode(!showCode)}>
560
+ <ITFlex align="center" gap={1}>
561
+ <FaCode size={9} />
562
+ {showCode ? "Hide code" : "Code"}
563
+ </ITFlex>
564
+ </ITButton>
565
+ )}
566
+ </div>
567
+ <div className="px-4 pb-4">{children}</div>
568
+ {showCode && code && (
569
+ <div className="px-4 pb-4 border-t border-slate-200 dark:border-slate-700 pt-3">
570
+ <CodeViewer code={code} compact />
571
+ </div>
572
+ )}
573
+ </div>
574
+ );
575
+ };
576
+
102
577
  // ─────────────────────────────────────────
103
578
  // 2. ITFlex Showcase
104
579
  // ─────────────────────────────────────────
580
+
581
+ const FLEX_PATTERN_CODES = {
582
+ spaceBetween: `<ITFlex
583
+ direction="row"
584
+ justify="between"
585
+ align="center"
586
+ gap={3}
587
+ >
588
+ <ITFlex direction="column" gap={0}>
589
+ <p>Document.pdf</p>
590
+ <p>Last edited 2 min ago</p>
591
+ </ITFlex>
592
+ <ITFlex direction="row" gap={2}>
593
+ <ITButton label="Cancel" variant="outlined" color="gray" size="small" />
594
+ <ITButton label="Save" variant="filled" color="primary" size="small" />
595
+ </ITFlex>
596
+ </ITFlex>`,
597
+ growItems: `<ITFlex direction="row" gap={3}>
598
+ <ITFlex grow direction="column" className="...">
599
+ Sidebar
600
+ </ITFlex>
601
+ <ITFlex grow direction="column" className="...">
602
+ Content
603
+ </ITFlex>
604
+ <div className="...">Fixed</div>
605
+ </ITFlex>`,
606
+ centeredCard: `<ITFlex
607
+ direction="column"
608
+ justify="center"
609
+ align="center"
610
+ gap={3}
611
+ className="min-h-56 text-center px-6 py-6"
612
+ >
613
+ <div className="w-14 h-14 rounded-2xl ...">✦</div>
614
+ <div>
615
+ <p className="text-lg font-bold ...">All set!</p>
616
+ <p className="text-xs ...">Your workspace is ready to use.</p>
617
+ </div>
618
+ <ITButton label="Get started" variant="filled" color="primary" size="small" />
619
+ </ITFlex>`,
620
+ formRowWrap: `<ITFlex
621
+ direction="row"
622
+ wrap="wrap"
623
+ gap={3}
624
+ >
625
+ {fields.map((f) => (
626
+ <ITFlex
627
+ key={f.label}
628
+ grow
629
+ basis={56}
630
+ direction="column"
631
+ gap={1}
632
+ >
633
+ <label>{f.label}</label>
634
+ <input />
635
+ </ITFlex>
636
+ ))}
637
+ </ITFlex>`,
638
+ stretchColumn: `<ITFlex
639
+ direction="column"
640
+ align="stretch"
641
+ gap={0}
642
+ className="h-full"
643
+ >
644
+ <div className="h-12 ...">Header</div>
645
+ <ITFlex grow align="center" justify="center" direction="column">
646
+ Main content
647
+ </ITFlex>
648
+ <div className="h-12 ...">Footer</div>
649
+ </ITFlex>`,
650
+ };
651
+
105
652
  export const FlexShowcase = () => {
106
- const [direction, setDirection] = useState<"row" | "column">("row");
653
+ const [direction, setDirection] = useState<"row" | "column" | "row-reverse" | "column-reverse">("row");
107
654
  const [justify, setJustify] = useState("start");
108
655
  const [align, setAlign] = useState("center");
656
+ const [wrap, setWrap] = useState("nowrap");
109
657
  const [gap, setGap] = useState(3);
110
658
 
111
659
  const justifyOptions = [
@@ -114,82 +662,216 @@ export const FlexShowcase = () => {
114
662
  { value: "end", label: "End" },
115
663
  { value: "between", label: "Between" },
116
664
  { value: "around", label: "Around" },
665
+ { value: "evenly", label: "Evenly" },
117
666
  ];
118
667
 
119
- const code = `<ITFlex direction="${direction}" justify="${justify}" align="${align}" gap={${gap}}>\n <Box>Item 1</Box>\n <Box>Item 2</Box>\n <Box>Item 3</Box>\n</ITFlex>`;
668
+ const buildCode = () => {
669
+ const props = [`direction="${direction}"`];
670
+ if (justify !== "start") props.push(`justify="${justify}"`);
671
+ if (align !== "stretch") props.push(`align="${align}"`);
672
+ if (wrap !== "nowrap") props.push(`wrap="${wrap}"`);
673
+ if (gap !== 0) props.push(`gap={${gap}}`);
674
+ return `<ITFlex\n ${props.join("\n ")}\n>\n <Box>Item 1</Box>\n <Box>Item 2</Box>\n <Box>Item 3</Box>\n</ITFlex>`;
675
+ };
120
676
 
121
677
  return (
122
678
  <ShowcaseLayout
123
679
  title="ITFlex"
124
680
  description="Contenedor flexbox completo con control total sobre alineación, distribución y gap. Para layouts complejos que requieren más control que ITStack."
125
- code={code}
681
+ code={buildCode()}
126
682
  demo={
127
- <div className="w-full">
128
- <ITFlex direction={direction} justify={justify as any} align={align as any} gap={gap} className="bg-slate-50 dark:bg-slate-900/50 rounded-xl p-4 min-h-[100px] border border-dashed border-slate-200 dark:border-slate-700">
129
- <DemoBox className="!bg-blue-100 !text-blue-700">Flex 1</DemoBox>
130
- <DemoBox className="!bg-emerald-100 !text-emerald-700">Flex 2</DemoBox>
131
- <DemoBox className="!bg-purple-100 !text-purple-700">Flex 3</DemoBox>
132
- </ITFlex>
683
+ <div className="w-full max-w-xl flex flex-col">
684
+ <div className="min-h-[360px]">
685
+ <ITFlex
686
+ direction={direction as any}
687
+ justify={justify as any}
688
+ align={align as any}
689
+ wrap={wrap as any}
690
+ gap={gap}
691
+ className="w-full bg-slate-50 dark:bg-slate-900/50 rounded-xl p-4 border border-dashed border-slate-200 dark:border-slate-700"
692
+ >
693
+ {[1, 2, 3, 4].map((i) => (
694
+ <div
695
+ key={i}
696
+ className="min-w-[80px] h-8 px-3 rounded-lg text-white text-xs font-semibold flex items-center justify-center shrink-0"
697
+ style={{
698
+ background: 'linear-gradient(135deg, var(--color-primary-500, #3b82f6) 0%, var(--color-primary-700, #1d4ed8) 100%)',
699
+ boxShadow: '0 4px 14px 0 rgba(59, 130, 246, 0.3)',
700
+ }}
701
+ >
702
+ Item {i}
703
+ </div>
704
+ ))}
705
+ </ITFlex>
706
+ </div>
707
+
708
+ {/* Fixed footer with active-property badges */}
709
+ <div className="sticky bottom-0 mt-4 -mx-6 -mb-6 px-6 py-3 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-t border-slate-200 dark:border-slate-700 flex items-center flex-wrap gap-1.5 text-[10px] font-mono">
710
+ <span className="text-[9px] uppercase tracking-wider font-bold text-slate-400 dark:text-slate-500 mr-1">Active:</span>
711
+ <span className="px-2 py-0.5 rounded-md bg-slate-900 text-white dark:bg-white dark:text-slate-900 font-semibold">{direction}</span>
712
+ <span className="px-2 py-0.5 rounded-md bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300">gap:{gap}</span>
713
+ {justify !== "start" && <span className="px-2 py-0.5 rounded-md bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300">justify:{justify}</span>}
714
+ {align !== "stretch" && <span className="px-2 py-0.5 rounded-md bg-primary-100 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300">align:{align}</span>}
715
+ {wrap !== "nowrap" && <span className="px-2 py-0.5 rounded-md bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-300">{wrap}</span>}
716
+ </div>
133
717
  </div>
134
718
  }
135
719
  controls={
136
720
  <ITStack spacing={4}>
137
- <ITSegmentedControl
721
+ <div>
722
+ <p className="text-xs font-semibold text-slate-500 dark:text-slate-400 mb-1.5 uppercase tracking-wider">Direction</p>
723
+ <ITSegmentedControl
724
+ options={[
725
+ { value: "row", label: "Row" },
726
+ { value: "column", label: "Column" },
727
+ { value: "row-reverse", label: "Row ↩" },
728
+ { value: "column-reverse", label: "Col ↩" },
729
+ ]}
730
+ value={direction}
731
+ onChange={(v) => setDirection(v as any)}
732
+ size="sm"
733
+ />
734
+ </div>
735
+ <ITSelect
736
+ name="flex_justify"
737
+ label="Justify Content"
738
+ value={justify}
739
+ onChange={(e) => setJustify(e.target.value)}
740
+ options={justifyOptions}
741
+ />
742
+ <ITSelect
743
+ name="flex_align"
744
+ label="Align Items"
745
+ value={align}
746
+ onChange={(e) => setAlign(e.target.value)}
138
747
  options={[
139
- { value: "row", label: "Row" },
140
- { value: "column", label: "Column" },
141
- { value: "row-reverse", label: "Row Rev" },
142
- { value: "column-reverse", label: "Col Rev" },
748
+ { label: "Start", value: "start" },
749
+ { label: "Center", value: "center" },
750
+ { label: "End", value: "end" },
751
+ { label: "Stretch", value: "stretch" },
752
+ { label: "Baseline", value: "baseline" },
143
753
  ]}
144
- value={direction}
145
- onChange={(v) => setDirection(v as any)}
146
- size="sm"
147
754
  />
148
- <ITStack spacing={2}>
149
- <span className="text-xs font-semibold text-slate-600">Justify</span>
150
- <ITSegmentedControl
151
- options={justifyOptions.map(o => ({ value: o.value, label: o.label }))}
152
- value={justify}
153
- onChange={setJustify}
154
- />
155
- </ITStack>
156
- <ITStack spacing={2}>
157
- <span className="text-xs font-semibold text-slate-600">Align</span>
755
+ <div>
756
+ <p className="text-xs font-semibold text-slate-500 dark:text-slate-400 mb-1.5 uppercase tracking-wider">Flex Wrap</p>
158
757
  <ITSegmentedControl
159
- options={["start", "center", "end", "stretch"].map(a => ({ value: a, label: a.charAt(0).toUpperCase() + a.slice(1) }))}
160
- value={align}
161
- onChange={setAlign}
758
+ options={[
759
+ { value: "nowrap", label: "Nowrap" },
760
+ { value: "wrap", label: "Wrap" },
761
+ { value: "wrap-reverse", label: "Reverse" },
762
+ ]}
763
+ value={wrap}
764
+ onChange={(v) => setWrap(v as string)}
162
765
  />
163
- </ITStack>
164
- <ITSlider label="Gap" value={gap} onChange={setGap} min={0} max={10} />
766
+ </div>
767
+ <ITSlider label="Gap (0.25rem units)" value={gap} onChange={setGap} min={0} max={12} />
165
768
  </ITStack>
166
769
  }
167
770
  gallery={
168
- <ITStack spacing={6}>
169
- <div>
170
- <p className="text-xs font-semibold text-slate-400 mb-2 uppercase tracking-wider">Space-Between Row</p>
171
- <ITFlex justify="between" className="bg-slate-50 dark:bg-slate-900/50 rounded-lg p-3">
172
- <DemoBox className="!w-20">Left</DemoBox>
173
- <DemoBox className="!w-20">Center</DemoBox>
174
- <DemoBox className="!w-20">Right</DemoBox>
175
- </ITFlex>
176
- </div>
177
- <div>
178
- <p className="text-xs font-semibold text-slate-400 mb-2 uppercase tracking-wider">Grow Items</p>
179
- <ITFlex gap={3}>
180
- <ITFlex grow className="bg-blue-100 dark:bg-blue-900/30 rounded-lg p-3 text-center text-sm text-blue-700">Grow</ITFlex>
181
- <ITFlex grow className="bg-emerald-100 dark:bg-emerald-900/30 rounded-lg p-3 text-center text-sm text-emerald-700">Grow</ITFlex>
182
- <div className="bg-slate-100 dark:bg-slate-800 rounded-lg p-3 text-center text-sm text-slate-500">Fixed</div>
183
- </ITFlex>
184
- </div>
185
- <div>
186
- <p className="text-xs font-semibold text-slate-400 mb-2 uppercase tracking-wider">Column Layout</p>
187
- <ITFlex direction="column" gap={2} className="bg-slate-50 dark:bg-slate-900/50 rounded-lg p-3">
188
- <DemoBox className="!w-full">Stacked 1</DemoBox>
189
- <DemoBox className="!w-full">Stacked 2</DemoBox>
190
- <DemoBox className="!w-full">Stacked 3</DemoBox>
191
- </ITFlex>
192
- </div>
771
+ <ITStack spacing={8}>
772
+ {/* ── Section 1: Real UI cases ── */}
773
+ <GallerySection
774
+ title="Real UI cases"
775
+ subtitle="Production-ready UI built entirely with ITFlex"
776
+ >
777
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-5">
778
+ {/* Space-between row */}
779
+ <PatternCard title="Toolbar row" desc="justify-between + nested actions" code={FLEX_PATTERN_CODES.spaceBetween}>
780
+ <div className="rounded-xl p-4 border border-slate-200 dark:border-slate-700 overflow-x-auto bg-slate-50 dark:bg-slate-800/80">
781
+ <ITFlex direction="row" justify="between" align="center" gap={3}>
782
+ <ITFlex direction="column" gap={0}>
783
+ <p className="text-sm font-bold text-slate-800 dark:text-slate-100">Document.pdf</p>
784
+ <p className="text-[11px] text-slate-500 dark:text-slate-400">Last edited 2 min ago</p>
785
+ </ITFlex>
786
+ <ITFlex direction="row" gap={2}>
787
+ <ITButton label="Cancel" variant="outlined" color="gray" size="small" />
788
+ <ITButton label="Save" variant="filled" color="primary" size="small" />
789
+ </ITFlex>
790
+ </ITFlex>
791
+ </div>
792
+ </PatternCard>
793
+
794
+ {/* Grow items */}
795
+ <PatternCard title="Grow layout" desc="flex-grow distributes remaining space" code={FLEX_PATTERN_CODES.growItems}>
796
+ <div className="rounded-xl p-4 border border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-800/80">
797
+ <ITFlex direction="row" gap={3}>
798
+ <ITFlex grow direction="column" gap={1} className="bg-blue-100 dark:bg-blue-900/30 rounded-xl p-4">
799
+ <p className="text-[10px] uppercase tracking-wider font-semibold text-blue-600 dark:text-blue-400">Sidebar</p>
800
+ <p className="text-sm font-semibold text-blue-900 dark:text-blue-200">Navigation</p>
801
+ </ITFlex>
802
+ <ITFlex grow direction="column" gap={1} className="bg-emerald-100 dark:bg-emerald-900/30 rounded-xl p-4">
803
+ <p className="text-[10px] uppercase tracking-wider font-semibold text-emerald-600 dark:text-emerald-400">Content</p>
804
+ <p className="text-sm font-semibold text-emerald-900 dark:text-emerald-200">Main area</p>
805
+ </ITFlex>
806
+ <div className="bg-slate-100 dark:bg-slate-800 rounded-xl p-4 text-center">
807
+ <p className="text-[10px] uppercase tracking-wider font-semibold text-slate-500 dark:text-slate-400">Fixed</p>
808
+ <p className="text-sm font-semibold text-slate-700 dark:text-slate-300 mt-1">100px</p>
809
+ </div>
810
+ </ITFlex>
811
+ </div>
812
+ </PatternCard>
813
+
814
+ {/* Centered card */}
815
+ <PatternCard title="Centered hero" desc="justify-center + align-center" code={FLEX_PATTERN_CODES.centeredCard}>
816
+ <div className="rounded-xl border border-primary-100 dark:border-primary-800/40 overflow-x-auto bg-blue-50 dark:bg-blue-950/30">
817
+ <ITFlex direction="column" justify="center" align="center" gap={3} className="min-h-56 text-center px-6 py-6">
818
+ <div className="w-14 h-14 rounded-2xl flex items-center justify-center text-white text-2xl font-bold"
819
+ style={{
820
+ background: 'linear-gradient(135deg, var(--color-primary-500, #3b82f6) 0%, var(--color-primary-700, #1d4ed8) 100%)',
821
+ boxShadow: '0 8px 24px 0 rgba(59, 130, 246, 0.3)',
822
+ }}
823
+ >
824
+
825
+ </div>
826
+ <div>
827
+ <p className="text-lg font-bold text-slate-800 dark:text-slate-100">All set!</p>
828
+ <p className="text-xs text-slate-500 dark:text-slate-400 mt-1">Your workspace is ready to use.</p>
829
+ </div>
830
+ <ITButton label="Get started" variant="filled" color="primary" size="small" />
831
+ </ITFlex>
832
+ </div>
833
+ </PatternCard>
834
+
835
+ {/* Form row with wrap */}
836
+ <PatternCard title="Responsive form" desc="wrap + grow + basis" code={FLEX_PATTERN_CODES.formRowWrap}>
837
+ <div className="rounded-xl p-4 border border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-800/80">
838
+ <ITFlex direction="row" wrap="wrap" gap={3}>
839
+ {[
840
+ { label: "First name", value: "John" },
841
+ { label: "Last name", value: "Doe" },
842
+ { label: "Email", value: "john@axzy.dev" },
843
+ ].map((field) => (
844
+ <ITFlex key={field.label} grow basis={56} direction="column" gap={1}>
845
+ <label className="text-[10px] font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400">{field.label}</label>
846
+ <div className="h-9 rounded-lg border border-slate-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 flex items-center text-sm text-slate-700 dark:text-slate-200 shadow-sm">
847
+ {field.value}
848
+ </div>
849
+ </ITFlex>
850
+ ))}
851
+ </ITFlex>
852
+ </div>
853
+ </PatternCard>
854
+
855
+ {/* Stretch column */}
856
+ <PatternCard title="Full-height layout" desc="column + stretch + grow" code={FLEX_PATTERN_CODES.stretchColumn}>
857
+ <div className="rounded-xl border border-slate-200 dark:border-slate-700 overflow-hidden h-72 bg-slate-50 dark:bg-slate-800/80">
858
+ <ITFlex direction="column" align="stretch" gap={0} className="h-full">
859
+ <div className="h-12 px-4 flex items-center justify-between bg-slate-100 dark:bg-slate-800 border-b border-slate-200 dark:border-slate-700">
860
+ <p className="text-xs font-bold text-slate-700 dark:text-slate-200">App Header</p>
861
+ <span className="text-[10px] text-slate-500">v1.0</span>
862
+ </div>
863
+ <ITFlex grow align="center" justify="center" direction="column" gap={2} className="bg-white dark:bg-slate-900/40">
864
+ <p className="text-2xl font-extrabold text-slate-800 dark:text-slate-100">Main content</p>
865
+ <p className="text-xs text-slate-500 dark:text-slate-400">flex-grow fills remaining space</p>
866
+ </ITFlex>
867
+ <div className="h-12 px-4 flex items-center justify-center bg-slate-100 dark:bg-slate-800 border-t border-slate-200 dark:border-slate-700">
868
+ <p className="text-[10px] text-slate-500">App Footer</p>
869
+ </div>
870
+ </ITFlex>
871
+ </div>
872
+ </PatternCard>
873
+ </div>
874
+ </GallerySection>
193
875
  </ITStack>
194
876
  }
195
877
  />
@@ -199,87 +881,430 @@ export const FlexShowcase = () => {
199
881
  // ─────────────────────────────────────────
200
882
  // 3. ITGrid Showcase
201
883
  // ─────────────────────────────────────────
884
+
885
+ const GRID_PATTERN_CODES = {
886
+ appDashboard: `// App shell: sidebar + main area, stacks on mobile
887
+ <ITGrid container spacing={4}>
888
+ <ITGrid item xs={12} md={3}>
889
+ <NavSidebar />
890
+ </ITGrid>
891
+ <ITGrid item xs={12} md={9}>
892
+ <MainPanel />
893
+ </ITGrid>
894
+ </ITGrid>`,
895
+ userProfile: `// Profile: avatar card + content area
896
+ <ITGrid container spacing={4}>
897
+ <ITGrid item xs={12} md={4}>
898
+ <ProfileCard user={user} />
899
+ </ITGrid>
900
+ <ITGrid item xs={12} md={8}>
901
+ <ActivityFeed activities={user.activity} />
902
+ </ITGrid>
903
+ </ITGrid>`,
904
+ settingsPage: `// Settings: section nav + form panels
905
+ <ITGrid container spacing={4}>
906
+ <ITGrid item xs={12} md={3}>
907
+ <SettingsNav />
908
+ </ITGrid>
909
+ <ITGrid item xs={12} md={9}>
910
+ <SettingsPanel section={current} />
911
+ </ITGrid>
912
+ </ITGrid>`,
913
+ articleLayout: `// Article + sidebar with metadata
914
+ <ITGrid container spacing={6}>
915
+ <ITGrid item xs={12} md={8}>
916
+ <Article />
917
+ </ITGrid>
918
+ <ITGrid item xs={12} md={4}>
919
+ <ArticleMeta author={author} tags={tags} />
920
+ </ITGrid>
921
+ </ITGrid>`,
922
+ pricingTiers: `// 3-column pricing comparison
923
+ <ITGrid container spacing={4}>
924
+ {plans.map((plan) => (
925
+ <ITGrid key={plan.id} item xs={12} md={4}>
926
+ <PricingCard plan={plan} highlighted={plan.featured} />
927
+ </ITGrid>
928
+ ))}
929
+ </ITGrid>`,
930
+ };
931
+
202
932
  export const GridShowcase = () => {
203
933
  const [spacing, setSpacing] = useState(3);
204
934
  const [columns, setColumns] = useState(3);
205
935
 
206
- const code = `<ITGrid container spacing={${spacing}}>\n {items.map(item => (\n <ITGrid item xs={12} md={${12 / columns}}>\n <Card>{item.name}</Card>\n </ITGrid>\n ))}\n</ITGrid>`;
936
+ const buildCode = () => {
937
+ const md = Math.floor(12 / columns);
938
+ return `<ITGrid container spacing={${spacing}}>\n {items.map((item) => (\n <ITGrid item xs={12} md={${md}}>\n <Card>{item.name}</Card>\n </ITGrid>\n ))}\n</ITGrid>`;
939
+ };
207
940
 
208
- const items = Array.from({ length: columns * 2 }, (_, i) => `Item ${i + 1}`);
941
+ const items = Array.from({ length: columns * 2 }, (_, i) => ({
942
+ id: i + 1,
943
+ name: `Item ${i + 1}`,
944
+ }));
209
945
 
210
946
  return (
211
947
  <ShowcaseLayout
212
948
  title="ITGrid"
213
949
  description="Sistema de grid responsivo de 12 columnas. Ideal para dashboards, galerías, y layouts de página completos."
214
- code={code}
950
+ code={buildCode()}
215
951
  demo={
216
- <div className="w-full">
217
- <ITGrid container spacing={spacing}>
218
- {items.map((item, i) => (
219
- <ITGrid key={i} item xs={12} md={Math.floor(12 / columns)}>
220
- <DemoBox className="!bg-white dark:!bg-slate-800 !text-slate-700 dark:!text-slate-200 border border-slate-200 dark:border-slate-700">
221
- {item}
222
- </DemoBox>
223
- </ITGrid>
224
- ))}
225
- </ITGrid>
952
+ <div className="w-full max-w-xl flex flex-col">
953
+ <div className="min-h-[360px]">
954
+ <ITGrid container spacing={spacing}>
955
+ {items.map((item) => (
956
+ <ITGrid key={item.id} item xs={12} md={Math.floor(12 / columns)}>
957
+ <div
958
+ className="h-16 rounded-lg flex items-center justify-center text-white text-sm font-semibold font-mono"
959
+ style={{
960
+ background: 'linear-gradient(135deg, var(--color-primary-500, #3b82f6) 0%, var(--color-primary-700, #1d4ed8) 100%)',
961
+ boxShadow: '0 4px 14px 0 rgba(59, 130, 246, 0.3)',
962
+ }}
963
+ >
964
+ {item.name}
965
+ </div>
966
+ </ITGrid>
967
+ ))}
968
+ </ITGrid>
969
+ </div>
970
+
971
+ {/* Fixed footer with active-property badges */}
972
+ <div className="sticky bottom-0 mt-4 -mx-6 -mb-6 px-6 py-3 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-t border-slate-200 dark:border-slate-700 flex items-center flex-wrap gap-1.5 text-[10px] font-mono">
973
+ <span className="text-[9px] uppercase tracking-wider font-bold text-slate-400 dark:text-slate-500 mr-1">Active:</span>
974
+ <span className="px-2 py-0.5 rounded-md bg-slate-900 text-white dark:bg-white dark:text-slate-900 font-semibold">cols:{columns}</span>
975
+ <span className="px-2 py-0.5 rounded-md bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300">gap:{spacing}</span>
976
+ <span className="px-2 py-0.5 rounded-md bg-primary-100 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300">md:{Math.floor(12 / columns)}</span>
977
+ </div>
226
978
  </div>
227
979
  }
228
980
  controls={
229
981
  <ITStack spacing={4}>
230
- <ITSlider label="Columnas" value={columns} onChange={setColumns} min={1} max={6} />
231
- <ITSlider label="Spacing" value={spacing} onChange={setSpacing} min={0} max={8} />
982
+ <ITSlider label="Columns" value={columns} onChange={setColumns} min={1} max={6} />
983
+ <ITSlider label="Spacing (0.25rem units)" value={spacing} onChange={setSpacing} min={0} max={8} />
232
984
  </ITStack>
233
985
  }
234
986
  gallery={
235
- <ITStack spacing={6}>
236
- {/* Sidebar + Content layout */}
237
- <div>
238
- <p className="text-xs font-semibold text-slate-400 mb-2 uppercase tracking-wider">Sidebar + Content (3/9)</p>
239
- <ITGrid container spacing={3}>
240
- <ITGrid item xs={12} md={3}>
241
- <div className="bg-slate-100 dark:bg-slate-800 rounded-xl p-4 text-center text-sm text-slate-500">Sidebar</div>
242
- </ITGrid>
243
- <ITGrid item xs={12} md={9}>
244
- <div className="bg-primary-50 dark:bg-primary-900/20 rounded-xl p-4 text-center text-sm text-primary-600">Main Content</div>
245
- </ITGrid>
246
- </ITGrid>
247
- </div>
248
- {/* Responsive cards */}
249
- <div>
250
- <p className="text-xs font-semibold text-slate-400 mb-2 uppercase tracking-wider">Responsive (xs=12 sm=6 md=4 lg=3)</p>
251
- <ITGrid container spacing={2}>
252
- {[1, 2, 3, 4].map((i) => (
253
- <ITGrid key={i} item xs={12} sm={6} md={4} lg={3}>
254
- <DemoCard>Card {i}</DemoCard>
255
- </ITGrid>
256
- ))}
257
- </ITGrid>
258
- </div>
259
- {/* 2-column form layout */}
260
- <div>
261
- <p className="text-xs font-semibold text-slate-400 mb-2 uppercase tracking-wider">Form Layout (2 columnas)</p>
262
- <ITGrid container spacing={3}>
263
- <ITGrid item xs={12} md={6}>
264
- <div className="bg-white dark:bg-slate-800 rounded-lg border border-slate-200 dark:border-slate-700 p-3">
265
- <div className="h-3 w-1/3 bg-slate-200 dark:bg-slate-700 rounded mb-2" />
266
- <div className="h-8 bg-slate-100 dark:bg-slate-700/50 rounded" />
987
+ <ITStack spacing={8}>
988
+ <GallerySection
989
+ title="Real UI cases"
990
+ subtitle="Production-ready layouts built with ITGrid"
991
+ >
992
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-5">
993
+
994
+ {/* 1. App dashboard — sidebar (3) + main (9) */}
995
+ <PatternCard
996
+ title="App dashboard"
997
+ desc="md=3 + md=9 → stacks on mobile"
998
+ code={GRID_PATTERN_CODES.appDashboard}
999
+ >
1000
+ <div className="rounded-xl border border-slate-200 dark:border-slate-700 overflow-hidden bg-white dark:bg-slate-900">
1001
+ <ITGrid container spacing={0}>
1002
+ <ITGrid item xs={12} md={3}>
1003
+ <div className="bg-slate-50 dark:bg-slate-800/50 px-4 py-5 border-r border-slate-200 dark:border-slate-700">
1004
+ <div className="flex items-center gap-2 mb-5">
1005
+ <div className="w-7 h-7 rounded-lg flex items-center justify-center text-white text-xs font-bold"
1006
+ style={{ background: 'linear-gradient(135deg, var(--color-primary-500) 0%, var(--color-primary-700) 100%)' }}
1007
+ >
1008
+ A
1009
+ </div>
1010
+ <p className="text-sm font-bold text-slate-800 dark:text-slate-100">Acme</p>
1011
+ </div>
1012
+ <div className="space-y-1">
1013
+ {[
1014
+ { label: "Overview", active: true },
1015
+ { label: "Projects", active: false },
1016
+ { label: "Team", active: false },
1017
+ { label: "Reports", active: false },
1018
+ { label: "Settings", active: false },
1019
+ ].map((item) => (
1020
+ <div
1021
+ key={item.label}
1022
+ className={`text-xs font-medium px-2.5 py-1.5 rounded-lg cursor-pointer transition-colors ${
1023
+ item.active
1024
+ ? "bg-primary-100 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300"
1025
+ : "text-slate-600 dark:text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-700/50"
1026
+ }`}
1027
+ >
1028
+ {item.label}
1029
+ </div>
1030
+ ))}
1031
+ </div>
1032
+ </div>
1033
+ </ITGrid>
1034
+ <ITGrid item xs={12} md={9}>
1035
+ <div className="p-4">
1036
+ <ITFlex direction="row" justify="between" align="center" className="mb-4">
1037
+ <div>
1038
+ <p className="text-base font-bold text-slate-800 dark:text-slate-100">Overview</p>
1039
+ <p className="text-[11px] text-slate-500 dark:text-slate-400">Last 30 days</p>
1040
+ </div>
1041
+ <ITButton label="+ New project" variant="filled" color="primary" size="small" />
1042
+ </ITFlex>
1043
+ <ITGrid container spacing={2}>
1044
+ {[
1045
+ { label: "Revenue", value: "$48.2k", tone: "emerald" },
1046
+ { label: "Active users", value: "2,847", tone: "primary" },
1047
+ { label: "Pending tasks", value: "12", tone: "amber" },
1048
+ ].map((s) => (
1049
+ <ITGrid key={s.label} item xs={12} sm={4}>
1050
+ <div className="rounded-lg border border-slate-200 dark:border-slate-700 p-3 bg-slate-50/50 dark:bg-slate-800/30">
1051
+ <p className="text-[10px] uppercase tracking-wider font-semibold text-slate-500 dark:text-slate-400">{s.label}</p>
1052
+ <p className="text-lg font-bold text-slate-800 dark:text-slate-100 font-mono mt-0.5">{s.value}</p>
1053
+ </div>
1054
+ </ITGrid>
1055
+ ))}
1056
+ </ITGrid>
1057
+ </div>
1058
+ </ITGrid>
1059
+ </ITGrid>
267
1060
  </div>
268
- </ITGrid>
269
- <ITGrid item xs={12} md={6}>
270
- <div className="bg-white dark:bg-slate-800 rounded-lg border border-slate-200 dark:border-slate-700 p-3">
271
- <div className="h-3 w-1/3 bg-slate-200 dark:bg-slate-700 rounded mb-2" />
272
- <div className="h-8 bg-slate-100 dark:bg-slate-700/50 rounded" />
1061
+ </PatternCard>
1062
+
1063
+ {/* 2. User profile avatar card (4) + activity (8) */}
1064
+ <PatternCard
1065
+ title="User profile"
1066
+ desc="md=4 + md=8 with nested activity"
1067
+ code={GRID_PATTERN_CODES.userProfile}
1068
+ >
1069
+ <div className="rounded-xl border border-slate-200 dark:border-slate-700 overflow-hidden bg-white dark:bg-slate-900">
1070
+ <ITGrid container spacing={0}>
1071
+ <ITGrid item xs={12} md={4}>
1072
+ <div className="bg-gradient-to-br from-primary-50 to-primary-100 dark:from-primary-900/30 dark:to-primary-800/20 p-5 border-r border-slate-200 dark:border-slate-700 text-center">
1073
+ <div className="w-20 h-20 mx-auto rounded-full flex items-center justify-center text-white text-2xl font-bold mb-3"
1074
+ style={{
1075
+ background: 'linear-gradient(135deg, var(--color-primary-500) 0%, var(--color-primary-700) 100%)',
1076
+ boxShadow: '0 8px 24px 0 rgba(59, 130, 246, 0.35)',
1077
+ }}
1078
+ >
1079
+ SC
1080
+ </div>
1081
+ <p className="text-sm font-bold text-slate-800 dark:text-slate-100">Sofía Castillo</p>
1082
+ <p className="text-[11px] text-slate-500 dark:text-slate-400">Product Designer</p>
1083
+ <div className="flex justify-center gap-2 mt-4">
1084
+ <span className="px-2 py-0.5 rounded-full text-[10px] font-semibold bg-primary-600 text-white">Design</span>
1085
+ <span className="px-2 py-0.5 rounded-full text-[10px] font-semibold bg-slate-200 dark:bg-slate-700 text-slate-600 dark:text-slate-300">Figma</span>
1086
+ </div>
1087
+ <ITButton label="Follow" variant="outlined" color="primary" size="small" className="mt-4 w-full" />
1088
+ </div>
1089
+ </ITGrid>
1090
+ <ITGrid item xs={12} md={8}>
1091
+ <div className="p-5">
1092
+ <p className="text-sm font-bold text-slate-800 dark:text-slate-100 mb-3">Recent activity</p>
1093
+ <ITStack spacing={3} divider={<div className="h-px bg-slate-100 dark:bg-slate-800" />}>
1094
+ {[
1095
+ { action: "Shipped", target: "Onboarding redesign", time: "2h ago", color: "emerald" },
1096
+ { action: "Reviewed PR", target: "#482 — Token system refactor", time: "Yesterday", color: "primary" },
1097
+ { action: "Started", target: "Q1 design system audit", time: "3 days ago", color: "info" },
1098
+ ].map((a) => (
1099
+ <div key={a.target} className="flex items-start gap-3 py-2">
1100
+ <span className={`w-2 h-2 rounded-full mt-1.5 shrink-0 ${
1101
+ a.color === "emerald" ? "bg-emerald-500" :
1102
+ a.color === "info" ? "bg-sky-500" :
1103
+ "bg-primary-500"
1104
+ }`} />
1105
+ <div className="flex-1 min-w-0">
1106
+ <p className="text-xs text-slate-700 dark:text-slate-200">
1107
+ <span className="font-semibold">{a.action}</span> <span className="text-slate-500 dark:text-slate-400">{a.target}</span>
1108
+ </p>
1109
+ <p className="text-[10px] text-slate-400 dark:text-slate-500 mt-0.5">{a.time}</p>
1110
+ </div>
1111
+ </div>
1112
+ ))}
1113
+ </ITStack>
1114
+ </div>
1115
+ </ITGrid>
1116
+ </ITGrid>
273
1117
  </div>
274
- </ITGrid>
275
- <ITGrid item xs={12}>
276
- <div className="bg-white dark:bg-slate-800 rounded-lg border border-slate-200 dark:border-slate-700 p-3">
277
- <div className="h-3 w-1/4 bg-slate-200 dark:bg-slate-700 rounded mb-2" />
278
- <div className="h-20 bg-slate-100 dark:bg-slate-700/50 rounded" />
1118
+ </PatternCard>
1119
+
1120
+ {/* 3. Settings page section nav (3) + form panels (9) */}
1121
+ <PatternCard
1122
+ title="Settings"
1123
+ desc="md=3 nav + md=9 form panels"
1124
+ code={GRID_PATTERN_CODES.settingsPage}
1125
+ >
1126
+ <div className="rounded-xl border border-slate-200 dark:border-slate-700 overflow-hidden bg-white dark:bg-slate-900">
1127
+ <ITGrid container spacing={0}>
1128
+ <ITGrid item xs={12} md={3}>
1129
+ <div className="px-4 py-5 border-r border-slate-200 dark:border-slate-700 space-y-1">
1130
+ {[
1131
+ { label: "Profile", active: false },
1132
+ { label: "Account", active: true },
1133
+ { label: "Notifications", active: false },
1134
+ { label: "Billing", active: false },
1135
+ { label: "API keys", active: false },
1136
+ ].map((s) => (
1137
+ <div
1138
+ key={s.label}
1139
+ className={`text-xs font-medium px-2.5 py-1.5 rounded-lg cursor-pointer ${
1140
+ s.active
1141
+ ? "bg-slate-100 dark:bg-slate-800 text-slate-800 dark:text-slate-100"
1142
+ : "text-slate-500 dark:text-slate-400 hover:bg-slate-50 dark:hover:bg-slate-800/50"
1143
+ }`}
1144
+ >
1145
+ {s.label}
1146
+ </div>
1147
+ ))}
1148
+ </div>
1149
+ </ITGrid>
1150
+ <ITGrid item xs={12} md={9}>
1151
+ <div className="p-5 space-y-4">
1152
+ <div>
1153
+ <p className="text-sm font-bold text-slate-800 dark:text-slate-100">Account</p>
1154
+ <p className="text-[11px] text-slate-500 dark:text-slate-400">Manage how your account appears and behaves.</p>
1155
+ </div>
1156
+ <ITGrid container spacing={3}>
1157
+ <ITGrid item xs={12} md={6}>
1158
+ <label className="text-[10px] font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400 block mb-1">Username</label>
1159
+ <div className="h-9 rounded-lg border border-slate-200 dark:border-slate-600 bg-slate-50 dark:bg-slate-800/50 px-3 flex items-center text-sm text-slate-700 dark:text-slate-200">@sofia.castillo</div>
1160
+ </ITGrid>
1161
+ <ITGrid item xs={12} md={6}>
1162
+ <label className="text-[10px] font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400 block mb-1">Email</label>
1163
+ <div className="h-9 rounded-lg border border-slate-200 dark:border-slate-600 bg-slate-50 dark:bg-slate-800/50 px-3 flex items-center text-sm text-slate-700 dark:text-slate-200">sofia@axzy.dev</div>
1164
+ </ITGrid>
1165
+ <ITGrid item xs={12}>
1166
+ <label className="text-[10px] font-semibold uppercase tracking-wider text-slate-500 dark:text-slate-400 block mb-1">Language</label>
1167
+ <div className="h-9 rounded-lg border border-slate-200 dark:border-slate-600 bg-slate-50 dark:bg-slate-800/50 px-3 flex items-center text-sm text-slate-700 dark:text-slate-200">English (US)</div>
1168
+ </ITGrid>
1169
+ </ITGrid>
1170
+ <div className="flex justify-end gap-2 pt-2 border-t border-slate-100 dark:border-slate-800">
1171
+ <ITButton label="Cancel" variant="outlined" color="gray" size="small" />
1172
+ <ITButton label="Save changes" variant="filled" color="primary" size="small" />
1173
+ </div>
1174
+ </div>
1175
+ </ITGrid>
1176
+ </ITGrid>
279
1177
  </div>
280
- </ITGrid>
281
- </ITGrid>
282
- </div>
1178
+ </PatternCard>
1179
+
1180
+ {/* 4. Article layout — body (8) + meta (4) */}
1181
+ <PatternCard
1182
+ title="Article layout"
1183
+ desc="md=8 body + md=4 sticky meta"
1184
+ code={GRID_PATTERN_CODES.articleLayout}
1185
+ >
1186
+ <div className="rounded-xl border border-slate-200 dark:border-slate-700 overflow-hidden bg-white dark:bg-slate-900">
1187
+ <ITGrid container spacing={0}>
1188
+ <ITGrid item xs={12} md={8} className="border-r border-slate-200 dark:border-slate-700">
1189
+ <article className="p-5">
1190
+ <span className="text-[10px] uppercase tracking-wider font-bold text-primary-600 dark:text-primary-400">Engineering</span>
1191
+ <h3 className="text-lg font-bold text-slate-800 dark:text-slate-100 mt-1.5 leading-tight">
1192
+ How we cut bundle size by 38% with route-level splitting
1193
+ </h3>
1194
+ <div className="flex items-center gap-2 mt-2 text-[11px] text-slate-500 dark:text-slate-400">
1195
+ <span>8 min read</span>
1196
+ <span>·</span>
1197
+ <span>Nov 14, 2025</span>
1198
+ </div>
1199
+ <p className="text-sm text-slate-600 dark:text-slate-300 mt-3 leading-relaxed">
1200
+ A few weeks ago we shipped lazy loading for all non-critical routes. The result was a 38% drop in our initial JS payload and a measurable improvement in time-to-interactive…
1201
+ </p>
1202
+ <p className="text-sm text-slate-600 dark:text-slate-300 mt-3 leading-relaxed">
1203
+ The strategy was simple: defer everything the user doesn't see on first paint, and split the rest by route. Below is what we measured.
1204
+ </p>
1205
+ </article>
1206
+ </ITGrid>
1207
+ <ITGrid item xs={12} md={4}>
1208
+ <div className="p-5 space-y-4 bg-slate-50/50 dark:bg-slate-800/30">
1209
+ <div>
1210
+ <p className="text-[10px] uppercase tracking-wider font-semibold text-slate-500 dark:text-slate-400 mb-2">Written by</p>
1211
+ <div className="flex items-center gap-2.5">
1212
+ <div className="w-9 h-9 rounded-full bg-emerald-100 dark:bg-emerald-900/30 flex items-center justify-center text-emerald-700 dark:text-emerald-300 text-xs font-bold">EM</div>
1213
+ <div>
1214
+ <p className="text-xs font-semibold text-slate-800 dark:text-slate-100">Elena Martínez</p>
1215
+ <p className="text-[10px] text-slate-500 dark:text-slate-400">Staff Engineer</p>
1216
+ </div>
1217
+ </div>
1218
+ </div>
1219
+ <div>
1220
+ <p className="text-[10px] uppercase tracking-wider font-semibold text-slate-500 dark:text-slate-400 mb-2">Tags</p>
1221
+ <div className="flex flex-wrap gap-1">
1222
+ {["Performance", "Webpack", "React"].map((t) => (
1223
+ <span key={t} className="px-2 py-0.5 rounded-md text-[10px] font-medium bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-300">{t}</span>
1224
+ ))}
1225
+ </div>
1226
+ </div>
1227
+ <ITButton label="Share article" variant="outlined" color="primary" size="small" className="w-full" />
1228
+ </div>
1229
+ </ITGrid>
1230
+ </ITGrid>
1231
+ </div>
1232
+ </PatternCard>
1233
+
1234
+ {/* 5. Pricing tiers — 3 equal columns */}
1235
+ <PatternCard
1236
+ title="Pricing comparison"
1237
+ desc="md=4 × 3 → comparison table"
1238
+ code={GRID_PATTERN_CODES.pricingTiers}
1239
+ >
1240
+ <div className="rounded-xl border border-slate-200 dark:border-slate-700 overflow-hidden bg-white dark:bg-slate-900 p-4">
1241
+ <ITGrid container spacing={3}>
1242
+ {[
1243
+ {
1244
+ name: "Starter",
1245
+ price: "$0",
1246
+ desc: "For personal projects",
1247
+ features: ["1 project", "Community support", "Basic analytics"],
1248
+ cta: "Get started",
1249
+ featured: false,
1250
+ },
1251
+ {
1252
+ name: "Pro",
1253
+ price: "$29",
1254
+ desc: "For growing teams",
1255
+ features: ["Unlimited projects", "Priority support", "Advanced analytics", "Custom domains"],
1256
+ cta: "Start trial",
1257
+ featured: true,
1258
+ },
1259
+ {
1260
+ name: "Enterprise",
1261
+ price: "Custom",
1262
+ desc: "For large organizations",
1263
+ features: ["SSO + SAML", "Dedicated CSM", "99.99% SLA", "Audit logs"],
1264
+ cta: "Contact sales",
1265
+ featured: false,
1266
+ },
1267
+ ].map((plan) => (
1268
+ <ITGrid key={plan.name} item xs={12} md={4}>
1269
+ <div className={`h-full rounded-xl p-4 border ${
1270
+ plan.featured
1271
+ ? "border-primary-400 dark:border-primary-600 bg-primary-50/50 dark:bg-primary-900/20"
1272
+ : "border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900"
1273
+ }`}>
1274
+ {plan.featured && (
1275
+ <span className="inline-block px-2 py-0.5 rounded-full bg-primary-600 text-white text-[9px] font-bold uppercase tracking-wider mb-2">
1276
+ Most popular
1277
+ </span>
1278
+ )}
1279
+ <p className="text-sm font-bold text-slate-800 dark:text-slate-100">{plan.name}</p>
1280
+ <p className="text-[11px] text-slate-500 dark:text-slate-400">{plan.desc}</p>
1281
+ <p className="text-2xl font-extrabold text-slate-800 dark:text-slate-100 font-mono mt-3">
1282
+ {plan.price}
1283
+ {plan.price !== "Custom" && <span className="text-xs font-normal text-slate-500 dark:text-slate-400"> /mo</span>}
1284
+ </p>
1285
+ <ul className="mt-3 space-y-1.5">
1286
+ {plan.features.map((f) => (
1287
+ <li key={f} className="text-[11px] text-slate-600 dark:text-slate-300 flex items-start gap-1.5">
1288
+ <span className={`mt-0.5 shrink-0 ${plan.featured ? "text-primary-600 dark:text-primary-400" : "text-emerald-500"}`}>✓</span>
1289
+ <span>{f}</span>
1290
+ </li>
1291
+ ))}
1292
+ </ul>
1293
+ <ITButton
1294
+ label={plan.cta}
1295
+ variant={plan.featured ? "filled" : "outlined"}
1296
+ color={plan.featured ? "primary" : "gray"}
1297
+ size="small"
1298
+ className="w-full mt-4"
1299
+ />
1300
+ </div>
1301
+ </ITGrid>
1302
+ ))}
1303
+ </ITGrid>
1304
+ </div>
1305
+ </PatternCard>
1306
+ </div>
1307
+ </GallerySection>
283
1308
  </ITStack>
284
1309
  }
285
1310
  />
@@ -456,44 +1481,52 @@ export const ScreenFormShowcase = () => {
456
1481
 
457
1482
  <ITGrid container spacing={4}>
458
1483
  <ITGrid item xs={12} md={6}>
459
- <div>
460
- <label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Nombre</label>
461
- <input className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500" placeholder="Ej: Juan" />
462
- </div>
1484
+ <ITInput
1485
+ name="nombre"
1486
+ label="Nombre"
1487
+ placeholder="Ej: Juan"
1488
+ onChange={() => {}}
1489
+ />
463
1490
  </ITGrid>
464
1491
  <ITGrid item xs={12} md={6}>
465
- <div>
466
- <label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Apellido</label>
467
- <input className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500" placeholder="Ej: Pérez" />
468
- </div>
1492
+ <ITInput
1493
+ name="apellido"
1494
+ label="Apellido"
1495
+ placeholder="Ej: Pérez"
1496
+ onChange={() => {}}
1497
+ />
469
1498
  </ITGrid>
470
1499
  <ITGrid item xs={12}>
471
- <div>
472
- <label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Email</label>
473
- <input className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500" placeholder="ej: usuario@correo.com" />
474
- </div>
1500
+ <ITInput
1501
+ name="email"
1502
+ label="Email"
1503
+ placeholder="ej: usuario@correo.com"
1504
+ onChange={() => {}}
1505
+ />
475
1506
  </ITGrid>
476
1507
  <ITGrid item xs={12} md={6}>
477
- <div>
478
- <label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Rol</label>
479
- <select className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500">
480
- <option>Seleccionar...</option>
481
- <option>Admin</option>
482
- <option>Editor</option>
483
- <option>Usuario</option>
484
- </select>
485
- </div>
1508
+ <ITSelect
1509
+ name="rol"
1510
+ label="Rol"
1511
+ options={[
1512
+ { label: "Seleccionar...", value: "" },
1513
+ { label: "Admin", value: "admin" },
1514
+ { label: "Editor", value: "editor" },
1515
+ { label: "Usuario", value: "usuario" },
1516
+ ]}
1517
+ />
486
1518
  </ITGrid>
487
1519
  <ITGrid item xs={12} md={6}>
488
- <div>
489
- <label className="text-xs font-semibold text-slate-600 dark:text-slate-400 mb-1 block">Departamento</label>
490
- <select className="w-full border border-slate-200 dark:border-slate-700 rounded-lg px-3 py-2 text-sm bg-white dark:bg-slate-800 text-slate-800 dark:text-white outline-none focus:ring-2 focus:ring-primary-500">
491
- <option>Seleccionar...</option>
492
- <option>Ingeniería</option>
493
- <option>Diseño</option>
494
- <option>Ventas</option>
495
- </select>
496
- </div>
1520
+ <ITSelect
1521
+ name="departamento"
1522
+ label="Departamento"
1523
+ options={[
1524
+ { label: "Seleccionar...", value: "" },
1525
+ { label: "Ingeniería", value: "ingenieria" },
1526
+ { label: "Diseño", value: "diseno" },
1527
+ { label: "Ventas", value: "ventas" },
1528
+ ]}
1529
+ />
497
1530
  </ITGrid>
498
1531
  <ITGrid item xs={12}>
499
1532
  <ITFlex justify="end" gap={3}>
@@ -510,60 +1543,3 @@ export const ScreenFormShowcase = () => {
510
1543
  );
511
1544
  };
512
1545
 
513
- export const ScreenCardGridShowcase = () => {
514
- const code = `// Grid de tarjetas 100% responsivo
515
- <ITGrid container spacing={4}>
516
- {products.map(product => (
517
- <ITGrid item xs={12} sm={6} md={4} lg={3} key={product.id}>
518
- <ITCard>
519
- <img src={product.image} alt={product.name} />
520
- <ITStack spacing={1}>
521
- <h3 className="font-bold">{product.name}</h3>
522
- <p className="text-sm text-slate-500">{product.price}</p>
523
- <ITButton label="Ver más" fullWidth />
524
- </ITStack>
525
- </ITCard>
526
- </ITGrid>
527
- ))}
528
- </ITGrid>`;
529
-
530
- return (
531
- <ITCard title="Grid de Tarjetas Responsivo">
532
- <ITStack spacing={4}>
533
- <div>
534
- <h2 className="text-xl font-bold text-slate-800 dark:text-white">Productos</h2>
535
- <p className="text-xs text-slate-400">Galería responsiva que pasa de 1 columna en mobile a 4 columnas en desktop</p>
536
- </div>
537
-
538
- <ITGrid container spacing={4}>
539
- {[
540
- { name: "Design Pro", color: "bg-blue-500" },
541
- { name: "Dev Kit", color: "bg-emerald-500" },
542
- { name: "UI Bundle", color: "bg-purple-500" },
543
- { name: "Analytics", color: "bg-amber-500" },
544
- { name: "Cloud Sync", color: "bg-rose-500" },
545
- { name: "Security+", color: "bg-cyan-500" },
546
- { name: "Data Viz", color: "bg-indigo-500" },
547
- { name: "API Hub", color: "bg-teal-500" },
548
- ].map((product, i) => (
549
- <ITGrid key={i} item xs={12} sm={6} md={4} lg={3}>
550
- <ITStack spacing={3} className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4 hover:shadow-md transition-shadow">
551
- <div className={`${product.color} h-24 rounded-lg flex items-center justify-center text-white text-2xl font-bold`}>
552
- {product.name.charAt(0)}
553
- </div>
554
- <div>
555
- <h3 className="font-bold text-slate-800 dark:text-white text-sm">{product.name}</h3>
556
- <p className="text-xs text-slate-400 mt-0.5">A partir de $19.99/mes</p>
557
- </div>
558
- <ITButton label="Ver más" size="small" className="w-full" />
559
- </ITStack>
560
- </ITGrid>
561
- ))}
562
- </ITGrid>
563
- </ITStack>
564
- <div className="mt-6">
565
- <CodeViewer code={code} />
566
- </div>
567
- </ITCard>
568
- );
569
- };