@1doc/1ds-react 2.8.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/CHANGELOG.md +1106 -0
  2. package/dist/components/AILabel/AILabel.js +1 -1
  3. package/dist/components/Accordion/Accordion.d.ts +6 -2
  4. package/dist/components/AttachmentCard/AttachmentCard.css +16 -0
  5. package/dist/components/AttachmentCard/AttachmentCard.d.ts +19 -2
  6. package/dist/components/AttachmentCard/AttachmentCard.js +40 -3
  7. package/dist/components/Avatar/Avatar.css +7 -2
  8. package/dist/components/Avatar/AvatarGroup.d.ts +17 -0
  9. package/dist/components/Avatar/AvatarGroup.js +22 -8
  10. package/dist/components/Badge/Badge.css +54 -2
  11. package/dist/components/Badge/Badge.d.ts +14 -4
  12. package/dist/components/Badge/Badge.js +1 -0
  13. package/dist/components/Box/Box.css +83 -0
  14. package/dist/components/Box/Box.d.ts +82 -2
  15. package/dist/components/Box/Box.js +42 -2
  16. package/dist/components/Button/Button.css +29 -0
  17. package/dist/components/Button/Button.d.ts +4 -4
  18. package/dist/components/Button/Button.js +4 -1
  19. package/dist/components/Calendar/Calendar.css +245 -0
  20. package/dist/components/Calendar/Calendar.d.ts +125 -0
  21. package/dist/components/Calendar/Calendar.js +320 -0
  22. package/dist/components/Chips/Chips.css +38 -0
  23. package/dist/components/Chips/Chips.d.ts +5 -2
  24. package/dist/components/Chips/Chips.js +2 -1
  25. package/dist/components/Coachmark/Coachmark.css +118 -0
  26. package/dist/components/Coachmark/Coachmark.d.ts +75 -0
  27. package/dist/components/Coachmark/Coachmark.js +321 -0
  28. package/dist/components/CodeBlock/CodeBlock.css +96 -0
  29. package/dist/components/CodeBlock/CodeBlock.d.ts +47 -0
  30. package/dist/components/CodeBlock/CodeBlock.js +103 -0
  31. package/dist/components/ColorPicker/ColorPicker.css +133 -0
  32. package/dist/components/ColorPicker/ColorPicker.d.ts +73 -0
  33. package/dist/components/ColorPicker/ColorPicker.js +219 -0
  34. package/dist/components/Combobox/Combobox.css +8 -0
  35. package/dist/components/DataTable/DataTable.css +80 -0
  36. package/dist/components/DataTable/DataTable.d.ts +19 -4
  37. package/dist/components/DataTable/DataTable.js +59 -15
  38. package/dist/components/DatePicker/DatePicker.css +8 -0
  39. package/dist/components/DatePicker/DatePicker.js +10 -1
  40. package/dist/components/DescriptionList/DescriptionList.css +113 -0
  41. package/dist/components/DescriptionList/DescriptionList.d.ts +59 -0
  42. package/dist/components/DescriptionList/DescriptionList.js +51 -0
  43. package/dist/components/FileInput/FileInput.css +16 -0
  44. package/dist/components/FileInput/FileInput.d.ts +4 -2
  45. package/dist/components/FileInput/FileInput.js +8 -2
  46. package/dist/components/Grid/Grid.js +5 -5
  47. package/dist/components/IconPicker/IconPicker.css +107 -0
  48. package/dist/components/IconPicker/IconPicker.d.ts +74 -0
  49. package/dist/components/IconPicker/IconPicker.js +194 -0
  50. package/dist/components/Input/Input.css +38 -0
  51. package/dist/components/Input/Input.d.ts +10 -1
  52. package/dist/components/Input/Input.js +66 -5
  53. package/dist/components/Kanban/Kanban.css +4 -0
  54. package/dist/components/Kbd/Kbd.css +66 -0
  55. package/dist/components/Kbd/Kbd.d.ts +32 -0
  56. package/dist/components/Kbd/Kbd.js +40 -0
  57. package/dist/components/List/List.css +136 -0
  58. package/dist/components/List/List.d.ts +82 -0
  59. package/dist/components/List/List.js +53 -0
  60. package/dist/components/List/ListItem.d.ts +85 -0
  61. package/dist/components/List/ListItem.js +81 -0
  62. package/dist/components/Modal/Modal.css +80 -0
  63. package/dist/components/Modal/Modal.d.ts +33 -6
  64. package/dist/components/Modal/Modal.js +101 -6
  65. package/dist/components/MultiSelect/MultiSelect.css +8 -0
  66. package/dist/components/MultiSelect/MultiSelect.js +10 -1
  67. package/dist/components/OrgChart/OrgChart.css +149 -0
  68. package/dist/components/OrgChart/OrgChart.d.ts +83 -0
  69. package/dist/components/OrgChart/OrgChart.js +297 -0
  70. package/dist/components/OtpInput/OtpInput.css +93 -0
  71. package/dist/components/OtpInput/OtpInput.d.ts +60 -0
  72. package/dist/components/OtpInput/OtpInput.js +215 -0
  73. package/dist/components/PhoneInput/PhoneInput.css +8 -0
  74. package/dist/components/Popover/Popover.d.ts +7 -0
  75. package/dist/components/Popover/Popover.js +11 -1
  76. package/dist/components/RichTextEditor/RichTextEditor.css +203 -0
  77. package/dist/components/RichTextEditor/RichTextEditor.d.ts +83 -0
  78. package/dist/components/RichTextEditor/RichTextEditor.js +494 -0
  79. package/dist/components/SegmentedControl/SegmentedControl.js +7 -2
  80. package/dist/components/Select/Select.css +70 -0
  81. package/dist/components/Select/Select.d.ts +12 -0
  82. package/dist/components/Select/Select.js +59 -4
  83. package/dist/components/Stack/Stack.css +49 -0
  84. package/dist/components/Stack/Stack.d.ts +65 -7
  85. package/dist/components/Stack/Stack.js +30 -2
  86. package/dist/components/StatCard/StatCard.css +73 -0
  87. package/dist/components/StatCard/StatCard.d.ts +17 -0
  88. package/dist/components/StatCard/StatCard.js +4 -1
  89. package/dist/components/Tabs/Tab.d.ts +15 -0
  90. package/dist/components/Tabs/Tab.js +30 -1
  91. package/dist/components/Tabs/Tabs.css +132 -0
  92. package/dist/components/Tabs/Tabs.d.ts +7 -0
  93. package/dist/components/Tabs/Tabs.js +13 -2
  94. package/dist/components/Tag/Tag.css +85 -2
  95. package/dist/components/Tag/Tag.d.ts +13 -6
  96. package/dist/components/Tag/Tag.js +1 -0
  97. package/dist/components/Text/Text.js +2 -2
  98. package/dist/components/Textarea/Textarea.css +8 -0
  99. package/dist/components/TimePicker/TimePicker.css +8 -0
  100. package/dist/components/Tooltip/Tooltip.css +25 -0
  101. package/dist/components/Tooltip/Tooltip.d.ts +11 -0
  102. package/dist/components/Tooltip/Tooltip.js +18 -3
  103. package/dist/index.d.ts +25 -0
  104. package/dist/index.js +14 -0
  105. package/dist/teste/AILabel.test.d.ts +1 -0
  106. package/dist/teste/AILabel.test.js +33 -0
  107. package/dist/teste/AccordionConteudoLivre.test.d.ts +1 -0
  108. package/dist/teste/AccordionConteudoLivre.test.js +29 -0
  109. package/dist/teste/AtributosRepassados.test.d.ts +1 -0
  110. package/dist/teste/AtributosRepassados.test.js +52 -0
  111. package/dist/teste/AttachmentCardIA.test.d.ts +1 -0
  112. package/dist/teste/AttachmentCardIA.test.js +89 -0
  113. package/dist/teste/AvatarGroupOverlap.test.d.ts +1 -0
  114. package/dist/teste/AvatarGroupOverlap.test.js +56 -0
  115. package/dist/teste/BadgeTag.test.d.ts +1 -0
  116. package/dist/teste/BadgeTag.test.js +42 -0
  117. package/dist/teste/BoxItemFlex.test.d.ts +1 -0
  118. package/dist/teste/BoxItemFlex.test.js +54 -0
  119. package/dist/teste/BoxLayout.test.d.ts +1 -0
  120. package/dist/teste/BoxLayout.test.js +35 -0
  121. package/dist/teste/Button.test.d.ts +1 -0
  122. package/dist/teste/Button.test.js +27 -0
  123. package/dist/teste/Calendar.test.d.ts +1 -0
  124. package/dist/teste/Calendar.test.js +221 -0
  125. package/dist/teste/ChipsXs.test.d.ts +1 -0
  126. package/dist/teste/ChipsXs.test.js +31 -0
  127. package/dist/teste/Coachmark.test.d.ts +1 -0
  128. package/dist/teste/Coachmark.test.js +149 -0
  129. package/dist/teste/ColorPicker.test.d.ts +1 -0
  130. package/dist/teste/ColorPicker.test.js +132 -0
  131. package/dist/teste/DataTableCelulaLivre.test.d.ts +1 -0
  132. package/dist/teste/DataTableCelulaLivre.test.js +76 -0
  133. package/dist/teste/DataTableDocumento.test.d.ts +1 -0
  134. package/dist/teste/DataTableDocumento.test.js +92 -0
  135. package/dist/teste/DatePicker.test.js +23 -0
  136. package/dist/teste/FileInputTrigger.test.d.ts +1 -0
  137. package/dist/teste/FileInputTrigger.test.js +53 -0
  138. package/dist/teste/IconPicker.test.d.ts +1 -0
  139. package/dist/teste/IconPicker.test.js +130 -0
  140. package/dist/teste/InputMascaraEAfins.test.d.ts +1 -0
  141. package/dist/teste/InputMascaraEAfins.test.js +99 -0
  142. package/dist/teste/KbdCodeBlock.test.d.ts +1 -0
  143. package/dist/teste/KbdCodeBlock.test.js +95 -0
  144. package/dist/teste/List.test.d.ts +1 -0
  145. package/dist/teste/List.test.js +153 -0
  146. package/dist/teste/ModalVariantes.test.d.ts +1 -0
  147. package/dist/teste/ModalVariantes.test.js +151 -0
  148. package/dist/teste/NomeAcessivelSsr.test.d.ts +1 -0
  149. package/dist/teste/NomeAcessivelSsr.test.js +88 -0
  150. package/dist/teste/OrgChart.test.d.ts +1 -0
  151. package/dist/teste/OrgChart.test.js +162 -0
  152. package/dist/teste/OtpInput.test.d.ts +1 -0
  153. package/dist/teste/OtpInput.test.js +143 -0
  154. package/dist/teste/PopoverMaxHeight.test.d.ts +1 -0
  155. package/dist/teste/PopoverMaxHeight.test.js +38 -0
  156. package/dist/teste/RichTextEditor.test.d.ts +1 -0
  157. package/dist/teste/RichTextEditor.test.js +287 -0
  158. package/dist/teste/SelectPlacementFiltro.test.d.ts +1 -0
  159. package/dist/teste/SelectPlacementFiltro.test.js +88 -0
  160. package/dist/teste/Stack.test.d.ts +1 -0
  161. package/dist/teste/Stack.test.js +57 -0
  162. package/dist/teste/StatCardRotuloTopo.test.d.ts +1 -0
  163. package/dist/teste/StatCardRotuloTopo.test.js +34 -0
  164. package/dist/teste/TabsContadorFechavel.test.d.ts +1 -0
  165. package/dist/teste/TabsContadorFechavel.test.js +79 -0
  166. package/dist/teste/TooltipDark.test.d.ts +1 -0
  167. package/dist/teste/TooltipDark.test.js +31 -0
  168. package/dist/utils/calendario.d.ts +28 -0
  169. package/dist/utils/calendario.js +73 -0
  170. package/dist/utils/html-seguro.d.ts +27 -0
  171. package/dist/utils/html-seguro.js +97 -0
  172. package/dist/utils/paleta-de-cores.d.ts +26 -0
  173. package/dist/utils/paleta-de-cores.js +10 -0
  174. package/dist/utils/texto.d.ts +5 -0
  175. package/dist/utils/texto.js +5 -0
  176. package/package.json +3 -3
  177. package/src/index.ts +26 -0
  178. package/src/teste/AILabel.test.tsx +41 -0
  179. package/src/teste/AccordionConteudoLivre.test.tsx +39 -0
  180. package/src/teste/AtributosRepassados.test.tsx +73 -0
  181. package/src/teste/AttachmentCardIA.test.tsx +126 -0
  182. package/src/teste/AvatarGroupOverlap.test.tsx +74 -0
  183. package/src/teste/BadgeTag.test.tsx +64 -0
  184. package/src/teste/BoxItemFlex.test.tsx +81 -0
  185. package/src/teste/BoxLayout.test.tsx +50 -0
  186. package/src/teste/Button.test.tsx +39 -0
  187. package/src/teste/Calendar.test.tsx +282 -0
  188. package/src/teste/ChipsXs.test.tsx +41 -0
  189. package/src/teste/Coachmark.test.tsx +198 -0
  190. package/src/teste/ColorPicker.test.tsx +153 -0
  191. package/src/teste/DataTableCelulaLivre.test.tsx +103 -0
  192. package/src/teste/DataTableDocumento.test.tsx +102 -0
  193. package/src/teste/DatePicker.test.tsx +38 -0
  194. package/src/teste/FileInputTrigger.test.tsx +89 -0
  195. package/src/teste/IconPicker.test.tsx +145 -0
  196. package/src/teste/InputMascaraEAfins.test.tsx +124 -0
  197. package/src/teste/KbdCodeBlock.test.tsx +106 -0
  198. package/src/teste/List.test.tsx +269 -0
  199. package/src/teste/ModalVariantes.test.tsx +173 -0
  200. package/src/teste/NomeAcessivelSsr.test.tsx +110 -0
  201. package/src/teste/OrgChart.test.tsx +183 -0
  202. package/src/teste/OtpInput.test.tsx +163 -0
  203. package/src/teste/PopoverMaxHeight.test.tsx +47 -0
  204. package/src/teste/RichTextEditor.test.tsx +329 -0
  205. package/src/teste/SelectPlacementFiltro.test.tsx +110 -0
  206. package/src/teste/Stack.test.tsx +80 -0
  207. package/src/teste/StatCardRotuloTopo.test.tsx +44 -0
  208. package/src/teste/TabsContadorFechavel.test.tsx +144 -0
  209. package/src/teste/TooltipDark.test.tsx +51 -0
  210. package/src/utils/calendario.ts +78 -0
  211. package/src/utils/html-seguro.ts +94 -0
  212. package/src/utils/paleta-de-cores.ts +34 -0
  213. package/src/utils/texto.ts +5 -0
@@ -0,0 +1,107 @@
1
+ /* ─────────────────────────────────────────────
2
+ ICON PICKER
3
+ Grade de ícones com busca. O escolhido ganha o fundo e a borda do primário.
4
+
5
+ Cores: semânticos · Medidas: primitivos
6
+ ───────────────────────────────────────────── */
7
+
8
+ .umds-icon-picker {
9
+ display: flex;
10
+ flex-direction: column;
11
+ gap: var(--umds-primitive-spacing-nano); /* 8px */
12
+ font-family: var(--umds-semantic-font-family-base);
13
+ }
14
+
15
+ .umds-icon-picker__label {
16
+ font-size: var(--umds-semantic-field-label-size);
17
+ font-weight: var(--umds-semantic-field-label-weight);
18
+ color: var(--umds-semantic-field-label-color);
19
+ }
20
+
21
+ /* Só para leitor de tela: "12 ícones", a cada busca. */
22
+ .umds-icon-picker__sr {
23
+ position: absolute;
24
+ width: 1px;
25
+ height: 1px;
26
+ padding: 0;
27
+ margin: -1px;
28
+ overflow: hidden;
29
+ clip: rect(0, 0, 0, 0);
30
+ clip-path: inset(50%);
31
+ white-space: nowrap;
32
+ border: 0;
33
+ }
34
+
35
+ /* ── Grade ── */
36
+ /* Tamanho do ladrilho: o ícone escolhe, a grade só repete (nada estica quando o container é largo). */
37
+ .umds-icon-picker--md {
38
+ --umds-icon-picker-tile: var(--umds-primitive-spacing-sm); /* 40px */
39
+ }
40
+
41
+ .umds-icon-picker--sm {
42
+ --umds-icon-picker-tile: var(--umds-primitive-spacing-xs); /* 32px */
43
+ }
44
+
45
+ .umds-icon-picker__grid {
46
+ display: grid;
47
+ justify-content: start;
48
+ gap: var(--umds-primitive-spacing-quarck); /* 4px */
49
+ /* Folga para o anel de foco não ser cortado pelo overflow da grade. */
50
+ padding: var(--umds-primitive-spacing-quarck);
51
+ overflow-y: auto;
52
+ }
53
+
54
+ .umds-icon-picker__item {
55
+ display: inline-flex;
56
+ align-items: center;
57
+ justify-content: center;
58
+ box-sizing: border-box;
59
+ min-width: 0;
60
+ margin: 0;
61
+ padding: 0;
62
+ width: var(--umds-icon-picker-tile);
63
+ height: var(--umds-icon-picker-tile);
64
+ border: var(--umds-primitive-border-width-hairline) solid var(--umds-semantic-color-neutral-light-medium);
65
+ border-radius: var(--umds-primitive-border-radius-sm);
66
+ background: var(--umds-semantic-color-background-white);
67
+ color: var(--umds-semantic-color-neutral-dark-down);
68
+ cursor: pointer;
69
+ transition:
70
+ background-color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard),
71
+ border-color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard),
72
+ color var(--umds-semantic-motion-duration-fast) var(--umds-semantic-motion-easing-standard);
73
+ }
74
+
75
+ .umds-icon-picker__item:hover:not(:disabled) {
76
+ background: var(--umds-semantic-color-background-light);
77
+ border-color: var(--umds-semantic-color-neutral-light-down);
78
+ color: var(--umds-semantic-color-neutral-dark-pure);
79
+ }
80
+
81
+ .umds-icon-picker__item--selected,
82
+ .umds-icon-picker__item--selected:hover:not(:disabled) {
83
+ background: var(--umds-semantic-color-primary-light);
84
+ border-color: var(--umds-semantic-color-primary-pure);
85
+ color: var(--umds-semantic-color-primary-dark);
86
+ }
87
+
88
+ .umds-icon-picker__item:focus-visible {
89
+ outline: var(--umds-primitive-border-width-thin) solid var(--umds-semantic-color-primary-pure);
90
+ outline-offset: var(--umds-primitive-border-width-thin);
91
+ }
92
+
93
+ .umds-icon-picker__item:disabled {
94
+ cursor: not-allowed;
95
+ opacity: var(--umds-semantic-field-disabled-opacity);
96
+ }
97
+
98
+ .umds-icon-picker__empty {
99
+ padding: var(--umds-primitive-spacing-xxxs) 0; /* 16px */
100
+ text-align: center;
101
+ }
102
+
103
+ @media (forced-colors: active) {
104
+ .umds-icon-picker__item--selected {
105
+ outline: var(--umds-primitive-border-width-thin) solid Highlight;
106
+ }
107
+ }
@@ -0,0 +1,74 @@
1
+ import './IconPicker.css';
2
+ /**
3
+ * Ícone do IconPicker, quando precisa de nome ou palavras de busca próprios.
4
+ * @property {any} icon - O ícone: o objeto importado do Font Awesome (`faUser`).
5
+ * @property {string} label - Nome para leitor de tela, tooltip e busca (padrão: o nome do ícone, sem hífen).
6
+ * @property {string[]} keywords - Palavras que também acham o ícone na busca (ex.: ["pessoa", "usuário"]).
7
+ */
8
+ export interface IconPickerItem {
9
+ icon: any;
10
+ label?: string;
11
+ keywords?: string[];
12
+ [key: string]: any;
13
+ }
14
+ /**
15
+ * IconPicker — escolha de UM ícone numa grade, com busca.
16
+ *
17
+ * Os ícones vêm por prop (`icons`): objetos do Font Awesome importados
18
+ * (`faUser`, `faFolder`...), puros ou embrulhados em `{ icon, label, keywords }`
19
+ * quando o nome ou a busca precisam de ajuda. O valor é o NOME do ícone
20
+ * (`"user"`, `"file-lines"`), o `iconName` do Font Awesome: guarde o nome e
21
+ * resolva de volta para o objeto na hora de desenhar.
22
+ *
23
+ * É um `radiogroup`: um Tab entra na grade (no ícone escolhido, ou no primeiro)
24
+ * e as setas movem a escolha (esquerda e direita um ícone, cima e baixo uma
25
+ * linha), com Home e End nas pontas. A busca (campo acima da grade, ligada por
26
+ * padrão) filtra por nome e palavras-chave sem acento nem caixa; a seta para
27
+ * baixo no campo leva à grade, e o número de resultados é anunciado.
28
+ *
29
+ * O ícone escolhido ganha fundo e borda do primário, e o resultado vazio mostra
30
+ * `emptyText`. A altura da grade pode ser limitada (`maxHeight`) para listas com
31
+ * dezenas de ícones.
32
+ * @property {any[]} icons - Os ícones: objetos do Font Awesome, ou `{ icon, label?, keywords? }`
33
+ * @property {string} value - Nome do ícone escolhido (controlado)
34
+ * @property {string} defaultValue - Nome inicial (não controlado)
35
+ * @property {string} label - Rótulo visível do grupo
36
+ * @property {string} ariaLabel - Nome acessível quando não há `label` visível
37
+ * @property {number} columns - Colunas da grade (padrão 8)
38
+ * @property {string} size - Tamanho do ícone: 'sm' | 'md' (padrão)
39
+ * @property {number} maxHeight - Altura máxima da grade, em px (rola dentro dela)
40
+ * @property {boolean} hideSearch - Esconde o campo de busca
41
+ * @property {string} searchLabel - Nome do campo de busca (padrão "Buscar ícone")
42
+ * @property {string} searchPlaceholder - Placeholder da busca (padrão "Buscar ícone...")
43
+ * @property {string} emptyText - Texto sem resultados (padrão "Nenhum ícone encontrado")
44
+ * @property {string} resultsLabel - Anúncio da quantidade de resultados; `{count}` vira o número (padrão "{count} ícones")
45
+ * @property {function} iconLabel - Nome de um ícone sem `label`: `(nome) => texto` (padrão: o nome sem hífen)
46
+ * @property {boolean} disabled - Desabilita o grupo inteiro
47
+ * @property {string} id - Base dos ids internos; passe em SSR para os ids já saírem no HTML do servidor
48
+ * @property {string} className - Classes CSS adicionais
49
+ * @property {function} onChange - Chamado com o nome do ícone e o item escolhido
50
+ * @quandoUsar Escolher o ícone de uma categoria, de um tipo de documento, de um perfil, de um atalho.
51
+ * @quandoNaoUsar Para escolher entre poucas opções que o texto descreve melhor, use `SegmentedControl` ou `Select`. Para escolher uma cor, use `ColorPicker`.
52
+ */
53
+ export interface IconPickerProps {
54
+ icons?: any[];
55
+ value?: string;
56
+ defaultValue?: string;
57
+ label?: string;
58
+ ariaLabel?: string;
59
+ columns?: number;
60
+ size?: "sm" | "md";
61
+ maxHeight?: number;
62
+ hideSearch?: boolean;
63
+ searchLabel?: string;
64
+ searchPlaceholder?: string;
65
+ emptyText?: string;
66
+ resultsLabel?: string;
67
+ iconLabel?: (name: string) => string;
68
+ disabled?: boolean;
69
+ id?: string;
70
+ className?: string;
71
+ onChange?: (name: string, item: any) => void;
72
+ }
73
+ declare function IconPicker(props: IconPickerProps): import("react/jsx-runtime").JSX.Element;
74
+ export default IconPicker;
@@ -0,0 +1,194 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import './IconPicker.css';
4
+ import { useState, useRef, useEffect } from "react";
5
+ import Icon from "../Icon/Icon";
6
+ import Input from "../Input/Input";
7
+ import Text from "../Text/Text";
8
+ import { gerarId } from "../../utils/id";
9
+ import { semAcento } from "../../utils/texto";
10
+ import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons";
11
+ function IconPicker(props) {
12
+ const groupRef = useRef(null);
13
+ const focoPendenteRef = useRef(-1);
14
+ const [internalValue, setInternalValue] = useState(() => props.defaultValue || "");
15
+ const [query, setQuery] = useState(() => "");
16
+ const [uid, setUid] = useState(() => "");
17
+ function baseId() {
18
+ return props.id || uid;
19
+ }
20
+ function labelId() {
21
+ return baseId() && props.label ? baseId() + "-label" : undefined;
22
+ }
23
+ function groupAriaLabel() {
24
+ if (props.ariaLabel)
25
+ return props.ariaLabel;
26
+ return props.label && !labelId() ? props.label : undefined;
27
+ }
28
+ function currentValue() {
29
+ return props.value !== undefined ? props.value : internalValue;
30
+ }
31
+ function columnCount() {
32
+ return props.columns && props.columns > 0 ? props.columns : 8;
33
+ }
34
+ function classes() {
35
+ return [
36
+ "umds-icon-picker",
37
+ `umds-icon-picker--${props.size || "md"}`,
38
+ props.disabled ? "umds-icon-picker--disabled" : "",
39
+ props.className,
40
+ ]
41
+ .filter(Boolean)
42
+ .join(" ");
43
+ }
44
+ function gridStyle() {
45
+ const estilo = {
46
+ gridTemplateColumns: "repeat(" + columnCount() + ", var(--umds-icon-picker-tile))",
47
+ };
48
+ if (props.maxHeight)
49
+ estilo.maxHeight = props.maxHeight + "px";
50
+ return estilo;
51
+ }
52
+ function nomeDe(icone) {
53
+ if (!icone)
54
+ return "";
55
+ if (typeof icone === "string")
56
+ return icone;
57
+ return icone.iconName || "";
58
+ }
59
+ function rotuloDe(nome) {
60
+ if (props.iconLabel)
61
+ return props.iconLabel(nome);
62
+ return nome.replace(/-/g, " ");
63
+ }
64
+ function itemList() {
65
+ const lista = props.icons || [];
66
+ const saida = [];
67
+ for (let i = 0; i < lista.length; i++) {
68
+ const bruto = lista[i];
69
+ const embrulhado = !!bruto && bruto.icon !== undefined && bruto.iconName === undefined;
70
+ const icone = embrulhado ? bruto.icon : bruto;
71
+ const nome = nomeDe(icone);
72
+ if (!nome)
73
+ continue;
74
+ const rotulo = embrulhado && bruto.label ? bruto.label : rotuloDe(nome);
75
+ const palavras = embrulhado && bruto.keywords ? bruto.keywords.join(" ") : "";
76
+ saida.push({
77
+ name: nome,
78
+ label: rotulo,
79
+ icon: icone,
80
+ raw: bruto,
81
+ search: semAcento(nome + " " + rotulo + " " + palavras),
82
+ });
83
+ }
84
+ return saida;
85
+ }
86
+ function visibleItems() {
87
+ const busca = semAcento(query);
88
+ if (!busca)
89
+ return itemList();
90
+ return itemList().filter((item) => item.search.indexOf(busca) !== -1);
91
+ }
92
+ function hasResults() {
93
+ return visibleItems().length > 0;
94
+ }
95
+ function emptyMessage() {
96
+ return props.emptyText || "Nenhum ícone encontrado";
97
+ }
98
+ function resultsText() {
99
+ return (props.resultsLabel || "{count} ícones").replace("{count}", String(visibleItems().length));
100
+ }
101
+ function searchName() {
102
+ return props.searchLabel || "Buscar ícone";
103
+ }
104
+ function estaEscolhido(item) {
105
+ return !!currentValue() && item.name === currentValue();
106
+ }
107
+ function itemClasses(item) {
108
+ return [
109
+ "umds-icon-picker__item",
110
+ estaEscolhido(item) ? "umds-icon-picker__item--selected" : "",
111
+ ]
112
+ .filter(Boolean)
113
+ .join(" ");
114
+ }
115
+ function indiceDoTab() {
116
+ const lista = visibleItems();
117
+ for (let i = 0; i < lista.length; i++) {
118
+ if (estaEscolhido(lista[i]))
119
+ return i;
120
+ }
121
+ return 0;
122
+ }
123
+ function tabIndexDe(index) {
124
+ return index === indiceDoTab() ? 0 : -1;
125
+ }
126
+ function escolher(item) {
127
+ if (props.disabled)
128
+ return;
129
+ setInternalValue(item.name);
130
+ if (props.onChange)
131
+ props.onChange(item.name, item.raw);
132
+ }
133
+ function focarEm(index) {
134
+ if (!groupRef.current)
135
+ return;
136
+ const botoes = groupRef.current.querySelectorAll('[role="radio"]');
137
+ const alvo = botoes[index];
138
+ if (alvo)
139
+ alvo.focus();
140
+ }
141
+ function handleKeyDown(event, index) {
142
+ if (!event || event.altKey || event.ctrlKey || event.metaKey)
143
+ return;
144
+ const lista = visibleItems();
145
+ const total = lista.length;
146
+ if (!total)
147
+ return;
148
+ const colunas = columnCount();
149
+ let alvo = index;
150
+ if (event.key === "ArrowRight")
151
+ alvo = (index + 1) % total;
152
+ else if (event.key === "ArrowLeft")
153
+ alvo = (index - 1 + total) % total;
154
+ else if (event.key === "ArrowDown")
155
+ alvo = index + colunas < total ? index + colunas : index;
156
+ else if (event.key === "ArrowUp")
157
+ alvo = index - colunas >= 0 ? index - colunas : index;
158
+ else if (event.key === "Home")
159
+ alvo = 0;
160
+ else if (event.key === "End")
161
+ alvo = total - 1;
162
+ else
163
+ return;
164
+ event.preventDefault();
165
+ if (alvo === index &&
166
+ event.key !== "ArrowRight" &&
167
+ event.key !== "ArrowLeft")
168
+ return;
169
+ escolher(lista[alvo]);
170
+ focoPendenteRef.current = alvo;
171
+ }
172
+ function handleSearch(texto) {
173
+ setQuery(texto);
174
+ }
175
+ function handleSearchKeyDown(event) {
176
+ if (!event || event.key !== "ArrowDown" || !hasResults())
177
+ return;
178
+ event.preventDefault();
179
+ focarEm(indiceDoTab());
180
+ }
181
+ useEffect(() => {
182
+ if (!props.id)
183
+ setUid(gerarId("umds-icon-picker"));
184
+ }, []);
185
+ useEffect(() => {
186
+ if (focoPendenteRef.current >= 0) {
187
+ const alvo = focoPendenteRef.current;
188
+ focoPendenteRef.current = -1;
189
+ focarEm(alvo);
190
+ }
191
+ });
192
+ return (_jsxs("div", { className: classes(), children: [props.label ? (_jsx("span", { className: "umds-icon-picker__label", id: labelId(), children: props.label })) : null, !props.hideSearch ? (_jsx("div", { className: "umds-icon-picker__search", onKeyDown: (event) => handleSearchKeyDown(event), children: _jsx(Input, { size: "sm", type: "search", ariaLabel: searchName(), placeholder: props.searchPlaceholder || "Buscar ícone...", iconLeft: faMagnifyingGlass, value: query, disabled: props.disabled, onChange: (texto) => handleSearch(texto) }) })) : null, _jsx("span", { role: "status", "aria-live": "polite", className: "umds-icon-picker__sr", children: resultsText() }), hasResults() ? (_jsx("div", { role: "radiogroup", className: "umds-icon-picker__grid", ref: groupRef, "aria-label": groupAriaLabel(), "aria-labelledby": labelId(), style: gridStyle(), children: visibleItems()?.map((item, posicao) => (_jsx("button", { type: "button", role: "radio", "aria-checked": estaEscolhido(item) ? "true" : "false", "aria-label": item.label, title: item.label, disabled: props.disabled, tabIndex: tabIndexDe(posicao), onClick: (event) => escolher(item), onKeyDown: (event) => handleKeyDown(event, posicao), className: itemClasses(item), children: _jsx(Icon, { variant: "inherit", icon: item.icon, size: props.size === "sm" ? "sm" : "md" }) }, item.name))) })) : null, !hasResults() ? (_jsx("div", { className: "umds-icon-picker__empty", children: _jsx(Text, { as: "p", variant: "body2", color: "secondary", children: emptyMessage() }) })) : null] }));
193
+ }
194
+ export default IconPicker;
@@ -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,22 @@
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
+
238
276
  /* ── Mobile: fonte ≥16px no controle (decisão 25/07) ──
239
277
  Fonte <16px num campo focado dispara zoom automático no Safari iOS.
240
278
  Só abaixo do breakpoint-sm (640px) — desktop permanece idêntico. */
@@ -34,7 +34,10 @@ 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} 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.
39
+ * @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.
40
+ * @property {function} onChange - Callback acionado A CADA TECLA (recebe o novo valor string), nos dois frameworks. O blur sai em `onBlur`.
38
41
  * @property {function} onFocus - Callback de foco (recebe o evento nativo)
39
42
  * @property {function} onBlur - Callback de blur (recebe o evento nativo)
40
43
  * @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 +90,12 @@ export interface InputProps {
87
90
  hidePasswordLabel?: string;
88
91
  iconLeft?: IconProp;
89
92
  iconsRight?: InputAction[];
93
+ /** Ícone decorativo à direita (não clicável, `aria-hidden`). Para ação, use `iconsRight`. */
94
+ iconRight?: IconProp;
95
+ /** 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 */
96
+ borderless?: boolean;
97
+ /** Máscara simples. O valor exibido e o de `onChange` já saem formatados. */
98
+ mask?: "cpf" | "cnpj" | "cep" | "phone";
90
99
  onChange?: (value: string) => void;
91
100
  onFocus?: (event?: any) => void;
92
101
  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,7 @@ 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 ? "umds-input--borderless" : "",
51
54
  `umds-input--${props.size || "md"}`,
52
55
  props.className,
53
56
  ]
@@ -69,16 +72,74 @@ function Input(props) {
69
72
  function iconSize() {
70
73
  return props.size === "sm" || props.size === "xs" ? "sm" : "md";
71
74
  }
75
+ function aplicarMascara(valor) {
76
+ const texto = valor === undefined || valor === null ? "" : String(valor);
77
+ if (!props.mask)
78
+ return texto;
79
+ let digitos = texto.replace(/\D/g, "");
80
+ let padrao = "";
81
+ if (props.mask === "cpf")
82
+ padrao = "###.###.###-##";
83
+ else if (props.mask === "cnpj")
84
+ padrao = "##.###.###/####-##";
85
+ else if (props.mask === "cep")
86
+ padrao = "#####-###";
87
+ else if (props.mask === "phone")
88
+ padrao = digitos.length > 10 ? "(##) #####-####" : "(##) ####-####";
89
+ let saida = "";
90
+ let posicao = 0;
91
+ for (let i = 0; i < padrao.length && posicao < digitos.length; i++) {
92
+ if (padrao.charAt(i) === "#") {
93
+ saida += digitos.charAt(posicao);
94
+ posicao++;
95
+ }
96
+ else {
97
+ saida += padrao.charAt(i);
98
+ }
99
+ }
100
+ return saida;
101
+ }
102
+ function tamanhoMaximo() {
103
+ if (props.mask === "cpf")
104
+ return 14;
105
+ if (props.mask === "cnpj")
106
+ return 18;
107
+ if (props.mask === "cep")
108
+ return 9;
109
+ if (props.mask === "phone")
110
+ return 15;
111
+ return undefined;
112
+ }
113
+ function modoDoTeclado() {
114
+ return props.mask ? "numeric" : undefined;
115
+ }
116
+ function valorExibido() {
117
+ const bruto = props.value !== undefined ? props.value : internalValue;
118
+ return aplicarMascara(bruto);
119
+ }
72
120
  function handleChange(event) {
73
- setInternalValue(event.target.value);
121
+ const nativo = event.nativeEvent || event;
122
+ if (nativo === ultimoEventoRef.current)
123
+ return;
124
+ ultimoEventoRef.current = nativo;
125
+ const valor = aplicarMascara(event.target.value);
126
+ // O `change` do blur (Vue) repete o que o `input` da última tecla
127
+ // entregou; só passa se o valor mudou de fato (ex.: change disparado à mão).
128
+ if (nativo.type === "change" && valor === ultimoValorRef.current)
129
+ return;
130
+ ultimoValorRef.current = valor;
131
+ if (props.mask && event.target.value !== valor) {
132
+ event.target.value = valor;
133
+ }
134
+ setInternalValue(valor);
74
135
  if (props.onChange) {
75
- props.onChange(event.target.value);
136
+ props.onChange(valor);
76
137
  }
77
138
  }
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 ||
139
+ 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
140
  !!(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
141
  e.stopPropagation();
81
142
  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] }));
143
+ }, 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
144
  }
84
145
  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
+ }