@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,951 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import './RichTextEditor.css';
4
+ import * as React from "react";
5
+ import { useState, useRef, useEffect } from "react";
6
+ import { faBold, faItalic, faUnderline, faStrikethrough, faListUl, faListOl, faLink, faRotateLeft, faRotateRight, faEraser, faAlignLeft, faAlignCenter, faAlignRight, faAlignJustify, faImage, faTable, faFont, faTextHeight, faPalette, } from "@fortawesome/free-solid-svg-icons";
7
+ import Button from "../Button/Button";
8
+ import ColorPicker from "../ColorPicker/ColorPicker";
9
+ import Select from "../Select/Select";
10
+ import Icon from "../Icon/Icon";
11
+ import Input from "../Input/Input";
12
+ import Text from "../Text/Text";
13
+ import { gerarId } from "../../utils/id";
14
+ import { htmlDaImagem, htmlDaTabela, htmlDoLink, estiloDeTexto, htmlVazio, imagemSegura, normalizarEndereco, sanitizarHtml, } from "../../utils/html-seguro";
15
+ function RichTextEditor(props) {
16
+ const editorRef = useRef(null);
17
+ const toolbarRef = useRef(null);
18
+ const linkInputWrapRef = useRef(null);
19
+ const ultimoEmitidoRef = useRef("");
20
+ const selecaoRef = useRef(null);
21
+ const focoPendenteRef = useRef("");
22
+ const observadorRef = useRef(null);
23
+ const imageInputWrapRef = useRef(null);
24
+ const tableInputWrapRef = useRef(null);
25
+ const fileInputRef = useRef(null);
26
+ const celulaRef = useRef(null);
27
+ const styleWrapRef = useRef(null);
28
+ const [uid, setUid] = useState(() => "");
29
+ const [linkOpen, setLinkOpen] = useState(() => false);
30
+ const [linkUrl, setLinkUrl] = useState(() => "");
31
+ const [linkError, setLinkError] = useState(() => false);
32
+ const [toolFocus, setToolFocus] = useState(() => 0);
33
+ const [active, setActive] = useState(() => "");
34
+ const [styleOpen, setStyleOpen] = useState(() => "");
35
+ const [styleError, setStyleError] = useState(() => false);
36
+ const [imageOpen, setImageOpen] = useState(() => false);
37
+ const [imgUrl, setImgUrl] = useState(() => "");
38
+ const [imgAlt, setImgAlt] = useState(() => "");
39
+ const [imgData, setImgData] = useState(() => "");
40
+ const [imgFileName, setImgFileName] = useState(() => "");
41
+ const [imgError, setImgError] = useState(() => "");
42
+ const [tableOpen, setTableOpen] = useState(() => false);
43
+ const [tblRows, setTblRows] = useState(() => "3");
44
+ const [tblCols, setTblCols] = useState(() => "3");
45
+ const [tblError, setTblError] = useState(() => false);
46
+ const [inTable, setInTable] = useState(() => false);
47
+ function baseId() {
48
+ return props.id || uid;
49
+ }
50
+ function labelId() {
51
+ return baseId() && props.label ? baseId() + "-label" : undefined;
52
+ }
53
+ function editorId() {
54
+ return baseId() ? baseId() + "-editor" : undefined;
55
+ }
56
+ function errorId() {
57
+ return baseId() && props.errorMessage ? baseId() + "-error" : undefined;
58
+ }
59
+ function helperId() {
60
+ return baseId() && props.helperText ? baseId() + "-helper" : undefined;
61
+ }
62
+ function describedBy() {
63
+ const ids = [errorId(), helperId()].filter(Boolean).join(" ");
64
+ return ids || undefined;
65
+ }
66
+ function editorAriaLabel() {
67
+ if (props.ariaLabel)
68
+ return props.ariaLabel;
69
+ return props.label && !labelId() ? props.label : undefined;
70
+ }
71
+ function isInvalid() {
72
+ return !!props.invalid || !!props.errorMessage;
73
+ }
74
+ function isEditable() {
75
+ return !props.disabled && !props.readOnly;
76
+ }
77
+ function editableText() {
78
+ return isEditable() ? "true" : "false";
79
+ }
80
+ function showToolbar() {
81
+ return !props.readOnly;
82
+ }
83
+ function classes() {
84
+ return [
85
+ "umds-rte",
86
+ isInvalid() ? "umds-rte--invalid" : "",
87
+ props.disabled ? "umds-rte--disabled" : "",
88
+ props.readOnly ? "umds-rte--readonly" : "",
89
+ props.resizable ? "umds-rte--resizable" : "",
90
+ props.className,
91
+ ]
92
+ .filter(Boolean)
93
+ .join(" ");
94
+ }
95
+ function editorStyle() {
96
+ const altura = props.minHeight !== undefined && props.minHeight !== null
97
+ ? props.minHeight
98
+ : 0;
99
+ return altura
100
+ ? {
101
+ minHeight: altura + "px",
102
+ }
103
+ : undefined;
104
+ }
105
+ function rotulo(chave) {
106
+ const padrao = {
107
+ bold: "Negrito",
108
+ italic: "Itálico",
109
+ underline: "Sublinhado",
110
+ strike: "Tachado",
111
+ ul: "Lista com marcadores",
112
+ ol: "Lista numerada",
113
+ link: "Link",
114
+ undo: "Desfazer",
115
+ redo: "Refazer",
116
+ clear: "Limpar formatação",
117
+ linkAddress: "Endereço do link",
118
+ linkApply: "Aplicar",
119
+ linkRemove: "Remover link",
120
+ linkCancel: "Cancelar",
121
+ linkInvalid: "Use um endereço http, https, mailto ou tel.",
122
+ alignLeft: "Alinhar à esquerda",
123
+ alignCenter: "Centralizar",
124
+ alignRight: "Alinhar à direita",
125
+ alignJustify: "Justificar",
126
+ image: "Imagem",
127
+ table: "Tabela",
128
+ imageUrl: "Endereço da imagem",
129
+ imageAlt: "Texto alternativo",
130
+ imageFile: "Escolher arquivo",
131
+ imageApply: "Inserir imagem",
132
+ imageCancel: "Cancelar",
133
+ imageInvalid: "Use um endereço http ou https, ou escolha um arquivo.",
134
+ imageType: "Use uma imagem PNG, JPEG, GIF ou WebP.",
135
+ imageTooLarge: "A imagem passa de 2 MB.",
136
+ tableRows: "Linhas",
137
+ tableCols: "Colunas",
138
+ tableApply: "Inserir tabela",
139
+ tableCancel: "Cancelar",
140
+ tableInvalid: "Use de 1 a 20 linhas e de 1 a 10 colunas.",
141
+ tableActions: "Tabela",
142
+ tableAddRow: "Adicionar linha",
143
+ tableRemoveRow: "Remover linha",
144
+ tableAddCol: "Adicionar coluna",
145
+ tableRemoveCol: "Remover coluna",
146
+ tableRemove: "Remover tabela",
147
+ fontFamily: "Fonte",
148
+ fontSize: "Tamanho da fonte",
149
+ textColor: "Cor do texto",
150
+ fontFamilyBase: "Padrão",
151
+ fontFamilyMono: "Monoespaçada",
152
+ styleClose: "Fechar",
153
+ styleNeedsSelection: "Selecione o texto antes de aplicar.",
154
+ };
155
+ const dado = props.labels || {};
156
+ return dado[chave] || padrao[chave];
157
+ }
158
+ function toolbarName() {
159
+ return props.toolbarLabel || "Formatação";
160
+ }
161
+ function tools() {
162
+ const padrao = [
163
+ "bold",
164
+ "italic",
165
+ "underline",
166
+ "|",
167
+ "ul",
168
+ "ol",
169
+ "|",
170
+ "link",
171
+ "|",
172
+ "undo",
173
+ "redo",
174
+ ];
175
+ const lista = props.toolbar && props.toolbar.length ? props.toolbar : padrao;
176
+ const catalogo = {
177
+ bold: {
178
+ command: "bold",
179
+ icon: faBold,
180
+ toggle: true,
181
+ },
182
+ italic: {
183
+ command: "italic",
184
+ icon: faItalic,
185
+ toggle: true,
186
+ },
187
+ underline: {
188
+ command: "underline",
189
+ icon: faUnderline,
190
+ toggle: true,
191
+ },
192
+ strike: {
193
+ command: "strikeThrough",
194
+ icon: faStrikethrough,
195
+ toggle: true,
196
+ },
197
+ ul: {
198
+ command: "insertUnorderedList",
199
+ icon: faListUl,
200
+ toggle: true,
201
+ },
202
+ ol: {
203
+ command: "insertOrderedList",
204
+ icon: faListOl,
205
+ toggle: true,
206
+ },
207
+ link: {
208
+ command: "link",
209
+ icon: faLink,
210
+ toggle: false,
211
+ },
212
+ undo: {
213
+ command: "undo",
214
+ icon: faRotateLeft,
215
+ toggle: false,
216
+ },
217
+ redo: {
218
+ command: "redo",
219
+ icon: faRotateRight,
220
+ toggle: false,
221
+ },
222
+ clear: {
223
+ command: "removeFormat",
224
+ icon: faEraser,
225
+ toggle: false,
226
+ },
227
+ alignLeft: {
228
+ command: "justifyLeft",
229
+ icon: faAlignLeft,
230
+ toggle: true,
231
+ },
232
+ alignCenter: {
233
+ command: "justifyCenter",
234
+ icon: faAlignCenter,
235
+ toggle: true,
236
+ },
237
+ alignRight: {
238
+ command: "justifyRight",
239
+ icon: faAlignRight,
240
+ toggle: true,
241
+ },
242
+ alignJustify: {
243
+ command: "justifyFull",
244
+ icon: faAlignJustify,
245
+ toggle: true,
246
+ },
247
+ image: {
248
+ command: "image",
249
+ icon: faImage,
250
+ toggle: false,
251
+ },
252
+ table: {
253
+ command: "table",
254
+ icon: faTable,
255
+ toggle: false,
256
+ },
257
+ fontFamily: {
258
+ command: "fontFamily",
259
+ icon: faFont,
260
+ toggle: false,
261
+ },
262
+ fontSize: {
263
+ command: "fontSize",
264
+ icon: faTextHeight,
265
+ toggle: false,
266
+ },
267
+ textColor: {
268
+ command: "textColor",
269
+ icon: faPalette,
270
+ toggle: false,
271
+ },
272
+ };
273
+ const saida = [];
274
+ let posicao = 0;
275
+ for (let i = 0; i < lista.length; i++) {
276
+ const chave = lista[i];
277
+ if (chave === "|") {
278
+ saida.push({
279
+ key: "sep-" + i,
280
+ separator: true,
281
+ });
282
+ continue;
283
+ }
284
+ const def = catalogo[chave];
285
+ if (!def)
286
+ continue;
287
+ saida.push({
288
+ key: chave,
289
+ separator: false,
290
+ command: def.command,
291
+ icon: def.icon,
292
+ toggle: def.toggle,
293
+ position: posicao,
294
+ label: rotulo(chave),
295
+ });
296
+ posicao = posicao + 1;
297
+ }
298
+ return saida;
299
+ }
300
+ function estaAtiva(ferramenta) {
301
+ return (!!ferramenta.toggle &&
302
+ active.split(",").indexOf(ferramenta.command) !== -1);
303
+ }
304
+ function pressedText(ferramenta) {
305
+ return ferramenta.toggle
306
+ ? estaAtiva(ferramenta)
307
+ ? "true"
308
+ : "false"
309
+ : undefined;
310
+ }
311
+ function toolClasses(ferramenta) {
312
+ return [
313
+ "umds-rte__tool",
314
+ estaAtiva(ferramenta) ? "umds-rte__tool--active" : "",
315
+ ]
316
+ .filter(Boolean)
317
+ .join(" ");
318
+ }
319
+ function toolTabIndex(ferramenta) {
320
+ return ferramenta.position === toolFocus ? 0 : -1;
321
+ }
322
+ function escreverHtml(html) {
323
+ if (!editorRef.current)
324
+ return;
325
+ const limpo = sanitizarHtml(html || "");
326
+ if (editorRef.current.innerHTML !== limpo)
327
+ editorRef.current.innerHTML = limpo;
328
+ }
329
+ function selecaoNaArea() {
330
+ if (typeof window === "undefined" ||
331
+ !window.getSelection ||
332
+ !editorRef.current)
333
+ return false;
334
+ const selecao = window.getSelection();
335
+ return (!!selecao &&
336
+ selecao.rangeCount > 0 &&
337
+ editorRef.current.contains(selecao.anchorNode));
338
+ }
339
+ function celulaAtual() {
340
+ if (typeof window === "undefined" ||
341
+ !window.getSelection ||
342
+ !editorRef.current)
343
+ return null;
344
+ const selecao = window.getSelection();
345
+ if (!selecao || selecao.rangeCount === 0)
346
+ return null;
347
+ const no = selecao.anchorNode;
348
+ const elemento = no && no.nodeType === 3 ? no.parentNode : no;
349
+ const celula = elemento && elemento.closest ? elemento.closest("td, th") : null;
350
+ return celula && editorRef.current.contains(celula) ? celula : null;
351
+ }
352
+ function lerEstados() {
353
+ if (typeof document === "undefined" ||
354
+ typeof document.queryCommandState !== "function")
355
+ return;
356
+ if (!selecaoNaArea())
357
+ return;
358
+ celulaRef.current = celulaAtual();
359
+ const dentro = !!celulaRef.current;
360
+ if (dentro !== inTable)
361
+ setInTable(dentro);
362
+ const comandos = [
363
+ "bold",
364
+ "italic",
365
+ "underline",
366
+ "strikeThrough",
367
+ "insertUnorderedList",
368
+ "insertOrderedList",
369
+ "justifyLeft",
370
+ "justifyCenter",
371
+ "justifyRight",
372
+ "justifyFull",
373
+ ];
374
+ const ligados = [];
375
+ for (let i = 0; i < comandos.length; i++) {
376
+ try {
377
+ if (document.queryCommandState(comandos[i]))
378
+ ligados.push(comandos[i]);
379
+ }
380
+ catch (erro) {
381
+ // O navegador não conhece o comando: fica desligado.
382
+ }
383
+ }
384
+ const texto = ligados.join(",");
385
+ if (texto !== active)
386
+ setActive(texto);
387
+ }
388
+ function emitir() {
389
+ if (!editorRef.current)
390
+ return;
391
+ let html = editorRef.current.innerHTML;
392
+ // Apagou tudo: o navegador deixa um <br> e o placeholder (que é :empty) não volta.
393
+ if (htmlVazio(html)) {
394
+ html = "";
395
+ if (editorRef.current.innerHTML !== "" &&
396
+ editorRef.current.querySelector("li") === null)
397
+ editorRef.current.innerHTML = "";
398
+ }
399
+ ultimoEmitidoRef.current = html;
400
+ if (props.onChange)
401
+ props.onChange(html);
402
+ }
403
+ function handleInput() {
404
+ emitir();
405
+ lerEstados();
406
+ }
407
+ function handlePaste(event) {
408
+ if (!event || !event.clipboardData)
409
+ return;
410
+ // Colar entra como texto puro: sem formatação de outro site e sem HTML estranho.
411
+ event.preventDefault();
412
+ const texto = event.clipboardData.getData("text/plain");
413
+ if (texto && typeof document !== "undefined")
414
+ document.execCommand("insertText", false, texto);
415
+ }
416
+ function handleEditorKeyDown(event) {
417
+ if (!event)
418
+ return;
419
+ if ((event.ctrlKey || event.metaKey) &&
420
+ !event.altKey &&
421
+ (event.key === "k" || event.key === "K")) {
422
+ event.preventDefault();
423
+ abrirLink();
424
+ }
425
+ }
426
+ function handleBlur(event) {
427
+ if (props.onBlur)
428
+ props.onBlur(event);
429
+ }
430
+ function handleToolMouseDown(event) {
431
+ if (event && event.preventDefault)
432
+ event.preventDefault();
433
+ }
434
+ function handleToolClick(ferramenta) {
435
+ if (!isEditable() || typeof document === "undefined")
436
+ return;
437
+ if (ferramenta.command === "link") {
438
+ abrirLink();
439
+ return;
440
+ }
441
+ if (ferramenta.command === "image") {
442
+ abrirImagem();
443
+ return;
444
+ }
445
+ if (ferramenta.command === "table") {
446
+ abrirTabela();
447
+ return;
448
+ }
449
+ if (ferramenta.command === "fontFamily" ||
450
+ ferramenta.command === "fontSize" ||
451
+ ferramenta.command === "textColor") {
452
+ abrirEstilo(ferramenta.command);
453
+ return;
454
+ }
455
+ if (editorRef.current && !selecaoNaArea())
456
+ editorRef.current.focus();
457
+ document.execCommand(ferramenta.command, false, undefined);
458
+ handleInput();
459
+ }
460
+ function handleToolFocus(ferramenta) {
461
+ if (toolFocus !== ferramenta.position)
462
+ setToolFocus(ferramenta.position);
463
+ }
464
+ function handleToolbarKeyDown(event) {
465
+ if (!event || !toolbarRef.current)
466
+ return;
467
+ const tecla = event.key;
468
+ if (tecla !== "ArrowRight" &&
469
+ tecla !== "ArrowLeft" &&
470
+ tecla !== "Home" &&
471
+ tecla !== "End")
472
+ return;
473
+ const botoes = toolbarRef.current.querySelectorAll("button");
474
+ const total = botoes.length;
475
+ if (!total)
476
+ return;
477
+ let atual = toolFocus;
478
+ if (tecla === "ArrowRight")
479
+ atual = (atual + 1) % total;
480
+ else if (tecla === "ArrowLeft")
481
+ atual = (atual - 1 + total) % total;
482
+ else if (tecla === "Home")
483
+ atual = 0;
484
+ else
485
+ atual = total - 1;
486
+ event.preventDefault();
487
+ setToolFocus(atual);
488
+ botoes[atual].focus();
489
+ }
490
+ function abrirLink() {
491
+ if (!isEditable() || typeof window === "undefined" || linkOpen)
492
+ return;
493
+ let enderecoAtual = "";
494
+ selecaoRef.current = null;
495
+ if (selecaoNaArea()) {
496
+ const selecao = window.getSelection();
497
+ selecaoRef.current = selecao.getRangeAt(0).cloneRange();
498
+ const no = selecao.anchorNode;
499
+ const elemento = no && no.nodeType === 3 ? no.parentNode : no;
500
+ const ancora = elemento && elemento.closest ? elemento.closest("a") : null;
501
+ if (ancora)
502
+ enderecoAtual = ancora.getAttribute("href") || "";
503
+ }
504
+ setLinkUrl(enderecoAtual);
505
+ setLinkError(false);
506
+ setImageOpen(false);
507
+ setTableOpen(false);
508
+ setStyleOpen("");
509
+ setLinkOpen(true);
510
+ focoPendenteRef.current = "link";
511
+ }
512
+ function fecharLink() {
513
+ setLinkOpen(false);
514
+ setLinkError(false);
515
+ focoPendenteRef.current = "editor";
516
+ }
517
+ function restaurarSelecao() {
518
+ if (typeof window === "undefined" || !window.getSelection)
519
+ return;
520
+ if (editorRef.current)
521
+ editorRef.current.focus();
522
+ if (selecaoRef.current) {
523
+ const selecao = window.getSelection();
524
+ selecao.removeAllRanges();
525
+ selecao.addRange(selecaoRef.current);
526
+ }
527
+ }
528
+ function handleLinkInput(texto) {
529
+ setLinkUrl(texto);
530
+ if (linkError)
531
+ setLinkError(false);
532
+ }
533
+ function aplicarLink() {
534
+ if (typeof document === "undefined")
535
+ return;
536
+ const endereco = normalizarEndereco(linkUrl);
537
+ if (!endereco) {
538
+ setLinkError(true);
539
+ return;
540
+ }
541
+ restaurarSelecao();
542
+ const selecao = window.getSelection();
543
+ const semTexto = !!selecao && selecao.isCollapsed;
544
+ // Sem texto escolhido, o próprio endereço vira o texto do link.
545
+ const comando = semTexto ? "insertHTML" : "createLink";
546
+ const argumento = semTexto ? htmlDoLink(endereco) : endereco;
547
+ document.execCommand(comando, false, argumento);
548
+ setLinkOpen(false);
549
+ focoPendenteRef.current = "editor";
550
+ handleInput();
551
+ }
552
+ function removerLink() {
553
+ if (typeof document === "undefined")
554
+ return;
555
+ restaurarSelecao();
556
+ document.execCommand("unlink", false, undefined);
557
+ setLinkOpen(false);
558
+ focoPendenteRef.current = "editor";
559
+ handleInput();
560
+ }
561
+ function handleLinkSubmit(event) {
562
+ if (event && event.preventDefault)
563
+ event.preventDefault();
564
+ aplicarLink();
565
+ }
566
+ function handleLinkKeyDown(event) {
567
+ if (event && event.key === "Escape") {
568
+ event.preventDefault();
569
+ event.stopPropagation();
570
+ fecharLink();
571
+ }
572
+ }
573
+ function guardarSelecao() {
574
+ selecaoRef.current = null;
575
+ if (selecaoNaArea() && typeof window !== "undefined") {
576
+ const selecao = window.getSelection();
577
+ selecaoRef.current = selecao.getRangeAt(0).cloneRange();
578
+ }
579
+ }
580
+ function abrirImagem() {
581
+ if (!isEditable() || typeof window === "undefined" || imageOpen)
582
+ return;
583
+ guardarSelecao();
584
+ setImgUrl("");
585
+ setImgAlt("");
586
+ setImgData("");
587
+ setImgFileName("");
588
+ setImgError("");
589
+ setLinkOpen(false);
590
+ setTableOpen(false);
591
+ setStyleOpen("");
592
+ setImageOpen(true);
593
+ focoPendenteRef.current = "image";
594
+ }
595
+ function fecharImagem() {
596
+ setImageOpen(false);
597
+ setImgError("");
598
+ focoPendenteRef.current = "editor";
599
+ }
600
+ function handleImageUrl(texto) {
601
+ setImgUrl(texto);
602
+ setImgData("");
603
+ setImgFileName("");
604
+ if (imgError)
605
+ setImgError("");
606
+ }
607
+ function handleImageAlt(texto) {
608
+ setImgAlt(texto);
609
+ }
610
+ function escolherArquivo() {
611
+ if (fileInputRef.current)
612
+ fileInputRef.current.click();
613
+ }
614
+ function handleArquivo(event) {
615
+ const alvo = event && event.target ? event.target : null;
616
+ const arquivo = alvo && alvo.files ? alvo.files[0] : null;
617
+ if (!arquivo)
618
+ return;
619
+ if (!/^image\/(png|jpe?g|gif|webp)$/i.test(String(arquivo.type))) {
620
+ setImgError("type");
621
+ return;
622
+ }
623
+ if (arquivo.size > 2 * 1024 * 1024) {
624
+ setImgError("size");
625
+ return;
626
+ }
627
+ const leitor = new FileReader();
628
+ leitor.onload = () => {
629
+ setImgData(String(leitor.result || ""));
630
+ setImgFileName(arquivo.name);
631
+ setImgUrl("");
632
+ setImgError("");
633
+ };
634
+ leitor.readAsDataURL(arquivo);
635
+ }
636
+ function aplicarImagem() {
637
+ if (typeof document === "undefined")
638
+ return;
639
+ const origem = imagemSegura(imgData || normalizarEndereco(imgUrl));
640
+ if (!origem) {
641
+ setImgError("invalid");
642
+ return;
643
+ }
644
+ restaurarSelecao();
645
+ document.execCommand("insertHTML", false, htmlDaImagem(origem, imgAlt));
646
+ setImageOpen(false);
647
+ focoPendenteRef.current = "editor";
648
+ handleInput();
649
+ }
650
+ function handleImageSubmit(event) {
651
+ if (event && event.preventDefault)
652
+ event.preventDefault();
653
+ aplicarImagem();
654
+ }
655
+ function handlePanelKeyDown(event) {
656
+ if (!event || event.key !== "Escape")
657
+ return;
658
+ event.preventDefault();
659
+ event.stopPropagation();
660
+ if (imageOpen)
661
+ fecharImagem();
662
+ else
663
+ fecharTabela();
664
+ }
665
+ function imageErrorText() {
666
+ if (imgError === "invalid")
667
+ return rotulo("imageInvalid");
668
+ if (imgError === "type")
669
+ return rotulo("imageType");
670
+ if (imgError === "size")
671
+ return rotulo("imageTooLarge");
672
+ return undefined;
673
+ }
674
+ function abrirTabela() {
675
+ if (!isEditable() || typeof window === "undefined" || tableOpen)
676
+ return;
677
+ guardarSelecao();
678
+ setTblError(false);
679
+ setLinkOpen(false);
680
+ setImageOpen(false);
681
+ setStyleOpen("");
682
+ setTableOpen(true);
683
+ focoPendenteRef.current = "table";
684
+ }
685
+ function fecharTabela() {
686
+ setTableOpen(false);
687
+ setTblError(false);
688
+ focoPendenteRef.current = "editor";
689
+ }
690
+ function handleTableRows(texto) {
691
+ setTblRows(texto);
692
+ if (tblError)
693
+ setTblError(false);
694
+ }
695
+ function handleTableCols(texto) {
696
+ setTblCols(texto);
697
+ if (tblError)
698
+ setTblError(false);
699
+ }
700
+ function aplicarTabela() {
701
+ if (typeof document === "undefined")
702
+ return;
703
+ const linhas = parseInt(tblRows, 10);
704
+ const colunas = parseInt(tblCols, 10);
705
+ if (!(linhas >= 1 && linhas <= 20 && colunas >= 1 && colunas <= 10)) {
706
+ setTblError(true);
707
+ return;
708
+ }
709
+ restaurarSelecao();
710
+ document.execCommand("insertHTML", false, htmlDaTabela(linhas, colunas));
711
+ setTableOpen(false);
712
+ focoPendenteRef.current = "editor";
713
+ handleInput();
714
+ }
715
+ function handleTableSubmit(event) {
716
+ if (event && event.preventDefault)
717
+ event.preventDefault();
718
+ aplicarTabela();
719
+ }
720
+ function tableErrorText() {
721
+ return tblError ? rotulo("tableInvalid") : undefined;
722
+ }
723
+ function tableBarVisible() {
724
+ if (!inTable || !isEditable())
725
+ return false;
726
+ const lista = props.toolbar || [];
727
+ return lista.indexOf("table") !== -1;
728
+ }
729
+ function handleTableAction(acao) {
730
+ const celula = celulaRef.current;
731
+ if (!celula || !editorRef.current || !editorRef.current.contains(celula))
732
+ return;
733
+ const linha = celula.parentNode;
734
+ const tabela = celula.closest("table");
735
+ if (!linha || !tabela)
736
+ return;
737
+ const indice = celula.cellIndex;
738
+ const linhas = Array.prototype.slice.call(tabela.rows);
739
+ const nova = (tag) => {
740
+ const c = document.createElement(tag);
741
+ c.appendChild(document.createElement("br"));
742
+ return c;
743
+ };
744
+ if (acao === "addRow") {
745
+ const novaLinha = document.createElement("tr");
746
+ for (let i = 0; i < linha.cells.length; i++)
747
+ novaLinha.appendChild(nova("td"));
748
+ linha.parentNode.insertBefore(novaLinha, linha.nextSibling);
749
+ }
750
+ else if (acao === "removeRow") {
751
+ if (linhas.length <= 1)
752
+ tabela.parentNode.removeChild(tabela);
753
+ else
754
+ linha.parentNode.removeChild(linha);
755
+ }
756
+ else if (acao === "addCol") {
757
+ for (let i = 0; i < linhas.length; i++) {
758
+ const ref = linhas[i].cells[indice];
759
+ const tag = ref && ref.tagName === "TH" ? "th" : "td";
760
+ const novaCelula = nova(tag);
761
+ if (ref)
762
+ linhas[i].insertBefore(novaCelula, ref.nextSibling);
763
+ else
764
+ linhas[i].appendChild(novaCelula);
765
+ }
766
+ }
767
+ else if (acao === "removeCol") {
768
+ if (linha.cells.length <= 1)
769
+ tabela.parentNode.removeChild(tabela);
770
+ else {
771
+ for (let i = 0; i < linhas.length; i++) {
772
+ const ref = linhas[i].cells[indice];
773
+ if (ref)
774
+ linhas[i].removeChild(ref);
775
+ }
776
+ }
777
+ }
778
+ else if (acao === "removeTable") {
779
+ tabela.parentNode.removeChild(tabela);
780
+ }
781
+ celulaRef.current = null;
782
+ setInTable(false);
783
+ handleInput();
784
+ if (editorRef.current)
785
+ editorRef.current.focus();
786
+ }
787
+ function fontFamilyOptions() {
788
+ return [
789
+ {
790
+ label: rotulo("fontFamilyBase"),
791
+ value: "var(--umds-semantic-font-family-base)",
792
+ },
793
+ {
794
+ label: rotulo("fontFamilyMono"),
795
+ value: "var(--umds-semantic-font-family-mono)",
796
+ },
797
+ ];
798
+ }
799
+ function fontSizeOptions() {
800
+ return [
801
+ {
802
+ label: "12",
803
+ value: "var(--umds-primitive-font-size-xxxs)",
804
+ },
805
+ {
806
+ label: "14",
807
+ value: "var(--umds-primitive-font-size-xxs)",
808
+ },
809
+ {
810
+ label: "16",
811
+ value: "var(--umds-primitive-font-size-xs)",
812
+ },
813
+ {
814
+ label: "20",
815
+ value: "var(--umds-primitive-font-size-sm)",
816
+ },
817
+ {
818
+ label: "24",
819
+ value: "var(--umds-primitive-font-size-md)",
820
+ },
821
+ ];
822
+ }
823
+ function abrirEstilo(qual) {
824
+ if (!isEditable() || typeof window === "undefined")
825
+ return;
826
+ guardarSelecao();
827
+ setStyleError(false);
828
+ setLinkOpen(false);
829
+ setImageOpen(false);
830
+ setTableOpen(false);
831
+ setStyleOpen(qual);
832
+ focoPendenteRef.current = "style";
833
+ }
834
+ function fecharEstilo() {
835
+ setStyleOpen("");
836
+ setStyleError(false);
837
+ focoPendenteRef.current = "editor";
838
+ }
839
+ function aplicarEstilo(propriedade, valor) {
840
+ if (typeof document === "undefined" || typeof window === "undefined")
841
+ return;
842
+ const declaracao = estiloDeTexto(propriedade, valor);
843
+ if (!declaracao)
844
+ return;
845
+ restaurarSelecao();
846
+ const selecao = window.getSelection();
847
+ if (!selecao || selecao.rangeCount === 0 || selecao.isCollapsed) {
848
+ setStyleError(true);
849
+ return;
850
+ }
851
+ const molde = document.createElement("div");
852
+ molde.appendChild(selecao.getRangeAt(0).cloneContents());
853
+ document.execCommand("insertHTML", false, '<span style="' + declaracao + '">' + molde.innerHTML + "</span>");
854
+ setStyleOpen("");
855
+ setStyleError(false);
856
+ focoPendenteRef.current = "editor";
857
+ handleInput();
858
+ }
859
+ function aplicarCor(token) {
860
+ if (!token || token.indexOf("--") !== 0)
861
+ return;
862
+ aplicarEstilo("color", "var(" + token + ")");
863
+ }
864
+ function handleStyleKeyDown(event) {
865
+ if (!event || event.key !== "Escape")
866
+ return;
867
+ // O Select aberto já tratou o Esc (fechou a lista e deu preventDefault): o painel fica para o próximo.
868
+ if (event.defaultPrevented)
869
+ return;
870
+ event.preventDefault();
871
+ event.stopPropagation();
872
+ fecharEstilo();
873
+ }
874
+ function styleErrorText() {
875
+ return styleError ? rotulo("styleNeedsSelection") : undefined;
876
+ }
877
+ function stylePanelLabel() {
878
+ return styleOpen ? rotulo(styleOpen) : "";
879
+ }
880
+ function linkErrorText() {
881
+ return linkError ? rotulo("linkInvalid") : undefined;
882
+ }
883
+ function linkRemoveVisible() {
884
+ return linkUrl !== "";
885
+ }
886
+ useEffect(() => {
887
+ setUid(gerarId("umds-rte"));
888
+ const inicial = props.value !== undefined ? props.value : props.defaultValue || "";
889
+ escreverHtml(inicial);
890
+ ultimoEmitidoRef.current = htmlVazio(inicial)
891
+ ? ""
892
+ : editorRef.current
893
+ ? editorRef.current.innerHTML
894
+ : "";
895
+ if (typeof document !== "undefined") {
896
+ const aoMudarSelecao = () => lerEstados();
897
+ document.addEventListener("selectionchange", aoMudarSelecao);
898
+ observadorRef.current = () => document.removeEventListener("selectionchange", aoMudarSelecao);
899
+ }
900
+ }, []);
901
+ useEffect(() => {
902
+ // `value` de fora diferente do que a área tem: reescreve (reset do formulário, valor vindo do servidor).
903
+ if (props.value !== undefined &&
904
+ editorRef.current &&
905
+ props.value !== ultimoEmitidoRef.current) {
906
+ const limpo = sanitizarHtml(props.value);
907
+ if (editorRef.current.innerHTML !== limpo &&
908
+ !(htmlVazio(limpo) && htmlVazio(editorRef.current.innerHTML))) {
909
+ editorRef.current.innerHTML = limpo;
910
+ }
911
+ ultimoEmitidoRef.current = props.value;
912
+ }
913
+ if (focoPendenteRef.current) {
914
+ const alvo = focoPendenteRef.current;
915
+ focoPendenteRef.current = "";
916
+ if (alvo === "editor" && editorRef.current) {
917
+ restaurarSelecao();
918
+ }
919
+ else if (alvo === "link" && linkInputWrapRef.current) {
920
+ const campo = linkInputWrapRef.current.querySelector("input");
921
+ if (campo)
922
+ campo.focus();
923
+ }
924
+ else if (alvo === "image" && imageInputWrapRef.current) {
925
+ const campo = imageInputWrapRef.current.querySelector("input");
926
+ if (campo)
927
+ campo.focus();
928
+ }
929
+ else if (alvo === "table" && tableInputWrapRef.current) {
930
+ const campo = tableInputWrapRef.current.querySelector("input");
931
+ if (campo)
932
+ campo.focus();
933
+ }
934
+ else if (alvo === "style" && styleWrapRef.current) {
935
+ const campo = styleWrapRef.current.querySelector('[role="combobox"], [role="radio"], button');
936
+ if (campo)
937
+ campo.focus();
938
+ }
939
+ }
940
+ });
941
+ useEffect(() => {
942
+ return () => {
943
+ if (observadorRef.current) {
944
+ observadorRef.current();
945
+ observadorRef.current = null;
946
+ }
947
+ };
948
+ }, []);
949
+ return (_jsxs("div", { className: classes(), children: [props.label ? (_jsx("span", { className: "umds-rte__label", id: labelId(), children: props.label })) : null, _jsxs("div", { className: "umds-rte__frame", children: [showToolbar() ? (_jsx("div", { role: "toolbar", className: "umds-rte__toolbar", ref: toolbarRef, "aria-label": toolbarName(), "aria-controls": editorId(), onKeyDown: (event) => handleToolbarKeyDown(event), children: tools()?.map((ferramenta) => (_jsxs(React.Fragment, { children: [ferramenta.separator ? (_jsx("span", { role: "separator", "aria-orientation": "vertical", className: "umds-rte__separator" })) : null, !ferramenta.separator ? (_jsx("button", { type: "button", "aria-label": ferramenta.label, title: ferramenta.label, "aria-pressed": pressedText(ferramenta), tabIndex: toolTabIndex(ferramenta), disabled: !isEditable(), onMouseDown: (event) => handleToolMouseDown(event), onClick: (event) => handleToolClick(ferramenta), onFocus: (event) => handleToolFocus(ferramenta), className: toolClasses(ferramenta), children: _jsx(Icon, { size: "sm", variant: "inherit", icon: ferramenta.icon }) })) : null] }, ferramenta.key))) })) : null, linkOpen ? (_jsxs("form", { className: "umds-rte__link", noValidate: true, onSubmit: (event) => handleLinkSubmit(event), onKeyDown: (event) => handleLinkKeyDown(event), children: [_jsx("div", { className: "umds-rte__link-field", ref: linkInputWrapRef, children: _jsx(Input, { size: "sm", type: "url", placeholder: "https://", label: rotulo("linkAddress"), value: linkUrl, errorMessage: linkErrorText(), onChange: (texto) => handleLinkInput(texto) }) }), _jsxs("div", { className: "umds-rte__link-actions", children: [_jsx(Button, { variant: "primary", size: "sm", type: "submit", children: rotulo("linkApply") }), linkRemoveVisible() ? (_jsx(Button, { variant: "secondary", size: "sm", onClick: (event) => removerLink(), children: rotulo("linkRemove") })) : null, _jsx(Button, { variant: "text", size: "sm", onClick: (event) => fecharLink(), children: rotulo("linkCancel") })] })] })) : null, imageOpen ? (_jsxs("form", { className: "umds-rte__link", noValidate: true, onSubmit: (event) => handleImageSubmit(event), onKeyDown: (event) => handlePanelKeyDown(event), children: [_jsx("div", { className: "umds-rte__link-field", ref: imageInputWrapRef, children: _jsx(Input, { size: "sm", type: "url", placeholder: "https://", label: rotulo("imageUrl"), value: imgUrl, errorMessage: imageErrorText(), onChange: (texto) => handleImageUrl(texto) }) }), _jsx("div", { className: "umds-rte__link-field", children: _jsx(Input, { size: "sm", label: rotulo("imageAlt"), value: imgAlt, onChange: (texto) => handleImageAlt(texto) }) }), _jsxs("div", { className: "umds-rte__link-actions", children: [_jsx(Button, { variant: "secondary", size: "sm", onClick: (event) => escolherArquivo(), children: rotulo("imageFile") }), _jsx("input", { type: "file", accept: "image/png,image/jpeg,image/gif,image/webp", ref: fileInputRef, hidden: true, onChange: (event) => handleArquivo(event) }), imgFileName ? (_jsx(Text, { as: "span", variant: "caption", color: "secondary", children: imgFileName })) : null, _jsx(Button, { variant: "primary", size: "sm", type: "submit", children: rotulo("imageApply") }), _jsx(Button, { variant: "text", size: "sm", onClick: (event) => fecharImagem(), children: rotulo("imageCancel") })] })] })) : null, tableOpen ? (_jsxs("form", { className: "umds-rte__link", noValidate: true, onSubmit: (event) => handleTableSubmit(event), onKeyDown: (event) => handlePanelKeyDown(event), children: [_jsx("div", { className: "umds-rte__table-field", ref: tableInputWrapRef, children: _jsx(Input, { size: "sm", type: "number", label: rotulo("tableRows"), value: tblRows, errorMessage: tableErrorText(), onChange: (texto) => handleTableRows(texto) }) }), _jsx("div", { className: "umds-rte__table-field", children: _jsx(Input, { size: "sm", type: "number", label: rotulo("tableCols"), value: tblCols, onChange: (texto) => handleTableCols(texto) }) }), _jsxs("div", { className: "umds-rte__link-actions", children: [_jsx(Button, { variant: "primary", size: "sm", type: "submit", children: rotulo("tableApply") }), _jsx(Button, { variant: "text", size: "sm", onClick: (event) => fecharTabela(), children: rotulo("tableCancel") })] })] })) : null, styleOpen !== "" ? (_jsxs("div", { role: "group", className: "umds-rte__link", "aria-label": stylePanelLabel(), onKeyDown: (event) => handleStyleKeyDown(event), children: [_jsxs("div", { className: "umds-rte__style-field", ref: styleWrapRef, children: [styleOpen === "fontFamily" ? (_jsx(Select, { size: "sm", ariaLabel: rotulo("fontFamily"), placeholder: rotulo("fontFamily"), options: fontFamilyOptions(), onChange: (valor) => aplicarEstilo("font-family", String(valor)) })) : null, styleOpen === "fontSize" ? (_jsx(Select, { size: "sm", ariaLabel: rotulo("fontSize"), placeholder: rotulo("fontSize"), options: fontSizeOptions(), onChange: (valor) => aplicarEstilo("font-size", String(valor)) })) : null, styleOpen === "textColor" ? (_jsx(ColorPicker, { size: "xs", ariaLabel: rotulo("textColor"), onChange: (token) => aplicarCor(token) })) : null] }), _jsx("div", { className: "umds-rte__link-actions", children: _jsx(Button, { variant: "text", size: "sm", onClick: (event) => fecharEstilo(), children: rotulo("styleClose") }) }), styleErrorText() ? (_jsx(Text, { as: "span", variant: "caption", color: "negative", role: "alert", children: styleErrorText() })) : null] })) : null, tableBarVisible() ? (_jsxs("div", { role: "group", className: "umds-rte__table-bar", "aria-label": rotulo("tableActions"), children: [_jsx(Button, { variant: "text", size: "sm", onClick: (event) => handleTableAction("addRow"), children: rotulo("tableAddRow") }), _jsx(Button, { variant: "text", size: "sm", onClick: (event) => handleTableAction("removeRow"), children: rotulo("tableRemoveRow") }), _jsx(Button, { variant: "text", size: "sm", onClick: (event) => handleTableAction("addCol"), children: rotulo("tableAddCol") }), _jsx(Button, { variant: "text", size: "sm", onClick: (event) => handleTableAction("removeCol"), children: rotulo("tableRemoveCol") }), _jsx(Button, { variant: "text", size: "sm", onClick: (event) => handleTableAction("removeTable"), children: rotulo("tableRemove") })] })) : null, _jsx("div", { role: "textbox", "aria-multiline": "true", className: "umds-rte__editor", ref: editorRef, id: editorId(), "aria-label": editorAriaLabel(), "aria-labelledby": labelId(), "aria-describedby": describedBy(), "aria-invalid": isInvalid() ? "true" : undefined, "aria-readonly": props.readOnly ? "true" : undefined, "aria-disabled": props.disabled ? "true" : undefined, "aria-placeholder": props.placeholder, "data-placeholder": props.placeholder, contentEditable: editableText(), tabIndex: props.disabled ? -1 : 0, style: editorStyle(), onInput: (event) => handleInput(), onPaste: (event) => handlePaste(event), onKeyDown: (event) => handleEditorKeyDown(event), onBlur: (event) => handleBlur(event) }), props.footer ? (_jsx("div", { className: "umds-rte__footer", children: _jsx(_Fragment, { children: props.footer }) })) : null] }), props.errorMessage ? (_jsx(Text, { as: "span", variant: "caption", color: "negative", id: errorId(), children: props.errorMessage })) : null, props.helperText ? (_jsx(Text, { as: "span", variant: "caption", color: "secondary", id: helperId(), children: props.helperText })) : null] }));
950
+ }
951
+ export default RichTextEditor;