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.
- package/dist/css/components.css +561 -83
- package/dist/css/components.min.css +1 -1
- package/dist/css/fokus-components.css +561 -83
- package/dist/css/fokus-components.min.css +1 -1
- package/dist/css/fokus-rtl.css +697 -83
- package/dist/css/fokus-rtl.min.css +1 -1
- package/dist/css/fokus-utilities.css +136 -0
- package/dist/css/fokus-utilities.min.css +1 -1
- package/dist/css/fokus.css +996 -258
- package/dist/css/fokus.min.css +1 -1
- package/dist/css/forms.css +300 -176
- package/dist/css/forms.min.css +1 -1
- package/dist/css/helpers.css +136 -0
- package/dist/css/helpers.min.css +1 -1
- package/dist/js/fokus.js +270 -25
- package/dist/js/fokus.min.js +18 -18
- package/package.json +17 -15
- package/packages/fokus-components/scss/components/_alerts.scss +128 -6
- package/packages/fokus-components/scss/components/_badges.scss +26 -10
- package/packages/fokus-components/scss/components/_index.scss +1 -0
- package/packages/fokus-components/scss/components/_popover.scss +131 -21
- package/packages/fokus-components/scss/components/_responsive.scss +23 -0
- package/packages/fokus-components/scss/components/_tag.scss +37 -14
- package/packages/fokus-components/scss/components/_toasts.scss +156 -11
- package/packages/fokus-components/scss/components/_tooltips.scss +70 -18
- package/packages/fokus-components/scss/forms/_check-radio-switch.scss +313 -215
- package/packages/fokus-components/scss/forms/_forms.scss +16 -0
- package/packages/fokus-js/js/carousel.d.ts +4 -0
- package/packages/fokus-js/js/carousel.js +8 -0
- package/packages/fokus-js/js/core/positioning.js +18 -9
- package/packages/fokus-js/js/dropdown.d.ts +4 -0
- package/packages/fokus-js/js/dropdown.js +7 -0
- package/packages/fokus-js/js/popover.js +26 -1
- package/packages/fokus-js/js/tabs.d.ts +3 -0
- package/packages/fokus-js/js/tabs.js +5 -0
- package/packages/fokus-js/js/tag.js +17 -0
- package/packages/fokus-js/js/toast.js +77 -3
- package/packages/fokus-js/js/tooltip.d.ts +8 -1
- package/packages/fokus-js/js/tooltip.js +106 -13
- package/packages/fokus-utilities/scss/utilities/_api.scss +48 -0
- package/CHANGELOG.md +0 -910
- package/dist/css/components.css.map +0 -1
- package/dist/css/components.min.css.map +0 -1
- package/dist/css/fokus-components.css.map +0 -1
- package/dist/css/fokus-components.min.css.map +0 -1
- package/dist/css/fokus-core.css.map +0 -1
- package/dist/css/fokus-core.min.css.map +0 -1
- package/dist/css/fokus-dark.css.map +0 -1
- package/dist/css/fokus-dark.min.css.map +0 -1
- package/dist/css/fokus-rtl.css.map +0 -1
- package/dist/css/fokus-rtl.min.css.map +0 -1
- package/dist/css/fokus-utilities.css.map +0 -1
- package/dist/css/fokus-utilities.min.css.map +0 -1
- package/dist/css/fokus.css.map +0 -1
- package/dist/css/fokus.min.css.map +0 -1
- package/dist/css/fonts.css.map +0 -1
- package/dist/css/fonts.min.css.map +0 -1
- package/dist/css/forms.css.map +0 -1
- package/dist/css/forms.min.css.map +0 -1
- package/dist/css/helpers.css.map +0 -1
- package/dist/css/helpers.min.css.map +0 -1
- package/dist/css/layout.css.map +0 -1
- package/dist/css/layout.min.css.map +0 -1
- package/dist/js/fokus.js.map +0 -7
- package/dist/js/fokus.min.js.map +0 -7
- package/docs/README.md +0 -86
- package/docs/comparison.md +0 -124
- package/docs/components/accordion.md +0 -104
- package/docs/components/alert-dialog.md +0 -99
- package/docs/components/alert.md +0 -59
- package/docs/components/avatar.md +0 -13
- package/docs/components/badge.md +0 -82
- package/docs/components/breadcrumb.md +0 -93
- package/docs/components/button-group.md +0 -13
- package/docs/components/button.md +0 -98
- package/docs/components/card.md +0 -111
- package/docs/components/carousel.md +0 -167
- package/docs/components/checkbox.md +0 -97
- package/docs/components/close-button.md +0 -13
- package/docs/components/code.md +0 -13
- package/docs/components/collapse.md +0 -78
- package/docs/components/combobox.md +0 -123
- package/docs/components/command-palette.md +0 -131
- package/docs/components/datatable.md +0 -173
- package/docs/components/datepicker.md +0 -137
- package/docs/components/divider.md +0 -57
- package/docs/components/dropdown.md +0 -103
- package/docs/components/empty-state.md +0 -65
- package/docs/components/file-upload-advanced.md +0 -116
- package/docs/components/file-upload.md +0 -93
- package/docs/components/icon-link.md +0 -13
- package/docs/components/input-group.md +0 -73
- package/docs/components/input.md +0 -90
- package/docs/components/list-group.md +0 -13
- package/docs/components/modal.md +0 -120
- package/docs/components/navbar.md +0 -74
- package/docs/components/nested-menu.md +0 -90
- package/docs/components/notification-center.md +0 -116
- package/docs/components/offcanvas.md +0 -102
- package/docs/components/pagination.md +0 -145
- package/docs/components/placeholder.md +0 -13
- package/docs/components/popover.md +0 -105
- package/docs/components/progress.md +0 -126
- package/docs/components/radio.md +0 -70
- package/docs/components/range.md +0 -83
- package/docs/components/rating.md +0 -91
- package/docs/components/ratio.md +0 -13
- package/docs/components/scrollspy.md +0 -13
- package/docs/components/segmented-control.md +0 -82
- package/docs/components/select.md +0 -89
- package/docs/components/skeleton.md +0 -70
- package/docs/components/stepper.md +0 -107
- package/docs/components/switch.md +0 -75
- package/docs/components/table.md +0 -90
- package/docs/components/tabs.md +0 -104
- package/docs/components/tag.md +0 -129
- package/docs/components/tile.md +0 -112
- package/docs/components/timeline.md +0 -78
- package/docs/components/toast.md +0 -95
- package/docs/components/tooltip.md +0 -77
- package/docs/components/tree-view.md +0 -118
- package/docs/contributing/contributing.md +0 -18
- package/docs/getting-started/installation.md +0 -70
- package/docs/getting-started/usage.md +0 -105
- package/docs/guides/accessibility.md +0 -102
- package/docs/guides/charts.md +0 -73
- package/docs/guides/dark-mode.md +0 -90
- package/docs/guides/icons.md +0 -99
- package/docs/guides/javascript-api.md +0 -9
- package/docs/guides/layout-advanced.md +0 -118
- package/docs/guides/migration-clarus-to-fokus.md +0 -48
- package/docs/guides/migration-external.md +0 -123
- package/docs/guides/migration-v1.md +0 -63
- package/docs/guides/print.md +0 -30
- package/docs/guides/rtl-and-system-preferences.md +0 -28
- package/docs/guides/theming.md +0 -140
- package/docs/guides/utility-api.md +0 -9
- package/docs/prompts/prompt-plan.md +0 -45
- package/docs/reference/accessibility-matrix.md +0 -77
- package/docs/reference/browser-support.md +0 -75
- package/docs/reference/contrast-report.md +0 -50
- package/docs/reference/definitions.md +0 -864
- package/docs/reference/design-tokens.md +0 -194
- package/docs/reference/scss-architecture.md +0 -227
- package/docs/reference/size-baseline.json +0 -34
- package/docs/reference/stability.md +0 -89
- package/docs/showcase.md +0 -25
- package/mockup/README.md +0 -41
- package/mockup/assets/carousel-planning.png +0 -0
- package/mockup/assets/carousel-workspace.png +0 -0
- package/mockup/assets/example-theme.css +0 -8
- package/mockup/assets/example-theme.js +0 -11
- package/mockup/assets/showcase-contracts.js +0 -84
- package/mockup/assets/showcase.css +0 -91
- package/mockup/assets/showcase.js +0 -724
- package/mockup/content-data.html +0 -9
- package/mockup/examples/accordion-tabs-toast.html +0 -149
- package/mockup/examples/alert-dialog.html +0 -84
- package/mockup/examples/alerts.html +0 -41
- package/mockup/examples/badges-alerts.html +0 -77
- package/mockup/examples/buttons.html +0 -58
- package/mockup/examples/cards.html +0 -132
- package/mockup/examples/carousel.html +0 -126
- package/mockup/examples/charts.html +0 -102
- package/mockup/examples/check-radio-switch.html +0 -144
- package/mockup/examples/collapse.html +0 -69
- package/mockup/examples/combobox.html +0 -60
- package/mockup/examples/command-palette.html +0 -64
- package/mockup/examples/datatable.html +0 -113
- package/mockup/examples/datepicker.html +0 -62
- package/mockup/examples/divider.html +0 -45
- package/mockup/examples/dropdown-tooltip.html +0 -77
- package/mockup/examples/empty-state.html +0 -56
- package/mockup/examples/file-drop.html +0 -74
- package/mockup/examples/file-upload-advanced.html +0 -68
- package/mockup/examples/forms-advanced.html +0 -77
- package/mockup/examples/hover-card.html +0 -86
- package/mockup/examples/icons.html +0 -157
- package/mockup/examples/input-group.html +0 -74
- package/mockup/examples/js-foundation.html +0 -215
- package/mockup/examples/layout.html +0 -134
- package/mockup/examples/modal-select.html +0 -127
- package/mockup/examples/nested-menu.html +0 -73
- package/mockup/examples/notification-center.html +0 -86
- package/mockup/examples/offcanvas-popover.html +0 -133
- package/mockup/examples/pagination-breadcrumbs.html +0 -92
- package/mockup/examples/range.html +0 -69
- package/mockup/examples/rating.html +0 -103
- package/mockup/examples/segmented-control.html +0 -96
- package/mockup/examples/skeletons.html +0 -82
- package/mockup/examples/spinner-progress.html +0 -130
- package/mockup/examples/stepper.html +0 -119
- package/mockup/examples/tables-navbar.html +0 -89
- package/mockup/examples/tag.html +0 -105
- package/mockup/examples/theming.html +0 -68
- package/mockup/examples/tile.html +0 -107
- package/mockup/examples/timeline.html +0 -108
- package/mockup/examples/tree-view.html +0 -68
- package/mockup/feedback-actions.html +0 -9
- package/mockup/forms.html +0 -13
- package/mockup/foundations.html +0 -7
- package/mockup/kitchen-sink.html +0 -696
- package/mockup/navigation-disclosure.html +0 -11
- package/mockup/overlays-commands.html +0 -12
- package/mockup/templates/README.md +0 -20
- package/mockup/templates/admin.html +0 -334
- package/mockup/templates/auth.html +0 -234
- package/mockup/templates/dashboard.html +0 -442
- package/mockup/templates/landing.html +0 -397
- package/packages/fokus-icons/package.json +0 -46
- package/scripts/migrate-fokus-map.json +0 -1366
- 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.
|