fokus-styles 2.4.0 → 2.6.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 (212) hide show
  1. package/dist/css/components.css +561 -83
  2. package/dist/css/components.min.css +1 -1
  3. package/dist/css/fokus-components.css +561 -83
  4. package/dist/css/fokus-components.min.css +1 -1
  5. package/dist/css/fokus-rtl.css +697 -83
  6. package/dist/css/fokus-rtl.min.css +1 -1
  7. package/dist/css/fokus-utilities.css +136 -0
  8. package/dist/css/fokus-utilities.min.css +1 -1
  9. package/dist/css/fokus.css +996 -258
  10. package/dist/css/fokus.min.css +1 -1
  11. package/dist/css/forms.css +300 -176
  12. package/dist/css/forms.min.css +1 -1
  13. package/dist/css/helpers.css +136 -0
  14. package/dist/css/helpers.min.css +1 -1
  15. package/dist/js/fokus.js +270 -25
  16. package/dist/js/fokus.min.js +18 -18
  17. package/package.json +17 -15
  18. package/packages/fokus-components/scss/components/_alerts.scss +128 -6
  19. package/packages/fokus-components/scss/components/_badges.scss +26 -10
  20. package/packages/fokus-components/scss/components/_index.scss +1 -0
  21. package/packages/fokus-components/scss/components/_popover.scss +131 -21
  22. package/packages/fokus-components/scss/components/_responsive.scss +23 -0
  23. package/packages/fokus-components/scss/components/_tag.scss +37 -14
  24. package/packages/fokus-components/scss/components/_toasts.scss +156 -11
  25. package/packages/fokus-components/scss/components/_tooltips.scss +70 -18
  26. package/packages/fokus-components/scss/forms/_check-radio-switch.scss +313 -215
  27. package/packages/fokus-components/scss/forms/_forms.scss +16 -0
  28. package/packages/fokus-js/js/carousel.d.ts +4 -0
  29. package/packages/fokus-js/js/carousel.js +8 -0
  30. package/packages/fokus-js/js/core/positioning.js +18 -9
  31. package/packages/fokus-js/js/dropdown.d.ts +4 -0
  32. package/packages/fokus-js/js/dropdown.js +7 -0
  33. package/packages/fokus-js/js/popover.js +26 -1
  34. package/packages/fokus-js/js/tabs.d.ts +3 -0
  35. package/packages/fokus-js/js/tabs.js +5 -0
  36. package/packages/fokus-js/js/tag.js +17 -0
  37. package/packages/fokus-js/js/toast.js +77 -3
  38. package/packages/fokus-js/js/tooltip.d.ts +8 -1
  39. package/packages/fokus-js/js/tooltip.js +106 -13
  40. package/packages/fokus-utilities/scss/utilities/_api.scss +48 -0
  41. package/CHANGELOG.md +0 -910
  42. package/dist/css/components.css.map +0 -1
  43. package/dist/css/components.min.css.map +0 -1
  44. package/dist/css/fokus-components.css.map +0 -1
  45. package/dist/css/fokus-components.min.css.map +0 -1
  46. package/dist/css/fokus-core.css.map +0 -1
  47. package/dist/css/fokus-core.min.css.map +0 -1
  48. package/dist/css/fokus-dark.css.map +0 -1
  49. package/dist/css/fokus-dark.min.css.map +0 -1
  50. package/dist/css/fokus-rtl.css.map +0 -1
  51. package/dist/css/fokus-rtl.min.css.map +0 -1
  52. package/dist/css/fokus-utilities.css.map +0 -1
  53. package/dist/css/fokus-utilities.min.css.map +0 -1
  54. package/dist/css/fokus.css.map +0 -1
  55. package/dist/css/fokus.min.css.map +0 -1
  56. package/dist/css/fonts.css.map +0 -1
  57. package/dist/css/fonts.min.css.map +0 -1
  58. package/dist/css/forms.css.map +0 -1
  59. package/dist/css/forms.min.css.map +0 -1
  60. package/dist/css/helpers.css.map +0 -1
  61. package/dist/css/helpers.min.css.map +0 -1
  62. package/dist/css/layout.css.map +0 -1
  63. package/dist/css/layout.min.css.map +0 -1
  64. package/dist/js/fokus.js.map +0 -7
  65. package/dist/js/fokus.min.js.map +0 -7
  66. package/docs/README.md +0 -86
  67. package/docs/comparison.md +0 -124
  68. package/docs/components/accordion.md +0 -104
  69. package/docs/components/alert-dialog.md +0 -99
  70. package/docs/components/alert.md +0 -59
  71. package/docs/components/avatar.md +0 -13
  72. package/docs/components/badge.md +0 -82
  73. package/docs/components/breadcrumb.md +0 -93
  74. package/docs/components/button-group.md +0 -13
  75. package/docs/components/button.md +0 -98
  76. package/docs/components/card.md +0 -111
  77. package/docs/components/carousel.md +0 -167
  78. package/docs/components/checkbox.md +0 -97
  79. package/docs/components/close-button.md +0 -13
  80. package/docs/components/code.md +0 -13
  81. package/docs/components/collapse.md +0 -78
  82. package/docs/components/combobox.md +0 -123
  83. package/docs/components/command-palette.md +0 -131
  84. package/docs/components/datatable.md +0 -173
  85. package/docs/components/datepicker.md +0 -137
  86. package/docs/components/divider.md +0 -57
  87. package/docs/components/dropdown.md +0 -103
  88. package/docs/components/empty-state.md +0 -65
  89. package/docs/components/file-upload-advanced.md +0 -116
  90. package/docs/components/file-upload.md +0 -93
  91. package/docs/components/icon-link.md +0 -13
  92. package/docs/components/input-group.md +0 -73
  93. package/docs/components/input.md +0 -90
  94. package/docs/components/list-group.md +0 -13
  95. package/docs/components/modal.md +0 -120
  96. package/docs/components/navbar.md +0 -74
  97. package/docs/components/nested-menu.md +0 -90
  98. package/docs/components/notification-center.md +0 -116
  99. package/docs/components/offcanvas.md +0 -102
  100. package/docs/components/pagination.md +0 -145
  101. package/docs/components/placeholder.md +0 -13
  102. package/docs/components/popover.md +0 -105
  103. package/docs/components/progress.md +0 -126
  104. package/docs/components/radio.md +0 -70
  105. package/docs/components/range.md +0 -83
  106. package/docs/components/rating.md +0 -91
  107. package/docs/components/ratio.md +0 -13
  108. package/docs/components/scrollspy.md +0 -13
  109. package/docs/components/segmented-control.md +0 -82
  110. package/docs/components/select.md +0 -89
  111. package/docs/components/skeleton.md +0 -70
  112. package/docs/components/stepper.md +0 -107
  113. package/docs/components/switch.md +0 -75
  114. package/docs/components/table.md +0 -90
  115. package/docs/components/tabs.md +0 -104
  116. package/docs/components/tag.md +0 -129
  117. package/docs/components/tile.md +0 -112
  118. package/docs/components/timeline.md +0 -78
  119. package/docs/components/toast.md +0 -95
  120. package/docs/components/tooltip.md +0 -77
  121. package/docs/components/tree-view.md +0 -118
  122. package/docs/contributing/contributing.md +0 -18
  123. package/docs/getting-started/installation.md +0 -70
  124. package/docs/getting-started/usage.md +0 -105
  125. package/docs/guides/accessibility.md +0 -102
  126. package/docs/guides/charts.md +0 -73
  127. package/docs/guides/dark-mode.md +0 -90
  128. package/docs/guides/icons.md +0 -99
  129. package/docs/guides/javascript-api.md +0 -9
  130. package/docs/guides/layout-advanced.md +0 -118
  131. package/docs/guides/migration-clarus-to-fokus.md +0 -48
  132. package/docs/guides/migration-external.md +0 -123
  133. package/docs/guides/migration-v1.md +0 -63
  134. package/docs/guides/print.md +0 -30
  135. package/docs/guides/rtl-and-system-preferences.md +0 -28
  136. package/docs/guides/theming.md +0 -140
  137. package/docs/guides/utility-api.md +0 -9
  138. package/docs/prompts/prompt-plan.md +0 -45
  139. package/docs/reference/accessibility-matrix.md +0 -77
  140. package/docs/reference/browser-support.md +0 -75
  141. package/docs/reference/contrast-report.md +0 -50
  142. package/docs/reference/definitions.md +0 -864
  143. package/docs/reference/design-tokens.md +0 -194
  144. package/docs/reference/scss-architecture.md +0 -227
  145. package/docs/reference/size-baseline.json +0 -34
  146. package/docs/reference/stability.md +0 -89
  147. package/docs/showcase.md +0 -25
  148. package/mockup/README.md +0 -41
  149. package/mockup/assets/carousel-planning.png +0 -0
  150. package/mockup/assets/carousel-workspace.png +0 -0
  151. package/mockup/assets/example-theme.css +0 -8
  152. package/mockup/assets/example-theme.js +0 -11
  153. package/mockup/assets/showcase-contracts.js +0 -84
  154. package/mockup/assets/showcase.css +0 -91
  155. package/mockup/assets/showcase.js +0 -724
  156. package/mockup/content-data.html +0 -9
  157. package/mockup/examples/accordion-tabs-toast.html +0 -149
  158. package/mockup/examples/alert-dialog.html +0 -84
  159. package/mockup/examples/alerts.html +0 -41
  160. package/mockup/examples/badges-alerts.html +0 -77
  161. package/mockup/examples/buttons.html +0 -58
  162. package/mockup/examples/cards.html +0 -132
  163. package/mockup/examples/carousel.html +0 -126
  164. package/mockup/examples/charts.html +0 -102
  165. package/mockup/examples/check-radio-switch.html +0 -144
  166. package/mockup/examples/collapse.html +0 -69
  167. package/mockup/examples/combobox.html +0 -60
  168. package/mockup/examples/command-palette.html +0 -64
  169. package/mockup/examples/datatable.html +0 -113
  170. package/mockup/examples/datepicker.html +0 -62
  171. package/mockup/examples/divider.html +0 -45
  172. package/mockup/examples/dropdown-tooltip.html +0 -77
  173. package/mockup/examples/empty-state.html +0 -56
  174. package/mockup/examples/file-drop.html +0 -74
  175. package/mockup/examples/file-upload-advanced.html +0 -68
  176. package/mockup/examples/forms-advanced.html +0 -77
  177. package/mockup/examples/hover-card.html +0 -86
  178. package/mockup/examples/icons.html +0 -157
  179. package/mockup/examples/input-group.html +0 -74
  180. package/mockup/examples/js-foundation.html +0 -215
  181. package/mockup/examples/layout.html +0 -134
  182. package/mockup/examples/modal-select.html +0 -127
  183. package/mockup/examples/nested-menu.html +0 -73
  184. package/mockup/examples/notification-center.html +0 -86
  185. package/mockup/examples/offcanvas-popover.html +0 -133
  186. package/mockup/examples/pagination-breadcrumbs.html +0 -92
  187. package/mockup/examples/range.html +0 -69
  188. package/mockup/examples/rating.html +0 -103
  189. package/mockup/examples/segmented-control.html +0 -96
  190. package/mockup/examples/skeletons.html +0 -82
  191. package/mockup/examples/spinner-progress.html +0 -130
  192. package/mockup/examples/stepper.html +0 -119
  193. package/mockup/examples/tables-navbar.html +0 -89
  194. package/mockup/examples/tag.html +0 -105
  195. package/mockup/examples/theming.html +0 -68
  196. package/mockup/examples/tile.html +0 -107
  197. package/mockup/examples/timeline.html +0 -108
  198. package/mockup/examples/tree-view.html +0 -68
  199. package/mockup/feedback-actions.html +0 -9
  200. package/mockup/forms.html +0 -13
  201. package/mockup/foundations.html +0 -7
  202. package/mockup/kitchen-sink.html +0 -696
  203. package/mockup/navigation-disclosure.html +0 -11
  204. package/mockup/overlays-commands.html +0 -12
  205. package/mockup/templates/README.md +0 -20
  206. package/mockup/templates/admin.html +0 -334
  207. package/mockup/templates/auth.html +0 -234
  208. package/mockup/templates/dashboard.html +0 -442
  209. package/mockup/templates/landing.html +0 -397
  210. package/packages/fokus-icons/package.json +0 -46
  211. package/scripts/migrate-fokus-map.json +0 -1366
  212. package/scripts/migrate-fokus.mjs +0 -97
@@ -1,864 +0,0 @@
1
- # Fokus Styles — Definições do Projeto
2
-
3
- > Este documento registra as decisões de arquitetura e produto. Para o nível
4
- > de estabilidade de cada grupo de componentes e o plano de consolidação,
5
- > consulte [`stability.md`](stability.md). A
6
- > seção 21 (catálogo por componente) reflete o estado em que cada trecho
7
- > foi escrito e não é atualizada retroativamente a cada componente novo;
8
- > para o catálogo completo e sempre atual, use
9
- > [`docs/README.md#componentes`](../README.md#componentes) e
10
- > [`docs/components/`](../components/).
11
-
12
- ## 1. Visão Geral
13
-
14
- Fokus Styles é um framework CSS open source, de uso recorrente nos projetos pessoais e profissionais do autor, com distribuição pública como produto para qualquer desenvolvedor que precise construir interfaces web com HTML, CSS e JavaScript de forma direta, consistente e reutilizável.
15
-
16
- O projeto será publicado no GitHub sob o repositório `fokus-styles` e terá distribuição oficial via npm desde o início. A licença adotada é MIT, mantendo o framework permissivo, simples de reutilizar e adequado para uso pessoal, comercial e comunitário.
17
-
18
- ## 2. Objetivo Estratégico
19
-
20
- O objetivo do Fokus Styles é oferecer uma base visual moderna, minimalista e produtiva para criação de páginas, sistemas e componentes de interface sem exigir dependências externas ou integração obrigatória com frameworks JavaScript.
21
-
22
- O projeto deve priorizar três finalidades, nesta ordem:
23
-
24
- 1. Servir como biblioteca CSS confiável para projetos recorrentes.
25
- 2. Consolidar uma API pequena, coerente e sustentável para terceiros.
26
- 3. Ampliar o ecossistema somente quando houver necessidade real e documentação suficiente.
27
-
28
- ## 3. Público-Alvo
29
-
30
- O público-alvo principal é o desenvolvedor que constrói páginas, sistemas
31
- administrativos e aplicações web com HTML, CSS e JavaScript nativo, sem querer
32
- adotar um framework de componentes obrigatório.
33
-
34
- React, Vue e outras stacks são integrações secundárias. O núcleo deve continuar
35
- completo e útil sem qualquer uma delas.
36
-
37
- ## 4. Posicionamento do Produto
38
-
39
- O Fokus Styles é um framework CSS híbrido, com prioridade deliberada para um
40
- núcleo pequeno de componentes prontos e utilitários previsíveis. Componentes
41
- avançados devem ser tratados como extensões até que tenham uso, testes e
42
- documentação suficientes para integrar o núcleo.
43
-
44
- A identidade visual deve seguir uma linha minimalista e moderna, com foco em clareza, legibilidade, baixo ruído visual e adaptação a diferentes tipos de aplicação.
45
-
46
- ## 5. Filosofia de Design
47
-
48
- A filosofia oficial do projeto é híbrida.
49
-
50
- Isso significa que o framework deve combinar:
51
-
52
- - Componentes prontos para uso, como botões, formulários, cards, menus, modais, alertas, tabelas e navegação.
53
- - Classes utilitárias para espaçamento, alinhamento, display, visibilidade, grid, tipografia, cores e estados visuais.
54
- - Padrões consistentes de nomenclatura para reduzir colisões, facilitar leitura do HTML e manter previsibilidade entre componentes.
55
-
56
- Essa decisão é firme e deve orientar toda a arquitetura do projeto.
57
-
58
- ## 6. Stack Tecnológica
59
-
60
- O projeto deve priorizar HTML, CSS e JavaScript nativo.
61
-
62
- A stack definida é:
63
-
64
- - CSS como base do framework.
65
- - SCSS/Sass para organização modular, variáveis, mixins e funções.
66
- - CSS Custom Properties para permitir customização em tempo de uso sem recompilação obrigatória.
67
- - PostCSS para pós-processamento e compatibilidade entre navegadores.
68
- - JavaScript nativo para componentes interativos.
69
- - Empacotamento leve para distribuição em formatos compatíveis com uso moderno e inclusão direta em páginas HTML.
70
-
71
- O Fokus Styles deve ter dependência externa zero em tempo de execução. Não deve depender de React, Vue, Angular, jQuery ou qualquer biblioteca JavaScript de terceiros para funcionar.
72
-
73
- ## 7. Arquitetura de Interface
74
-
75
- O framework deve priorizar uso direto em HTML, CSS e JavaScript, sem exigir build complexo para o usuário final.
76
-
77
- As classes e componentes devem ser pensados para:
78
-
79
- - Uso direto em arquivos HTML.
80
- - Integração simples com qualquer back-end ou front-end.
81
- - Compatibilidade futura com projetos que usem React, Vue, Angular ou outras stacks, sem tornar essas stacks obrigatórias.
82
-
83
- ## 8. Sistema de Layout
84
-
85
- O sistema de layout será baseado em Flexbox.
86
-
87
- O grid deve seguir uma abordagem convencional de 12 colunas, com breakpoints
88
- (`packages/fokus-core/scss/settings/_breakpoints.scss`) calibrados pelas larguras lógicas de tela
89
- mais comuns do mercado atual, não por números arbitrários:
90
-
91
- - `sm` (640px) — tablets pequenos/phablets
92
- - `md` (768px) — tablet retrato
93
- - `lg` (1024px) — tablet paisagem / iPad
94
- - `xl` (1280px) — laptop comum
95
- - `xxl` (1536px) — laptop/desktop com escala (Mac/Windows)
96
- - `xxxl` (1920px) — monitor externo Full HD sem escala
97
-
98
- O objetivo é reduzir a curva de aprendizado para quem já usou um framework CSS de componentes, mantendo liberdade para adaptar detalhes internos à identidade do Fokus Styles.
99
-
100
- ## 9. Escopo do Núcleo Essencial
101
-
102
- A versão estável deve priorizar os recursos usados na maioria das interfaces
103
- administrativas e institucionais:
104
-
105
- O escopo inicial inclui:
106
-
107
- - Layout e containers.
108
- - Grid baseado em Flexbox.
109
- - Utilitários de espaçamento, display, alinhamento, visibilidade e tipografia.
110
- - Formulários e validação visual.
111
- - Botões.
112
- - Cards.
113
- - Alertas.
114
- - Badges.
115
- - Tabelas.
116
- - Navbar.
117
- - Dropdown, modal, accordion, tabs e toast.
118
- - Paginação e breadcrumbs.
119
-
120
- Combobox, Datepicker, DataTable, Tree View, Command Palette, Carousel e
121
- Upload avançado permanecem disponíveis como componentes avançados, mas não
122
- devem expandir o núcleo sem uma decisão explícita.
123
-
124
- ## 10. Temas e Customização
125
-
126
- O Fokus Styles deve oferecer suporte nativo a dark mode desde a primeira versão.
127
-
128
- A paleta de cores oficial é a "Indigo autoral" (`primary #4F46E5`,
129
- `success #1BC559`, `warning #F0B40E`, `danger #DC263E`, `info #8BA2C4`,
130
- com escala neutra própria de 9 degraus), definida na seção 18.1. A
131
- arquitetura já está preparada para temas claros e escuros por meio de CSS
132
- Custom Properties.
133
-
134
- A customização deve permitir que usuários alterem cores, espaçamentos, tipografia e estados visuais sem reescrever o framework inteiro.
135
-
136
- ## 11. Tipografia
137
-
138
- A família tipográfica oficial é a Plus Jakarta Sans (heading e body),
139
- definida na seção 18.2, escolhida por boa legibilidade, aparência moderna e
140
- compatibilidade com interfaces web de uso geral. Os arquivos da fonte são
141
- distribuídos self-hosted junto ao próprio pacote (sem dependência de
142
- serviços externos como fonts.googleapis.com em tempo de execução), alinhado
143
- à stack definida na seção 6.
144
-
145
- ## 12. Documentação
146
-
147
- A documentação inicial será mantida em Markdown no GitHub.
148
-
149
- O repositório continua sendo a fonte versionada da documentação. A próxima
150
- etapa de produto é disponibilizar uma documentação visual pesquisável, com
151
- exemplos executáveis e caminho de início rápido. Markdown continua sendo a
152
- fonte normativa até que esse site exista.
153
-
154
- Os documentos devem explicar:
155
-
156
- - Instalação via npm.
157
- - Uso direto via arquivo compilado.
158
- - Estrutura de classes.
159
- - Sistema de grid.
160
- - Componentes disponíveis.
161
- - Customização por variáveis.
162
- - Modo escuro.
163
- - Convenções de contribuição.
164
-
165
- ## 13. Distribuição
166
-
167
- O Fokus Styles será publicado no npm desde o início.
168
-
169
- A distribuição deve contemplar:
170
-
171
- - Pacote npm oficial.
172
- - Arquivos compilados em `dist`.
173
- - Versão minificada para produção.
174
- - CSS principal.
175
- - JavaScript nativo para componentes interativos.
176
- - Possibilidade de uso via CDN por meio de serviços como jsDelivr e unpkg após publicação no npm.
177
-
178
- ## 14. Licenciamento
179
-
180
- O projeto será licenciado sob MIT.
181
-
182
- Essa licença confirma a intenção de permitir uso amplo, modificação, cópia, redistribuição e uso comercial, preservando apenas os requisitos básicos de atribuição e inclusão do aviso de licença.
183
-
184
- ## 15. Estrutura do Repositório
185
-
186
- A estrutura evoluiu de um único diretório `scss/`/`js/` (intenção original
187
- desta seção) para um monorepo por pacote, separando cada camada da
188
- arquitetura (ver [scss-architecture.md](scss-architecture.md)):
189
-
190
- ```text
191
- fokus-styles/
192
- ├── assets/ # fontes self-hosted
193
- ├── dist/ # CSS/JS compilados (gitignored, gerado por `npm run build`)
194
- ├── docs/ # documentação pública
195
- ├── mockup/ # exemplo funcional por componente + templates prontos
196
- ├── packages/
197
- │ ├── fokus-core/ # tokens, base, layout, temas
198
- │ ├── fokus-components/ # componentes e formulários (SCSS)
199
- │ ├── fokus-utilities/ # utilitários atômicos (SCSS)
200
- │ ├── fokus-fonts/ # @font-face self-hosted
201
- │ ├── fokus-js/ # API JavaScript de todos os componentes interativos
202
- │ ├── fokus-icons/ # fonte interna de ícones (exportada por /icons)
203
- │ ├── fokus-cli/ # fonte interna da CLI (bin `fokus`)
204
- │ └── fokus-react/ # fonte interna do wrapper React (/react)
205
- ├── scripts/ # build, migração, contraste, tamanho
206
- ├── scss/ # ponto de entrada Sass que agrega os pacotes acima
207
- ├── tests/ # unit (Vitest), a11y e visual (Playwright)
208
- ├── CHANGELOG.md
209
- ├── CONTRIBUTING.md
210
- ├── LICENSE
211
- ├── package.json
212
- └── README.md
213
- ```
214
-
215
- ## 16. Boas Práticas de Engenharia
216
-
217
- O projeto deve adotar práticas que transmitam seriedade técnica desde o início:
218
-
219
- - Versionamento semântico.
220
- - Histórico de mudanças em `CHANGELOG.md`.
221
- - Orientações de contribuição em `CONTRIBUTING.md`.
222
- - Scripts de build e minificação.
223
- - Organização modular por componente.
224
- - Convenção consistente de nomenclatura de classes.
225
- - GitHub Actions para lint, build e validações básicas.
226
- - Publicação controlada por release.
227
-
228
- ## 17. Decisões Firmes
229
-
230
- As seguintes decisões estão definidas:
231
-
232
- - Nome do produto: FokusStyles.
233
- - Nome do projeto/repositório: `fokus-styles`.
234
- - Modelo de design: híbrido.
235
- - Referência: convenções amplamente adotadas em frameworks CSS de componentes.
236
- - Stack prioritária: HTML, CSS e JavaScript nativo.
237
- - Dependências externas em tempo de execução: zero.
238
- - Sistema de layout: Flexbox.
239
- - Breakpoints: valores convencionais amplamente adotados.
240
- - Identidade visual: minimalista e moderna.
241
- - Paleta de cores: "Indigo autoral", definida na seção 18.1.
242
- - Tipografia: Plus Jakarta Sans, self-hosted, definida na seção 18.2.
243
- - Dark mode: nativo desde a primeira versão.
244
- - Documentação inicial: Markdown no GitHub.
245
- - Distribuição: npm desde o início.
246
- - Licença: MIT.
247
- - Tom do projeto: técnico, estratégico e com posicionamento de produto.
248
- - Convenção de nomenclatura de classes: definida na seção 19.
249
- - API JavaScript dos componentes interativos: definida na seção 20.
250
- - Catálogo e arquitetura dos componentes: detalhado na seção 21.
251
- - Testes automatizados (funcionais e visuais): detalhados na seção 22.
252
-
253
- ## 18. Paleta de Cores e Tipografia
254
-
255
- As duas pendências desta seção (antes "a definir posteriormente") foram decididas.
256
-
257
- ### 18.1 Paleta de cores oficial
258
-
259
- Opção "Indigo autoral": paleta própria, escolhida por dar ao FokusStyles uma
260
- identidade cromática distinta dos azuis e paletas genéricas mais comuns em
261
- frameworks de UI (uma paleta de placeholder chegou a ser usada em
262
- `packages/fokus-core/scss/settings/_colors.scss` durante o desenvolvimento inicial), reforçando o
263
- posicionamento de identidade visual própria (seção 4).
264
-
265
- - Cores de estado:
266
- - `primary`: `#4F46E5`
267
- - `success`: `#1BC559`
268
- - `warning`: `#F0B40E`
269
- - `danger`: `#DC263E`
270
- - `info`: `#8BA2C4`
271
- - `info` passa a ser uma cor distinta de `primary`, corrigindo a duplicidade
272
- que existia antes desta implementação (`$color-primary` e `$color-info`
273
- com o mesmo valor).
274
- - Escala neutra com 9 degraus cheios (100 a 900, sem lacunas), já
275
- implementada em `packages/fokus-core/scss/settings/_colors.scss`: `#F8FAFC`, `#F1F5F9`,
276
- `#E2E8F0`, `#CBD5E1`, `#94A3B8`, `#64748B`, `#475569`, `#334155`,
277
- `#1E293B`.
278
- - Variantes de `primary`/`success`/`warning`/`danger`/`info` para o dark
279
- mode já implementadas em `packages/fokus-core/scss/themes/_dark.scss` (token
280
- `--fs-color-#{nome}`, recalculado via `color.mix()` com um peso por
281
- cor no mapa `$dark-color-weights`); `alert-*-bg`/`-text` continuam
282
- recalculados à parte para o tema escuro.
283
-
284
- ### 18.2 Família tipográfica final
285
-
286
- Plus Jakarta Sans para heading e body (família única), mantendo Source Code
287
- Pro no monoespaçado (`$font-family-mono`, sem alteração).
288
-
289
- - Os arquivos da fonte (`.woff2`, licença OFL) já são self-hosted, distribuídos
290
- junto ao pacote em `assets/fonts/plus-jakarta-sans/` (incluindo o
291
- `OFL.txt` da fonte, requisito da licença), com `@font-face` declarado em
292
- `packages/fokus-core/scss/base/_typography.scss` no lugar do antigo `@import
293
- url("https://fonts.googleapis.com/...")` — cumprindo a meta de
294
- "dependência externa zero em tempo de execução" (seção 6) para a fonte
295
- principal. O monoespaçado (Source Code Pro) permanece via `@import` do
296
- Google Fonts, sem alteração, conforme decidido acima.
297
-
298
- ## 19. Convenção de Nomenclatura de Classes
299
-
300
- - Prefixo `fs-` em toda classe de componente (`.fs-btn`, `.fs-card`,
301
- `.fs-container`), para não colidir com nomes de classe de outras
302
- bibliotecas/CSS de terceiros na mesma página.
303
- - Variantes de cor/estilo por sufixo direto: `.fs-btn-primary`, `.fs-alert-danger`,
304
- `.fs-badge-success`, seguindo os nomes já usados em `$theme-colors`
305
- (`packages/fokus-core/scss/settings/_colors.scss`).
306
- - Tamanhos por sufixo `-sm`/`-lg` consistente em todos os componentes que
307
- tiverem variação de tamanho (botões, badges, cards, inputs), generalizando
308
- o padrão já usado em `.fs-form-control-sm`/`.fs-form-control-lg`.
309
- - Estados controlados por JavaScript usam classes `is-*` (`.is-open`,
310
- `.is-active`, `.is-disabled`), nunca atributos `data-state` customizados.
311
- - Utilitários usam prefixo `fs-u-` + abreviações curtas (`.fs-u-d-flex`, `.fs-u-mt-3`,
312
- `.fs-u-gx-2`, `.fs-u-p-2`), como já implementado em
313
- `packages/fokus-utilities/scss/utilities/`.
314
- - Responsividade em utilitários e grid segue sempre o formato fixo
315
- `{propriedade}-{breakpoint}-{valor}` (ex.: `.fs-col-md-6`, `.fs-u-d-md-none`,
316
- `.fs-u-mt-lg-3`).
317
- - Tokens CSS (`--fs-*`), atributo de auto-init (`data-fs`/`data-fs-target`/
318
- `data-fs-dismiss`) e eventos customizados (`fs:*`) seguem o mesmo prefixo;
319
- o global JavaScript (`window.FokusStyles`) e o pacote npm (`fokus-styles`) não
320
- mudam.
321
-
322
- ## 20. API JavaScript dos Componentes Interativos
323
-
324
- - Inicialização sempre automática via atributo HTML (ex.:
325
- `data-fs="modal" data-fs-target="#meuModal"`), sem exigir `new` manual
326
- para o uso básico — alinhado com "uso direto em HTML sem build" (seção 7).
327
- - Toda instância criada automaticamente continua acessível para controle
328
- programático via método estático de recuperação (ex.:
329
- `FokusStyles.Modal.getInstance(el)`), permitindo chamar seus métodos sem
330
- precisar instanciar manualmente.
331
- - Namespace global único: `window.FokusStyles`, com cada componente como
332
- propriedade (`FokusStyles.Modal`, `FokusStyles.Tooltip`, `FokusStyles.Dropdown`, etc.),
333
- em vez de globais separados.
334
- - API de instância padronizada para todo componente interativo: `.show()`,
335
- `.hide()`, `.toggle()`, `.dispose()`.
336
- - Comunicação com a aplicação via eventos DOM customizados (ex.:
337
- `fs:modal:shown`, `fs:tab:changed`), disparados com
338
- `CustomEvent` nativo — sem exigir callbacks de construtor.
339
- - Acessibilidade (ARIA, foco, teclado) é requisito obrigatório da API desde
340
- a v0.1 para todo componente interativo, não um extra a ser adicionado
341
- depois.
342
- - Além do bundle único (`dist/js/fokus.js`), haverá import granular por
343
- componente (ex.: `import { Modal } from "fokus-styles/js/modal"`), para uso
344
- com bundlers.
345
-
346
- ## 21. Componentes do Framework
347
-
348
- Esta seção documenta, por grupo de componente, as classes CSS, tokens e
349
- módulos JavaScript entregues pelo framework até o momento em que cada
350
- trecho foi escrito (ver nota no topo do documento — componentes
351
- adicionados depois têm sua própria página em
352
- [`docs/components/`](../components/), não um adendo aqui). Todo
353
- componente/grupo tem um mockup dedicado em `mockup/` (HTML puro consumindo
354
- os arquivos gerados em `dist/css/`/`dist/js/`), usado tanto como exemplo de
355
- uso quanto como fixture dos testes visuais (seção 22).
356
-
357
- ### Botões
358
-
359
- Variantes sólidas e outline por cor de estado
360
- (`.fs-btn-primary/success/warning/danger/info`, `.fs-btn-outline-*`), tamanhos
361
- (`.fs-btn-sm`/`.fs-btn-lg`) e estados de hover/active/focus/disabled. A função
362
- `color-contrast()` (`packages/fokus-core/scss/tools/_mixins.scss`) garante contraste WCAG AA em
363
- cada variante — reaproveitada por cards, alertas, modal e navbar.
364
-
365
- Mockup: `mockup/feedback-actions.html#button`.
366
-
367
- ### Badges e Alertas
368
-
369
- Badges sólidos com tamanhos (`.fs-badge-sm`/`.fs-badge-lg`), reaproveitados por
370
- cards, navbar e tabelas. Alertas com fundo tintado por estado (`.fs-alert-*`),
371
- via tokens `--fs-alert-*-bg`/`-text` com suporte a dark mode, usando as
372
- funções `tint-color()`/`shade-color()` (`packages/fokus-core/scss/tools/_mixins.scss`). Os dois
373
- componentes compartilham o mesmo padrão de variante de cor de estado
374
- (success/warning/danger/info), também usado por tabelas.
375
-
376
- Mockup: `mockup/feedback-actions.html#badge`.
377
-
378
- ### Cards
379
-
380
- Combina botões, badges e tipografia base num contêiner:
381
- `.fs-card-header`/`.fs-card-body`/`.fs-card-footer`, `.fs-card-title`/`.fs-card-subtitle`/
382
- `.fs-card-text`, tamanhos (`.fs-card-sm`/`.fs-card-lg`). O `.fs-card-header` suporta a
383
- variante título + botão de fechar (`.fs-btn-close`, reaproveitável em
384
- modal/toast). Utilitários de sombra (`.fs-u-shadow-sm`/`.fs-u-shadow`/`.fs-u-shadow-lg`,
385
- `packages/fokus-utilities/scss/utilities/_shadow.scss`) dão elevação ao card. `.fs-card-clickable` +
386
- `.fs-stretched-link` tornam o card inteiro clicável/focável sem aninhar
387
- elementos interativos; `.fs-card-horizontal` muda o eixo para linha, ajustando
388
- raio/borda do header/footer para a lateral.
389
-
390
- Mockup: `mockup/content-data.html#card`.
391
-
392
- ### Tabelas e Navbar
393
-
394
- Tabelas: `.fs-table-striped`/`.fs-table-hover`/`.fs-table-bordered`/
395
- `.fs-table-borderless`/`.fs-table-sm`/`.fs-table-responsive` e variantes de cor de
396
- estado, reaproveitando os tokens `--fs-alert-*` de Badges e Alertas.
397
-
398
- Navbar (versão estática, sem dropdown/collapse próprio — a combinação com
399
- Dropdown é feita compondo os dois componentes): `.fs-navbar-brand`/
400
- `.fs-navbar-nav`/`.fs-nav-link`, com estados `.is-active`/`.is-disabled`, reaproveitando
401
- botões e badges para o conteúdo interno.
402
-
403
- Mockup: `mockup/content-data.html#table`.
404
-
405
- ### Paginação e Breadcrumbs
406
-
407
- Paginação: `.fs-page-link` com estados `.is-active`/`.is-disabled`, reaproveitando
408
- `color-contrast()` (mesma função dos botões) para garantir contraste.
409
- Breadcrumbs: `.fs-breadcrumb-item` com separador via `::before` e estado
410
- `.is-active`. Ambos são auxiliares de navegação, sem JavaScript.
411
-
412
- Mockup: `mockup/navigation-disclosure.html#pagination`.
413
-
414
- ### Formulários Avançados
415
-
416
- Estados de validação: `.fs-form-control.is-valid`/`.is-invalid` (borda e anel
417
- de foco em `--fs-color-success`/`-danger`, reaproveitando as cores de
418
- estado de alertas/badges), com `.fs-valid-feedback`/`.fs-invalid-feedback`
419
- exibidos via seletor de irmão adjacente, sem JavaScript.
420
-
421
- Upload de arquivo estilizado: `.fs-file-upload`/`.fs-file-input`/`.fs-file-label` —
422
- o input nativo é ocultado por `clip-path` (mantendo foco e navegação por
423
- teclado), com rótulo estilizado via `<label for>`, tamanhos
424
- (`.fs-file-label-sm`/`-lg`) e estado desabilitado. Todo o grupo é 100% CSS, sem
425
- dependência de JavaScript.
426
-
427
- Mockup: `mockup/forms.html#input`.
428
-
429
- ### Infraestrutura JS Compartilhada
430
-
431
- Módulos internos em `packages/fokus-js/js/core/` (ES modules, sem dependências externas)
432
- usados por todos os componentes interativos, sem componente visual próprio:
433
-
434
- - `positioning.js` — `computePosition()`/`applyPosition()`, com flip
435
- automático para o lado oposto e clamp dentro da viewport. Usado por
436
- Dropdown, Tooltip e, indiretamente via composição, Select customizado.
437
- - `overlay.js` — `lockScroll()`/`unlockScroll()` com compensação de
438
- scrollbar e contagem de referências para overlays aninhados, além de
439
- `onClickOutside()`. Usado por Modal e Dropdown.
440
- - `focus.js` — `createFocusTrap()` com ciclo Tab/Shift+Tab e
441
- `onEscapeKey()`. Usado por Modal e Dropdown.
442
- - `transition.js` — `collapse()`/`expand()`, animando `height` via
443
- `transitionend` e respeitando `prefers-reduced-motion`. Usado por
444
- Accordion, Tabs e Toast.
445
- - `register.js` — `autoInit()`/`createInstanceRegistry()`, padrão comum de
446
- inicialização automática (`data-fs="..."`) e registro de instância
447
- (`getInstance()`) usado por todo componente interativo.
448
-
449
- Reexportado como `FokusStyles.core` pelo bundle único (`packages/fokus-js/js/fokus.js` →
450
- `dist/js/fokus.js`) e também importável de forma granular
451
- (`fokus-styles/js/core/positioning`, etc.), alinhado com a API JavaScript
452
- definida na seção 20.
453
-
454
- Mockup: `mockup/foundations.html#js-foundation` (harness de posicionamento, foco e
455
- transição, sem componente visual final).
456
-
457
- ### Dropdown e Tooltip
458
-
459
- `.fs-dropdown-toggle`/`.fs-dropdown-menu`/`.fs-dropdown-item`/`.fs-dropdown-divider`/
460
- `.fs-dropdown-header` (`packages/fokus-components/scss/components/_dropdown.scss`). `.fs-tooltip`/
461
- `.fs-tooltip-inner`/`.fs-tooltip-arrow` com 4 posicionamentos
462
- (`packages/fokus-components/scss/components/_tooltips.scss`), usando os tokens
463
- `--fs-tooltip-bg`/`-text` (invertidos no dark mode).
464
-
465
- `packages/fokus-js/js/dropdown.js` e `packages/fokus-js/js/tooltip.js` seguem a API da seção 20: auto-init via
466
- `data-fs="dropdown"`/`"tooltip"`, `FokusStyles.Dropdown`/`FokusStyles.Tooltip` com
467
- `getInstance()`, `.show()`/`.hide()`/`.toggle()`/`.dispose()`, eventos
468
- `fs:dropdown:shown`/`-hidden` e `fs:tooltip:shown`/`-hidden`.
469
- Dropdown navega entre itens com ArrowUp/ArrowDown e fecha ao clicar em um
470
- item, fora do menu ou com Escape (foco retorna ao toggle). Tooltip
471
- mostra/esconde por hover/foco/blur e Escape, com `aria-describedby` ligando
472
- o elemento de referência ao tooltip.
473
-
474
- `computePosition()` (`packages/fokus-js/js/core/positioning.js`) suporta a opção `align`
475
- (`"start"`/`"center"`/`"end"`) para o eixo cruzado, além do `placement`. O
476
- Dropdown usa `data-align` no toggle (padrão `"start"`, alinhamento à esquerda)
477
- com offset de 4px em relação ao toggle; `.fs-dropdown-menu` tem
478
- `position: absolute` explícito no CSS base, evitando que o menu seja medido
479
- como bloco normal antes do JS aplicar a posição (o que quebraria o cálculo
480
- de alinhamento `start`/`end`).
481
-
482
- Mockup: `mockup/overlays-commands.html#dropdown`.
483
-
484
- ### Modal e Select Customizado
485
-
486
- Modal: `.fs-modal`/`.fs-modal-dialog`/`.fs-modal-content`/`.fs-modal-header`/
487
- `.fs-modal-title`/`.fs-modal-body`/`.fs-modal-footer` (`packages/fokus-components/scss/components/_modal.scss`),
488
- com tamanhos `.fs-modal-sm`/`.fs-modal-lg` no `.fs-modal-dialog`. `packages/fokus-js/js/modal.js`
489
- (`FokusStyles.Modal`) reaproveita a infraestrutura JS compartilhada:
490
- `lockScroll()` enquanto aberto, `createFocusTrap()` no `.fs-modal-dialog`,
491
- `onEscapeKey()` e `onClickOutside()` para fechar (foco retorna ao gatilho);
492
- dismiss via qualquer elemento com `data-fs-dismiss="modal"`;
493
- `data-backdrop="static"` no `.fs-modal` desativa fechar por Escape/clique fora.
494
-
495
- Select customizado: `packages/fokus-js/js/select.js` (`FokusStyles.Select`) gera a marcação
496
- (`.fs-form-select` + `.fs-dropdown-menu`/`.fs-dropdown-item` por `<option>`) a partir
497
- de um `<select>` nativo (`data-fs="select"`, oculto mas mantido em
498
- sincronia para submissão de formulário) e **compõe uma instância de
499
- Dropdown por cima** — reaproveitando 100% do posicionamento, navegação por
500
- setas e fechamento do Dropdown, em vez de duplicar essa lógica. A seleção
501
- atualiza o `<select>` nativo e dispara `change` nativo (compatibilidade com
502
- listeners externos), além de `fs:select:changed`. ARIA usa
503
- `role="listbox"`/`"option"`/`aria-selected` (semântica mais correta para
504
- este caso, em vez de `"menu"`/`"menuitem"` herdado do Dropdown). Tamanhos
505
- via `data-size="sm"/"lg"` no `<select>` (`.fs-form-select-sm`/`-lg`,
506
- `packages/fokus-components/scss/forms/_forms.scss`).
507
-
508
- Mockup: `mockup/overlays-commands.html#modal`.
509
-
510
- ### Accordion, Tabs e Toast
511
-
512
- Os três reaproveitam a infraestrutura de transição/collapse
513
- (`packages/fokus-js/js/core/transition.js`).
514
-
515
- **Accordion** (`.fs-accordion`/`.fs-accordion-item`/`.fs-accordion-header`/
516
- `.fs-accordion-button`/`.fs-accordion-collapse`/`.fs-accordion-body`,
517
- `packages/fokus-components/scss/components/_accordion.scss`): `packages/fokus-js/js/accordion.js` usa `collapse()`/
518
- `expand()` de `FokusStyles.core` para animar a altura de cada painel; só um
519
- painel aberto por vez por padrão (`data-multiple="true"` permite vários
520
- simultâneos).
521
-
522
- **Tabs** (`.fs-tabs`/`.fs-tab-content`/`.fs-tab-pane`, `packages/fokus-components/scss/components/_tabs.scss`,
523
- reaproveitando `.fs-nav-link` da Navbar com um indicador de sublinhado escopado
524
- a `.fs-tabs`): `packages/fokus-js/js/tabs.js` alterna `.is-active` no link e no painel
525
- correspondente, com navegação por ArrowLeft/ArrowRight/Home/End entre as
526
- abas habilitadas (`role="tablist"`/`"tab"`/`"tabpanel"`, `aria-selected`,
527
- `tabindex` roving), disparando `fs:tab:changed`.
528
-
529
- **Toast** (`.fs-toast-container`/`.fs-toast`/`.fs-toast-header`/`.fs-toast-body`,
530
- variantes de cor de estado via `.fs-toast-#{nome}`,
531
- `packages/fokus-components/scss/components/_toasts.scss`): `packages/fokus-js/js/toast.js` usa `expand()`/`collapse()`
532
- para mostrar/esconder, com timer de auto-dismiss configurável (`data-delay`,
533
- `data-autohide="false"` para desativar) e dismiss via
534
- `data-fs-dismiss="toast"`. Instâncias são criadas no auto-init mas só ficam
535
- visíveis quando `.show()` é chamado (tipicamente após alguma ação), via
536
- `FokusStyles.Toast.getInstance(el).show()`.
537
-
538
- Mockup: `mockup/navigation-disclosure.html#accordion`.
539
-
540
- ### Spinner e Progress
541
-
542
- Indicadores de carregamento e progresso, 100% CSS (sem JavaScript). Spinner
543
- giratório `.fs-spinner` (anel com um lado transparente, animação contínua
544
- `fokus-spin`), com tamanhos (`.fs-spinner-sm`/`.fs-spinner-lg`) e variantes de cor
545
- de estado (`.spinner-#{nome}`) via os tokens `--fs-color-*`; a cor herda
546
- de `currentColor`, permitindo colorir também com utilitários de texto.
547
-
548
- Barra de progresso `.fs-progress`/`.fs-progress-bar`
549
- (`packages/fokus-components/scss/components/_spinner.scss`): a largura do preenchimento é controlada por
550
- `--fs-progress-value` (0–100) ou por `style="width"`, com transição suave.
551
- Tamanhos (`.fs-progress-sm`/`.fs-progress-lg`), variantes de cor de estado
552
- (`.fs-progress-bar-#{nome}`, reaproveitando `color-contrast()` como botões/badges)
553
- e faixas diagonais opcionais (`.fs-progress-bar-striped`, animáveis com
554
- `.fs-progress-bar-animated`). Toda animação respeita `prefers-reduced-motion`
555
- (spinner desacelera, listras param). ARIA fica a cargo do consumidor
556
- (`role="status"` no spinner, `role="progressbar"` + `aria-valuenow` na barra).
557
-
558
- Mockup: `mockup/feedback-actions.html#progress`.
559
-
560
- ### Carousel
561
-
562
- Carrossel de slides (`.fs-carousel`/`.fs-carousel-inner`/`.fs-carousel-item`,
563
- `packages/fokus-components/scss/components/_carousel.scss`). O layout padrão é "slide": `.fs-carousel-inner`
564
- é uma trilha flex e `packages/fokus-js/js/carousel.js` a desloca por `translateX(-index*100%)`;
565
- o recorte (`overflow: hidden`) fica no `.fs-carousel` (elemento parado), não na
566
- trilha, senão a área de recorte se moveria junto e cortaria os slides
567
- seguintes. A variante `.fs-carousel-fade` empilha os slides e anima a opacidade.
568
- Controles `.fs-carousel-control-prev`/`-next` (setas),
569
- `.fs-carousel-indicators` (dots em pill quando ativos) e
570
- `.fs-carousel-control-toggle[data-fs-carousel-toggle]` (pausa/reprodução)
571
- são opcionais — o JS liga cada um ao slide correspondente. A legenda opt-in
572
- `.fs-carousel-caption` usa scrim para conteúdo de produto sobre imagens. O
573
- modificador `.fs-carousel-hover-controls` esconde os controles até o
574
- hover/foco (`:focus-within`) do carrossel.
575
-
576
- `packages/fokus-js/js/carousel.js` (`FokusStyles.Carousel`) segue a API da seção 20: auto-init via
577
- `data-fs="carousel"`, `FokusStyles.Carousel.getInstance()`, métodos
578
- `.next()`/`.prev()`/`.goTo(i)`/`.pause()`/`.play()`/`.dispose()`, evento
579
- `fs:carousel:slid` (`detail: { from, to }`). Navegação por teclado
580
- (ArrowLeft/Right, Home/End quando o carrossel tem foco), swipe por
581
- pointer events (com pointer capture, feedback durante o arraste e preservação
582
- da rolagem vertical) e autoplay opcional (`data-autoplay="true"`, intervalo
583
- por `data-interval`, em ms). Autoplay pausa temporariamente no hover, foco,
584
- arraste e aba oculta; `pause()` exige `play()` para retomá-lo. `role="group"`
585
- + `aria-roledescription="carousel"`, `aria-hidden` por slide, `aria-current`
586
- nos indicadores e `aria-pressed` no toggle; `aria-live` fica `off` apenas
587
- enquanto o autoplay roda e `polite` quando manual ou pausado. As transições
588
- respeitam `prefers-reduced-motion`.
589
-
590
- Mockup: `mockup/content-data.html#carousel`.
591
-
592
- ### Stepper
593
-
594
- Stepper/Wizard (`.fs-stepper`/`.fs-stepper-header`/`.fs-step`, `packages/fokus-components/scss/components/_stepper.scss`).
595
- Cada `.fs-step` tem um `.fs-step-indicator` (círculo com número, ou um "check" em SVG
596
- quando concluído) e um `.fs-step-label`; a variante `.fs-stepper-vertical` empilha os
597
- passos com `.fs-step-content` (label + `.fs-step-description`). Estados por passo:
598
- padrão (pendente), `.fs-step-active`, `.fs-step-completed` e `.fs-step-error`. O conector
599
- entre passos é desenhado via `::after` e fica na cor primária depois de um passo
600
- concluído (indica progresso) — a regra usa `:not(:last-child)` para casar a
601
- especificidade da regra base do conector. Opcionalmente há painéis de conteúdo
602
- (`.fs-step-panel`, só o ativo visível) e ações de navegação (`.fs-stepper-actions` com
603
- botões `[data-stepper="prev"]`/`[data-stepper="next"]`).
604
-
605
- `packages/fokus-js/js/stepper.js` (`FokusStyles.Stepper`) segue a API da seção 20: auto-init via
606
- `data-fs="stepper"`, `getInstance()`, métodos `.next()`/`.prev()`/`.goTo(i)`/
607
- `.setError(i, bool)`/`.complete()`/`.dispose()`. Antes de cada troca dispara o
608
- evento **cancelável** `fs:stepper:beforechange` (`detail: { from, to }`) —
609
- prevenir com `preventDefault()` bloqueia o avanço (hook de validação por passo);
610
- depois de trocar dispara `fs:stepper:changed`, e ao concluir o último passo,
611
- `fs:stepper:completed`. Por padrão é linear (`data-linear`, padrão `true`):
612
- o cabeçalho só navega para passos já concluídos; `data-linear="false"` libera
613
- pular para qualquer passo. Acessibilidade: `aria-current="step"` no passo ativo,
614
- passos clicáveis navegáveis por teclado (Enter/Espaço).
615
-
616
- Mockup: `mockup/navigation-disclosure.html#stepper`.
617
-
618
- ### Offcanvas
619
-
620
- Painel deslizante (`.fs-offcanvas`, `packages/fokus-components/scss/components/_offcanvas.scss`), com o
621
- mesmo mecanismo de overlay do Modal (bloqueio de scroll, focus trap,
622
- fechamento por Escape/clique fora), aplicado de forma independente (não
623
- compõe `packages/fokus-js/js/modal.js` — segue o padrão já usado por Accordion/Tabs/Toast, cada
624
- um reaproveitando os módulos de `packages/fokus-js/js/core/` por si). Modificadores de posição
625
- obrigatórios `.fs-offcanvas-start`/`-end`/`-top`/`-bottom` definem o eixo de
626
- tamanho (largura para start/end, altura para top/bottom) e a direção inicial
627
- do `transform`; `.fs-offcanvas-header`/`-title`/`-body`/`-footer` seguem o mesmo
628
- padrão do Modal (reaproveitando `.fs-btn-close`). O `.fs-offcanvas-backdrop` é criado
629
- dinamicamente pelo JS (não fica fixo ao painel, como no Modal, porque o painel
630
- não cobre a tela inteira).
631
-
632
- `packages/fokus-js/js/offcanvas.js` (`FokusStyles.Offcanvas`) segue a API da seção 20: auto-init via
633
- `data-fs="offcanvas"`, `data-fs-target` no gatilho, `getInstance()`,
634
- `.show()`/`.hide()`/`.toggle()`/`.dispose()`, eventos
635
- `fs:offcanvas:shown`/`-hidden`. `data-fs-dismiss="offcanvas"` fecha a partir
636
- de qualquer elemento interno; `data-backdrop="static"` desativa Escape e
637
- clique fora (dismiss continua funcionando); `data-backdrop="false"` remove o
638
- elemento visual de backdrop mas mantém Escape e clique fora ativos (via
639
- `onClickOutside` no próprio painel, ignorando cliques no gatilho). Uma
640
- particularidade de implementação: como `visibility: hidden` mantém
641
- `offsetParent` não nulo (diferente de `display: none`), o elemento só fica de
642
- fato focável depois que o navegador processa a transição de visibilidade —
643
- por isso a ativação do focus trap é adiada por um duplo
644
- `requestAnimationFrame` (mesma técnica já usada por `collapse()`/`expand()`
645
- em `packages/fokus-js/js/core/transition.js`).
646
-
647
- Mockup: `mockup/overlays-commands.html#offcanvas`.
648
-
649
- ### Popover
650
-
651
- Painel flutuante com conteúdo rico (`.fs-popover`/`.fs-popover-header`/`-body`/
652
- `-footer`, `packages/fokus-components/scss/components/_popover.scss`), posicionado com a mesma técnica
653
- do Tooltip (`.fs-popover-arrow`, quadrado rotacionado 45°) mas com aparência de
654
- card de superfície (`--fs-color-surface`/`-border`, `--fs-shadow-md`)
655
- em vez do chip escuro do tooltip, já que pode conter elementos interativos.
656
- `role="dialog"` (não `"tooltip"`, que por spec ARIA não pode conter conteúdo
657
- interativo) com `aria-modal="false"` — é um overlay leve, sem focus trap e sem
658
- bloqueio de scroll (diferente de Modal/Offcanvas).
659
-
660
- `packages/fokus-js/js/popover.js` (`FokusStyles.Popover`) é independente (não compõe `Tooltip` nem
661
- `Dropdown`), reaproveitando apenas `positioning.js`
662
- (`computePosition`/`applyPosition`, como Dropdown/Tooltip) e
663
- `onClickOutside`/`onEscapeKey`. Segue a API da seção 20
664
- (`data-fs="popover"`, `data-fs-target` no gatilho, `getInstance()`,
665
- `.show()`/`.hide()`/`.toggle()`/`.dispose()`, eventos
666
- `fs:popover:shown`/`-hidden`). `data-trigger` controla o disparo:
667
- `"click"` (padrão, com `onClickOutside` ignorando o gatilho e Escape
668
- devolvendo o foco), `"hover"` (mouseenter/mouseleave no gatilho **e** no
669
- próprio popover, com um pequeno delay de saída para permitir mover o mouse
670
- para dentro do conteúdo), `"focus"` (usa `focusout`/`relatedTarget` em vez de
671
- `blur`, pela mesma razão do hover) ou `"manual"` (instância criada via
672
- auto-init, sem nenhum listener automático — só API programática, no espírito
673
- do Toast). `data-fs-dismiss="popover"` fecha a partir de qualquer elemento
674
- interno; `data-placement`/`data-align` controlam o posicionamento.
675
-
676
- Mockup: `mockup/overlays-commands.html#offcanvas`.
677
-
678
- ### Segmented Control
679
-
680
- Grupo de botões com estado selecionado (`.fs-segmented-control`/`.fs-segmented-item`/
681
- `.fs-segmented-label`, `packages/fokus-components/scss/components/_segmented-control.scss`), 100% CSS.
682
- Modo exclusivo: `<input type="radio">` (mesmo `name` em todos os itens do
683
- grupo). Modo inclusivo: `<input type="checkbox">`, cada item
684
- seleciona/deseleciona de forma independente. O `<input>` fica visualmente
685
- oculto (mesma técnica de `.fs-file-input`, `packages/fokus-components/scss/forms/_forms.scss`) e o
686
- `<label>` irmão recebe o estilo — o item selecionado reaproveita
687
- `color-contrast()` (mesma função de botões/badges/pagination) para garantir
688
- contraste. Tamanhos `.fs-segmented-control-sm`/`-lg`.
689
-
690
- Mockup: `mockup/forms.html#segmented-control`.
691
-
692
- ### Skeletons
693
-
694
- Placeholder de carregamento (`.fs-skeleton`, `packages/fokus-components/scss/components/_skeleton.scss`),
695
- 100% CSS. Variantes `.fs-skeleton-text`/`-circle`/`-rect`; tamanho/forma
696
- controlados por largura/altura inline ou pelo elemento host. Animação padrão
697
- "pulse" (oscila a opacidade); variante `.fs-skeleton-wave` substitui por um
698
- brilho que varre da esquerda pra direita via pseudo-elemento. Ambas
699
- desativadas em `prefers-reduced-motion: reduce`.
700
-
701
- Mockup: `mockup/feedback-actions.html#skeleton`.
702
-
703
- ### Timeline
704
-
705
- Linha do tempo (`.fs-timeline`/`.fs-timeline-item`/`.fs-timeline-marker`/
706
- `.fs-timeline-content`, `packages/fokus-components/scss/components/_timeline.scss`), 100% CSS, vertical por
707
- padrão (`.fs-timeline-horizontal` inverte o eixo). Estados por item: padrão
708
- (pendente), `.fs-timeline-active`, `.fs-timeline-completed` (marcador com "check",
709
- mesmo ícone do Stepper) e `.fs-timeline-failed`, reaproveitando os tokens de cor
710
- de estado (`--fs-color-primary/success/danger`). O conector entre
711
- marcadores fica na cor de sucesso depois de um item concluído, mesma lógica
712
- de progresso do Stepper (`packages/fokus-components/scss/components/_stepper.scss`).
713
-
714
- Mockup: `mockup/content-data.html#timeline`.
715
-
716
- ### Collapse (standalone)
717
-
718
- Extrai o padrão `collapse()`/`expand()` de `packages/fokus-js/js/core/transition.js` — já usado
719
- internamente pelo Accordion — para uma seção expansível independente, sem
720
- precisar de um accordion completo. `.fs-collapse` (`packages/fokus-components/scss/components/_collapse.scss`)
721
- só define o `overflow: hidden` exigido pela animação de `height`. `packages/fokus-js/js/collapse.js`
722
- (`FokusStyles.Collapse`) segue a API da seção 20: auto-init via
723
- `data-fs="collapse"` no gatilho com `data-fs-target`, `getInstance()`,
724
- `.show()`/`.hide()`/`.toggle()`/`.dispose()`, eventos
725
- `fs:collapse:shown`/`-hidden`, `aria-expanded`/`aria-controls` geridos
726
- automaticamente. Estado inicial aberto via `aria-expanded="true"` no gatilho.
727
-
728
- Mockup: `mockup/navigation-disclosure.html#collapse`.
729
-
730
- ### Breadcrumb Avançado
731
-
732
- Estende `.fs-breadcrumb`/`.fs-breadcrumb-item` (`packages/fokus-components/scss/components/_breadcrumbs.scss`)
733
- com truncamento e colapso automático em telas pequenas, via `packages/fokus-js/js/breadcrumb.js`
734
- (`FokusStyles.Breadcrumb`, auto-init com `data-fs="breadcrumb"` na lista,
735
- `data-max-items` configurável). Cada label ganha `.fs-breadcrumb-item-truncate`
736
- (reticências por CSS); labels que realmente transbordam (medido só depois de
737
- `document.fonts.ready`, por causa da tipografia self-hosted da seção 18.2)
738
- ganham um `Tooltip` (`packages/fokus-js/js/tooltip.js`) com o texto completo. Abaixo do
739
- breakpoint `sm` (640px), se a lista tiver mais itens que `data-max-items`,
740
- os níveis intermediários são substituídos por um único item `.fs-breadcrumb-more`
741
- ("…") que **compõe um `Dropdown`** (`packages/fokus-js/js/dropdown.js`, mesmo padrão de
742
- composição do Select customizado) com os links ocultos — mantém
743
- sempre o primeiro e o último nível visíveis.
744
-
745
- Mockup: `mockup/navigation-disclosure.html#pagination`.
746
-
747
- ### Input Group
748
-
749
- Funde `.fs-form-control` (ou `.fs-form-select`/`.fs-btn`) com "addons" de texto/ícone
750
- de prefixo/sufixo (`.fs-input-group`/`.fs-input-group-text`,
751
- `packages/fokus-components/scss/forms/_forms.scss`), 100% CSS. A altura do addon acompanha a do
752
- controle via `align-items: stretch` (sem precisar fixar `height`); as bordas
753
- adjacentes são fundidas (sem dupla borda) e só as pontas do grupo mantêm o
754
- radius. Tamanhos `.fs-input-group-sm`/`-lg`.
755
-
756
- Mockup: `mockup/forms.html#input-group`.
757
-
758
- ### Alert Dialog / Confirm
759
-
760
- Variante do Modal (`packages/fokus-components/scss/components/_alert-dialog.scss`, estende
761
- `.fs-modal`/`.fs-modal-dialog`/`.fs-modal-content`/`.fs-modal-footer` sem duplicar
762
- layout) para confirmação, 100% programática — ao contrário dos demais
763
- componentes (auto-init declarativo via `data-fs`), é montada na hora por
764
- `FokusStyles.confirm(options)` (`packages/fokus-js/js/confirm.js`), sem precisar de marcação
765
- pré-declarada na página. Internamente reaproveita `packages/fokus-js/js/modal.js` (foco,
766
- teclado, overlay) com um gatilho sintético. Retorna uma `Promise<boolean>`:
767
- `true` se o botão de confirmação for clicado, `false` se cancelado ou
768
- fechado por Escape/clique fora. Opções: `title`, `message`, `confirmText`,
769
- `cancelText`, `variant` (cor de estado do ícone circular e do botão de
770
- confirmação, reaproveitando `color-contrast()`). O foco volta para o
771
- elemento que estava focado antes da chamada (o botão que abriu o diálogo).
772
-
773
- Mockup: `mockup/overlays-commands.html#alert-dialog`.
774
-
775
- ### Divider
776
-
777
- Linha divisória (`packages/fokus-components/scss/components/_divider.scss`), 100% CSS.
778
- `<hr class="divider">` para o traço simples; `<div class="divider">` (não
779
- pode ser `<hr>`, que não aceita filhos) com `.fs-divider-label` para texto
780
- centralizado, flanqueado por duas linhas via pseudo-elementos.
781
-
782
- Mockup: `mockup/foundations.html#divider`.
783
-
784
- ### Empty State
785
-
786
- Bloco padrão para listas/telas vazias (`.fs-empty-state`,
787
- `packages/fokus-components/scss/components/_empty-state.scss`), 100% CSS: `.fs-empty-state-icon` (slot
788
- vazio para o consumidor colocar seu próprio SVG/emoji/ilustração),
789
- `.fs-empty-state-title`, `.fs-empty-state-text` e ação opcional reaproveitando os
790
- botões existentes.
791
-
792
- Mockup: `mockup/feedback-actions.html#empty-state`.
793
-
794
- ### Rating / Stars
795
-
796
- Avaliação por estrelas (`.fs-rating`/`.fs-rating-star`, `packages/fokus-components/scss/components/_rating.scss`),
797
- 100% CSS — mesma técnica de input oculto + label irmão do Segmented Control
798
- (seção anterior): um `<input type="radio">` por estrela, exclusivo dentro do
799
- grupo. A marcação usa os pares input+label em ordem decrescente de valor
800
- (5, 4, 3...) com `.fs-rating` em `row-reverse` — o truque clássico de CSS para
801
- destacar "a estrela clicada e todas à esquerda dela" usando só o combinador
802
- de irmãos gerais (`~`). Tamanhos `.fs-rating-sm`/`-lg`.
803
-
804
- Mockup: `mockup/forms.html#rating`.
805
-
806
- ### Badge Dismissível / Tag
807
-
808
- Tag removível (`.fs-tag`, `packages/fokus-components/scss/components/_tag.scss`), estendendo
809
- `.fs-badge` e `.fs-btn-close` sem duplicar estilos — só ajusta o
810
- tamanho do botão de fechar (14×14px) para caber num badge. Precisa de
811
- JavaScript, mas de forma mínima:
812
- `packages/fokus-js/js/tag.js` (`FokusStyles.Tag`) só ouve o clique em `[data-fs-dismiss="tag"]`.
813
- Antes de remover o elemento do DOM, dispara o evento **cancelável**
814
- `fs:tag:dismissed` (mesmo espírito de `fs:stepper:beforechange`) —
815
- `preventDefault()` bloqueia a remoção.
816
-
817
- Mockup: `mockup/feedback-actions.html#tag`.
818
-
819
- ### File Input Drag-and-Drop
820
-
821
- Evolui o upload de arquivo (`.fs-file-upload`/`.fs-file-input`/`.fs-file-label`)
822
- com arrastar-e-soltar. `packages/fokus-js/js/file-drop.js` (`FokusStyles.FileDrop`)
823
- auto-inicia via `data-fs="file-drop"` no próprio `<label for="...">`
824
- (o input associado é resolvido pelo atributo `for`, o mesmo vínculo que já
825
- existe entre `.fs-file-input`/`.fs-file-label`); escuta `dragenter`/`dragover`/
826
- `dragleave`/`drop`, aplicando `.is-dragover` como feedback visual, e ao
827
- soltar sincroniza `input.files` com o arquivo solto, disparando `change`
828
- nativo (mesmo padrão do Select customizado). Variante visual
829
- `.fs-file-label-dropzone` para quando o alvo de soltar precisa ser maior que
830
- o botão padrão.
831
-
832
- Mockup: `mockup/forms.html#file-upload`.
833
-
834
- ### Hover Card
835
-
836
- Não é um componente novo — composição do Popover (`packages/fokus-components/scss/components/_popover.scss`,
837
- `packages/fokus-js/js/popover.js`) com `data-trigger="hover"` (já suportado) e
838
- conteúdo mais rico (ex. avatar + bio). O único ajuste é visual: o
839
- modificador `.fs-popover-hover-card` alarga o popover (320px) e alinha um
840
- layout de linha (avatar ao lado do texto) no `.fs-popover-body`.
841
-
842
- Mockup: `mockup/overlays-commands.html#hover-card`.
843
-
844
- ## 22. Testes Automatizados
845
-
846
- - **Teste funcional de JavaScript:** Vitest com `jsdom` (`vitest.config.mjs`,
847
- `tests/unit/`), cobrindo estado, atributos ARIA e eventos disparados por
848
- cada componente interativo e pelos módulos de `packages/fokus-js/js/core/` (posicionamento,
849
- overlay, foco, transição). Executado via `npm test`.
850
- - **Teste visual (regressão de CSS):** Playwright (`playwright.config.mjs`,
851
- `tests/visual/`), com screenshots de baseline por mockup e testes de
852
- interação (abrir/fechar dropdown, modal, accordion, tabs, toast — foco,
853
- Escape, clique fora, navegação por teclado). Executado via
854
- `npm run test:visual`; as baselines são geradas por plataforma (sufixo
855
- `-win32`/`-linux` no nome do arquivo), com as baselines Linux geradas em
856
- um container Docker (`mcr.microsoft.com/playwright`) para bater com o
857
- ambiente do CI (`ubuntu-latest`).
858
- - Os laboratórios em `mockup/*.html` são as fixtures oficiais de regressão
859
- visual; as fontes em `mockup/examples/*.html` preservam a cobertura de
860
- acessibilidade e interações dos componentes
861
- visuais — cada componente/grupo implementado tem um mockup dedicado,
862
- mantido atualizado.
863
- - Testes (funcionais e visuais) rodam automaticamente no GitHub Actions a
864
- cada push/PR (`.github/workflows/ci.yml`), além do lint e build.