@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
@@ -186,6 +186,14 @@
186
186
  cursor: default;
187
187
  }
188
188
 
189
+ /* Somente leitura não é desabilitado: o texto segue lido e a WCAG 1.4.3 vale
190
+ sem isenção. O placeholder padrão foi calibrado para fundo branco e cai para
191
+ ~4,2:1 sobre o fundo de somente leitura; neutral-dark-down passa 4,5:1 em
192
+ todos os temas (1doc 6,78:1 · 1doc-dark 10,83:1 · alto contraste 16,48:1). */
193
+ .umds-input--readonly .umds-input__control::placeholder {
194
+ color: var(--umds-semantic-color-neutral-dark-down);
195
+ }
196
+
189
197
  /* ── Ícone esquerdo ── */
190
198
  .umds-input__icon-left {
191
199
  display: flex;
@@ -196,6 +204,20 @@
196
204
  flex-shrink: 0;
197
205
  }
198
206
 
207
+ /* ── Ícone decorativo à direita (iconRight) ── */
208
+ .umds-input__icon-right {
209
+ display: flex;
210
+ align-items: center;
211
+ justify-content: center;
212
+ margin-left: var(--umds-primitive-spacing-nano);
213
+ color: var(--umds-semantic-color-neutral-dark-medium);
214
+ flex-shrink: 0;
215
+ }
216
+
217
+ .umds-input--disabled .umds-input__icon-right {
218
+ color: var(--umds-semantic-color-neutral-dark-up);
219
+ }
220
+
199
221
  /* ── Ações à direita (botões de ícone) ── */
200
222
  .umds-input__actions-right {
201
223
  display: flex;
@@ -235,6 +257,43 @@
235
257
  outline-offset: 0; /* exceção ao offset 2px: o botão vive DENTRO do campo, e o afastamento invadiria a borda */
236
258
  }
237
259
 
260
+ /* ── borderless: o campo dentro de um grupo que já tem a moldura ──
261
+ Sem borda, fundo e raio. O foco NÃO some: o anel do campo vira um contorno
262
+ para dentro (WCAG 2.4.7), e o erro mantém a borda vermelha (a cor do erro não
263
+ pode depender só da moldura do grupo). Sem erro, hover e foco não pintam borda. */
264
+ .umds-input--borderless:not(.umds-input--error) .umds-input__container {
265
+ border-color: transparent;
266
+ border-radius: 0;
267
+ background-color: transparent;
268
+ }
269
+
270
+ .umds-input--borderless .umds-input__container:focus-within:not(.umds-input__container--disabled):not(.umds-input__container--readonly) {
271
+ box-shadow: none;
272
+ outline: 2px solid var(--umds-semantic-color-primary-pure);
273
+ outline-offset: -2px;
274
+ }
275
+
276
+ /* ── grouped: o campo dentro de um contêiner que já tem moldura e foco ──
277
+ O campo de chips: as tags e o input moram na mesma caixa, e quem desenha a moldura
278
+ e o foco (`:focus-within`) é o contêiner. Aqui o campo não impõe altura de campo
279
+ (a linha cresce com as tags), nem padding, nem anel próprio. */
280
+ .umds-input--grouped:not(.umds-input--full-width) {
281
+ width: auto;
282
+ flex: 1 1 var(--umds-primitive-spacing-xxl); /* 80px: o input nunca encolhe a ponto de sumir */
283
+ min-width: 0;
284
+ }
285
+
286
+ .umds-input--grouped .umds-input__container {
287
+ height: auto;
288
+ min-height: 0;
289
+ padding: 0;
290
+ }
291
+
292
+ .umds-input--grouped .umds-input__container:focus-within:not(.umds-input__container--disabled):not(.umds-input__container--readonly) {
293
+ outline: none;
294
+ box-shadow: none;
295
+ }
296
+
238
297
  /* ── Mobile: fonte ≥16px no controle (decisão 25/07) ──
239
298
  Fonte <16px num campo focado dispara zoom automático no Safari iOS.
240
299
  Só abaixo do breakpoint-sm (640px) — desktop permanece idêntico. */
@@ -34,7 +34,11 @@ export interface InputAction {
34
34
  * @property {string} ariaLabel - Nome acessível quando não há label visível
35
35
  * @property {IconProp} iconLeft - Ícone Font Awesome à esquerda
36
36
  * @property {InputAction[]} iconsRight - Botões de ação com ícone à direita
37
- * @property {function} onChange - Callback acionado ao digitar (recebe o novo valor string)
37
+ * @property {IconProp} iconRight - Ícone decorativo à direita (não é botão, some para o leitor de tela). Para ação clicável, use `iconsRight`.
38
+ * @property {boolean} grouped - O campo vive dentro de um contêiner que já desenha a moldura E o foco (o campo de chips: as tags e o input na mesma caixa). Implica `borderless`, e tira a altura de campo, o padding e o anel de foco próprio: o contêiner mostra o foco com `:focus-within`. Sem esse foco no contêiner, quem usa teclado perde o indicador (WCAG 2.4.7).
39
+ * @property {boolean} borderless - Sem borda, fundo e raio: o campo dentro de um grupo que já tem a moldura (um Select e um Input lado a lado numa mesma caixa). O foco continua visível, em contorno, e o erro mantém a borda vermelha.
40
+ * @property {string} mask - Máscara simples: 'cpf' | 'cnpj' | 'cep' | 'phone'. O valor exibido e o que chega em `onChange` já vêm formatados (para só os dígitos, `valor.replace(/\D/g, "")`). Aceita só dígitos, limita o tamanho e abre o teclado numérico no celular.
41
+ * @property {function} onChange - Callback acionado A CADA TECLA (recebe o novo valor string), nos dois frameworks. O blur sai em `onBlur`.
38
42
  * @property {function} onFocus - Callback de foco (recebe o evento nativo)
39
43
  * @property {function} onBlur - Callback de blur (recebe o evento nativo)
40
44
  * @quandoUsar Entrada de texto de UMA linha: nome, e-mail, número, busca. É o campo padrão quando o dado é curto e livre.
@@ -87,6 +91,18 @@ export interface InputProps {
87
91
  hidePasswordLabel?: string;
88
92
  iconLeft?: IconProp;
89
93
  iconsRight?: InputAction[];
94
+ /** Ícone decorativo à direita (não clicável, `aria-hidden`). Para ação, use `iconsRight`. */
95
+ iconRight?: IconProp;
96
+ /** Sem borda, fundo e raio, para o campo dentro de um grupo que já tem a moldura. O foco e o erro continuam visíveis. @default false */
97
+ borderless?: boolean;
98
+ /**
99
+ * O campo dentro de um contêiner que já tem a moldura e o foco (o campo de chips).
100
+ * Implica `borderless` e tira a altura de campo, o padding e o anel de foco
101
+ * próprio: o foco vem do contêiner (`:focus-within`). @default false
102
+ */
103
+ grouped?: boolean;
104
+ /** Máscara simples. O valor exibido e o de `onChange` já saem formatados. */
105
+ mask?: "cpf" | "cnpj" | "cep" | "phone";
90
106
  onChange?: (value: string) => void;
91
107
  onFocus?: (event?: any) => void;
92
108
  onBlur?: (event?: any) => void;
@@ -1,11 +1,13 @@
1
1
  "use client";
2
2
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import './Input.css';
4
- import { useState } from "react";
4
+ import { useState, useRef } from "react";
5
5
  import { faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";
6
6
  import Icon from "../Icon/Icon";
7
7
  import Text from "../Text/Text";
8
8
  function Input(props) {
9
+ const ultimoEventoRef = useRef(null);
10
+ const ultimoValorRef = useRef(null);
9
11
  const [isPasswordVisible, setIsPasswordVisible] = useState(() => false);
10
12
  const [internalValue, setInternalValue] = useState(() => props.defaultValue || "");
11
13
  const [uid, setUid] = useState(() => "umds-input-" + Math.random().toString(36).slice(2, 9));
@@ -48,6 +50,8 @@ function Input(props) {
48
50
  props.disabled ? "umds-input--disabled" : "",
49
51
  props.readOnly ? "umds-input--readonly" : "",
50
52
  props.numberSpinner ? "umds-input--number-spinner" : "",
53
+ props.borderless || props.grouped ? "umds-input--borderless" : "",
54
+ props.grouped ? "umds-input--grouped" : "",
51
55
  `umds-input--${props.size || "md"}`,
52
56
  props.className,
53
57
  ]
@@ -69,16 +73,74 @@ function Input(props) {
69
73
  function iconSize() {
70
74
  return props.size === "sm" || props.size === "xs" ? "sm" : "md";
71
75
  }
76
+ function aplicarMascara(valor) {
77
+ const texto = valor === undefined || valor === null ? "" : String(valor);
78
+ if (!props.mask)
79
+ return texto;
80
+ let digitos = texto.replace(/\D/g, "");
81
+ let padrao = "";
82
+ if (props.mask === "cpf")
83
+ padrao = "###.###.###-##";
84
+ else if (props.mask === "cnpj")
85
+ padrao = "##.###.###/####-##";
86
+ else if (props.mask === "cep")
87
+ padrao = "#####-###";
88
+ else if (props.mask === "phone")
89
+ padrao = digitos.length > 10 ? "(##) #####-####" : "(##) ####-####";
90
+ let saida = "";
91
+ let posicao = 0;
92
+ for (let i = 0; i < padrao.length && posicao < digitos.length; i++) {
93
+ if (padrao.charAt(i) === "#") {
94
+ saida += digitos.charAt(posicao);
95
+ posicao++;
96
+ }
97
+ else {
98
+ saida += padrao.charAt(i);
99
+ }
100
+ }
101
+ return saida;
102
+ }
103
+ function tamanhoMaximo() {
104
+ if (props.mask === "cpf")
105
+ return 14;
106
+ if (props.mask === "cnpj")
107
+ return 18;
108
+ if (props.mask === "cep")
109
+ return 9;
110
+ if (props.mask === "phone")
111
+ return 15;
112
+ return undefined;
113
+ }
114
+ function modoDoTeclado() {
115
+ return props.mask ? "numeric" : undefined;
116
+ }
117
+ function valorExibido() {
118
+ const bruto = props.value !== undefined ? props.value : internalValue;
119
+ return aplicarMascara(bruto);
120
+ }
72
121
  function handleChange(event) {
73
- setInternalValue(event.target.value);
122
+ const nativo = event.nativeEvent || event;
123
+ if (nativo === ultimoEventoRef.current)
124
+ return;
125
+ ultimoEventoRef.current = nativo;
126
+ const valor = aplicarMascara(event.target.value);
127
+ // O `change` do blur (Vue) repete o que o `input` da última tecla
128
+ // entregou; só passa se o valor mudou de fato (ex.: change disparado à mão).
129
+ if (nativo.type === "change" && valor === ultimoValorRef.current)
130
+ return;
131
+ ultimoValorRef.current = valor;
132
+ if (props.mask && event.target.value !== valor) {
133
+ event.target.value = valor;
134
+ }
135
+ setInternalValue(valor);
74
136
  if (props.onChange) {
75
- props.onChange(event.target.value);
137
+ props.onChange(valor);
76
138
  }
77
139
  }
78
- return (_jsxs("div", { className: wrapperClasses(), children: [props.label ? (_jsxs(Text, { as: "label", variant: "label", className: "umds-input__label", forId: inputId(), children: [_jsx(_Fragment, { children: props.label }), props.required ? (_jsx("span", { className: "umds-input__required", children: "*" })) : null] })) : null, _jsxs("div", { className: inputContainerClasses(), children: [props.iconLeft ? (_jsx("div", { className: "umds-input__icon-left", children: _jsx(Icon, { icon: props.iconLeft, size: iconSize() }) })) : null, _jsx("input", { className: "umds-input__control", id: inputId(), type: inputType(), name: props.name, min: props.min, max: props.max, step: props.step, disabled: props.disabled, readOnly: props.readOnly, placeholder: props.placeholder, value: props.value !== undefined ? props.value : internalValue, onChange: (event) => handleChange(event), onFocus: (event) => props.onFocus?.(event), onBlur: (event) => props.onBlur?.(event), "aria-label": props.ariaLabel, "aria-invalid": !!props.invalid ||
140
+ return (_jsxs("div", { className: wrapperClasses(), children: [props.label ? (_jsxs(Text, { as: "label", variant: "label", className: "umds-input__label", forId: inputId(), children: [_jsx(_Fragment, { children: props.label }), props.required ? (_jsx("span", { className: "umds-input__required", children: "*" })) : null] })) : null, _jsxs("div", { className: inputContainerClasses(), children: [props.iconLeft ? (_jsx("div", { className: "umds-input__icon-left", children: _jsx(Icon, { icon: props.iconLeft, size: iconSize() }) })) : null, _jsx("input", { className: "umds-input__control", id: inputId(), type: inputType(), name: props.name, min: props.min, max: props.max, step: props.step, disabled: props.disabled, readOnly: props.readOnly, placeholder: props.placeholder, value: valorExibido(), maxLength: tamanhoMaximo(), inputMode: modoDoTeclado(), onInput: (event) => handleChange(event), onChange: (event) => handleChange(event), onFocus: (event) => props.onFocus?.(event), onBlur: (event) => props.onBlur?.(event), "aria-label": props.ariaLabel, "aria-invalid": !!props.invalid ||
79
141
  !!(props.errorMessage && props.errorMessage.length > 0), "aria-describedby": describedBy() || undefined, required: props.required }), _jsxs("div", { className: "umds-input__actions-right", children: [props.type === "password" ? (_jsx("button", { type: "button", className: "umds-input__action-btn", disabled: props.disabled, onClick: (event) => togglePassword(), "aria-label": passwordToggleLabel(), children: _jsx(Icon, { icon: isPasswordVisible ? faEyeSlash : faEye, size: iconSize() }) })) : null, props.iconsRight?.length ? (_jsx(_Fragment, { children: props.iconsRight?.map((action, index) => (_jsx("button", { type: "button", className: "umds-input__action-btn", disabled: props.disabled, onClick: (e) => {
80
142
  e.stopPropagation();
81
143
  action.onClick?.(e);
82
- }, title: action.tooltip, "aria-label": action.label || action.tooltip, children: _jsx(Icon, { icon: action.icon, size: iconSize() }) }, index))) })) : null] })] }), props.errorMessage ? (_jsx(Text, { as: "span", variant: "caption", color: "negative", id: errorId(), children: _jsx(_Fragment, { children: props.errorMessage }) })) : null, props.helperText ? (_jsx(Text, { as: "span", variant: "caption", color: "secondary", id: helperId(), children: _jsx(_Fragment, { children: props.helperText }) })) : null] }));
144
+ }, title: action.tooltip, "aria-label": action.label || action.tooltip, children: _jsx(Icon, { icon: action.icon, size: iconSize() }) }, index))) })) : null] }), props.iconRight ? (_jsx("div", { "aria-hidden": "true", className: "umds-input__icon-right", children: _jsx(Icon, { icon: props.iconRight, size: iconSize() }) })) : null] }), props.errorMessage ? (_jsx(Text, { as: "span", variant: "caption", color: "negative", id: errorId(), children: _jsx(_Fragment, { children: props.errorMessage }) })) : null, props.helperText ? (_jsx(Text, { as: "span", variant: "caption", color: "secondary", id: helperId(), children: _jsx(_Fragment, { children: props.helperText }) })) : null] }));
83
145
  }
84
146
  export default Input;
@@ -7,7 +7,11 @@
7
7
  cartão.
8
8
  ============================================ */
9
9
 
10
+ /* `position: relative` ancora os textos só para leitor de tela (absolutos) das
11
+ colunas dentro da área que rola; sem ele, o de uma coluna fora da tela sobe
12
+ até a página e cria rolagem horizontal nela. */
10
13
  .umds-kanban {
14
+ position: relative;
11
15
  display: flex;
12
16
  align-items: stretch;
13
17
  gap: var(--umds-primitive-spacing-xxxs);
@@ -0,0 +1,66 @@
1
+ /* ─────────────────────────────────────────────
2
+ KBD
3
+ Uma tecla, ou uma combinação, em fonte monoespaçada.
4
+
5
+ A caixa é cinza com borda e uma sombra de base de 1px (a "espessura" da
6
+ tecla). Texto escuro sobre cinza claro: contraste de texto, não só de cor.
7
+
8
+ Cores: semânticos · Medidas: primitivos
9
+ ───────────────────────────────────────────── */
10
+
11
+ .umds-kbd {
12
+ display: inline-block;
13
+ box-sizing: border-box;
14
+ min-width: var(--umds-primitive-spacing-xxs); /* 24px */
15
+ padding: var(--umds-primitive-spacing-micro) var(--umds-primitive-spacing-nano); /* 2px 8px */
16
+ font-family: var(--umds-semantic-font-family-mono);
17
+ font-weight: var(--umds-primitive-font-weight-semibold);
18
+ line-height: var(--umds-primitive-font-line-height-lg);
19
+ text-align: center;
20
+ white-space: nowrap;
21
+ color: var(--umds-semantic-color-neutral-dark-pure);
22
+ background: var(--umds-semantic-color-background-light);
23
+ border: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-color-neutral-light-down);
24
+ border-bottom-width: var(--umds-primitive-border-width-thin);
25
+ border-radius: var(--umds-primitive-border-radius-xs);
26
+ }
27
+
28
+ .umds-kbd.umds-kbd--md {
29
+ font-size: var(--umds-primitive-font-size-xxs); /* 14px */
30
+ }
31
+
32
+ .umds-kbd.umds-kbd--sm {
33
+ min-width: 0;
34
+ padding: 0 var(--umds-primitive-spacing-quarck); /* 0 4px */
35
+ font-size: var(--umds-primitive-font-size-xxxs); /* 12px */
36
+ }
37
+
38
+ /* ── Combinação ── */
39
+ .umds-kbd-combo {
40
+ display: inline-flex;
41
+ align-items: center;
42
+ gap: var(--umds-primitive-spacing-quarck); /* 4px */
43
+ font-family: var(--umds-semantic-font-family-mono);
44
+ }
45
+
46
+ .umds-kbd-combo__item {
47
+ display: inline-flex;
48
+ align-items: center;
49
+ gap: var(--umds-primitive-spacing-quarck); /* 4px */
50
+ }
51
+
52
+ .umds-kbd-combo__separator {
53
+ font-size: var(--umds-primitive-font-size-xxxs); /* 12px */
54
+ color: var(--umds-semantic-color-neutral-dark-down);
55
+ }
56
+
57
+ /* O tamanho do conjunto vale para cada tecla dentro dele. */
58
+ .umds-kbd-combo.umds-kbd--md .umds-kbd--inner {
59
+ font-size: var(--umds-primitive-font-size-xxs); /* 14px */
60
+ }
61
+
62
+ .umds-kbd-combo.umds-kbd--sm .umds-kbd--inner {
63
+ min-width: 0;
64
+ padding: 0 var(--umds-primitive-spacing-quarck); /* 0 4px */
65
+ font-size: var(--umds-primitive-font-size-xxxs); /* 12px */
66
+ }
@@ -0,0 +1,32 @@
1
+ import './Kbd.css';
2
+ /**
3
+ * Kbd — uma tecla, ou uma combinação de teclas, num `<kbd>`.
4
+ *
5
+ * Uma tecla: `<Kbd>Esc</Kbd>`. Uma combinação: `keys` (`["Ctrl", "Shift", "P"]`),
6
+ * que desenha uma caixa por tecla com o `separator` entre elas (`+` por padrão).
7
+ * A fonte é a monoespaçada do DS (`--umds-semantic-font-family-mono`), a caixa é
8
+ * cinza com borda e uma sombra de base, como uma tecla de verdade.
9
+ *
10
+ * Semântica: `<kbd>` é o elemento HTML de "entrada de teclado", e um `<kbd>`
11
+ * dentro de outro é a forma de dizer "combinação de teclas". O leitor de tela lê
12
+ * "Ctrl + Shift + P" (o separador é texto, não desenho).
13
+ * @property {string[]} keys - Teclas de uma combinação, em ordem. Sem `keys`, vale o conteúdo (uma tecla)
14
+ * @property {string} separator - Texto entre as teclas de uma combinação (padrão "+")
15
+ * @property {string} size - 'sm' | 'md' (padrão)
16
+ * @property {string} className - Classes CSS adicionais
17
+ * @quandoUsar Mostrar um atalho de teclado ou a tecla que a pessoa deve apertar: painel de atalhos, dica de campo, instrução.
18
+ * @quandoNaoUsar Para botão, use `Button`. Para trecho de código, use `CodeBlock`.
19
+ */
20
+ export interface KbdProps {
21
+ keys?: string[];
22
+ separator?: string;
23
+ size?: "sm" | "md";
24
+ className?: string;
25
+ id?: string;
26
+ style?: any;
27
+ [key: string]: any;
28
+ /** Uma tecla (quando não há `keys`). */
29
+ children?: any;
30
+ }
31
+ declare function Kbd(props: KbdProps): import("react/jsx-runtime").JSX.Element;
32
+ export default Kbd;
@@ -0,0 +1,40 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import './Kbd.css';
3
+ function Kbd(props) {
4
+ function isSingle() {
5
+ return !(props.keys && props.keys.length > 0);
6
+ }
7
+ function keyList() {
8
+ return props.keys || [];
9
+ }
10
+ function classes() {
11
+ const combinacao = !!props.keys && props.keys.length > 0;
12
+ return [
13
+ combinacao ? "umds-kbd-combo" : "umds-kbd",
14
+ `umds-kbd--${props.size || "md"}`,
15
+ props.className,
16
+ ]
17
+ .filter(Boolean)
18
+ .join(" ");
19
+ }
20
+ function separatorText() {
21
+ return props.separator || "+";
22
+ }
23
+ function isLast(index) {
24
+ return index === keyList().length - 1;
25
+ }
26
+ function htmlAttrs() {
27
+ const out = {};
28
+ for (const chave in props) {
29
+ if (chave.indexOf("data-") === 0 ||
30
+ chave.indexOf("aria-") === 0 ||
31
+ chave === "style" ||
32
+ chave === "title") {
33
+ out[chave] = props[chave];
34
+ }
35
+ }
36
+ return out;
37
+ }
38
+ return (_jsxs("kbd", { id: props.id, ...htmlAttrs(), className: classes(), children: [isSingle() ? _jsx(_Fragment, { children: props.children }) : null, keyList()?.map((tecla, posicao) => (_jsxs("span", { className: "umds-kbd-combo__item", children: [_jsx("kbd", { className: "umds-kbd umds-kbd--inner", children: tecla }), !isLast(posicao) ? (_jsx("span", { className: "umds-kbd-combo__separator", children: separatorText() })) : null] }, posicao)))] }));
39
+ }
40
+ export default Kbd;
@@ -0,0 +1,136 @@
1
+ /* ─────────────────────────────────────────────
2
+ LIST / LIST ITEM
3
+ Lista semântica (ul/ol > li) de linhas clicáveis com conteúdo livre.
4
+ Só tokens do DS. Sem equivalente (mantido como literal):
5
+ padding vertical de 10px do CrisDoc → usa spacing-nano (8px).
6
+ ───────────────────────────────────────────── */
7
+
8
+ /* ── List ── */
9
+ .umds-list {
10
+ display: flex;
11
+ flex-direction: column;
12
+ min-width: 0;
13
+ box-sizing: border-box;
14
+ font-family: var(--umds-semantic-font-family-base);
15
+ }
16
+
17
+ ul.umds-list,
18
+ ol.umds-list {
19
+ list-style: none;
20
+ margin: 0;
21
+ padding: 0;
22
+ }
23
+
24
+ .umds-list--gap-none { gap: 0; }
25
+ .umds-list--gap-micro { gap: var(--umds-primitive-spacing-micro); }
26
+ .umds-list--gap-quarck { gap: var(--umds-primitive-spacing-quarck); }
27
+ .umds-list--gap-nano { gap: var(--umds-primitive-spacing-nano); }
28
+ .umds-list--gap-mini { gap: var(--umds-primitive-spacing-mini); }
29
+ .umds-list--gap-xxxs { gap: var(--umds-primitive-spacing-xxxs); }
30
+
31
+ /* Estado vazio: o miolo da lista troca de conteúdo; quem rodeia não muda. */
32
+ .umds-list--empty {
33
+ align-items: center;
34
+ justify-content: center;
35
+ }
36
+
37
+ /* ── <li> que envolve a linha ── */
38
+ .umds-list__item {
39
+ display: block;
40
+ list-style: none;
41
+ margin: 0;
42
+ padding: 0;
43
+ min-width: 0;
44
+ }
45
+
46
+ /* ── Linha ── */
47
+ .umds-list-item {
48
+ display: flex;
49
+ align-items: flex-start;
50
+ gap: var(--umds-primitive-spacing-nano); /* 8px */
51
+ width: 100%;
52
+ box-sizing: border-box;
53
+ min-width: 0;
54
+ margin: 0;
55
+ padding: var(--umds-primitive-spacing-nano) var(--umds-primitive-spacing-mini); /* 8px 12px */
56
+ border: 0;
57
+ border-radius: var(--umds-primitive-border-radius-sm); /* 8px */
58
+ background: transparent;
59
+ color: var(--umds-semantic-color-neutral-dark-pure);
60
+ font: inherit;
61
+ text-align: left;
62
+ text-decoration: none;
63
+ transition: background-color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard);
64
+ }
65
+
66
+ .umds-list-item--interactive {
67
+ cursor: pointer;
68
+ }
69
+
70
+ .umds-list-item--interactive:hover {
71
+ background: var(--umds-semantic-color-background-light);
72
+ }
73
+
74
+ .umds-list-item--interactive:focus-visible {
75
+ outline: 2px solid var(--umds-semantic-color-primary-pure);
76
+ outline-offset: -2px; /* dentro da linha: o anel não é cortado por overflow do pai */
77
+ }
78
+
79
+ /* ── Selecionado ── */
80
+ .umds-list-item--selected {
81
+ background: var(--umds-semantic-color-primary-light);
82
+ }
83
+
84
+ .umds-list-item--selected.umds-list-item--interactive:hover {
85
+ background: color-mix(
86
+ in srgb,
87
+ var(--umds-semantic-color-primary-light) 85%,
88
+ var(--umds-semantic-color-background-white)
89
+ );
90
+ }
91
+
92
+ /* ── Desabilitado ── */
93
+ .umds-list-item--disabled,
94
+ .umds-list-item--disabled .umds-list-item__subtitle,
95
+ .umds-list-item--disabled .umds-list-item__meta {
96
+ color: var(--umds-semantic-color-neutral-dark-up);
97
+ }
98
+
99
+ .umds-list-item--disabled,
100
+ .umds-list-item--disabled.umds-list-item--interactive:hover {
101
+ cursor: not-allowed;
102
+ background: transparent;
103
+ }
104
+
105
+ /* ── Anatomia ── */
106
+ .umds-list-item__start,
107
+ .umds-list-item__end {
108
+ display: inline-flex;
109
+ flex-shrink: 0;
110
+ align-items: center;
111
+ align-self: center;
112
+ }
113
+
114
+ .umds-list-item__end {
115
+ margin-left: auto;
116
+ }
117
+
118
+ .umds-list-item__body {
119
+ display: flex;
120
+ flex: 1 1 auto;
121
+ flex-direction: column;
122
+ gap: var(--umds-primitive-spacing-micro); /* 2px */
123
+ min-width: 0;
124
+ overflow-wrap: anywhere;
125
+ }
126
+
127
+ .umds-list-item__title {
128
+ display: block;
129
+ color: inherit;
130
+ }
131
+
132
+ .umds-list-item__subtitle,
133
+ .umds-list-item__meta {
134
+ display: block;
135
+ color: var(--umds-semantic-color-neutral-dark-down);
136
+ }
@@ -0,0 +1,82 @@
1
+ import './List.css';
2
+ /** Espaço entre as linhas, na escala oficial do DS. `none` cola as linhas. */
3
+ export type ListGap = "none" | "micro" | "quarck" | "nano" | "mini" | "xxxs";
4
+ /** Elemento da lista: `ul` (padrão) ou `ol` quando a ordem importa. */
5
+ /** Espaço entre as linhas, na escala oficial do DS. `none` cola as linhas. */
6
+ /** Elemento da lista: `ul` (padrão) ou `ol` quando a ordem importa. */
7
+ export type ListTag = "ul" | "ol";
8
+ /**
9
+ * List — agrupa `ListItem` numa lista semântica (`ul`/`ol` com `li`) e traz o
10
+ * estado vazio dentro dela.
11
+ *
12
+ * Quando não há itens, passe `isEmpty`: a lista troca os itens por um
13
+ * `EmptyState` (`emptyTitle`, `emptyDescription`, `emptyIcon`, `emptyActionLabel`
14
+ * com `onEmptyAction`) ou, para um conteúdo próprio, pelo slot `empty`. Só o
15
+ * miolo troca: o título do cartão, a busca, os filtros e a paginação ao redor
16
+ * continuam montados, e o estado vazio é anunciado ao leitor de tela
17
+ * (`role="status"`). `isEmpty` é uma decisão sua, porque a lista não conta
18
+ * filhos: `:is-empty="!itens.length"`.
19
+ *
20
+ * A lista precisa de nome: passe `ariaLabel` (ou `ariaLabelledby`, apontando
21
+ * para o título visível). Sem isso o leitor de tela anuncia "lista, 5 itens"
22
+ * sem dizer de quê.
23
+ *
24
+ * `ul` e `ol` saem sem marcador, margem e recuo, com `role="list"` (o Safari
25
+ * tira a semântica de lista de `list-style: none`).
26
+ * @property {string} as - Elemento: 'ul' (padrão) | 'ol'
27
+ * @property {string} gap - Espaço entre as linhas, na escala do DS ('none' cola)
28
+ * @property {string} ariaLabel - Nome acessível da lista
29
+ * @property {string} ariaLabelledby - Id do título visível que nomeia a lista
30
+ * @property {boolean} isEmpty - Sem itens: mostra o estado vazio no lugar das linhas
31
+ * @property {string} emptyTitle - Título do estado vazio (padrão: "Nenhum item encontrado")
32
+ * @property {string} emptyDescription - Texto de apoio do estado vazio
33
+ * @property {IconProp} emptyIcon - Ícone do estado vazio (objeto do Font Awesome)
34
+ * @property {string} emptySize - Tamanho do estado vazio: 'sm' (padrão, compacto) | 'md' | 'lg'
35
+ * @property {string} emptyActionLabel - Rótulo do botão do estado vazio (junto de onEmptyAction)
36
+ * @property {function} onEmptyAction - Callback do botão do estado vazio
37
+ * @property {any} empty - Slot `empty`: conteúdo próprio no lugar do EmptyState
38
+ * @property {string} className - Classes CSS adicionais
39
+ * @slot empty - Conteúdo do estado vazio (substitui o EmptyState padrão).
40
+ * @quandoUsar Qualquer lista de linhas clicáveis (`ListItem`) ou de itens simples que pode ficar sem resultado: documentos não lidos, notificações, resultados de busca. Resolve a semântica de lista e o "nada por aqui" num lugar só.
41
+ * @quandoNaoUsar Para dados tabulares comparados coluna a coluna, use `DataTable` (que já tem o próprio estado vazio). Para só empilhar blocos com espaçamento, sem semântica de lista, use `Stack`. Para um estado vazio que ocupa a tela inteira (sem lista), use `EmptyState` direto.
42
+ */
43
+ /** Espaço entre as linhas, na escala oficial do DS. `none` cola as linhas. */
44
+ /** Elemento da lista: `ul` (padrão) ou `ol` quando a ordem importa. */
45
+ export interface ListProps {
46
+ /** Elemento da lista. @default 'ul' */
47
+ as?: ListTag;
48
+ /** Espaço entre as linhas, na escala oficial (`none` cola). @default 'quarck' */
49
+ gap?: ListGap;
50
+ /** Nome acessível da lista. */
51
+ ariaLabel?: string;
52
+ /** Id do título visível que nomeia a lista. */
53
+ ariaLabelledby?: string;
54
+ /** Sem itens: mostra o estado vazio no lugar das linhas. @default false */
55
+ isEmpty?: boolean;
56
+ /** Título do estado vazio. @default 'Nenhum item encontrado' */
57
+ emptyTitle?: string;
58
+ /** Texto de apoio do estado vazio. */
59
+ emptyDescription?: string;
60
+ /** Ícone do estado vazio: o objeto importado do Font Awesome. */
61
+ emptyIcon?: IconProp;
62
+ /** Tamanho do estado vazio. @default 'sm' */
63
+ emptySize?: "sm" | "md" | "lg";
64
+ /** Rótulo do botão do estado vazio (exibido junto de `onEmptyAction`). */
65
+ emptyActionLabel?: string;
66
+ /** Chamado no botão do estado vazio. */
67
+ onEmptyAction?: () => void;
68
+ /** Conteúdo próprio do estado vazio. No Vue, slot `empty`. */
69
+ empty?: any;
70
+ /** Classes CSS adicionais. */
71
+ className?: string;
72
+ /** ID HTML do elemento raiz. */
73
+ id?: string;
74
+ /** Atributos HTML repassados ao elemento raiz (style, data-*…). */
75
+ style?: any;
76
+ [key: string]: any;
77
+ /** As linhas: `ListItem` (ou `li`). */
78
+ children?: any;
79
+ }
80
+ import type { IconProp } from "../Icon/Icon";
81
+ declare function List(props: ListProps): import("react/jsx-runtime").JSX.Element;
82
+ export default List;
@@ -0,0 +1,53 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import './List.css';
3
+ import EmptyState from "../EmptyState/EmptyState";
4
+ function List(props) {
5
+ function elementTag() {
6
+ return props.as || "ul";
7
+ }
8
+ function showEmpty() {
9
+ return !!props.isEmpty;
10
+ }
11
+ function showItems() {
12
+ return !props.isEmpty;
13
+ }
14
+ function classes() {
15
+ return [
16
+ "umds-list",
17
+ `umds-list--gap-${props.gap || "quarck"}`,
18
+ props.className,
19
+ ]
20
+ .filter(Boolean)
21
+ .join(" ");
22
+ }
23
+ function emptyClasses() {
24
+ return ["umds-list umds-list--empty", props.className]
25
+ .filter(Boolean)
26
+ .join(" ");
27
+ }
28
+ function emptyTitleText() {
29
+ return props.emptyTitle || "Nenhum item encontrado";
30
+ }
31
+ function emptyActionProps() {
32
+ if (!props.onEmptyAction)
33
+ return {};
34
+ return {
35
+ actionLabel: props.emptyActionLabel,
36
+ onAction: props.onEmptyAction,
37
+ };
38
+ }
39
+ function emptySizeValue() {
40
+ return props.emptySize || "sm";
41
+ }
42
+ function htmlAttrs() {
43
+ const out = {};
44
+ for (const chave in props) {
45
+ if (chave.indexOf("data-") === 0 || chave === "style") {
46
+ out[chave] = props[chave];
47
+ }
48
+ }
49
+ return out;
50
+ }
51
+ return (_jsxs(_Fragment, { children: [showEmpty() ? (_jsx("div", { role: "status", id: props.id, ...htmlAttrs(), className: emptyClasses(), children: _jsx(_Fragment, { children: props.empty || (_jsx(EmptyState, { icon: props.emptyIcon, title: emptyTitleText(), description: props.emptyDescription, size: emptySizeValue(), ...emptyActionProps() })) }) })) : null, showItems() && elementTag() === "ul" ? (_jsx("ul", { role: "list", id: props.id, "aria-label": props.ariaLabel, "aria-labelledby": props.ariaLabelledby, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null, showItems() && elementTag() === "ol" ? (_jsx("ol", { role: "list", id: props.id, "aria-label": props.ariaLabel, "aria-labelledby": props.ariaLabelledby, ...htmlAttrs(), className: classes(), children: _jsx(_Fragment, { children: props.children }) })) : null] }));
52
+ }
53
+ export default List;