@1doc/1ds-react 2.7.2 → 2.9.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 (302) hide show
  1. package/CHANGELOG.md +1280 -0
  2. package/dist/components/AIContent/AIContent.d.ts +10 -0
  3. package/dist/components/AIContent/AIContent.js +1 -1
  4. package/dist/components/AILabel/AILabel.d.ts +4 -0
  5. package/dist/components/AILabel/AILabel.js +2 -2
  6. package/dist/components/Accordion/Accordion.d.ts +6 -2
  7. package/dist/components/Alert/Alert.css +2 -0
  8. package/dist/components/Alert/Alert.d.ts +3 -1
  9. package/dist/components/Alert/Alert.js +7 -1
  10. package/dist/components/AppHeader/AppHeader.css +82 -8
  11. package/dist/components/AppHeader/AppHeader.d.ts +12 -1
  12. package/dist/components/AppHeader/AppHeader.js +186 -1
  13. package/dist/components/AppNavItem/AppNavItem.css +11 -3
  14. package/dist/components/AppShell/AppShell.css +9 -0
  15. package/dist/components/AppShell/AppShell.d.ts +8 -0
  16. package/dist/components/AppShell/AppShell.js +4 -1
  17. package/dist/components/AppSidebar/AppSidebar.css +1 -1
  18. package/dist/components/AppSidebar/AppSidebar.d.ts +4 -0
  19. package/dist/components/AppSidebar/AppSidebar.js +3 -1
  20. package/dist/components/AttachmentCard/AttachmentCard.css +17 -1
  21. package/dist/components/AttachmentCard/AttachmentCard.d.ts +29 -2
  22. package/dist/components/AttachmentCard/AttachmentCard.js +88 -20
  23. package/dist/components/Avatar/Avatar.css +7 -2
  24. package/dist/components/Avatar/AvatarGroup.d.ts +27 -0
  25. package/dist/components/Avatar/AvatarGroup.js +28 -4
  26. package/dist/components/Badge/Badge.css +61 -3
  27. package/dist/components/Badge/Badge.d.ts +14 -4
  28. package/dist/components/Badge/Badge.js +1 -0
  29. package/dist/components/BottomSheet/BottomSheet.css +1 -0
  30. package/dist/components/BottomSheet/BottomSheet.d.ts +8 -0
  31. package/dist/components/BottomSheet/BottomSheet.js +14 -2
  32. package/dist/components/Box/Box.css +83 -0
  33. package/dist/components/Box/Box.d.ts +82 -2
  34. package/dist/components/Box/Box.js +42 -2
  35. package/dist/components/Button/Button.css +29 -0
  36. package/dist/components/Button/Button.d.ts +4 -4
  37. package/dist/components/Button/Button.js +4 -1
  38. package/dist/components/Calendar/Calendar.css +245 -0
  39. package/dist/components/Calendar/Calendar.d.ts +125 -0
  40. package/dist/components/Calendar/Calendar.js +320 -0
  41. package/dist/components/Chart/BarChart.d.ts +6 -0
  42. package/dist/components/Chart/BarChart.js +3 -1
  43. package/dist/components/Chart/LineChart.d.ts +6 -0
  44. package/dist/components/Chart/LineChart.js +3 -1
  45. package/dist/components/Checkbox/Checkbox.css +4 -1
  46. package/dist/components/Chips/Chips.css +39 -0
  47. package/dist/components/Chips/Chips.d.ts +7 -2
  48. package/dist/components/Chips/Chips.js +6 -2
  49. package/dist/components/Coachmark/Coachmark.css +118 -0
  50. package/dist/components/Coachmark/Coachmark.d.ts +75 -0
  51. package/dist/components/Coachmark/Coachmark.js +321 -0
  52. package/dist/components/CodeBlock/CodeBlock.css +96 -0
  53. package/dist/components/CodeBlock/CodeBlock.d.ts +47 -0
  54. package/dist/components/CodeBlock/CodeBlock.js +103 -0
  55. package/dist/components/ColorPicker/ColorPicker.css +133 -0
  56. package/dist/components/ColorPicker/ColorPicker.d.ts +73 -0
  57. package/dist/components/ColorPicker/ColorPicker.js +219 -0
  58. package/dist/components/Combobox/Combobox.css +11 -3
  59. package/dist/components/ConfirmAIAction/ConfirmAIAction.d.ts +11 -1
  60. package/dist/components/ConfirmAIAction/ConfirmAIAction.js +6 -1
  61. package/dist/components/ConfirmDialog/ConfirmDialog.css +3 -0
  62. package/dist/components/ConfirmDialog/ConfirmDialog.d.ts +14 -0
  63. package/dist/components/ConfirmDialog/ConfirmDialog.js +2 -2
  64. package/dist/components/DataTable/DataTable.css +80 -0
  65. package/dist/components/DataTable/DataTable.d.ts +23 -4
  66. package/dist/components/DataTable/DataTable.js +61 -15
  67. package/dist/components/DatePicker/DatePicker.css +8 -0
  68. package/dist/components/DatePicker/DatePicker.d.ts +4 -0
  69. package/dist/components/DatePicker/DatePicker.js +14 -1
  70. package/dist/components/DescriptionList/DescriptionList.css +113 -0
  71. package/dist/components/DescriptionList/DescriptionList.d.ts +59 -0
  72. package/dist/components/DescriptionList/DescriptionList.js +51 -0
  73. package/dist/components/Drawer/Drawer.css +1 -0
  74. package/dist/components/Dropdown/Dropdown.js +47 -29
  75. package/dist/components/FileInput/FileInput.css +24 -4
  76. package/dist/components/FileInput/FileInput.d.ts +22 -2
  77. package/dist/components/FileInput/FileInput.js +23 -2
  78. package/dist/components/Grid/Grid.js +5 -5
  79. package/dist/components/IconPicker/IconPicker.css +107 -0
  80. package/dist/components/IconPicker/IconPicker.d.ts +74 -0
  81. package/dist/components/IconPicker/IconPicker.js +194 -0
  82. package/dist/components/Input/Input.css +41 -3
  83. package/dist/components/Input/Input.d.ts +14 -1
  84. package/dist/components/Input/Input.js +72 -6
  85. package/dist/components/Kanban/Kanban.css +5 -0
  86. package/dist/components/Kanban/Kanban.d.ts +41 -0
  87. package/dist/components/Kanban/Kanban.js +59 -27
  88. package/dist/components/Kanban/KanbanCard.d.ts +2 -0
  89. package/dist/components/Kanban/KanbanCard.js +1 -1
  90. package/dist/components/Kanban/KanbanColumn.d.ts +2 -0
  91. package/dist/components/Kanban/KanbanColumn.js +3 -0
  92. package/dist/components/Kbd/Kbd.css +66 -0
  93. package/dist/components/Kbd/Kbd.d.ts +32 -0
  94. package/dist/components/Kbd/Kbd.js +40 -0
  95. package/dist/components/Link/Link.css +1 -1
  96. package/dist/components/List/List.css +136 -0
  97. package/dist/components/List/List.d.ts +82 -0
  98. package/dist/components/List/List.js +53 -0
  99. package/dist/components/List/ListItem.d.ts +85 -0
  100. package/dist/components/List/ListItem.js +81 -0
  101. package/dist/components/Modal/Modal.css +93 -8
  102. package/dist/components/Modal/Modal.d.ts +45 -7
  103. package/dist/components/Modal/Modal.js +106 -6
  104. package/dist/components/MultiSelect/MultiSelect.css +9 -1
  105. package/dist/components/MultiSelect/MultiSelect.js +45 -8
  106. package/dist/components/OrgChart/OrgChart.css +149 -0
  107. package/dist/components/OrgChart/OrgChart.d.ts +83 -0
  108. package/dist/components/OrgChart/OrgChart.js +297 -0
  109. package/dist/components/OtpInput/OtpInput.css +93 -0
  110. package/dist/components/OtpInput/OtpInput.d.ts +60 -0
  111. package/dist/components/OtpInput/OtpInput.js +215 -0
  112. package/dist/components/Pagination/Pagination.d.ts +6 -0
  113. package/dist/components/Pagination/Pagination.js +9 -1
  114. package/dist/components/PhoneInput/PhoneInput.css +9 -1
  115. package/dist/components/PhoneInput/PhoneInput.d.ts +10 -0
  116. package/dist/components/PhoneInput/PhoneInput.js +20 -3
  117. package/dist/components/Popover/Popover.d.ts +7 -0
  118. package/dist/components/Popover/Popover.js +11 -1
  119. package/dist/components/RichTextEditor/RichTextEditor.css +203 -0
  120. package/dist/components/RichTextEditor/RichTextEditor.d.ts +83 -0
  121. package/dist/components/RichTextEditor/RichTextEditor.js +494 -0
  122. package/dist/components/SegmentedControl/SegmentedControl.d.ts +2 -0
  123. package/dist/components/SegmentedControl/SegmentedControl.js +21 -8
  124. package/dist/components/Select/Select.css +71 -1
  125. package/dist/components/Select/Select.d.ts +12 -0
  126. package/dist/components/Select/Select.js +93 -10
  127. package/dist/components/SidePanel/SidePanel.css +4 -4
  128. package/dist/components/SidePanelItem/SidePanelItem.css +7 -5
  129. package/dist/components/SidePanelSearch/SidePanelSearch.css +2 -2
  130. package/dist/components/SidePanelSection/SidePanelSection.css +7 -5
  131. package/dist/components/Stack/Stack.css +49 -0
  132. package/dist/components/Stack/Stack.d.ts +65 -7
  133. package/dist/components/Stack/Stack.js +30 -2
  134. package/dist/components/StatCard/StatCard.css +73 -0
  135. package/dist/components/StatCard/StatCard.d.ts +17 -0
  136. package/dist/components/StatCard/StatCard.js +4 -1
  137. package/dist/components/Stepper/Stepper.css +4 -1
  138. package/dist/components/Stepper/Stepper.d.ts +8 -0
  139. package/dist/components/Stepper/Stepper.js +4 -4
  140. package/dist/components/Switch/Switch.css +1 -0
  141. package/dist/components/Tabs/Tab.d.ts +15 -0
  142. package/dist/components/Tabs/Tab.js +30 -1
  143. package/dist/components/Tabs/Tabs.css +132 -0
  144. package/dist/components/Tabs/Tabs.d.ts +7 -0
  145. package/dist/components/Tabs/Tabs.js +13 -2
  146. package/dist/components/Tag/Tag.css +85 -2
  147. package/dist/components/Tag/Tag.d.ts +13 -6
  148. package/dist/components/Tag/Tag.js +1 -0
  149. package/dist/components/Text/Text.d.ts +9 -1
  150. package/dist/components/Text/Text.js +2 -2
  151. package/dist/components/Textarea/Textarea.css +11 -3
  152. package/dist/components/TimePicker/TimePicker.css +8 -0
  153. package/dist/components/TimePicker/TimePicker.d.ts +6 -0
  154. package/dist/components/TimePicker/TimePicker.js +1 -1
  155. package/dist/components/Tooltip/Tooltip.css +40 -0
  156. package/dist/components/Tooltip/Tooltip.d.ts +11 -0
  157. package/dist/components/Tooltip/Tooltip.js +114 -11
  158. package/dist/index.d.ts +25 -0
  159. package/dist/index.js +14 -0
  160. package/dist/teste/AILabel.test.d.ts +1 -0
  161. package/dist/teste/AILabel.test.js +33 -0
  162. package/dist/teste/AccordionConteudoLivre.test.d.ts +1 -0
  163. package/dist/teste/AccordionConteudoLivre.test.js +29 -0
  164. package/dist/teste/Alert.test.d.ts +1 -0
  165. package/dist/teste/Alert.test.js +27 -0
  166. package/dist/teste/AtributosRepassados.test.d.ts +1 -0
  167. package/dist/teste/AtributosRepassados.test.js +52 -0
  168. package/dist/teste/AttachmentCardIA.test.d.ts +1 -0
  169. package/dist/teste/AttachmentCardIA.test.js +89 -0
  170. package/dist/teste/AvatarGroupOverlap.test.d.ts +1 -0
  171. package/dist/teste/AvatarGroupOverlap.test.js +56 -0
  172. package/dist/teste/BadgeTag.test.d.ts +1 -0
  173. package/dist/teste/BadgeTag.test.js +42 -0
  174. package/dist/teste/BottomSheet.test.d.ts +1 -0
  175. package/dist/teste/BottomSheet.test.js +23 -0
  176. package/dist/teste/BoxItemFlex.test.d.ts +1 -0
  177. package/dist/teste/BoxItemFlex.test.js +54 -0
  178. package/dist/teste/BoxLayout.test.d.ts +1 -0
  179. package/dist/teste/BoxLayout.test.js +35 -0
  180. package/dist/teste/Button.test.d.ts +1 -0
  181. package/dist/teste/Button.test.js +27 -0
  182. package/dist/teste/Calendar.test.d.ts +1 -0
  183. package/dist/teste/Calendar.test.js +221 -0
  184. package/dist/teste/ChipsXs.test.d.ts +1 -0
  185. package/dist/teste/ChipsXs.test.js +31 -0
  186. package/dist/teste/Coachmark.test.d.ts +1 -0
  187. package/dist/teste/Coachmark.test.js +149 -0
  188. package/dist/teste/ColorPicker.test.d.ts +1 -0
  189. package/dist/teste/ColorPicker.test.js +132 -0
  190. package/dist/teste/ConfirmAIAction.test.d.ts +1 -0
  191. package/dist/teste/ConfirmAIAction.test.js +33 -0
  192. package/dist/teste/DataTableCelulaLivre.test.d.ts +1 -0
  193. package/dist/teste/DataTableCelulaLivre.test.js +76 -0
  194. package/dist/teste/DataTableDocumento.test.d.ts +1 -0
  195. package/dist/teste/DataTableDocumento.test.js +92 -0
  196. package/dist/teste/DatePicker.test.js +23 -0
  197. package/dist/teste/Dropdown.test.js +111 -0
  198. package/dist/teste/FileInputTrigger.test.d.ts +1 -0
  199. package/dist/teste/FileInputTrigger.test.js +53 -0
  200. package/dist/teste/IconPicker.test.d.ts +1 -0
  201. package/dist/teste/IconPicker.test.js +130 -0
  202. package/dist/teste/InputMascaraEAfins.test.d.ts +1 -0
  203. package/dist/teste/InputMascaraEAfins.test.js +99 -0
  204. package/dist/teste/KbdCodeBlock.test.d.ts +1 -0
  205. package/dist/teste/KbdCodeBlock.test.js +95 -0
  206. package/dist/teste/List.test.d.ts +1 -0
  207. package/dist/teste/List.test.js +153 -0
  208. package/dist/teste/Modal.test.d.ts +1 -0
  209. package/dist/teste/Modal.test.js +26 -0
  210. package/dist/teste/ModalVariantes.test.d.ts +1 -0
  211. package/dist/teste/ModalVariantes.test.js +151 -0
  212. package/dist/teste/MultiSelectErro.test.d.ts +1 -0
  213. package/dist/teste/MultiSelectErro.test.js +62 -0
  214. package/dist/teste/NomeAcessivelSsr.test.d.ts +1 -0
  215. package/dist/teste/NomeAcessivelSsr.test.js +88 -0
  216. package/dist/teste/OrgChart.test.d.ts +1 -0
  217. package/dist/teste/OrgChart.test.js +162 -0
  218. package/dist/teste/OtpInput.test.d.ts +1 -0
  219. package/dist/teste/OtpInput.test.js +143 -0
  220. package/dist/teste/PopoverMaxHeight.test.d.ts +1 -0
  221. package/dist/teste/PopoverMaxHeight.test.js +38 -0
  222. package/dist/teste/RichTextEditor.test.d.ts +1 -0
  223. package/dist/teste/RichTextEditor.test.js +287 -0
  224. package/dist/teste/RotulosTraduziveis.test.d.ts +1 -0
  225. package/dist/teste/RotulosTraduziveis.test.js +405 -0
  226. package/dist/teste/SegmentedControl.test.js +33 -0
  227. package/dist/teste/Select.test.d.ts +1 -0
  228. package/dist/teste/Select.test.js +62 -0
  229. package/dist/teste/SelectPlacementFiltro.test.d.ts +1 -0
  230. package/dist/teste/SelectPlacementFiltro.test.js +88 -0
  231. package/dist/teste/Stack.test.d.ts +1 -0
  232. package/dist/teste/Stack.test.js +57 -0
  233. package/dist/teste/StatCardRotuloTopo.test.d.ts +1 -0
  234. package/dist/teste/StatCardRotuloTopo.test.js +34 -0
  235. package/dist/teste/TabsContadorFechavel.test.d.ts +1 -0
  236. package/dist/teste/TabsContadorFechavel.test.js +79 -0
  237. package/dist/teste/Tooltip.test.d.ts +1 -0
  238. package/dist/teste/Tooltip.test.js +109 -0
  239. package/dist/teste/TooltipDark.test.d.ts +1 -0
  240. package/dist/teste/TooltipDark.test.js +31 -0
  241. package/dist/utils/calendario.d.ts +28 -0
  242. package/dist/utils/calendario.js +73 -0
  243. package/dist/utils/chart.d.ts +4 -0
  244. package/dist/utils/chart.js +3 -2
  245. package/dist/utils/html-seguro.d.ts +27 -0
  246. package/dist/utils/html-seguro.js +97 -0
  247. package/dist/utils/id.d.ts +2 -0
  248. package/dist/utils/id.js +23 -0
  249. package/dist/utils/paleta-de-cores.d.ts +26 -0
  250. package/dist/utils/paleta-de-cores.js +10 -0
  251. package/dist/utils/texto.d.ts +5 -0
  252. package/dist/utils/texto.js +5 -0
  253. package/package.json +3 -3
  254. package/src/index.ts +26 -0
  255. package/src/teste/AILabel.test.tsx +41 -0
  256. package/src/teste/AccordionConteudoLivre.test.tsx +39 -0
  257. package/src/teste/Alert.test.tsx +32 -0
  258. package/src/teste/AtributosRepassados.test.tsx +73 -0
  259. package/src/teste/AttachmentCardIA.test.tsx +126 -0
  260. package/src/teste/AvatarGroupOverlap.test.tsx +74 -0
  261. package/src/teste/BadgeTag.test.tsx +64 -0
  262. package/src/teste/BottomSheet.test.tsx +25 -0
  263. package/src/teste/BoxItemFlex.test.tsx +81 -0
  264. package/src/teste/BoxLayout.test.tsx +50 -0
  265. package/src/teste/Button.test.tsx +39 -0
  266. package/src/teste/Calendar.test.tsx +282 -0
  267. package/src/teste/ChipsXs.test.tsx +41 -0
  268. package/src/teste/Coachmark.test.tsx +198 -0
  269. package/src/teste/ColorPicker.test.tsx +153 -0
  270. package/src/teste/ConfirmAIAction.test.tsx +41 -0
  271. package/src/teste/DataTableCelulaLivre.test.tsx +103 -0
  272. package/src/teste/DataTableDocumento.test.tsx +102 -0
  273. package/src/teste/DatePicker.test.tsx +38 -0
  274. package/src/teste/Dropdown.test.tsx +146 -0
  275. package/src/teste/FileInputTrigger.test.tsx +89 -0
  276. package/src/teste/IconPicker.test.tsx +145 -0
  277. package/src/teste/InputMascaraEAfins.test.tsx +124 -0
  278. package/src/teste/KbdCodeBlock.test.tsx +106 -0
  279. package/src/teste/List.test.tsx +269 -0
  280. package/src/teste/Modal.test.tsx +28 -0
  281. package/src/teste/ModalVariantes.test.tsx +173 -0
  282. package/src/teste/MultiSelectErro.test.tsx +97 -0
  283. package/src/teste/NomeAcessivelSsr.test.tsx +110 -0
  284. package/src/teste/OrgChart.test.tsx +183 -0
  285. package/src/teste/OtpInput.test.tsx +163 -0
  286. package/src/teste/PopoverMaxHeight.test.tsx +47 -0
  287. package/src/teste/RichTextEditor.test.tsx +329 -0
  288. package/src/teste/RotulosTraduziveis.test.tsx +545 -0
  289. package/src/teste/SegmentedControl.test.tsx +57 -0
  290. package/src/teste/Select.test.tsx +97 -0
  291. package/src/teste/SelectPlacementFiltro.test.tsx +110 -0
  292. package/src/teste/Stack.test.tsx +80 -0
  293. package/src/teste/StatCardRotuloTopo.test.tsx +44 -0
  294. package/src/teste/TabsContadorFechavel.test.tsx +144 -0
  295. package/src/teste/Tooltip.test.tsx +219 -0
  296. package/src/teste/TooltipDark.test.tsx +51 -0
  297. package/src/utils/calendario.ts +78 -0
  298. package/src/utils/chart.ts +7 -2
  299. package/src/utils/html-seguro.ts +94 -0
  300. package/src/utils/id.ts +24 -0
  301. package/src/utils/paleta-de-cores.ts +34 -0
  302. package/src/utils/texto.ts +5 -0
@@ -0,0 +1,93 @@
1
+ /* ─────────────────────────────────────────────
2
+ OTP INPUT
3
+ Código de verificação em caixas de um caractere.
4
+
5
+ A caixa segue a família de campos: borda de repouso, hover, foco (borda +
6
+ anel) e erro vêm dos tokens `--umds-semantic-field-*`. O que muda é a
7
+ geometria: caixa alta, número grande e centralizado.
8
+
9
+ Cores: semânticos · Medidas: primitivos
10
+ ───────────────────────────────────────────── */
11
+
12
+ .umds-otp {
13
+ display: inline-flex;
14
+ flex-direction: column;
15
+ gap: var(--umds-primitive-spacing-quarck); /* 4px */
16
+ font-family: var(--umds-semantic-font-family-base);
17
+ }
18
+
19
+ .umds-otp__label {
20
+ font-size: var(--umds-semantic-field-label-size);
21
+ font-weight: var(--umds-semantic-field-label-weight);
22
+ color: var(--umds-semantic-field-label-color);
23
+ }
24
+
25
+ .umds-otp__digits {
26
+ display: flex;
27
+ gap: var(--umds-primitive-spacing-nano); /* 8px */
28
+ }
29
+
30
+ .umds-otp__digit {
31
+ box-sizing: border-box;
32
+ margin: 0;
33
+ padding: 0;
34
+ text-align: center;
35
+ font-family: inherit;
36
+ font-weight: var(--umds-primitive-font-weight-bold);
37
+ color: var(--umds-semantic-field-text-color);
38
+ background: var(--umds-semantic-color-background-white);
39
+ border: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-field-border-default);
40
+ border-radius: var(--umds-primitive-border-radius-sm);
41
+ caret-color: var(--umds-semantic-color-primary-pure);
42
+ transition:
43
+ border-color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard),
44
+ box-shadow var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard);
45
+ }
46
+
47
+ .umds-otp--md .umds-otp__digit {
48
+ width: var(--umds-primitive-spacing-md); /* 48px */
49
+ height: var(--umds-primitive-spacing-lg); /* 56px */
50
+ font-size: var(--umds-primitive-font-size-md); /* 24px */
51
+ }
52
+
53
+ .umds-otp--sm .umds-otp__digit {
54
+ width: var(--umds-primitive-spacing-sm); /* 40px */
55
+ height: var(--umds-primitive-spacing-md); /* 48px */
56
+ font-size: var(--umds-primitive-font-size-sm); /* 20px */
57
+ }
58
+
59
+ .umds-otp__digit:hover:not(:disabled) {
60
+ border-color: var(--umds-semantic-field-border-hover);
61
+ }
62
+
63
+ .umds-otp__digit:focus,
64
+ .umds-otp__digit:focus-visible {
65
+ outline: none;
66
+ border-color: var(--umds-semantic-field-border-focus);
67
+ box-shadow: var(--umds-semantic-field-ring-focus);
68
+ }
69
+
70
+ .umds-otp--invalid .umds-otp__digit,
71
+ .umds-otp--invalid .umds-otp__digit:hover:not(:disabled) {
72
+ border-color: var(--umds-semantic-field-border-error);
73
+ }
74
+
75
+ .umds-otp--invalid .umds-otp__digit:focus,
76
+ .umds-otp--invalid .umds-otp__digit:focus-visible {
77
+ box-shadow: var(--umds-semantic-field-ring-error);
78
+ }
79
+
80
+ .umds-otp__digit:disabled {
81
+ cursor: not-allowed;
82
+ background: var(--umds-semantic-field-disabled-background);
83
+ opacity: var(--umds-semantic-field-disabled-opacity);
84
+ }
85
+
86
+ /* Alto contraste: o anel de foco de sombra some, o contorno do sistema fica. */
87
+ @media (forced-colors: active) {
88
+ .umds-otp__digit:focus,
89
+ .umds-otp__digit:focus-visible {
90
+ outline: var(--umds-primitive-border-width-thin) solid Highlight;
91
+ outline-offset: var(--umds-primitive-border-width-thin);
92
+ }
93
+ }
@@ -0,0 +1,60 @@
1
+ import './OtpInput.css';
2
+ /**
3
+ * OtpInput — código de verificação em caixas de um caractere (SMS, e-mail,
4
+ * app autenticador).
5
+ *
6
+ * `length` caixas (6 por padrão). O foco anda sozinho: digitar avança, Backspace
7
+ * apaga e volta, as setas, Home e End movem. Colar o código inteiro em qualquer
8
+ * caixa distribui os caracteres; o preenchimento automático do navegador (SMS)
9
+ * também, porque a primeira caixa leva `autocomplete="one-time-code"`.
10
+ * Clicar numa caixa à frente da primeira vazia manda o foco de volta a ela: o
11
+ * código nunca fica com buraco no meio.
12
+ *
13
+ * O valor é uma string. `onChange` recebe o código a cada mudança e `onComplete`
14
+ * recebe quando as `length` caixas ficam cheias (uma vez por código completo).
15
+ * Aceita só dígitos (`type="numeric"`, padrão, com teclado numérico no celular)
16
+ * ou letras e dígitos (`type="alphanumeric"`, que sai em maiúsculas).
17
+ *
18
+ * Acessibilidade: o conjunto é um `role="group"` nomeado por `label` ou
19
+ * `ariaLabel`, e cada caixa tem nome próprio ("Dígito 3 de 6"). Troque
20
+ * `digitLabel` para traduzir; `{n}` e `{total}` viram a posição e o tamanho.
21
+ * Erro por `invalid` e `errorMessage` (ligado às caixas por `aria-describedby`).
22
+ * @property {number} length - Quantidade de caixas (padrão 6)
23
+ * @property {string} value - Código (controlado)
24
+ * @property {string} defaultValue - Código inicial (não controlado)
25
+ * @property {string} type - 'numeric' (padrão) | 'alphanumeric'
26
+ * @property {string} label - Rótulo visível do conjunto
27
+ * @property {string} ariaLabel - Nome acessível quando não há `label` visível
28
+ * @property {string} digitLabel - Nome de cada caixa; `{n}` e `{total}` são trocados (padrão: "Dígito {n} de {total}")
29
+ * @property {boolean} invalid - Estado de erro
30
+ * @property {string} errorMessage - Mensagem de erro (liga o estado de erro)
31
+ * @property {boolean} disabled - Desabilita todas as caixas
32
+ * @property {boolean} autoFocus - Foca a primeira caixa vazia ao montar
33
+ * @property {string} size - 'sm' | 'md' (padrão)
34
+ * @property {string} id - Base dos ids internos; passe em SSR para os ids já saírem no HTML do servidor
35
+ * @property {string} className - Classes CSS adicionais
36
+ * @property {function} onChange - Chamado com o código a cada mudança
37
+ * @property {function} onComplete - Chamado com o código quando todas as caixas ficam cheias
38
+ * @quandoUsar Confirmar um código curto que a pessoa recebeu por outro canal: autenticação em duas etapas, confirmação de e-mail ou de telefone.
39
+ * @quandoNaoUsar Para texto livre ou código de tamanho variável, use `Input`. Para senha, use `Input type="password"`. Para número com máscara (CPF, CEP), use `Input mask`.
40
+ */
41
+ export interface OtpInputProps {
42
+ length?: number;
43
+ value?: string;
44
+ defaultValue?: string;
45
+ type?: "numeric" | "alphanumeric";
46
+ label?: string;
47
+ ariaLabel?: string;
48
+ digitLabel?: string;
49
+ invalid?: boolean;
50
+ errorMessage?: string;
51
+ disabled?: boolean;
52
+ autoFocus?: boolean;
53
+ size?: "sm" | "md";
54
+ id?: string;
55
+ className?: string;
56
+ onChange?: (value: string) => void;
57
+ onComplete?: (value: string) => void;
58
+ }
59
+ declare function OtpInput(props: OtpInputProps): import("react/jsx-runtime").JSX.Element;
60
+ export default OtpInput;
@@ -0,0 +1,215 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import './OtpInput.css';
4
+ import { useState, useRef, useEffect } from "react";
5
+ import Text from "../Text/Text";
6
+ import { gerarId } from "../../utils/id";
7
+ function OtpInput(props) {
8
+ const groupRef = useRef(null);
9
+ const ultimoEventoRef = useRef(null);
10
+ const focoPendenteRef = useRef(-1);
11
+ const [internalValue, setInternalValue] = useState(() => props.defaultValue || "");
12
+ const [uid, setUid] = useState(() => "");
13
+ function baseId() {
14
+ return props.id || uid;
15
+ }
16
+ function codeLength() {
17
+ const n = props.length || 6;
18
+ return n < 1 ? 1 : n;
19
+ }
20
+ function positions() {
21
+ return Array.from({
22
+ length: codeLength(),
23
+ }, (_, i) => i);
24
+ }
25
+ function isAlpha() {
26
+ return props.type === "alphanumeric";
27
+ }
28
+ function limpar(texto) {
29
+ const bruto = texto || "";
30
+ const aceito = isAlpha()
31
+ ? bruto.replace(/[^0-9a-zA-Z]/g, "").toUpperCase()
32
+ : bruto.replace(/[^0-9]/g, "");
33
+ return aceito;
34
+ }
35
+ function currentValue() {
36
+ const bruto = props.value !== undefined ? props.value : internalValue;
37
+ return limpar(bruto).slice(0, codeLength());
38
+ }
39
+ function charAt(index) {
40
+ return currentValue().charAt(index);
41
+ }
42
+ function isInvalid() {
43
+ return !!props.invalid || !!props.errorMessage;
44
+ }
45
+ function labelId() {
46
+ return baseId() && props.label ? baseId() + "-label" : undefined;
47
+ }
48
+ function errorId() {
49
+ return baseId() && props.errorMessage ? baseId() + "-error" : undefined;
50
+ }
51
+ function groupAriaLabel() {
52
+ if (props.ariaLabel)
53
+ return props.ariaLabel;
54
+ return props.label && !labelId() ? props.label : undefined;
55
+ }
56
+ function ariaInvalidText() {
57
+ return isInvalid() ? "true" : undefined;
58
+ }
59
+ function classes() {
60
+ return [
61
+ "umds-otp",
62
+ `umds-otp--${props.size || "md"}`,
63
+ isInvalid() ? "umds-otp--invalid" : "",
64
+ props.disabled ? "umds-otp--disabled" : "",
65
+ props.className,
66
+ ]
67
+ .filter(Boolean)
68
+ .join(" ");
69
+ }
70
+ function digitName(index) {
71
+ const modelo = props.digitLabel || "Dígito {n} de {total}";
72
+ return modelo
73
+ .replace("{n}", String(index + 1))
74
+ .replace("{total}", String(codeLength()));
75
+ }
76
+ function inputMode() {
77
+ return isAlpha() ? "text" : "numeric";
78
+ }
79
+ function autoComplete(index) {
80
+ return index === 0 ? "one-time-code" : "off";
81
+ }
82
+ function digitId(index) {
83
+ return baseId() ? baseId() + "-" + index : undefined;
84
+ }
85
+ function definir(proximo) {
86
+ const novo = limpar(proximo).slice(0, codeLength());
87
+ const antigo = currentValue();
88
+ if (novo === antigo)
89
+ return false;
90
+ setInternalValue(novo);
91
+ if (props.onChange)
92
+ props.onChange(novo);
93
+ if (novo.length === codeLength() && props.onComplete)
94
+ props.onComplete(novo);
95
+ return true;
96
+ }
97
+ function focarDepois(index, mudou) {
98
+ if (mudou)
99
+ focoPendenteRef.current = index;
100
+ else
101
+ focarEm(index);
102
+ }
103
+ function focarEm(index) {
104
+ if (!groupRef.current)
105
+ return;
106
+ const caixas = groupRef.current.querySelectorAll("input");
107
+ const alvo = caixas[Math.max(0, Math.min(index, codeLength() - 1))];
108
+ if (alvo)
109
+ alvo.focus();
110
+ }
111
+ function limiteDoFoco() {
112
+ return Math.min(currentValue().length, codeLength() - 1);
113
+ }
114
+ function handleInput(event, index) {
115
+ const nativo = event.nativeEvent || event;
116
+ if (nativo === ultimoEventoRef.current)
117
+ return;
118
+ ultimoEventoRef.current = nativo;
119
+ const alvo = event.target;
120
+ const bruto = alvo.value || "";
121
+ const atual = charAt(index);
122
+ const valor = currentValue();
123
+ // Apagou: o código fecha o buraco (os de trás andam um para a frente).
124
+ if (bruto === "") {
125
+ const sem = atual
126
+ ? valor.slice(0, index) + valor.slice(index + 1)
127
+ : valor;
128
+ if (atual)
129
+ definir(sem);
130
+ alvo.value = sem.charAt(index);
131
+ return;
132
+ }
133
+ let texto = bruto;
134
+ // Digitou numa caixa que já tinha caractere: vale o que é novo.
135
+ if (atual && bruto.length === 2) {
136
+ texto = bruto.charAt(0) === atual ? bruto.charAt(1) : bruto.charAt(0);
137
+ }
138
+ const limpo = limpar(texto);
139
+ if (!limpo) {
140
+ alvo.value = atual;
141
+ return;
142
+ }
143
+ // O que sobra de um código colado ou autopreenchido segue para as próximas caixas.
144
+ const proximo = valor.slice(0, index) + limpo + valor.slice(index + limpo.length);
145
+ const mudou = definir(proximo);
146
+ // A caixa mostra já o que o código passa a ter (o React só relê a prop no próximo render).
147
+ alvo.value = limpar(proximo).slice(0, codeLength()).charAt(index);
148
+ focarDepois(Math.min(index + limpo.length, codeLength() - 1), mudou);
149
+ }
150
+ function handlePaste(event, index) {
151
+ if (!event || !event.clipboardData)
152
+ return;
153
+ const texto = limpar(event.clipboardData.getData("text"));
154
+ event.preventDefault();
155
+ if (!texto)
156
+ return;
157
+ // Código inteiro: substitui tudo. Pedaço: entra a partir da caixa em que se colou.
158
+ const inicio = texto.length >= codeLength() ? 0 : index;
159
+ const valor = currentValue();
160
+ const mudou = definir(valor.slice(0, inicio) + texto + valor.slice(inicio + texto.length));
161
+ focarDepois(Math.min(inicio + texto.length, codeLength() - 1), mudou);
162
+ }
163
+ function handleKeyDown(event, index) {
164
+ if (!event || event.altKey || event.ctrlKey || event.metaKey)
165
+ return;
166
+ const tecla = event.key;
167
+ if (tecla === "Backspace" && !charAt(index) && index > 0) {
168
+ event.preventDefault();
169
+ const valor = currentValue();
170
+ const mudou = definir(valor.slice(0, index - 1) + valor.slice(index));
171
+ focarDepois(index - 1, mudou);
172
+ }
173
+ else if (tecla === "ArrowLeft") {
174
+ event.preventDefault();
175
+ focarEm(index - 1);
176
+ }
177
+ else if (tecla === "ArrowRight") {
178
+ event.preventDefault();
179
+ focarEm(Math.min(index + 1, limiteDoFoco()));
180
+ }
181
+ else if (tecla === "Home") {
182
+ event.preventDefault();
183
+ focarEm(0);
184
+ }
185
+ else if (tecla === "End") {
186
+ event.preventDefault();
187
+ focarEm(limiteDoFoco());
188
+ }
189
+ }
190
+ function handleFocus(event, index) {
191
+ // Sem buraco: foco à frente da primeira vazia volta para ela.
192
+ const limite = limiteDoFoco();
193
+ if (index > limite) {
194
+ focarEm(limite);
195
+ return;
196
+ }
197
+ if (event && event.target && event.target.select)
198
+ event.target.select();
199
+ }
200
+ useEffect(() => {
201
+ if (!props.id)
202
+ setUid(gerarId("umds-otp"));
203
+ if (props.autoFocus)
204
+ focarEm(limiteDoFoco());
205
+ }, []);
206
+ useEffect(() => {
207
+ if (focoPendenteRef.current >= 0) {
208
+ const alvo = focoPendenteRef.current;
209
+ focoPendenteRef.current = -1;
210
+ focarEm(alvo);
211
+ }
212
+ });
213
+ return (_jsxs("div", { className: classes(), children: [props.label ? (_jsx("span", { className: "umds-otp__label", id: labelId(), children: props.label })) : null, _jsx("div", { role: "group", className: "umds-otp__digits", ref: groupRef, "aria-label": groupAriaLabel(), "aria-labelledby": labelId(), children: positions()?.map((caixa) => (_jsx("input", { type: "text", autoCapitalize: "off", className: "umds-otp__digit", id: digitId(caixa), inputMode: inputMode(), autoComplete: autoComplete(caixa), spellCheck: false, value: charAt(caixa), disabled: props.disabled, "aria-label": digitName(caixa), "aria-invalid": ariaInvalidText(), "aria-describedby": errorId(), onInput: (event) => handleInput(event, caixa), onChange: (event) => handleInput(event, caixa), onKeyDown: (event) => handleKeyDown(event, caixa), onPaste: (event) => handlePaste(event, caixa), onFocus: (event) => handleFocus(event, caixa) }, caixa))) }), props.errorMessage ? (_jsx(Text, { as: "span", variant: "caption", color: "negative", id: errorId(), children: props.errorMessage })) : null] }));
214
+ }
215
+ export default OtpInput;
@@ -31,6 +31,12 @@ export interface PaginationProps {
31
31
  previousPageLabel?: string;
32
32
  /** Rótulo acessível do botão de próxima página. @default 'Próxima página' */
33
33
  nextPageLabel?: string;
34
+ /** Palavra entre o campo de página e o total (`default` e `alternative`). Troque para traduzir. @default 'de' */
35
+ ofLabel?: string;
36
+ /** Texto do intervalo na variante `resumed`. Recebe início, fim e total de itens. Troque para traduzir. @default (start, end, total) => start + '-' + end + ' de ' + total */
37
+ itemRangeLabel?: (start: number, end: number, total: number) => string;
38
+ /** Nome acessível de cada botão numerado (`full-width` e `bordered`). Recebe o número da página. Troque para traduzir. @default (page) => 'Página ' + page */
39
+ pageLabel?: (page: number) => string;
34
40
  page?: number;
35
41
  totalPages?: number;
36
42
  variant?: "default" | "alternative" | "resumed" | "full-width" | "bordered";
@@ -161,8 +161,16 @@ function Pagination(props) {
161
161
  const current = props.page || 1;
162
162
  const start = (current - 1) * size + 1;
163
163
  const end = Math.min(current * size, totalItems);
164
+ if (props.itemRangeLabel)
165
+ return props.itemRangeLabel(start, end, totalItems);
164
166
  return start + "-" + end + " de " + totalItems;
165
167
  }
168
+ function ofText() {
169
+ return props.ofLabel || "de";
170
+ }
171
+ function pageAriaLabel(page) {
172
+ return props.pageLabel ? props.pageLabel(page) : "Página " + page;
173
+ }
166
174
  function prevText() {
167
175
  return props.prevLabel || "Anterior";
168
176
  }
@@ -240,6 +248,6 @@ function Pagination(props) {
240
248
  useEffect(() => {
241
249
  syncInputToPage();
242
250
  });
243
- return (_jsxs("nav", { "aria-label": props.ariaLabel || "Paginação", className: classes(), children: [resolvedVariant() === "default" ? (_jsxs(_Fragment, { children: [props.showPrevNext !== false ? (_jsxs("button", { type: "button", className: "umds-pagination__link-btn", onClick: (event) => goToPage((props.page || 1) - 1), disabled: isPrevDisabled(), children: [_jsx(Icon, { variant: "inherit", customSize: "14px", icon: faChevronLeft }), _jsx("span", { children: prevText() })] })) : null, _jsx("input", { type: "text", inputMode: "numeric", className: "umds-pagination__input", value: inputValue, disabled: props.disabled, "aria-label": props.currentPageLabel || "Página atual", onInput: (event) => handleInputChange(event), onKeyDown: (event) => handleInputKeydown(event), onBlur: (event) => commitInput() }), _jsx("span", { className: "umds-pagination__of", children: "de" }), _jsx("span", { className: "umds-pagination__total", children: props.totalPages || 1 }), props.showPrevNext !== false ? (_jsxs("button", { type: "button", className: "umds-pagination__link-btn", onClick: (event) => goToPage((props.page || 1) + 1), disabled: isNextDisabled(), children: [_jsx("span", { children: nextText() }), _jsx(Icon, { variant: "inherit", customSize: "14px", icon: faChevronRight })] })) : null] })) : null, resolvedVariant() === "alternative" ? (_jsxs(_Fragment, { children: [props.showPrevNext !== false ? (_jsx("button", { type: "button", className: "umds-pagination__ghost-btn", onClick: (event) => goToPage((props.page || 1) - 1), disabled: isPrevDisabled(), "aria-label": props.previousPageLabel || "Página anterior", children: _jsx(Icon, { variant: "inherit", customSize: "16px", icon: faChevronLeft }) })) : null, _jsx("input", { type: "text", inputMode: "numeric", className: "umds-pagination__input", value: inputValue, disabled: props.disabled, "aria-label": props.currentPageLabel || "Página atual", onInput: (event) => handleInputChange(event), onKeyDown: (event) => handleInputKeydown(event), onBlur: (event) => commitInput() }), _jsx("span", { className: "umds-pagination__of", children: "de" }), _jsx("span", { className: "umds-pagination__total", children: props.totalPages || 1 }), props.showPrevNext !== false ? (_jsx("button", { type: "button", className: "umds-pagination__ghost-btn", onClick: (event) => goToPage((props.page || 1) + 1), disabled: isNextDisabled(), "aria-label": props.nextPageLabel || "Próxima página", children: _jsx(Icon, { variant: "inherit", customSize: "16px", icon: faChevronRight }) })) : null] })) : null, resolvedVariant() === "resumed" ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "umds-pagination__range", children: rangeLabel() }), props.showPrevNext !== false ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "umds-pagination__ghost-btn", onClick: (event) => goToPage((props.page || 1) - 1), disabled: isPrevDisabled(), "aria-label": props.previousPageLabel || "Página anterior", children: _jsx(Icon, { variant: "inherit", customSize: "16px", icon: faChevronLeft }) }), _jsx("button", { type: "button", className: "umds-pagination__ghost-btn", onClick: (event) => goToPage((props.page || 1) + 1), disabled: isNextDisabled(), "aria-label": props.nextPageLabel || "Próxima página", children: _jsx(Icon, { variant: "inherit", customSize: "16px", icon: faChevronRight }) })] })) : null] })) : null, resolvedVariant() === "full-width" ? (_jsxs(_Fragment, { children: [props.showPrevNext !== false ? (_jsxs("button", { type: "button", className: "umds-pagination__nav-btn", onClick: (event) => goToPage((props.page || 1) - 1), disabled: isPrevDisabled(), children: [_jsx(Icon, { variant: "inherit", customSize: "14px", icon: faChevronLeft }), _jsx("span", { children: prevText() })] })) : null, pages()?.map((item) => (_jsxs("span", { className: "umds-pagination__item", children: [item.type === "page" ? (_jsx("button", { type: "button", onClick: (event) => goToPage(item.value), disabled: props.disabled, "aria-label": `Página ${item.value}`, "aria-current": isActive(item.value) ? "page" : undefined, className: getBtnClass(item.value), children: item.label })) : null, item.type === "dots" ? (_jsx("span", { "aria-hidden": "true", className: "umds-pagination__dots", children: item.label })) : null] }, item.key))), props.showPrevNext !== false ? (_jsxs("button", { type: "button", className: "umds-pagination__nav-btn", onClick: (event) => goToPage((props.page || 1) + 1), disabled: isNextDisabled(), children: [_jsx("span", { children: nextText() }), _jsx(Icon, { variant: "inherit", customSize: "14px", icon: faChevronRight })] })) : null] })) : null, resolvedVariant() === "bordered" ? (_jsxs("span", { className: "umds-pagination__box", children: [props.showPrevNext !== false ? (_jsxs("button", { type: "button", className: "umds-pagination__cell-btn umds-pagination__cell-btn--prev", onClick: (event) => goToPage((props.page || 1) - 1), disabled: isPrevDisabled(), children: [_jsx(Icon, { variant: "inherit", customSize: "14px", icon: faChevronLeft }), _jsx("span", { children: prevText() })] })) : null, _jsx("span", { className: "umds-pagination__cell-pages", children: pages()?.map((item) => (_jsxs("span", { className: "umds-pagination__item", children: [item.type === "page" ? (_jsx("button", { type: "button", onClick: (event) => goToPage(item.value), disabled: props.disabled, "aria-label": `Página ${item.value}`, "aria-current": isActive(item.value) ? "page" : undefined, className: getBtnClass(item.value), children: item.label })) : null, item.type === "dots" ? (_jsx("span", { "aria-hidden": "true", className: "umds-pagination__dots", children: item.label })) : null] }, item.key))) }), props.showPrevNext !== false ? (_jsxs("button", { type: "button", className: "umds-pagination__cell-btn umds-pagination__cell-btn--next", onClick: (event) => goToPage((props.page || 1) + 1), disabled: isNextDisabled(), children: [_jsx("span", { children: nextText() }), _jsx(Icon, { variant: "inherit", customSize: "14px", icon: faChevronRight })] })) : null] })) : null] }));
251
+ return (_jsxs("nav", { "aria-label": props.ariaLabel || "Paginação", className: classes(), children: [resolvedVariant() === "default" ? (_jsxs(_Fragment, { children: [props.showPrevNext !== false ? (_jsxs("button", { type: "button", className: "umds-pagination__link-btn", onClick: (event) => goToPage((props.page || 1) - 1), disabled: isPrevDisabled(), children: [_jsx(Icon, { variant: "inherit", customSize: "14px", icon: faChevronLeft }), _jsx("span", { children: prevText() })] })) : null, _jsx("input", { type: "text", inputMode: "numeric", className: "umds-pagination__input", value: inputValue, disabled: props.disabled, "aria-label": props.currentPageLabel || "Página atual", onInput: (event) => handleInputChange(event), onKeyDown: (event) => handleInputKeydown(event), onBlur: (event) => commitInput() }), _jsx("span", { className: "umds-pagination__of", children: ofText() }), _jsx("span", { className: "umds-pagination__total", children: props.totalPages || 1 }), props.showPrevNext !== false ? (_jsxs("button", { type: "button", className: "umds-pagination__link-btn", onClick: (event) => goToPage((props.page || 1) + 1), disabled: isNextDisabled(), children: [_jsx("span", { children: nextText() }), _jsx(Icon, { variant: "inherit", customSize: "14px", icon: faChevronRight })] })) : null] })) : null, resolvedVariant() === "alternative" ? (_jsxs(_Fragment, { children: [props.showPrevNext !== false ? (_jsx("button", { type: "button", className: "umds-pagination__ghost-btn", onClick: (event) => goToPage((props.page || 1) - 1), disabled: isPrevDisabled(), "aria-label": props.previousPageLabel || "Página anterior", children: _jsx(Icon, { variant: "inherit", customSize: "16px", icon: faChevronLeft }) })) : null, _jsx("input", { type: "text", inputMode: "numeric", className: "umds-pagination__input", value: inputValue, disabled: props.disabled, "aria-label": props.currentPageLabel || "Página atual", onInput: (event) => handleInputChange(event), onKeyDown: (event) => handleInputKeydown(event), onBlur: (event) => commitInput() }), _jsx("span", { className: "umds-pagination__of", children: ofText() }), _jsx("span", { className: "umds-pagination__total", children: props.totalPages || 1 }), props.showPrevNext !== false ? (_jsx("button", { type: "button", className: "umds-pagination__ghost-btn", onClick: (event) => goToPage((props.page || 1) + 1), disabled: isNextDisabled(), "aria-label": props.nextPageLabel || "Próxima página", children: _jsx(Icon, { variant: "inherit", customSize: "16px", icon: faChevronRight }) })) : null] })) : null, resolvedVariant() === "resumed" ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "umds-pagination__range", children: rangeLabel() }), props.showPrevNext !== false ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "umds-pagination__ghost-btn", onClick: (event) => goToPage((props.page || 1) - 1), disabled: isPrevDisabled(), "aria-label": props.previousPageLabel || "Página anterior", children: _jsx(Icon, { variant: "inherit", customSize: "16px", icon: faChevronLeft }) }), _jsx("button", { type: "button", className: "umds-pagination__ghost-btn", onClick: (event) => goToPage((props.page || 1) + 1), disabled: isNextDisabled(), "aria-label": props.nextPageLabel || "Próxima página", children: _jsx(Icon, { variant: "inherit", customSize: "16px", icon: faChevronRight }) })] })) : null] })) : null, resolvedVariant() === "full-width" ? (_jsxs(_Fragment, { children: [props.showPrevNext !== false ? (_jsxs("button", { type: "button", className: "umds-pagination__nav-btn", onClick: (event) => goToPage((props.page || 1) - 1), disabled: isPrevDisabled(), children: [_jsx(Icon, { variant: "inherit", customSize: "14px", icon: faChevronLeft }), _jsx("span", { children: prevText() })] })) : null, pages()?.map((item) => (_jsxs("span", { className: "umds-pagination__item", children: [item.type === "page" ? (_jsx("button", { type: "button", onClick: (event) => goToPage(item.value), disabled: props.disabled, "aria-label": pageAriaLabel(item.value), "aria-current": isActive(item.value) ? "page" : undefined, className: getBtnClass(item.value), children: item.label })) : null, item.type === "dots" ? (_jsx("span", { "aria-hidden": "true", className: "umds-pagination__dots", children: item.label })) : null] }, item.key))), props.showPrevNext !== false ? (_jsxs("button", { type: "button", className: "umds-pagination__nav-btn", onClick: (event) => goToPage((props.page || 1) + 1), disabled: isNextDisabled(), children: [_jsx("span", { children: nextText() }), _jsx(Icon, { variant: "inherit", customSize: "14px", icon: faChevronRight })] })) : null] })) : null, resolvedVariant() === "bordered" ? (_jsxs("span", { className: "umds-pagination__box", children: [props.showPrevNext !== false ? (_jsxs("button", { type: "button", className: "umds-pagination__cell-btn umds-pagination__cell-btn--prev", onClick: (event) => goToPage((props.page || 1) - 1), disabled: isPrevDisabled(), children: [_jsx(Icon, { variant: "inherit", customSize: "14px", icon: faChevronLeft }), _jsx("span", { children: prevText() })] })) : null, _jsx("span", { className: "umds-pagination__cell-pages", children: pages()?.map((item) => (_jsxs("span", { className: "umds-pagination__item", children: [item.type === "page" ? (_jsx("button", { type: "button", onClick: (event) => goToPage(item.value), disabled: props.disabled, "aria-label": pageAriaLabel(item.value), "aria-current": isActive(item.value) ? "page" : undefined, className: getBtnClass(item.value), children: item.label })) : null, item.type === "dots" ? (_jsx("span", { "aria-hidden": "true", className: "umds-pagination__dots", children: item.label })) : null] }, item.key))) }), props.showPrevNext !== false ? (_jsxs("button", { type: "button", className: "umds-pagination__cell-btn umds-pagination__cell-btn--next", onClick: (event) => goToPage((props.page || 1) + 1), disabled: isNextDisabled(), children: [_jsx("span", { children: nextText() }), _jsx(Icon, { variant: "inherit", customSize: "14px", icon: faChevronRight })] })) : null] })) : null] }));
244
252
  }
245
253
  export default Pagination;
@@ -96,7 +96,15 @@
96
96
  }
97
97
 
98
98
  .umds-phone-input--readonly .umds-phone-input__container:hover {
99
- border-color: var(--umds-semantic-color-neutral-light-down); /* #D5D5D5 */
99
+ border-color: var(--umds-semantic-field-border-default);
100
+ }
101
+
102
+ /* Somente leitura não é desabilitado: o texto segue lido e a WCAG 1.4.3 vale
103
+ sem isenção. O placeholder padrão foi calibrado para fundo branco e cai para
104
+ ~4,2:1 sobre o fundo de somente leitura; neutral-dark-down passa 4,5:1 em
105
+ todos os temas (1doc 6,78:1 · 1doc-dark 10,83:1 · alto contraste 16,48:1). */
106
+ .umds-phone-input--readonly .umds-phone-input__field::placeholder {
107
+ color: var(--umds-semantic-color-neutral-dark-down);
100
108
  }
101
109
 
102
110
  /* ── Flag selector pill ── */
@@ -36,6 +36,16 @@ export interface PhoneInputCountry {
36
36
  export interface PhoneInputProps {
37
37
  /** Rótulo acessível do seletor de país. @default 'Selecionar país' */
38
38
  countryLabel?: string;
39
+ /** Nomes dos países na lista e no alt da bandeira, por código ISO (ex.: `{ BR: "Brazil", ES: "Spain" }`). Código ausente mantém o nome padrão. Troque para traduzir. @default nomes em português */
40
+ countryNames?: {
41
+ [code: string]: string;
42
+ };
43
+ /** Nome acessível do botão de copiar o número. Troque para traduzir. @default 'Copiar número' */
44
+ copyLabel?: string;
45
+ /** Dica (title) do botão de copiar. Troque para traduzir. @default 'Copiar' */
46
+ copyTitle?: string;
47
+ /** Nome acessível e dica do botão de copiar logo depois da cópia. Troque para traduzir. @default 'Copiado!' */
48
+ copiedLabel?: string;
39
49
  value?: string;
40
50
  defaultValue?: string;
41
51
  placeholder?: string;
@@ -97,14 +97,31 @@ function PhoneInput(props) {
97
97
  const [internalValue, setInternalValue] = useState(() => props.defaultValue || "");
98
98
  const [uid, setUid] = useState(() => "umds-phone-input-" + Math.random().toString(36).slice(2, 9));
99
99
  function countryList() {
100
- return COUNTRIES;
100
+ const nomes = props.countryNames;
101
+ if (!nomes)
102
+ return COUNTRIES;
103
+ return COUNTRIES.map((c) => ({
104
+ ...c,
105
+ name: nomes[c.code] || c.name,
106
+ }));
101
107
  }
102
108
  function selectedCode() {
103
109
  return props.country || internalCountry;
104
110
  }
105
111
  function currentCountry() {
106
112
  const code = selectedCode();
107
- return COUNTRIES.find((c) => c.code === code) || COUNTRIES[1];
113
+ const lista = countryList();
114
+ return lista.find((c) => c.code === code) || lista[1];
115
+ }
116
+ function copyAriaText() {
117
+ return copied
118
+ ? props.copiedLabel || "Copiado!"
119
+ : props.copyLabel || "Copiar número";
120
+ }
121
+ function copyTitleText() {
122
+ return copied
123
+ ? props.copiedLabel || "Copiado!"
124
+ : props.copyTitle || "Copiar";
108
125
  }
109
126
  function inputId() {
110
127
  return props.id || uid;
@@ -298,7 +315,7 @@ function PhoneInput(props) {
298
315
  stopAutoUpdate();
299
316
  };
300
317
  }, []);
301
- return (_jsxs("div", { ref: rootRef, onKeyDown: (event) => handleWrapperKeydown(event), className: wrapperClasses(), children: [props.label ? (_jsx("label", { className: "umds-phone-input__label", htmlFor: inputId(), children: props.label })) : null, _jsxs("div", { className: containerClasses(), children: [_jsxs("button", { type: "button", "aria-haspopup": "listbox", className: "umds-phone-input__flag-btn", ref: flagBtnRef, onClick: (event) => toggleDropdown(), disabled: props.disabled || props.readOnly, "aria-expanded": open, "aria-label": props.countryLabel || "Selecionar país", children: [_jsx("img", { width: "16", height: "12", className: "umds-phone-input__flag-img", src: currentCountry().flagUrl, alt: currentCountry().name }), _jsx("span", { "aria-hidden": "true", className: "umds-phone-input__chevron", children: _jsx(Icon, { variant: "inherit", customSize: "10px", icon: faChevronDown }) })] }), _jsx("input", { type: "tel", inputMode: "tel", className: "umds-phone-input__field", id: inputId(), name: props.name, value: displayValue(), placeholder: props.placeholder || `${currentCountry().ddi} (000) 000-0000`, disabled: props.disabled, readOnly: props.readOnly, "aria-invalid": isInvalid(), "aria-describedby": describedBy() || undefined, onChange: (event) => handleChange(event) }), props.name ? (_jsx("input", { type: "hidden", name: props.name + "_ddi", value: currentCountry().ddi })) : null, showCopy() && !props.disabled && !props.readOnly ? (_jsxs("button", { type: "button", onClick: (event) => handleCopy(), "aria-label": copied ? "Copiado!" : "Copiar número", title: copied ? "Copiado!" : "Copiar", className: [
318
+ return (_jsxs("div", { ref: rootRef, onKeyDown: (event) => handleWrapperKeydown(event), className: wrapperClasses(), children: [props.label ? (_jsx("label", { className: "umds-phone-input__label", htmlFor: inputId(), children: props.label })) : null, _jsxs("div", { className: containerClasses(), children: [_jsxs("button", { type: "button", "aria-haspopup": "listbox", className: "umds-phone-input__flag-btn", ref: flagBtnRef, onClick: (event) => toggleDropdown(), disabled: props.disabled || props.readOnly, "aria-expanded": open, "aria-label": props.countryLabel || "Selecionar país", children: [_jsx("img", { width: "16", height: "12", className: "umds-phone-input__flag-img", src: currentCountry().flagUrl, alt: currentCountry().name }), _jsx("span", { "aria-hidden": "true", className: "umds-phone-input__chevron", children: _jsx(Icon, { variant: "inherit", customSize: "10px", icon: faChevronDown }) })] }), _jsx("input", { type: "tel", inputMode: "tel", className: "umds-phone-input__field", id: inputId(), name: props.name, value: displayValue(), placeholder: props.placeholder || `${currentCountry().ddi} (000) 000-0000`, disabled: props.disabled, readOnly: props.readOnly, "aria-invalid": isInvalid(), "aria-describedby": describedBy() || undefined, onChange: (event) => handleChange(event) }), props.name ? (_jsx("input", { type: "hidden", name: props.name + "_ddi", value: currentCountry().ddi })) : null, showCopy() && !props.disabled && !props.readOnly ? (_jsxs("button", { type: "button", onClick: (event) => handleCopy(), "aria-label": copyAriaText(), title: copyTitleText(), className: [
302
319
  "umds-phone-input__copy-btn",
303
320
  copied ? "umds-phone-input__copy-btn--copied" : "",
304
321
  ]
@@ -22,6 +22,7 @@ import './Popover.css';
22
22
  * @property {boolean} closable - Exibe o botão de fechar no topo.
23
23
  * @property {string} closeLabel - Nome acessível do botão de fechar. Padrão: "Fechar".
24
24
  * @property {number} width - Largura do painel, em px. Padrão: 240.
25
+ * @property {number | string} maxHeight - Altura máxima do corpo, que rola quando o conteúdo passa dela. Número vira px; texto vai como CSS (`"60vh"`). `"none"` deixa o corpo crescer com o conteúdo (painel "Colunas do card"). Sem a prop, o teto histórico de 300px continua.
25
26
  * @property {string} ariaLabel - Nome acessível quando não há `title`.
26
27
  * @property {string} className - Classes CSS adicionais.
27
28
  * @property {function} onOpenChange - Avisa quando abre e quando fecha.
@@ -45,6 +46,12 @@ export interface PopoverProps {
45
46
  closable?: boolean;
46
47
  closeLabel?: string;
47
48
  width?: number;
49
+ /**
50
+ * Altura máxima do corpo. Número vira px; texto vai como CSS (`"60vh"`).
51
+ * `"none"` deixa o corpo crescer com o conteúdo. Sem a prop, vale o teto de
52
+ * 300px de sempre (o cabeçalho e o × não rolam junto).
53
+ */
54
+ maxHeight?: number | string;
48
55
  ariaLabel?: string;
49
56
  className?: string;
50
57
  children?: any;
@@ -305,6 +305,16 @@ function Popover(props) {
305
305
  visibility: positioned ? "visible" : "hidden",
306
306
  };
307
307
  }
308
+ function corpoStyle() {
309
+ if (props.maxHeight === undefined || props.maxHeight === null) {
310
+ return undefined;
311
+ }
312
+ return {
313
+ maxHeight: typeof props.maxHeight === "number"
314
+ ? props.maxHeight + "px"
315
+ : props.maxHeight,
316
+ };
317
+ }
308
318
  function panelStyle() {
309
319
  return {
310
320
  opacity: positioned ? 1 : 0,
@@ -339,6 +349,6 @@ function Popover(props) {
339
349
  }, []);
340
350
  return (_jsxs("span", { ref: anchorRef, className: anchorClasses(), style: {
341
351
  display: "inline-flex",
342
- }, children: [_jsx("span", { className: "umds-popover__trigger", ref: triggerButtonRef, id: triggerIdText(), role: triggerIsInteractive ? undefined : "button", tabIndex: triggerIsInteractive ? undefined : 0, "aria-haspopup": triggerIsInteractive ? undefined : "dialog", "aria-expanded": triggerIsInteractive ? undefined : ariaExpandedText(), onClick: (event) => toggle(), onKeyDown: (event) => handleTriggerKeydown(event), children: _jsx(_Fragment, { children: props.children }) }), _jsx(Portal, { children: mounted ? (_jsx("span", { className: "umds-popover__floating", ref: floatingRef, style: floatingStyle(), children: _jsxs("div", { className: "umds-popover__panel", role: "dialog", "aria-modal": "false", ref: panelRef, "aria-labelledby": labelledByText(), "aria-label": props.title ? undefined : props.ariaLabel, tabIndex: -1, style: panelStyle(), onKeyDown: (event) => handlePanelKeydown(event), children: [props.title || props.closable ? (_jsxs("div", { className: "umds-popover__header", children: [props.title ? (_jsx(Text, { as: "span", variant: "body2", weight: "semibold", id: titleIdText(), children: props.title })) : null, props.closable ? (_jsx("button", { type: "button", className: "umds-popover__close", "aria-label": props.closeLabel || "Fechar", onClick: (event) => close(), children: _jsx(Icon, { size: "sm", variant: "inherit", icon: faXmark }) })) : null] })) : null, _jsx("div", { className: "umds-popover__body", children: _jsx(_Fragment, { children: props.content }) })] }) })) : null })] }));
352
+ }, children: [_jsx("span", { className: "umds-popover__trigger", ref: triggerButtonRef, id: triggerIdText(), role: triggerIsInteractive ? undefined : "button", tabIndex: triggerIsInteractive ? undefined : 0, "aria-haspopup": triggerIsInteractive ? undefined : "dialog", "aria-expanded": triggerIsInteractive ? undefined : ariaExpandedText(), onClick: (event) => toggle(), onKeyDown: (event) => handleTriggerKeydown(event), children: _jsx(_Fragment, { children: props.children }) }), _jsx(Portal, { children: mounted ? (_jsx("span", { className: "umds-popover__floating", ref: floatingRef, style: floatingStyle(), children: _jsxs("div", { className: "umds-popover__panel", role: "dialog", "aria-modal": "false", ref: panelRef, "aria-labelledby": labelledByText(), "aria-label": props.title ? undefined : props.ariaLabel, tabIndex: -1, style: panelStyle(), onKeyDown: (event) => handlePanelKeydown(event), children: [props.title || props.closable ? (_jsxs("div", { className: "umds-popover__header", children: [props.title ? (_jsx(Text, { as: "span", variant: "body2", weight: "semibold", id: titleIdText(), children: props.title })) : null, props.closable ? (_jsx("button", { type: "button", className: "umds-popover__close", "aria-label": props.closeLabel || "Fechar", onClick: (event) => close(), children: _jsx(Icon, { size: "sm", variant: "inherit", icon: faXmark }) })) : null] })) : null, _jsx("div", { className: "umds-popover__body", style: corpoStyle(), children: _jsx(_Fragment, { children: props.content }) })] }) })) : null })] }));
343
353
  }
344
354
  export default Popover;