@liguelead/design-system 0.0.30 → 0.0.31
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/components/Alert/Alert.stories.tsx +94 -18
- package/components/Badge/Badge.stories.tsx +285 -0
- package/components/Badge/Badge.styles.ts +24 -0
- package/components/Badge/Badge.tsx +25 -0
- package/components/Badge/Badge.types.ts +11 -0
- package/components/Badge/Badge.variants.ts +37 -0
- package/components/Badge/index.ts +2 -0
- package/components/Button/Button.appearance.ts +1 -1
- package/components/Button/Button.stories.tsx +99 -18
- package/components/Checkbox/Checkbox.stories.tsx +107 -7
- package/components/DatePicker/DatePicker.styles.ts +1 -0
- package/components/DatePicker/DatePicker.tsx +9 -10
- package/components/IconButton/IconButton.sizes.ts +7 -7
- package/components/IconButton/IconButton.tsx +0 -1
- package/components/InputOpt/InputOpt.stories.tsx +30 -44
- package/components/Select/Select.stories.tsx +80 -19
- package/components/Select/Select.tsx +7 -9
- package/components/Table/Datatable.stories.tsx +186 -0
- package/components/Table/Table.stories.tsx +127 -46
- package/components/Table/Table.styles.ts +83 -8
- package/components/Table/Table.tsx +292 -142
- package/components/Table/Table.types.ts +104 -12
- package/components/Table/components/ColumnVisibility/ColumnVisibility.style.ts +48 -0
- package/components/Table/components/ColumnVisibility/ColumnVisibility.tsx +55 -0
- package/components/Table/components/DatatableColumnFilterMenu/DatatableColumnFilterMenu.styles.ts +121 -0
- package/components/Table/components/DatatableColumnFilterMenu/DatatableColumnFilterMenu.tsx +228 -0
- package/components/Table/components/DatatableColumnFilterMenu/index.ts +1 -0
- package/components/Table/components/DatatableTopBar/DatatableTopBar.styles.ts +25 -0
- package/components/Table/components/DatatableTopBar/DatatableTopBar.tsx +89 -0
- package/components/Table/components/DatatableTopBar/index.ts +1 -0
- package/components/Table/components/SearchInput/SearchInput.tsx +30 -0
- package/components/Table/components/TableHeader/TableHeader.tsx +98 -0
- package/components/Table/components/TablePagination/TablePagination.tsx +78 -0
- package/components/Table/components/index.ts +6 -0
- package/components/Table/hooks/useDatatableFilters.ts +88 -0
- package/components/Table/stories.fixtures.ts +100 -0
- package/components/Table/tanstack-table.d.ts +10 -0
- package/components/Table/utils/dateRangeFilterFn.ts +33 -0
- package/components/Table/utils/index.ts +2 -1
- package/components/Tabs/Tabs.stories.tsx +152 -0
- package/components/Tabs/Tabs.styles.ts +12 -0
- package/components/Tabs/Tabs.tsx +34 -0
- package/components/Tabs/Tabs.types.ts +15 -0
- package/components/Tabs/index.ts +2 -0
- package/components/TextField/TextField.stories.tsx +135 -12
- package/components/index.ts +3 -0
- package/package.json +1 -1
|
@@ -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: '
|
|
34
|
+
description: 'Variante visual do alerta',
|
|
35
|
+
table: { defaultValue: { summary: 'default' } },
|
|
16
36
|
},
|
|
17
37
|
title: {
|
|
18
38
|
control: 'text',
|
|
19
|
-
description: '
|
|
39
|
+
description: 'Título do alerta (obrigatório)',
|
|
20
40
|
},
|
|
21
41
|
description: {
|
|
22
42
|
control: 'text',
|
|
23
|
-
description: '
|
|
43
|
+
description: 'Descrição complementar do alerta',
|
|
24
44
|
},
|
|
25
45
|
hasButton: {
|
|
26
46
|
control: 'boolean',
|
|
27
|
-
description: '
|
|
47
|
+
description: 'Exibe botão de ação',
|
|
48
|
+
table: { defaultValue: { summary: 'false' } },
|
|
28
49
|
},
|
|
29
50
|
buttonLabel: {
|
|
30
51
|
control: 'text',
|
|
31
|
-
description: '
|
|
52
|
+
description: 'Texto do botão de ação',
|
|
32
53
|
},
|
|
33
54
|
href: {
|
|
34
55
|
control: 'text',
|
|
35
|
-
description: '
|
|
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
|
|
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:
|
|
46
|
-
<Alert variant="default" title="Default
|
|
47
|
-
<Alert variant="info" title="Info
|
|
48
|
-
<Alert variant="success" title="
|
|
49
|
-
<Alert variant="warning" title="
|
|
50
|
-
<Alert variant="danger" title="
|
|
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
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
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,285 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
|
+
import { CheckCircleIcon, ArrowRightIcon, WarningCircleIcon, XCircleIcon, InfoIcon } from '@phosphor-icons/react'
|
|
3
|
+
import Badge from './Badge'
|
|
4
|
+
import type { BadgeVariantTypes } from './Badge.types'
|
|
5
|
+
|
|
6
|
+
const variantOptions: BadgeVariantTypes[] = ['default', 'secondary', 'outline', 'danger', 'icon']
|
|
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
|
+
Badges são rótulos compactos usados para destacar status, categorias ou contagens.
|
|
17
|
+
|
|
18
|
+
**Quando usar:**
|
|
19
|
+
- \`default\` — status ativo, confirmado ou primário
|
|
20
|
+
- \`secondary\` — categorias secundárias ou tags neutras
|
|
21
|
+
- \`outline\` — destaque sutil sem peso visual
|
|
22
|
+
- \`danger\` — erros, alertas críticos ou itens removidos
|
|
23
|
+
- \`icon\` — quando o ícone reforça o significado do rótulo
|
|
24
|
+
|
|
25
|
+
**Boas práticas:**
|
|
26
|
+
- Mantenha o texto curto (1–2 palavras)
|
|
27
|
+
- Use ícones apenas quando agregam contexto
|
|
28
|
+
- Não use mais de 3 badges em sequência sem separação visual
|
|
29
|
+
`,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
tags: ['autodocs'],
|
|
34
|
+
argTypes: {
|
|
35
|
+
variant: {
|
|
36
|
+
control: 'select',
|
|
37
|
+
options: variantOptions,
|
|
38
|
+
description: 'Variante visual do badge',
|
|
39
|
+
table: {
|
|
40
|
+
defaultValue: { summary: 'default' },
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
children: {
|
|
44
|
+
control: 'text',
|
|
45
|
+
description: 'Texto exibido no badge',
|
|
46
|
+
table: {
|
|
47
|
+
defaultValue: { summary: 'Badge' },
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
showLeftIcon: {
|
|
51
|
+
control: 'boolean',
|
|
52
|
+
description: 'Exibe ícone à esquerda do texto',
|
|
53
|
+
table: {
|
|
54
|
+
defaultValue: { summary: 'false' },
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
showRightIcon: {
|
|
58
|
+
control: 'boolean',
|
|
59
|
+
description: 'Exibe ícone à direita do texto',
|
|
60
|
+
table: {
|
|
61
|
+
defaultValue: { summary: 'false' },
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
leftIcon: {
|
|
65
|
+
control: false,
|
|
66
|
+
description: 'Elemento React para o ícone esquerdo (ex: `<CheckCircleIcon />`)',
|
|
67
|
+
},
|
|
68
|
+
rightIcon: {
|
|
69
|
+
control: false,
|
|
70
|
+
description: 'Elemento React para o ícone direito (ex: `<ArrowRightIcon />`)',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export default meta
|
|
76
|
+
type Story = StoryObj<typeof meta>
|
|
77
|
+
|
|
78
|
+
// ─── Stories individuais por variante ────────────────────────────────────────
|
|
79
|
+
|
|
80
|
+
export const Default: Story = {
|
|
81
|
+
parameters: {
|
|
82
|
+
docs: {
|
|
83
|
+
description: { story: 'Variante principal. Use para status ativos, confirmados ou ações primárias.' },
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
args: {
|
|
87
|
+
children: 'Ativo',
|
|
88
|
+
variant: 'default',
|
|
89
|
+
},
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const Secondary: Story = {
|
|
93
|
+
parameters: {
|
|
94
|
+
docs: {
|
|
95
|
+
description: { story: 'Variante secundária (roxa). Use para categorias, tags ou classificações.' },
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
args: {
|
|
99
|
+
children: 'Categoria',
|
|
100
|
+
variant: 'secondary',
|
|
101
|
+
},
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export const Outline: Story = {
|
|
105
|
+
parameters: {
|
|
106
|
+
docs: {
|
|
107
|
+
description: { story: 'Variante com borda. Use quando precisar de destaque sutil sem peso visual.' },
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
args: {
|
|
111
|
+
children: 'Pendente',
|
|
112
|
+
variant: 'outline',
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export const Danger: Story = {
|
|
117
|
+
parameters: {
|
|
118
|
+
docs: {
|
|
119
|
+
description: { story: 'Variante de perigo. Use para erros, alertas críticos ou itens bloqueados.' },
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
args: {
|
|
123
|
+
children: 'Erro',
|
|
124
|
+
variant: 'danger',
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export const Icon: Story = {
|
|
129
|
+
parameters: {
|
|
130
|
+
docs: {
|
|
131
|
+
description: { story: 'Variante com ícone proeminente. Use quando o ícone reforça o significado.' },
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
args: {
|
|
135
|
+
children: 'Concluído',
|
|
136
|
+
variant: 'icon',
|
|
137
|
+
showLeftIcon: true,
|
|
138
|
+
leftIcon: <CheckCircleIcon size={16} />,
|
|
139
|
+
},
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ─── Combinações com ícones ───────────────────────────────────────────────────
|
|
143
|
+
|
|
144
|
+
export const ComLeftIcon: Story = {
|
|
145
|
+
name: 'Com ícone esquerdo',
|
|
146
|
+
parameters: {
|
|
147
|
+
docs: {
|
|
148
|
+
description: { story: 'Ícone à esquerda reforça o significado visual do badge.' },
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
args: {
|
|
152
|
+
children: 'Verificado',
|
|
153
|
+
variant: 'default',
|
|
154
|
+
showLeftIcon: true,
|
|
155
|
+
leftIcon: <CheckCircleIcon size={16} />,
|
|
156
|
+
},
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export const ComRightIcon: Story = {
|
|
160
|
+
name: 'Com ícone direito',
|
|
161
|
+
parameters: {
|
|
162
|
+
docs: {
|
|
163
|
+
description: { story: 'Ícone à direita indica ação ou navegação.' },
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
args: {
|
|
167
|
+
children: 'Ver mais',
|
|
168
|
+
variant: 'default',
|
|
169
|
+
showRightIcon: true,
|
|
170
|
+
rightIcon: <ArrowRightIcon size={16} />,
|
|
171
|
+
},
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export const ComAmbosIcones: Story = {
|
|
175
|
+
name: 'Com ambos os ícones',
|
|
176
|
+
parameters: {
|
|
177
|
+
docs: {
|
|
178
|
+
description: { story: 'Use com moderação — apenas quando ambos os ícones agregam contexto.' },
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
args: {
|
|
182
|
+
children: 'Badge',
|
|
183
|
+
variant: 'default',
|
|
184
|
+
showLeftIcon: true,
|
|
185
|
+
showRightIcon: true,
|
|
186
|
+
leftIcon: <CheckCircleIcon size={16} />,
|
|
187
|
+
rightIcon: <ArrowRightIcon size={16} />,
|
|
188
|
+
},
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// ─── Todas as variantes ───────────────────────────────────────────────────────
|
|
192
|
+
|
|
193
|
+
export const TodasVariantes: Story = {
|
|
194
|
+
name: 'Todas as variantes',
|
|
195
|
+
parameters: {
|
|
196
|
+
docs: {
|
|
197
|
+
description: { story: 'Visão geral de todas as variantes disponíveis lado a lado.' },
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
render: () => (
|
|
201
|
+
<div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
|
|
202
|
+
<Badge variant="default">Default</Badge>
|
|
203
|
+
<Badge variant="secondary">Secondary</Badge>
|
|
204
|
+
<Badge variant="outline">Outline</Badge>
|
|
205
|
+
<Badge variant="danger">Danger</Badge>
|
|
206
|
+
<Badge variant="icon" showLeftIcon leftIcon={<CheckCircleIcon size={16} />}>Icon</Badge>
|
|
207
|
+
</div>
|
|
208
|
+
),
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ─── Exemplos de uso real ─────────────────────────────────────────────────────
|
|
212
|
+
|
|
213
|
+
export const StatusDePedido: Story = {
|
|
214
|
+
name: 'Exemplo: Status de pedido',
|
|
215
|
+
parameters: {
|
|
216
|
+
docs: {
|
|
217
|
+
description: { story: 'Badges aplicados a diferentes estados de um pedido em uma listagem.' },
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
render: () => (
|
|
221
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 12, fontFamily: 'Manrope, sans-serif' }}>
|
|
222
|
+
{[
|
|
223
|
+
{ id: '#1042', status: 'Aprovado', variant: 'default' as BadgeVariantTypes, icon: <CheckCircleIcon size={16} /> },
|
|
224
|
+
{ id: '#1043', status: 'Pendente', variant: 'outline' as BadgeVariantTypes, icon: null },
|
|
225
|
+
{ id: '#1044', status: 'Cancelado', variant: 'danger' as BadgeVariantTypes, icon: <XCircleIcon size={16} /> },
|
|
226
|
+
{ id: '#1045', status: 'Em análise', variant: 'secondary' as BadgeVariantTypes, icon: <InfoIcon size={16} /> },
|
|
227
|
+
{ id: '#1046', status: 'Alerta', variant: 'danger' as BadgeVariantTypes, icon: <WarningCircleIcon size={16} /> },
|
|
228
|
+
].map(({ id, status, variant, icon }) => (
|
|
229
|
+
<div key={id} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '8px 12px', border: '1px solid #e5e7eb', borderRadius: 6, width: 280 }}>
|
|
230
|
+
<span style={{ fontSize: 14, color: '#374151' }}>Pedido {id}</span>
|
|
231
|
+
<Badge variant={variant} showLeftIcon={!!icon} leftIcon={icon ?? undefined}>{status}</Badge>
|
|
232
|
+
</div>
|
|
233
|
+
))}
|
|
234
|
+
</div>
|
|
235
|
+
),
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export const TagsDeCategoria: Story = {
|
|
239
|
+
name: 'Exemplo: Tags de categoria',
|
|
240
|
+
parameters: {
|
|
241
|
+
docs: {
|
|
242
|
+
description: { story: 'Badges como tags de categorias em um card de produto ou artigo.' },
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
render: () => (
|
|
246
|
+
<div style={{ padding: 16, border: '1px solid #e5e7eb', borderRadius: 8, width: 320, fontFamily: 'Manrope, sans-serif' }}>
|
|
247
|
+
<div style={{ fontSize: 16, fontWeight: 600, marginBottom: 8, color: '#111827' }}>
|
|
248
|
+
Introdução ao Design System
|
|
249
|
+
</div>
|
|
250
|
+
<div style={{ fontSize: 13, color: '#6b7280', marginBottom: 12 }}>
|
|
251
|
+
Aprenda os fundamentos de um design system escalável.
|
|
252
|
+
</div>
|
|
253
|
+
<div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
|
|
254
|
+
<Badge variant="secondary">Design</Badge>
|
|
255
|
+
<Badge variant="secondary">Frontend</Badge>
|
|
256
|
+
<Badge variant="outline">Iniciante</Badge>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
),
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export const NotificacaoComContador: Story = {
|
|
263
|
+
name: 'Exemplo: Notificação com contador',
|
|
264
|
+
parameters: {
|
|
265
|
+
docs: {
|
|
266
|
+
description: { story: 'Badge usado para indicar contagem de notificações ou itens pendentes.' },
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
render: () => (
|
|
270
|
+
<div style={{ display: 'flex', gap: 16, alignItems: 'center', fontFamily: 'Manrope, sans-serif' }}>
|
|
271
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
|
272
|
+
<span style={{ fontSize: 14, color: '#374151' }}>Mensagens</span>
|
|
273
|
+
<Badge variant="danger">3</Badge>
|
|
274
|
+
</div>
|
|
275
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
|
276
|
+
<span style={{ fontSize: 14, color: '#374151' }}>Tarefas</span>
|
|
277
|
+
<Badge variant="default">12</Badge>
|
|
278
|
+
</div>
|
|
279
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
|
280
|
+
<span style={{ fontSize: 14, color: '#374151' }}>Revisões</span>
|
|
281
|
+
<Badge variant="outline">5</Badge>
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
),
|
|
285
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import styled from 'styled-components'
|
|
2
|
+
import { spacing, fontSize, fontWeight, lineHeight, radius } from '@liguelead/foundation'
|
|
3
|
+
|
|
4
|
+
export const StyledBadge = styled.span<{ $variant: string }>`
|
|
5
|
+
display: inline-flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
gap: ${spacing.spacing4}px;
|
|
9
|
+
padding: ${spacing.spacing2}px ${spacing.spacing8}px;
|
|
10
|
+
border-radius: ${radius.radius4}px;
|
|
11
|
+
font-size: ${fontSize.fontSize12}px;
|
|
12
|
+
font-weight: ${fontWeight.fontWeight500};
|
|
13
|
+
line-height: ${lineHeight.lineHeight16}px;
|
|
14
|
+
font-family: Manrope, sans-serif;
|
|
15
|
+
white-space: nowrap;
|
|
16
|
+
|
|
17
|
+
${({ $variant }) => $variant}
|
|
18
|
+
|
|
19
|
+
& svg {
|
|
20
|
+
width: 16px;
|
|
21
|
+
height: 16px;
|
|
22
|
+
flex-shrink: 0;
|
|
23
|
+
}
|
|
24
|
+
`
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { StyledBadge } from './Badge.styles'
|
|
2
|
+
import { BadgeVariant } from './Badge.variants'
|
|
3
|
+
import { TBadgeProps } from './Badge.types'
|
|
4
|
+
|
|
5
|
+
const Badge = ({
|
|
6
|
+
children = 'Badge',
|
|
7
|
+
className,
|
|
8
|
+
variant = 'default',
|
|
9
|
+
leftIcon,
|
|
10
|
+
rightIcon,
|
|
11
|
+
showLeftIcon = false,
|
|
12
|
+
showRightIcon = false,
|
|
13
|
+
}: TBadgeProps) => {
|
|
14
|
+
const badgeVariant = BadgeVariant(variant)
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<StyledBadge $variant={badgeVariant} className={className}>
|
|
18
|
+
{showLeftIcon && leftIcon}
|
|
19
|
+
{children}
|
|
20
|
+
{showRightIcon && rightIcon}
|
|
21
|
+
</StyledBadge>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default Badge
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type BadgeVariantTypes = 'default' | 'secondary' | 'outline' | 'danger' | 'icon'
|
|
2
|
+
|
|
3
|
+
export type TBadgeProps = {
|
|
4
|
+
children?: React.ReactNode
|
|
5
|
+
className?: string
|
|
6
|
+
variant?: BadgeVariantTypes
|
|
7
|
+
leftIcon?: React.ReactNode
|
|
8
|
+
rightIcon?: React.ReactNode
|
|
9
|
+
showLeftIcon?: boolean
|
|
10
|
+
showRightIcon?: boolean
|
|
11
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useTheme } from 'styled-components'
|
|
2
|
+
import { parseColor } from '../../utils'
|
|
3
|
+
import { BadgeVariantTypes } from './Badge.types'
|
|
4
|
+
|
|
5
|
+
export const BadgeVariant = (variant: BadgeVariantTypes) => {
|
|
6
|
+
const theme = useTheme()
|
|
7
|
+
|
|
8
|
+
const variants: Record<BadgeVariantTypes, string> = {
|
|
9
|
+
default: `
|
|
10
|
+
background-color: ${parseColor(theme.colors.primary)};
|
|
11
|
+
color: ${parseColor(theme.colors.textLight)};
|
|
12
|
+
border: 1px solid transparent;
|
|
13
|
+
`,
|
|
14
|
+
secondary: `
|
|
15
|
+
background-color: ${parseColor(theme.colors.secondary)};
|
|
16
|
+
color: ${parseColor(theme.colors.textLight)};
|
|
17
|
+
border: 1px solid transparent;
|
|
18
|
+
`,
|
|
19
|
+
outline: `
|
|
20
|
+
background-color: transparent;
|
|
21
|
+
color: ${parseColor(theme.colors.primary)};
|
|
22
|
+
border: 1px solid ${parseColor(theme.colors.primary)};
|
|
23
|
+
`,
|
|
24
|
+
danger: `
|
|
25
|
+
background-color: ${parseColor(theme.colors.danger200)};
|
|
26
|
+
color: ${parseColor(theme.colors.textLight)};
|
|
27
|
+
border: 1px solid transparent;
|
|
28
|
+
`,
|
|
29
|
+
icon: `
|
|
30
|
+
background-color: ${parseColor(theme.colors.secondary)};
|
|
31
|
+
color: ${parseColor(theme.colors.textLight)};
|
|
32
|
+
border: 1px solid transparent;
|
|
33
|
+
`,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return variants[variant]
|
|
37
|
+
}
|
|
@@ -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.
|
|
78
|
+
border: 1px solid ${parseColor(theme.colors.neutral400)};
|
|
79
79
|
|
|
80
80
|
&:hover {
|
|
81
81
|
background-color: ${parseColor(theme.colors.primaryDarker)};
|