@liguelead/design-system 0.0.31 → 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.
@@ -1,285 +1,114 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
- import { CheckCircleIcon, ArrowRightIcon, WarningCircleIcon, XCircleIcon, InfoIcon } from '@phosphor-icons/react'
2
+ import { CheckCircleIcon, ArrowRightIcon, XCircleIcon, InfoIcon, WarningCircleIcon } from '@phosphor-icons/react'
3
+ import { themes } from '@liguelead/foundation'
3
4
  import Badge from './Badge'
4
- import type { BadgeVariantTypes } from './Badge.types'
5
5
 
6
- const variantOptions: BadgeVariantTypes[] = ['default', 'secondary', 'outline', 'danger', 'icon']
6
+ const colorOptions = Object.keys(themes.spa.colors)
7
7
 
8
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
- },
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 },
56
50
  },
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
51
  }
74
52
 
75
53
  export default meta
76
54
  type Story = StoryObj<typeof meta>
77
55
 
78
- // ─── Stories individuais por variante ────────────────────────────────────────
79
-
80
56
  export const Default: Story = {
81
- parameters: {
82
- docs: {
83
- description: { story: 'Variante principal. Use para status ativos, confirmados ou ações primárias.' },
57
+ args: {
58
+ children: 'Ativo',
59
+ color: 'success50',
84
60
  },
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
61
  }
115
62
 
116
63
  export const Danger: Story = {
117
- parameters: {
118
- docs: {
119
- description: { story: 'Variante de perigo. Use para erros, alertas críticos ou itens bloqueados.' },
64
+ args: {
65
+ children: 'Erro',
66
+ color: 'danger50',
120
67
  },
121
- },
122
- args: {
123
- children: 'Erro',
124
- variant: 'danger',
125
- },
126
68
  }
127
69
 
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.' },
70
+ export const Secondary: Story = {
71
+ args: {
72
+ children: 'Categoria',
73
+ color: 'warning50',
164
74
  },
165
- },
166
- args: {
167
- children: 'Ver mais',
168
- variant: 'default',
169
- showRightIcon: true,
170
- rightIcon: <ArrowRightIcon size={16} />,
171
- },
172
75
  }
173
76
 
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.' },
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} />,
179
84
  },
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
85
  }
190
86
 
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.' },
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} />,
198
94
  },
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
95
  }
210
96
 
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>
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
+ ))}
232
112
  </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
- ),
113
+ ),
285
114
  }
@@ -1,7 +1,17 @@
1
- import styled from 'styled-components'
1
+ import styled, { DefaultTheme } from 'styled-components'
2
2
  import { spacing, fontSize, fontWeight, lineHeight, radius } from '@liguelead/foundation'
3
+ import { getTextColor, parseColor } from '../../utils'
4
+ import { colorType } from '../../types'
3
5
 
4
- export const StyledBadge = styled.span<{ $variant: string }>`
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 }>`
5
15
  display: inline-flex;
6
16
  align-items: center;
7
17
  justify-content: center;
@@ -14,7 +24,9 @@ export const StyledBadge = styled.span<{ $variant: string }>`
14
24
  font-family: Manrope, sans-serif;
15
25
  white-space: nowrap;
16
26
 
17
- ${({ $variant }) => $variant}
27
+ background-color: ${({ theme, $color }) => getBadgeColors(theme, $color).background};
28
+
29
+ color: ${({ theme, $color }) => getBadgeColors(theme, $color).text};
18
30
 
19
31
  & svg {
20
32
  width: 16px;
@@ -1,20 +1,18 @@
1
1
  import { StyledBadge } from './Badge.styles'
2
- import { BadgeVariant } from './Badge.variants'
3
2
  import { TBadgeProps } from './Badge.types'
4
3
 
5
4
  const Badge = ({
6
5
  children = 'Badge',
7
6
  className,
8
- variant = 'default',
7
+ color = 'primary',
9
8
  leftIcon,
10
9
  rightIcon,
11
10
  showLeftIcon = false,
12
11
  showRightIcon = false,
13
12
  }: TBadgeProps) => {
14
- const badgeVariant = BadgeVariant(variant)
15
13
 
16
14
  return (
17
- <StyledBadge $variant={badgeVariant} className={className}>
15
+ <StyledBadge $color={color} className={className}>
18
16
  {showLeftIcon && leftIcon}
19
17
  {children}
20
18
  {showRightIcon && rightIcon}
@@ -1,11 +1,11 @@
1
- export type BadgeVariantTypes = 'default' | 'secondary' | 'outline' | 'danger' | 'icon'
1
+ import { colorType } from "../../types"
2
2
 
3
3
  export type TBadgeProps = {
4
4
  children?: React.ReactNode
5
5
  className?: string
6
- variant?: BadgeVariantTypes
7
6
  leftIcon?: React.ReactNode
8
7
  rightIcon?: React.ReactNode
9
8
  showLeftIcon?: boolean
10
9
  showRightIcon?: boolean
10
+ color?: colorType
11
11
  }
@@ -1,2 +1,2 @@
1
1
  export { default as Badge } from './Badge'
2
- export type { TBadgeProps, BadgeVariantTypes } from './Badge.types'
2
+ export type { TBadgeProps } from './Badge.types'
@@ -17,8 +17,6 @@ export const PopoverWrapper = style.div`
17
17
  border: 1px solid ${({ theme }) => parseColor(theme.colors.neutral200)};
18
18
  border-radius: 4px;
19
19
  padding: 8px;
20
-
21
- // Adicionar essa shadow no nosso thema
22
20
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.10), 0 2px 4px -2px rgba(0, 0, 0, 0.10);
23
21
  `;
24
22
 
@@ -115,7 +115,6 @@ export const StyledTextInput = styled.input`
115
115
 
116
116
  export const ClearFilterButtonWrapper = styled.span`
117
117
  display: flex;
118
- flex: 1;
119
118
  align-items: center;
120
119
  justify-content: end;
121
120
  `
@@ -1,6 +1,6 @@
1
1
  export { default as Alert } from './Alert'
2
2
  export { Badge } from './Badge'
3
- export type { TBadgeProps, BadgeVariantTypes } from './Badge'
3
+ export type { TBadgeProps } from './Badge'
4
4
  export { default as Button } from './Button'
5
5
  export { default as Checkbox } from './Checkbox'
6
6
  export { default as DatePicker } from './DatePicker'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liguelead/design-system",
3
- "version": "0.0.31",
3
+ "version": "0.0.32",
4
4
  "type": "module",
5
5
  "main": "components/index.ts",
6
6
  "publishConfig": {
@@ -24,7 +24,8 @@
24
24
  "react-datepicker": "^7.6.0",
25
25
  "react-toastify": "^11.0.5",
26
26
  "cmdk": "^1.1.1",
27
- "date-fns": "^2.30.0"
27
+ "date-fns": "^2.30.0",
28
+ "@tanstack/react-table": "^8.0.0"
28
29
  },
29
30
  "scripts": {
30
31
  "lint": "eslint ."
@@ -1,37 +0,0 @@
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
- }