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.
- package/README.md +187 -917
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/dist/types/sidebar.d.ts +2 -1
- package/docs/AUDIT_PROMPT.md +74 -0
- package/docs/PROJECT_KNOWLEDGE_TEMPLATE.md +117 -0
- package/docs/PROMPT_TEMPLATE.md +77 -0
- package/docs/STARTER_TEMPLATE.md +114 -0
- package/docs/design-system/README.md +45 -0
- package/docs/design-system/buttons-actions.md +427 -0
- package/docs/design-system/charts-dashboards.md +547 -0
- package/docs/design-system/crud.md +243 -0
- package/docs/design-system/data-display.md +360 -0
- package/docs/design-system/dialogs.md +588 -0
- package/docs/design-system/domain.md +651 -0
- package/docs/design-system/examples.md +275 -0
- package/docs/design-system/foundation.md +82 -0
- package/docs/design-system/infra-utils.md +36 -0
- package/docs/design-system/inputs.md +536 -0
- package/docs/design-system/layout.md +351 -0
- package/docs/design-system/navigation.md +599 -0
- package/docs/design-system/notifications-feedback.md +137 -0
- package/docs/design-system/platform.md +95 -0
- package/docs/design-system/selectors.md +424 -0
- package/docs/design-system/tables-grids.md +114 -0
- package/package.json +2 -2
|
@@ -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
|
+
---
|