@seedgrid/ai-toolkit 0.0.0-stage → 0.3.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 (225) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +151 -2
  3. package/dist/adapters/claude.js +114 -0
  4. package/dist/adapters/codex.js +108 -0
  5. package/dist/adapters/index.js +17 -0
  6. package/dist/adapters/shared.js +142 -0
  7. package/dist/adapters/types.js +1 -0
  8. package/dist/cli.js +203 -0
  9. package/dist/commands/common.js +98 -0
  10. package/dist/commands/doctor.js +290 -0
  11. package/dist/commands/init.js +9 -0
  12. package/dist/commands/install.js +107 -0
  13. package/dist/commands/remove.js +54 -0
  14. package/dist/commands/review.js +127 -0
  15. package/dist/commands/status.js +73 -0
  16. package/dist/commands/update.js +8 -0
  17. package/dist/commands/validate.js +27 -0
  18. package/dist/core/apply.js +181 -0
  19. package/dist/core/blocks.js +64 -0
  20. package/dist/core/content.js +528 -0
  21. package/dist/core/env.js +40 -0
  22. package/dist/core/frontmatter.js +29 -0
  23. package/dist/core/hash.js +14 -0
  24. package/dist/core/inspect.js +51 -0
  25. package/dist/core/lock.js +124 -0
  26. package/dist/core/paths.js +65 -0
  27. package/dist/core/plan.js +242 -0
  28. package/dist/core/tools.js +62 -0
  29. package/dist/core/types.js +11 -0
  30. package/dist/core/updates.js +121 -0
  31. package/docs/arquitetura.md +80 -0
  32. package/docs/compatibilidade.md +50 -0
  33. package/docs/formato.md +155 -0
  34. package/docs/instalacao.md +105 -0
  35. package/docs/manutencao.md +115 -0
  36. package/package.json +43 -4
  37. package/seedgridKB/SeedGrid/Extensions/Catalogo-de-enums.md +161 -0
  38. package/seedgridKB/SeedGrid/Extensions/Catalogo-de-propriedades.md +971 -0
  39. package/seedgridKB/SeedGrid/Extensions/Indice.md +63 -0
  40. package/seedgridKB/SeedGrid/Extensions/ai-pricing/Configuracao.md +124 -0
  41. package/seedgridKB/SeedGrid/Extensions/ai-pricing/Enums.md +40 -0
  42. package/seedgridKB/SeedGrid/Extensions/ai-pricing/Exemplos.md +97 -0
  43. package/seedgridKB/SeedGrid/Extensions/ai-pricing/Visao-geral.md +114 -0
  44. package/seedgridKB/SeedGrid/Extensions/apikeys/Configuracao-Rust.md +69 -0
  45. package/seedgridKB/SeedGrid/Extensions/apikeys/Configuracao.md +88 -0
  46. package/seedgridKB/SeedGrid/Extensions/apikeys/Enums.md +33 -0
  47. package/seedgridKB/SeedGrid/Extensions/apikeys/Exemplos.md +121 -0
  48. package/seedgridKB/SeedGrid/Extensions/apikeys/Rust.md +126 -0
  49. package/seedgridKB/SeedGrid/Extensions/apikeys/Visao-geral.md +111 -0
  50. package/seedgridKB/SeedGrid/Extensions/audit/Configuracao-Rust.md +93 -0
  51. package/seedgridKB/SeedGrid/Extensions/audit/Configuracao.md +127 -0
  52. package/seedgridKB/SeedGrid/Extensions/audit/Enums.md +66 -0
  53. package/seedgridKB/SeedGrid/Extensions/audit/Exemplos.md +151 -0
  54. package/seedgridKB/SeedGrid/Extensions/audit/Rust.md +120 -0
  55. package/seedgridKB/SeedGrid/Extensions/audit/Visao-geral.md +114 -0
  56. package/seedgridKB/SeedGrid/Extensions/backup/Configuracao-Rust.md +136 -0
  57. package/seedgridKB/SeedGrid/Extensions/backup/Configuracao.md +319 -0
  58. package/seedgridKB/SeedGrid/Extensions/backup/Enums.md +131 -0
  59. package/seedgridKB/SeedGrid/Extensions/backup/Exemplos.md +210 -0
  60. package/seedgridKB/SeedGrid/Extensions/backup/Rust.md +135 -0
  61. package/seedgridKB/SeedGrid/Extensions/backup/Visao-geral.md +150 -0
  62. package/seedgridKB/SeedGrid/Extensions/billing/Configuracao-Rust.md +86 -0
  63. package/seedgridKB/SeedGrid/Extensions/billing/Configuracao.md +243 -0
  64. package/seedgridKB/SeedGrid/Extensions/billing/Enums.md +165 -0
  65. package/seedgridKB/SeedGrid/Extensions/billing/Exemplos.md +205 -0
  66. package/seedgridKB/SeedGrid/Extensions/billing/Rust.md +109 -0
  67. package/seedgridKB/SeedGrid/Extensions/billing/Visao-geral.md +181 -0
  68. package/seedgridKB/SeedGrid/Extensions/broker/Configuracao-Rust.md +40 -0
  69. package/seedgridKB/SeedGrid/Extensions/broker/Visao-geral.md +114 -0
  70. package/seedgridKB/SeedGrid/Extensions/cache/Configuracao-Rust.md +73 -0
  71. package/seedgridKB/SeedGrid/Extensions/cache/Configuracao.md +112 -0
  72. package/seedgridKB/SeedGrid/Extensions/cache/Enums.md +36 -0
  73. package/seedgridKB/SeedGrid/Extensions/cache/Exemplos.md +149 -0
  74. package/seedgridKB/SeedGrid/Extensions/cache/Rust.md +81 -0
  75. package/seedgridKB/SeedGrid/Extensions/cache/Visao-geral.md +90 -0
  76. package/seedgridKB/SeedGrid/Extensions/commons/Configuracao.md +107 -0
  77. package/seedgridKB/SeedGrid/Extensions/commons/Enums.md +105 -0
  78. package/seedgridKB/SeedGrid/Extensions/commons/Exemplos.md +141 -0
  79. package/seedgridKB/SeedGrid/Extensions/commons/Visao-geral.md +99 -0
  80. package/seedgridKB/SeedGrid/Extensions/exchange/Configuracao.md +122 -0
  81. package/seedgridKB/SeedGrid/Extensions/exchange/Enums.md +29 -0
  82. package/seedgridKB/SeedGrid/Extensions/exchange/Exemplos.md +82 -0
  83. package/seedgridKB/SeedGrid/Extensions/exchange/Visao-geral.md +118 -0
  84. package/seedgridKB/SeedGrid/Extensions/filemanagement/Configuracao-Rust.md +110 -0
  85. package/seedgridKB/SeedGrid/Extensions/filemanagement/Configuracao.md +157 -0
  86. package/seedgridKB/SeedGrid/Extensions/filemanagement/Exemplos.md +157 -0
  87. package/seedgridKB/SeedGrid/Extensions/filemanagement/Rust.md +70 -0
  88. package/seedgridKB/SeedGrid/Extensions/filemanagement/Visao-geral.md +88 -0
  89. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Configuracao-Rust.md +124 -0
  90. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Configuracao.md +195 -0
  91. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Enums.md +71 -0
  92. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Exemplos.md +149 -0
  93. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Rust.md +139 -0
  94. package/seedgridKB/SeedGrid/Extensions/login-tenancy/Visao-geral.md +130 -0
  95. package/seedgridKB/SeedGrid/Extensions/notification/Configuracao.md +141 -0
  96. package/seedgridKB/SeedGrid/Extensions/notification/Enums.md +52 -0
  97. package/seedgridKB/SeedGrid/Extensions/notification/Exemplos.md +141 -0
  98. package/seedgridKB/SeedGrid/Extensions/notification/Visao-geral.md +113 -0
  99. package/seedgridKB/SeedGrid/Extensions/privacy/Configuracao-Rust.md +67 -0
  100. package/seedgridKB/SeedGrid/Extensions/privacy/Configuracao.md +94 -0
  101. package/seedgridKB/SeedGrid/Extensions/privacy/Enums.md +79 -0
  102. package/seedgridKB/SeedGrid/Extensions/privacy/Exemplos.md +172 -0
  103. package/seedgridKB/SeedGrid/Extensions/privacy/Rust.md +107 -0
  104. package/seedgridKB/SeedGrid/Extensions/privacy/Visao-geral.md +90 -0
  105. package/seedgridKB/SeedGrid/Extensions/realtime/Configuracao-Rust.md +72 -0
  106. package/seedgridKB/SeedGrid/Extensions/realtime/Configuracao.md +104 -0
  107. package/seedgridKB/SeedGrid/Extensions/realtime/Exemplos.md +104 -0
  108. package/seedgridKB/SeedGrid/Extensions/realtime/Rust.md +69 -0
  109. package/seedgridKB/SeedGrid/Extensions/realtime/Visao-geral.md +105 -0
  110. package/seedgridKB/SeedGrid/Extensions/resilience/Configuracao-Rust.md +68 -0
  111. package/seedgridKB/SeedGrid/Extensions/resilience/Configuracao.md +186 -0
  112. package/seedgridKB/SeedGrid/Extensions/resilience/Enums.md +96 -0
  113. package/seedgridKB/SeedGrid/Extensions/resilience/Exemplos.md +229 -0
  114. package/seedgridKB/SeedGrid/Extensions/resilience/Rust.md +80 -0
  115. package/seedgridKB/SeedGrid/Extensions/resilience/Visao-geral.md +112 -0
  116. package/seedgridKB/SeedGrid/Extensions/runtime/Configuracao-Rust.md +90 -0
  117. package/seedgridKB/SeedGrid/Extensions/runtime/Visao-geral.md +114 -0
  118. package/seedgridKB/SeedGrid/Extensions/security/Configuracao-Rust.md +327 -0
  119. package/seedgridKB/SeedGrid/Extensions/security/Configuracao.md +510 -0
  120. package/seedgridKB/SeedGrid/Extensions/security/Enums.md +95 -0
  121. package/seedgridKB/SeedGrid/Extensions/security/Exemplos.md +218 -0
  122. package/seedgridKB/SeedGrid/Extensions/security/Rust.md +203 -0
  123. package/seedgridKB/SeedGrid/Extensions/security/Visao-geral.md +131 -0
  124. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Configuracao-Rust.md +188 -0
  125. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Configuracao.md +345 -0
  126. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Enums.md +117 -0
  127. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Exemplos.md +205 -0
  128. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Rust.md +161 -0
  129. package/seedgridKB/SeedGrid/Extensions/subdomain-tenancy/Visao-geral.md +142 -0
  130. package/seedgridKB/SeedGrid/Extensions/whatsapp/Configuracao-Rust.md +75 -0
  131. package/seedgridKB/SeedGrid/Extensions/whatsapp/Configuracao.md +152 -0
  132. package/seedgridKB/SeedGrid/Extensions/whatsapp/Enums.md +198 -0
  133. package/seedgridKB/SeedGrid/Extensions/whatsapp/Exemplos.md +173 -0
  134. package/seedgridKB/SeedGrid/Extensions/whatsapp/Rust.md +83 -0
  135. package/seedgridKB/SeedGrid/Extensions/whatsapp/Visao-geral.md +99 -0
  136. package/seedgridKB/SeedGrid/Mapa-dos-repositorios.md +112 -0
  137. package/seedgridKB/SeedGrid/SeedGrid-components/Indice.md +323 -0
  138. package/seedgridKB/SeedGrid/SeedGrid-components/buttons/API.md +257 -0
  139. package/seedgridKB/SeedGrid/SeedGrid-components/buttons/Exemplos.md +307 -0
  140. package/seedgridKB/SeedGrid/SeedGrid-components/buttons/Visao-geral.md +51 -0
  141. package/seedgridKB/SeedGrid/SeedGrid-components/datatable/API.md +174 -0
  142. package/seedgridKB/SeedGrid/SeedGrid-components/datatable/Exemplos.md +236 -0
  143. package/seedgridKB/SeedGrid/SeedGrid-components/datatable/Visao-geral.md +76 -0
  144. package/seedgridKB/SeedGrid/SeedGrid-components/digits/API.md +339 -0
  145. package/seedgridKB/SeedGrid/SeedGrid-components/digits/Exemplos.md +311 -0
  146. package/seedgridKB/SeedGrid/SeedGrid-components/digits/Visao-geral.md +57 -0
  147. package/seedgridKB/SeedGrid/SeedGrid-components/editor/API.md +125 -0
  148. package/seedgridKB/SeedGrid/SeedGrid-components/editor/Exemplos.md +116 -0
  149. package/seedgridKB/SeedGrid/SeedGrid-components/editor/Visao-geral.md +86 -0
  150. package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/API.md +490 -0
  151. package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/Exemplos.md +544 -0
  152. package/seedgridKB/SeedGrid/SeedGrid-components/feedback-e-exibicao/Visao-geral.md +69 -0
  153. package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/API.md +113 -0
  154. package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/Exemplos.md +159 -0
  155. package/seedgridKB/SeedGrid/SeedGrid-components/fundamentos/Visao-geral.md +92 -0
  156. package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/API.md +516 -0
  157. package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/Exemplos.md +629 -0
  158. package/seedgridKB/SeedGrid/SeedGrid-components/gadgets/Visao-geral.md +80 -0
  159. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/API.md +615 -0
  160. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/Exemplos.md +384 -0
  161. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-selecao/Visao-geral.md +111 -0
  162. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/API.md +661 -0
  163. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/Exemplos.md +312 -0
  164. package/seedgridKB/SeedGrid/SeedGrid-components/inputs-texto/Visao-geral.md +123 -0
  165. package/seedgridKB/SeedGrid/SeedGrid-components/layout/API.md +1090 -0
  166. package/seedgridKB/SeedGrid/SeedGrid-components/layout/Exemplos.md +1172 -0
  167. package/seedgridKB/SeedGrid/SeedGrid-components/layout/Visao-geral.md +98 -0
  168. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/Visao-geral.md +98 -0
  169. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-apikeys.md +118 -0
  170. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-audit.md +88 -0
  171. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-backup.md +131 -0
  172. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-billing-platform.md +132 -0
  173. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-billing-user.md +120 -0
  174. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-login-tenancy.md +119 -0
  175. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-security.md +427 -0
  176. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-self-enter.md +104 -0
  177. package/seedgridKB/SeedGrid/SeedGrid-components/modulos/fe-subdomain-tenancy.md +110 -0
  178. package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/API.md +490 -0
  179. package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/Exemplos.md +561 -0
  180. package/seedgridKB/SeedGrid/SeedGrid-components/navegacao-e-overlay/Visao-geral.md +82 -0
  181. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/Visao-geral.md +68 -0
  182. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-commons.md +61 -0
  183. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-core.md +140 -0
  184. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-playground.md +112 -0
  185. package/seedgridKB/SeedGrid/SeedGrid-components/pacotes/fe-theme.md +97 -0
  186. package/seedgridKB/SeedGrid/SeedGrid-components/providers/API.md +177 -0
  187. package/seedgridKB/SeedGrid/SeedGrid-components/providers/Exemplos.md +332 -0
  188. package/seedgridKB/SeedGrid/SeedGrid-components/providers/Visao-geral.md +106 -0
  189. package/seedgridKB/SeedGrid/SeedGrid-components/showcase.md +70 -0
  190. package/seedgridKB/SeedGrid/Toolkit/agents/arquiteto.md +53 -0
  191. package/seedgridKB/SeedGrid/Toolkit/agents/backend-java.md +45 -0
  192. package/seedgridKB/SeedGrid/Toolkit/agents/backend-rust.md +43 -0
  193. package/seedgridKB/SeedGrid/Toolkit/agents/frontend-react.md +41 -0
  194. package/seedgridKB/SeedGrid/Toolkit/agents/qa.md +44 -0
  195. package/seedgridKB/SeedGrid/Toolkit/agents/revisor.md +40 -0
  196. package/seedgridKB/SeedGrid/Toolkit/references/fluxo-de-trabalho.md +78 -0
  197. package/seedgridKB/SeedGrid/Toolkit/references/glossario.md +15 -0
  198. package/seedgridKB/SeedGrid/Toolkit/references/modos-shared-native.md +27 -0
  199. package/seedgridKB/SeedGrid/Toolkit/rules/backend-java-seedgrid.md +54 -0
  200. package/seedgridKB/SeedGrid/Toolkit/rules/coordenacao.md +39 -0
  201. package/seedgridKB/SeedGrid/Toolkit/rules/formato-entrega.md +29 -0
  202. package/seedgridKB/SeedGrid/Toolkit/rules/frontend-seedgrid.md +47 -0
  203. package/seedgridKB/SeedGrid/Toolkit/rules/personalizacao-local.md +22 -0
  204. package/seedgridKB/SeedGrid/Toolkit/skills/planejar-mudanca/SKILL.md +38 -0
  205. package/seedgridKB/SeedGrid/Toolkit/skills/revisar-codigo/SKILL.md +33 -0
  206. package/seedgridKB/SeedGrid/Toolkit/skills/revisar-codigo/references/checklist.md +25 -0
  207. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-backend-crud/SKILL.md +29 -0
  208. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-bump/SKILL.md +26 -0
  209. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/SKILL.md +221 -0
  210. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/agents/openai.yaml +4 -0
  211. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/checklist.md +31 -0
  212. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/patterns.md +185 -0
  213. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-crud/references/routing.md +66 -0
  214. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/SKILL.md +56 -0
  215. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/agents/openai.yaml +4 -0
  216. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/references/checklist.md +32 -0
  217. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-new-screen/references/steps.md +114 -0
  218. package/seedgridKB/SeedGrid/Toolkit/skills/seedgrid-review/SKILL.md +61 -0
  219. package/seedgridKB/SeedGrid/Toolkit/skills/validar-mudanca/SKILL.md +29 -0
  220. package/seedgridKB/SeedGrid/Toolkit/templates/decisao-arquitetura.md +29 -0
  221. package/seedgridKB/SeedGrid/Toolkit/templates/especificacao-tarefa.md +32 -0
  222. package/seedgridKB/SeedGrid/Toolkit/templates/relatorio-validacao.md +30 -0
  223. package/seedgridKB/SeedGrid/Versoes.md +64 -0
  224. package/seedgridKB/SeedGrid/Visao-geral.md +35 -0
  225. package/seedgridKB/manifest.json +142 -0
@@ -0,0 +1,615 @@
1
+ ---
2
+ tags: [seedgrid, component, frontend, react, inputs-selecao, api]
3
+ fonte: front/seedgrid-fe-components/packages/seedgrid-fe-components/src/inputs
4
+ branch: main
5
+ commit: ad30fc11de
6
+ analisado-em: 2026-10-14
7
+ ---
8
+
9
+ # Inputs de seleção: API
10
+
11
+ Pacote `@seedgrid/fe-components` v`2026.7.1`. Contexto: [[SeedGrid/SeedGrid-components/inputs-selecao/Visao-geral|Visão geral dos inputs de seleção]]. Exemplos: [[SeedGrid/SeedGrid-components/inputs-selecao/Exemplos|Exemplos dos inputs de seleção]].
12
+
13
+ As tabelas seguem a metodologia descrita em [[SeedGrid/SeedGrid-components/inputs-texto/API#Como as tabelas foram montadas|Como as tabelas foram montadas]]:
14
+ - tipos e obrigatoriedade vêm do type checker;
15
+ - padrões e descrições foram lidos no código;
16
+ - elas são completas.
17
+
18
+ Props `name`/`control`/`register`/`rules`/`error` seguem o [[SeedGrid/SeedGrid-components/inputs-texto/API#Contrato RhfFieldProps (react-hook-form)|contrato RhfFieldProps]]. Desvios desse contrato estão anotados na descrição de cada prop. `SgAutocomplete`, `SgCombobox` e `SgMultiSelect` herdam do [[SeedGrid/SeedGrid-components/inputs-texto/API#Contrato base SgInputText|contrato base SgInputText]].
19
+
20
+ ## Importação e exportação pública
21
+
22
+ `import { … } from "@seedgrid/fe-components"`. Não existe outro subpath, só `"."` e `"./style.css"`. **Confirmado**.
23
+
24
+ | Componente | Exportado | Tipos/valores públicos associados |
25
+ |---|---|---|
26
+ | `SgAutocomplete` | sim | `SgAutocompleteProps`, `SgAutocompleteItem` (`SgAutocompleteSource` **não** é reexportado) |
27
+ | `SgCombobox` | sim | `SgComboboxProps`, `SgComboboxSource` |
28
+ | `SgCheckboxGroup` | sim | `SgCheckboxGroupProps`, `SgCheckboxGroupOption`, `SgCheckboxGroupOrientation`, `SgCheckboxGroupSelectionStyle`, `SgCheckboxGroupRef` |
29
+ | `SgRadioGroup` | sim | `SgRadioGroupProps`, `SgRadioGroupOption`, `SgRadioGroupOrientation`, `SgRadioGroupSelectionStyle` |
30
+ | `SgMultiSelect` | sim | `SgMultiSelectProps`, `SgMultiSelectOption`, `SgMultiSelectOptionValue` |
31
+ | `SgMultiSelectChips` | sim | `SgMultiSelectChipsProps` |
32
+ | `SgMultiSelectDropdown` | **não** (interno) | Dropdown compartilhado; `SgMultiSelectDropdownProps` não exportado |
33
+ | `useSgMultiSelect` | **não** (interno) | Hook compartilhado por `SgMultiSelect`/`SgMultiSelectChips` |
34
+ | `SgOrderList` | sim | `SgOrderListProps`, `SgOrderListItem`, `SgOrderListSelectionMode`, `SgOrderListControlsPosition`, `SgOrderListRef` |
35
+ | `SgPickList` | sim | `SgPickListProps`, `SgPickListItem`, `SgPickListListName`, `SgPickListSelectionMode`, `SgPickListFilterMatchMode`, `SgPickListChangeType`, `SgPickListValue`, `SgPickListChangeEvent`, `SgPickListRef` |
36
+ | `SgPeriodSelector` | sim | `SgPeriodSelectorProps`, `ResolvedPeriod`, `ResolvePeriodOptions`; valores `PeriodPreset` (enum), `resolvePeriod`, `periodPresetLabel`, `buildPeriodOptions` |
37
+ | `SgYearPartSelector` | sim | `SgYearPartSelectorProps`; de `yearPart.ts`: enum `YearPartKind`, tipos `YearPartValue`, `ResolvedYearPart`, funções `resolveYearPart`, `yearPartOptions`, `yearPartLabel`, `yearPartKindLabel`, `yearPartCount`, `yearPartMonths`, `isValidYearPart`, `clampYearPart`, `yearPartOf` |
38
+ | `SgToggleSwitch` | sim | `SgToggleSwitchProps`. O arquivo também define os aliases `SgSwitch`/`SgSwitchProps`, que **não** são reexportados pelo `index.ts`. |
39
+ | `SgRating` | sim | `SgRatingProps`, `SgRatingSize` |
40
+ | `SgSlider` | sim | `SgSliderProps` |
41
+ | `SgStepperInput` | sim | `SgStepperInputProps` |
42
+
43
+ ## Tipos de item
44
+
45
+ | Tipo | Forma | Fonte |
46
+ |---|---|---|
47
+ | `SgAutocompleteItem` | `{ id: string \| number; label: string; value?: string; group?: string; disabled?: boolean; data?: unknown }` | `SgAutocomplete.tsx` |
48
+ | `SgComboboxSource<T>` | `T[] \| ((query: string) => Promise<T[]> \| T[])` | `SgCombobox.tsx` |
49
+ | `SgCheckboxGroupOption` | `{ label: string; value: string \| number; checked?: boolean; icon?: ReactNode; disabled?: boolean }` | `SgCheckboxGroup.tsx` |
50
+ | `SgRadioGroupOption` | `{ label: string; value: string \| number; icon?: ReactNode; disabled?: boolean }` | `SgRadioGroup.tsx` |
51
+ | `SgMultiSelectOption` | `{ label: string; value: string \| number; chipLabel?: string; disabled?: boolean }` | `useSgMultiSelect.ts` |
52
+ | `SgOrderListItem` / `SgPickListItem` | `{ label: string; value: string \| number; disabled?: boolean; icon?: ReactNode; data?: unknown }` | `SgOrderList.tsx` / `SgPickList.tsx` |
53
+ | `SgPickListChangeType` | `"moveToTarget" \| "moveAllToTarget" \| "moveToSource" \| "moveAllToSource" \| "reorderSource" \| "reorderTarget" \| "dragdrop"` | `SgPickList.tsx` |
54
+ | `ResolvedPeriod` | `{ preset: PeriodPreset; label: string; startDate: Date \| null; endDate: Date \| null }` | `SgPeriodSelector.tsx` |
55
+ | `YearPartValue` / `ResolvedYearPart` | `{ year; kind: YearPartKind; part }` / `{ value; label; startDate: Date; endDate: Date }` | `yearPart.ts` |
56
+
57
+ ## SgAutocomplete
58
+
59
+ Fonte: `src/inputs/SgAutocomplete.tsx`. É um componente genérico, `SgAutocomplete<T = SgAutocompleteItem>`. O input é um `SgInputText`, e a lista é renderizada por portal em `document.body` (`position: fixed`, `z-[1100]`).
60
+
61
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
62
+ |---|---|---|---|---|
63
+ | `value` | `string` | — | Não | Texto exibido (controlado). |
64
+ | `onChange` | `((value: string) => void)` | — | Não | Texto confirmado: label (ou `formatSelection`) ao selecionar; durante digitação emite `""` (ou o texto, se `allowCustomValue`). |
65
+ | `source` | `SgAutocompleteSource<T>` | — | Sim | `(query) => T[] \| Promise<T[]>`. |
66
+ | `mapItem` | `((raw: T) => SgAutocompleteItem)` | identidade | Não | Converte o item cru `T` em `SgAutocompleteItem` (`{id, label, value?, group?, disabled?, data?}`). |
67
+ | `minLengthForSearch` | `number` | `2` | Não | Caracteres mínimos para buscar. |
68
+ | `delay` | `number` | `300` | Não | Debounce da busca em ms. |
69
+ | `maxResult` | `number` | `50` | Não | Máximo de itens exibidos. |
70
+ | `cacheEnabled` | `boolean` | `true` | Não | Cache em memória por query. |
71
+ | `cacheTTL` | `number` | `300000` (5 min) | Não | Validade do cache em ms. |
72
+ | `showDropDownButton` | `boolean` | `false` | Não | Botão chevron que lista o catálogo inteiro. |
73
+ | `openOnFocus` | `boolean` | `false` | Não | Abre a lista já no primeiro caractere digitado, sem esperar `minLengthForSearch`. |
74
+ | `clearOnSelect` | `boolean` | `false` | Não | Limpa o texto após selecionar (emite `""`). |
75
+ | `allowCustomValue` | `boolean` | `false` | Não | Aceita texto livre; se `false`, texto não selecionado é revertido para a última seleção (ou `""`) ao sair. |
76
+ | `grouped` | `boolean` | `false` | Não | Agrupa por `item.group`. |
77
+ | `groupped` | `boolean` | `false` | Não | Alias legado (grafia antiga) de `grouped`. |
78
+ | `placeholderEmpty` | `string` | i18n `components.autocomplete.empty` | Não | Texto de lista vazia. |
79
+ | `loadingText` | `string` | i18n `components.autocomplete.loading` | Não | Texto de carregamento. |
80
+ | `onSelect` | `((item: SgAutocompleteItem) => void)` | — | Não | Recebe o `SgAutocompleteItem` selecionado. |
81
+ | `onSearch` | `((query: string) => void)` | — | Não | Recebe a query pesquisada. |
82
+ | `onOpenChange` | `((open: boolean) => void)` | — | Não | Abertura/fechamento da lista. |
83
+ | `renderItem` | `((item: SgAutocompleteItem, isActive: boolean) => ReactNode)` | — | Não | Render customizado do item. |
84
+ | `renderGroupHeader` | `((group: string) => ReactNode)` | — | Não | Render do cabeçalho de grupo. |
85
+ | `renderFooter` | `((query: string, hasResults: boolean) => ReactNode)` | — | Não | Rodapé da lista `(query, hasResults)`. |
86
+ | `renderEmpty` | `((query: string) => ReactNode)` | — | Não | Render de lista vazia. |
87
+ | `formatSelection` | `((item: SgAutocompleteItem) => string)` | `item.label` | Não | Texto colocado no input ao selecionar. |
88
+ | `renderValue` | `((item: SgAutocompleteItem \| null) => ReactNode)` | — | Não | Render sobreposto do item selecionado (texto do input fica transparente). |
89
+ | `itemTooltip` | `((item: SgAutocompleteItem) => ReactNode)` | — | Não | Tooltip à direita do item no hover. |
90
+
91
+ **Herdadas de `SgInputText` (tipo inalterado; ver contrato base) (45):** `required`, `maxLength`, `minLength`, `name`, `control`, `register`, `rules`, `error`, `id`, `label`, `labelText`, `labelPosition`, `labelWidth`, `labelAlign`, `elevation`, `hintText`, `prefixText`, `suffixText`, `type`, `placeholder`, `className`, `labelClassName`, `inputProps`, `maxLengthMessage`, `minLengthMessage`, `minNumberOfWords`, `minNumberOfWordsMessage`, `prefixIcon`, `width`, `clearButton`, `filled`, `enabled`, `textInputType`, `onEnter`, `onExit`, `onClear`, `withBorder`, `borderRadius`, `requiredMessage`, `showCharCounter`, `iconButtons`, `readOnly`, `validation`, `validateOnBlur`, `onValidation`.
92
+
93
+ **Removidas do contrato base:** nenhuma.
94
+
95
+ - **Valor:** é **texto**, não id. O `onChange` e o campo RHF recebem o label selecionado, ou o retorno de `formatSelection`. Para obter o objeto, use `onSelect(item)`. **Confirmado**.
96
+ - **RHF:**
97
+ - `control`: usa `Controller`, com `value = field.value ?? ""` e `mergeRequiredRule`.
98
+ - `register`: repassa `name`/`register`/`rules` ao `SgInputText`, que registra o input de texto.
99
+ - O teste `tests/rhf-components-contract.test.mjs` cobre os dois caminhos.
100
+ - **Teclado:** ↓/↑ navegam, Enter seleciona e Esc fecha, mas só com a lista aberta. Fora da lista não há atalhos.
101
+ - **Acessibilidade:**
102
+ - O botão dropdown tem `aria-label` = i18n `components.actions.openList`.
103
+ - Não há `role="combobox"`/`listbox`/`option` nem `aria-activedescendant`.
104
+ - **Testes DOM:**
105
+ - texto digitado preservado;
106
+ - texto arbitrário não confirmado sem `allowCustomValue`;
107
+ - botão dropdown lista tudo após uma seleção;
108
+ - botão dropdown mantém o filtro digitado.
109
+
110
+ **Confirmado**.
111
+
112
+ ## SgCombobox
113
+
114
+ Fonte: `src/inputs/SgCombobox.tsx`. É um componente genérico, `SgCombobox<T = SgAutocompleteItem>`. Funciona como um select: o `SgInputText` fica sempre `readOnly`, com `clearButton={false}` e um chevron.
115
+
116
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
117
+ |---|---|---|---|---|
118
+ | `source` | `SgComboboxSource<T>` | — | Sim | Array de `T` ou função `(query) => T[] \| Promise<T[]>` (chamada com `""`). |
119
+ | `value` | `ComboboxValue` | — | Não | `id` selecionado (`string \| number \| null`); controlado quando definido. |
120
+ | `onValueChange` | `((value: ComboboxValue) => void)` | — | Não | Recebe o `id` do item selecionado. |
121
+ | `mapItem` | `((raw: T) => SgAutocompleteItem)` | mapeador padrão | Não | Padrão: strings/números viram `{id,label}`; objetos usam `id ?? value ?? key ?? label` e `label ?? name ?? description ?? title`. |
122
+ | `grouped` | `boolean` | `false` | Não | Agrupa por `group`. |
123
+ | `groupped` | `boolean` | `false` | Não | Alias legado de `grouped`. |
124
+ | `loadingText` | `string` | i18n `components.autocomplete.loading` | Não | Texto de carregamento. |
125
+ | `emptyText` | `string` | i18n `components.autocomplete.empty` | Não | Texto de lista vazia. |
126
+ | `onSelect` | `((value: T) => void)` | — | Não | Recebe o item CRU `T` selecionado (inclusive por type-ahead). |
127
+ | `renderItem` | `((item: SgAutocompleteItem, isActive: boolean) => ReactNode)` | — | Não | Render do item. |
128
+ | `renderValue` | `((item: SgAutocompleteItem \| null) => ReactNode)` | — | Não | Render sobreposto do valor. |
129
+ | `renderGroupHeader` | `((group: string) => ReactNode)` | — | Não | Render de cabeçalho de grupo. |
130
+ | `renderFooter` | `((query: string, hasResults: boolean) => ReactNode)` | — | Não | Rodapé (`query` sempre `""`). |
131
+ | `itemTooltip` | `((item: SgAutocompleteItem) => ReactNode)` | — | Não | Tooltip do item. |
132
+ | `inputProps` | `(InputHTMLAttributes<HTMLInputElement> & { ref?: Ref<HTMLInputElement>; })` | — | Não | Atributos do `<input>` (somente leitura) interno. |
133
+
134
+ **Herdadas de `SgInputText` (tipo inalterado; ver contrato base) (39):** `required`, `maxLength`, `minLength`, `name`, `control`, `rules`, `error`, `id`, `label`, `labelText`, `labelPosition`, `labelWidth`, `labelAlign`, `elevation`, `hintText`, `prefixText`, `suffixText`, `placeholder`, `className`, `labelClassName`, `maxLengthMessage`, `minLengthMessage`, `minNumberOfWords`, `minNumberOfWordsMessage`, `prefixIcon`, `width`, `filled`, `enabled`, `textInputType`, `onEnter`, `onExit`, `onClear`, `withBorder`, `borderRadius`, `requiredMessage`, `showCharCounter`, `validation`, `validateOnBlur`, `onValidation`.
135
+
136
+ **Removidas do contrato base (`Omit`) (5):** `type`, `clearButton`, `onChange`, `iconButtons`, `readOnly`.
137
+
138
+ - **Valor:** é o **`id`** do item (`string | number | null`). `onSelect` entrega o objeto cru `T`. **Confirmado**.
139
+ - **Type-ahead:** com o campo focado, digitar seleciona o primeiro label que começa com o texto acumulado. O buffer zera depois de 700 ms (`TYPEAHEAD_RESET_MS`). **Confirmado**.
140
+ - **Teclado:**
141
+ - ↓/↑ abrem a lista ou navegam nela.
142
+ - Enter/Espaço abrem a lista ou selecionam.
143
+ - Esc e Tab fecham.
144
+
145
+ **Confirmado** (`onKeyDown` em `SgCombobox.tsx`).
146
+ - **RHF:**
147
+ - Só `control`+`name` integram. O `field.value` é o id.
148
+ - `rules` são repassadas **sem** `mergeRequiredRule`: `required` não vira regra automaticamente.
149
+ - Para formulário, use `control` + `name`.
150
+
151
+ **Confirmado**.
152
+ - **Acessibilidade:** o chevron tem `aria-label` traduzido. Não há roles ARIA de combobox/listbox.
153
+
154
+ ## SgCheckboxGroup
155
+
156
+ Fonte: `src/inputs/SgCheckboxGroup.tsx`. O grupo é renderizado dentro de um `SgGroupBox`. Usa `forwardRef<SgCheckboxGroupRef>`.
157
+
158
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
159
+ |---|---|---|---|---|
160
+ | `id` | `string` | — | Não | Usado como `name` dos checkboxes quando `name` ausente. |
161
+ | `title` | `string` | — | Não | Título do `SgGroupBox` (ganha ` *` se `required`). |
162
+ | `source` | `SgCheckboxGroupOption[]` | — | Sim | Opções `{label, value, checked?, icon?, disabled?}`; `checked` define o valor inicial não controlado. |
163
+ | `value` | `(string \| number)[]` | — | Não | Valores marcados (controlado). |
164
+ | `orientation` | `SgCheckboxGroupOrientation` | `"vertical"` | Não | `vertical` ou `horizontal`. |
165
+ | `selectionStyle` | `SgCheckboxGroupSelectionStyle` | `"checkbox"` | Não | `checkbox` ou `highlight` (lista com destaque). |
166
+ | `iconOnly` | `boolean` | `false` | Não | Mostra só o ícone. |
167
+ | `disabled` | `boolean` | `false` | Não | Desabilita tudo. |
168
+ | `readOnly` | `boolean` | `false` | Não | Somente leitura. |
169
+ | `required` | `boolean` | `false` | Não | Asterisco no título, `aria-required` e regra `required` no RHF. |
170
+ | `onChange` | `((value: (string \| number)[]) => void)` | — | Não | Recebe o array de valores marcados. |
171
+ | `showCheckAll` | `boolean` | `false` | Não | Mostra "selecionar todos" (só opções habilitadas). |
172
+ | `checkAllLabel` | `string` | i18n `components.checkboxgroup.checkAll` | Não | Rótulo do selecionar todos. |
173
+ | `checkAllIcon` | `ReactNode` | — | Não | Ícone do selecionar todos. |
174
+ | `className` | `string` | `""` | Não | Classes do wrapper. |
175
+ | `style` | `CSSProperties` | — | Não | Estilo do wrapper. |
176
+ | `optionClassName` | `string` | `""` | Não | Classes de cada opção. |
177
+ | `groupBoxProps` | `(Omit<Partial<SgGroupBoxProps>, "title" \| "children"> & { title?: string; })` | `{}` | Não | Props repassadas ao `SgGroupBox` (`title` aqui tem precedência sobre `title`). |
178
+ | `name` | `string` | — | Não | Nome do campo no react-hook-form. Só tem efeito junto com `control` ou `register` (ver contrato RHF). |
179
+ | `control` | `any` | — | Não | `Control` do `useForm()`; com `name`, envolve o componente em `<Controller>`. |
180
+ | `register` | `UseFormRegister<any>` | — | Não | `register` do `useForm()`; com `name`, registra o elemento nativo. |
181
+ | `rules` | `RegisterOptions<any>` | — | Não | Regras de validação do RHF (`RegisterOptions`). |
182
+ | `error` | `string` | — | Não | Erro exibido abaixo do grupo (com `control`, combinado com `fieldState.error`). |
183
+
184
+ **Ref (`SgCheckboxGroupRef`)**:
185
+
186
+ | Método | Efeito |
187
+ |---|---|
188
+ | `getChecked(): (string \| number)[]` | Valores marcados. |
189
+ | `setChecked(values)` | Define os marcados e dispara `onChange`. |
190
+ | `checkAll()` | Marca todas as opções habilitadas. |
191
+ | `clearAll()` | Desmarca tudo. |
192
+
193
+ - **RHF:** `control` tem precedência sobre `register` e usa `mergeRequiredRule`.
194
+ - **No caminho `control`, o ref imperativo não é ligado**: o componente base é chamado com `imperativeRef` `undefined`.
195
+ - Com `register`, cada `<input type="checkbox">` recebe o `registration`.
196
+
197
+ **Confirmado**.
198
+ - **Acessibilidade:** container com `role="group"`, mais `aria-disabled`, `aria-readonly` e `aria-required`, sobre inputs nativos.
199
+
200
+ ## SgRadioGroup
201
+
202
+ Fonte: `src/inputs/SgRadioGroup.tsx`. Usa `SgGroupBox` e **não** tem ref.
203
+
204
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
205
+ |---|---|---|---|---|
206
+ | `id` | `string` | — | Não | Usado como `name` dos radios quando `name` ausente. |
207
+ | `title` | `string` | — | Não | Título do `SgGroupBox` (` *` se `required`). |
208
+ | `source` | `SgRadioGroupOption[]` | — | Sim | Opções `{label, value, icon?, disabled?}`. |
209
+ | `value` | `string \| number` | — | Não | Valor selecionado (controlado). |
210
+ | `orientation` | `SgRadioGroupOrientation` | `"vertical"` | Não | `vertical` ou `horizontal`. |
211
+ | `selectionStyle` | `SgRadioGroupSelectionStyle` | `"radio"` | Não | `radio` ou `highlight`. |
212
+ | `iconOnly` | `boolean` | `false` | Não | Só ícone. |
213
+ | `disabled` | `boolean` | `false` | Não | Desabilita. |
214
+ | `readOnly` | `boolean` | `false` | Não | Somente leitura. |
215
+ | `required` | `boolean` | `false` | Não | Asterisco, `aria-required` e regra `required` no RHF. |
216
+ | `onChange` | `((value: string \| number \| null) => void)` | — | Não | Recebe o valor selecionado (`string \| number \| null`). |
217
+ | `className` | `string` | `""` | Não | Classes do wrapper. |
218
+ | `style` | `CSSProperties` | — | Não | Estilo do wrapper. |
219
+ | `optionClassName` | `string` | `""` | Não | Classes de cada opção. |
220
+ | `groupBoxProps` | `(Omit<Partial<SgGroupBoxProps>, "title" \| "children"> & { title?: string; })` | `{}` | Não | Props do `SgGroupBox`. |
221
+ | `name` | `string` | — | Não | Nome do campo no react-hook-form. Só tem efeito junto com `control` ou `register` (ver contrato RHF). |
222
+ | `control` | `any` | — | Não | `Control` do `useForm()`; com `name`, envolve o componente em `<Controller>`. |
223
+ | `register` | `UseFormRegister<any>` | — | Não | `register` do `useForm()`; com `name`, registra o elemento nativo. |
224
+ | `rules` | `RegisterOptions<any>` | — | Não | Regras de validação do RHF (`RegisterOptions`). |
225
+ | `error` | `string` | — | Não | Erro exibido abaixo do grupo. |
226
+
227
+ - **RHF:** `control` tem precedência, com `mergeRequiredRule`. Com `register`, os `<input type="radio">` recebem o `registration`.
228
+ - **Acessibilidade:** `role="radiogroup"`, `aria-disabled`, `aria-readonly`, `aria-required`.
229
+
230
+ **Confirmado**.
231
+
232
+ ## SgMultiSelect
233
+
234
+ Fonte: `src/inputs/SgMultiSelect.tsx`, `useSgMultiSelect.ts` e `SgMultiSelectDropdown.tsx`. O gatilho é um `SgInputText` `readOnly`. O texto exibido junta os rótulos selecionados até `summaryThreshold`; acima disso mostra o resumo i18n `components.inputs.multiSelect.summary`.
235
+
236
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
237
+ |---|---|---|---|---|
238
+ | `onExit` | `() => void` | — | Não | Disparado no blur, exceto quando o foco vai para o dropdown/wrapper. |
239
+ | `options` | `SgMultiSelectOption[]` | — | Sim | `{label, value, chipLabel?, disabled?}`. |
240
+ | `value` | `SgMultiSelectOptionValue[]` | — | Não | Valores selecionados (controlado). |
241
+ | `onChange` | `((value: SgMultiSelectOptionValue[]) => void)` | — | Não | Recebe o array de valores selecionados. |
242
+ | `searchable` | `boolean` | `false` | Não | Campo de busca no dropdown. |
243
+ | `searchPlaceholder` | `string` | — | Não | Placeholder da busca. |
244
+ | `clearable` | `boolean` | `false` | Não | Botão limpar seleção. |
245
+ | `maxSelected` | `number` | — | Não | Limite de seleção (opções extras ficam bloqueadas). |
246
+ | `emptyText` | `string` | i18n `components.autocomplete.empty` | Não | Texto sem opções. |
247
+ | `summaryThreshold` | `number` | `2` | Não | Quantos rótulos exibir antes do resumo "N selecionadas" (`components.inputs.multiSelect.summary`). |
248
+
249
+ **Herdadas de `SgInputText` (tipo inalterado; ver contrato base) (34):** `required`, `name`, `control`, `rules`, `error`, `id`, `label`, `labelText`, `labelPosition`, `labelWidth`, `labelAlign`, `elevation`, `hintText`, `prefixText`, `suffixText`, `placeholder`, `className`, `labelClassName`, `maxLengthMessage`, `minLengthMessage`, `minNumberOfWords`, `minNumberOfWordsMessage`, `prefixIcon`, `width`, `filled`, `enabled`, `textInputType`, `onClear`, `withBorder`, `borderRadius`, `requiredMessage`, `validation`, `validateOnBlur`, `onValidation`.
250
+
251
+ **Removidas do contrato base (`Omit`) (8):** `type`, `inputProps`, `maxLength`, `minLength`, `clearButton`, `showCharCounter`, `iconButtons`, `readOnly`.
252
+
253
+ - **Valor:** `(string | number)[]`. Comparação por `String(a) === String(b)`.
254
+ - **RHF:** via `control`+`name`, com `field.value ?? []`. `rules` sem `mergeRequiredRule`.
255
+ - **Teclado:**
256
+ - No gatilho: Esc fecha; ↓/Enter/Espaço abrem ou navegam.
257
+ - No dropdown (`useSgMultiSelect`): Esc, Tab, ↑/↓, Enter/Espaço alternam a seleção.
258
+ - **Acessibilidade:**
259
+ - Gatilho com `role="combobox"`, `aria-expanded`, `aria-haspopup="listbox"`.
260
+ - Dropdown com `role="listbox"` e `aria-multiselectable`; opções com `role="option"` e `aria-selected`.
261
+ - **Testes DOM:**
262
+ - abre no clique;
263
+ - mantém aberto ao alternar;
264
+ - busca;
265
+ - limpar;
266
+ - `chipLabel` no resumo.
267
+
268
+ **Confirmado**.
269
+
270
+ ## SgMultiSelectChips
271
+
272
+ Fonte: `src/inputs/SgMultiSelectChips.tsx`. Mesma lógica e dropdown do `SgMultiSelect`, mas mostra um chip removível por seleção. **Não** herda de `SgInputText`: o tipo é próprio, com `RhfFieldProps`.
273
+
274
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
275
+ |---|---|---|---|---|
276
+ | `name` | `string` | — | Não | Nome do campo no react-hook-form. Só tem efeito junto com `control` ou `register` (ver contrato RHF). |
277
+ | `control` | `any` | — | Não | `Control` do `useForm()`; com `name`, envolve o componente em `<Controller>`. |
278
+ | `rules` | `RegisterOptions<any>` | — | Não | Regras de validação do RHF (`RegisterOptions`). |
279
+ | `error` | `string` | — | Não | Erro abaixo do campo. |
280
+ | `id` | `string` | — | Sim | `id` do gatilho. |
281
+ | `label` | `string` | — | Não | Rótulo. |
282
+ | `labelText` | `string` | — | Não | Rótulo; precedência sobre `label`. |
283
+ | `className` | `string` | — | Não | Classes do wrapper. |
284
+ | `labelClassName` | `string` | — | Não | Classes do rótulo. |
285
+ | `width` | `string \| number` | — | Não | Largura. |
286
+ | `borderRadius` | `string \| number` | — | Não | Raio da borda. |
287
+ | `enabled` | `boolean` | `true` (efetivo) | Não | `false` desabilita. |
288
+ | `required` | `boolean` | — | Não | Exibe `*` (não injeta regra RHF). |
289
+ | `options` | `SgMultiSelectOption[]` | — | Sim | `{label, value, chipLabel?, disabled?}`; o chip mostra `chipLabel ?? label`. |
290
+ | `value` | `SgMultiSelectOptionValue[]` | — | Não | Valores selecionados (controlado). |
291
+ | `onChange` | `((value: SgMultiSelectOptionValue[]) => void)` | — | Não | Recebe o array de valores. |
292
+ | `searchable` | `boolean` | `false` | Não | Busca no dropdown. |
293
+ | `searchPlaceholder` | `string` | — | Não | Placeholder da busca. |
294
+ | `clearable` | `boolean` | `false` | Não | Botão limpar seleção. |
295
+ | `maxSelected` | `number` | — | Não | Limite de seleção. |
296
+ | `emptyText` | `string` | i18n `components.autocomplete.empty` | Não | Texto sem opções. |
297
+ | `placeholder` | `string` | i18n `components.inputs.select.placeholder` | Não | Texto sem seleção. |
298
+ | `onEnter` | `(() => void)` | — | Não | Chamado ao receber foco. |
299
+ | `onExit` | `(() => void)` | — | Não | Chamado ao perder o foco (após a validação). |
300
+
301
+ - **Acessibilidade:**
302
+ - Gatilho com `role="combobox"`, `aria-expanded`, `aria-haspopup="listbox"`.
303
+ - Remover chip tem `aria-label` = i18n `components.inputs.multiSelect.removeChip`.
304
+ - Limpar e abrir usam as chaves `components.actions.*`.
305
+ - **Testes DOM:** chip por seleção, remoção, limpar, busca, `chipLabel` no chip e `label` no `title`, abertura pelo chevron.
306
+
307
+ **Confirmado**.
308
+
309
+ ## SgOrderList
310
+
311
+ Fonte: `src/inputs/SgOrderList.tsx`. Lista reordenável por botões, por teclado ou por arrastar e soltar. Usa `forwardRef<SgOrderListRef>`. Os botões são `SgButton`, dentro de um `SgGroupBox`.
312
+
313
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
314
+ |---|---|---|---|---|
315
+ | `error` | `string` | — | Não | Erro exibido acima da lista. |
316
+ | `id` | `string` | — | Não | Identificador. |
317
+ | `title` | `string` | — | Não | Título do `SgGroupBox`. |
318
+ | `source` | `SgOrderListItem[]` | — | Sim | Itens `{label, value, disabled?, icon?, data?}` (estado inicial e ressincronizado quando não controlado). |
319
+ | `value` | `SgOrderListItem[]` | — | Não | Ordem controlada. |
320
+ | `onChange` | `((items: SgOrderListItem[]) => void)` | — | Não | Recebe o array reordenado. |
321
+ | `selectedValues` | `(string \| number)[]` | — | Não | Seleção controlada (valores). |
322
+ | `onSelectionChange` | `((values: (string \| number)[]) => void)` | — | Não | Recebe os valores selecionados. |
323
+ | `selectionMode` | `SgOrderListSelectionMode` | `"multiple"` | Não | `single` ou `multiple`. |
324
+ | `showControls` | `boolean` | `true` | Não | Botões Topo/Subir/Descer/Base. |
325
+ | `controlsPosition` | `SgOrderListControlsPosition` | `"left"` | Não | `left` ou `right`. |
326
+ | `draggable` | `boolean` | `true` | Não | Arrastar e soltar. |
327
+ | `disabled` | `boolean` | `false` | Não | Desabilita. |
328
+ | `readOnly` | `boolean` | `false` | Não | Somente leitura. |
329
+ | `emptyMessage` | `string` | i18n `components.orderlist.empty` | Não | Texto de lista vazia. |
330
+ | `itemTemplate` | `((item: SgOrderListItem, state: { index: number; selected: boolean; disabled: boolean; }) => ReactNode)` | — | Não | Render do item `(item, {index, selected, disabled})`. |
331
+ | `className` | `string` | `""` | Não | Classes do wrapper. |
332
+ | `style` | `CSSProperties` | — | Não | Estilo do wrapper. |
333
+ | `listClassName` | `string` | `""` | Não | Classes da lista. |
334
+ | `itemClassName` | `string` | `""` | Não | Classes do item. |
335
+ | `groupBoxProps` | `(Omit<Partial<SgGroupBoxProps>, "title" \| "children"> & { title?: string; })` | `{}` | Não | Props do `SgGroupBox`. |
336
+ | `name` | `string` | — | Não | Nome do campo no react-hook-form. Só tem efeito junto com `control` ou `register` (ver contrato RHF). |
337
+ | `control` | `any` | — | Não | `Control` do `useForm()`; com `name`, envolve o componente em `<Controller>`. |
338
+ | `rules` | `RegisterOptions<any>` | — | Não | Regras de validação do RHF (`RegisterOptions`). |
339
+
340
+ **Ref (`SgOrderListRef`)**: `getItems()`, `setItems(items)`, `getSelection()`, `setSelection(values)`, `moveTop()`, `moveUp()`, `moveDown()`, `moveBottom()`, `clearSelection()`.
341
+
342
+ - **Teclado no item:**
343
+ - Espaço/Enter selecionam.
344
+ - Ctrl/⌘+↑/↓ sobem ou descem.
345
+ - Ctrl/⌘+Home/End levam ao topo ou à base.
346
+ - **Acessibilidade:** `role="listbox"`, `aria-multiselectable`, itens `<button role="option" aria-selected>`, botões com `aria-label` i18n `components.orderlist.move*`.
347
+ - **RHF:** só `control`+`name`. O campo guarda o **array de itens**, não os valores.
348
+
349
+ **Confirmado**.
350
+
351
+ ## SgPickList
352
+
353
+ Fonte: `src/inputs/SgPickList.tsx`. Duas listas, origem e destino, com transferência, reordenação, filtro e arrastar e soltar. Usa `forwardRef<SgPickListRef>`.
354
+
355
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
356
+ |---|---|---|---|---|
357
+ | `error` | `string` | — | Não | Erro exibido. |
358
+ | `id` | `string` | — | Não | Identificador. |
359
+ | `title` | `string` | — | Não | Título do `SgGroupBox`. |
360
+ | `source` | `SgPickListItem[]` | — | Sim | Itens da lista de origem (estado inicial não controlado). |
361
+ | `target` | `SgPickListItem[]` | — | Sim | Itens da lista de destino. |
362
+ | `value` | `SgPickListValue` | — | Não | `{source, target}` controlado. |
363
+ | `onChange` | `((event: SgPickListChangeEvent) => void)` | — | Não | Recebe `SgPickListChangeEvent` = `{source, target, type}`. |
364
+ | `sourceSelection` | `(string \| number)[]` | — | Não | Seleção controlada da origem. |
365
+ | `targetSelection` | `(string \| number)[]` | — | Não | Seleção controlada do destino. |
366
+ | `onSourceSelectionChange` | `((values: (string \| number)[]) => void)` | — | Não | Seleção da origem mudou. |
367
+ | `onTargetSelectionChange` | `((values: (string \| number)[]) => void)` | — | Não | Seleção do destino mudou. |
368
+ | `selectionMode` | `SgPickListSelectionMode` | `"multiple"` | Não | `single` ou `multiple`. |
369
+ | `sourceHeader` | `string` | i18n `components.picklist.sourceHeader` | Não | Cabeçalho da origem. |
370
+ | `targetHeader` | `string` | i18n `components.picklist.targetHeader` | Não | Cabeçalho do destino. |
371
+ | `showTransferControls` | `boolean` | `true` | Não | Botões de transferência. |
372
+ | `showSourceControls` | `boolean` | `true` | Não | Botões de ordenação da origem. |
373
+ | `showTargetControls` | `boolean` | `true` | Não | Botões de ordenação do destino. |
374
+ | `showSourceFilter` | `boolean` | `false` | Não | Filtro na origem. |
375
+ | `showTargetFilter` | `boolean` | `false` | Não | Filtro no destino. |
376
+ | `sourceFilterPlaceholder` | `string` | i18n `components.picklist.sourceFilterPlaceholder` | Não | Placeholder do filtro de origem. |
377
+ | `targetFilterPlaceholder` | `string` | i18n `components.picklist.targetFilterPlaceholder` | Não | Placeholder do filtro de destino. |
378
+ | `filterMatchMode` | `SgPickListFilterMatchMode` | `"contains"` | Não | `contains`, `startsWith`, `endsWith`. |
379
+ | `draggable` | `boolean` | `true` | Não | Arrastar e soltar entre/dentro das listas. |
380
+ | `disabled` | `boolean` | `false` | Não | Desabilita. |
381
+ | `readOnly` | `boolean` | `false` | Não | Somente leitura. |
382
+ | `emptyMessage` | `string` | i18n `components.picklist.empty` | Não | Texto de lista vazia. |
383
+ | `itemTemplate` | `((item: SgPickListItem, state: { index: number; selected: boolean; disabled: boolean; list: SgPickListListName; }) => ReactNode)` | — | Não | Render `(item, {index, selected, disabled, list})`. |
384
+ | `className` | `string` | `""` | Não | Classes do wrapper. |
385
+ | `style` | `CSSProperties` | — | Não | Estilo. |
386
+ | `listClassName` | `string` | `""` | Não | Classes das listas. |
387
+ | `itemClassName` | `string` | `""` | Não | Classes dos itens. |
388
+ | `groupBoxProps` | `(Omit<Partial<SgGroupBoxProps>, "title" \| "children"> & { title?: string; })` | `{}` | Não | Props do `SgGroupBox`. |
389
+ | `name` | `string` | — | Não | Nome do campo no react-hook-form. Só tem efeito junto com `control` ou `register` (ver contrato RHF). |
390
+ | `control` | `any` | — | Não | `Control` do `useForm()`; com `name`, envolve o componente em `<Controller>`. |
391
+ | `rules` | `RegisterOptions<any>` | — | Não | Regras de validação do RHF (`RegisterOptions`). |
392
+
393
+ - **Ref (`SgPickListRef`):** `getValue()`, `setValue(value)` (emite `onChange` com `type: "dragdrop"`), `moveToTarget()`, `moveAllToTarget()`, `moveToSource()`, `moveAllToSource()`, `clearSelection()`.
394
+ - **Evento:** `onChange({ source, target, type })`. No RHF, `field.onChange({ source, target })`, sem o `type`.
395
+ - **Acessibilidade:** cada lista tem `role="listbox"`; itens `<button role="option" aria-selected>`. Os botões têm `aria-label` traduzido (`components.picklist.*`, `components.orderlist.*`). Não há atalhos de teclado além do clique nativo nos botões.
396
+
397
+ **Confirmado**.
398
+
399
+ ## SgPeriodSelector
400
+
401
+ Fonte: `src/inputs/SgPeriodSelector.tsx`. É um `SgCombobox` agrupado com presets temporais. Com `CUSTOM` aparecem dois `SgInputDate`.
402
+
403
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
404
+ |---|---|---|---|---|
405
+ | `id` | `string` | `"sg-period-selector"` | Não | Id do combo; datas customizadas usam `<id>-custom-start`/`-end`. |
406
+ | `label` | `string` | — | Não | Rótulo. |
407
+ | `value` | `PeriodPreset` | — | Não | Preset selecionado (`PeriodPreset`), controlado. |
408
+ | `onChange` | `((period: ResolvedPeriod) => void)` | — | Não | Recebe `ResolvedPeriod` `{preset, label, startDate, endDate}`. Não dispara na montagem. |
409
+ | `permitPast` | `boolean` | `true` | Não | Grupo LAST_*. |
410
+ | `permitCurrent` | `boolean` | `true` | Não | Grupo THIS_*, TODAY, YESTERDAY. |
411
+ | `permitFuture` | `boolean` | `true` | Não | Grupo TOMORROW, NEXT_*. |
412
+ | `permitAll` | `boolean` | `true` | Não | Opção ALL (datas nulas). |
413
+ | `allowCustomPeriod` | `boolean` | `true` | Não | Opção CUSTOM com dois `SgInputDate`. |
414
+ | `locale` | `string` | `"pt-BR"` | Não | Locale dos rótulos (independe do provider i18n). |
415
+ | `disabled` | `boolean` | — | Não | Desabilita. |
416
+ | `required` | `boolean` | — | Não | Repassado ao `SgCombobox` (asterisco). |
417
+ | `minDate` | `Date` | — | Não | Clamp do início do intervalo. |
418
+ | `maxDate` | `Date` | — | Não | Clamp do fim do intervalo. |
419
+ | `referenceDate` | `Date` | `new Date()` | Não | Data de referência dos presets. |
420
+ | `className` | `string` | — | Não | Classes do wrapper (`max-w-[18rem]`). |
421
+ | `error` | `string` | — | Não | Erro. |
422
+ | `control` | `Control<FieldValues>` | — | Não | RHF: o campo guarda o `preset` (string), não o intervalo. |
423
+ | `name` | `string` | — | Não | Nome RHF. |
424
+ | `rules` | `RegisterOptions` | — | Não | Regras RHF. |
425
+
426
+ **Presets (`PeriodPreset`)**:
427
+ - `ALL`, `CUSTOM`;
428
+ - `TODAY`, `YESTERDAY`, `TOMORROW`;
429
+ - `THIS_` / `LAST_` / `NEXT_` combinados com `WEEK`, `QUINZENA`, `MONTH`, `QUARTER`, `SEMESTER` e `YEAR`.
430
+
431
+ Convenções do `resolvePeriod` (cobertas por `tests/period-resolver.test.mjs`; **Confirmado**):
432
+ - A semana começa na **segunda-feira**.
433
+ - A quinzena é de calendário: dias 1–15 e 16–fim do mês.
434
+ - `startDate` = 00:00:00.000 local; `endDate` = 23:59:59.999 local.
435
+ - `ALL`/`CUSTOM` devolvem datas `null`.
436
+ - `minDate`/`maxDate` fazem clamp.
437
+
438
+ Mais detalhes:
439
+ - **i18n:** os rótulos têm tabela própria, em ASCII e sem o provider: `pt-BR`, `en-US`, `es`, `pt-PT`, `fr`.
440
+ - **RHF:** só `control`. O campo guarda o **`PeriodPreset`**; o intervalo resolvido sai em `onChange`.
441
+ - **CUSTOM:** emite um novo `ResolvedPeriod` a cada mudança nas datas. Datas incompletas (ano < 1000) viram `null`.
442
+
443
+ **Confirmado**.
444
+
445
+ ## SgYearPartSelector
446
+
447
+ Fonte: `src/inputs/SgYearPartSelector.tsx` + `yearPart.ts`. Tem três `SgCombobox` (ano, recorte, fatia) e responde a "o 1º semestre de 2024", enquanto o `SgPeriodSelector` responde a "este semestre". **Sem integração RHF**: o tipo não tem `control`/`name`.
448
+
449
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
450
+ |---|---|---|---|---|
451
+ | `id` | `string` | `"sg-year-part-selector"` | Não | Prefixo dos ids dos três combos (`-year`, `-kind`, `-part`). |
452
+ | `label` | `string` | — | Não | Rótulo do grupo. |
453
+ | `value` | `YearPartValue` | — | Não | `YearPartValue` `{year, kind, part}` controlado. |
454
+ | `onChange` | `((resolved: ResolvedYearPart) => void)` | — | Não | Recebe `ResolvedYearPart` `{value, label, startDate, endDate}` (datas nunca nulas). Não dispara na montagem. |
455
+ | `allowedKinds` | `YearPartKind[]` | os três (`SEMESTER`, `QUARTER`, `BIMESTER`) | Não | Recortes oferecidos; com um só, o combo de recorte some. Array vazio → padrão. |
456
+ | `minYear` | `number` | ano atual − 30 | Não | Primeiro ano da lista. |
457
+ | `maxYear` | `number` | ano atual + 10 | Não | Último ano. |
458
+ | `locale` | `string` | `"pt-BR"` | Não | Locale dos rótulos. |
459
+ | `disabled` | `boolean` | — | Não | Desabilita os três combos. |
460
+ | `required` | `boolean` | — | Não | Asterisco no rótulo e nos combos. |
461
+ | `className` | `string` | — | Não | Classes do wrapper. |
462
+
463
+ - **Estado inicial:** ano corrente, primeiro recorte permitido, fatia de hoje.
464
+ - **Normalização:** um `value` controlado inconsistente é ajustado com `clampYearPart`, e um recorte fora de `allowedKinds` vira o primeiro permitido.
465
+ - **Testes:** `tests/year-part-resolver.test.mjs` cobre fatias, ano bissexto, clamp, rótulos por locale e `yearPartOf`.
466
+
467
+ **Confirmado**.
468
+
469
+ ## SgToggleSwitch
470
+
471
+ Fonte: `src/inputs/SgToggleSwitch.tsx`. É um `<input type="checkbox" role="switch">` estilizado.
472
+
473
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
474
+ |---|---|---|---|---|
475
+ | `name` | `string` | — | Não | Nome do campo no react-hook-form. Só tem efeito junto com `control` ou `register` (ver contrato RHF). |
476
+ | `control` | `any` | — | Não | `Control` do `useForm()`; com `name`, envolve o componente em `<Controller>`. |
477
+ | `register` | `UseFormRegister<any>` | — | Não | `register` do `useForm()`; com `name`, registra o elemento nativo. |
478
+ | `rules` | `RegisterOptions<any>` | — | Não | Regras de validação do RHF (`RegisterOptions`). |
479
+ | `error` | `string` | — | Não | Erro (ligado a `aria-describedby`). |
480
+ | `id` | `string` | — | Sim | `id` do `<input type="checkbox" role="switch">`. |
481
+ | `label` | `string` | — | Não | Rótulo visível; sem ele usa `aria-label` i18n `components.inputs.toggle.ariaLabel`. |
482
+ | `description` | `string` | — | Não | Texto secundário abaixo do rótulo. |
483
+ | `className` | `string` | — | Não | Classes do wrapper. |
484
+ | `labelClassName` | `string` | — | Não | Classes do rótulo. |
485
+ | `switchClassName` | `string` | — | Não | Classes do container do switch. |
486
+ | `trackClassName` | `string` | — | Não | Classes do trilho. |
487
+ | `thumbClassName` | `string` | — | Não | Classes do botão deslizante. |
488
+ | `onIcon` | `ReactNode` | — | Não | Ícone ligado. |
489
+ | `offIcon` | `ReactNode` | — | Não | Ícone desligado. |
490
+ | `checked` | `boolean` | — | Não | Controlado. |
491
+ | `defaultChecked` | `boolean` | `false` | Não | Valor inicial não controlado. |
492
+ | `width` | `string \| number` | — | Não | Largura do wrapper. |
493
+ | `enabled` | `boolean` | `true` (efetivo) | Não | `false` desabilita. |
494
+ | `readOnly` | `boolean` | — | Não | Impede alteração. |
495
+ | `required` | `boolean` | `false` | Não | Exige ligado (`true`); injeta `required` nas rules RHF. |
496
+ | `requiredMessage` | `string` | i18n `components.inputs.required` | Não | Mensagem para campo obrigatório vazio. |
497
+ | `validateOnBlur` | `boolean` | `true` | Não | `true`: valida no blur (e na digitação após interação); `false`: valida a cada alteração. |
498
+ | `validation` | `((checked: boolean) => string \| null)` | — | Não | `(checked) => string \| null`. |
499
+ | `onValidation` | `((message: string \| null) => void)` | — | Não | Recebe a mensagem de erro corrente ou `null` a cada validação. |
500
+ | `onChange` | `((checked: boolean) => void)` | — | Não | Recebe `checked: boolean`. |
501
+ | `inputProps` | `(InputHTMLAttributes<HTMLInputElement> & { ref?: Ref<HTMLInputElement>; })` | — | Não | Atributos do `<input>` (aceita `checked`/`defaultChecked` como alternativa). |
502
+
503
+ - **Valor:** `boolean`. O valor do RHF é convertido por `toBoolean`, que aceita `"true"`, `"1"`, `"on"`, `"yes"` e números ≠ 0.
504
+ - **RHF:** `register` ou `control`, com `mergeRequiredRule`.
505
+ - **Acessibilidade:** `role="switch"`, `aria-invalid`, `aria-describedby` apontando para `<id>-error`. Sem rótulo visível, usa o `aria-label` traduzido (coberto por `tests/inputs-i18n.test.mjs`).
506
+
507
+ **Confirmado**.
508
+
509
+ ## SgRating
510
+
511
+ Fonte: `src/inputs/SgRating.tsx`. Estrelas em SVG, com meia estrela opcional.
512
+
513
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
514
+ |---|---|---|---|---|
515
+ | `label` | `string` | — | Não | Rótulo. |
516
+ | `value` | `number` | `0` | Não | Valor (sincroniza o estado interno quando muda). |
517
+ | `stars` | `number` | `5` | Não | Quantidade de estrelas. |
518
+ | `allowHalf` | `boolean` | `false` | Não | Meia estrela. |
519
+ | `cancel` | `boolean` | `true` | Não | Botão para zerar. |
520
+ | `disabled` | `boolean` | `false` | Não | Desabilita. |
521
+ | `readOnly` | `boolean` | `false` | Não | Somente leitura. |
522
+ | `size` | `SgRatingSize` | `"md"` | Não | `sm`=16, `md`=24, `lg`=32, `xl`=40 px. |
523
+ | `className` | `string` | `""` | Não | Classes. |
524
+ | `style` | `CSSProperties` | — | Não | Estilo. |
525
+ | `onIcon` | `ReactNode` | — | Não | Ícone cheio. |
526
+ | `offIcon` | `ReactNode` | — | Não | Ícone vazio. |
527
+ | `cancelIcon` | `ReactNode` | — | Não | Ícone do cancelar. |
528
+ | `color` | `string` | `hsl(var(--primary))` | Não | Cor cheia. |
529
+ | `emptyColor` | `string` | `hsl(var(--muted-foreground))` | Não | Cor vazia. |
530
+ | `showTooltip` | `boolean` | `false` | Não | Tooltip com o valor no hover. |
531
+ | `onChange` | `((value: number) => void)` | — | Não | Recebe o número (0 ao cancelar). |
532
+ | `onHover` | `((value: number \| null) => void)` | — | Não | Recebe o valor em hover ou `null`. |
533
+ | `required` | `boolean` | `false` | Não | Valida 0 após interação (`components.rating.required`) e injeta regra RHF. |
534
+ | `requiredMessage` | `string` | i18n `components.rating.required` | Não | Mensagem. |
535
+ | `name` | `string` | — | Não | Nome do campo no react-hook-form. Só tem efeito junto com `control` ou `register` (ver contrato RHF). |
536
+ | `control` | `any` | — | Não | `Control` do `useForm()`; com `name`, envolve o componente em `<Controller>`. |
537
+ | `rules` | `RegisterOptions<any>` | — | Não | Regras de validação do RHF (`RegisterOptions`). |
538
+ | `error` | `string` | — | Não | Erro. |
539
+
540
+ - **RHF:** via `control` + `name`, com `mergeRequiredRule`.
541
+ - **Validação:** a regra de obrigatório interna só é avaliada em clique ou cancelamento.
542
+ - **Acessibilidade:**
543
+ - O botão cancelar tem `title` traduzido (`components.rating.cancel`).
544
+ - As estrelas são `div` clicáveis, sem `role`, `tabIndex` ou teclado, ou seja, não são acessíveis por teclado.
545
+
546
+ **Confirmado** pela ausência no código.
547
+
548
+ ## SgSlider
549
+
550
+ Fonte: `src/inputs/SgSlider.tsx`. É um `<input type="range">` nativo.
551
+
552
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
553
+ |---|---|---|---|---|
554
+ | `id` | `string` | — | Sim | `id` do `<input type="range">`. |
555
+ | `minValue` | `number` | — | Sim | Mínimo (não finito → 0). |
556
+ | `maxValue` | `number` | — | Sim | Máximo (ajustado para ≥ min). |
557
+ | `value` | `number` | — | Não | Controlado (clamp em min..max). |
558
+ | `defaultValue` | `number` | `minValue` | Não | Inicial não controlado. |
559
+ | `step` | `number` | `1` | Não | Passo (≤ 0 → 1). |
560
+ | `disabled` | `boolean` | `false` | Não | Desabilita. |
561
+ | `onChange` | `((value: number) => void)` | — | Não | Recebe o número (clamp). |
562
+ | `ariaLabel` | `string` | — | Não | `aria-label` do range. |
563
+ | `className` | `string` | — | Não | Classes do `<input>`. |
564
+ | `width` | `string \| number` | — | Não | Largura do wrapper. |
565
+ | `error` | `string` | — | Não | Erro (`aria-invalid`). |
566
+ | `inputProps` | `SliderInputProps` | — | Não | Atributos do `<input>` (sem `type/id/min/max/step/value/defaultValue/disabled/aria-label`). Espalhados por último: um `onChange` aqui SUBSTITUI o handler interno (Inferência; afeta o caminho `register`). |
567
+ | `name` | `string` | — | Não | Nome do campo no react-hook-form. Só tem efeito junto com `control` ou `register` (ver contrato RHF). |
568
+ | `control` | `any` | — | Não | `Control` do `useForm()`; com `name`, envolve o componente em `<Controller>`. |
569
+ | `register` | `UseFormRegister<any>` | — | Não | `register` do `useForm()`; com `name`, registra o elemento nativo. |
570
+ | `rules` | `RegisterOptions<any>` | — | Não | Regras de validação do RHF (`RegisterOptions`). |
571
+
572
+ - **RHF:** `register` ou `control`, sem `mergeRequiredRule` (o tipo não tem `required`). Com `control`, `value = field.value`, convertido para número.
573
+ - **Possível defeito (Inferência pela ordem do JSX):** `{...inputProps}` vem depois do `onChange` interno.
574
+ - No caminho `register`, o `inputProps.onChange` (que chama `reg.onChange`) substitui o handler interno.
575
+ - Nesse caso o estado interno e a prop `onChange` deixam de ser atualizados, e o range controlado pode não se mover.
576
+ - Não verificado em runtime.
577
+ - **Acessibilidade:** `aria-label` via `ariaLabel`, `aria-invalid` com erro.
578
+
579
+ ## SgStepperInput
580
+
581
+ Fonte: `src/inputs/SgStepperInput.tsx`. Usa `<input type="number">` e dois botões, aumentar e diminuir.
582
+
583
+ | Prop | Tipo | Padrão | Obrigatória | Descrição |
584
+ |---|---|---|---|---|
585
+ | `id` | `string` | — | Sim | `id` do `<input type="number">`. |
586
+ | `minValue` | `number` | — | Sim | Mínimo. |
587
+ | `maxValue` | `number` | — | Sim | Máximo. |
588
+ | `step` | `number` | `1` | Não | Passo dos botões. |
589
+ | `value` | `number` | — | Não | Controlado. |
590
+ | `defaultValue` | `number` | `minValue` | Não | Inicial não controlado. |
591
+ | `disabled` | `boolean` | `false` | Não | Desabilita. |
592
+ | `readOnly` | `boolean` | `false` | Não | Somente leitura (botões desativados). |
593
+ | `onChange` | `((value: number) => void)` | — | Não | Recebe o número (clamp). |
594
+ | `ariaLabel` | `string` | — | Não | `aria-label` do input. |
595
+ | `className` | `string` | — | Não | Classes do container. |
596
+ | `inputClassName` | `string` | — | Não | Classes do `<input>`. |
597
+ | `width` | `string \| number` | — | Não | Largura. |
598
+ | `error` | `string` | — | Não | Erro (`aria-invalid`, borda vermelha). |
599
+ | `inputProps` | `StepperInputProps` | — | Não | Atributos do `<input>`; espalhados por último (um `onChange` aqui substitui o interno — Inferência). |
600
+ | `name` | `string` | — | Não | Nome do campo no react-hook-form. Só tem efeito junto com `control` ou `register` (ver contrato RHF). |
601
+ | `control` | `any` | — | Não | `Control` do `useForm()`; com `name`, envolve o componente em `<Controller>`. |
602
+ | `register` | `UseFormRegister<any>` | — | Não | `register` do `useForm()`; com `name`, registra o elemento nativo. |
603
+ | `rules` | `RegisterOptions<any>` | — | Não | Regras de validação do RHF (`RegisterOptions`). |
604
+
605
+ - **RHF:** `register` ou `control`.
606
+ - **Ressalva com `register` (Inferência):**
607
+ - Os botões chamam só `onChange` (a prop), não o `register`.
608
+ - O `{...inputProps}` espalhado por último sobrescreve o `onChange` interno do `<input>`.
609
+ - **Acessibilidade:** botões com `aria-label` i18n `components.inputs.stepper.increase` e `components.inputs.stepper.decrease`; `aria-invalid` no input.
610
+
611
+ ## Fontes
612
+
613
+ - `front/seedgrid-fe-components/packages/seedgrid-fe-components/src/inputs/{SgAutocomplete,SgCombobox,SgCheckboxGroup,SgRadioGroup,SgMultiSelect,SgMultiSelectChips,SgMultiSelectDropdown,SgOrderList,SgPickList,SgPeriodSelector,SgYearPartSelector,SgToggleSwitch,SgRating,SgSlider,SgStepperInput}.tsx`, `useSgMultiSelect.ts`, `yearPart.ts`
614
+ - `front/seedgrid-fe-components/packages/seedgrid-fe-components/src/index.ts` (exportações)
615
+ - `front/seedgrid-fe-components/packages/seedgrid-fe-components/tests/{inputs-dom,inputs-i18n,rhf-components-contract,period-resolver,year-part-resolver}.test.mjs` (lidos; **não executados**)