@liguelead/design-system 0.0.30 → 0.0.32

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 (46) hide show
  1. package/components/Alert/Alert.stories.tsx +94 -18
  2. package/components/Badge/Badge.stories.tsx +114 -0
  3. package/components/Badge/Badge.styles.ts +36 -0
  4. package/components/Badge/Badge.tsx +23 -0
  5. package/components/Badge/Badge.types.ts +11 -0
  6. package/components/Badge/index.ts +2 -0
  7. package/components/Button/Button.appearance.ts +1 -1
  8. package/components/Button/Button.stories.tsx +99 -18
  9. package/components/Checkbox/Checkbox.stories.tsx +107 -7
  10. package/components/DatePicker/DatePicker.styles.ts +1 -0
  11. package/components/DatePicker/DatePicker.tsx +9 -10
  12. package/components/IconButton/IconButton.sizes.ts +7 -7
  13. package/components/IconButton/IconButton.tsx +0 -1
  14. package/components/InputOpt/InputOpt.stories.tsx +30 -44
  15. package/components/Select/Select.stories.tsx +80 -19
  16. package/components/Select/Select.tsx +7 -9
  17. package/components/Table/Datatable.stories.tsx +186 -0
  18. package/components/Table/Table.stories.tsx +127 -46
  19. package/components/Table/Table.styles.ts +83 -8
  20. package/components/Table/Table.tsx +292 -142
  21. package/components/Table/Table.types.ts +104 -12
  22. package/components/Table/components/ColumnVisibility/ColumnVisibility.style.ts +46 -0
  23. package/components/Table/components/ColumnVisibility/ColumnVisibility.tsx +55 -0
  24. package/components/Table/components/DatatableColumnFilterMenu/DatatableColumnFilterMenu.styles.ts +120 -0
  25. package/components/Table/components/DatatableColumnFilterMenu/DatatableColumnFilterMenu.tsx +228 -0
  26. package/components/Table/components/DatatableColumnFilterMenu/index.ts +1 -0
  27. package/components/Table/components/DatatableTopBar/DatatableTopBar.styles.ts +25 -0
  28. package/components/Table/components/DatatableTopBar/DatatableTopBar.tsx +89 -0
  29. package/components/Table/components/DatatableTopBar/index.ts +1 -0
  30. package/components/Table/components/SearchInput/SearchInput.tsx +30 -0
  31. package/components/Table/components/TableHeader/TableHeader.tsx +98 -0
  32. package/components/Table/components/TablePagination/TablePagination.tsx +78 -0
  33. package/components/Table/components/index.ts +6 -0
  34. package/components/Table/hooks/useDatatableFilters.ts +88 -0
  35. package/components/Table/stories.fixtures.ts +100 -0
  36. package/components/Table/tanstack-table.d.ts +10 -0
  37. package/components/Table/utils/dateRangeFilterFn.ts +33 -0
  38. package/components/Table/utils/index.ts +2 -1
  39. package/components/Tabs/Tabs.stories.tsx +152 -0
  40. package/components/Tabs/Tabs.styles.ts +12 -0
  41. package/components/Tabs/Tabs.tsx +34 -0
  42. package/components/Tabs/Tabs.types.ts +15 -0
  43. package/components/Tabs/index.ts +2 -0
  44. package/components/TextField/TextField.stories.tsx +135 -12
  45. package/components/index.ts +3 -0
  46. package/package.json +3 -2
@@ -6,55 +6,131 @@ const meta: Meta<typeof Alert> = {
6
6
  component: Alert,
7
7
  parameters: {
8
8
  layout: 'padded',
9
+ docs: {
10
+ description: {
11
+ component: `
12
+ Componente de alerta para comunicar mensagens de feedback ao usuário.
13
+
14
+ **Quando usar cada variante:**
15
+ - \`default\` — informações gerais ou neutras
16
+ - \`info\` — dicas, orientações ou informações complementares
17
+ - \`success\` — confirmação de ação concluída com sucesso
18
+ - \`warning\` — atenção necessária, mas não crítica
19
+ - \`danger\` — erros, falhas ou ações destrutivas
20
+
21
+ **Boas práticas:**
22
+ - Use títulos curtos e objetivos
23
+ - A descrição deve complementar, não repetir o título
24
+ - Use \`hasButton\` apenas quando houver uma ação clara para o usuário
25
+ `,
26
+ },
27
+ },
9
28
  },
10
29
  tags: ['autodocs'],
11
30
  argTypes: {
12
31
  variant: {
13
32
  control: 'select',
14
33
  options: ['default', 'danger', 'warning', 'info', 'success'],
15
- description: 'Visual style variant of the alert'
34
+ description: 'Variante visual do alerta',
35
+ table: { defaultValue: { summary: 'default' } },
16
36
  },
17
37
  title: {
18
38
  control: 'text',
19
- description: 'Alert title'
39
+ description: 'Título do alerta (obrigatório)',
20
40
  },
21
41
  description: {
22
42
  control: 'text',
23
- description: 'Alert description'
43
+ description: 'Descrição complementar do alerta',
24
44
  },
25
45
  hasButton: {
26
46
  control: 'boolean',
27
- description: 'Whether to show action button'
47
+ description: 'Exibe botão de ação',
48
+ table: { defaultValue: { summary: 'false' } },
28
49
  },
29
50
  buttonLabel: {
30
51
  control: 'text',
31
- description: 'Action button label'
52
+ description: 'Texto do botão de ação',
32
53
  },
33
54
  href: {
34
55
  control: 'text',
35
- description: 'Action button link'
36
- }
56
+ description: 'URL do botão de ação',
57
+ },
37
58
  },
38
59
  }
39
60
 
40
61
  export default meta
41
62
  type Story = StoryObj<typeof meta>
42
63
 
43
- export const Variants: Story = {
64
+ export const Default: Story = {
65
+ args: {
66
+ title: 'Informação importante',
67
+ description: 'Esta é uma mensagem de alerta padrão.',
68
+ },
69
+ }
70
+
71
+ export const TodasVariantes: Story = {
72
+ name: 'Todas as variantes',
73
+ parameters: {
74
+ docs: { description: { story: 'Visão geral de todas as variantes disponíveis.' } },
75
+ },
44
76
  render: () => (
45
- <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
46
- <Alert variant="default" title="Default Alert" description="This is a default alert message." />
47
- <Alert variant="info" title="Info Alert" description="This is an informational alert message." />
48
- <Alert variant="success" title="Success Alert" description="This is a success alert message." />
49
- <Alert variant="warning" title="Warning Alert" description="This is a warning alert message." />
50
- <Alert variant="danger" title="Danger Alert" description="This is a danger alert message." />
77
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
78
+ <Alert variant="default" title="Default" description="Informação geral ou neutra." />
79
+ <Alert variant="info" title="Info" description="Dica ou orientação complementar." />
80
+ <Alert variant="success" title="Sucesso" description="Ação concluída com sucesso." />
81
+ <Alert variant="warning" title="Atenção" description="Requer atenção, mas não é crítico." />
82
+ <Alert variant="danger" title="Erro" description="Falha ou ação destrutiva detectada." />
51
83
  </div>
52
84
  ),
53
85
  }
54
86
 
55
- export const Default: Story = {
56
- args: {
57
- title: 'Alert Title',
58
- description: 'This is an alert description.',
87
+ export const ComBotao: Story = {
88
+ name: 'Com botão de ação',
89
+ parameters: {
90
+ docs: { description: { story: 'Use `hasButton` quando houver uma ação clara para o usuário tomar.' } },
59
91
  },
92
+ render: () => (
93
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
94
+ <Alert variant="info" title="Nova versão disponível" description="Uma atualização está pronta para ser instalada." hasButton buttonLabel="Atualizar agora" href="#" />
95
+ <Alert variant="warning" title="Sessão expirando" description="Sua sessão expira em 5 minutos." hasButton buttonLabel="Renovar sessão" href="#" />
96
+ <Alert variant="danger" title="Falha no pagamento" description="Não foi possível processar seu pagamento." hasButton buttonLabel="Tentar novamente" href="#" />
97
+ </div>
98
+ ),
99
+ }
100
+
101
+ export const SemDescricao: Story = {
102
+ name: 'Sem descrição',
103
+ parameters: {
104
+ docs: { description: { story: 'Alertas podem ser usados apenas com título quando a mensagem é autoexplicativa.' } },
105
+ },
106
+ render: () => (
107
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
108
+ <Alert variant="success" title="Salvo com sucesso." />
109
+ <Alert variant="danger" title="Erro ao carregar os dados." />
110
+ </div>
111
+ ),
112
+ }
113
+
114
+ export const ExemploFormulario: Story = {
115
+ name: 'Exemplo: Feedback de formulário',
116
+ parameters: {
117
+ docs: { description: { story: 'Padrão de uso em formulários para comunicar resultado de submissão.' } },
118
+ },
119
+ render: () => (
120
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12, width: 480 }}>
121
+ <Alert
122
+ variant="success"
123
+ title="Cadastro realizado com sucesso!"
124
+ description="Você receberá um e-mail de confirmação em breve."
125
+ />
126
+ <Alert
127
+ variant="danger"
128
+ title="Não foi possível salvar"
129
+ description="Verifique os campos obrigatórios e tente novamente."
130
+ hasButton
131
+ buttonLabel="Ver erros"
132
+ href="#"
133
+ />
134
+ </div>
135
+ ),
60
136
  }
@@ -0,0 +1,114 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import { CheckCircleIcon, ArrowRightIcon, XCircleIcon, InfoIcon, WarningCircleIcon } from '@phosphor-icons/react'
3
+ import { themes } from '@liguelead/foundation'
4
+ import Badge from './Badge'
5
+
6
+ const colorOptions = Object.keys(themes.spa.colors)
7
+
8
+ const meta: Meta<typeof Badge> = {
9
+ title: 'Data Display/Badge',
10
+ component: Badge,
11
+ parameters: {
12
+ layout: 'centered',
13
+ docs: {
14
+ description: {
15
+ component: `
16
+ Badge compacto para destacar status, categorias ou contagens.
17
+
18
+ **Props principais:**
19
+ - \`color\` — qualquer token de cor do tema (ex: \`primary\`, \`danger200\`, \`secondary\`)
20
+ - \`showLeftIcon\` / \`showRightIcon\` — exibe ícones nas extremidades
21
+ `,
22
+ },
23
+ },
24
+ },
25
+ tags: ['autodocs'],
26
+ argTypes: {
27
+ color: {
28
+ control: 'select',
29
+ options: colorOptions,
30
+ description: 'Cor de fundo do badge (token do tema)',
31
+ table: { defaultValue: { summary: 'primary' } },
32
+ },
33
+ children: {
34
+ control: 'text',
35
+ description: 'Texto exibido no badge',
36
+ table: { defaultValue: { summary: 'Badge' } },
37
+ },
38
+ showLeftIcon: {
39
+ control: 'boolean',
40
+ description: 'Exibe ícone à esquerda',
41
+ table: { defaultValue: { summary: 'false' } },
42
+ },
43
+ showRightIcon: {
44
+ control: 'boolean',
45
+ description: 'Exibe ícone à direita',
46
+ table: { defaultValue: { summary: 'false' } },
47
+ },
48
+ leftIcon: { control: false },
49
+ rightIcon: { control: false },
50
+ },
51
+ }
52
+
53
+ export default meta
54
+ type Story = StoryObj<typeof meta>
55
+
56
+ export const Default: Story = {
57
+ args: {
58
+ children: 'Ativo',
59
+ color: 'success50',
60
+ },
61
+ }
62
+
63
+ export const Danger: Story = {
64
+ args: {
65
+ children: 'Erro',
66
+ color: 'danger50',
67
+ },
68
+ }
69
+
70
+ export const Secondary: Story = {
71
+ args: {
72
+ children: 'Categoria',
73
+ color: 'warning50',
74
+ },
75
+ }
76
+
77
+ export const ComIconeEsquerdo: Story = {
78
+ name: 'Com ícone esquerdo',
79
+ args: {
80
+ children: 'Verificado',
81
+ color: 'success50',
82
+ showLeftIcon: true,
83
+ leftIcon: <CheckCircleIcon size={16} />,
84
+ },
85
+ }
86
+
87
+ export const ComIconeDireito: Story = {
88
+ name: 'Com ícone direito',
89
+ args: {
90
+ children: 'Ver mais',
91
+ color: 'success50',
92
+ showRightIcon: true,
93
+ rightIcon: <ArrowRightIcon size={16} />,
94
+ },
95
+ }
96
+
97
+ export const TodasAsCores: Story = {
98
+ name: 'Exemplo: Status de pedido',
99
+ render: () => (
100
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12, fontFamily: 'Manrope, sans-serif' }}>
101
+ {[
102
+ { id: '#1042', status: 'Aprovado', color: 'primary' as const, icon: <CheckCircleIcon size={16} /> },
103
+ { id: '#1043', status: 'Pendente', color: 'warning100' as const, icon: <InfoIcon size={16} /> },
104
+ { id: '#1044', status: 'Cancelado', color: 'danger200' as const, icon: <XCircleIcon size={16} /> },
105
+ { id: '#1045', status: 'Em análise', color: 'secondary' as const, icon: <WarningCircleIcon size={16} /> },
106
+ ].map(({ id, status, color, icon }) => (
107
+ <div key={id} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '8px 12px', border: '1px solid #e5e7eb', borderRadius: 6, width: 280 }}>
108
+ <span style={{ fontSize: 14, color: '#374151' }}>Pedido {id}</span>
109
+ <Badge color={color} showLeftIcon leftIcon={icon}>{status}</Badge>
110
+ </div>
111
+ ))}
112
+ </div>
113
+ ),
114
+ }
@@ -0,0 +1,36 @@
1
+ import styled, { DefaultTheme } from 'styled-components'
2
+ import { spacing, fontSize, fontWeight, lineHeight, radius } from '@liguelead/foundation'
3
+ import { getTextColor, parseColor } from '../../utils'
4
+ import { colorType } from '../../types'
5
+
6
+ const getBadgeColors = (theme: DefaultTheme, color: colorType) => {
7
+ const parsedColor = parseColor(theme.colors[color])
8
+ return {
9
+ background: parsedColor,
10
+ text: parseColor(theme.colors[getTextColor(parsedColor)]),
11
+ }
12
+ }
13
+
14
+ export const StyledBadge = styled.span<{ $color: colorType }>`
15
+ display: inline-flex;
16
+ align-items: center;
17
+ justify-content: center;
18
+ gap: ${spacing.spacing4}px;
19
+ padding: ${spacing.spacing2}px ${spacing.spacing8}px;
20
+ border-radius: ${radius.radius4}px;
21
+ font-size: ${fontSize.fontSize12}px;
22
+ font-weight: ${fontWeight.fontWeight500};
23
+ line-height: ${lineHeight.lineHeight16}px;
24
+ font-family: Manrope, sans-serif;
25
+ white-space: nowrap;
26
+
27
+ background-color: ${({ theme, $color }) => getBadgeColors(theme, $color).background};
28
+
29
+ color: ${({ theme, $color }) => getBadgeColors(theme, $color).text};
30
+
31
+ & svg {
32
+ width: 16px;
33
+ height: 16px;
34
+ flex-shrink: 0;
35
+ }
36
+ `
@@ -0,0 +1,23 @@
1
+ import { StyledBadge } from './Badge.styles'
2
+ import { TBadgeProps } from './Badge.types'
3
+
4
+ const Badge = ({
5
+ children = 'Badge',
6
+ className,
7
+ color = 'primary',
8
+ leftIcon,
9
+ rightIcon,
10
+ showLeftIcon = false,
11
+ showRightIcon = false,
12
+ }: TBadgeProps) => {
13
+
14
+ return (
15
+ <StyledBadge $color={color} className={className}>
16
+ {showLeftIcon && leftIcon}
17
+ {children}
18
+ {showRightIcon && rightIcon}
19
+ </StyledBadge>
20
+ )
21
+ }
22
+
23
+ export default Badge
@@ -0,0 +1,11 @@
1
+ import { colorType } from "../../types"
2
+
3
+ export type TBadgeProps = {
4
+ children?: React.ReactNode
5
+ className?: string
6
+ leftIcon?: React.ReactNode
7
+ rightIcon?: React.ReactNode
8
+ showLeftIcon?: boolean
9
+ showRightIcon?: boolean
10
+ color?: colorType
11
+ }
@@ -0,0 +1,2 @@
1
+ export { default as Badge } from './Badge'
2
+ export type { TBadgeProps } from './Badge.types'
@@ -75,7 +75,7 @@ export const ButtonVariant = (
75
75
  neutralOutline: `
76
76
  background-color: transparent;
77
77
  color: ${parseColor(theme.colors.textDark)};
78
- border: 1px solid ${parseColor(theme.colors.neutral900)};
78
+ border: 1px solid ${parseColor(theme.colors.neutral400)};
79
79
 
80
80
  &:hover {
81
81
  background-color: ${parseColor(theme.colors.primaryDarker)};
@@ -1,15 +1,12 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
2
  import { themes } from '@liguelead/foundation'
3
+ import { PlusIcon, ArrowRightIcon, TrashIcon } from '@phosphor-icons/react'
3
4
  import Button from './Button'
4
5
  import type { ButtonVariantTypes } from './Button.types'
5
6
 
6
7
  const themeColors = Object.keys(themes.spa.colors)
7
8
  const buttonVariantOptions: ButtonVariantTypes[] = [
8
- 'solid',
9
- 'outline',
10
- 'ghost',
11
- 'neutralOutline',
12
- 'neutralGhost'
9
+ 'solid', 'outline', 'ghost', 'neutralOutline', 'neutralGhost',
13
10
  ]
14
11
 
15
12
  const meta: Meta<typeof Button> = {
@@ -17,35 +14,53 @@ const meta: Meta<typeof Button> = {
17
14
  component: Button,
18
15
  parameters: {
19
16
  layout: 'centered',
17
+ docs: {
18
+ description: {
19
+ component: `
20
+ Botão de ação principal do design system.
21
+
22
+ **Quando usar cada variante:**
23
+ - \`solid\` — ação primária da tela (ex: Salvar, Confirmar)
24
+ - \`outline\` — ação secundária com destaque (ex: Editar)
25
+ - \`ghost\` — ação terciária ou em contextos com fundo colorido
26
+ - \`neutralOutline\` / \`neutralGhost\` — ações neutras, cancelar, voltar
27
+ `,
28
+ },
29
+ },
20
30
  },
21
31
  tags: ['autodocs'],
22
32
  argTypes: {
23
33
  variant: {
24
34
  control: 'select',
25
35
  options: buttonVariantOptions,
26
- description: 'Visual style variant of the button',
36
+ description: 'Variante visual do botão',
37
+ table: { defaultValue: { summary: 'solid' } },
27
38
  },
28
39
  size: {
29
40
  control: 'select',
30
41
  options: ['sm', 'md', 'lg'],
31
- description: 'Size of the button',
42
+ description: 'Tamanho do botão',
43
+ table: { defaultValue: { summary: 'md' } },
32
44
  },
33
45
  color: {
34
46
  control: 'select',
35
47
  options: themeColors,
36
- description: 'Color theme of the button',
48
+ description: 'Cor do botão baseada nos tokens do tema',
49
+ table: { defaultValue: { summary: 'primary' } },
37
50
  },
38
51
  disabled: {
39
52
  control: 'boolean',
40
- description: 'Whether the button is disabled',
53
+ description: 'Desabilita o botão',
54
+ table: { defaultValue: { summary: 'false' } },
41
55
  },
42
56
  fullWidth: {
43
57
  control: 'boolean',
44
- description: 'Whether the button takes full width',
58
+ description: 'Ocupa 100% da largura do container',
59
+ table: { defaultValue: { summary: 'false' } },
45
60
  },
46
61
  children: {
47
62
  control: 'text',
48
- description: 'Button content',
63
+ description: 'Conteúdo do botão',
49
64
  },
50
65
  },
51
66
  }
@@ -54,17 +69,16 @@ export default meta
54
69
  type Story = StoryObj<typeof meta>
55
70
 
56
71
  export const Default: Story = {
57
- args: {
58
- children: 'Button',
59
- },
72
+ args: { children: 'Confirmar' },
60
73
  }
61
74
 
62
- export const Variants: Story = {
63
- args: {
64
- children: 'Button',
75
+ export const Variantes: Story = {
76
+ name: 'Todas as variantes',
77
+ parameters: {
78
+ docs: { description: { story: 'Todas as variantes disponíveis com a cor primária.' } },
65
79
  },
66
80
  render: (args) => (
67
- <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
81
+ <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' }}>
68
82
  <Button {...args} variant="solid">Solid</Button>
69
83
  <Button {...args} variant="outline">Outline</Button>
70
84
  <Button {...args} variant="ghost">Ghost</Button>
@@ -73,3 +87,70 @@ export const Variants: Story = {
73
87
  </div>
74
88
  ),
75
89
  }
90
+
91
+ export const Tamanhos: Story = {
92
+ name: 'Tamanhos',
93
+ parameters: {
94
+ docs: { description: { story: 'Três tamanhos disponíveis: `sm`, `md` e `lg`.' } },
95
+ },
96
+ render: () => (
97
+ <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
98
+ <Button size="sm">Pequeno</Button>
99
+ <Button size="md">Médio</Button>
100
+ <Button size="lg">Grande</Button>
101
+ </div>
102
+ ),
103
+ }
104
+
105
+ export const Desabilitado: Story = {
106
+ name: 'Estado desabilitado',
107
+ parameters: {
108
+ docs: { description: { story: 'Estado `disabled` em todas as variantes.' } },
109
+ },
110
+ render: () => (
111
+ <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
112
+ <Button disabled variant="solid">Solid</Button>
113
+ <Button disabled variant="outline">Outline</Button>
114
+ <Button disabled variant="ghost">Ghost</Button>
115
+ </div>
116
+ ),
117
+ }
118
+
119
+ export const LarguraTotal: Story = {
120
+ name: 'Largura total',
121
+ parameters: {
122
+ docs: { description: { story: 'Use `fullWidth` em formulários ou containers de largura definida.' } },
123
+ },
124
+ render: () => (
125
+ <div style={{ width: 320 }}>
126
+ <Button fullWidth>Entrar</Button>
127
+ </div>
128
+ ),
129
+ }
130
+
131
+ export const ComIcones: Story = {
132
+ name: 'Com ícones',
133
+ parameters: {
134
+ docs: { description: { story: 'Combine com ícones do Phosphor para reforçar a ação.' } },
135
+ },
136
+ render: () => (
137
+ <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' }}>
138
+ <Button><PlusIcon size={16} /> Adicionar</Button>
139
+ <Button variant="outline">Próximo <ArrowRightIcon size={16} /></Button>
140
+ <Button variant="ghost" color="danger200"><TrashIcon size={16} /> Excluir</Button>
141
+ </div>
142
+ ),
143
+ }
144
+
145
+ export const ExemploFormulario: Story = {
146
+ name: 'Exemplo: Rodapé de formulário',
147
+ parameters: {
148
+ docs: { description: { story: 'Padrão comum de ações em formulários: ação primária + cancelar.' } },
149
+ },
150
+ render: () => (
151
+ <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end', padding: 16, border: '1px solid #e5e7eb', borderRadius: 8, width: 400 }}>
152
+ <Button variant="neutralGhost">Cancelar</Button>
153
+ <Button variant="solid">Salvar alterações</Button>
154
+ </div>
155
+ ),
156
+ }
@@ -1,4 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import { useState } from 'react'
2
3
  import Checkbox from './Checkbox'
3
4
 
4
5
  const meta: Meta<typeof Checkbox> = {
@@ -6,29 +7,48 @@ const meta: Meta<typeof Checkbox> = {
6
7
  component: Checkbox,
7
8
  parameters: {
8
9
  layout: 'centered',
10
+ docs: {
11
+ description: {
12
+ component: `
13
+ Checkbox para seleção de uma ou múltiplas opções independentes.
14
+
15
+ **Quando usar:**
16
+ - Seleção múltipla em listas de opções
17
+ - Aceite de termos e condições
18
+ - Filtros que podem ser combinados
19
+
20
+ **Não usar para:**
21
+ - Seleção exclusiva (use RadioButton)
22
+ - Ativar/desativar configurações em tempo real (use Toggle)
23
+ `,
24
+ },
25
+ },
9
26
  },
10
27
  tags: ['autodocs'],
11
28
  argTypes: {
12
29
  label: {
13
30
  control: 'text',
14
- description: 'Checkbox label'
31
+ description: 'Texto do label do checkbox',
15
32
  },
16
33
  description: {
17
34
  control: 'text',
18
- description: 'Checkbox description'
35
+ description: 'Descrição complementar abaixo do label',
19
36
  },
20
37
  checked: {
21
38
  control: 'boolean',
22
- description: 'Whether checkbox is checked'
39
+ description: 'Estado marcado do checkbox',
40
+ table: { defaultValue: { summary: 'false' } },
23
41
  },
24
42
  disabled: {
25
43
  control: 'boolean',
26
- description: 'Whether checkbox is disabled'
44
+ description: 'Desabilita o checkbox',
45
+ table: { defaultValue: { summary: 'false' } },
27
46
  },
28
47
  $hasError: {
29
48
  control: 'boolean',
30
- description: 'Whether checkbox has error state'
31
- }
49
+ description: 'Estado de erro',
50
+ table: { defaultValue: { summary: 'false' } },
51
+ },
32
52
  },
33
53
  }
34
54
 
@@ -37,6 +57,86 @@ type Story = StoryObj<typeof meta>
37
57
 
38
58
  export const Default: Story = {
39
59
  args: {
40
- label: 'Checkbox Label',
60
+ label: 'Aceito os termos de uso',
61
+ },
62
+ }
63
+
64
+ export const ComDescricao: Story = {
65
+ name: 'Com descrição',
66
+ parameters: {
67
+ docs: { description: { story: 'Use a descrição para dar contexto adicional à opção.' } },
68
+ },
69
+ args: {
70
+ label: 'Receber notificações',
71
+ description: 'Enviaremos atualizações sobre sua conta por e-mail.',
72
+ },
73
+ }
74
+
75
+ export const Marcado: Story = {
76
+ name: 'Estado marcado',
77
+ args: {
78
+ label: 'Opção selecionada',
79
+ checked: true,
80
+ },
81
+ }
82
+
83
+ export const Desabilitado: Story = {
84
+ name: 'Estado desabilitado',
85
+ parameters: {
86
+ docs: { description: { story: 'Estado desabilitado — marcado e desmarcado.' } },
87
+ },
88
+ render: () => (
89
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
90
+ <Checkbox label="Desabilitado desmarcado" disabled />
91
+ <Checkbox label="Desabilitado marcado" disabled checked />
92
+ </div>
93
+ ),
94
+ }
95
+
96
+ export const ComErro: Story = {
97
+ name: 'Estado de erro',
98
+ parameters: {
99
+ docs: { description: { story: 'Use para indicar que o campo é obrigatório e não foi preenchido.' } },
100
+ },
101
+ args: {
102
+ label: 'Aceito os termos de uso',
103
+ $hasError: true,
104
+ },
105
+ }
106
+
107
+ export const ExemploGrupo: Story = {
108
+ name: 'Exemplo: Grupo de checkboxes',
109
+ parameters: {
110
+ docs: { description: { story: 'Padrão de uso em formulários com múltiplas opções selecionáveis.' } },
111
+ },
112
+ render: () => {
113
+ const [selected, setSelected] = useState<string[]>(['email'])
114
+ const options = [
115
+ { value: 'email', label: 'E-mail', description: 'Notificações por e-mail' },
116
+ { value: 'sms', label: 'SMS', description: 'Mensagens de texto' },
117
+ { value: 'push', label: 'Push', description: 'Notificações no app' },
118
+ ]
119
+
120
+ const toggle = (value: string) =>
121
+ setSelected(prev =>
122
+ prev.includes(value) ? prev.filter(v => v !== value) : [...prev, value]
123
+ )
124
+
125
+ return (
126
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
127
+ <p style={{ fontSize: 14, fontWeight: 600, marginBottom: 4, fontFamily: 'Manrope, sans-serif' }}>
128
+ Canais de notificação
129
+ </p>
130
+ {options.map(opt => (
131
+ <Checkbox
132
+ key={opt.value}
133
+ label={opt.label}
134
+ description={opt.description}
135
+ checked={selected.includes(opt.value)}
136
+ onChange={() => toggle(opt.value)}
137
+ />
138
+ ))}
139
+ </div>
140
+ )
41
141
  },
42
142
  }
@@ -197,6 +197,7 @@ export const DatePickerContent = styled(Popover.Content)`
197
197
  0 1px 3px 0 rgba(0, 0, 0, 0.10),
198
198
  0 1px 2px -1px rgba(0, 0, 0, 0.10);
199
199
  min-width: 240px;
200
+ z-index: 9999;
200
201
  `
201
202
 
202
203
  export const CalendarWrapper = styled.div<{$singleMonth: boolean}>`