@1doc/1ds-react 2.8.0 → 2.10.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 (287) hide show
  1. package/CHANGELOG.md +1540 -0
  2. package/dist/components/AILabel/AILabel.js +1 -1
  3. package/dist/components/Accordion/Accordion.css +13 -0
  4. package/dist/components/Accordion/Accordion.d.ts +9 -2
  5. package/dist/components/Accordion/Accordion.js +1 -0
  6. package/dist/components/AppSubheader/AppSubheader.css +10 -1
  7. package/dist/components/AttachmentCard/AttachmentCard.css +26 -8
  8. package/dist/components/AttachmentCard/AttachmentCard.d.ts +22 -2
  9. package/dist/components/AttachmentCard/AttachmentCard.js +47 -3
  10. package/dist/components/Avatar/Avatar.css +7 -2
  11. package/dist/components/Avatar/AvatarGroup.d.ts +17 -0
  12. package/dist/components/Avatar/AvatarGroup.js +22 -8
  13. package/dist/components/Badge/Badge.css +67 -2
  14. package/dist/components/Badge/Badge.d.ts +23 -4
  15. package/dist/components/Badge/Badge.js +4 -0
  16. package/dist/components/Box/Box.css +83 -0
  17. package/dist/components/Box/Box.d.ts +82 -2
  18. package/dist/components/Box/Box.js +42 -2
  19. package/dist/components/Button/Button.css +29 -0
  20. package/dist/components/Button/Button.d.ts +4 -4
  21. package/dist/components/Button/Button.js +4 -1
  22. package/dist/components/Calendar/Calendar.css +245 -0
  23. package/dist/components/Calendar/Calendar.d.ts +126 -0
  24. package/dist/components/Calendar/Calendar.js +320 -0
  25. package/dist/components/Chips/Chips.css +38 -0
  26. package/dist/components/Chips/Chips.d.ts +5 -2
  27. package/dist/components/Chips/Chips.js +2 -1
  28. package/dist/components/Coachmark/Coachmark.css +128 -0
  29. package/dist/components/Coachmark/Coachmark.d.ts +87 -0
  30. package/dist/components/Coachmark/Coachmark.js +362 -0
  31. package/dist/components/CodeBlock/CodeBlock.css +96 -0
  32. package/dist/components/CodeBlock/CodeBlock.d.ts +47 -0
  33. package/dist/components/CodeBlock/CodeBlock.js +103 -0
  34. package/dist/components/ColorPicker/ColorPicker.css +140 -0
  35. package/dist/components/ColorPicker/ColorPicker.d.ts +73 -0
  36. package/dist/components/ColorPicker/ColorPicker.js +219 -0
  37. package/dist/components/Combobox/Combobox.css +8 -0
  38. package/dist/components/DataTable/DataTable.css +254 -0
  39. package/dist/components/DataTable/DataTable.d.ts +81 -5
  40. package/dist/components/DataTable/DataTable.js +335 -19
  41. package/dist/components/DatePicker/DatePicker.css +8 -0
  42. package/dist/components/DatePicker/DatePicker.js +10 -1
  43. package/dist/components/DescriptionList/DescriptionList.css +127 -0
  44. package/dist/components/DescriptionList/DescriptionList.d.ts +62 -0
  45. package/dist/components/DescriptionList/DescriptionList.js +52 -0
  46. package/dist/components/EmptyState/EmptyState.d.ts +4 -2
  47. package/dist/components/EmptyState/EmptyState.js +2 -2
  48. package/dist/components/FileInput/FileInput.css +16 -0
  49. package/dist/components/FileInput/FileInput.d.ts +4 -2
  50. package/dist/components/FileInput/FileInput.js +8 -2
  51. package/dist/components/Grid/Grid.js +5 -5
  52. package/dist/components/IconPicker/IconPicker.css +107 -0
  53. package/dist/components/IconPicker/IconPicker.d.ts +74 -0
  54. package/dist/components/IconPicker/IconPicker.js +194 -0
  55. package/dist/components/Input/Input.css +59 -0
  56. package/dist/components/Input/Input.d.ts +17 -1
  57. package/dist/components/Input/Input.js +67 -5
  58. package/dist/components/Kanban/Kanban.css +4 -0
  59. package/dist/components/Kbd/Kbd.css +66 -0
  60. package/dist/components/Kbd/Kbd.d.ts +32 -0
  61. package/dist/components/Kbd/Kbd.js +40 -0
  62. package/dist/components/List/List.css +136 -0
  63. package/dist/components/List/List.d.ts +82 -0
  64. package/dist/components/List/List.js +53 -0
  65. package/dist/components/List/ListItem.d.ts +97 -0
  66. package/dist/components/List/ListItem.js +82 -0
  67. package/dist/components/Modal/Modal.css +80 -0
  68. package/dist/components/Modal/Modal.d.ts +33 -6
  69. package/dist/components/Modal/Modal.js +101 -6
  70. package/dist/components/MultiSelect/MultiSelect.css +8 -0
  71. package/dist/components/MultiSelect/MultiSelect.js +10 -1
  72. package/dist/components/OrgChart/OrgChart.css +149 -0
  73. package/dist/components/OrgChart/OrgChart.d.ts +83 -0
  74. package/dist/components/OrgChart/OrgChart.js +297 -0
  75. package/dist/components/OtpInput/OtpInput.css +93 -0
  76. package/dist/components/OtpInput/OtpInput.d.ts +60 -0
  77. package/dist/components/OtpInput/OtpInput.js +215 -0
  78. package/dist/components/PhoneInput/PhoneInput.css +8 -0
  79. package/dist/components/Popover/Popover.d.ts +7 -0
  80. package/dist/components/Popover/Popover.js +11 -1
  81. package/dist/components/RichTextEditor/RichTextEditor.css +250 -0
  82. package/dist/components/RichTextEditor/RichTextEditor.d.ts +97 -0
  83. package/dist/components/RichTextEditor/RichTextEditor.js +951 -0
  84. package/dist/components/SegmentedControl/SegmentedControl.css +24 -0
  85. package/dist/components/SegmentedControl/SegmentedControl.d.ts +2 -0
  86. package/dist/components/SegmentedControl/SegmentedControl.js +10 -2
  87. package/dist/components/Select/Select.css +164 -0
  88. package/dist/components/Select/Select.d.ts +34 -0
  89. package/dist/components/Select/Select.js +258 -28
  90. package/dist/components/Stack/Stack.css +49 -0
  91. package/dist/components/Stack/Stack.d.ts +65 -7
  92. package/dist/components/Stack/Stack.js +30 -2
  93. package/dist/components/StatCard/StatCard.css +138 -0
  94. package/dist/components/StatCard/StatCard.d.ts +26 -0
  95. package/dist/components/StatCard/StatCard.js +13 -1
  96. package/dist/components/Tabs/Tab.d.ts +15 -0
  97. package/dist/components/Tabs/Tab.js +30 -1
  98. package/dist/components/Tabs/Tabs.css +132 -0
  99. package/dist/components/Tabs/Tabs.d.ts +7 -0
  100. package/dist/components/Tabs/Tabs.js +13 -2
  101. package/dist/components/Tag/Tag.css +85 -2
  102. package/dist/components/Tag/Tag.d.ts +13 -6
  103. package/dist/components/Tag/Tag.js +1 -0
  104. package/dist/components/Text/Text.js +2 -2
  105. package/dist/components/Textarea/Textarea.css +8 -0
  106. package/dist/components/TimePicker/TimePicker.css +8 -0
  107. package/dist/components/Toast/Toast.css +32 -0
  108. package/dist/components/Toast/Toast.d.ts +18 -0
  109. package/dist/components/Toast/Toast.js +14 -1
  110. package/dist/components/Toast/ToastStack.js +8 -1
  111. package/dist/components/Tooltip/Tooltip.css +25 -0
  112. package/dist/components/Tooltip/Tooltip.d.ts +11 -0
  113. package/dist/components/Tooltip/Tooltip.js +18 -3
  114. package/dist/index.d.ts +25 -0
  115. package/dist/index.js +14 -0
  116. package/dist/teste/AILabel.test.d.ts +1 -0
  117. package/dist/teste/AILabel.test.js +33 -0
  118. package/dist/teste/AccordionConteudoLivre.test.d.ts +1 -0
  119. package/dist/teste/AccordionConteudoLivre.test.js +29 -0
  120. package/dist/teste/AccordionTituloNeutro.test.d.ts +1 -0
  121. package/dist/teste/AccordionTituloNeutro.test.js +23 -0
  122. package/dist/teste/AppSubheaderRegiao.test.d.ts +1 -0
  123. package/dist/teste/AppSubheaderRegiao.test.js +13 -0
  124. package/dist/teste/AtributosRepassados.test.d.ts +1 -0
  125. package/dist/teste/AtributosRepassados.test.js +52 -0
  126. package/dist/teste/AttachmentCardIA.test.d.ts +1 -0
  127. package/dist/teste/AttachmentCardIA.test.js +89 -0
  128. package/dist/teste/AttachmentCardLista.test.d.ts +1 -0
  129. package/dist/teste/AttachmentCardLista.test.js +49 -0
  130. package/dist/teste/AttachmentCardSm.test.d.ts +1 -0
  131. package/dist/teste/AttachmentCardSm.test.js +26 -0
  132. package/dist/teste/AvatarGroupOverlap.test.d.ts +1 -0
  133. package/dist/teste/AvatarGroupOverlap.test.js +56 -0
  134. package/dist/teste/BadgeNeutroColado.test.d.ts +1 -0
  135. package/dist/teste/BadgeNeutroColado.test.js +11 -0
  136. package/dist/teste/BadgeTag.test.d.ts +1 -0
  137. package/dist/teste/BadgeTag.test.js +55 -0
  138. package/dist/teste/BoxItemFlex.test.d.ts +1 -0
  139. package/dist/teste/BoxItemFlex.test.js +54 -0
  140. package/dist/teste/BoxLayout.test.d.ts +1 -0
  141. package/dist/teste/BoxLayout.test.js +35 -0
  142. package/dist/teste/Button.test.d.ts +1 -0
  143. package/dist/teste/Button.test.js +27 -0
  144. package/dist/teste/Calendar.test.d.ts +1 -0
  145. package/dist/teste/Calendar.test.js +221 -0
  146. package/dist/teste/CalendarCabecalho.test.d.ts +1 -0
  147. package/dist/teste/CalendarCabecalho.test.js +11 -0
  148. package/dist/teste/ChipsXs.test.d.ts +1 -0
  149. package/dist/teste/ChipsXs.test.js +31 -0
  150. package/dist/teste/Coachmark.test.d.ts +1 -0
  151. package/dist/teste/Coachmark.test.js +149 -0
  152. package/dist/teste/CoachmarkSemVeu.test.d.ts +1 -0
  153. package/dist/teste/CoachmarkSemVeu.test.js +85 -0
  154. package/dist/teste/ColorPicker.test.d.ts +1 -0
  155. package/dist/teste/ColorPicker.test.js +132 -0
  156. package/dist/teste/ColorPickerXs.test.d.ts +1 -0
  157. package/dist/teste/ColorPickerXs.test.js +21 -0
  158. package/dist/teste/DataTableArvoreEVariantes.test.d.ts +1 -0
  159. package/dist/teste/DataTableArvoreEVariantes.test.js +190 -0
  160. package/dist/teste/DataTableCelulaLivre.test.d.ts +1 -0
  161. package/dist/teste/DataTableCelulaLivre.test.js +76 -0
  162. package/dist/teste/DataTableDocumento.test.d.ts +1 -0
  163. package/dist/teste/DataTableDocumento.test.js +92 -0
  164. package/dist/teste/DatePicker.test.js +23 -0
  165. package/dist/teste/DescriptionListCompacta.test.d.ts +1 -0
  166. package/dist/teste/DescriptionListCompacta.test.js +22 -0
  167. package/dist/teste/EmptyStateTituloRico.test.d.ts +1 -0
  168. package/dist/teste/EmptyStateTituloRico.test.js +23 -0
  169. package/dist/teste/FileInputTrigger.test.d.ts +1 -0
  170. package/dist/teste/FileInputTrigger.test.js +53 -0
  171. package/dist/teste/IconPicker.test.d.ts +1 -0
  172. package/dist/teste/IconPicker.test.js +130 -0
  173. package/dist/teste/InputAgrupado.test.d.ts +1 -0
  174. package/dist/teste/InputAgrupado.test.js +24 -0
  175. package/dist/teste/InputMascaraEAfins.test.d.ts +1 -0
  176. package/dist/teste/InputMascaraEAfins.test.js +99 -0
  177. package/dist/teste/KbdCodeBlock.test.d.ts +1 -0
  178. package/dist/teste/KbdCodeBlock.test.js +95 -0
  179. package/dist/teste/List.test.d.ts +1 -0
  180. package/dist/teste/List.test.js +153 -0
  181. package/dist/teste/ListItemTooltipStandalone.test.d.ts +1 -0
  182. package/dist/teste/ListItemTooltipStandalone.test.js +39 -0
  183. package/dist/teste/ModalVariantes.test.d.ts +1 -0
  184. package/dist/teste/ModalVariantes.test.js +151 -0
  185. package/dist/teste/NomeAcessivelSsr.test.d.ts +1 -0
  186. package/dist/teste/NomeAcessivelSsr.test.js +88 -0
  187. package/dist/teste/OrgChart.test.d.ts +1 -0
  188. package/dist/teste/OrgChart.test.js +162 -0
  189. package/dist/teste/OtpInput.test.d.ts +1 -0
  190. package/dist/teste/OtpInput.test.js +143 -0
  191. package/dist/teste/PopoverMaxHeight.test.d.ts +1 -0
  192. package/dist/teste/PopoverMaxHeight.test.js +38 -0
  193. package/dist/teste/RichTextEditor.test.d.ts +1 -0
  194. package/dist/teste/RichTextEditor.test.js +287 -0
  195. package/dist/teste/RichTextEditorAlinhaImagemTabela.test.d.ts +1 -0
  196. package/dist/teste/RichTextEditorAlinhaImagemTabela.test.js +212 -0
  197. package/dist/teste/RichTextEditorEstiloDeTexto.test.d.ts +1 -0
  198. package/dist/teste/RichTextEditorEstiloDeTexto.test.js +120 -0
  199. package/dist/teste/SegmentedControlContador.test.d.ts +1 -0
  200. package/dist/teste/SegmentedControlContador.test.js +39 -0
  201. package/dist/teste/SelectAbertoControladoEFlutuante.test.d.ts +1 -0
  202. package/dist/teste/SelectAbertoControladoEFlutuante.test.js +145 -0
  203. package/dist/teste/SelectFiltroCorETamanho.test.d.ts +1 -0
  204. package/dist/teste/SelectFiltroCorETamanho.test.js +77 -0
  205. package/dist/teste/SelectPlacementFiltro.test.d.ts +1 -0
  206. package/dist/teste/SelectPlacementFiltro.test.js +88 -0
  207. package/dist/teste/Stack.test.d.ts +1 -0
  208. package/dist/teste/Stack.test.js +57 -0
  209. package/dist/teste/StatCardRotuloTopo.test.d.ts +1 -0
  210. package/dist/teste/StatCardRotuloTopo.test.js +34 -0
  211. package/dist/teste/StatCardSecundariaETom.test.d.ts +1 -0
  212. package/dist/teste/StatCardSecundariaETom.test.js +45 -0
  213. package/dist/teste/TabsContadorFechavel.test.d.ts +1 -0
  214. package/dist/teste/TabsContadorFechavel.test.js +79 -0
  215. package/dist/teste/ToastAcaoEDetalhes.test.d.ts +1 -0
  216. package/dist/teste/ToastAcaoEDetalhes.test.js +94 -0
  217. package/dist/teste/TooltipDark.test.d.ts +1 -0
  218. package/dist/teste/TooltipDark.test.js +31 -0
  219. package/dist/utils/calendario.d.ts +28 -0
  220. package/dist/utils/calendario.js +73 -0
  221. package/dist/utils/html-seguro.d.ts +45 -0
  222. package/dist/utils/html-seguro.js +208 -0
  223. package/dist/utils/paleta-de-cores.d.ts +26 -0
  224. package/dist/utils/paleta-de-cores.js +10 -0
  225. package/dist/utils/texto.d.ts +5 -0
  226. package/dist/utils/texto.js +5 -0
  227. package/dist/utils/toast.d.ts +10 -1
  228. package/dist/utils/toast.js +2 -1
  229. package/package.json +3 -3
  230. package/src/index.ts +26 -0
  231. package/src/teste/AILabel.test.tsx +41 -0
  232. package/src/teste/AccordionConteudoLivre.test.tsx +39 -0
  233. package/src/teste/AccordionTituloNeutro.test.tsx +25 -0
  234. package/src/teste/AppSubheaderRegiao.test.tsx +17 -0
  235. package/src/teste/AtributosRepassados.test.tsx +73 -0
  236. package/src/teste/AttachmentCardIA.test.tsx +126 -0
  237. package/src/teste/AttachmentCardLista.test.tsx +53 -0
  238. package/src/teste/AttachmentCardSm.test.tsx +29 -0
  239. package/src/teste/AvatarGroupOverlap.test.tsx +74 -0
  240. package/src/teste/BadgeNeutroColado.test.tsx +15 -0
  241. package/src/teste/BadgeTag.test.tsx +85 -0
  242. package/src/teste/BoxItemFlex.test.tsx +81 -0
  243. package/src/teste/BoxLayout.test.tsx +50 -0
  244. package/src/teste/Button.test.tsx +39 -0
  245. package/src/teste/Calendar.test.tsx +282 -0
  246. package/src/teste/CalendarCabecalho.test.tsx +11 -0
  247. package/src/teste/ChipsXs.test.tsx +41 -0
  248. package/src/teste/Coachmark.test.tsx +198 -0
  249. package/src/teste/CoachmarkSemVeu.test.tsx +101 -0
  250. package/src/teste/ColorPicker.test.tsx +153 -0
  251. package/src/teste/ColorPickerXs.test.tsx +22 -0
  252. package/src/teste/DataTableArvoreEVariantes.test.tsx +240 -0
  253. package/src/teste/DataTableCelulaLivre.test.tsx +103 -0
  254. package/src/teste/DataTableDocumento.test.tsx +102 -0
  255. package/src/teste/DatePicker.test.tsx +38 -0
  256. package/src/teste/DescriptionListCompacta.test.tsx +24 -0
  257. package/src/teste/EmptyStateTituloRico.test.tsx +34 -0
  258. package/src/teste/FileInputTrigger.test.tsx +89 -0
  259. package/src/teste/IconPicker.test.tsx +145 -0
  260. package/src/teste/InputAgrupado.test.tsx +26 -0
  261. package/src/teste/InputMascaraEAfins.test.tsx +124 -0
  262. package/src/teste/KbdCodeBlock.test.tsx +106 -0
  263. package/src/teste/List.test.tsx +269 -0
  264. package/src/teste/ListItemTooltipStandalone.test.tsx +64 -0
  265. package/src/teste/ModalVariantes.test.tsx +173 -0
  266. package/src/teste/NomeAcessivelSsr.test.tsx +110 -0
  267. package/src/teste/OrgChart.test.tsx +183 -0
  268. package/src/teste/OtpInput.test.tsx +163 -0
  269. package/src/teste/PopoverMaxHeight.test.tsx +47 -0
  270. package/src/teste/RichTextEditor.test.tsx +329 -0
  271. package/src/teste/RichTextEditorAlinhaImagemTabela.test.tsx +238 -0
  272. package/src/teste/RichTextEditorEstiloDeTexto.test.tsx +137 -0
  273. package/src/teste/SegmentedControlContador.test.tsx +43 -0
  274. package/src/teste/SelectAbertoControladoEFlutuante.test.tsx +180 -0
  275. package/src/teste/SelectFiltroCorETamanho.test.tsx +90 -0
  276. package/src/teste/SelectPlacementFiltro.test.tsx +110 -0
  277. package/src/teste/Stack.test.tsx +80 -0
  278. package/src/teste/StatCardRotuloTopo.test.tsx +44 -0
  279. package/src/teste/StatCardSecundariaETom.test.tsx +51 -0
  280. package/src/teste/TabsContadorFechavel.test.tsx +144 -0
  281. package/src/teste/ToastAcaoEDetalhes.test.tsx +109 -0
  282. package/src/teste/TooltipDark.test.tsx +51 -0
  283. package/src/utils/calendario.ts +78 -0
  284. package/src/utils/html-seguro.ts +197 -0
  285. package/src/utils/paleta-de-cores.ts +34 -0
  286. package/src/utils/texto.ts +5 -0
  287. package/src/utils/toast.ts +12 -2
@@ -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;
@@ -99,6 +99,14 @@
99
99
  border-color: var(--umds-semantic-field-border-default);
100
100
  }
101
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);
108
+ }
109
+
102
110
  /* ── Flag selector pill ── */
103
111
  .umds-phone-input__flag-btn {
104
112
  display: inline-flex;
@@ -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;
@@ -0,0 +1,250 @@
1
+ /* ─────────────────────────────────────────────
2
+ RICH TEXT EDITOR
3
+ Editor de texto rico leve sobre contenteditable.
4
+
5
+ A moldura (borda, raio, foco, erro) segue a família de campos. A barra é uma
6
+ faixa de fundo claro com botões de 32px: o botão LIGADO (negrito, lista...)
7
+ ganha o fundo e a cor do primário, e a mesma informação sai em `aria-pressed`.
8
+
9
+ Cores: semânticos · Medidas: primitivos
10
+ ───────────────────────────────────────────── */
11
+
12
+ .umds-rte {
13
+ display: 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-rte__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-rte__frame {
26
+ display: flex;
27
+ flex-direction: column;
28
+ border: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-field-border-default);
29
+ border-radius: var(--umds-primitive-border-radius-sm);
30
+ background: var(--umds-semantic-color-background-white);
31
+ overflow: hidden;
32
+ transition:
33
+ border-color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard),
34
+ box-shadow var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard);
35
+ }
36
+
37
+ .umds-rte__frame:hover {
38
+ border-color: var(--umds-semantic-field-border-hover);
39
+ }
40
+
41
+ .umds-rte__frame:focus-within {
42
+ border-color: var(--umds-semantic-field-border-focus);
43
+ box-shadow: var(--umds-semantic-field-ring-focus);
44
+ }
45
+
46
+ .umds-rte--invalid .umds-rte__frame,
47
+ .umds-rte--invalid .umds-rte__frame:hover {
48
+ border-color: var(--umds-semantic-field-border-error);
49
+ }
50
+
51
+ .umds-rte--invalid .umds-rte__frame:focus-within {
52
+ box-shadow: var(--umds-semantic-field-ring-error);
53
+ }
54
+
55
+ .umds-rte--disabled .umds-rte__frame {
56
+ background: var(--umds-semantic-field-disabled-background);
57
+ opacity: var(--umds-semantic-field-disabled-opacity);
58
+ cursor: not-allowed;
59
+ }
60
+
61
+ .umds-rte--readonly .umds-rte__frame {
62
+ background: var(--umds-semantic-field-readonly-background);
63
+ }
64
+
65
+ /* ── Barra ── */
66
+ .umds-rte__toolbar {
67
+ display: flex;
68
+ flex-wrap: wrap;
69
+ align-items: center;
70
+ gap: var(--umds-primitive-spacing-quarck); /* 4px */
71
+ padding: var(--umds-primitive-spacing-quarck) var(--umds-primitive-spacing-nano); /* 4px 8px */
72
+ background: var(--umds-semantic-color-background-light);
73
+ border-bottom: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-color-neutral-light-medium);
74
+ }
75
+
76
+ .umds-rte__tool {
77
+ display: inline-flex;
78
+ align-items: center;
79
+ justify-content: center;
80
+ box-sizing: border-box;
81
+ width: var(--umds-primitive-spacing-xs); /* 32px */
82
+ height: var(--umds-primitive-spacing-xs);
83
+ margin: 0;
84
+ padding: 0;
85
+ border: none;
86
+ border-radius: var(--umds-primitive-border-radius-sm);
87
+ background: transparent;
88
+ color: var(--umds-semantic-color-neutral-dark-down);
89
+ cursor: pointer;
90
+ transition:
91
+ background-color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard),
92
+ color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard);
93
+ }
94
+
95
+ .umds-rte__tool:hover:not(:disabled) {
96
+ background: var(--umds-semantic-color-neutral-light-medium);
97
+ color: var(--umds-semantic-color-neutral-dark-pure);
98
+ }
99
+
100
+ .umds-rte__tool--active,
101
+ .umds-rte__tool--active:hover:not(:disabled) {
102
+ background: var(--umds-semantic-color-primary-light);
103
+ color: var(--umds-semantic-color-primary-dark);
104
+ }
105
+
106
+ .umds-rte__tool:focus-visible {
107
+ outline: var(--umds-primitive-border-width-thin) solid var(--umds-semantic-color-primary-pure);
108
+ outline-offset: calc(var(--umds-primitive-border-width-thin) * -1);
109
+ }
110
+
111
+ .umds-rte__tool:disabled {
112
+ cursor: not-allowed;
113
+ opacity: var(--umds-semantic-field-disabled-opacity);
114
+ }
115
+
116
+ .umds-rte__separator {
117
+ align-self: stretch;
118
+ width: var(--umds-primitive-border-width-hairline);
119
+ margin: var(--umds-primitive-spacing-quarck) var(--umds-primitive-spacing-micro);
120
+ background: var(--umds-semantic-color-neutral-light-down);
121
+ }
122
+
123
+ /* ── Campo de link, logo abaixo da barra ── */
124
+ .umds-rte__link {
125
+ display: flex;
126
+ flex-wrap: wrap;
127
+ align-items: flex-end;
128
+ gap: var(--umds-primitive-spacing-nano); /* 8px */
129
+ padding: var(--umds-primitive-spacing-nano) var(--umds-primitive-spacing-mini); /* 8px 12px */
130
+ background: var(--umds-semantic-color-background-light);
131
+ border-bottom: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-color-neutral-light-medium);
132
+ }
133
+
134
+ .umds-rte__link-field {
135
+ flex: 1 1 var(--umds-primitive-spacing-giant);
136
+ min-width: 0;
137
+ }
138
+
139
+ .umds-rte__link-actions {
140
+ display: flex;
141
+ align-items: center;
142
+ gap: var(--umds-primitive-spacing-nano); /* 8px */
143
+ }
144
+
145
+ .umds-rte__table-field {
146
+ flex: 0 1 var(--umds-primitive-spacing-xxxl); /* 120px */
147
+ min-width: 0;
148
+ }
149
+
150
+ .umds-rte__style-field {
151
+ flex: 0 1 auto;
152
+ min-width: 0;
153
+ }
154
+
155
+ /* Barra de linha e coluna: aparece com o cursor numa célula. */
156
+ .umds-rte__table-bar {
157
+ display: flex;
158
+ flex-wrap: wrap;
159
+ align-items: center;
160
+ gap: var(--umds-primitive-spacing-quarck); /* 4px */
161
+ padding: var(--umds-primitive-spacing-quarck) var(--umds-primitive-spacing-nano); /* 4px 8px */
162
+ background: var(--umds-semantic-color-background-light);
163
+ border-bottom: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-color-neutral-light-medium);
164
+ }
165
+
166
+ /* ── Área de escrita ── */
167
+ .umds-rte__editor {
168
+ box-sizing: border-box;
169
+ min-height: var(--umds-primitive-spacing-xxxl); /* 120px */
170
+ padding: var(--umds-primitive-spacing-mini) var(--umds-primitive-spacing-xxxs); /* 12px 16px */
171
+ font-size: var(--umds-semantic-field-text-size); /* 14px */
172
+ line-height: var(--umds-primitive-font-line-height-lg);
173
+ color: var(--umds-semantic-field-text-color);
174
+ outline: none;
175
+ overflow-wrap: anywhere;
176
+ overflow-y: auto;
177
+ }
178
+
179
+ .umds-rte--resizable .umds-rte__editor {
180
+ resize: vertical;
181
+ }
182
+
183
+ /* Placeholder: o :empty some assim que há conteúdo (o JS limpa o <br> que sobra). */
184
+ .umds-rte__editor:empty::before {
185
+ content: attr(data-placeholder);
186
+ color: var(--umds-semantic-field-placeholder-color);
187
+ pointer-events: none;
188
+ }
189
+
190
+ .umds-rte__editor ul,
191
+ .umds-rte__editor ol {
192
+ margin: var(--umds-primitive-spacing-quarck) 0;
193
+ padding-left: var(--umds-primitive-spacing-xxs); /* 24px */
194
+ }
195
+
196
+ .umds-rte__editor p,
197
+ .umds-rte__editor blockquote {
198
+ margin: 0 0 var(--umds-primitive-spacing-nano);
199
+ }
200
+
201
+ .umds-rte__editor blockquote {
202
+ padding-left: var(--umds-primitive-spacing-mini);
203
+ border-left: var(--umds-primitive-border-width-thin) solid var(--umds-semantic-color-neutral-light-down);
204
+ color: var(--umds-semantic-color-neutral-dark-down);
205
+ }
206
+
207
+ .umds-rte__editor img {
208
+ max-width: 100%;
209
+ height: auto;
210
+ }
211
+
212
+ .umds-rte__editor table {
213
+ width: 100%;
214
+ margin: var(--umds-primitive-spacing-nano) 0;
215
+ border-collapse: collapse;
216
+ table-layout: fixed;
217
+ }
218
+
219
+ .umds-rte__editor th,
220
+ .umds-rte__editor td {
221
+ min-width: var(--umds-primitive-spacing-sm); /* 40px: a célula vazia continua alcançável */
222
+ padding: var(--umds-primitive-spacing-quarck) var(--umds-primitive-spacing-nano); /* 4px 8px */
223
+ border: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-color-neutral-light-down);
224
+ vertical-align: top;
225
+ text-align: left;
226
+ }
227
+
228
+ .umds-rte__editor th {
229
+ background: var(--umds-semantic-color-background-light);
230
+ font-weight: var(--umds-primitive-font-weight-semibold);
231
+ }
232
+
233
+ .umds-rte__editor a {
234
+ color: var(--umds-semantic-color-primary-pure);
235
+ text-decoration: underline;
236
+ }
237
+
238
+ .umds-rte__footer {
239
+ padding: var(--umds-primitive-spacing-nano) var(--umds-primitive-spacing-xxxs); /* 8px 16px */
240
+ border-top: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-color-neutral-light-medium);
241
+ background: var(--umds-semantic-color-background-light);
242
+ font-size: var(--umds-primitive-font-size-xxs); /* 14px */
243
+ color: var(--umds-semantic-color-neutral-dark-down);
244
+ }
245
+
246
+ @media (forced-colors: active) {
247
+ .umds-rte__tool--active {
248
+ outline: var(--umds-primitive-border-width-thin) solid Highlight;
249
+ }
250
+ }
@@ -0,0 +1,97 @@
1
+ import './RichTextEditor.css';
2
+ /** Ferramentas da barra, na ordem em que aparecem em `toolbar`. `"|"` é um separador. */
3
+ export type RichTextTool = "bold" | "italic" | "underline" | "strike" | "ul" | "ol" | "link" | "undo" | "redo" | "clear" | "alignLeft" | "alignCenter" | "alignRight" | "alignJustify" | "image" | "table" | "fontFamily" | "fontSize" | "textColor" | "|";
4
+ /**
5
+ * RichTextEditor — editor de texto rico leve, sobre `contenteditable`, sem
6
+ * biblioteca: negrito, itálico, sublinhado, tachado, listas, link, desfazer e
7
+ * refazer, e limpar formatação.
8
+ *
9
+ * O valor é HTML (`value`/`defaultValue`/`onChange`) e SEMPRE passa por uma
10
+ * higienização: só ficam negrito, itálico, sublinhado, tachado, listas,
11
+ * parágrafos, quebras, títulos, citação e link; o resto (`script`, `style`,
12
+ * `onerror`, `class`, `javascript:`) sai, tanto do `value` que entra quanto do
13
+ * que se cola (colar entra como texto puro). Link só aceita `http(s)`, `mailto`,
14
+ * `tel`, caminho e âncora.
15
+ *
16
+ * A barra é um `role="toolbar"` com Tab numa parada só e setas entre as
17
+ * ferramentas; negrito, itálico, sublinhado, tachado e as listas são botões de
18
+ * liga/desliga (`aria-pressed`) que seguem a posição do cursor. Os atalhos do
19
+ * navegador (Ctrl+B, Ctrl+I, Ctrl+U, Ctrl+Z) valem, e Ctrl+K abre o link. O
20
+ * botão de link abre um campo logo abaixo da barra (endereço, aplicar, remover,
21
+ * cancelar), sem modal.
22
+ *
23
+ * A barra se escolhe por `toolbar`: a completa é o padrão; `["bold", "italic",
24
+ * "underline", "ul", "ol", "link"]` é a compacta; `["bold", "italic"]`, a mínima.
25
+ * O rodapé aceita o slot `footer` (a assinatura do autor, por exemplo) e a área
26
+ * pode ser redimensionável (`resizable`).
27
+ *
28
+ * Todos os textos são props (`labels`, `toolbarLabel`, `placeholder`).
29
+ *
30
+ * Opcionais na `toolbar` (fora da barra padrão): alinhamento (`alignLeft`,
31
+ * `alignCenter`, `alignRight`, `alignJustify`), imagem (`image`: por endereço ou por
32
+ * arquivo, que entra como `data:` URL, com texto alternativo) e tabela simples
33
+ * (`table`: insere linhas × colunas; com o cursor numa célula aparece a barra de
34
+ * adicionar e remover linha e coluna). Imagem e tabela passam pela mesma
35
+ * higienização: só PNG, JPEG, GIF e WebP em `data:`, ou `http(s)`; sem SVG.
36
+ *
37
+ * Estilo de texto por TOKEN do DS, também opcional na `toolbar`: `fontFamily`
38
+ * (padrão ou monoespaçada), `fontSize` (12, 14, 16, 20 e 24px, da escala do DS) e
39
+ * `textColor` (a paleta do DS). Cada um abre um painel abaixo da barra e aplica ao
40
+ * texto selecionado (sem seleção, o painel pede que se selecione). O valor guarda
41
+ * `<span style="color: var(--umds-primitive-red-pure)">`: só token do DS passa na
42
+ * higienização, cor em hex, rgb ou nome sai. Para voltar ao padrão, use `clear`.
43
+ *
44
+ * Limites: usa `document.execCommand`, que o
45
+ * navegador mantém mas está marcado como obsoleto (o comportamento do desfazer
46
+ * varia um pouco entre navegadores; adicionar e remover linha ou coluna mexe no
47
+ * DOM e não entra no desfazer). Imagem de arquivo passa de 2 MB? Recusada: o HTML
48
+ * do valor guarda a imagem inteira.
49
+ * @property {string} value - HTML (controlado)
50
+ * @property {string} defaultValue - HTML inicial (não controlado)
51
+ * @property {string} label - Rótulo visível do campo
52
+ * @property {string} ariaLabel - Nome acessível quando não há `label` visível
53
+ * @property {string} placeholder - Texto de apoio com o editor vazio
54
+ * @property {string[]} toolbar - Ferramentas da barra, em ordem: 'bold' | 'italic' | 'underline' | 'strike' | 'ul' | 'ol' | 'link' | 'undo' | 'redo' | 'clear' | 'alignLeft' | 'alignCenter' | 'alignRight' | 'alignJustify' | 'image' | 'table' | 'fontFamily' | 'fontSize' | 'textColor' | '|' (separador)
55
+ * @property {string} toolbarLabel - Nome da barra (padrão "Formatação")
56
+ * @property {object} labels - Nomes das ferramentas e dos campos, parcial: `{ bold, italic, underline, strike, ul, ol, link, undo, redo, clear, alignLeft, alignCenter, alignRight, alignJustify, image, table, linkAddress, linkApply, linkRemove, linkCancel, linkInvalid, imageUrl, imageAlt, imageFile, imageApply, imageCancel, imageInvalid, imageType, imageTooLarge, tableRows, tableCols, tableApply, tableCancel, tableInvalid, tableActions, tableAddRow, tableRemoveRow, tableAddCol, tableRemoveCol, tableRemove, fontFamily, fontSize, textColor, fontFamilyBase, fontFamilyMono, styleClose, styleNeedsSelection }`
57
+ * @property {number} minHeight - Altura mínima da área de escrita, em px (padrão 120)
58
+ * @property {boolean} resizable - Deixa redimensionar a altura pelo canto
59
+ * @property {boolean} disabled - Desabilita barra e área
60
+ * @property {boolean} readOnly - Só leitura: a área não edita e a barra some
61
+ * @property {boolean} invalid - Estado de erro
62
+ * @property {string} errorMessage - Mensagem de erro (liga o estado de erro)
63
+ * @property {string} helperText - Texto de ajuda abaixo do campo
64
+ * @property {string} id - Base dos ids internos; passe em SSR para os ids já saírem no HTML do servidor
65
+ * @property {string} className - Classes CSS adicionais
66
+ * @property {function} onChange - Chamado com o HTML a cada edição
67
+ * @property {function} onBlur - Chamado quando o foco sai da área de escrita
68
+ * @slot footer - Rodapé dentro da moldura, abaixo da área de escrita (assinatura).
69
+ * @quandoUsar Texto formatado que vira conteúdo de documento: despacho, resposta, descrição de serviço, modelo de texto.
70
+ * @quandoNaoUsar Para texto simples de várias linhas, use `Textarea`. Para texto de uma linha, `Input`. Quando for preciso tabela, imagem, cor ou fonte, este corte não serve: peça ao DS ou use um editor especializado.
71
+ */
72
+ /** Ferramentas da barra, na ordem em que aparecem em `toolbar`. `"|"` é um separador. */
73
+ export interface RichTextEditorProps {
74
+ value?: string;
75
+ defaultValue?: string;
76
+ label?: string;
77
+ ariaLabel?: string;
78
+ placeholder?: string;
79
+ toolbar?: RichTextTool[];
80
+ toolbarLabel?: string;
81
+ labels?: Record<string, string>;
82
+ minHeight?: number;
83
+ resizable?: boolean;
84
+ disabled?: boolean;
85
+ readOnly?: boolean;
86
+ invalid?: boolean;
87
+ errorMessage?: string;
88
+ helperText?: string;
89
+ id?: string;
90
+ className?: string;
91
+ /** Slot `footer`: abaixo da área de escrita. */
92
+ footer?: any;
93
+ onChange?: (html: string) => void;
94
+ onBlur?: (event?: any) => void;
95
+ }
96
+ declare function RichTextEditor(props: RichTextEditorProps): import("react/jsx-runtime").JSX.Element;
97
+ export default RichTextEditor;