xertica-ui 2.7.0 → 2.8.0

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 (228) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +19 -11
  3. package/bin/generate-tokens.ts +25 -9
  4. package/components/assistant/xertica-assistant/xertica-assistant.tsx +1 -1
  5. package/components/ui/button/button.test.tsx +2 -2
  6. package/components/ui/button/button.tsx +6 -6
  7. package/components/ui/card/card.tsx +14 -2
  8. package/components/ui/input/input.tsx +1 -1
  9. package/components/ui/input-otp/input-otp.tsx +1 -1
  10. package/components/ui/search/search.tsx +1 -1
  11. package/components/ui/select/select.tsx +2 -2
  12. package/components/ui/switch/switch.tsx +1 -1
  13. package/components/ui/textarea/textarea.tsx +1 -1
  14. package/contexts/BrandColorsContext.tsx +50 -2
  15. package/contexts/theme-data.ts +100 -3
  16. package/dist/AssistantChart-BFBJXVcm.js +3383 -0
  17. package/dist/AssistantChart-BTnE94FR.cjs +3551 -0
  18. package/dist/AssistantChart-BvccsQMx.cjs +3551 -0
  19. package/dist/AssistantChart-CkskcBVD.js +3383 -0
  20. package/dist/AssistantChart-CrPkO9ip.js +3383 -0
  21. package/dist/AssistantChart-DKz2O1R8.cjs +3551 -0
  22. package/dist/AssistantChart-DYL6UEvo.cjs +3551 -0
  23. package/dist/AssistantChart-keo-ogKi.js +3383 -0
  24. package/dist/AudioPlayer-AoU5MTiM.cjs +1282 -0
  25. package/dist/AudioPlayer-Bx1vrblm.js +1278 -0
  26. package/dist/AudioPlayer-D0-I6J3J.cjs +1282 -0
  27. package/dist/AudioPlayer-DIWX_Yg7.cjs +1282 -0
  28. package/dist/AudioPlayer-DrWJnS7c.js +1278 -0
  29. package/dist/AudioPlayer-_P-Z7pAK.js +1278 -0
  30. package/dist/BrandColorsContext-B25Bpr3b.cjs +819 -0
  31. package/dist/BrandColorsContext-BCieATdW.js +812 -0
  32. package/dist/BrandColorsContext-DP0DXAXS.js +824 -0
  33. package/dist/BrandColorsContext-DjpC9wR_.cjs +798 -0
  34. package/dist/BrandColorsContext-MpXFhte7.cjs +831 -0
  35. package/dist/BrandColorsContext-V3tOc-Zw.js +791 -0
  36. package/dist/CodeBlock-CK4rO6lM.js +221 -0
  37. package/dist/CodeBlock-CKXamfVd.cjs +223 -0
  38. package/dist/CodeBlock-CVmE7isS.cjs +223 -0
  39. package/dist/CodeBlock-D7i5-cMv.js +221 -0
  40. package/dist/CodeBlock-Dg56j2ut.cjs +223 -0
  41. package/dist/CodeBlock-Dt6nUQoo.js +221 -0
  42. package/dist/CustomTooltipContent-Bxynuq7T.js +33 -0
  43. package/dist/CustomTooltipContent-BzjOSA0P.cjs +54 -0
  44. package/dist/CustomTooltipContent-C-ZeCNsf.js +33 -0
  45. package/dist/CustomTooltipContent-CON_QrXm.cjs +54 -0
  46. package/dist/CustomTooltipContent-UR_n2QfW.js +33 -0
  47. package/dist/CustomTooltipContent-v1SXjoFn.cjs +54 -0
  48. package/dist/FeatureCard-4n_8a63v.cjs +497 -0
  49. package/dist/FeatureCard-BLiAWT3w.js +485 -0
  50. package/dist/FeatureCard-BXRW97Ef.cjs +497 -0
  51. package/dist/FeatureCard-CDgLlWE2.js +485 -0
  52. package/dist/FeatureCard-CgQ8lq-I.cjs +497 -0
  53. package/dist/FeatureCard-Cp8cVC6T.cjs +497 -0
  54. package/dist/FeatureCard-D0MwrTRP.js +485 -0
  55. package/dist/FeatureCard-uE5i0in_.js +485 -0
  56. package/dist/ImageWithFallback-BOh1FM3I.js +98 -0
  57. package/dist/ImageWithFallback-BQO7952C.js +98 -0
  58. package/dist/ImageWithFallback-BkMXHCvV.cjs +122 -0
  59. package/dist/ImageWithFallback-C72nwszA.cjs +122 -0
  60. package/dist/ImageWithFallback-CCUMDuEC.cjs +122 -0
  61. package/dist/ImageWithFallback-DQD5TTlY.js +98 -0
  62. package/dist/LanguageSelector-1XhM7R1i.cjs +48 -0
  63. package/dist/LanguageSelector-B3ZVNc55.js +46 -0
  64. package/dist/LanguageSelector-Cj6zl0CM.js +46 -0
  65. package/dist/LanguageSelector-DK1zD4VH.cjs +48 -0
  66. package/dist/LanguageSelector-DseCAa0p.cjs +48 -0
  67. package/dist/LanguageSelector-Du09anfM.js +46 -0
  68. package/dist/LanguageSelector-PZHlFfEs.cjs +48 -0
  69. package/dist/LanguageSelector-SB-NJSmx.js +46 -0
  70. package/dist/PasswordStrengthMeter-B3S6i_k4.cjs +179 -0
  71. package/dist/PasswordStrengthMeter-B8ky1nJI.js +173 -0
  72. package/dist/PasswordStrengthMeter-C5VEopH-.cjs +179 -0
  73. package/dist/PasswordStrengthMeter-CIm7_jNT.js +173 -0
  74. package/dist/PasswordStrengthMeter-DKSAbQzu.js +173 -0
  75. package/dist/PasswordStrengthMeter-DxLu54p-.cjs +179 -0
  76. package/dist/PasswordStrengthMeter-k-e9Pole.cjs +179 -0
  77. package/dist/PasswordStrengthMeter-pAi2viq5.js +173 -0
  78. package/dist/ThemeToggle-4pQbVkpK.js +215 -0
  79. package/dist/ThemeToggle-B6rIVLvC.cjs +219 -0
  80. package/dist/ThemeToggle-BUOTps5l.cjs +219 -0
  81. package/dist/ThemeToggle-CO5mPl6e.js +215 -0
  82. package/dist/ThemeToggle-DbZQ0JSV.cjs +219 -0
  83. package/dist/ThemeToggle-vLXEq2TS.js +215 -0
  84. package/dist/VerifyEmailPage-BTjI2c9n.js +2954 -0
  85. package/dist/VerifyEmailPage-CJGfDSOx.js +2954 -0
  86. package/dist/VerifyEmailPage-DOlZUNc0.cjs +2963 -0
  87. package/dist/VerifyEmailPage-DQPRl_RJ.js +2954 -0
  88. package/dist/VerifyEmailPage-DrdqMbLC.cjs +2963 -0
  89. package/dist/VerifyEmailPage-hyDfeCRa.cjs +2963 -0
  90. package/dist/VerifyEmailPage-kKSXl8vu.cjs +2963 -0
  91. package/dist/VerifyEmailPage-w4N-bDhU.js +2954 -0
  92. package/dist/XerticaOrbe-B9tegV1n.js +1925 -0
  93. package/dist/XerticaOrbe-BQ_NjwPS.cjs +1927 -0
  94. package/dist/XerticaOrbe-BdUX171Q.cjs +1927 -0
  95. package/dist/XerticaOrbe-BdlKXRHU.cjs +1927 -0
  96. package/dist/XerticaOrbe-CByPAFE5.js +1925 -0
  97. package/dist/XerticaOrbe-Ccu9eFMu.js +1925 -0
  98. package/dist/XerticaProvider-BVid1oqn.cjs +46 -0
  99. package/dist/XerticaProvider-Bz_YfNY4.js +44 -0
  100. package/dist/XerticaProvider-CtvYfRbZ.cjs +46 -0
  101. package/dist/XerticaProvider-DMiyExQS.js +44 -0
  102. package/dist/XerticaProvider-DP2lzKip.cjs +46 -0
  103. package/dist/XerticaProvider-De79hhgp.js +44 -0
  104. package/dist/XerticaProvider-Dkk1Vbsy.js +44 -0
  105. package/dist/XerticaProvider-EdzH9Nrw.cjs +46 -0
  106. package/dist/alert-dialog-9XYAn5z5.js +819 -0
  107. package/dist/alert-dialog-B281hud0.cjs +872 -0
  108. package/dist/alert-dialog-BVWbrcrw.cjs +872 -0
  109. package/dist/alert-dialog-B_Ko1xpu.js +819 -0
  110. package/dist/alert-dialog-CIxE8T-J.cjs +872 -0
  111. package/dist/alert-dialog-DW-_iPuf.js +819 -0
  112. package/dist/assistant.cjs.js +2 -2
  113. package/dist/assistant.es.js +2 -2
  114. package/dist/avatar-BJwIMbZ_.js +54 -0
  115. package/dist/avatar-C4Zh5fAJ.cjs +77 -0
  116. package/dist/avatar-CTEUKZUT.js +54 -0
  117. package/dist/avatar-D1bZhlhL.cjs +77 -0
  118. package/dist/avatar-DKIxHeKG.cjs +77 -0
  119. package/dist/avatar-v16eZC8p.js +54 -0
  120. package/dist/blocks.cjs.js +2 -2
  121. package/dist/blocks.es.js +2 -2
  122. package/dist/brand.cjs.js +4 -4
  123. package/dist/brand.es.js +4 -4
  124. package/dist/breadcrumb-B1mUiaWB.cjs +98 -0
  125. package/dist/breadcrumb-BIRgmem-.js +90 -0
  126. package/dist/breadcrumb-BSng-oUf.cjs +98 -0
  127. package/dist/breadcrumb-CES7furU.js +90 -0
  128. package/dist/breadcrumb-CP275kbF.cjs +98 -0
  129. package/dist/breadcrumb-D7hr1EvJ.js +90 -0
  130. package/dist/button-BYtQygX5.cjs +85 -0
  131. package/dist/button-BnAW-a_w.js +62 -0
  132. package/dist/button-CUPDQews.js +62 -0
  133. package/dist/button-DFa-rtPy.js +62 -0
  134. package/dist/button-DV1G6XrI.cjs +85 -0
  135. package/dist/button-Kd9Fj53S.cjs +85 -0
  136. package/dist/cli.js +94 -10
  137. package/dist/components/ui/card/card.d.ts +11 -1
  138. package/dist/contexts/theme-data.d.ts +15 -1
  139. package/dist/dropdown-menu-B9wTZ0uX.cjs +225 -0
  140. package/dist/dropdown-menu-BeBtZOrs.cjs +225 -0
  141. package/dist/dropdown-menu-D7mRDGis.js +190 -0
  142. package/dist/dropdown-menu-D8ZmqHB7.js +190 -0
  143. package/dist/dropdown-menu-_AWBeOts.cjs +225 -0
  144. package/dist/dropdown-menu-qGzLO_HO.js +190 -0
  145. package/dist/hooks.cjs.js +1 -1
  146. package/dist/hooks.es.js +1 -1
  147. package/dist/index.cjs.js +24 -24
  148. package/dist/index.es.js +24 -24
  149. package/dist/input-B53E6K8G.js +65 -0
  150. package/dist/input-B7Q7vcoG.cjs +91 -0
  151. package/dist/input-BysqLMK1.js +65 -0
  152. package/dist/input-CStdFsaH.cjs +91 -0
  153. package/dist/input-CXYth6nW.cjs +91 -0
  154. package/dist/input-CX_fWE2D.cjs +91 -0
  155. package/dist/input-CitUVnEn.js +65 -0
  156. package/dist/input-wkBYTp-B.js +65 -0
  157. package/dist/layout.cjs.js +1 -1
  158. package/dist/layout.es.js +1 -1
  159. package/dist/media.cjs.js +1 -1
  160. package/dist/media.es.js +1 -1
  161. package/dist/pages.cjs.js +1 -1
  162. package/dist/pages.es.js +1 -1
  163. package/dist/rich-text-editor-BHiRUzWZ.js +2894 -0
  164. package/dist/rich-text-editor-BWMRUMJ2.js +2894 -0
  165. package/dist/rich-text-editor-BoE6Ks5x.cjs +2968 -0
  166. package/dist/rich-text-editor-BzuEwR_X.js +2894 -0
  167. package/dist/rich-text-editor-CcopGbQ-.js +2894 -0
  168. package/dist/rich-text-editor-CmxSRJIi.cjs +2968 -0
  169. package/dist/rich-text-editor-DyYAu28v.cjs +2968 -0
  170. package/dist/rich-text-editor-JS_eMQCC.cjs +2968 -0
  171. package/dist/select-BNfFJwYp.js +130 -0
  172. package/dist/select-CN8IDjGB.js +130 -0
  173. package/dist/select-CwRzQHA7.cjs +161 -0
  174. package/dist/select-CwgD3nMD.js +130 -0
  175. package/dist/select-DEHUm_AC.cjs +161 -0
  176. package/dist/select-DJDgpVm3.cjs +161 -0
  177. package/dist/select-DSLWQLmo.cjs +161 -0
  178. package/dist/select-YFx0wCYT.js +130 -0
  179. package/dist/sidebar-BF7JEL7U.js +1151 -0
  180. package/dist/sidebar-Bjr2doX5.cjs +1154 -0
  181. package/dist/sidebar-CMrNCmhb.cjs +1154 -0
  182. package/dist/sidebar-CO9x8AVn.cjs +1154 -0
  183. package/dist/sidebar-Cn_KB4c6.js +1151 -0
  184. package/dist/sidebar-Db_C30ph.cjs +1154 -0
  185. package/dist/sidebar-miPHsRz4.js +1151 -0
  186. package/dist/sidebar-pZF8mLLu.js +1151 -0
  187. package/dist/skeleton-BX2XTjMO.cjs +87 -0
  188. package/dist/skeleton-BoLK0iV7.js +78 -0
  189. package/dist/skeleton-Bysq8yeB.js +79 -0
  190. package/dist/skeleton-C7nspYnC.cjs +87 -0
  191. package/dist/skeleton-DL4V5Vub.cjs +87 -0
  192. package/dist/skeleton-DSMhdqp1.js +78 -0
  193. package/dist/skeleton-DhJswvTW.cjs +88 -0
  194. package/dist/skeleton-DicUfozA.js +78 -0
  195. package/dist/slider-77T_Eqw4.js +56 -0
  196. package/dist/slider-B6puMLXS.cjs +78 -0
  197. package/dist/slider-B785N7lZ.js +56 -0
  198. package/dist/slider-C6yssKyZ.cjs +78 -0
  199. package/dist/slider-CKZO9gVh.cjs +78 -0
  200. package/dist/slider-Cn-ImSze.js +56 -0
  201. package/dist/tooltip-BiJVGob3.cjs +72 -0
  202. package/dist/tooltip-D2OPn-1v.cjs +72 -0
  203. package/dist/tooltip-DlCHQuh1.js +48 -0
  204. package/dist/tooltip-fQ2Va0G8.cjs +72 -0
  205. package/dist/tooltip-oAw00FX2.js +48 -0
  206. package/dist/tooltip-u147L0wD.js +48 -0
  207. package/dist/ui.cjs.js +13 -13
  208. package/dist/ui.es.js +13 -13
  209. package/dist/xertica-assistant-C2A0R94j.js +2173 -0
  210. package/dist/xertica-assistant-CSUprvTR.js +2173 -0
  211. package/dist/xertica-assistant-Caubm0HR.js +2173 -0
  212. package/dist/xertica-assistant-DEexPM2u.cjs +2180 -0
  213. package/dist/xertica-assistant-Dh1dmEx3.cjs +2180 -0
  214. package/dist/xertica-assistant-GGcyHEZG.cjs +2180 -0
  215. package/dist/xertica-assistant-USefPe2L.js +2173 -0
  216. package/dist/xertica-assistant-cwSHFwfv.cjs +2180 -0
  217. package/dist/xertica-ui.css +1 -1
  218. package/package.json +3 -2
  219. package/styles/xertica/base.css +38 -0
  220. package/styles/xertica/tokens.css +9 -0
  221. package/templates/src/app/App.tsx +5 -1
  222. package/templates/src/features/home/ui/HomeContent.tsx +12 -13
  223. package/templates/src/features/template/ui/TemplateContent.tsx +569 -26
  224. package/templates/src/locales/en/pages/templates.json +112 -4
  225. package/templates/src/locales/es/pages/templates.json +112 -4
  226. package/templates/src/locales/pt-BR/pages/templates.json +112 -4
  227. package/templates/src/styles/xertica/tokens.css +9 -0
  228. package/templates/vite.config.ts +25 -0
@@ -1,21 +1,120 @@
1
- import React from 'react';
2
- import { Button, Input, Label, Card, CardHeader, CardTitle, CardContent } from 'xertica-ui/ui';
1
+ import React, { useState } from 'react';
2
+ import {
3
+ Accordion,
4
+ AccordionContent,
5
+ AccordionItem,
6
+ AccordionTrigger,
7
+ Alert,
8
+ AlertDescription,
9
+ AlertDialog,
10
+ AlertDialogAction,
11
+ AlertDialogCancel,
12
+ AlertDialogContent,
13
+ AlertDialogDescription,
14
+ AlertDialogFooter,
15
+ AlertDialogHeader,
16
+ AlertDialogTitle,
17
+ AlertDialogTrigger,
18
+ AlertTitle,
19
+ Avatar,
20
+ AvatarFallback,
21
+ AvatarImage,
22
+ Badge,
23
+ Button,
24
+ Card,
25
+ CardContent,
26
+ CardDescription,
27
+ CardFooter,
28
+ CardHeader,
29
+ CardTitle,
30
+ Checkbox,
31
+ Dialog,
32
+ DialogContent,
33
+ DialogDescription,
34
+ DialogFooter,
35
+ DialogHeader,
36
+ DialogTitle,
37
+ DialogTrigger,
38
+ Input,
39
+ Label,
40
+ PageHeader,
41
+ Progress,
42
+ RadioGroup,
43
+ RadioGroupItem,
44
+ Select,
45
+ SelectContent,
46
+ SelectItem,
47
+ SelectTrigger,
48
+ SelectValue,
49
+ Separator,
50
+ Slider,
51
+ StatsCard,
52
+ Switch,
53
+ Table,
54
+ TableBody,
55
+ TableCell,
56
+ TableHead,
57
+ TableHeader,
58
+ TableRow,
59
+ Textarea,
60
+ Tooltip,
61
+ TooltipContent,
62
+ TooltipTrigger,
63
+ } from 'xertica-ui/ui';
3
64
  import { Header } from 'xertica-ui/layout';
4
65
  import { useLayout } from 'xertica-ui/hooks';
5
66
  import { Link } from 'react-router-dom';
6
67
  import { useTranslation } from 'react-i18next';
68
+ import { toast } from 'sonner';
69
+ import {
70
+ Activity,
71
+ DollarSign,
72
+ Mail,
73
+ Search,
74
+ Settings,
75
+ ThumbsUp,
76
+ Users,
77
+ } from 'lucide-react';
78
+
79
+ interface MockUser {
80
+ id: string;
81
+ name: string;
82
+ email: string;
83
+ status: 'active' | 'invited' | 'inactive';
84
+ }
85
+
86
+ const MOCK_USERS: MockUser[] = [
87
+ { id: '1', name: 'Ana Souza', email: 'ana.souza@example.com', status: 'active' },
88
+ { id: '2', name: 'Bruno Lima', email: 'bruno.lima@example.com', status: 'invited' },
89
+ { id: '3', name: 'Carla Dias', email: 'carla.dias@example.com', status: 'active' },
90
+ { id: '4', name: 'Diego Alves', email: 'diego.alves@example.com', status: 'inactive' },
91
+ ];
7
92
 
8
93
  /**
9
- * Template page content — starter placeholder.
94
+ * Template page content — Design System showcase.
10
95
  *
11
- * Replace this with your own page content. It shows a few basic
12
- * `xertica-ui/ui` components wired up as a starting point; delete or expand
13
- * as needed.
96
+ * Curated overview of the most common `xertica-ui/ui` primitives, grouped by
97
+ * category. Replace this with your own page content keep the `Header` +
98
+ * `useLayout()` wiring below if you want the sidebar-aware layout to keep
99
+ * working.
14
100
  */
15
101
  export function TemplateContent() {
16
102
  const { t } = useTranslation();
17
103
  const { sidebarExpanded, sidebarWidth } = useLayout();
18
104
 
105
+ const [progress, setProgress] = useState(45);
106
+ const [volume, setVolume] = useState([60]);
107
+ const [tableFilter, setTableFilter] = useState('');
108
+
109
+ const filteredUsers = MOCK_USERS.filter(user =>
110
+ `${user.name} ${user.email}`.toLowerCase().includes(tableFilter.toLowerCase())
111
+ );
112
+
113
+ const handleFormSubmit = (event: React.FormEvent) => {
114
+ event.preventDefault();
115
+ toast.success(t('templates.forms.submitSuccess'));
116
+ };
117
+
19
118
  return (
20
119
  <div
21
120
  style={{
@@ -39,26 +138,470 @@ export function TemplateContent() {
39
138
  <div className="h-full" style={{ overflowY: 'auto', overflowX: 'hidden' }}>
40
139
  <div className="p-5 sm:p-4 md:p-6">
41
140
  <div className="max-w-6xl mx-auto space-y-8">
42
- <div className="space-y-2">
43
- <h2>{t('templates.title')}</h2>
44
- <p className="text-muted-foreground">{t('templates.subtitle')}</p>
45
- </div>
46
-
47
- {/* Replace this with your own page content */}
48
- <Card>
49
- <CardHeader>
50
- <CardTitle>{t('templates.exampleTitle')}</CardTitle>
51
- </CardHeader>
52
- <CardContent className="space-y-4">
53
- <div className="space-y-2">
54
- <Label htmlFor="template-example-input">
55
- {t('templates.exampleInputLabel')}
56
- </Label>
57
- <Input id="template-example-input" placeholder={t('templates.exampleInputPlaceholder')} />
58
- </div>
59
- <Button>{t('templates.exampleButton')}</Button>
60
- </CardContent>
61
- </Card>
141
+ <PageHeader title={t('templates.title')} subtitle={t('templates.subtitle')} />
142
+
143
+ {/* Replace this with your own page content — everything below is a Design System showcase */}
144
+
145
+ {/* Overview */}
146
+ <section>
147
+ <h3 className="mb-4">{t('templates.sections.overview')}</h3>
148
+ <div className="grid gap-4 md:grid-cols-3">
149
+ <StatsCard
150
+ title={t('templates.overview.activeUsers')}
151
+ value="1,234"
152
+ icon={<Users className="size-5" />}
153
+ iconColor="text-primary"
154
+ iconBg="bg-primary/10"
155
+ trend={{ value: 12 }}
156
+ />
157
+ <StatsCard
158
+ title={t('templates.overview.revenue')}
159
+ value="$45.2k"
160
+ icon={<DollarSign className="size-5" />}
161
+ iconColor="text-success"
162
+ iconBg="bg-success/10"
163
+ trend={{ value: 8 }}
164
+ />
165
+ <StatsCard
166
+ title={t('templates.overview.engagement')}
167
+ value="3.2%"
168
+ icon={<Activity className="size-5" />}
169
+ iconColor="text-info"
170
+ iconBg="bg-info/10"
171
+ trend={{ value: -2 }}
172
+ />
173
+ </div>
174
+ </section>
175
+
176
+ <Separator className="my-8" />
177
+
178
+ {/* Buttons */}
179
+ <section>
180
+ <h3 className="mb-4">{t('templates.sections.buttons')}</h3>
181
+ <Card>
182
+ <CardHeader>
183
+ <CardTitle>{t('templates.buttons.title')}</CardTitle>
184
+ <CardDescription>{t('templates.buttons.description')}</CardDescription>
185
+ </CardHeader>
186
+ <CardContent className="space-y-6">
187
+ <div className="space-y-3">
188
+ <Label>{t('templates.buttons.variants')}</Label>
189
+ <div className="flex flex-wrap gap-3">
190
+ <Button variant="default">Default</Button>
191
+ <Button variant="secondary">Secondary</Button>
192
+ <Button variant="outline">Outline</Button>
193
+ <Button variant="ghost">Ghost</Button>
194
+ <Button variant="link">Link</Button>
195
+ <Button variant="destructive">Destructive</Button>
196
+ <Button variant="success">Success</Button>
197
+ <Button variant="info">Info</Button>
198
+ <Button variant="warning">Warning</Button>
199
+ </div>
200
+ </div>
201
+
202
+ <Separator />
203
+
204
+ <div className="space-y-3">
205
+ <Label>{t('templates.buttons.sizes')}</Label>
206
+ <div className="flex flex-wrap items-center gap-3">
207
+ <Button size="sm">Small</Button>
208
+ <Button size="default">Default</Button>
209
+ <Button size="lg">Large</Button>
210
+ <Button size="icon" aria-label={t('nav.settings')}>
211
+ <Settings className="h-4 w-4" />
212
+ </Button>
213
+ </div>
214
+ </div>
215
+
216
+ <Separator />
217
+
218
+ <div className="space-y-3">
219
+ <Label>{t('templates.buttons.withIcons')}</Label>
220
+ <div className="flex flex-wrap gap-3">
221
+ <Button>
222
+ <Mail className="mr-2 h-4 w-4" />
223
+ {t('templates.buttons.sendEmail')}
224
+ </Button>
225
+ <Button variant="outline" loading>
226
+ {t('templates.buttons.loading')}
227
+ </Button>
228
+ <Button disabled>{t('templates.buttons.disabled')}</Button>
229
+ </div>
230
+ </div>
231
+ </CardContent>
232
+ </Card>
233
+ </section>
234
+
235
+ <Separator className="my-8" />
236
+
237
+ {/* Badges */}
238
+ <section>
239
+ <h3 className="mb-4">{t('templates.sections.badges')}</h3>
240
+ <Card>
241
+ <CardHeader>
242
+ <CardTitle>{t('templates.badges.title')}</CardTitle>
243
+ <CardDescription>{t('templates.badges.description')}</CardDescription>
244
+ </CardHeader>
245
+ <CardContent>
246
+ <div className="flex flex-wrap gap-3">
247
+ <Badge variant="default">Default</Badge>
248
+ <Badge variant="secondary">Secondary</Badge>
249
+ <Badge variant="outline">Outline</Badge>
250
+ <Badge variant="destructive">Destructive</Badge>
251
+ <Badge className="bg-success text-success-foreground">Success</Badge>
252
+ <Badge className="bg-warning text-warning-foreground">Warning</Badge>
253
+ <Badge className="bg-info text-info-foreground">Info</Badge>
254
+ </div>
255
+ </CardContent>
256
+ </Card>
257
+ </section>
258
+
259
+ <Separator className="my-8" />
260
+
261
+ {/* Alerts */}
262
+ <section>
263
+ <h3 className="mb-4">{t('templates.sections.alerts')}</h3>
264
+ <div className="grid gap-4 md:grid-cols-2">
265
+ <Alert variant="info">
266
+ <AlertTitle>{t('templates.alerts.infoTitle')}</AlertTitle>
267
+ <AlertDescription>{t('templates.alerts.infoDescription')}</AlertDescription>
268
+ </Alert>
269
+ <Alert variant="success">
270
+ <AlertTitle>{t('templates.alerts.successTitle')}</AlertTitle>
271
+ <AlertDescription>{t('templates.alerts.successDescription')}</AlertDescription>
272
+ </Alert>
273
+ <Alert variant="warning">
274
+ <AlertTitle>{t('templates.alerts.warningTitle')}</AlertTitle>
275
+ <AlertDescription>{t('templates.alerts.warningDescription')}</AlertDescription>
276
+ </Alert>
277
+ <Alert variant="destructive">
278
+ <AlertTitle>{t('templates.alerts.errorTitle')}</AlertTitle>
279
+ <AlertDescription>{t('templates.alerts.errorDescription')}</AlertDescription>
280
+ </Alert>
281
+ </div>
282
+ </section>
283
+
284
+ <Separator className="my-8" />
285
+
286
+ {/* Form Elements */}
287
+ <section>
288
+ <h3 className="mb-4">{t('templates.sections.forms')}</h3>
289
+ <Card>
290
+ <CardHeader>
291
+ <CardTitle>{t('templates.forms.title')}</CardTitle>
292
+ <CardDescription>{t('templates.forms.description')}</CardDescription>
293
+ </CardHeader>
294
+ <CardContent>
295
+ <form onSubmit={handleFormSubmit} className="space-y-4">
296
+ <div className="grid gap-4 md:grid-cols-2">
297
+ <div className="space-y-2">
298
+ <Label htmlFor="tpl-name">{t('templates.forms.name')}</Label>
299
+ <Input id="tpl-name" placeholder={t('templates.forms.namePlaceholder')} />
300
+ </div>
301
+ <div className="space-y-2">
302
+ <Label htmlFor="tpl-role">{t('templates.forms.role')}</Label>
303
+ <Select>
304
+ <SelectTrigger id="tpl-role">
305
+ <SelectValue placeholder={t('templates.forms.rolePlaceholder')} />
306
+ </SelectTrigger>
307
+ <SelectContent>
308
+ <SelectItem value="developer">
309
+ {t('templates.forms.roles.developer')}
310
+ </SelectItem>
311
+ <SelectItem value="designer">
312
+ {t('templates.forms.roles.designer')}
313
+ </SelectItem>
314
+ <SelectItem value="manager">
315
+ {t('templates.forms.roles.manager')}
316
+ </SelectItem>
317
+ </SelectContent>
318
+ </Select>
319
+ </div>
320
+ </div>
321
+
322
+ <div className="space-y-2">
323
+ <Label htmlFor="tpl-bio">{t('templates.forms.bio')}</Label>
324
+ <Textarea
325
+ id="tpl-bio"
326
+ placeholder={t('templates.forms.bioPlaceholder')}
327
+ rows={3}
328
+ />
329
+ </div>
330
+
331
+ <Separator />
332
+
333
+ <div className="space-y-3">
334
+ <div className="flex items-center space-x-2">
335
+ <Checkbox id="tpl-newsletter" />
336
+ <Label htmlFor="tpl-newsletter" className="font-normal">
337
+ {t('templates.forms.newsletter')}
338
+ </Label>
339
+ </div>
340
+
341
+ <div className="flex items-center justify-between">
342
+ <Label htmlFor="tpl-notifications" className="font-normal">
343
+ {t('templates.forms.pushNotifications')}
344
+ </Label>
345
+ <Switch id="tpl-notifications" defaultChecked />
346
+ </div>
347
+ </div>
348
+
349
+ <Separator />
350
+
351
+ <div className="space-y-3">
352
+ <Label>{t('templates.forms.accountType')}</Label>
353
+ <RadioGroup defaultValue="personal" aria-label={t('templates.forms.accountType')}>
354
+ <div className="flex items-center space-x-2">
355
+ <RadioGroupItem value="personal" id="tpl-personal" />
356
+ <Label htmlFor="tpl-personal" className="font-normal">
357
+ {t('templates.forms.accountPersonal')}
358
+ </Label>
359
+ </div>
360
+ <div className="flex items-center space-x-2">
361
+ <RadioGroupItem value="business" id="tpl-business" />
362
+ <Label htmlFor="tpl-business" className="font-normal">
363
+ {t('templates.forms.accountBusiness')}
364
+ </Label>
365
+ </div>
366
+ </RadioGroup>
367
+ </div>
368
+ </form>
369
+ </CardContent>
370
+ <CardFooter className="flex justify-between">
371
+ <Button variant="outline">{t('templates.forms.cancel')}</Button>
372
+ <Button onClick={handleFormSubmit}>{t('templates.forms.submit')}</Button>
373
+ </CardFooter>
374
+ </Card>
375
+ </section>
376
+
377
+ <Separator className="my-8" />
378
+
379
+ {/* Data Table */}
380
+ <section>
381
+ <h3 className="mb-4">{t('templates.sections.data')}</h3>
382
+ <Card>
383
+ <CardHeader>
384
+ <CardTitle>{t('templates.data.title')}</CardTitle>
385
+ <CardDescription>{t('templates.data.description')}</CardDescription>
386
+ </CardHeader>
387
+ <CardContent>
388
+ <div className="mb-4 relative">
389
+ <Search className="absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
390
+ <Input
391
+ value={tableFilter}
392
+ onChange={event => setTableFilter(event.target.value)}
393
+ placeholder={t('templates.data.searchPlaceholder')}
394
+ aria-label={t('templates.data.searchPlaceholder')}
395
+ className="pl-10"
396
+ />
397
+ </div>
398
+
399
+ <div className="rounded-[var(--radius-lg)] border border-border overflow-hidden">
400
+ <Table>
401
+ <TableHeader>
402
+ <TableRow>
403
+ <TableHead>{t('templates.data.columns.name')}</TableHead>
404
+ <TableHead>{t('templates.data.columns.email')}</TableHead>
405
+ <TableHead className="text-right">
406
+ {t('templates.data.columns.status')}
407
+ </TableHead>
408
+ </TableRow>
409
+ </TableHeader>
410
+ <TableBody>
411
+ {filteredUsers.map(user => (
412
+ <TableRow key={user.id}>
413
+ <TableCell>{user.name}</TableCell>
414
+ <TableCell>{user.email}</TableCell>
415
+ <TableCell className="text-right">
416
+ <Badge
417
+ variant={
418
+ user.status === 'active'
419
+ ? 'default'
420
+ : user.status === 'invited'
421
+ ? 'secondary'
422
+ : 'outline'
423
+ }
424
+ >
425
+ {t(`templates.data.status.${user.status}`)}
426
+ </Badge>
427
+ </TableCell>
428
+ </TableRow>
429
+ ))}
430
+ </TableBody>
431
+ </Table>
432
+ </div>
433
+ </CardContent>
434
+ </Card>
435
+ </section>
436
+
437
+ <Separator className="my-8" />
438
+
439
+ {/* Dialogs */}
440
+ <section>
441
+ <h3 className="mb-4">{t('templates.sections.dialogs')}</h3>
442
+ <div className="grid gap-4 md:grid-cols-2">
443
+ <Card>
444
+ <CardHeader>
445
+ <CardTitle>{t('templates.dialogs.dialogTitle')}</CardTitle>
446
+ <CardDescription>{t('templates.dialogs.dialogDescription')}</CardDescription>
447
+ </CardHeader>
448
+ <CardContent className="flex justify-center py-6">
449
+ <Dialog>
450
+ <DialogTrigger asChild>
451
+ <Button variant="outline">{t('templates.dialogs.editProfile')}</Button>
452
+ </DialogTrigger>
453
+ <DialogContent className="sm:max-w-[425px]">
454
+ <DialogHeader>
455
+ <DialogTitle>{t('templates.dialogs.editProfile')}</DialogTitle>
456
+ <DialogDescription>
457
+ {t('templates.dialogs.editProfileDescription')}
458
+ </DialogDescription>
459
+ </DialogHeader>
460
+ <div className="grid gap-4 py-4">
461
+ <div className="space-y-2">
462
+ <Label htmlFor="tpl-dialog-name">{t('templates.dialogs.name')}</Label>
463
+ <Input id="tpl-dialog-name" defaultValue="Ana Souza" />
464
+ </div>
465
+ </div>
466
+ <DialogFooter>
467
+ <Button type="submit">{t('templates.dialogs.update')}</Button>
468
+ </DialogFooter>
469
+ </DialogContent>
470
+ </Dialog>
471
+ </CardContent>
472
+ </Card>
473
+
474
+ <Card>
475
+ <CardHeader>
476
+ <CardTitle>{t('templates.dialogs.alertDialogTitle')}</CardTitle>
477
+ <CardDescription>
478
+ {t('templates.dialogs.alertDialogDescription')}
479
+ </CardDescription>
480
+ </CardHeader>
481
+ <CardContent className="flex justify-center py-6">
482
+ <AlertDialog>
483
+ <AlertDialogTrigger asChild>
484
+ <Button variant="destructive">
485
+ {t('templates.dialogs.deleteAccount')}
486
+ </Button>
487
+ </AlertDialogTrigger>
488
+ <AlertDialogContent className="sm:max-w-[425px]">
489
+ <AlertDialogHeader>
490
+ <AlertDialogTitle>{t('templates.dialogs.areYouSure')}</AlertDialogTitle>
491
+ <AlertDialogDescription>
492
+ {t('templates.dialogs.deleteWarning')}
493
+ </AlertDialogDescription>
494
+ </AlertDialogHeader>
495
+ <AlertDialogFooter>
496
+ <AlertDialogCancel>{t('templates.dialogs.cancel')}</AlertDialogCancel>
497
+ <AlertDialogAction className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
498
+ {t('templates.dialogs.continue')}
499
+ </AlertDialogAction>
500
+ </AlertDialogFooter>
501
+ </AlertDialogContent>
502
+ </AlertDialog>
503
+ </CardContent>
504
+ </Card>
505
+ </div>
506
+ </section>
507
+
508
+ <Separator className="my-8" />
509
+
510
+ {/* Overlays & Feedback */}
511
+ <section>
512
+ <h3 className="mb-4">{t('templates.sections.overlays')}</h3>
513
+ <Card>
514
+ <CardHeader>
515
+ <CardTitle>{t('templates.overlays.title')}</CardTitle>
516
+ <CardDescription>{t('templates.overlays.description')}</CardDescription>
517
+ </CardHeader>
518
+ <CardContent className="space-y-6">
519
+ <div className="flex flex-wrap items-center gap-6">
520
+ <div className="flex items-center gap-3">
521
+ <Avatar>
522
+ <AvatarImage src="https://github.com/shadcn.png" alt="Avatar" />
523
+ <AvatarFallback>AS</AvatarFallback>
524
+ </Avatar>
525
+ <span className="text-muted-foreground">{t('templates.overlays.avatarLabel')}</span>
526
+ </div>
527
+
528
+ <Tooltip>
529
+ <TooltipTrigger asChild>
530
+ <Button variant="outline" size="icon" aria-label={t('templates.overlays.tooltipLabel')}>
531
+ <ThumbsUp className="h-4 w-4" />
532
+ </Button>
533
+ </TooltipTrigger>
534
+ <TooltipContent>{t('templates.overlays.tooltipContent')}</TooltipContent>
535
+ </Tooltip>
536
+ </div>
537
+
538
+ <Separator />
539
+
540
+ <div className="space-y-2">
541
+ <div className="flex items-center justify-between">
542
+ <Label>{t('templates.overlays.progressLabel')}</Label>
543
+ <span className="text-sm text-muted-foreground">{progress}%</span>
544
+ </div>
545
+ <Progress value={progress} className="w-full" />
546
+ <div className="flex gap-2">
547
+ <Button size="sm" onClick={() => setProgress(value => Math.max(0, value - 10))}>
548
+ -10%
549
+ </Button>
550
+ <Button size="sm" onClick={() => setProgress(value => Math.min(100, value + 10))}>
551
+ +10%
552
+ </Button>
553
+ </div>
554
+ </div>
555
+
556
+ <Separator />
557
+
558
+ <div className="space-y-2">
559
+ <div className="flex items-center justify-between">
560
+ <Label>{t('templates.overlays.sliderLabel')}</Label>
561
+ <span className="text-sm text-muted-foreground">{volume[0]}%</span>
562
+ </div>
563
+ <Slider
564
+ value={volume}
565
+ onValueChange={setVolume}
566
+ min={0}
567
+ max={100}
568
+ step={1}
569
+ className="w-full"
570
+ aria-label={t('templates.overlays.sliderLabel')}
571
+ />
572
+ </div>
573
+ </CardContent>
574
+ </Card>
575
+ </section>
576
+
577
+ <Separator className="my-8" />
578
+
579
+ {/* Accordion */}
580
+ <section>
581
+ <h3 className="mb-4">{t('templates.sections.accordion')}</h3>
582
+ <Card>
583
+ <CardHeader>
584
+ <CardTitle>{t('templates.accordion.title')}</CardTitle>
585
+ <CardDescription>{t('templates.accordion.description')}</CardDescription>
586
+ </CardHeader>
587
+ <CardContent>
588
+ <Accordion type="single" collapsible>
589
+ <AccordionItem value="item-1">
590
+ <AccordionTrigger>{t('templates.accordion.q1')}</AccordionTrigger>
591
+ <AccordionContent>{t('templates.accordion.a1')}</AccordionContent>
592
+ </AccordionItem>
593
+ <AccordionItem value="item-2">
594
+ <AccordionTrigger>{t('templates.accordion.q2')}</AccordionTrigger>
595
+ <AccordionContent>{t('templates.accordion.a2')}</AccordionContent>
596
+ </AccordionItem>
597
+ <AccordionItem value="item-3">
598
+ <AccordionTrigger>{t('templates.accordion.q3')}</AccordionTrigger>
599
+ <AccordionContent>{t('templates.accordion.a3')}</AccordionContent>
600
+ </AccordionItem>
601
+ </Accordion>
602
+ </CardContent>
603
+ </Card>
604
+ </section>
62
605
  </div>
63
606
  </div>
64
607
  </div>