@axzydev/axzy_ui_system 1.2.7 → 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 (184) hide show
  1. package/dist/index.cjs +576 -398
  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 +1463 -86
  6. package/dist/index.d.ts +1463 -86
  7. package/dist/index.js +597 -417
  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 +19 -0
  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 +29 -2
  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 +27 -0
  90. package/src/components/page/page.doc.mdx +80 -0
  91. package/src/components/page/page.props.ts +21 -0
  92. package/src/components/page/page.tsx +18 -0
  93. package/src/components/page-header/page-header.doc.mdx +54 -0
  94. package/src/components/page-header/page-header.props.ts +9 -0
  95. package/src/components/page-header/page-header.tsx +15 -0
  96. package/src/components/pagination/pagination.doc.mdx +62 -0
  97. package/src/components/pagination/pagination.props.ts +11 -32
  98. package/src/components/pagination/pagination.tsx +17 -0
  99. package/src/components/popover/popover.doc.mdx +53 -0
  100. package/src/components/popover/popover.props.ts +8 -0
  101. package/src/components/popover/popover.tsx +13 -0
  102. package/src/components/progress/progress.doc.mdx +48 -0
  103. package/src/components/progress/progress.props.ts +8 -0
  104. package/src/components/progress/progress.tsx +9 -0
  105. package/src/components/radio/radio.doc.mdx +62 -0
  106. package/src/components/radio/radio.props.ts +11 -0
  107. package/src/components/radio/radio.tsx +18 -0
  108. package/src/components/search-select/search-select.doc.mdx +72 -0
  109. package/src/components/search-select/search-select.props.ts +23 -18
  110. package/src/components/search-select/search-select.tsx +27 -2
  111. package/src/components/searchTable/searchTable.doc.mdx +79 -0
  112. package/src/components/searchTable/searchTable.props.ts +42 -3
  113. package/src/components/searchTable/searchTable.stories.tsx +74 -0
  114. package/src/components/searchTable/searchTable.tsx +23 -0
  115. package/src/components/segmented-control/segmented-control.doc.mdx +60 -0
  116. package/src/components/segmented-control/segmented-control.props.ts +12 -0
  117. package/src/components/segmented-control/segmented-control.tsx +15 -0
  118. package/src/components/select/select.doc.mdx +75 -0
  119. package/src/components/select/select.props.ts +22 -0
  120. package/src/components/select/select.tsx +2 -5
  121. package/src/components/sidebar/sidebar.doc.mdx +86 -0
  122. package/src/components/sidebar/sidebar.props.ts +22 -0
  123. package/src/components/sidebar/sidebar.tsx +22 -0
  124. package/src/components/skeleton/skeleton.doc.mdx +43 -0
  125. package/src/components/skeleton/skeleton.props.ts +8 -0
  126. package/src/components/skeleton/skeleton.tsx +10 -0
  127. package/src/components/slide/slide.doc.mdx +46 -0
  128. package/src/components/slide/slide.props.ts +11 -24
  129. package/src/components/slide/slide.tsx +10 -1
  130. package/src/components/slider/slider.doc.mdx +49 -0
  131. package/src/components/slider/slider.props.ts +9 -0
  132. package/src/components/slider/slider.tsx +15 -0
  133. package/src/components/stack/stack.doc.mdx +126 -0
  134. package/src/components/stack/stack.props.ts +18 -0
  135. package/src/components/stack/stack.stories.tsx +221 -16
  136. package/src/components/stack/stack.tsx +21 -0
  137. package/src/components/stat-card/stat-card.doc.mdx +48 -0
  138. package/src/components/stat-card/stat-card.props.ts +9 -0
  139. package/src/components/stat-card/stat-card.tsx +10 -0
  140. package/src/components/stepper/stepper.doc.mdx +54 -0
  141. package/src/components/stepper/stepper.props.ts +11 -1
  142. package/src/components/stepper/stepper.tsx +15 -0
  143. package/src/components/table/table.doc.mdx +58 -0
  144. package/src/components/table/table.props.ts +17 -0
  145. package/src/components/table/table.tsx +199 -84
  146. package/src/components/tabs/tabs.doc.mdx +52 -0
  147. package/src/components/tabs/tabs.props.ts +11 -0
  148. package/src/components/tabs/tabs.tsx +14 -0
  149. package/src/components/text/text.doc.mdx +41 -0
  150. package/src/components/text/text.props.ts +5 -0
  151. package/src/components/text/text.stories.tsx +67 -0
  152. package/src/components/text/text.tsx +10 -0
  153. package/src/components/textarea/textarea.doc.mdx +64 -0
  154. package/src/components/textarea/textarea.props.ts +11 -0
  155. package/src/components/textarea/textarea.tsx +16 -0
  156. package/src/components/theme-provider/themeProvider.doc.mdx +75 -0
  157. package/src/components/theme-provider/themeProvider.props.ts +3 -0
  158. package/src/components/theme-provider/themeProvider.stories.tsx +59 -0
  159. package/src/components/theme-provider/themeProvider.tsx +14 -0
  160. package/src/components/time-picker/timePicker.doc.mdx +68 -0
  161. package/src/components/time-picker/timePicker.props.ts +14 -0
  162. package/src/components/time-picker/timePicker.tsx +22 -1
  163. package/src/components/toast/toast.doc.mdx +50 -0
  164. package/src/components/toast/toast.props.ts +5 -0
  165. package/src/components/toast/toast.tsx +21 -0
  166. package/src/components/tooltip/tooltip.doc.mdx +47 -0
  167. package/src/components/tooltip/tooltip.props.ts +6 -0
  168. package/src/components/tooltip/tooltip.tsx +19 -0
  169. package/src/components/topbar/topbar.doc.mdx +69 -0
  170. package/src/components/topbar/topbar.props.ts +15 -0
  171. package/src/components/topbar/topbar.tsx +38 -0
  172. package/src/components/triple-filter/tripleFilter.doc.mdx +62 -0
  173. package/src/components/triple-filter/tripleFilter.props.ts +7 -0
  174. package/src/components/triple-filter/tripleFilter.tsx +32 -0
  175. package/src/index.css +2 -0
  176. package/src/showcases/DataShowcases.tsx +529 -45
  177. package/src/showcases/FormShowcases.tsx +399 -29
  178. package/src/showcases/HomeShowcase.tsx +252 -272
  179. package/src/showcases/LayoutPrimitivesShowcases.tsx +1224 -248
  180. package/src/showcases/PageShowcases.tsx +688 -391
  181. package/src/showcases/ShowcaseLayout.tsx +237 -73
  182. package/src/showcases/StructureShowcases.tsx +846 -73
  183. package/src/types/table.types.ts +1 -1
  184. package/src/utils/styles.ts +2 -1
@@ -1,6 +1,5 @@
1
1
  import React, { useState } from "react";
2
2
  import {
3
- FaCheckCircle,
4
3
  FaHome,
5
4
  FaUsers,
6
5
  FaShoppingCart,
@@ -9,11 +8,18 @@ import {
9
8
  FaChartLine,
10
9
  FaFileAlt,
11
10
  FaBell,
11
+ FaCode,
12
+ FaCheck,
13
+ FaPlayCircle,
14
+ FaPlus,
15
+ FaSearch,
12
16
  } from "react-icons/fa";
13
17
  import {
14
18
  ITCard,
15
19
  ITButton,
16
20
  ITInput,
21
+ ITAvatar,
22
+ ITFlex,
17
23
  ITSlideToggle,
18
24
  ITText,
19
25
  ITNavbar,
@@ -22,48 +28,500 @@ import {
22
28
  ITStatCard,
23
29
  ITGrid,
24
30
  ITPageHeader,
25
- ITPage,
31
+ ITBadget,
32
+ ITDivider,
33
+ ITProgress,
34
+ ITSelect,
26
35
  } from "../index";
27
36
  import { ShowcaseLayout, CodeViewer } from "./ShowcaseLayout";
28
37
 
38
+ // ─────────────────────────────────────────
29
39
  // 1. ITCard Showcase
40
+ // ─────────────────────────────────────────
41
+
42
+ const CARD_PATTERN_CODES = {
43
+ course: `<ITCard
44
+ title="Advanced TypeScript Patterns"
45
+ image="/courses/typescript.jpg"
46
+ onClick={() => resume(course.id)}
47
+ actions={
48
+ <ITButton label="Continue lesson 8" variant="filled" color="primary" size="small" />
49
+ }
50
+ >
51
+ <ITFlex align="center" gap={3} className="mb-3">
52
+ <ITText muted className="text-xs">12 lessons</ITText>
53
+ <ITDivider orientation="vertical" className="h-3" />
54
+ <ITText muted className="text-xs font-mono">4h 32m</ITText>
55
+ <ITDivider orientation="vertical" className="h-3" />
56
+ <ITBadget label="★ 4.9" color="warning" size="small" variant="outlined" />
57
+ </ITFlex>
58
+ <ITProgress value={66} color="primary" size="md" />
59
+ <ITFlex justify="between" align="center" className="mt-2">
60
+ <ITText muted className="text-xs">66% complete</ITText>
61
+ <ITText muted className="text-xs">Lesson 8 of 12</ITText>
62
+ </ITFlex>
63
+ </ITCard>`,
64
+ pricing: `<div className="relative">
65
+ <ITBadget
66
+ label="Most popular"
67
+ color="primary"
68
+ size="small"
69
+ className="absolute -top-2 left-4 z-10 shadow-md"
70
+ />
71
+ <ITCard
72
+ title="Scale"
73
+ className="ring-2 ring-primary-500/30"
74
+ actions={
75
+ <ITButton label="Start 14-day free trial"
76
+ variant="filled" color="primary" size="medium" className="w-full" />
77
+ }
78
+ >
79
+ <ITFlex align="baseline" gap={1}>
80
+ <ITText as="span" className="text-4xl font-extrabold font-mono">$79</ITText>
81
+ <ITText muted as="span" className="text-xs">/ month</ITText>
82
+ </ITFlex>
83
+ <ITText muted as="span" className="text-xs mt-1 block">Billed annually · Up to 25 seats</ITText>
84
+ <ITDivider className="my-4" />
85
+ <ITStack spacing={2}>
86
+ {FEATURES.map(f => (
87
+ <ITFlex align="center" gap={2}>
88
+ <FaCheck className="text-primary-500 shrink-0" />
89
+ <ITText as="span" className="text-sm text-slate-700">{f}</ITText>
90
+ </ITFlex>
91
+ ))}
92
+ </ITStack>
93
+ </ITCard>
94
+ </div>`,
95
+ activity: `<ITCard
96
+ actions={
97
+ <ITFlex gap={2}>
98
+ <ITButton label="Reply" variant="text" color="primary" size="small" />
99
+ <ITButton label="Mute" variant="text" color="gray" size="small" />
100
+ </ITFlex>
101
+ }
102
+ >
103
+ <ITFlex align="start" gap={3}>
104
+ <ITAvatar initials="DK" size="md" />
105
+ <div className="min-w-0 flex-1">
106
+ <ITText className="text-sm leading-relaxed">
107
+ <ITText as="span" className="font-semibold">Daniela Klein</ITText>
108
+ {' '}deployed{' '}
109
+ <ITBadget label="v2.4.1" color="primary" size="small" variant="outlined" />
110
+ {' '}to <ITText as="span" className="font-semibold">production</ITText>.
111
+ </ITText>
112
+ <ITText muted className="text-xs mt-1.5 block">3 minutes ago · api-service</ITText>
113
+ <ITFlex align="center" gap={2} className="mt-3">
114
+ <ITFlex align="center" gap={1}>
115
+ <FaPlayCircle size={10} />
116
+ <ITText muted as="span" className="text-xs">4 reactions</ITText>
117
+ </ITFlex>
118
+ <ITDivider orientation="vertical" className="h-3" />
119
+ <ITFlex align="center" gap={1}>
120
+ <FaFileAlt size={10} />
121
+ <ITText muted as="span" className="text-xs">2 comments</ITText>
122
+ </ITFlex>
123
+ </ITFlex>
124
+ </div>
125
+ </ITFlex>
126
+ </ITCard>`,
127
+ teamMember: `<ITCard
128
+ title="Mariana Reyes"
129
+ image="/team/cover.jpg"
130
+ imageClassName="h-32"
131
+ onClick={() => openProfile(user.id)}
132
+ actions={
133
+ <ITFlex gap={2}>
134
+ <ITButton label="Message" variant="filled" color="primary" size="small" />
135
+ <ITButton label="View profile" variant="outlined" color="gray" size="small" />
136
+ </ITFlex>
137
+ }
138
+ >
139
+ <ITFlex align="center" gap={3} className="mb-3">
140
+ <ITAvatar initials="MR" size="md" />
141
+ <div>
142
+ <ITText as="span" className="text-sm font-semibold block">Engineering Lead</ITText>
143
+ <ITText muted as="span" className="text-xs">Madrid · 142 commits / month</ITText>
144
+ </div>
145
+ </ITFlex>
146
+ <ITText className="text-sm leading-relaxed">
147
+ Building resilient distributed systems and mentoring the platform team across 4 time zones.
148
+ </ITText>
149
+ <ITFlex gap={1} wrap="wrap" className="mt-3">
150
+ {['TypeScript', 'Distributed systems', 'Open source'].map(t => (
151
+ <ITBadget key={t} label={t} color="primary" size="small" variant="outlined" />
152
+ ))}
153
+ </ITFlex>
154
+ </ITCard>`,
155
+ release: `<ITCard
156
+ title="Midnight Frequencies"
157
+ image="/albums/midnight.jpg"
158
+ imageClassName="h-40"
159
+ onClick={() => play(album.id)}
160
+ actions={
161
+ <ITButton label="Play album" variant="filled" color="primary" size="small" />
162
+ }
163
+ >
164
+ <ITFlex justify="between" gap={3}>
165
+ <div className="min-w-0">
166
+ <ITText as="span" className="text-sm font-semibold block">Aurelia Sound</ITText>
167
+ <ITText muted as="span" className="text-xs">Released Mar 2026</ITText>
168
+ </div>
169
+ <ITStack spacing={0} align="end">
170
+ <ITText as="span" className="text-xs font-mono font-semibold">9 tracks</ITText>
171
+ <ITText muted as="span" className="text-[10px] font-mono">38 min</ITText>
172
+ </ITStack>
173
+ </ITFlex>
174
+ <ITFlex align="center" gap={1} className="mt-3">
175
+ {Array.from({length: 5}).map((_, i) => (
176
+ <FaPlay key={i} size={7}
177
+ className={i < 4 ? 'text-primary-500' : 'text-slate-300'} />
178
+ ))}
179
+ <ITText muted as="span" className="text-[10px] font-mono ml-1.5">4.7 · 12.4k plays</ITText>
180
+ </ITFlex>
181
+ </ITCard>`,
182
+ };
183
+
184
+ const TEXT_PATTERN_CODES = {
185
+ articleHeader: `<ITFlex align="center" gap={2} className="mb-3">
186
+ <ITBadget label="ENGINEERING" color="primary" size="small" variant="outlined" />
187
+ <ITText muted as="span" className="text-[11px] uppercase tracking-wider font-semibold">
188
+ Featured
189
+ </ITText>
190
+ </ITFlex>
191
+ <ITText as="h2" className="text-2xl font-bold leading-tight mb-2 block">
192
+ How we cut bundle size by 38% in two weeks
193
+ </ITText>
194
+ <ITText as="p" className="text-sm leading-relaxed mb-3 block">
195
+ A pragmatic walkthrough of our lazy-loading rollout…
196
+ </ITText>
197
+ <ITFlex align="center" gap={3}>
198
+ <ITAvatar initials="MR" size="sm" />
199
+ <ITText as="span" className="text-xs font-semibold">Mariana Reyes</ITText>
200
+ <ITDivider orientation="vertical" className="h-3" />
201
+ <ITText muted as="span" className="text-xs">Nov 14, 2025</ITText>
202
+ <ITDivider orientation="vertical" className="h-3" />
203
+ <ITText muted as="span" className="text-xs font-mono">8 min read</ITText>
204
+ </ITFlex>`,
205
+ sectionHeading: `<ITFlex justify="between" align="start" gap={4} className="mb-2">
206
+ <ITText as="h2" className="text-xl font-bold">Recent activity</ITText>
207
+ <ITButton label="View all →" variant="text" color="primary" size="small" />
208
+ </ITFlex>
209
+ <ITText as="p" muted className="text-sm leading-relaxed">
210
+ Latest commits, deployments and reviews from your team this week.
211
+ </ITText>`,
212
+ emptyState: `<ITStack spacing={3} alignItems="center" className="text-center">
213
+ <div className="w-14 h-14 rounded-2xl bg-gradient-to-br from-primary-500 to-primary-700">
214
+ <FaBell className="text-white" />
215
+ </div>
216
+ <ITText as="h3" className="text-lg font-bold">You're all caught up</ITText>
217
+ <ITText as="p" className="text-sm">
218
+ No new notifications.
219
+ </ITText>
220
+ <ITText as="p" muted className="text-xs">
221
+ Last checked 2 minutes ago
222
+ </ITText>
223
+ </ITStack>`,
224
+ inlineContent: `<ITText as="p" className="text-sm leading-relaxed">
225
+ <ITText as="span" className="font-semibold">Daniela Klein</ITText>
226
+ {' '}pushed commit{' '}
227
+ <ITText as="code" className="px-1.5 py-0.5 rounded bg-slate-100
228
+ text-primary-600 font-mono text-[11px]">a3f9c2e</ITText>
229
+ {' '}to <ITText as="span" className="font-semibold">main</ITText>.
230
+ </ITText>`,
231
+ formLabels: `<ITText as="label" className="text-sm font-semibold block mb-1">
232
+ Workspace name <ITText as="span" className="text-danger-500">*</ITText>
233
+ </ITText>
234
+ <ITInput name="ws_name" placeholder="my-awesome-project" />
235
+ <ITText muted as="span" className="text-[11px] mt-1 block">
236
+ Lowercase letters, numbers and hyphens only.
237
+ </ITText>`,
238
+ };
239
+
240
+ const GallerySection = ({ title, subtitle, children }: { title: string; subtitle?: string; children: React.ReactNode }) => (
241
+ <div>
242
+ <div className="mb-5">
243
+ <h3 className="text-base font-bold text-slate-800 dark:text-slate-100 flex items-center gap-2">
244
+ <span className="w-1 h-5 rounded-full bg-gradient-to-b from-primary-500 to-primary-700" />
245
+ {title}
246
+ </h3>
247
+ {subtitle && <p className="text-xs text-slate-500 dark:text-slate-400 mt-1 ml-3">{subtitle}</p>}
248
+ </div>
249
+ {children}
250
+ </div>
251
+ );
252
+
253
+ const PatternCard = ({ title, desc, code, children }: { title: string; desc?: string; code?: string; children: React.ReactNode }) => {
254
+ const [showCode, setShowCode] = useState(false);
255
+ return (
256
+ <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">
257
+ <div className="flex items-start justify-between gap-2 p-4 pb-3">
258
+ <div className="min-w-0">
259
+ <p className="text-sm font-semibold text-slate-800 dark:text-slate-100">{title}</p>
260
+ {desc && <p className="text-[11px] text-slate-500 dark:text-slate-400 mt-0.5">{desc}</p>}
261
+ </div>
262
+ {code && (
263
+ <ITButton variant="outlined" color="gray" size="small" onClick={() => setShowCode(!showCode)}>
264
+ <ITFlex align="center" gap={1}>
265
+ <FaCode size={9} />
266
+ {showCode ? "Hide code" : "Code"}
267
+ </ITFlex>
268
+ </ITButton>
269
+ )}
270
+ </div>
271
+ <div className="px-4 pb-4">{children}</div>
272
+ {showCode && code && (
273
+ <div className="px-4 pb-4 border-t border-slate-200 dark:border-slate-700 pt-3">
274
+ <CodeViewer code={code} compact />
275
+ </div>
276
+ )}
277
+ </div>
278
+ );
279
+ };
280
+
30
281
  export const CardShowcase = () => {
31
- const [title, setTitle] = useState("Registro de Logs del Sistema");
282
+ const [title, setTitle] = useState("Monthly revenue");
32
283
  const [showActions, setShowActions] = useState(true);
284
+ const [showImage, setShowImage] = useState(false);
285
+ const [clickable, setClickable] = useState(false);
33
286
 
34
- const code = `<ITCard\n title="${title}"\n actions={${showActions ? "<ITButton label='Exportar' />" : "undefined"}}\n>\n <p>Contenido interno de la tarjeta.</p>\n</ITCard>`;
287
+ const buildCode = () => {
288
+ const lines = [`<ITCard`];
289
+ if (title) lines.push(` title="${title}"`);
290
+ if (showImage) lines.push(` image="https://images.unsplash.com/photo-1554224155-6726b3ff858f?w=400&h=200&fit=crop"`);
291
+ if (clickable) lines.push(` onClick={() => openDetails()}`);
292
+ if (showActions) lines.push(` actions={<ITButton label="View" variant="filled" color="primary" size="small" />}`);
293
+ lines.push(`>`);
294
+ lines.push(` <p className="text-3xl font-bold">$48,230</p>`);
295
+ lines.push(` <p className="text-xs text-emerald-600">↑ 12.4% vs last month</p>`);
296
+ lines.push(`</ITCard>`);
297
+ return lines.join("\n");
298
+ };
35
299
 
36
300
  return (
37
301
  <ShowcaseLayout
38
302
  title="ITCard"
39
- description="Tarjetas de contenedor multipropósito con cabecera y espacio para acciones."
40
- code={code}
303
+ description="Contenedor multipropósito con cabecera opcional, imagen, contenido y pie de acciones. Se vuelve interactivo con `onClick` (efecto hover)."
304
+ code={buildCode()}
41
305
  demo={
42
- <div className="w-full max-w-md">
43
- <ITCard
44
- title={title}
45
- actions={showActions ? <ITButton label="Exportar" color="primary" size="small" variant="outlined" /> : undefined}
46
- >
47
- <div className="space-y-3">
48
- <p className="text-sm text-slate-600 dark:text-slate-300">
49
- Esta es una tarjeta administrativa estándar AXZY. Es ideal para agrupar paneles de control, tablas y formularios.
306
+ <div className="w-full max-w-xl flex flex-col">
307
+ <div className="min-h-[360px]">
308
+ <ITCard
309
+ title={title || undefined}
310
+ image={showImage ? "https://images.unsplash.com/photo-1554224155-6726b3ff858f?w=400&h=200&fit=crop" : undefined}
311
+ actions={showActions ? (
312
+ <ITButton label="View details" variant="filled" color="primary" size="small" />
313
+ ) : undefined}
314
+ onClick={clickable ? () => {} : undefined}
315
+ className="max-w-sm mx-auto"
316
+ >
317
+ <p className="text-3xl font-extrabold text-slate-800 dark:text-slate-100 font-mono">$48,230</p>
318
+ <p className="text-xs text-emerald-600 dark:text-emerald-400 font-semibold mt-1 flex items-center gap-1">
319
+ <span>↑</span> 12.4% vs last month
50
320
  </p>
51
- <div className="p-3 bg-emerald-50 dark:bg-emerald-950/20 border border-emerald-100 dark:border-emerald-900 rounded-xl flex items-center gap-2">
52
- <FaCheckCircle className="text-emerald-500" />
53
- <span className="text-xs font-medium text-emerald-800 dark:text-emerald-300">Estado de servidor: Conectado</span>
54
- </div>
55
- </div>
56
- </ITCard>
321
+ <p className="text-xs text-slate-500 dark:text-slate-400 mt-3">
322
+ Total revenue across all active subscriptions for the current billing cycle.
323
+ </p>
324
+ </ITCard>
325
+ </div>
326
+
327
+ {/* Fixed footer with active-property badges */}
328
+ <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">
329
+ <span className="text-[9px] uppercase tracking-wider font-bold text-slate-400 dark:text-slate-500 mr-1">Active:</span>
330
+ {title && <span className="px-2 py-0.5 rounded-md bg-slate-900 text-white dark:bg-white dark:text-slate-900 font-semibold">title</span>}
331
+ {showImage && <span className="px-2 py-0.5 rounded-md bg-primary-100 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300">image</span>}
332
+ {showActions && <span className="px-2 py-0.5 rounded-md bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300">actions</span>}
333
+ {clickable && <span className="px-2 py-0.5 rounded-md bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-300">onClick</span>}
334
+ </div>
57
335
  </div>
58
336
  }
59
337
  controls={
60
- <>
61
- <ITInput name="title_ctrl" label="Título de Tarjeta" value={title} onChange={(e: any) => setTitle(e.target.value)} onBlur={() => { }} />
62
- <div className="flex items-center justify-between pt-2">
63
- <span className="text-sm font-semibold text-gray-700">Mostrar Botón de Acción</span>
338
+ <ITStack spacing={4}>
339
+ <ITInput
340
+ name="title_ctrl"
341
+ label="Title"
342
+ value={title}
343
+ onChange={(e: any) => setTitle(e.target.value)}
344
+ onBlur={() => { }}
345
+ placeholder="Leave empty to hide"
346
+ />
347
+ <div className="flex items-center justify-between pt-1">
348
+ <span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Show image</span>
349
+ <ITSlideToggle isOn={showImage} onToggle={setShowImage} size="sm" />
350
+ </div>
351
+ <div className="flex items-center justify-between">
352
+ <span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Show actions</span>
64
353
  <ITSlideToggle isOn={showActions} onToggle={setShowActions} size="sm" />
65
354
  </div>
66
- </>
355
+ <div className="flex items-center justify-between">
356
+ <span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Interactive (onClick)</span>
357
+ <ITSlideToggle isOn={clickable} onToggle={setClickable} size="sm" />
358
+ </div>
359
+ </ITStack>
360
+ }
361
+ gallery={
362
+ <ITStack spacing={8}>
363
+ <GallerySection
364
+ title="Real UI cases"
365
+ subtitle="Production-ready card layouts built with ITCard"
366
+ >
367
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-5">
368
+
369
+ {/* 1. Course progress — ITProgress + ITBadget + ITDivider + ITText */}
370
+ <PatternCard
371
+ title="Course progress"
372
+ desc="ITProgress + ITBadget + ITDivider + ITText"
373
+ code={CARD_PATTERN_CODES.course}
374
+ >
375
+ <div className="max-w-sm mx-auto">
376
+ <ITCard
377
+ title="Advanced TypeScript Patterns"
378
+ image="https://images.unsplash.com/photo-1516321318423-f06f85e504b3?w=600&h=200&fit=crop"
379
+ onClick={() => {}}
380
+ actions={
381
+ <ITButton label="Continue lesson 8" variant="filled" color="primary" size="small" />
382
+ }
383
+ >
384
+ <ITFlex align="center" gap={3} className="mb-3">
385
+ <ITText muted className="text-xs">12 lessons</ITText>
386
+ <ITDivider orientation="vertical" className="h-3" />
387
+ <ITText muted className="text-xs font-mono">4h 32m</ITText>
388
+ <ITDivider orientation="vertical" className="h-3" />
389
+ <ITBadget label="★ 4.9" color="warning" size="small" variant="outlined" />
390
+ </ITFlex>
391
+ <ITProgress value={66} color="primary" size="md" />
392
+ <ITFlex justify="between" align="center" className="mt-2">
393
+ <ITText muted className="text-xs">66% complete</ITText>
394
+ <ITText muted className="text-xs">Lesson 8 of 12</ITText>
395
+ </ITFlex>
396
+ <ITText className="text-xs mt-2 block">
397
+ Next up: <ITText as="span" className="font-semibold text-slate-700">Conditional types deep dive</ITText>
398
+ </ITText>
399
+ </ITCard>
400
+ </div>
401
+ </PatternCard>
402
+
403
+ {/* 2. Featured pricing plan — ITBadget outside + ITFlex + ITStack + ITDivider */}
404
+ <PatternCard
405
+ title="Featured pricing plan"
406
+ desc="ITBadget + ITDivider + ITStack with ITFlex items"
407
+ code={CARD_PATTERN_CODES.pricing}
408
+ >
409
+ <div className="max-w-sm mx-auto pt-3">
410
+ <div className="relative">
411
+ <ITBadget
412
+ label="Most popular"
413
+ color="primary"
414
+ size="small"
415
+ className="absolute -top-2 left-4 z-10 shadow-md"
416
+ />
417
+ <ITCard
418
+ title="Scale"
419
+ className="ring-2 ring-primary-500/30"
420
+ actions={
421
+ <ITButton label="Start 14-day free trial" variant="filled" color="primary" size="medium" className="w-full" />
422
+ }
423
+ >
424
+ <ITFlex align="baseline" gap={1}>
425
+ <ITText as="span" className="text-4xl font-extrabold font-mono text-slate-800">$79</ITText>
426
+ <ITText muted as="span" className="text-xs">/ month</ITText>
427
+ </ITFlex>
428
+ <ITText muted as="span" className="text-xs mt-1 block">Billed annually · Up to 25 seats</ITText>
429
+ <ITDivider className="my-4" />
430
+ <ITStack spacing={2}>
431
+ {['Unlimited projects', 'Advanced analytics', 'Priority support', 'SSO & audit logs', 'Custom integrations'].map((f) => (
432
+ <ITFlex key={f} align="center" gap={2}>
433
+ <FaCheck size={11} className="text-primary-500 shrink-0" />
434
+ <ITText as="span" className="text-sm text-slate-700">{f}</ITText>
435
+ </ITFlex>
436
+ ))}
437
+ </ITStack>
438
+ </ITCard>
439
+ </div>
440
+ </div>
441
+ </PatternCard>
442
+
443
+ {/* 3. Activity feed item — ITText + ITBadget for commit hash + ITDivider separators */}
444
+ <PatternCard
445
+ title="Activity feed item"
446
+ desc="ITText + ITBadget (commit hash) + ITDivider separators"
447
+ code={CARD_PATTERN_CODES.activity}
448
+ >
449
+ <div className="max-w-md mx-auto">
450
+ <ITCard
451
+ actions={
452
+ <ITFlex gap={2}>
453
+ <ITButton label="Reply" variant="text" color="primary" size="small" />
454
+ <ITButton label="Mute" variant="text" color="gray" size="small" />
455
+ </ITFlex>
456
+ }
457
+ >
458
+ <ITFlex align="start" gap={3}>
459
+ <ITAvatar initials="DK" size="md" />
460
+ <div className="min-w-0 flex-1">
461
+ <ITText className="text-sm leading-relaxed text-slate-700">
462
+ <ITText as="span" className="font-semibold">Daniela Klein</ITText>
463
+ {' '}deployed{' '}
464
+ <ITBadget label="v2.4.1" color="primary" size="small" variant="outlined" />
465
+ {' '}to <ITText as="span" className="font-semibold">production</ITText>.
466
+ </ITText>
467
+ <ITText muted className="text-xs mt-1.5 block">3 minutes ago · api-service</ITText>
468
+ <ITFlex align="center" gap={2} className="mt-3">
469
+ <ITFlex align="center" gap={1}>
470
+ <FaPlayCircle size={10} className="text-slate-500" />
471
+ <ITText muted as="span" className="text-xs">4 reactions</ITText>
472
+ </ITFlex>
473
+ <ITDivider orientation="vertical" className="h-3" />
474
+ <ITFlex align="center" gap={1}>
475
+ <FaFileAlt size={10} className="text-slate-500" />
476
+ <ITText muted as="span" className="text-xs">2 comments</ITText>
477
+ </ITFlex>
478
+ </ITFlex>
479
+ </div>
480
+ </ITFlex>
481
+ </ITCard>
482
+ </div>
483
+ </PatternCard>
484
+
485
+ {/* 4. Team member profile — ITFlex + ITBadget for skills + ITText throughout */}
486
+ <PatternCard
487
+ title="Team member profile"
488
+ desc="ITFlex + ITBadget skills + ITText throughout"
489
+ code={CARD_PATTERN_CODES.teamMember}
490
+ >
491
+ <div className="max-w-sm mx-auto">
492
+ <ITCard
493
+ title="Mariana Reyes"
494
+ image="https://images.unsplash.com/photo-1497366216548-37526070297c?w=600&h=200&fit=crop"
495
+ imageClassName="h-32"
496
+ onClick={() => {}}
497
+ actions={
498
+ <ITFlex gap={2}>
499
+ <ITButton label="Message" variant="filled" color="primary" size="small" />
500
+ <ITButton label="View profile" variant="outlined" color="gray" size="small" />
501
+ </ITFlex>
502
+ }
503
+ >
504
+ <ITFlex align="center" gap={3} className="mb-3">
505
+ <ITAvatar initials="MR" size="md" />
506
+ <div className="min-w-0">
507
+ <ITText as="span" className="text-sm font-semibold text-slate-800 block">Engineering Lead</ITText>
508
+ <ITText muted as="span" className="text-xs">Madrid · 142 commits / month</ITText>
509
+ </div>
510
+ </ITFlex>
511
+ <ITText className="text-sm leading-relaxed text-slate-600">
512
+ Building resilient distributed systems and mentoring the platform team across 4 time zones.
513
+ </ITText>
514
+ <ITFlex gap={1} wrap="wrap" className="mt-3">
515
+ {['TypeScript', 'Distributed systems', 'Open source'].map((t) => (
516
+ <ITBadget key={t} label={t} color="primary" size="small" variant="outlined" />
517
+ ))}
518
+ </ITFlex>
519
+ </ITCard>
520
+ </div>
521
+ </PatternCard>
522
+ </div>
523
+ </GallerySection>
524
+ </ITStack>
67
525
  }
68
526
  />
69
527
  );
@@ -71,70 +529,382 @@ export const CardShowcase = () => {
71
529
 
72
530
  // 2. ITText Showcase
73
531
  export const TextShowcase = () => {
74
- const [bold, setBold] = useState(false);
532
+ const [element, setElement] = useState("p");
75
533
  const [size, setSize] = useState("text-base");
534
+ const [bold, setBold] = useState(false);
535
+ const [muted, setMuted] = useState(false);
536
+ const [maxLength, setMaxLength] = useState<string>("0");
537
+ const [lineClamp, setLineClamp] = useState(0);
538
+ const [breakLength, setBreakLength] = useState<string>("0");
539
+
540
+ const FULL_SAMPLE =
541
+ "AXZY UI System provee una capa tipográfica consistente sobre React, permitiendo que cada componente respire con la misma jerarquía visual sin importar el tema o el contexto.";
76
542
 
77
- const code = `<ITText className="${bold ? "font-bold" : ""} ${size}">\n Texto tipográfico estándar AXZY\n</ITText>`;
543
+ const maxLengthNum = maxLength === "" ? 0 : Number(maxLength) || 0;
544
+ const breakLengthNum = breakLength === "" ? 0 : Number(breakLength) || 0;
545
+
546
+ const buildCode = () => {
547
+ const lines = [`<ITText`];
548
+ if (element !== "p") lines.push(` as="${element}"`);
549
+ if (muted) lines.push(` muted`);
550
+ const cls = [
551
+ bold ? "font-bold" : "",
552
+ size,
553
+ lineClamp > 0 ? `line-clamp-${lineClamp}` : "",
554
+ "text-slate-800 dark:text-white",
555
+ ].filter(Boolean).join(" ");
556
+ lines.push(` className="${cls.trim()}"`);
557
+ if (maxLengthNum > 0) lines.push(` // truncated at ${maxLengthNum} chars`);
558
+ if (breakLengthNum > 0) lines.push(` // wrap hint every ${breakLengthNum} chars`);
559
+ lines.push(`>`);
560
+ lines.push(` ${FULL_SAMPLE.slice(0, 80)}${FULL_SAMPLE.length > 80 ? "…" : ""}`);
561
+ lines.push(`</ITText>`);
562
+ return lines.join("\n");
563
+ };
564
+
565
+ const processedText = (() => {
566
+ let t = FULL_SAMPLE;
567
+ if (maxLengthNum > 0 && t.length > maxLengthNum) t = t.slice(0, maxLengthNum).trimEnd() + "…";
568
+ return t;
569
+ })();
570
+
571
+ const renderWithBreaks = (text: string) => {
572
+ if (!breakLengthNum || breakLengthNum <= 0) return text;
573
+ const parts: string[] = [];
574
+ for (let i = 0; i < text.length; i += breakLengthNum) {
575
+ parts.push(text.slice(i, i + breakLengthNum));
576
+ }
577
+ return parts.join("\u200B");
578
+ };
579
+
580
+ const clampClass = lineClamp > 0 ? `line-clamp-${lineClamp}` : "";
78
581
 
79
582
  return (
80
583
  <ShowcaseLayout
81
584
  title="ITText"
82
- description="Contenedor tipográfico básico alineado con las tipografías globales del tema."
83
- code={code}
585
+ description="Wrapper tipográfico semántico. Renderiza cualquier elemento HTML, con soporte para truncado por caracteres, clamp de líneas y corte programático."
586
+ code={buildCode()}
84
587
  demo={
85
- <ITText className={`${bold ? "font-bold" : ""} ${size} text-slate-800 dark:text-white`}>
86
- Diseñado para inyectar consistencia tipográfica sobre las variables globales de Outfit/Inter.
87
- </ITText>
588
+ <div className="w-full flex flex-col">
589
+ <div className="min-h-[360px] flex items-center justify-center">
590
+ <div className="w-full max-w-md p-6 rounded-2xl bg-white dark:bg-slate-900/60 border border-slate-200 dark:border-slate-700 shadow-sm">
591
+ {/* BIG element indicator — makes the `as` change unmissable */}
592
+ <ITStack spacing={2} alignItems="center" className="mb-5 text-center">
593
+ <ITText muted as="span" className="text-[10px] uppercase tracking-wider font-bold">
594
+ Rendering as
595
+ </ITText>
596
+ <code
597
+ key={element}
598
+ className="inline-block px-3 py-1 rounded-lg bg-slate-900 text-white dark:bg-white dark:text-slate-900 font-mono text-sm font-bold shadow-sm"
599
+ >
600
+ &lt;{element}&gt;
601
+ </code>
602
+ </ITStack>
603
+
604
+ <div key={`wrap-${element}`} className="text-center">
605
+ <ITText
606
+ key={element}
607
+ as={element as any}
608
+ muted={muted}
609
+ className={`${bold ? "font-bold" : ""} ${size} ${clampClass} text-slate-800 dark:text-white block break-words`}
610
+ >
611
+ {element === "code" ? "const axzy = 'design-system';" : renderWithBreaks(processedText)}
612
+ </ITText>
613
+ </div>
614
+ </div>
615
+ </div>
616
+
617
+ {/* Fixed footer with active-property badges */}
618
+ <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">
619
+ <span className="text-[9px] uppercase tracking-wider font-bold text-slate-400 dark:text-slate-500 mr-1">Active:</span>
620
+ {element !== "p" && <span className="px-2 py-0.5 rounded-md bg-slate-900 text-white dark:bg-white dark:text-slate-900 font-semibold">as=&quot;{element}&quot;</span>}
621
+ <span className="px-2 py-0.5 rounded-md bg-primary-100 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300">{size}</span>
622
+ {bold && <span className="px-2 py-0.5 rounded-md bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300">font-bold</span>}
623
+ {muted && <span className="px-2 py-0.5 rounded-md bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-300">muted</span>}
624
+ {maxLengthNum > 0 && <span className="px-2 py-0.5 rounded-md bg-purple-100 dark:bg-purple-900/30 text-purple-700 dark:text-purple-300">max {maxLengthNum}c</span>}
625
+ {lineClamp > 0 && <span className="px-2 py-0.5 rounded-md bg-cyan-100 dark:bg-cyan-900/30 text-cyan-700 dark:text-cyan-300">clamp-{lineClamp}</span>}
626
+ {breakLengthNum > 0 && <span className="px-2 py-0.5 rounded-md bg-rose-100 dark:bg-rose-900/30 text-rose-700 dark:text-rose-300">break@{breakLengthNum}c</span>}
627
+ </div>
628
+ </div>
88
629
  }
89
630
  controls={
90
- <>
91
- <ITSelectStub
631
+ <ITStack spacing={4}>
632
+ <ITSelect
633
+ name="elem_ctrl"
634
+ label="Elemento HTML (as)"
635
+ value={element}
636
+ onChange={(e) => setElement(e.target.value)}
637
+ options={[
638
+ { label: "Párrafo (p)", value: "p" },
639
+ { label: "Encabezado H1", value: "h1" },
640
+ { label: "Encabezado H2", value: "h2" },
641
+ { label: "Encabezado H3", value: "h3" },
642
+ { label: "Span inline", value: "span" },
643
+ { label: "Etiqueta (label)", value: "label" },
644
+ { label: "Código (code)", value: "code" },
645
+ ]}
646
+ />
647
+ <ITSelect
92
648
  name="sz_ctrl"
93
- label="Tamaño de Fuente"
649
+ label="Tamaño"
94
650
  value={size}
95
- onChange={(e: any) => setSize(e.target.value)}
651
+ onChange={(e) => setSize(e.target.value)}
652
+ options={[
653
+ { label: "XS (12px)", value: "text-xs" },
654
+ { label: "SM (14px)", value: "text-sm" },
655
+ { label: "Base (16px)", value: "text-base" },
656
+ { label: "LG (18px)", value: "text-lg" },
657
+ { label: "XL (20px)", value: "text-xl" },
658
+ { label: "2XL (24px)", value: "text-2xl" },
659
+ ]}
660
+ />
661
+ <ITSelect
662
+ name="clamp_ctrl"
663
+ label="Número de líneas (lineClamp)"
664
+ value={String(lineClamp)}
665
+ onChange={(e) => setLineClamp(Number(e.target.value))}
96
666
  options={[
97
- { label: "Chico (text-xs)", value: "text-xs" },
98
- { label: "Estándar (text-base)", value: "text-base" },
99
- { label: "Grande (text-xl)", value: "text-xl" },
100
- { label: "Título (text-3xl)", value: "text-3xl" }
667
+ { label: "Sin límite", value: "0" },
668
+ { label: "1 línea", value: "1" },
669
+ { label: "2 líneas", value: "2" },
670
+ { label: "3 líneas", value: "3" },
671
+ { label: "4 líneas", value: "4" },
101
672
  ]}
102
673
  />
103
- <div className="flex items-center justify-between pt-2">
104
- <span className="text-sm font-semibold text-gray-700">Negrita (Bold)</span>
674
+ <ITInput
675
+ name="max_ctrl"
676
+ label="Texto máximo (caracteres)"
677
+ type="number"
678
+ value={maxLength}
679
+ onChange={(e) => setMaxLength(e.target.value)}
680
+ placeholder="0 = sin límite"
681
+ />
682
+ <ITFlex justify="between" align="center">
683
+ <ITText muted as="span" className="text-[10px]">
684
+ Trunca con "…" al superar (0 = desactivado).
685
+ </ITText>
686
+ <ITButton variant="text" color="primary" size="small" onClick={() => setMaxLength("0")}>
687
+ Reset
688
+ </ITButton>
689
+ </ITFlex>
690
+ <ITInput
691
+ name="break_ctrl"
692
+ label="Salto de línea después de (caracteres)"
693
+ type="number"
694
+ value={breakLength}
695
+ onChange={(e) => setBreakLength(e.target.value)}
696
+ placeholder="0 = sin salto"
697
+ />
698
+ <ITFlex justify="between" align="center">
699
+ <ITText muted as="span" className="text-[10px]">
700
+ Inserta un &lt;br /&gt; al superar el límite.
701
+ </ITText>
702
+ <ITButton variant="text" color="primary" size="small" onClick={() => setBreakLength("0")}>
703
+ Reset
704
+ </ITButton>
705
+ </ITFlex>
706
+ <div>
707
+ <ITText as="label" htmlFor="break_ctrl" className="text-xs font-semibold text-slate-600 dark:text-slate-400 block mb-1">
708
+ breakLengthWrap (corte cada N caracteres)
709
+ </ITText>
710
+ <input
711
+ id="break_ctrl"
712
+ type="number"
713
+ min={0}
714
+ step={5}
715
+ value={breakLength}
716
+ onChange={(e) => setBreakLength(e.target.value)}
717
+ className="w-full bg-slate-50 dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-lg p-2 text-xs text-slate-800 dark:text-slate-100 outline-none focus:ring-2 focus:ring-primary-500"
718
+ placeholder="0 = sin corte"
719
+ />
720
+ <ITFlex justify="between" align="center" className="mt-1.5">
721
+ <ITText muted as="span" className="text-[10px]">
722
+ Inserta oportunidades de corte cada N chars (0 = desactivado).
723
+ </ITText>
724
+ <button
725
+ type="button"
726
+ onClick={() => setBreakLength("0")}
727
+ className="text-[10px] font-semibold text-primary-600 hover:text-primary-700 dark:text-primary-400"
728
+ >
729
+ Reset
730
+ </button>
731
+ </ITFlex>
732
+ </div>
733
+ <div className="flex items-center justify-between pt-1">
734
+ <ITText as="span" className="text-sm font-semibold text-slate-700 dark:text-slate-300">Negrita (font-bold)</ITText>
105
735
  <ITSlideToggle isOn={bold} onToggle={setBold} size="sm" />
106
736
  </div>
107
- </>
737
+ <div className="flex items-center justify-between">
738
+ <ITText as="span" className="text-sm font-semibold text-slate-700 dark:text-slate-300">Muted color</ITText>
739
+ <ITSlideToggle isOn={muted} onToggle={setMuted} size="sm" />
740
+ </div>
741
+ </ITStack>
742
+ }
743
+ gallery={
744
+ <ITStack spacing={8}>
745
+ <GallerySection
746
+ title="Real UI cases"
747
+ subtitle="Production-ready typography patterns built with ITText"
748
+ >
749
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-5">
750
+
751
+ {/* 1. Article header — eyebrow + title + meta */}
752
+ <PatternCard
753
+ title="Article header"
754
+ desc="eyebrow tag + h1 title + author/date/read-time meta"
755
+ code={TEXT_PATTERN_CODES.articleHeader}
756
+ >
757
+ <div className="max-w-md">
758
+ <ITFlex align="center" gap={2} className="mb-3">
759
+ <ITBadget label="ENGINEERING" color="primary" size="small" variant="outlined" />
760
+ <ITText muted as="span" className="text-[11px] uppercase tracking-wider font-semibold">Featured</ITText>
761
+ </ITFlex>
762
+ <ITText as="h2" className="text-2xl font-bold text-slate-800 dark:text-slate-100 leading-tight mb-2 block">
763
+ How we cut bundle size by 38% in two weeks
764
+ </ITText>
765
+ <ITText as="p" className="text-sm text-slate-600 dark:text-slate-300 leading-relaxed mb-3 block">
766
+ A pragmatic walkthrough of our lazy-loading rollout, route-level code splitting, and the metrics that proved it worked.
767
+ </ITText>
768
+ <ITFlex align="center" gap={3}>
769
+ <ITAvatar initials="MR" size="sm" />
770
+ <ITText as="span" className="text-xs text-slate-700 dark:text-slate-300 font-semibold">Mariana Reyes</ITText>
771
+ <ITDivider orientation="vertical" className="h-3" />
772
+ <ITText muted as="span" className="text-xs">Nov 14, 2025</ITText>
773
+ <ITDivider orientation="vertical" className="h-3" />
774
+ <ITText muted as="span" className="text-xs font-mono">8 min read</ITText>
775
+ </ITFlex>
776
+ </div>
777
+ </PatternCard>
778
+
779
+ {/* 2. Section heading — h2 + description + action link */}
780
+ <PatternCard
781
+ title="Section heading"
782
+ desc="h2 title + description + action link on the right"
783
+ code={TEXT_PATTERN_CODES.sectionHeading}
784
+ >
785
+ <div>
786
+ <ITFlex justify="between" align="start" gap={4} className="mb-2">
787
+ <ITText as="h2" className="text-xl font-bold text-slate-800 dark:text-slate-100">
788
+ Recent activity
789
+ </ITText>
790
+ <ITButton label="View all →" variant="text" color="primary" size="small" />
791
+ </ITFlex>
792
+ <ITText as="p" muted className="text-sm leading-relaxed">
793
+ Latest commits, deployments and reviews from your team this week. Updates every 30 seconds.
794
+ </ITText>
795
+ </div>
796
+ </PatternCard>
797
+
798
+ {/* 3. Empty state — big title + description + muted helper */}
799
+ <PatternCard
800
+ title="Empty state"
801
+ desc="big title + description + muted helper text"
802
+ code={TEXT_PATTERN_CODES.emptyState}
803
+ >
804
+ <ITStack spacing={3} alignItems="center" className="text-center py-2">
805
+ <div
806
+ className="w-14 h-14 rounded-2xl flex items-center justify-center"
807
+ style={{
808
+ background: 'linear-gradient(135deg, var(--color-primary-500) 0%, var(--color-primary-700) 100%)',
809
+ boxShadow: '0 8px 24px 0 rgba(59, 130, 246, 0.3)',
810
+ }}
811
+ >
812
+ <FaBell className="text-white text-xl" />
813
+ </div>
814
+ <ITText as="h3" className="text-lg font-bold text-slate-800 dark:text-slate-100">
815
+ You're all caught up
816
+ </ITText>
817
+ <ITText as="p" className="text-sm text-slate-600 dark:text-slate-300 max-w-xs">
818
+ No new notifications. We'll let you know when something important happens.
819
+ </ITText>
820
+ <ITText as="p" muted className="text-xs">
821
+ Last checked 2 minutes ago
822
+ </ITText>
823
+ </ITStack>
824
+ </PatternCard>
825
+
826
+ {/* 4. Inline content — paragraph with bold name + inline code + muted meta */}
827
+ <PatternCard
828
+ title="Inline content"
829
+ desc="paragraph with bold name + inline code + muted timestamp"
830
+ code={TEXT_PATTERN_CODES.inlineContent}
831
+ >
832
+ <div className="max-w-md">
833
+ <ITText as="p" className="text-sm text-slate-700 dark:text-slate-200 leading-relaxed">
834
+ <ITText as="span" className="font-semibold">Daniela Klein</ITText>
835
+ {' '}pushed commit{' '}
836
+ <ITText as="code" className="px-1.5 py-0.5 rounded bg-slate-100 dark:bg-slate-800 text-primary-600 dark:text-primary-400 font-mono text-[11px]">
837
+ a3f9c2e
838
+ </ITText>
839
+ {' '}to{' '}
840
+ <ITText as="span" className="font-semibold">main</ITText>
841
+ {' '}with the message{' '}
842
+ <ITText as="span" className="italic">"fix: race condition in cache invalidation"</ITText>.
843
+ </ITText>
844
+ <ITFlex align="center" gap={2} className="mt-3">
845
+ <ITText muted as="span" className="text-[11px]">12 minutes ago</ITText>
846
+ <ITDivider orientation="vertical" className="h-3" />
847
+ <ITText muted as="span" className="text-[11px] font-mono">api-service</ITText>
848
+ <ITDivider orientation="vertical" className="h-3" />
849
+ <ITBadget label="+124 -38" color="success" size="small" variant="outlined" />
850
+ </ITFlex>
851
+ </div>
852
+ </PatternCard>
853
+
854
+ {/* 5. Form labels — label + helper text */}
855
+ <PatternCard
856
+ title="Form labels"
857
+ desc="label + required asterisk + muted helper text"
858
+ code={TEXT_PATTERN_CODES.formLabels}
859
+ >
860
+ <ITStack spacing={4} className="max-w-sm">
861
+ <div>
862
+ <ITText as="label" className="text-sm font-semibold text-slate-700 dark:text-slate-200 block mb-1">
863
+ Workspace name <ITText as="span" className="text-danger-500">*</ITText>
864
+ </ITText>
865
+ <ITInput
866
+ name="ws_name"
867
+ value=""
868
+ onChange={() => {}}
869
+ onBlur={() => {}}
870
+ placeholder="my-awesome-project"
871
+ />
872
+ <ITText muted as="span" className="text-[11px] mt-1 block">
873
+ Lowercase letters, numbers and hyphens only.
874
+ </ITText>
875
+ </div>
876
+ <div>
877
+ <ITText as="label" className="text-sm font-semibold text-slate-700 dark:text-slate-200 block mb-1">
878
+ Description
879
+ </ITText>
880
+ <ITInput
881
+ name="ws_desc"
882
+ value=""
883
+ onChange={() => {}}
884
+ onBlur={() => {}}
885
+ placeholder="A short summary of what your team is building"
886
+ />
887
+ <ITText muted as="span" className="text-[11px] mt-1 block">
888
+ Optional. Max 140 characters.
889
+ </ITText>
890
+ </div>
891
+ </ITStack>
892
+ </PatternCard>
893
+ </div>
894
+ </GallerySection>
895
+ </ITStack>
108
896
  }
109
897
  />
110
898
  );
111
899
  };
112
900
 
113
- // Temporary helper helper to render ITSelect inside showcases
114
- const ITSelectStub = ({ name, label, value, onChange, options }: any) => {
115
- return (
116
- <div className="flex flex-col gap-1">
117
- <label className="text-xs font-semibold text-slate-600 dark:text-slate-400">{label}</label>
118
- <select
119
- name={name}
120
- value={value}
121
- onChange={onChange}
122
- className="w-full bg-slate-50 dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-lg p-2 text-xs text-slate-800 dark:text-slate-100 outline-none"
123
- >
124
- {options.map((opt: any) => (
125
- <option key={opt.value} value={opt.value}>
126
- {opt.label}
127
- </option>
128
- ))}
129
- </select>
130
- </div>
131
- );
132
- };
901
+
133
902
 
134
903
  // 3. ITLayout & ITNavbar Showcase
135
904
  export const LayoutShowcase = () => {
136
905
  const [collapsed, setCollapsed] = useState(false);
137
906
  const [activeId, setActiveId] = useState("dashboard");
907
+ const [navActiveId, setNavActiveId] = useState<string | null>("1");
138
908
 
139
909
  const topBar = {
140
910
  logo: <div className="w-9 h-9 rounded-lg bg-primary-500 flex items-center justify-center text-white font-bold">A</div>,
@@ -184,18 +954,25 @@ export const LayoutShowcase = () => {
184
954
  }}
185
955
  sidebar={{
186
956
  navigationItems: [...],
187
- isCollapsed: false,
188
- onToggleCollapse: () => {}
957
+ isCollapsed: ${collapsed},
958
+ onToggleCollapse: () => setCollapsed(v => !v)
189
959
  }}
190
960
  >
191
961
  {/* Tu contenido */}
192
962
  </ITLayout>`;
193
963
 
964
+ const navbarItems = [
965
+ { id: "1", label: "Inicio", icon: <FaHome />, isActive: navActiveId === "1", action: () => setNavActiveId("1") },
966
+ { id: "2", label: "Documentos", icon: <FaFileAlt />, isActive: navActiveId === "2", action: () => setNavActiveId("2") },
967
+ { id: "3", label: "Alertas", icon: <FaBell />, isActive: navActiveId === "3", action: () => setNavActiveId("3") },
968
+ ];
969
+
194
970
  const navbarCode = `<ITNavbar
195
971
  logoText="AXZY"
196
972
  navigationItems={[
197
973
  { id: "1", label: "Inicio", icon: <FaHome />, isActive: true },
198
- { id: "2", label: "Auditoría" }
974
+ { id: "2", label: "Documentos", icon: <FaFileAlt /> },
975
+ { id: "3", label: "Alertas", icon: <FaBell /> }
199
976
  ]}
200
977
  userMenu={{
201
978
  userName: "Auditor AXZY",
@@ -260,11 +1037,7 @@ export const LayoutShowcase = () => {
260
1037
  <div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden h-[420px]">
261
1038
  <ITNavbar
262
1039
  logoText="AXZY"
263
- navigationItems={[
264
- { id: "1", label: "Inicio", icon: <FaHome />, isActive: true },
265
- { id: "2", label: "Documentos", icon: <FaFileAlt /> },
266
- { id: "3", label: "Alertas", icon: <FaBell /> },
267
- ]}
1040
+ navigationItems={navbarItems}
268
1041
  userMenu={{
269
1042
  userName: "Auditor AXZY",
270
1043
  userEmail: "auditor@axzy.dev",
@@ -275,7 +1048,7 @@ export const LayoutShowcase = () => {
275
1048
  }}
276
1049
  >
277
1050
  <div className="p-8 text-center text-slate-500 text-sm">
278
- Contenido principal (children)
1051
+ {navActiveId ? `Item activo: "${navbarItems.find(i => i.isActive)?.label}"` : "Selecciona un item en la navegación"}
279
1052
  </div>
280
1053
  </ITNavbar>
281
1054
  </div>
@@ -309,7 +1082,7 @@ export const LayoutShowcase = () => {
309
1082
  }}
310
1083
  >
311
1084
  <div className="p-8 text-center text-slate-500 text-sm">
312
- Click en "Ventas" para expandir el submenú
1085
+ Haz clic en "Ventas" para expandir/colapsar el submenú
313
1086
  </div>
314
1087
  </ITNavbar>
315
1088
  </div>