@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,85 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { render } from "@testing-library/react";
3
+ import Badge from "../components/Badge/Badge";
4
+ import Tag from "../components/Tag/Tag";
5
+
6
+ const raiz = (c: HTMLElement) => c.firstElementChild as HTMLElement;
7
+
8
+ describe("Badge compacto, novidade e colado", () => {
9
+ it("size 2xs escreve a classe; sem size continua md", () => {
10
+ const { container } = render(
11
+ <>
12
+ <Badge size="2xs">A</Badge>
13
+ <Badge>B</Badge>
14
+ </>,
15
+ );
16
+ expect(container.children[0]).toHaveClass("umds-badge--2xs");
17
+ expect(container.children[1]).toHaveClass("umds-badge--md");
18
+ });
19
+
20
+ it("variant new escreve a classe da variante", () => {
21
+ const { container } = render(<Badge variant="new">Novidade</Badge>);
22
+ expect(raiz(container)).toHaveClass("umds-badge--new");
23
+ });
24
+
25
+ it("attached escreve o modificador; sem ele não há", () => {
26
+ const { container } = render(
27
+ <>
28
+ <Badge attached>A</Badge>
29
+ <Badge>B</Badge>
30
+ </>,
31
+ );
32
+ expect(container.children[0]).toHaveClass("umds-badge--attached");
33
+ expect(container.children[1]).not.toHaveClass("umds-badge--attached");
34
+ });
35
+ });
36
+
37
+ describe("Tag compacta, soft, pílula e novidade", () => {
38
+ it("size xs escreve a classe e sm continua", () => {
39
+ const { container } = render(
40
+ <>
41
+ <Tag label="a" size="xs" />
42
+ <Tag label="b" size="sm" />
43
+ </>,
44
+ );
45
+ expect(container.children[0]).toHaveClass("umds-tag--xs");
46
+ expect(container.children[1]).toHaveClass("umds-tag--sm");
47
+ });
48
+
49
+ it("appearance soft e pill escrevem as classes", () => {
50
+ const { container } = render(<Tag label="SOBR" appearance="soft" variant="primary" pill />);
51
+ expect(raiz(container)).toHaveClass("umds-tag--soft", "umds-tag--primary", "umds-tag--pill");
52
+ });
53
+
54
+ it("sem pill não há a classe; padrão segue outlined", () => {
55
+ const { container } = render(<Tag label="x" />);
56
+ expect(raiz(container)).toHaveClass("umds-tag--outlined");
57
+ expect(raiz(container)).not.toHaveClass("umds-tag--pill");
58
+ });
59
+
60
+ it("variant new escreve a classe", () => {
61
+ const { container } = render(<Tag label="Dado simulado" variant="new" appearance="soft" />);
62
+ expect(raiz(container)).toHaveClass("umds-tag--new", "umds-tag--soft");
63
+ });
64
+ });
65
+
66
+ describe("Badge attachedSide", () => {
67
+ it("right escreve o modificador do canto direito; left e o padrão não", () => {
68
+ const { container } = render(
69
+ <>
70
+ <Badge attached attachedSide="right">A</Badge>
71
+ <Badge attached attachedSide="left">B</Badge>
72
+ <Badge attached>C</Badge>
73
+ </>,
74
+ );
75
+ expect(container.children[0]).toHaveClass("umds-badge--attached", "umds-badge--attached-right");
76
+ expect(container.children[1]).not.toHaveClass("umds-badge--attached-right");
77
+ expect(container.children[2]).not.toHaveClass("umds-badge--attached-right");
78
+ });
79
+
80
+ it("attachedSide sem attached não faz nada", () => {
81
+ const { container } = render(<Badge attachedSide="right">A</Badge>);
82
+ expect(raiz(container)).not.toHaveClass("umds-badge--attached-right");
83
+ expect(raiz(container)).not.toHaveClass("umds-badge--attached");
84
+ });
85
+ });
@@ -0,0 +1,81 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { fireEvent, render, screen } from "@testing-library/react";
3
+ import Box from "../components/Box/Box";
4
+
5
+ describe("Box como item flex e com `as`", () => {
6
+ it("sem `as` continua um div", () => {
7
+ const { container } = render(<Box padding="md">x</Box>);
8
+ expect(container.firstElementChild?.tagName).toBe("DIV");
9
+ });
10
+
11
+ for (const tag of ["div", "span", "ul", "ol", "li", "section", "nav", "header", "footer", "form"]) {
12
+ it(`as="${tag}" renderiza <${tag}> e só ele`, () => {
13
+ const { container } = render(<Box as={tag as any}>x</Box>);
14
+ expect(container.firstElementChild?.tagName).toBe(tag.toUpperCase());
15
+ expect(container.children).toHaveLength(1);
16
+ });
17
+ }
18
+
19
+ it("ul e ol mantêm a semântica de lista (role=list)", () => {
20
+ render(
21
+ <>
22
+ <Box as="ul" aria-label="Itens">
23
+ <Box as="li">a</Box>
24
+ </Box>
25
+ <Box as="ol" aria-label="Passos">
26
+ <Box as="li">b</Box>
27
+ </Box>
28
+ </>,
29
+ );
30
+ expect(screen.getByRole("list", { name: "Itens" }).tagName).toBe("UL");
31
+ expect(screen.getByRole("list", { name: "Passos" }).tagName).toBe("OL");
32
+ });
33
+
34
+ it("nav com aria-label vira região de navegação nomeada", () => {
35
+ render(
36
+ <Box as="nav" aria-label="Atalhos">
37
+ x
38
+ </Box>,
39
+ );
40
+ expect(screen.getByRole("navigation", { name: "Atalhos" })).toBeInTheDocument();
41
+ });
42
+
43
+ it("as=form chama onSubmit", () => {
44
+ const aoEnviar = vi.fn((e: Event) => e.preventDefault());
45
+ const { container } = render(
46
+ <Box as="form" onSubmit={aoEnviar}>
47
+ <button type="submit">Enviar</button>
48
+ </Box>,
49
+ );
50
+ fireEvent.submit(container.querySelector("form") as HTMLFormElement);
51
+ expect(aoEnviar).toHaveBeenCalledTimes(1);
52
+ });
53
+
54
+ it("escreve as classes de item flex", () => {
55
+ const { container } = render(
56
+ <Box grow shrink="0" basis="50" minWidth="auto" overflow="hidden" overflowX="auto" overflowY="scroll" fullHeight fullWidth>
57
+ x
58
+ </Box>,
59
+ );
60
+ const el = container.firstElementChild as HTMLElement;
61
+ for (const c of [
62
+ "umds-box--grow",
63
+ "umds-box--shrink-0",
64
+ "umds-box--basis-50",
65
+ "umds-box--min-w-auto",
66
+ "umds-box--overflow-hidden",
67
+ "umds-box--overflow-x-auto",
68
+ "umds-box--overflow-y-scroll",
69
+ "umds-box--full-height",
70
+ "umds-box--full",
71
+ ]) {
72
+ expect(el).toHaveClass(c);
73
+ }
74
+ });
75
+
76
+ it("sem as props de item não escreve nenhuma classe delas", () => {
77
+ const { container } = render(<Box padding="md">x</Box>);
78
+ const classes = (container.firstElementChild as HTMLElement).className;
79
+ expect(classes).not.toMatch(/grow|shrink|basis|min-w|overflow|full-height/);
80
+ });
81
+ });
@@ -0,0 +1,50 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { render, screen } from "@testing-library/react";
3
+ import Box from "../components/Box/Box";
4
+
5
+ describe("Box de layout", () => {
6
+ it("sem props de layout não vira flex", () => {
7
+ const { container } = render(
8
+ <Box padding="md" bordered>
9
+ x
10
+ </Box>,
11
+ );
12
+ expect(container.firstElementChild).not.toHaveClass("umds-box--flex");
13
+ });
14
+
15
+ it("com direction, gap, align, justify e wrap vira flex", () => {
16
+ const { container } = render(
17
+ <Box direction="horizontal" gap="xxxs" align="center" justify="between" wrap padding="md">
18
+ x
19
+ </Box>,
20
+ );
21
+ const el = container.firstElementChild as HTMLElement;
22
+ for (const c of [
23
+ "umds-box--flex",
24
+ "umds-box--horizontal",
25
+ "umds-box--gap-xxxs",
26
+ "umds-box--align-center",
27
+ "umds-box--justify-between",
28
+ "umds-box--wrap",
29
+ "umds-box--p-md",
30
+ ]) {
31
+ expect(el).toHaveClass(c);
32
+ }
33
+ });
34
+
35
+ it("só com gap vira flex vertical", () => {
36
+ const { container } = render(<Box gap="xs">x</Box>);
37
+ expect(container.firstElementChild).toHaveClass("umds-box--flex", "umds-box--vertical");
38
+ });
39
+
40
+ it("repassa id, role, aria-label e style", () => {
41
+ render(
42
+ <Box id="r" role="region" aria-label="Resumo" style={{ marginTop: 4 }}>
43
+ x
44
+ </Box>,
45
+ );
46
+ const el = screen.getByRole("region", { name: "Resumo" });
47
+ expect(el.id).toBe("r");
48
+ expect(el.style.marginTop).toBe("4px");
49
+ });
50
+ });
@@ -0,0 +1,39 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { render, screen } from "@testing-library/react";
3
+ import { faPlus } from "@fortawesome/free-solid-svg-icons";
4
+ import Button from "../components/Button/Button";
5
+
6
+ describe("Button: variante neutral-text e tamanho xs", () => {
7
+ it("neutral-text escreve a classe da variante", () => {
8
+ render(<Button variant="neutral-text">Simular</Button>);
9
+ expect(screen.getByRole("button", { name: "Simular" })).toHaveClass("umds-button--neutral-text");
10
+ });
11
+
12
+ it("neutral continua sendo o contornado cinza", () => {
13
+ render(<Button variant="neutral">Ordenar</Button>);
14
+ const botao = screen.getByRole("button", { name: "Ordenar" });
15
+ expect(botao).toHaveClass("umds-button--neutral");
16
+ expect(botao).not.toHaveClass("umds-button--neutral-text");
17
+ });
18
+
19
+ it("size xs escreve a classe e o botão sem size continua md", () => {
20
+ render(
21
+ <>
22
+ <Button size="xs">Resolver</Button>
23
+ <Button>Padrão</Button>
24
+ </>,
25
+ );
26
+ expect(screen.getByRole("button", { name: "Resolver" })).toHaveClass("umds-button--xs");
27
+ expect(screen.getByRole("button", { name: "Padrão" })).toHaveClass("umds-button--md");
28
+ });
29
+
30
+ it("no xs o ícone usa o tamanho sm do Icon (o CSS do botão o reduz)", () => {
31
+ const { container } = render(
32
+ <Button size="xs" startIcon={faPlus}>
33
+ Novo
34
+ </Button>,
35
+ );
36
+ expect(container.querySelector(".umds-icon")).toHaveClass("umds-icon--sm");
37
+ expect(container.querySelector(".umds-icon--xs")).toBeNull();
38
+ });
39
+ });
@@ -0,0 +1,282 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { useState } from "react";
3
+ import { render, screen, within } from "@testing-library/react";
4
+ import userEvent from "@testing-library/user-event";
5
+ import Calendar from "../components/Calendar/Calendar";
6
+
7
+ const HOJE = "2026-05-15";
8
+ const EVENTOS = [
9
+ { id: "a", date: "2026-05-04", title: "Proc. Administrativo 002/2020", color: "--umds-primitive-blue-pure" },
10
+ { id: "b", date: "2026-05-11", title: "Protocolo 005/2020", color: "--umds-primitive-green-pure", time: "09:00" },
11
+ { id: "c", date: "2026-05-11", title: "Ofício 001/2020", color: "--umds-primitive-red-pure", time: "08:00" },
12
+ { id: "d1", date: "2026-05-20", title: "Reunião 1" },
13
+ { id: "d2", date: "2026-05-20", title: "Reunião 2" },
14
+ { id: "d3", date: "2026-05-20", title: "Reunião 3" },
15
+ { id: "d4", date: "2026-05-20", title: "Reunião 4" },
16
+ { id: "d5", date: "2026-05-20", title: "Reunião 5" },
17
+ ];
18
+
19
+ const celula = (container: HTMLElement, iso: string) => container.querySelector(`[data-date="${iso}"]`) as HTMLElement;
20
+
21
+ describe("Calendar", () => {
22
+ it("é uma grade nomeada pelo mês, com sete cabeçalhos de dia", () => {
23
+ render(<Calendar today={HOJE} defaultDate={HOJE} />);
24
+ expect(screen.getByRole("grid", { name: "Maio 2026" })).toBeInTheDocument();
25
+ const cabecalhos = screen.getAllByRole("columnheader");
26
+ expect(cabecalhos).toHaveLength(7);
27
+ expect(cabecalhos[0]).toHaveAccessibleName("Domingo");
28
+ expect(screen.getByText("Maio 2026")).toBeInTheDocument();
29
+ });
30
+
31
+ it("o mês de maio de 2026 ocupa seis semanas inteiras; dias de fora ganham a classe", () => {
32
+ const { container } = render(<Calendar today={HOJE} defaultDate={HOJE} />);
33
+ expect(container.querySelectorAll('[role="gridcell"]')).toHaveLength(42);
34
+ expect(celula(container, "2026-04-26")).toHaveClass("umds-calendar__cell--outside");
35
+ expect(celula(container, "2026-05-15")).not.toHaveClass("umds-calendar__cell--outside");
36
+ });
37
+
38
+ it("hoje é marcado com aria-current", () => {
39
+ const { container } = render(<Calendar today={HOJE} defaultDate={HOJE} />);
40
+ expect(celula(container, HOJE)).toHaveAttribute("aria-current", "date");
41
+ expect(celula(container, "2026-05-16")).not.toHaveAttribute("aria-current");
42
+ });
43
+
44
+ it("cada dia tem nome acessível com a data e a contagem de eventos", () => {
45
+ const { container } = render(<Calendar today={HOJE} defaultDate={HOJE} events={EVENTOS} />);
46
+ expect(celula(container, "2026-05-11")).toHaveAttribute("aria-label", "segunda-feira, 11 de maio de 2026, 2 eventos");
47
+ expect(celula(container, "2026-05-04")).toHaveAttribute("aria-label", "segunda-feira, 4 de maio de 2026, 1 evento");
48
+ expect(celula(container, "2026-05-12")).toHaveAttribute("aria-label", "terça-feira, 12 de maio de 2026, sem eventos");
49
+ });
50
+
51
+ it("dayLabel troca o nome do dia", () => {
52
+ const { container } = render(<Calendar today={HOJE} defaultDate={HOJE} dayLabel={(iso, n) => `${iso}:${n}`} events={EVENTOS} />);
53
+ expect(celula(container, "2026-05-11")).toHaveAttribute("aria-label", "2026-05-11:2");
54
+ });
55
+
56
+ it("os eventos caem no dia certo, em ordem de horário, com a cor do dado", () => {
57
+ const { container } = render(<Calendar today={HOJE} defaultDate={HOJE} events={EVENTOS} />);
58
+ const dia = celula(container, "2026-05-11");
59
+ const chips = within(dia).getAllByRole("button");
60
+ expect(chips).toHaveLength(2);
61
+ expect(chips[0]).toHaveTextContent("08:00");
62
+ expect(chips[0]).toHaveTextContent("Ofício 001/2020");
63
+ expect((chips[0] as HTMLElement).style.borderLeftColor).toBe("var(--umds-primitive-red-pure)");
64
+ });
65
+
66
+ it("evento sem cor usa o primário", () => {
67
+ const { container } = render(<Calendar today={HOJE} defaultDate={HOJE} events={EVENTOS} />);
68
+ const chip = within(celula(container, "2026-05-20")).getAllByRole("button")[0] as HTMLElement;
69
+ expect(chip.style.borderLeftColor).toBe("var(--umds-semantic-color-primary-pure)");
70
+ });
71
+
72
+ it("passou de maxVisible: mostra três e um +N, que avisa com os escondidos", async () => {
73
+ const usuario = userEvent.setup();
74
+ const aoVerMais = vi.fn();
75
+ const { container } = render(<Calendar today={HOJE} defaultDate={HOJE} events={EVENTOS} onMoreClick={aoVerMais} />);
76
+ const dia = celula(container, "2026-05-20");
77
+ expect(within(dia).getAllByText(/Reunião/)).toHaveLength(3);
78
+ const mais = within(dia).getByRole("button", { name: "2 eventos a mais em 20 de maio" });
79
+ expect(mais).toHaveTextContent("+2");
80
+ await usuario.click(mais);
81
+ expect(aoVerMais).toHaveBeenCalledTimes(1);
82
+ expect(aoVerMais.mock.calls[0][0]).toBe("2026-05-20");
83
+ expect(aoVerMais.mock.calls[0][1].map((e: any) => e.id)).toEqual(["d4", "d5"]);
84
+ });
85
+
86
+ it("maxVisible muda o corte", () => {
87
+ const { container } = render(<Calendar today={HOJE} defaultDate={HOJE} events={EVENTOS} maxVisible={1} />);
88
+ expect(within(celula(container, "2026-05-20")).getAllByText(/Reunião/)).toHaveLength(1);
89
+ expect(within(celula(container, "2026-05-20")).getByText("+4")).toBeInTheDocument();
90
+ });
91
+
92
+ it("clicar no evento avisa com o evento e não clica no dia", async () => {
93
+ const usuario = userEvent.setup();
94
+ const aoEvento = vi.fn();
95
+ const aoDia = vi.fn();
96
+ render(<Calendar today={HOJE} defaultDate={HOJE} events={EVENTOS} onEventClick={aoEvento} onDayClick={aoDia} />);
97
+ await usuario.click(screen.getByRole("button", { name: /Proc\. Administrativo 002\/2020/ }));
98
+ expect(aoEvento).toHaveBeenCalledWith(expect.objectContaining({ id: "a" }));
99
+ expect(aoDia).not.toHaveBeenCalled();
100
+ });
101
+
102
+ it("clicar no dia avisa com o ISO", async () => {
103
+ const usuario = userEvent.setup();
104
+ const aoDia = vi.fn();
105
+ const { container } = render(<Calendar today={HOJE} defaultDate={HOJE} onDayClick={aoDia} />);
106
+ await usuario.click(celula(container, "2026-05-12"));
107
+ expect(aoDia).toHaveBeenCalledWith("2026-05-12");
108
+ });
109
+
110
+ it("anterior, próximo e hoje navegam e avisam em onDateChange", async () => {
111
+ const usuario = userEvent.setup();
112
+ const aoMudar = vi.fn();
113
+ render(<Calendar today={HOJE} defaultDate={HOJE} onDateChange={aoMudar} />);
114
+ await usuario.click(screen.getByRole("button", { name: "Próximo" }));
115
+ expect(screen.getByText("Junho 2026")).toBeInTheDocument();
116
+ expect(aoMudar).toHaveBeenLastCalledWith("2026-06-15");
117
+ await usuario.click(screen.getByRole("button", { name: "Anterior" }));
118
+ await usuario.click(screen.getByRole("button", { name: "Anterior" }));
119
+ expect(screen.getByText("Abril 2026")).toBeInTheDocument();
120
+ await usuario.click(screen.getByRole("button", { name: "Hoje" }));
121
+ expect(screen.getByText("Maio 2026")).toBeInTheDocument();
122
+ expect(aoMudar).toHaveBeenLastCalledWith(HOJE);
123
+ });
124
+
125
+ it("só um dia entra na ordem de Tab (hoje), com os eventos dele", () => {
126
+ const { container } = render(<Calendar today="2026-05-11" defaultDate="2026-05-11" events={EVENTOS} />);
127
+ const comTab = [...container.querySelectorAll('[role="gridcell"]')].filter((c) => c.getAttribute("tabindex") === "0");
128
+ expect(comTab).toHaveLength(1);
129
+ expect(comTab[0]).toHaveAttribute("data-date", "2026-05-11");
130
+ const chipsComTab = [...container.querySelectorAll(".umds-calendar__event")].filter((c) => c.getAttribute("tabindex") === "0");
131
+ expect(chipsComTab).toHaveLength(2);
132
+ });
133
+
134
+ it("setas movem o foco entre os dias; Home, End e Enter", async () => {
135
+ const usuario = userEvent.setup();
136
+ const aoDia = vi.fn();
137
+ const { container } = render(<Calendar today={HOJE} defaultDate={HOJE} onDayClick={aoDia} />);
138
+ celula(container, HOJE).focus();
139
+ await usuario.keyboard("{ArrowRight}");
140
+ expect(celula(container, "2026-05-16")).toHaveFocus();
141
+ await usuario.keyboard("{ArrowDown}");
142
+ expect(celula(container, "2026-05-23")).toHaveFocus();
143
+ await usuario.keyboard("{ArrowLeft}{ArrowUp}");
144
+ expect(celula(container, "2026-05-15")).toHaveFocus();
145
+ await usuario.keyboard("{Home}");
146
+ expect(celula(container, "2026-05-10")).toHaveFocus();
147
+ await usuario.keyboard("{End}");
148
+ expect(celula(container, "2026-05-16")).toHaveFocus();
149
+ await usuario.keyboard("{Enter}");
150
+ expect(aoDia).toHaveBeenCalledWith("2026-05-16");
151
+ });
152
+
153
+ it("a seta que sai do mês troca de mês e leva o foco", async () => {
154
+ const usuario = userEvent.setup();
155
+ const { container } = render(<Calendar today={HOJE} defaultDate="2026-05-30" />);
156
+ celula(container, "2026-05-30").focus();
157
+ await usuario.keyboard("{ArrowRight}{ArrowRight}");
158
+ expect(screen.getByText("Junho 2026")).toBeInTheDocument();
159
+ expect(celula(container, "2026-06-01")).toHaveFocus();
160
+ });
161
+
162
+ it("PageDown e PageUp trocam de mês", async () => {
163
+ const usuario = userEvent.setup();
164
+ const { container } = render(<Calendar today={HOJE} defaultDate={HOJE} />);
165
+ celula(container, HOJE).focus();
166
+ await usuario.keyboard("{PageDown}");
167
+ expect(screen.getByText("Junho 2026")).toBeInTheDocument();
168
+ expect(celula(container, "2026-06-15")).toHaveFocus();
169
+ await usuario.keyboard("{PageUp}{PageUp}");
170
+ expect(screen.getByText("Abril 2026")).toBeInTheDocument();
171
+ });
172
+
173
+ it("a visão de semana mostra sete dias, todos os eventos, e avisa em onViewChange", async () => {
174
+ const usuario = userEvent.setup();
175
+ const aoVisao = vi.fn();
176
+ const { container } = render(<Calendar today="2026-05-20" defaultDate="2026-05-20" events={EVENTOS} onViewChange={aoVisao} />);
177
+ await usuario.click(screen.getByRole("radio", { name: "Semana" }));
178
+ expect(aoVisao).toHaveBeenCalledWith("week");
179
+ expect(container.querySelectorAll('[role="gridcell"]')).toHaveLength(7);
180
+ expect(within(celula(container, "2026-05-20")).getAllByText(/Reunião/)).toHaveLength(5);
181
+ expect(screen.queryByText("+2")).toBeNull();
182
+ expect(container.querySelector(".umds-calendar--week")).not.toBeNull();
183
+ });
184
+
185
+ it("na semana, anterior e próximo andam sete dias", async () => {
186
+ const usuario = userEvent.setup();
187
+ const aoMudar = vi.fn();
188
+ render(<Calendar today="2026-05-20" defaultDate="2026-05-20" defaultView="week" onDateChange={aoMudar} />);
189
+ await usuario.click(screen.getByRole("button", { name: "Próximo" }));
190
+ expect(aoMudar).toHaveBeenLastCalledWith("2026-05-27");
191
+ await usuario.click(screen.getByRole("button", { name: "Anterior" }));
192
+ await usuario.click(screen.getByRole("button", { name: "Anterior" }));
193
+ expect(aoMudar).toHaveBeenLastCalledWith("2026-05-13");
194
+ });
195
+
196
+ it("weekStartsOn=1 começa a semana na segunda", () => {
197
+ render(<Calendar today={HOJE} defaultDate={HOJE} weekStartsOn={1} />);
198
+ expect(screen.getAllByRole("columnheader")[0]).toHaveAccessibleName("Segunda-feira");
199
+ });
200
+
201
+ it("controlado: date e view mandam", () => {
202
+ function Pai() {
203
+ const [data, setData] = useState("2026-08-10");
204
+ return <Calendar today={HOJE} date={data} onDateChange={setData} view="month" />;
205
+ }
206
+ render(<Pai />);
207
+ expect(screen.getByText("Agosto 2026")).toBeInTheDocument();
208
+ });
209
+
210
+ it("locale e textos por prop (inglês)", () => {
211
+ render(
212
+ <Calendar
213
+ today={HOJE}
214
+ defaultDate={HOJE}
215
+ locale="en-US"
216
+ previousLabel="Previous"
217
+ nextLabel="Next"
218
+ todayLabel="Today"
219
+ monthLabel="Month"
220
+ weekLabel="Week"
221
+ viewLabel="View"
222
+ />,
223
+ );
224
+ expect(screen.getByText("May 2026")).toBeInTheDocument();
225
+ expect(screen.getByRole("button", { name: "Previous" })).toBeInTheDocument();
226
+ expect(screen.getByRole("button", { name: "Next" })).toBeInTheDocument();
227
+ expect(screen.getByRole("button", { name: "Today" })).toBeInTheDocument();
228
+ expect(screen.getByRole("radio", { name: "Week" })).toBeInTheDocument();
229
+ expect(screen.getByRole("group", { name: "View" })).toBeInTheDocument();
230
+ expect(screen.getAllByRole("columnheader")[0]).toHaveAccessibleName("Sunday");
231
+ });
232
+
233
+ it("moreLabel e moreAriaLabel traduzem o +N", () => {
234
+ render(
235
+ <Calendar
236
+ today={HOJE}
237
+ defaultDate={HOJE}
238
+ events={EVENTOS}
239
+ locale="en-US"
240
+ moreLabel="{count} more"
241
+ moreAriaLabel="{count} more events on {date}"
242
+ />,
243
+ );
244
+ expect(screen.getByRole("button", { name: "2 more events on May 20" })).toHaveTextContent("2 more");
245
+ });
246
+
247
+ it("hideViewSwitcher esconde o seletor; os slots do cabeçalho aparecem", () => {
248
+ render(
249
+ <Calendar
250
+ today={HOJE}
251
+ defaultDate={HOJE}
252
+ hideViewSwitcher
253
+ headerStart={<span data-testid="filtro">Todos os documentos</span>}
254
+ headerEnd={<span data-testid="legenda">Legenda</span>}
255
+ />,
256
+ );
257
+ expect(screen.queryByRole("radio")).toBeNull();
258
+ expect(screen.getByTestId("filtro")).toBeInTheDocument();
259
+ expect(screen.getByTestId("legenda")).toBeInTheDocument();
260
+ });
261
+
262
+ it("selectedDate marca o dia", () => {
263
+ const { container } = render(<Calendar today={HOJE} defaultDate={HOJE} selectedDate="2026-05-12" />);
264
+ expect(celula(container, "2026-05-12")).toHaveAttribute("aria-selected", "true");
265
+ expect(celula(container, "2026-05-12")).toHaveClass("umds-calendar__cell--selected");
266
+ });
267
+
268
+ it("evento com Date e com data-hora entra no dia", () => {
269
+ const { container } = render(
270
+ <Calendar
271
+ today={HOJE}
272
+ defaultDate={HOJE}
273
+ events={[
274
+ { date: new Date(2026, 4, 12), title: "Com Date" },
275
+ { date: "2026-05-13T10:30:00", title: "Com hora" },
276
+ ]}
277
+ />,
278
+ );
279
+ expect(within(celula(container, "2026-05-12")).getByText("Com Date")).toBeInTheDocument();
280
+ expect(within(celula(container, "2026-05-13")).getByText("Com hora")).toBeInTheDocument();
281
+ });
282
+ });
@@ -0,0 +1,11 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { render, screen } from "@testing-library/react";
3
+ import Calendar from "../components/Calendar/Calendar";
4
+
5
+ describe("Calendar · cabeçalho", () => {
6
+ it("headerStart e headerEnd (React: props com nó) chegam ao cabeçalho", () => {
7
+ render(<Calendar events={[]} defaultDate="2026-10-08" headerStart={<span>Todos os documentos</span>} headerEnd={<span>Legenda</span>} />);
8
+ expect(screen.getByText("Todos os documentos")).toBeInTheDocument();
9
+ expect(screen.getByText("Legenda")).toBeInTheDocument();
10
+ });
11
+ });
@@ -0,0 +1,41 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { fireEvent, render, screen } from "@testing-library/react";
3
+ import Chips from "../components/Chips/Chips";
4
+
5
+ const raiz = (c: HTMLElement) => c.firstElementChild as HTMLElement;
6
+
7
+ describe("Chips · xs e × em círculo", () => {
8
+ it("size xs escreve a classe; sem size continua md", () => {
9
+ const { container } = render(
10
+ <>
11
+ <Chips label="a" size="xs" />
12
+ <Chips label="b" />
13
+ </>,
14
+ );
15
+ expect(container.children[0]).toHaveClass("umds-chip--xs");
16
+ expect(container.children[1]).toHaveClass("umds-chip--md");
17
+ });
18
+
19
+ it("circularRemove com removable escreve a classe do círculo", () => {
20
+ const { container } = render(<Chips label="Marcador" removable circularRemove />);
21
+ expect(raiz(container)).toHaveClass("umds-chip--remove-circle");
22
+ });
23
+
24
+ it("circularRemove sem removable não escreve a classe (não há ×)", () => {
25
+ const { container } = render(<Chips label="Marcador" circularRemove />);
26
+ expect(raiz(container)).not.toHaveClass("umds-chip--remove-circle");
27
+ expect(screen.queryByRole("button")).toBeNull();
28
+ });
29
+
30
+ it("o × em círculo continua sendo o mesmo botão, com o mesmo nome e o mesmo clique", () => {
31
+ const aoRemover = vi.fn();
32
+ render(<Chips label="Urgente" size="xs" removable circularRemove onRemove={aoRemover} />);
33
+ fireEvent.click(screen.getByRole("button", { name: "Remover Urgente" }));
34
+ expect(aoRemover).toHaveBeenCalledTimes(1);
35
+ });
36
+
37
+ it("sem circularRemove o chip removível é o de antes", () => {
38
+ const { container } = render(<Chips label="x" removable />);
39
+ expect(raiz(container)).not.toHaveClass("umds-chip--remove-circle");
40
+ });
41
+ });