@xjur-ui/react 3.1.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +1472 -3
  2. package/dist/components/controls/pin-input/index.d.ts +4 -0
  3. package/dist/components/controls/pin-input/index.js +1 -0
  4. package/dist/components/controls/pin-input/pin-input-caption.d.ts +2 -0
  5. package/dist/components/controls/pin-input/pin-input-caption.js +1 -0
  6. package/dist/components/controls/pin-input/pin-input-control.d.ts +6 -0
  7. package/dist/components/controls/pin-input/pin-input-control.js +1 -0
  8. package/dist/components/controls/pin-input/pin-input-root.d.ts +29 -0
  9. package/dist/components/controls/pin-input/pin-input-root.js +1 -0
  10. package/dist/components/controls/pin-input/pin-input-trigger.d.ts +2 -0
  11. package/dist/components/controls/pin-input/pin-input-trigger.js +1 -0
  12. package/dist/components/message/index.d.ts +5 -0
  13. package/dist/components/message/index.js +1 -0
  14. package/dist/components/message/message-action.d.ts +3 -0
  15. package/dist/components/message/message-action.js +1 -0
  16. package/dist/components/message/message-close.d.ts +4 -0
  17. package/dist/components/message/message-close.js +1 -0
  18. package/dist/components/message/message-icon.d.ts +1 -0
  19. package/dist/components/message/message-icon.js +1 -0
  20. package/dist/components/message/message-root.d.ts +15 -0
  21. package/dist/components/message/message-root.js +1 -0
  22. package/dist/components/message/message-text.d.ts +3 -0
  23. package/dist/components/message/message-text.js +1 -0
  24. package/dist/components/selection-bar/index.d.ts +5 -58
  25. package/dist/components/selection-bar/index.js +1 -1
  26. package/dist/components/selection-bar/selection-bar-action-group.d.ts +2 -0
  27. package/dist/components/selection-bar/selection-bar-action-group.js +1 -0
  28. package/dist/components/selection-bar/selection-bar-action.d.ts +3 -0
  29. package/dist/components/selection-bar/selection-bar-action.js +1 -0
  30. package/dist/components/selection-bar/selection-bar-close.d.ts +3 -0
  31. package/dist/components/selection-bar/selection-bar-close.js +1 -0
  32. package/dist/components/selection-bar/selection-bar-root.d.ts +12 -0
  33. package/dist/components/selection-bar/selection-bar-root.js +1 -0
  34. package/dist/components/selection-bar/selection-bar-title.d.ts +4 -0
  35. package/dist/components/selection-bar/selection-bar-title.js +1 -0
  36. package/dist/components/toast/index.d.ts +1 -24
  37. package/dist/components/toast/index.js +1 -1
  38. package/dist/components/toast/toast-component.d.ts +10 -0
  39. package/dist/components/toast/toast-component.js +1 -0
  40. package/dist/components/toast/toast.d.ts +25 -0
  41. package/dist/components/toast/toast.js +1 -0
  42. package/dist/components/toast/toast.types.d.ts +6 -0
  43. package/dist/components/toast/toast.types.js +0 -0
  44. package/dist/index.css +1 -1
  45. package/package.json +8 -6
  46. package/dist/components/controls/otp-input.d.ts +0 -20
  47. package/dist/components/controls/otp-input.js +0 -1
package/CHANGELOG.md CHANGED
@@ -1,16 +1,1485 @@
1
1
  # @xjur-ui/react
2
2
 
3
- ## 3.1.2
3
+ ## 4.0.0
4
4
 
5
- ### Patch Changes
5
+ ### Major Changes
6
+
7
+ - 07e5bf1: # Migração de OTPInput para PinInput + Novo Componente Message
8
+
9
+ Esta release inclui duas mudanças importantes:
10
+ 1. **BREAKING CHANGE**: Migração do componente OTPInput para PinInput com arquitetura composicional
11
+ 2. **NEW FEATURE**: Adição do componente Message para feedback e notificações
12
+
13
+ ***
14
+
15
+ ## 1. Migração de OTPInput para PinInput com arquitetura composicional
16
+
17
+ ## Breaking Changes
18
+
19
+ **BREAKING CHANGE**: O componente `OTPInput` foi completamente substituído pelo novo componente `PinInput` com arquitetura composicional moderna.
20
+
21
+ ### Migração Necessária
22
+
23
+ #### Antes (OTPInput - Depreciado)
24
+
25
+ ```tsx
26
+ import {
27
+ OTPInputRoot,
28
+ OTPInputTrigger,
29
+ OTPInputInput,
30
+ OTPInputCaption,
31
+ OTPInputHiddenInput
32
+ } from '@xjur-ui/react/otp-input'
33
+
34
+ ;<OTPInputRoot state="normal" length={4} initial="1234">
35
+ <OTPInputTrigger>
36
+ <OTPInputInput index={0} />
37
+ <OTPInputInput index={1} />
38
+ <OTPInputInput index={2} />
39
+ <OTPInputInput index={3} />
40
+ </OTPInputTrigger>
41
+ <OTPInputCaption>Digite o código</OTPInputCaption>
42
+ <OTPInputHiddenInput name="code" />
43
+ </OTPInputRoot>
44
+ ```
45
+
46
+ #### Depois (PinInput - Novo)
47
+
48
+ ```tsx
49
+ import {
50
+ PinInput,
51
+ PinInputControl,
52
+ PinInputTrigger,
53
+ PinInputCaption
54
+ } from '@xjur-ui/react/pin-input'
55
+
56
+ ;<PinInput state="normal" length={4} defaultValue="1234" name="code">
57
+ <PinInputTrigger>
58
+ <PinInputControl index={0} />
59
+ <PinInputControl index={1} />
60
+ <PinInputControl index={2} />
61
+ <PinInputControl index={3} />
62
+ </PinInputTrigger>
63
+ <PinInputCaption>Digite o código</PinInputCaption>
64
+ </PinInput>
65
+ ```
66
+
67
+ ### Principais Mudanças na API
68
+
69
+ | OTPInput (Antigo) | PinInput (Novo) | Notas |
70
+ | --------------------- | ---------------------------------------- | ------------------------------------------ |
71
+ | `OTPInputRoot` | `PinInput` | Renomeado para seguir padrão composicional |
72
+ | `OTPInputInput` | `PinInputControl` | Nome mais descritivo |
73
+ | `initial` prop | `defaultValue` prop | API mais consistente com React |
74
+ | `OTPInputHiddenInput` | Campo automático via prop `name` | Simplificado |
75
+ | Sem callbacks | `onChangeValue`, `onComplete`, `onError` | Maior controle |
76
+ | Sem auto-submit | `autoSubmit` prop | Nova funcionalidade |
77
+ | Sem placeholder | `placeholder` prop | Melhoria UX |
78
+
79
+ ## Novas Funcionalidades
80
+
81
+ ### 1. Auto-Submit de Formulários
82
+
83
+ ```tsx
84
+ <PinInput autoSubmit={true} name="code" onError={handleError}>
85
+ {/* Submete automaticamente quando completo */}
86
+ </PinInput>
87
+ ```
88
+
89
+ ### 2. Placeholder Posicional
90
+
91
+ ```tsx
92
+ <PinInput placeholder="0000">{/* Mostra "0" em cada campo vazio */}</PinInput>
93
+ ```
94
+
95
+ ### 3. Callbacks Detalhados
96
+
97
+ ```tsx
98
+ <PinInput
99
+ onChangeValue={(value) => console.log('Valor:', value)}
100
+ onComplete={(value) => console.log('Completo:', value)}
101
+ onError={(error) => console.error('Erro:', error)}
102
+ >
103
+ ```
104
+
105
+ ### 4. Hidden Input Automático
106
+
107
+ ```tsx
108
+ <PinInput name="verification_code">
109
+ {/* Cria automaticamente <input type="hidden" name="verification_code" /> */}
110
+ </PinInput>
111
+ ```
112
+
113
+ ### 5. Colagem Inteligente de Código
114
+ - Detecta quando usuário cola código completo
115
+ - Distribui automaticamente pelos campos
116
+ - Valida todos os caracteres contra padrão regex
117
+
118
+ ### 6. Validação Customizada por Campo
119
+
120
+ ```tsx
121
+ <PinInputControl pattern="[A-Z0-9]" inputMode="text" />
122
+ ```
123
+
124
+ ## Melhorias de Performance
125
+ - **Context memoizado**: Reduz re-renders desnecessários
126
+ - **Callbacks estáveis**: `useCallback` para `setCodeAt` e `registerInput`
127
+ - **Refs otimizadas**: Mantém referências sem causar re-renders
128
+ - **Validação lazy**: Regex compilado apenas quando necessário
129
+
130
+ ## Melhorias de Acessibilidade
131
+ - `autoComplete="one-time-code"`: Melhor experiência em dispositivos móveis
132
+ - `inputMode="numeric"`: Exibe teclado numérico automaticamente
133
+ - Navegação por teclado completa (setas, backspace, tab)
134
+ - Estados visuais claros (normal, error, disabled)
135
+ - Suporte completo a leitores de tela
136
+
137
+ ## Melhorias de DX (Developer Experience)
138
+ - **TypeScript completo**: Tipos exportados e documentados
139
+ - **Hook de contexto**: `usePinInputContext()` para componentes customizados
140
+ - **Documentação**: README.md detalhado com exemplos práticos
141
+ - **Stories**: 9 exemplos no Storybook cobrindo todos os casos de uso
142
+ - **Tratamento de erros**: Callback `onError` para debugging
143
+
144
+ ## Arquivos Criados
145
+ - `packages/react/src/components/controls/pin-input/pin-input-root.tsx`
146
+ - `packages/react/src/components/controls/pin-input/pin-input-control.tsx`
147
+ - `packages/react/src/components/controls/pin-input/pin-input-trigger.tsx`
148
+ - `packages/react/src/components/controls/pin-input/pin-input-caption.tsx`
149
+ - `packages/react/src/components/controls/pin-input/index.ts`
150
+ - `packages/react/src/components/controls/pin-input/README.md`
151
+
152
+ ## Arquivos Removidos
153
+ - `packages/react/src/components/controls/otp-input.tsx`
154
+ - `apps/docs/src/components/otp-input.stories.tsx`
155
+
156
+ ## Arquivos Criados/Atualizados (Documentação)
157
+ - `apps/docs/src/components/pin-input.stories.tsx` - 9 stories interativas:
158
+ - **Playground**: Exemplo básico com controles interativos
159
+ - **SixDigits**: OTP de 6 dígitos
160
+ - **Error**: Estado de erro com validação
161
+ - **Disabled**: Estado desabilitado
162
+ - **AutoSubmit**: Submissão automática de formulário
163
+ - **WithDefaultValue**: Valor inicial pré-preenchido
164
+ - **Alphanumeric**: Validação customizada alfanumérica
165
+ - **WithMonitoring**: Monitoramento em tempo real
166
+ - **TwoFactorAuth**: Fluxo completo de autenticação 2FA
167
+
168
+ ## Casos de Uso Suportados
169
+ 1. ✅ Verificação de Email/SMS (OTP de 6 dígitos)
170
+ 2. ✅ Autenticação de Dois Fatores (2FA)
171
+ 3. ✅ PIN de Segurança (4 dígitos)
172
+ 4. ✅ Código de Ativação (alfanumérico)
173
+ 5. ✅ Verificação de Pagamento
174
+ 6. ✅ Reset de Senha
175
+ 7. ✅ Confirmação de Transação
176
+
177
+ ## Guia de Migração Detalhado
178
+
179
+ ### Passo 1: Atualizar Imports
180
+
181
+ ```diff
182
+ - import { OTPInputRoot, OTPInputTrigger, OTPInputInput, OTPInputCaption } from '@xjur-ui/react/otp-input'
183
+ + import { PinInput, PinInputTrigger, PinInputControl, PinInputCaption } from '@xjur-ui/react/pin-input'
184
+ ```
185
+
186
+ ### Passo 2: Renomear Componentes
187
+
188
+ ```diff
189
+ - <OTPInputRoot state="normal" length={4} initial="1234">
190
+ + <PinInput state="normal" length={4} defaultValue="1234" name="code">
191
+ <OTPInputTrigger>
192
+ - <OTPInputInput index={0} />
193
+ + <PinInputControl index={0} />
194
+ </OTPInputTrigger>
195
+ - <OTPInputHiddenInput name="code" />
196
+ </PinInput>
197
+ ```
198
+
199
+ ### Passo 3: Adicionar Callbacks (Opcional)
200
+
201
+ ```tsx
202
+ <PinInput
203
+ onComplete={(code) => {
204
+ // Código completo digitado
205
+ verifyCode(code)
206
+ }}
207
+ onChangeValue={(value) => {
208
+ // Cada alteração
209
+ console.log('Valor:', value)
210
+ }}
211
+ >
212
+ ```
213
+
214
+ ### Passo 4: Habilitar Auto-Submit (Opcional)
215
+
216
+ ```tsx
217
+ <form onSubmit={handleSubmit}>
218
+ <PinInput autoSubmit={true} name="code">
219
+ {/* Submete automaticamente ao completar */}
220
+ </PinInput>
221
+ </form>
222
+ ```
223
+
224
+ ## Compatibilidade
225
+ - ✅ React 19.1.1+
226
+ - ✅ TypeScript 5.x
227
+ - ✅ Tailwind CSS 4.x
228
+ - ✅ Navegadores modernos (Chrome, Firefox, Safari, Edge)
229
+ - ✅ Dispositivos móveis (iOS Safari, Chrome Mobile)
230
+
231
+ ## Próximos Passos
232
+
233
+ Após esta atualização, recomendamos:
234
+ 1. **Testar fluxos de autenticação**: Verifique todos os fluxos que usavam OTPInput
235
+ 2. **Revisar validações**: Configure validações customizadas se necessário
236
+ 3. **Implementar auto-submit**: Aproveite a nova funcionalidade para melhor UX
237
+ 4. **Adicionar tratamento de erros**: Use o callback `onError` para debugging
238
+
239
+ ## Suporte
240
+
241
+ Para dúvidas ou problemas com a migração, consulte:
242
+ - 📖 README.md completo em `packages/react/src/components/controls/pin-input/README.md`
243
+ - 📚 9 exemplos interativos no Storybook
244
+ - 🔍 TypeScript types para autocomplete e documentação inline
245
+
246
+ ***
247
+
248
+ ## 2. Novo Componente Message
249
+
250
+ ### Visão Geral
251
+
252
+ O **Message** é um novo componente composicional para exibir mensagens e notificações contextuais aos usuários. Perfeito para feedbacks de ações, alertas, avisos e mensagens de sucesso.
253
+
254
+ ### Características Principais
255
+
256
+ #### Arquitetura Composicional
257
+ - **MessageRoot**: Container principal com controle de variante e modo de exibição
258
+ - **MessageIcon**: Ícone automático baseado na variante (success, neutral, warning, error)
259
+ - **MessageText**: Componente de texto com truncate automático
260
+ - **MessageClose**: Botão de fechamento que remove o elemento do DOM
261
+
262
+ #### Variantes Visuais
263
+
264
+ | Variante | Ícone | Cor | Uso |
265
+ | -------- | ------- | -------- | ----------------------------------- |
266
+ | success | check | Verde | Confirmações de ações bem-sucedidas |
267
+ | neutral | info | Cinza | Informações gerais |
268
+ | warning | warning | Amarelo | Avisos que requerem atenção |
269
+ | error | error | Vermelho | Erros e problemas críticos |
270
+
271
+ #### Modos de Apresentação
272
+
273
+ **Full-Width (Padrão)**
274
+ - Largura total do container
275
+ - Ícone visível à esquerda
276
+ - Borda colorida de 4px à esquerda
277
+ - Padding generoso
278
+ - Ideal para mensagens de sistema
279
+
280
+ **Inline (Compacto)**
281
+ - Largura ajustada ao conteúdo (w-fit)
282
+ - Sem ícone
283
+ - Sem borda lateral
284
+ - Padding compacto
285
+ - Ideal para mensagens próximas a campos
286
+
287
+ ### API do Componente
288
+
289
+ #### MessageRoot Props
290
+
291
+ ```tsx
292
+ interface MessageRootProps {
293
+ variant?: 'success' | 'neutral' | 'warning' | 'error' // Padrão: 'neutral'
294
+ inline?: boolean // Padrão: false
295
+ children: React.ReactNode
296
+ // + todas as props de HTMLDivElement
297
+ }
298
+ ```
299
+
300
+ #### MessageIcon
301
+ - Renderiza automaticamente o ícone apropriado
302
+ - Não é exibido quando `inline={true}`
303
+ - Sem props customizáveis
304
+
305
+ #### MessageText
306
+ - Wrapper do Typography com truncate automático
307
+ - Aceita todas as props do Typography
308
+ - Herda cor do contexto da mensagem
309
+
310
+ #### MessageClose
311
+ - Botão que remove a mensagem do DOM
312
+ - Renderiza ícone "close" por padrão
313
+ - Aceita children customizados
314
+ - Aceita todas as props de `<button>`
315
+
316
+ ### Exemplos de Uso
317
+
318
+ #### Mensagem de Sucesso
319
+
320
+ ```tsx
321
+ import {
322
+ MessageRoot,
323
+ MessageIcon,
324
+ MessageText,
325
+ MessageClose
326
+ } from '@xjur-ui/react/message'
327
+
328
+ ;<MessageRoot variant="success">
329
+ <MessageIcon />
330
+ <MessageText>Documento salvo com sucesso!</MessageText>
331
+ <MessageClose />
332
+ </MessageRoot>
333
+ ```
334
+
335
+ #### Mensagem de Erro em Formulário
336
+
337
+ ```tsx
338
+ <MessageRoot variant="error">
339
+ <MessageIcon />
340
+ <MessageText>Por favor, preencha todos os campos obrigatórios.</MessageText>
341
+ </MessageRoot>
342
+ ```
343
+
344
+ #### Aviso Importante
345
+
346
+ ```tsx
347
+ <MessageRoot variant="warning">
348
+ <MessageIcon />
349
+ <MessageText>Esta ação não pode ser desfeita.</MessageText>
350
+ </MessageRoot>
351
+ ```
352
+
353
+ #### Mensagem Inline
354
+
355
+ ```tsx
356
+ <MessageRoot variant="neutral" inline>
357
+ <MessageText>Informação adicional</MessageText>
358
+ </MessageRoot>
359
+ ```
360
+
361
+ ### Funcionalidades
362
+
363
+ #### 1. Animação de Entrada
364
+ - Fade-in suave (250ms) para não assustar usuários
365
+ - Classes: `animate-in fade-in-0 duration-250`
366
+
367
+ #### 2. Fechamento Inteligente
368
+ - Remove o elemento do DOM ao clicar no botão de fechar
369
+ - Utiliza `ref.current?.remove()` para limpeza completa
370
+ - Callback `onClose` disponível via contexto
371
+
372
+ #### 3. Context API
373
+
374
+ ```tsx
375
+ interface MessageRootContextValue {
376
+ variant: MessageRootVariant
377
+ inline: boolean
378
+ onClose?: () => void
379
+ }
380
+
381
+ // Hook para componentes customizados
382
+ const { variant, inline, onClose } = useMessageRootContext()
383
+ ```
384
+
385
+ #### 4. Mapeamento Automático de Ícones
386
+
387
+ ```tsx
388
+ const iconMap = new Map<MessageRootVariant, React.ReactNode>([
389
+ ['success', <Icon name="check" className="text-success-idle" />],
390
+ ['neutral', <Icon name="info" className="text-icon-neutral-3" />],
391
+ ['warning', <Icon name="warning" className="text-warning-idle" />],
392
+ ['error', <Icon name="error" className="text-danger-idle" />]
393
+ ])
394
+ ```
395
+
396
+ ### Acessibilidade
397
+ - ✅ Botão de fechamento com `type="button"` para evitar submissão acidental
398
+ - ✅ Estados visuais claros com cores contrastantes
399
+ - ✅ Animação suave de entrada
400
+ - ✅ Remoção do DOM ao fechar para limpar árvore de acessibilidade
401
+ - ✅ Texto com truncate para evitar quebras visuais
402
+ - ✅ Suporte completo a leitores de tela
403
+
404
+ ### Performance
405
+ - **Context memoizado**: Reduz re-renders desnecessários
406
+ - **Callback estável**: `handleClose` com `useCallback`
407
+ - **Ícones pré-compilados**: Map de ícones criado uma única vez
408
+ - **Composição modular**: Componentes pequenos e focados
409
+
410
+ ### Documentação no Storybook
411
+
412
+ 10 stories interativas demonstrando todos os casos de uso:
413
+ 1. **Playground**: Exemplo interativo com controles
414
+ 2. **Success**: Mensagem de sucesso
415
+ 3. **Neutral**: Mensagem neutra/informativa
416
+ 4. **Warning**: Mensagem de aviso
417
+ 5. **Error**: Mensagem de erro
418
+ 6. **InlineSuccess**: Versão compacta de sucesso
419
+ 7. **InlineError**: Versão compacta de erro
420
+ 8. **WithoutClose**: Mensagem persistente sem botão fechar
421
+ 9. **LongText**: Demonstração com texto longo
422
+ 10. **MultipleMessages**: Showcase de todas as variantes
423
+
424
+ ### Casos de Uso Suportados
425
+ 1. ✅ Feedback de ações (salvar, deletar, enviar)
426
+ 2. ✅ Validação de formulários
427
+ 3. ✅ Avisos importantes
428
+ 4. ✅ Mensagens de erro
429
+ 5. ✅ Notificações de sistema
430
+ 6. ✅ Confirmações de operações
431
+ 7. ✅ Informações contextuais inline
432
+ 8. ✅ Alertas temporários
433
+ 9. ✅ Status de operações assíncronas
434
+ 10. ✅ Mensagens de onboarding
435
+
436
+ ### Arquivos Criados
437
+ - `packages/react/src/components/message/index.ts`
438
+ - `packages/react/src/components/message/message-root.tsx`
439
+ - `packages/react/src/components/message/message-icon.tsx`
440
+ - `packages/react/src/components/message/message-text.tsx`
441
+ - `packages/react/src/components/message/message-close.tsx`
442
+ - `apps/docs/src/components/message.stories.tsx`
443
+
444
+ ### Integração com Design System
445
+
446
+ O componente Message utiliza:
447
+ - **Design tokens** do @xjur-ui/styles para cores e espaçamentos
448
+ - **Sistema de ícones** via componente Icon
449
+ - **Typography** para texto consistente
450
+ - **TailwindCSS 4.x** para estilização
451
+ - **Tailwind Variants** (tv) para variantes CSS
452
+
453
+ ### TypeScript
454
+
455
+ Tipagem completa exportada:
456
+
457
+ ```tsx
458
+ export type MessageRootVariant = 'success' | 'neutral' | 'warning' | 'error'
459
+
460
+ export interface MessageRootProps extends ComponentProps<'div'> {
461
+ variant?: MessageRootVariant
462
+ inline?: boolean
463
+ children: React.ReactNode
464
+ }
465
+
466
+ export function useMessageRootContext(): MessageRootContextValue
467
+ ```
468
+
469
+ ### Compatibilidade
470
+ - ✅ React 19.1.1+
471
+ - ✅ TypeScript 5.x
472
+ - ✅ Tailwind CSS 4.x
473
+ - ✅ Navegadores modernos (Chrome, Firefox, Safari, Edge)
474
+ - ✅ Dispositivos móveis (iOS Safari, Chrome Mobile)
475
+
476
+ ### Roadmap Futuro
477
+
478
+ Possíveis melhorias para próximas versões:
479
+ - Auto-dismiss com timeout configurável
480
+ - Posicionamento fixo (toast-style)
481
+ - Animações de saída customizáveis
482
+ - Suporte a ações customizadas (além de close)
483
+ - Progress bar para mensagens temporárias
484
+ - Queue de mensagens
485
+ - Suporte a rich content (links, imagens)
486
+
487
+ ***
488
+
489
+ ## 3. Novo Componente Toast (toast-v2)
490
+
491
+ ### Visão Geral
492
+
493
+ O **Toast** é um sistema completo de notificações temporárias não intrusivas, construído sobre a biblioteca Sonner e o componente Message. Oferece uma API imperativa simples e poderosa para exibir notificações toast com posicionamento, ações e callbacks.
494
+
495
+ ### Características Principais
496
+
497
+ #### Baseado em Sonner
498
+ - **Library moderna e performática**: Sonner é a biblioteca toast mais popular e otimizada do ecossistema React
499
+ - **Empilhamento inteligente**: Gerenciamento automático de múltiplos toasts
500
+ - **Animações suaves**: CSS transforms otimizadas
501
+ - **Mobile-friendly**: Suporte a swipe gestures
502
+ - **Acessibilidade integrada**: ARIA live regions automáticas
503
+
504
+ #### Integração com Message
505
+ - Reutiliza componente Message para consistência visual
506
+ - Usa MessageIcon, MessageText, MessageAction e MessageClose
507
+ - Design tokens compartilhados
508
+ - Mesmos padrões de acessibilidade
509
+
510
+ #### Arquitetura
511
+ - **ToastWrapper**: Provider global baseado no Toaster do Sonner
512
+ - **toast()**: Função imperativa para disparar toasts
513
+ - **ToastComponent**: Componente interno que renderiza usando Message
6
514
 
7
- - 338d246: feat: ajuste no componente de otp input para receber borda de erro
515
+ ### API do Componente
516
+
517
+ O objeto `toast` expõe 3 métodos principais:
518
+
519
+ #### 1. toast.dispatch(message, options)
520
+
521
+ Dispara um novo toast e retorna o ID do toast criado.
522
+
523
+ ```tsx
524
+ function toast.dispatch(message: string, options?: {
525
+ variant?: 'primary' | 'destructive'
526
+ dismissible?: boolean
527
+ action?: { label: string; onClick: () => void }
528
+ position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'
529
+ inline?: boolean
530
+ duration?: number // ms, default: 3000
531
+ toasterId?: string
532
+ onAutoClose?: (toast) => void
533
+ onDismiss?: (toast) => void
534
+ }): string // Retorna o ID do toast
535
+ ```
536
+
537
+ #### 2. toast.dismiss(toastId)
538
+
539
+ Fecha um toast específico pelo ID.
540
+
541
+ ```tsx
542
+ function toast.dismiss(toastId: string): void
543
+ ```
544
+
545
+ **Exemplo**:
546
+
547
+ ```tsx
548
+ const toastId = toast.dispatch('Processando...')
549
+ // Mais tarde...
550
+ toast.dismiss(toastId)
551
+ ```
552
+
553
+ #### 3. toast.clear()
554
+
555
+ Fecha todos os toasts ativos.
556
+
557
+ ```tsx
558
+ function toast.clear(): void
559
+ ```
560
+
561
+ **Exemplo**:
562
+
563
+ ```tsx
564
+ // Fechar todos os toasts ao navegar para outra página
565
+ toast.clear()
566
+ ```
567
+
568
+ #### Opções Disponíveis
569
+
570
+ | Opção | Tipo | Padrão | Descrição |
571
+ | ----------- | ---------------------------------------- | -------------- | --------------------------------------------- | ----------------------------------------- | --------------- |
572
+ | variant | `'primary' | 'destructive'` | `'primary'` | Estilo visual (mapeia para success/error) |
573
+ | dismissible | `boolean` | `true` | Se pode ser fechado manualmente |
574
+ | action | `{ label: string; onClick: () => void }` | `undefined` | Botão de ação adicional |
575
+ | position | `'top-right' | 'top-left' | ...` | `undefined` | Posição na tela |
576
+ | inline | `boolean` | `false` | Modo compacto |
577
+ | duration | `number` | `3000` | Duração em ms (Infinity se dismissible=false) |
578
+ | toasterId | `string` | `undefined` | ID do toaster específico |
579
+ | onAutoClose | `(toast) => void` | `undefined` | Callback ao fechar automaticamente |
580
+ | onDismiss | `(toast) => void` | `undefined` | Callback ao fechar |
581
+
582
+ ### Variantes
583
+
584
+ | Variante | Mapeia para Message | Visual | Uso |
585
+ | ----------- | ------------------- | ------------------------ | -------------------------------- |
586
+ | primary | success | Verde com ícone check | Confirmações e sucessos (padrão) |
587
+ | destructive | error | Vermelho com ícone error | Erros e ações destrutivas |
588
+
589
+ **Nota**: Para variantes `neutral` e `warning`, use o componente Message diretamente com posicionamento fixo.
590
+
591
+ ### Posições Disponíveis
592
+ - **top-right**: Canto superior direito
593
+ - **top-left**: Canto superior esquerdo
594
+ - **bottom-right**: Canto inferior direito (padrão Sonner)
595
+ - **bottom-left**: Canto inferior esquerdo
596
+
597
+ ### Exemplos de Uso
598
+
599
+ #### Setup Inicial
600
+
601
+ ```tsx
602
+ import { ToastWrapper } from '@xjur-ui/react/toast-v2'
603
+
604
+ function App() {
605
+ return (
606
+ <>
607
+ <ToastWrapper />
608
+ {/* Resto da aplicação */}
609
+ </>
610
+ )
611
+ }
612
+ ```
613
+
614
+ #### Toast Simples
615
+
616
+ ```tsx
617
+ import { toast } from '@xjur-ui/react/toast'
618
+
619
+ // Sucesso
620
+ toast.dispatch('Documento salvo com sucesso!')
621
+
622
+ // Erro
623
+ toast.dispatch('Erro ao processar solicitação', {
624
+ variant: 'destructive'
625
+ })
626
+ ```
627
+
628
+ #### Toast com Ação
629
+
630
+ ```tsx
631
+ toast.dispatch('Email enviado com sucesso', {
632
+ action: {
633
+ label: 'Desfazer',
634
+ onClick: () => undoSendEmail()
635
+ }
636
+ })
637
+ ```
638
+
639
+ #### Toast Persistente com Dismiss
640
+
641
+ ```tsx
642
+ const toastId = toast.dispatch('Processando... Por favor aguarde', {
643
+ dismissible: false,
644
+ duration: Infinity
645
+ })
646
+
647
+ // Depois de completar a tarefa
648
+ setTimeout(() => {
649
+ toast.dismiss(toastId)
650
+ toast.dispatch('Concluído!', { variant: 'primary' })
651
+ }, 3000)
652
+ ```
653
+
654
+ #### Fechar Todos os Toasts
655
+
656
+ ```tsx
657
+ // Disparar múltiplos toasts
658
+ toast.dispatch('Primeira notificação')
659
+ toast.dispatch('Segunda notificação')
660
+ toast.dispatch('Terceira notificação')
661
+
662
+ // Fechar todos de uma vez
663
+ toast.clear()
664
+ ```
665
+
666
+ #### Toast com Posição e Duração
667
+
668
+ ```tsx
669
+ toast.dispatch('Notificação importante', {
670
+ position: 'top-right',
671
+ duration: 5000 // 5 segundos
672
+ })
673
+ ```
674
+
675
+ #### Toast com Callbacks
676
+
677
+ ```tsx
678
+ toast.dispatch('Upload iniciado', {
679
+ onAutoClose: t => {
680
+ console.log('Toast auto-fechado:', t)
681
+ logAnalytics('toast_auto_close')
682
+ },
683
+ onDismiss: t => {
684
+ console.log('Toast fechado:', t)
685
+ }
686
+ })
687
+ ```
688
+
689
+ ### Funcionalidades
690
+
691
+ #### 1. Empilhamento Automático
692
+ - Sonner gerencia automaticamente a queue de toasts
693
+ - Toasts são empilhados verticalmente
694
+ - Animações coordenadas ao adicionar/remover
695
+
696
+ #### 2. Swipe to Dismiss (Mobile)
697
+ - Gestos de swipe para fechar em mobile
698
+ - Feedback visual durante o swipe
699
+ - Configuração automática pelo Sonner
700
+
701
+ #### 3. Auto-dismiss Inteligente
702
+ - Duração padrão de 3 segundos
703
+ - Ajuste automático para Infinity se `dismissible=false`
704
+ - Pause no hover (comportamento Sonner)
705
+
706
+ #### 4. Callbacks de Lifecycle
707
+ - `onAutoClose`: Chamado quando fecha automaticamente
708
+ - `onDismiss`: Chamado em qualquer tipo de fechamento
709
+ - Recebe objeto toast com ID e metadata
710
+
711
+ #### 5. Múltiplos Toasters
712
+ - Suporte a múltiplos toasters com IDs diferentes
713
+ - Útil para diferentes áreas da aplicação
714
+ - Configuração via `toasterId`
715
+
716
+ #### 6. Gerenciamento de Ciclo de Vida
717
+ - **Disparar**: `toast.dispatch()` retorna o ID do toast
718
+ - **Fechar específico**: `toast.dismiss(id)` fecha um toast pelo ID
719
+ - **Fechar todos**: `toast.clear()` limpa todos os toasts ativos
720
+ - Permite padrões avançados:
721
+ - Substituir toast de loading por sucesso
722
+ - Limpar notificações ao mudar de página
723
+ - Gerenciar toasts relacionados
724
+
725
+ ### Integração com Message
726
+
727
+ O Toast reutiliza completamente o componente Message:
728
+
729
+ ```tsx
730
+ // toast-component.tsx
731
+ export function ToastComponent({
732
+ variant = 'primary',
733
+ inline = false,
734
+ dismissible = true,
735
+ message,
736
+ action,
737
+ onDismiss
738
+ }: ToastComponentProps) {
739
+ return (
740
+ <MessageRoot inline={inline} variant={variant}>
741
+ <MessageIcon />
742
+ <MessageText>{message}</MessageText>
743
+
744
+ {action && (
745
+ <MessageAction variant={variant} onClick={action.onClick}>
746
+ {action.label}
747
+ </MessageAction>
748
+ )}
749
+
750
+ {dismissible && <MessageClose onClick={onDismiss} />}
751
+ </MessageRoot>
752
+ )
753
+ }
754
+ ```
755
+
756
+ Isso garante:
757
+ - ✅ Consistência visual total
758
+ - ✅ Mesmos design tokens
759
+ - ✅ Manutenção centralizada
760
+ - ✅ Reutilização de código
761
+
762
+ ### Acessibilidade
763
+ - ✅ **ARIA live regions**: Sonner cria automaticamente
764
+ - ✅ **Screen readers**: Anúncios automáticos de toasts
765
+ - ✅ **Navegação por teclado**: Tab, Enter, Escape
766
+ - ✅ **Focus management**: Foco adequado em ações
767
+ - ✅ **Swipe gestures**: Mobile acessível
768
+ - ✅ **Prefers-reduced-motion**: Respeita preferências do usuário
769
+ - ✅ **Labels apropriadas**: Botões com texto claro
770
+
771
+ ### Performance
772
+ - ✅ **Renderização otimizada**: Sonner usa virtualização
773
+ - ✅ **Animações com transforms**: GPU-accelerated
774
+ - ✅ **Limpeza automática**: Remove toasts do DOM após fechar
775
+ - ✅ **Memoização**: Context e callbacks memoizados
776
+ - ✅ **Bundle size pequeno**: ~10KB (Sonner) + componentes existentes
777
+
778
+ ### Documentação no Storybook
779
+
780
+ 13 stories interativas cobrindo todos os casos:
781
+ 1. **Playground**: Exemplo básico interativo
782
+ 2. **Primary**: Toast de sucesso
783
+ 3. **Destructive**: Toast de erro
784
+ 4. **WithAction**: Toast com botão de ação
785
+ 5. **NotDismissible**: Toast persistente
786
+ 6. **CustomDuration**: Durações customizadas (1s, 10s)
787
+ 7. **Positions**: Todas as 4 posições
788
+ 8. **InlineMode**: Modo compacto
789
+ 9. **WithCallbacks**: Demonstração de callbacks
790
+ 10. **MultipleToasts**: Empilhamento de 3 toasts
791
+ 11. **DismissSpecific**: Fechar toast específico por ID
792
+ 12. **ClearAll**: Fechar todos os toasts ativos
793
+ 13. **RealWorldExample**: Exemplos CRUD práticos
794
+
795
+ ### Casos de Uso Suportados
796
+ 1. ✅ Confirmações de ações (salvar, deletar, enviar)
797
+ 2. ✅ Notificações de erro
798
+ 3. ✅ Ações com desfazer (undo)
799
+ 4. ✅ Status de upload/download
800
+ 5. ✅ Notificações de sistema
801
+ 6. ✅ Feedback de formulários
802
+ 7. ✅ Operações assíncronas
803
+ 8. ✅ Alertas temporários
804
+ 9. ✅ Confirmações destrutivas
805
+ 10. ✅ Múltiplas notificações simultâneas
806
+
807
+ ### Arquivos Criados/Substituídos
808
+
809
+ **Toast (substituição completa)**:
810
+ - `packages/react/src/components/toast/index.ts`
811
+ - `packages/react/src/components/toast/toast.tsx`
812
+ - `packages/react/src/components/toast/toast-component.tsx`
813
+ - `packages/react/src/components/toast/toast.types.ts`
814
+
815
+ **Message**:
816
+ - `packages/react/src/components/message/message-action.tsx` (novo)
817
+
818
+ **Documentação**:
819
+ - `apps/docs/src/components/toast.stories.tsx` (reescrito completamente)
820
+
821
+ **Observação**: O componente Toast foi completamente reescrito. O código antigo baseado em Radix foi substituído por uma nova implementação baseada em Sonner.
822
+
823
+ ### Dependências
824
+
825
+ Nova dependência adicionada:
826
+
827
+ ```json
828
+ {
829
+ "dependencies": {
830
+ "sonner": "^1.x"
831
+ }
832
+ }
833
+ ```
834
+
835
+ **Sonner**: Library toast moderna, leve e performática
836
+ - Bundle: ~10KB gzipped
837
+ - Zero dependencies além de React
838
+ - Amplamente adotada pela comunidade
839
+ - Manutenção ativa
840
+
841
+ ### Comparação: Toast vs Message
842
+
843
+ | Aspecto | Toast (toast-v2) | Message |
844
+ | ---------------- | ------------------------- | ------------------------- |
845
+ | **Posição** | Fixo na tela (flutuante) | Inline no layout |
846
+ | **Duração** | Temporário (auto-dismiss) | Persistente |
847
+ | **API** | Imperativa (`toast()`) | Declarativa (JSX) |
848
+ | **Uso** | Notificações globais | Feedback contextual |
849
+ | **Empilhamento** | Automático (Sonner queue) | Manual |
850
+ | **Biblioteca** | Sonner + Message | Nativo |
851
+ | **Callbacks** | onAutoClose, onDismiss | onClose via ref |
852
+ | **Posições** | 4 cantos da tela | Onde for renderizado |
853
+ | **Ações** | Suporte via MessageAction | Suporte via MessageAction |
854
+
855
+ ### Boas Práticas
856
+ 1. **Use Toast para feedback não crítico**: Confirmações rápidas, updates de status
857
+ 2. **Use Message para feedback crítico inline**: Erros de formulário, avisos importantes
858
+ 3. **Limite a duração**: 3-5s para leitura confortável
859
+ 4. **Evite spam de toasts**: Não dispare múltiplos toasts em sequência rápida
860
+ 5. **Forneça ações quando relevante**: "Desfazer", "Ver detalhes"
861
+ 6. **Posicione adequadamente**: top-right para notificações, bottom-right para status
862
+ 7. **Teste em mobile**: Verifique swipe gestures
863
+ 8. **Use callbacks para analytics**: Track abertura e fechamento
864
+ 9. **Gerencie o ciclo de vida**: Use `dismiss()` para substituir loading por sucesso
865
+ 10. **Limpe ao navegar**: Use `clear()` ao mudar de página/contexto
866
+ 11. **Armazene IDs quando necessário**: Salve o retorno de `dispatch()` para controle posterior
867
+
868
+ ### Migração do Toast Antigo (Radix)
869
+
870
+ O toast antigo baseado em Radix UI será removido. Migração:
871
+
872
+ #### Antes (Toast Radix - Depreciado)
873
+
874
+ ```tsx
875
+ import {
876
+ ToastProvider,
877
+ ToastComponent,
878
+ ToastViewport
879
+ } from '@xjur-ui/react/toast'
880
+
881
+ ;<ToastProvider>
882
+ <ToastComponent variant="success" description="Salvo!" />
883
+ <ToastViewport />
884
+ </ToastProvider>
885
+ ```
886
+
887
+ #### Depois (Toast Sonner - Novo)
888
+
889
+ ```tsx
890
+ import { ToastWrapper, toast } from '@xjur-ui/react/toast'
891
+
892
+ // No root da app
893
+ ;<ToastWrapper />
894
+
895
+ // Onde precisar
896
+ toast.dispatch('Salvo!', { variant: 'primary' })
897
+
898
+ // Com controle de ciclo de vida
899
+ const toastId = toast.dispatch('Processando...')
900
+ toast.dismiss(toastId) // Fechar específico
901
+ toast.clear() // Fechar todos
902
+ ```
903
+
904
+ ### Compatibilidade
905
+ - ✅ React 19.1.1+
906
+ - ✅ TypeScript 5.x
907
+ - ✅ Tailwind CSS 4.x
908
+ - ✅ Navegadores modernos (Chrome, Firefox, Safari, Edge)
909
+ - ✅ iOS Safari 12+
910
+ - ✅ Chrome Mobile
911
+ - ✅ Suporte SSR/SSG
912
+
913
+ ### Roadmap Futuro
914
+
915
+ Melhorias planejadas:
916
+ - Mais variantes (neutral, warning) mapeando para Message
917
+ - Suporte a rich content (imagens, progress bars)
918
+ - Posições customizadas (não apenas cantos)
919
+ - Temas customizados
920
+ - Agrupamento de toasts relacionados
921
+ - Priorização de toasts
922
+ - Rate limiting automático
923
+
924
+ ***
925
+
926
+ ## 4. Novo Componente SelectionBar (selection-bar-v2)
927
+
928
+ ### Visão Geral
929
+
930
+ O **SelectionBar** é um componente composicional que exibe uma barra de ações flutuante na parte inferior da tela quando itens são selecionados. Renderizado via Portal React, é ideal para operações em lote em listas, tabelas e grids, oferecendo uma experiência moderna e intuitiva.
931
+
932
+ ### Características Principais
933
+
934
+ #### Arquitetura Composicional Moderna
935
+ - **SelectionBarRoot**: Container principal com gerenciamento de estado e portal
936
+ - **SelectionBarTitleRoot**: Container para título e botão de fechar
937
+ - **SelectionBarTitle**: Texto do título (wrapper do Typography)
938
+ - **SelectionBarClose**: Botão para fechar a barra
939
+ - **SelectionBarActionGroup**: Container de ações com suporte a overflow
940
+ - **SelectionBarAction**: Botão de ação (wrapper do Button)
941
+
942
+ #### Portal e Posicionamento Fixo
943
+ - Renderizado via `createPortal` React
944
+ - Alvo: elemento `#selection-bar-root` ou `document.body`
945
+ - Posição: `fixed bottom-[60px]` (acima de barras de navegação)
946
+ - Centralizado horizontalmente: `left-1/2 -translate-x-1/2`
947
+ - Z-index: 1000 (acima de outros elementos)
948
+
949
+ #### Animações e Transições
950
+ - **Entrada**: `slide-in-from-top` (200ms)
951
+ - **Saída**: `slide-out-to-bottom` (200ms)
952
+ - Auto-remoção do DOM após fechamento
953
+ - Estados visuais: `data-state="open|closed"`
954
+
955
+ ### API do Componente
956
+
957
+ #### SelectionBarRoot
958
+
959
+ ```tsx
960
+ interface SelectionBarRootProps {
961
+ open?: boolean // Padrão: true
962
+ onOpenChange?: (open: boolean) => void
963
+ className?: string
964
+ children: React.ReactNode
965
+ // + todas as props de HTMLDivElement
966
+ }
967
+ ```
968
+
969
+ **Context API**:
970
+
971
+ ```tsx
972
+ interface SelectionBarContextValue {
973
+ open: boolean
974
+ onClose: () => void
975
+ }
976
+
977
+ // Hook
978
+ const { open, onClose } = useSelectionBarContext()
979
+ ```
980
+
981
+ #### Outros Componentes
982
+
983
+ | Componente | Base | Props Especiais |
984
+ | ----------------------- | ---------- | ----------------------------- |
985
+ | SelectionBarTitleRoot | div | Container flexbox |
986
+ | SelectionBarTitle | Typography | weight="medium", cor neutra |
987
+ | SelectionBarClose | Button | size="icon_md", ícone close |
988
+ | SelectionBarActionGroup | div | Flexbox com overflow-x-hidden |
989
+ | SelectionBarAction | Button | className="shrink-0" |
990
+
991
+ ### Exemplos de Uso
992
+
993
+ #### Seleção Básica em Tabela
994
+
995
+ ```tsx
996
+ import {
997
+ SelectionBarRoot,
998
+ SelectionBarTitleRoot,
999
+ SelectionBarTitle,
1000
+ SelectionBarClose,
1001
+ SelectionBarActionGroup,
1002
+ SelectionBarAction
1003
+ } from '@xjur-ui/react/selection-bar'
1004
+ import { Icon } from '@xjur-ui/react/icon'
1005
+
1006
+ const [selectedIds, setSelectedIds] = useState<string[]>([])
1007
+
1008
+ {
1009
+ selectedIds.length > 0 && (
1010
+ <SelectionBarRoot>
1011
+ <SelectionBarTitleRoot>
1012
+ <SelectionBarClose />
1013
+ <SelectionBarTitle>
1014
+ {selectedIds.length} selecionados
1015
+ </SelectionBarTitle>
1016
+ </SelectionBarTitleRoot>
1017
+
1018
+ <SelectionBarActionGroup>
1019
+ <SelectionBarAction onClick={handleExport}>
1020
+ <Icon name="download" />
1021
+ Exportar
1022
+ </SelectionBarAction>
1023
+ <SelectionBarAction onClick={handleArchive}>
1024
+ Arquivar
1025
+ </SelectionBarAction>
1026
+ <SelectionBarAction variant="destructive" onClick={handleDelete}>
1027
+ <Icon name="delete" />
1028
+ Excluir
1029
+ </SelectionBarAction>
1030
+ </SelectionBarActionGroup>
1031
+ </SelectionBarRoot>
1032
+ )
1033
+ }
1034
+ ```
1035
+
1036
+ #### Com Controle de Estado
1037
+
1038
+ ```tsx
1039
+ const [open, setOpen] = useState(false)
1040
+ const [selectedItems, setSelectedItems] = useState([])
1041
+
1042
+ <SelectionBarRoot
1043
+ open={open}
1044
+ onOpenChange={(newOpen) => {
1045
+ setOpen(newOpen)
1046
+ if (!newOpen) {
1047
+ // Limpar seleções ao fechar
1048
+ setSelectedItems([])
1049
+ }
1050
+ }}
1051
+ >
1052
+ <SelectionBarTitleRoot>
1053
+ <SelectionBarClose />
1054
+ <SelectionBarTitle>
1055
+ {selectedItems.length} selecionados
1056
+ </SelectionBarTitle>
1057
+ </SelectionBarTitleRoot>
1058
+
1059
+ <SelectionBarActionGroup>
1060
+ <SelectionBarAction>Exportar PDF</SelectionBarAction>
1061
+ <SelectionBarAction>Compartilhar</SelectionBarAction>
1062
+ <SelectionBarAction variant="destructive">
1063
+ <Icon name="delete" />
1064
+ </SelectionBarAction>
1065
+ </SelectionBarActionGroup>
1066
+ </SelectionBarRoot>
1067
+ ```
1068
+
1069
+ #### Operações em Lote
1070
+
1071
+ ```tsx
1072
+ <SelectionBarRoot>
1073
+ <SelectionBarTitleRoot>
1074
+ <SelectionBarClose />
1075
+ <SelectionBarTitle>5 documentos selecionados</SelectionBarTitle>
1076
+ </SelectionBarTitleRoot>
1077
+
1078
+ <SelectionBarActionGroup>
1079
+ <SelectionBarAction>Exportar PDF</SelectionBarAction>
1080
+ <SelectionBarAction>Exportar Excel</SelectionBarAction>
1081
+ <SelectionBarAction>Compartilhar</SelectionBarAction>
1082
+ <SelectionBarAction>Mover para</SelectionBarAction>
1083
+ <SelectionBarAction>Arquivar</SelectionBarAction>
1084
+
1085
+ <SelectionBarAction size="icon_md" variant="destructive">
1086
+ <Icon name="delete" />
1087
+ </SelectionBarAction>
1088
+ </SelectionBarActionGroup>
1089
+ </SelectionBarRoot>
1090
+ ```
1091
+
1092
+ ### Funcionalidades
1093
+
1094
+ #### 1. Portal Rendering
1095
+ - Renderiza fora da hierarquia DOM do componente pai
1096
+ - Evita problemas de z-index e overflow
1097
+ - Permite posicionamento fixo global
1098
+ - Fallback automático para `document.body`
1099
+
1100
+ #### 2. Gerenciamento de Estado
1101
+ - Estado controlado via props `open` e `onOpenChange`
1102
+ - Estado interno quando não controlado
1103
+ - Callback ao fechar para sincronizar com estado externo
1104
+ - Auto-remoção do DOM após animação de saída
1105
+
1106
+ #### 3. Overflow Horizontal
1107
+ - Container de ações com `overflow-x-hidden`
1108
+ - Scroll horizontal automático em mobile
1109
+ - Ações com `shrink-0` para não comprimir
1110
+ - Suporta muitas ações sem quebrar layout
1111
+
1112
+ #### 4. Context API
1113
+ - Hook `useSelectionBarContext()` para componentes customizados
1114
+ - Acesso a `open` e `onClose` em qualquer nível
1115
+ - Permite criar componentes especializados
1116
+
1117
+ #### 5. Integração com Componentes Base
1118
+ - Usa Button para ações (todas as variantes disponíveis)
1119
+ - Usa Typography para título (todas as props disponíveis)
1120
+ - Usa Icon para ícones
1121
+ - Mantém consistência visual com design system
1122
+
1123
+ ### Acessibilidade
1124
+ - ✅ **Navegação por teclado**: Todos os botões são focáveis
1125
+ - ✅ **Ícones descritivos**: Ações com ícones e/ou texto claro
1126
+ - ✅ **Botão de fechar**: Sempre visível e acessível
1127
+ - ✅ **Contraste adequado**: Fundo primário com texto legível
1128
+ - ✅ **Animações**: Respeitam `prefers-reduced-motion`
1129
+ - ✅ **Focus management**: Foco adequado em botões
1130
+
1131
+ ### Performance
1132
+ - ✅ **Portal rendering**: Otimizado pelo React
1133
+ - ✅ **Animações CSS**: GPU-accelerated com transforms
1134
+ - ✅ **Auto-remoção**: Limpa DOM após fechamento
1135
+ - ✅ **Context memoizado**: Evita re-renders desnecessários
1136
+ - ✅ **Callbacks estáveis**: `useCallback` para `handleClose`
1137
+ - ✅ **Composição modular**: Componentes pequenos e focados
1138
+
1139
+ ### Documentação no Storybook
1140
+
1141
+ 8 stories interativas cobrindo todos os casos:
1142
+ 1. **Playground**: Exemplo básico com 3 itens selecionados
1143
+ 2. **WithManyActions**: Múltiplas ações com overflow
1144
+ 3. **WithIconsOnly**: Apenas ícones (compacto)
1145
+ 4. **WithMixedActions**: Mistura de ícones e texto
1146
+ 5. **ControlledState**: Controle total do estado
1147
+ 6. **TableIntegration**: Integração completa com tabela
1148
+ 7. **MinimalActions**: Uma única ação
1149
+ 8. **WithVariants**: Diferentes variantes de botão
1150
+
1151
+ ### Casos de Uso Suportados
1152
+ 1. ✅ Seleção em tabelas
1153
+ 2. ✅ Operações em lote em listas
1154
+ 3. ✅ Seleção múltipla em grids
1155
+ 4. ✅ Ações de arquivamento em massa
1156
+ 5. ✅ Exportação de múltiplos itens
1157
+ 6. ✅ Compartilhamento em lote
1158
+ 7. ✅ Exclusão de múltiplos registros
1159
+ 8. ✅ Movimentação de arquivos
1160
+ 9. ✅ Marcação de leitura/não lido
1161
+ 10. ✅ Aprovação/rejeição em lote
1162
+
1163
+ ### Arquivos Criados/Substituídos
1164
+
1165
+ **SelectionBar (substituição completa)**:
1166
+ - `packages/react/src/components/selection-bar/index.ts`
1167
+ - `packages/react/src/components/selection-bar/selection-bar-root.tsx`
1168
+ - `packages/react/src/components/selection-bar/selection-bar-title.tsx`
1169
+ - `packages/react/src/components/selection-bar/selection-bar-close.tsx`
1170
+ - `packages/react/src/components/selection-bar/selection-bar-action.tsx`
1171
+ - `packages/react/src/components/selection-bar/selection-bar-action-group.tsx`
1172
+
1173
+ **Documentação**:
1174
+ - `apps/docs/src/components/selection-bar.stories.tsx` (reescrito completamente)
1175
+
1176
+ **Observação**: O componente SelectionBar foi completamente reescrito. O código antigo foi substituído por uma nova implementação composicional com portal, estado gerenciado e animações.
1177
+
1178
+ ### Comparação: Versão Antiga vs Nova
1179
+
1180
+ | Aspecto | Antiga | Nova (v2) |
1181
+ | ---------------- | ----------------------- | ---------------------------- |
1182
+ | **Arquitetura** | Monolítica | Composicional |
1183
+ | **Renderização** | Normal no DOM | Portal (flutuante) |
1184
+ | **Estado** | Não gerenciado | Controlado/não-controlado |
1185
+ | **Animações** | Básicas ou inexistentes | Slide-in/out suaves |
1186
+ | **Overflow** | Sem tratamento | Scroll horizontal automático |
1187
+ | **Fechamento** | Manual | Auto-remoção do DOM |
1188
+ | **Context** | Sem context | Context API completa |
1189
+ | **Callbacks** | Limitados | `onOpenChange` completo |
1190
+ | **Composição** | 1-2 componentes | 6 componentes especializados |
1191
+
1192
+ ### Boas Práticas
1193
+ 1. **Use para operações em lote**: Perfeito para ações em múltiplos itens
1194
+ 2. **Limite o número de ações**: 3-5 ações principais
1195
+ 3. **Priorize ações importantes**: Mais usadas primeiro
1196
+ 4. **Indique quantidade selecionada**: Sempre mostre o número
1197
+ 5. **Forneça feedback visual**: Ícones e cores apropriadas
1198
+ 6. **Feche ao limpar seleção**: Use `onOpenChange` para sincronizar
1199
+ 7. **Teste em mobile**: Verifique overflow horizontal
1200
+ 8. **Confirme ações destrutivas**: Use diálogos para deletar
1201
+ 9. **Crie portal root**: Adicione `<div id="selection-bar-root" />` no app
1202
+ 10. **Sincronize estado**: Mantenha seleções e barra em sync
1203
+
1204
+ ### Migração da Versão Antiga
1205
+
1206
+ #### Antes (SelectionBar Antigo - Depreciado)
1207
+
1208
+ ```tsx
1209
+ import { SelectionBar } from '@xjur-ui/react/selection-bar'
1210
+
1211
+ ;<SelectionBar
1212
+ title="3 selecionados"
1213
+ actions={[
1214
+ { label: 'Exportar', onClick: handleExport },
1215
+ { label: 'Excluir', onClick: handleDelete }
1216
+ ]}
1217
+ />
1218
+ ```
1219
+
1220
+ #### Depois (SelectionBar Novo - Composicional)
1221
+
1222
+ ```tsx
1223
+ import {
1224
+ SelectionBarRoot,
1225
+ SelectionBarTitleRoot,
1226
+ SelectionBarTitle,
1227
+ SelectionBarClose,
1228
+ SelectionBarActionGroup,
1229
+ SelectionBarAction
1230
+ } from '@xjur-ui/react/selection-bar'
1231
+
1232
+ ;<SelectionBarRoot>
1233
+ <SelectionBarTitleRoot>
1234
+ <SelectionBarClose />
1235
+ <SelectionBarTitle>3 selecionados</SelectionBarTitle>
1236
+ </SelectionBarTitleRoot>
1237
+
1238
+ <SelectionBarActionGroup>
1239
+ <SelectionBarAction onClick={handleExport}>Exportar</SelectionBarAction>
1240
+ <SelectionBarAction variant="destructive" onClick={handleDelete}>
1241
+ Excluir
1242
+ </SelectionBarAction>
1243
+ </SelectionBarActionGroup>
1244
+ </SelectionBarRoot>
1245
+ ```
1246
+
1247
+ ### Compatibilidade
1248
+ - ✅ React 19.1.1+
1249
+ - ✅ TypeScript 5.x
1250
+ - ✅ Tailwind CSS 4.x
1251
+ - ✅ Navegadores modernos (Chrome, Firefox, Safari, Edge)
1252
+ - ✅ iOS Safari 12+
1253
+ - ✅ Chrome Mobile
1254
+ - ✅ Suporte SSR/SSG (com hydration de portals)
1255
+
1256
+ ### Roadmap Futuro
1257
+
1258
+ Melhorias planejadas:
1259
+ - Indicador visual de scroll (mais ações disponíveis)
1260
+ - Posicionamento customizável (top/bottom)
1261
+ - Temas customizados
1262
+ - Suporte a ações agrupadas (dropdowns)
1263
+ - Contador animado ao mudar seleção
1264
+ - Undo/Redo de ações
1265
+ - Modo compacto para mobile
1266
+
1267
+ ***
1268
+
1269
+ ## Resumo da Release
1270
+
1271
+ ### Breaking Changes
1272
+ - ❌ **OTPInput** removido e substituído por **PinInput**
1273
+ - ❌ **Toast (Radix)** removido e substituído por **Toast (Sonner)**
1274
+ - ❌ **SelectionBar** reescrito completamente com arquitetura composicional
1275
+
1276
+ ### Novas Funcionalidades
1277
+ - ✅ **PinInput**: Componente moderno com auto-submit, callbacks e validação
1278
+ - ✅ **Message**: Sistema de mensagens contextuais com 4 variantes
1279
+ - ✅ **Toast**: Sistema de notificações baseado em Sonner com controle de ciclo de vida
1280
+ - ✅ **SelectionBar**: Barra de ações flutuante com portal e estado gerenciado
1281
+ - ✅ **MessageAction**: Componente de ação para Message e Toast
1282
+
1283
+ ### Melhorias
1284
+ - 📖 Documentação completa no Storybook (40 stories no total)
1285
+ - 🎨 Design consistente com tokens do sistema
1286
+ - ♿ Acessibilidade aprimorada em todos os componentes
1287
+ - ⚡ Performance otimizada com memoização e portals
1288
+ - 📦 TypeScript completo com tipos exportados
1289
+ - 🔄 Reutilização de componentes (Toast usa Message internamente)
1290
+ - 📱 Mobile-friendly (swipe no Toast, overflow no SelectionBar)
1291
+ - 🎯 Controle total de ciclo de vida (toasts e selection bar)
1292
+ - 🎭 Animações suaves em todos os componentes
1293
+
1294
+ ### Arquivos Modificados/Criados
1295
+ - 5 arquivos do componente PinInput
1296
+ - 6 arquivos do componente Message (incluindo MessageAction)
1297
+ - 4 arquivos do componente Toast
1298
+ - 6 arquivos do componente SelectionBar
1299
+ - 3 arquivos de stories no Storybook
1300
+ - 1 README do PinInput
1301
+
1302
+ ### Arquivos Removidos
1303
+ - 1 arquivo do OTPInput antigo
1304
+ - 1 arquivo do Toast antigo (Radix)
1305
+ - 1 arquivo do SelectionBar antigo
1306
+ - 1 arquivo de stories do OTPInput
1307
+
1308
+ ### Dependências Adicionadas
1309
+ - **sonner**: ^2.0.7 (~10KB) - Library moderna para toasts
1310
+
1311
+ ### Estatísticas da Release
1312
+ - **Componentes novos/reescritos**: 4 (PinInput, Message, Toast, SelectionBar)
1313
+ - **Componentes removidos**: 3 (OTPInput, Toast Radix, SelectionBar antigo)
1314
+ - **Stories no Storybook**: 40 (9 PinInput + 10 Message + 13 Toast + 8 SelectionBar)
1315
+ - **Breaking changes**: 3 (OTPInput → PinInput, Toast Radix → Toast Sonner, SelectionBar reescrito)
1316
+ - **Linhas de código**: ~1800 novas linhas
1317
+ - **Cobertura de casos de uso**: 37+ casos diferentes
1318
+ - **Funcionalidades do Toast**: 3 métodos (dispatch, dismiss, clear)
1319
+ - **Componentes no SelectionBar**: 6 componentes especializados
1320
+
1321
+ ### Próximos Passos Recomendados
1322
+ 1. **Migrar de OTPInput para PinInput**
1323
+ - Atualizar imports: `@xjur-ui/react/pin-input`
1324
+ - Renomear componentes: `OTPInputRoot` → `PinInput`, etc.
1325
+ - Ajustar props: `initial` → `defaultValue`
1326
+ - Adicionar callbacks opcionais: `onComplete`, `onChangeValue`
1327
+ - Aproveitar auto-submit para melhor UX
1328
+ 2. **Migrar de Toast Radix para Toast Sonner**
1329
+ - Atualizar imports: `@xjur-ui/react/toast`
1330
+ - Substituir `<ToastProvider>` por `<ToastWrapper />`
1331
+ - Converter de API declarativa para imperativa
1332
+ - Usar `toast.dispatch()` ao invés de componentes JSX
1333
+ - Aproveitar `toast.dismiss()` e `toast.clear()` para controle avançado
1334
+ - Armazenar IDs retornados por `dispatch()` quando necessário
1335
+ - Remover lógica de gerenciamento manual de toasts
1336
+ 3. **Integrar Message no sistema**
1337
+ - Substituir alerts antigos por Message
1338
+ - Padronizar feedback de ações em formulários
1339
+ - Implementar em fluxos críticos
1340
+ - Usar MessageAction para ações contextuais
1341
+ 4. **Migrar SelectionBar**
1342
+ - Atualizar imports para componentes composicionais
1343
+ - Converter props de array para JSX composicional
1344
+ - Adicionar `<div id="selection-bar-root" />` no root da aplicação (opcional)
1345
+ - Usar `onOpenChange` para sincronizar estado com seleções
1346
+ - Aproveitar overflow horizontal para muitas ações
1347
+ 5. **Integrar Toast para notificações**
1348
+ - Adicionar `<ToastWrapper />` no root da aplicação
1349
+ - Substituir notificações antigas por `toast.dispatch()`
1350
+ - Usar `toast.dismiss()` para substituir loading por sucesso
1351
+ - Usar `toast.clear()` ao mudar de página/contexto
1352
+ - Implementar callbacks para analytics
1353
+ - Configurar posicionamento adequado
1354
+ - Armazenar IDs para controle de toasts relacionados
1355
+ 6. **Integrar SelectionBar em tabelas e listas**
1356
+ - Adicionar ao componente de seleção múltipla
1357
+ - Sincronizar estado de seleções com `onOpenChange`
1358
+ - Implementar ações em lote (exportar, deletar, arquivar)
1359
+ - Configurar portal root para melhor controle
1360
+ - Testar overflow em mobile
1361
+ 7. **Testar em produção**
1362
+ - Validar acessibilidade com leitores de tela
1363
+ - Verificar performance em dispositivos low-end
1364
+ - Testar gestures em mobile (swipe to dismiss, overflow horizontal)
1365
+ - Validar portals em SSR/SSG
1366
+ - Coletar feedback de usuários
1367
+ - Monitorar métricas de uso
1368
+
1369
+ ### Impacto Estimado
1370
+
1371
+ **Positivo:**
1372
+ - ✅ Melhor DX com API simplificada
1373
+ - ✅ Componentes mais modernos e performáticos
1374
+ - ✅ Documentação muito mais completa
1375
+ - ✅ Consistência visual total entre Message e Toast
1376
+ - ✅ Redução de bundle size (Sonner vs Radix Toast)
1377
+ - ✅ Mais casos de uso suportados
1378
+
1379
+ **Atenção Necessária:**
1380
+ - ⚠️ Migração necessária em todos os usos de OTPInput
1381
+ - ⚠️ Migração necessária em todos os usos de Toast
1382
+ - ⚠️ Migração necessária em todos os usos de SelectionBar
1383
+ - ⚠️ Testes extensivos recomendados (especialmente portals em SSR)
1384
+ - ⚠️ Atualização de documentação interna da equipe
1385
+ - ⚠️ Validação de z-index em diferentes contextos
1386
+
1387
+ ### Guias de Migração Rápida
1388
+
1389
+ #### OTPInput → PinInput (1 minuto)
1390
+
1391
+ ```diff
1392
+ - import { OTPInputRoot, OTPInputInput, ... } from '@xjur-ui/react/otp-input'
1393
+ + import { PinInput, PinInputControl, ... } from '@xjur-ui/react/pin-input'
1394
+
1395
+ - <OTPInputRoot initial="1234" length={4}>
1396
+ + <PinInput defaultValue="1234" length={4} name="code">
1397
+ <PinInputTrigger>
1398
+ - <OTPInputInput index={0} />
1399
+ + <PinInputControl index={0} />
1400
+ </PinInputTrigger>
1401
+ - <OTPInputHiddenInput name="code" />
1402
+ </PinInput>
1403
+ ```
1404
+
1405
+ #### Toast Radix → Toast Sonner (30 segundos)
1406
+
1407
+ ```diff
1408
+ - import { ToastProvider, ToastComponent } from '@xjur-ui/react/toast'
1409
+ + import { ToastWrapper, toast } from '@xjur-ui/react/toast'
1410
+
1411
+ // No root
1412
+ - <ToastProvider>
1413
+ - <App />
1414
+ - </ToastProvider>
1415
+ + <ToastWrapper />
1416
+ + <App />
1417
+
1418
+ // Ao disparar
1419
+ - <ToastComponent variant="success" description="Salvo!" />
1420
+ + toast.dispatch('Salvo!', { variant: 'primary' })
1421
+
1422
+ // Controle avançado
1423
+ + const id = toast.dispatch('Processando...')
1424
+ + toast.dismiss(id) // Fechar específico
1425
+ + toast.clear() // Fechar todos
1426
+ ```
1427
+
1428
+ #### SelectionBar Antigo → SelectionBar Composicional (2 minutos)
1429
+
1430
+ ```diff
1431
+ - import { SelectionBar } from '@xjur-ui/react/selection-bar'
1432
+ + import {
1433
+ + SelectionBarRoot,
1434
+ + SelectionBarTitleRoot,
1435
+ + SelectionBarTitle,
1436
+ + SelectionBarClose,
1437
+ + SelectionBarActionGroup,
1438
+ + SelectionBarAction
1439
+ + } from '@xjur-ui/react/selection-bar'
1440
+
1441
+ - <SelectionBar
1442
+ - title="3 selecionados"
1443
+ - actions={[
1444
+ - { label: 'Exportar', onClick: handleExport },
1445
+ - { label: 'Excluir', onClick: handleDelete }
1446
+ - ]}
1447
+ - />
1448
+ + <SelectionBarRoot>
1449
+ + <SelectionBarTitleRoot>
1450
+ + <SelectionBarClose />
1451
+ + <SelectionBarTitle>3 selecionados</SelectionBarTitle>
1452
+ + </SelectionBarTitleRoot>
1453
+ +
1454
+ + <SelectionBarActionGroup>
1455
+ + <SelectionBarAction onClick={handleExport}>
1456
+ + Exportar
1457
+ + </SelectionBarAction>
1458
+ + <SelectionBarAction
1459
+ + variant="destructive"
1460
+ + onClick={handleDelete}
1461
+ + >
1462
+ + Excluir
1463
+ + </SelectionBarAction>
1464
+ + </SelectionBarActionGroup>
1465
+ + </SelectionBarRoot>
1466
+
1467
+ // Com controle de estado
1468
+ + <SelectionBarRoot
1469
+ + open={open}
1470
+ + onOpenChange={(newOpen) => {
1471
+ + setOpen(newOpen)
1472
+ + if (!newOpen) setSelectedItems([])
1473
+ + }}
1474
+ + >
1475
+ ```
8
1476
 
9
1477
  ## 3.1.1
10
1478
 
11
1479
  ### Patch Changes
12
1480
 
13
1481
  - 6ff314b: fix progress text view
1482
+ - ffe201e: Add error state and disabled state in otp input
14
1483
 
15
1484
  ## 3.1.0
16
1485