forlogic-core 2.0.2 → 2.0.4

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.
@@ -0,0 +1,137 @@
1
+ <!-- ⚠️ ARQUIVO GERADO AUTOMATICAMENTE — NÃO EDITAR MANUALMENTE -->
2
+ <!-- Fonte: src/design-system/docs/ | Regenerar: npx tsx scripts/generate-ds-docs.ts -->
3
+
4
+ # Notifications & Feedback
5
+
6
+ Categoria: **Notifications & Feedback** | 4 componentes
7
+
8
+ ### Toast
9
+
10
+ Componente de notificação toast usando Sonner. Feedback temporário e não bloqueante que informa rapidamente o usuário sem competir visualmente com outros Toasts.
11
+
12
+ **Uso:**
13
+ ```tsx
14
+ import { toast } from "sonner"
15
+
16
+ // Informativo (BG #FFFFFF)
17
+ toast("Mensagem simples")
18
+ toast.info("Informação importante")
19
+
20
+ // Sucesso (BG #E0FBE8)
21
+ toast.success("Operação concluída")
22
+
23
+ // Alerta (BG #FEF3C8)
24
+ toast.warning("Atenção necessária")
25
+
26
+ // Erro (BG #FEE1E1)
27
+ toast.error("Algo deu errado")
28
+ ```
29
+
30
+ **Props:**
31
+ | Prop | Tipo | Padrão | Descrição |
32
+ |------|------|--------|-----------|
33
+ | `message` | `string | ReactNode` | - | Texto principal ou conteúdo do toast. |
34
+ | `description` | `string | ReactNode` | - | Descrição adicional exibida abaixo do título. |
35
+ | `action` | `{ label: string, onClick: () => void }` | - | Botão de ação principal. |
36
+ | `cancel` | `{ label: string, onClick: () => void }` | - | Botão de cancelamento secundário. |
37
+ | `duration` | `number` | 4000 | Duração em ms antes de dispensar. Use Infinity para persistir. |
38
+ | `closeButton` | `boolean` | false | Exibe botão X para fechar o toast. |
39
+ | `icon` | `ReactNode` | - | Ícone personalizado para o toast. |
40
+ | `id` | `string | number` | - | ID único para atualizar ou dispensar o toast. |
41
+ | `onDismiss` | `(toast) => void` | - | Callback executado quando o toast é dispensado. |
42
+ | `onAutoClose` | `(toast) => void` | - | Callback executado quando o toast fecha automaticamente. |
43
+
44
+ **Exemplos:**
45
+ ```tsx
46
+ // Toast é um feedback temporário e não bloqueante
47
+ // - Informa rapidamente o usuário
48
+ // - Não compete visualmente com outros Toasts
49
+ // - Empilhamento vertical sem sobreposição
50
+ // - Ordem previsível: mais recente no topo
51
+ ```
52
+ ```tsx
53
+ // Empilhamento vertical com espaçamento consistente
54
+ toast.success(
55
+ ```
56
+ ```tsx
57
+ // Configuração de posição no Toaster:
58
+ <Sonner
59
+ position=
60
+ ```
61
+
62
+ **Acessibilidade:**
63
+ - Utiliza ARIA live regions para anunciar toasts aos leitores de tela
64
+ - Dispensável via tecla Escape
65
+ - Auto-dispensa com duração configurável respeitando usabilidade
66
+ - Suporte a swipe para dispensar em dispositivos touch
67
+ - Respeita prefers-reduced-motion do sistema operacional
68
+ - Foco gerenciado corretamente quando toast contém elementos interativos
69
+
70
+ **Notas:**
71
+ - Informativo (#FFFFFF): toast() e toast.info() - Para informações contextuais e notificações neutras
72
+ - Sucesso (#E0FBE8): toast.success() - Para feedback de operações bem-sucedidas
73
+ - Alerta (#FEF3C8): toast.warning() - Para alertas que requerem atenção do usuário
74
+ - Erro (#FEE1E1): toast.error() - Para erros e falhas, considere incluir ação de retry
75
+ - Use toast.promise() para operações assíncronas com feedback de loading
76
+ - Mantenha mensagens curtas e objetivas (máximo 2 linhas)
77
+ - Forneça ação de
78
+ - para operações destrutivas quando possível
79
+ - Evite usar duration: Infinity sem closeButton ou action para dispensar
80
+
81
+ > Fonte: `src\design-system\docs\components\ToastDoc.tsx`
82
+
83
+ ---
84
+
85
+ ### Updates Notification
86
+
87
+ Botão com popover para exibir notificações de atualização das aplicações. Possui dois modos: automático (self-contained, busca dados da API sozinho) e controlado (recebe dados via props).
88
+
89
+ **Uso:**
90
+ ```tsx
91
+ // Modo automático — basta importar e usar, sem props
92
+ // O componente busca dados da API internamente usando useAuth() e useUpdatesNotification()
93
+ import { UpdatesNotification } from 'forlogic-core';
94
+
95
+ <UpdatesNotification />
96
+
97
+ // Modo controlado — para testes, docs ou lógica customizada
98
+ <UpdatesNotification
99
+ updates={[{ id: '1', title: 'Nova versão', text: 'Descrição' }]}
100
+ badgeCount={1}
101
+ onOpen={() => markAsViewed()}
102
+ onViewAll={() => window.open('https://apps4.qualiex.com/common/alias/up/view', '_blank')}
103
+ />
104
+ ```
105
+
106
+ **Exemplos:**
107
+ ```tsx
108
+ import { UpdatesNotification } from
109
+ ```
110
+
111
+ **Notas:**
112
+ - O componente possui dois modos: automático (sem props) e controlado (com props). O modo é determinado pela presença da prop updates.
113
+ - No modo automático, o componente usa useAuth() para obter o alias e useUpdatesNotification() para buscar dados da API.
114
+ - No modo controlado, todas as props são fornecidas externamente — útil para testes e documentação.
115
+ - O tipo canônico é UpdateNotificationItem (id, title, text), exportado do hook. UpdateNotification é um alias deprecated.
116
+ - No modo automático, onOpen chama markAsVisualized (POST Updates/userVisualized/3/undefined) e onViewAll abre a rota legada.
117
+ - O ícone utilizado é Coffee do Lucide React — não requer fontes externas nos projetos consumidores.
118
+ - O hook useUpdatesNotification também é exportado separadamente para uso avançado.
119
+ - Todas as chamadas à API incluem o header x-waf-rate (base64 do campo sub do JWT), exigido pelo WAF da API legada.
120
+ - Em caso de 401, o hook faz retry automático regenerando o token via QualiexErrorInterceptor.
121
+ - Em produção, o componente deve ser colocado no AppHeader — já está integrado no forlogic-core.
122
+
123
+ > Fonte: `src\design-system\docs\components\UpdatesNotificationDoc.tsx`
124
+
125
+ ---
126
+
127
+ ### Electronic Signature
128
+
129
+ *Documentação não extraída automaticamente. Consulte o Design System interativo em `/ds`.*
130
+
131
+ ---
132
+
133
+ ### ErrorBoundary
134
+
135
+ *Documentação não extraída automaticamente. Consulte o Design System interativo em `/ds`.*
136
+
137
+ ---
@@ -0,0 +1,95 @@
1
+ <!-- ⚠️ ARQUIVO GERADO AUTOMATICAMENTE — NÃO EDITAR MANUALMENTE -->
2
+ <!-- Fonte: src/design-system/docs/ | Regenerar: npx tsx scripts/generate-ds-docs.ts -->
3
+
4
+ # Plataforma
5
+
6
+ Categoria: **Plataforma** | 6 componentes
7
+
8
+ ### Autenticação (Auth)
9
+
10
+ *Documentação não extraída automaticamente. Consulte o Design System interativo em `/ds`.*
11
+
12
+ ---
13
+
14
+ ### Alias via URL
15
+
16
+ *Documentação não extraída automaticamente. Consulte o Design System interativo em `/ds`.*
17
+
18
+ ---
19
+
20
+ ### Acesso Módulo (ModuleAccess)
21
+
22
+ *Documentação não extraída automaticamente. Consulte o Design System interativo em `/ds`.*
23
+
24
+ ---
25
+
26
+ ### Assinatura Digital (Sign)
27
+
28
+ Componente único multi-provider de assinatura digital com fluxo em 3 fases: Upload → Assinatura → Download. Suporta Clicksign (widget JavaScript embedded v2.1.0, API v3) e D4Sign (iframe embedded, API v1). O provedor é resolvido automaticamente pela configuração da unidade na tabela sign_configs.
29
+
30
+ **Uso:**
31
+ ```tsx
32
+ // Uso básico — provedor resolvido automaticamente pela config da unidade
33
+ <DocumentSigner
34
+ showEventLog
35
+ onDocumentSigned={(data) => {
36
+ // data.provider → 'clicksign' ou 'd4sign'
37
+ // data.envelope_id, data.document_id, data.signer_id, data.environment
38
+ console.log('Assinado:', data);
39
+ }}
40
+ onError={(error) => {
41
+ console.error('Erro:', error.message);
42
+ }}
43
+ />
44
+
45
+ // Passando PDF programaticamente (sem upload manual)
46
+ <DocumentSigner
47
+ file={meuArquivoPdf}
48
+ onDocumentSigned={(data) => console.log('Assinado:', data)}
49
+ />
50
+ ```
51
+
52
+ **Props:**
53
+ | Prop | Tipo | Padrão | Descrição |
54
+ |------|------|--------|-----------|
55
+ | `file` | `File` | - | PDF passado programaticamente (pula upload manual) |
56
+ | `onDocumentSigned` | `(data: SignEnvelopeResult) => void` | - | Callback quando o documento é assinado. Retorna provider, envelope_id, document_id, signer_id, environment. |
57
+ | `onError` | `(error: Error) => void` | - | Callback em caso de erro |
58
+ | `showEventLog` | `boolean` | false | Exibe log de eventos no componente |
59
+
60
+ **Exemplos:**
61
+ ```tsx
62
+ import { DocumentSigner } from
63
+ ```
64
+ ```tsx
65
+ import { DocumentSigner } from
66
+ ```
67
+
68
+ **Notas:**
69
+ - Multi-provider: suporta Clicksign e D4Sign. O provedor é resolvido automaticamente pela configuração da unidade na tabela sign_configs.
70
+ - Clicksign: Widget embedded v2.1.0 com script carregado automaticamente pela lib (lazy load sob demanda). Usa API v3 com header
71
+ - (sem Bearer). Não é necessário adicionar nenhum script no index.html.
72
+ - D4Sign: iframe embedded apontando para secure.d4sign.com.br/embed/viewblob/{uuid}. Usa API v1 com tokenAPI + cryptKey como query params.
73
+ - D4Sign NÃO possui sandbox automático via secrets. É necessário configurar a unidade diretamente na tabela sign_configs (via /a/cs).
74
+ - Clicksign possui fallback automático para sandbox via secret CLICKSIGN_SANDBOX_API_KEY.
75
+ - Tabela unificada sign_configs com coluna provider (clicksign | d4sign). Campos extras do D4Sign: crypt_key, uuid_safe.
76
+ - Após assinatura: polling automático busca documento assinado a cada 10s, até 6 tentativas (~1 min).
77
+ - Se polling falhar, botão
78
+ - permite busca manual ilimitada.
79
+ - Configuração de produção: Admin → /a/cs (aba Assinatura digital).
80
+
81
+ > Fonte: `src\design-system\docs\components\SignDoc.tsx`
82
+
83
+ ---
84
+
85
+ ### Segurança (Vite Config)
86
+
87
+ *Documentação não extraída automaticamente. Consulte o Design System interativo em `/ds`.*
88
+
89
+ ---
90
+
91
+ ### Environments (Config)
92
+
93
+ *Documentação não extraída automaticamente. Consulte o Design System interativo em `/ds`.*
94
+
95
+ ---
@@ -0,0 +1,424 @@
1
+ <!-- ⚠️ ARQUIVO GERADO AUTOMATICAMENTE — NÃO EDITAR MANUALMENTE -->
2
+ <!-- Fonte: src/design-system/docs/ | Regenerar: npx tsx scripts/generate-ds-docs.ts -->
3
+
4
+ # Seletores
5
+
6
+ Categoria: **Seletores** | 7 componentes
7
+
8
+ ### TreeSelect (ComboTree)
9
+
10
+ Componente de seleção hierárquica (tree view) com busca recursiva, expansão por chevron e seleção por label. Também disponível como TreeSelect.
11
+
12
+ **Uso:**
13
+ ```tsx
14
+ import { ComboTree, type ComboTreeOption } from 'forlogic-core';
15
+ // 💡 Alias disponível: import { TreeSelect, type TreeSelectProps } from 'forlogic-core';
16
+ import { Folder, FolderOpen, FileText } from 'lucide-react';
17
+
18
+ const options: ComboTreeOption[] = [
19
+ {
20
+ value: 'quality',
21
+ label: 'Qualidade',
22
+ icon: Folder,
23
+ iconOpen: FolderOpen,
24
+ children: [
25
+ { value: 'docs', label: 'Documentos', icon: FileText },
26
+ { value: 'occurrences', label: 'Ocorrências', icon: FileText },
27
+ ],
28
+ },
29
+ { value: 'hr', label: 'RH' },
30
+ ];
31
+
32
+ <ComboTree
33
+ options={options}
34
+ value={selected}
35
+ onChange={setSelected}
36
+ label="Departamento"
37
+ placeholder="Selecione..."
38
+ />
39
+ ```
40
+
41
+ **Acessibilidade:**
42
+ - Navegação por teclado com Tab e Enter
43
+ - Aria-expanded indica estado de expansão dos nós
44
+ - Role tree e treeitem para semântica correta
45
+ - Busca por texto filtra sem perder contexto hierárquico
46
+
47
+ **Notas:**
48
+ - 💡 Alias: Também disponível como
49
+ - — import { TreeSelect } from
50
+ - ,
51
+
52
+ - ,
53
+
54
+
55
+ > Fonte: `src\design-system\docs\components\ComboTreeDoc.tsx`
56
+
57
+ ---
58
+
59
+ ### AutoComplete (Combobox)
60
+
61
+ Componente versátil para seleção única ou múltipla com busca inteligente. Combina Popover e Command para autocomplete. Também disponível como AutoComplete. O componente Command é usado internamente para fornecer funcionalidades de busca e navegação por teclado.
62
+
63
+ **Uso:**
64
+ ```tsx
65
+ import { Combobox } from "forlogic-core"
66
+
67
+ const options = [
68
+ { value: 'next.js', label: 'Next.js' },
69
+ { value: 'sveltekit', label: 'SvelteKit' },
70
+ ]
71
+
72
+ // Seleção única
73
+ <Combobox
74
+ options={options}
75
+ value={selected}
76
+ onChange={setSelected}
77
+ placeholder="Select..."
78
+ />
79
+
80
+ // Seleção múltipla
81
+ <Combobox
82
+ multiple
83
+ options={options}
84
+ value={selectedArray}
85
+ onChange={setSelectedArray}
86
+ placeholder="Select multiple..."
87
+ />
88
+
89
+ // =====================
90
+ // POPOVER COM COMMAND
91
+ // =====================
92
+ import { Popover, PopoverTrigger, PopoverContent, Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, Button } from "forlogic-core"
93
+
94
+ <Popover open={open} onOpenChange={setOpen}>
95
+ <PopoverTrigger asChild>
96
+ <Button variant="outline">
97
+ {selectedStatus ? selectedStatus.label : "+ Definir status"}
98
+ </Button>
99
+ </PopoverTrigger>
100
+ <PopoverContent className="p-0 bg-popover" side="right" align="start">
101
+ <Command>
102
+ <CommandInput placeholder="Alterar status..." />
103
+ <CommandList>
104
+ <CommandEmpty>Nenhum resultado.</CommandEmpty>
105
+ <CommandGroup>
106
+ {statuses.map((status) => (
107
+ <CommandItem
108
+ key={status.value}
109
+ value={status.value}
110
+ onSelect={(value) => {
111
+ setSelectedStatus(statuses.find((s) => s.value === value))
112
+ setOpen(false)
113
+ }}
114
+ >
115
+ {status.label}
116
+ </CommandItem>
117
+ ))}
118
+ </CommandGroup>
119
+ </CommandList>
120
+ </Command>
121
+ </PopoverContent>
122
+ </Popover>
123
+
124
+ // =====================
125
+ // DROPDOWN MENU COM COMMAND
126
+ // =====================
127
+ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent } from "forlogic-core"
128
+
129
+ <DropdownMenu open={open} onOpenChange={setOpen}>
130
+ <DropdownMenuTrigger asChild>
131
+ <Button variant="ghost" size="sm">
132
+ <MoreVertical className="h-4 w-4" />
133
+ </Button>
134
+ </DropdownMenuTrigger>
135
+ <DropdownMenuContent align="end" className="w-[200px] bg-popover">
136
+ <DropdownMenuLabel>Ações</DropdownMenuLabel>
137
+ <DropdownMenuSeparator />
138
+ <DropdownMenuSub>
139
+ <DropdownMenuSubTrigger>Aplicar label</DropdownMenuSubTrigger>
140
+ <DropdownMenuSubContent className="p-0 bg-popover">
141
+ <Command>
142
+ <CommandInput placeholder="Filtrar label..." />
143
+ <CommandList>
144
+ <CommandEmpty>Nenhum label encontrado.</CommandEmpty>
145
+ <CommandGroup>
146
+ {labels.map((label) => (
147
+ <CommandItem
148
+ key={label}
149
+ value={label}
150
+ onSelect={(value) => {
151
+ setLabel(value)
152
+ setOpen(false)
153
+ }}
154
+ >
155
+ {label}
156
+ </CommandItem>
157
+ ))}
158
+ </CommandGroup>
159
+ </CommandList>
160
+ </Command>
161
+ </DropdownMenuSubContent>
162
+ </DropdownMenuSub>
163
+ </DropdownMenuContent>
164
+ </DropdownMenu>
165
+
166
+ // =====================
167
+ // RESPONSIVO (Popover/Drawer)
168
+ // =====================
169
+ import { useMediaQuery } from "@/design-system/hooks/useMediaQuery"
170
+ import { Drawer, DrawerTrigger, DrawerContent } from "forlogic-core"
171
+
172
+ function ResponsiveCombobox() {
173
+ const isDesktop = useMediaQuery("(min-width: 768px)")
174
+
175
+ if (isDesktop) {
176
+ return (
177
+ <Popover>
178
+ <PopoverTrigger asChild>
179
+ <Button>Definir status</Button>
180
+ </PopoverTrigger>
181
+ <PopoverContent className="p-0 bg-popover">
182
+ <StatusList />
183
+ </PopoverContent>
184
+ </Popover>
185
+ )
186
+ }
187
+
188
+ return (
189
+ <Drawer>
190
+ <DrawerTrigger asChild>
191
+ <Button>Definir status</Button>
192
+ </DrawerTrigger>
193
+ <DrawerContent>
194
+ <StatusList />
195
+ </DrawerContent>
196
+ </Drawer>
197
+ )
198
+ }
199
+ ```
200
+
201
+ **Acessibilidade:**
202
+ - Navegação completa por teclado
203
+ - Busca inteligente (sem acentos, case-insensitive)
204
+ - Segue padrão WAI-ARIA combobox
205
+ - Anúncios para leitores de tela
206
+ - Badges removíveis com teclado (modo múltiplo)
207
+ - Versão responsiva com Drawer para mobile
208
+
209
+ **Notas:**
210
+ - 💡 Alias: Também disponível como
211
+ - — import { AutoComplete } from
212
+ - ,
213
+
214
+
215
+ > Fonte: `src\design-system\docs\components\ComboboxDoc.tsx`
216
+
217
+ ---
218
+
219
+ ### TreeSelect (ComboTree)
220
+
221
+ Componente de seleção hierárquica (tree view) com busca recursiva, expansão por chevron e seleção por label. Também disponível como TreeSelect.
222
+
223
+ **Uso:**
224
+ ```tsx
225
+ import { ComboTree, type ComboTreeOption } from 'forlogic-core';
226
+ // 💡 Alias disponível: import { TreeSelect, type TreeSelectProps } from 'forlogic-core';
227
+ import { Folder, FolderOpen, FileText } from 'lucide-react';
228
+
229
+ const options: ComboTreeOption[] = [
230
+ {
231
+ value: 'quality',
232
+ label: 'Qualidade',
233
+ icon: Folder,
234
+ iconOpen: FolderOpen,
235
+ children: [
236
+ { value: 'docs', label: 'Documentos', icon: FileText },
237
+ { value: 'occurrences', label: 'Ocorrências', icon: FileText },
238
+ ],
239
+ },
240
+ { value: 'hr', label: 'RH' },
241
+ ];
242
+
243
+ <ComboTree
244
+ options={options}
245
+ value={selected}
246
+ onChange={setSelected}
247
+ label="Departamento"
248
+ placeholder="Selecione..."
249
+ />
250
+ ```
251
+
252
+ **Acessibilidade:**
253
+ - Navegação por teclado com Tab e Enter
254
+ - Aria-expanded indica estado de expansão dos nós
255
+ - Role tree e treeitem para semântica correta
256
+ - Busca por texto filtra sem perder contexto hierárquico
257
+
258
+ **Notas:**
259
+ - 💡 Alias: Também disponível como
260
+ - — import { TreeSelect } from
261
+ - ,
262
+
263
+ - ,
264
+
265
+
266
+ > Fonte: `src\design-system\docs\components\ComboTreeDoc.tsx`
267
+
268
+ ---
269
+
270
+ ### Color Picker
271
+
272
+ Seletor de cores com paleta predefinida e seletor customizado.
273
+
274
+ **Uso:**
275
+ ```tsx
276
+ import { ColorPicker } from "forlogic-core"
277
+ import { useState } from 'react'
278
+
279
+ const [color, setColor] = useState('#3b82f6')
280
+
281
+ <ColorPicker
282
+ value={color}
283
+ onChange={setColor}
284
+ label="Escolha uma cor"
285
+ />
286
+ ```
287
+
288
+ **Props:**
289
+ | Prop | Tipo | Padrão | Descrição |
290
+ |------|------|--------|-----------|
291
+ | `value` | `string` | #3b82f6 | Cor atual selecionada (formato hexadecimal). |
292
+ | `onChange` | `(color: string) => void` | - | Callback quando a cor é alterada. |
293
+ | `label` | `string` | - | Label opcional para o campo. |
294
+
295
+ **Acessibilidade:**
296
+ - Botão com papel semântico correto
297
+ - Input de cor nativo acessível
298
+ - Labels descritivos para cores predefinidas
299
+ - Navegação por teclado completa
300
+
301
+ > Fonte: `src\design-system\docs\components\ColorPickerDoc.tsx`
302
+
303
+ ---
304
+
305
+ ### Icon Picker
306
+
307
+ Seletor de ícones da biblioteca Lucide React com busca integrada.
308
+
309
+ **Uso:**
310
+ ```tsx
311
+ import { IconPicker } from "forlogic-core"
312
+ import { useState } from 'react'
313
+
314
+ const [icon, setIcon] = useState('Star')
315
+
316
+ <IconPicker
317
+ value={icon}
318
+ onChange={setIcon}
319
+ label="Escolha um ícone"
320
+ />
321
+ ```
322
+
323
+ **Props:**
324
+ | Prop | Tipo | Padrão | Descrição |
325
+ |------|------|--------|-----------|
326
+ | `value` | `string` | Star | Nome do ícone selecionado (Lucide React). |
327
+ | `onChange` | `(iconName: string) => void` | - | Callback quando o ícone é alterado. |
328
+ | `label` | `string` | - | Label opcional para o campo. |
329
+
330
+ **Acessibilidade:**
331
+ - Busca por nome do ícone
332
+ - Grid acessível por teclado
333
+ - Títulos descritivos em cada ícone
334
+ - Indicador visual de seleção
335
+ - Scroll area com navegação adequada
336
+
337
+ > Fonte: `src\design-system\docs\components\IconPickerDoc.tsx`
338
+
339
+ ---
340
+
341
+ ### Calendar & Date Picker
342
+
343
+ Componentes para seleção de datas. O Calendar exibe um calendário interativo, enquanto o Date Picker combina um campo de input com o calendário em um popover.
344
+
345
+ **Uso:**
346
+ ```tsx
347
+ import { Calendar, DatePicker } from "forlogic-core"
348
+ import { useState } from "react"
349
+
350
+ // Calendar
351
+ const [date, setDate] = useState<Date | undefined>(new Date())
352
+
353
+ <Calendar
354
+ mode="single"
355
+ selected={date}
356
+ onSelect={setDate}
357
+ className="rounded-md border"
358
+ />
359
+
360
+ // Date Picker
361
+ <DatePicker
362
+ date={date}
363
+ onDateChange={setDate}
364
+ placeholder="Selecione uma data"
365
+ />
366
+ ```
367
+
368
+ **Acessibilidade:**
369
+ - Navegação completa por teclado
370
+ - Teclas de seta para navegar entre datas
371
+ - Page Up/Down para navegação mensal
372
+ - Labels e roles ARIA apropriados
373
+ - Gerenciamento de foco adequado
374
+
375
+ > Fonte: `src\design-system\docs\components\CalendarDoc.tsx`
376
+
377
+ ---
378
+
379
+ ### RequiredFieldsCounter
380
+
381
+ Indica o progresso de preenchimento de campos obrigatórios em formulários com feedback visual e tooltips informativos.
382
+
383
+ **Uso:**
384
+ ```tsx
385
+ import { RequiredFieldsCounter } from "@/design-system/components/RequiredFieldsCounter"
386
+
387
+ // Progresso parcial
388
+ <RequiredFieldsCounter filled={2} total={5} />
389
+
390
+ // Formulário completo
391
+ <RequiredFieldsCounter filled={5} total={5} />
392
+ ```
393
+
394
+ **Props:**
395
+ | Prop | Tipo | Padrão | Descrição |
396
+ |------|------|--------|-----------|
397
+ | `filled` | `number` | - | Quantidade de campos obrigatórios preenchidos |
398
+ | `total` | `number` | - | Total de campos obrigatórios no formulário |
399
+
400
+ **Exemplos:**
401
+ ```tsx
402
+ <RequiredFieldsCounter filled={2} total={5} />
403
+ ```
404
+ ```tsx
405
+ <RequiredFieldsCounter filled={5} total={5} />
406
+ ```
407
+
408
+ **Acessibilidade:**
409
+ - Usa Tooltip para fornecer informações adicionais sobre campos faltantes
410
+ - Cores semânticas (success para completo, muted para incompleto) auxiliam na identificação visual
411
+ - Animação sutil no ícone de check fornece feedback de conclusão
412
+ - Texto sempre visível, não depende apenas de cor para transmitir informação
413
+
414
+ **Notas:**
415
+ - O componente usa a animação
416
+ - definida no tailwind.config.ts
417
+ - Importar de
418
+ - ou diretamente de
419
+ - ,
420
+
421
+
422
+ > Fonte: `src\design-system\docs\components\RequiredFieldsCounterDoc.tsx`
423
+
424
+ ---