kaizen-lib 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -1
- package/package.json +1 -1
- package/src/ui/Badge.tsx +77 -0
- package/src/ui/index.ts +2 -0
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ styled-components con `moduleResolution: "bundler"`, así que lo transpilan ello
|
|
|
12
12
|
|---|---|---|
|
|
13
13
|
| `kaizen-lib/tokens` | Referencias `var(--kz-*)` tipadas | listo |
|
|
14
14
|
| `kaizen-lib/tokens.css` | Valores por defecto, tema oscuro y claro | listo |
|
|
15
|
-
| `kaizen-lib/ui` | Componentes (`IconButton`, `ReactionButton`, `Medidor`, `Relieve`, `LangSelector`, `Modal`) | en curso |
|
|
15
|
+
| `kaizen-lib/ui` | Componentes (`IconButton`, `ReactionButton`, `Medidor`, `Relieve`, `LangSelector`, `Modal`, `Badge`) | en curso |
|
|
16
16
|
|
|
17
17
|
## ¿Qué uso para qué?
|
|
18
18
|
|
|
@@ -30,6 +30,7 @@ alcanza, extendé el componente en vez de bypassearlo (ver `implement.md` del ha
|
|
|
30
30
|
| Un ciclador de idioma con banderas en la topbar | `LangSelector` | reconstruir el ciclado a mano — ya lo resuelve, con `Relieve` incluido |
|
|
31
31
|
| Un panel flotante que bloquea el resto de la página hasta que se resuelve (formulario, confirmación, contenido a pantalla completa) | `Modal` | un overlay propio — portal, foco atrapado, `Escape`, scroll bloqueado y anidamiento ya están resueltos ahí |
|
|
32
32
|
| Un arco/medidor que muestra cuánto de un total está ocupado | `Medidor` | un `<progress>` o una barra propia |
|
|
33
|
+
| Una píldora de estado (activo, vencido, un rol, una etiqueta) con fondo lavado y texto del mismo tono | `Badge` | un `styled.span` propio por producto — es exactamente lo que ya había triplicado |
|
|
33
34
|
| Espaciado, radios, color, tipografía, sombra | `kaizen-lib/tokens` (`space`, `radius`, `fg`, `accent`, `font`, `shadow`, `relief`...) | un valor a mano — cada uno es una referencia `var(--kz-*)` |
|
|
34
35
|
|
|
35
36
|
Ningún componente trae íconos ni banderas: los recibe como `children`/`icono`, y el
|
|
@@ -250,6 +251,20 @@ Lo que **no** trae: un `placement` lateral (drawer) y un padding compacto de cue
|
|
|
250
251
|
casos de un solo consumidor cada uno (`components/ui/Dialog` de valle-verde) — se resuelven
|
|
251
252
|
ahí con un wrapper local hasta que un segundo consumidor los pida acá.
|
|
252
253
|
|
|
254
|
+
```tsx
|
|
255
|
+
import { Badge } from 'kaizen-lib/ui';
|
|
256
|
+
|
|
257
|
+
<Badge tone="success">Activo</Badge>
|
|
258
|
+
<Badge tone="danger" bordered>Vencido</Badge>
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**`Badge`** es una píldora de estado: fondo lavado + texto del mismo tono (`neutral` |
|
|
262
|
+
`accent` | `success` | `danger` | `warning` | `info`, default `neutral`), mayúsculas
|
|
263
|
+
apretadas. Elicitado de tres implementaciones ya duplicadas (taboo-next, valle-verde,
|
|
264
|
+
kaizen-next) — el look es el de valle-verde. `bordered` agrega un borde de 1px del color
|
|
265
|
+
pleno del tono, para cuando el fondo lavado solo no alcanza de contraste contra la
|
|
266
|
+
superficie de atrás; no es una segunda estética, es el mismo tono con más peso.
|
|
267
|
+
|
|
253
268
|
## Desarrollo
|
|
254
269
|
|
|
255
270
|
```bash
|
package/package.json
CHANGED
package/src/ui/Badge.tsx
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
4
|
+
import styled from 'styled-components';
|
|
5
|
+
import { accent, danger, fg, font, info, radius, space, success, surface, warning } from '../tokens';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* El tono resuelve un TRÍO por tabla: fondo lavado, texto y el color pleno
|
|
9
|
+
* (para `bordered`) — así no puede salir una píldora con el texto invisible
|
|
10
|
+
* sobre su propio fondo, ni un borde que no combina con ninguno de los dos.
|
|
11
|
+
*/
|
|
12
|
+
export type BadgeTone = 'neutral' | 'accent' | 'success' | 'danger' | 'warning' | 'info';
|
|
13
|
+
|
|
14
|
+
const TONOS: Record<BadgeTone, { fondo: string; texto: string; pleno: string }> = {
|
|
15
|
+
neutral: { fondo: surface.hover, texto: fg.muted, pleno: fg.muted },
|
|
16
|
+
accent: { fondo: accent.soft, texto: accent.fg, pleno: accent.DEFAULT },
|
|
17
|
+
success: { fondo: success.soft, texto: success.fg, pleno: success.DEFAULT },
|
|
18
|
+
danger: { fondo: danger.soft, texto: danger.fg, pleno: danger.DEFAULT },
|
|
19
|
+
warning: { fondo: warning.soft, texto: warning.fg, pleno: warning.DEFAULT },
|
|
20
|
+
info: { fondo: info.soft, texto: info.fg, pleno: info.DEFAULT },
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type Props = {
|
|
24
|
+
tone?: BadgeTone;
|
|
25
|
+
/** Borde de 1px del color pleno del tono. Para una píldora que necesita más peso que el fondo lavado solo. */
|
|
26
|
+
bordered?: boolean;
|
|
27
|
+
children: ReactNode;
|
|
28
|
+
className?: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const Raiz = styled.span<{ $tone: BadgeTone; $bordered: boolean }>`
|
|
32
|
+
display: inline-flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
gap: ${space[1]};
|
|
35
|
+
padding: 3px ${space[2]};
|
|
36
|
+
border-radius: ${radius.sm};
|
|
37
|
+
border: 1px solid ${({ $tone, $bordered }) => ($bordered ? TONOS[$tone].pleno : 'transparent')};
|
|
38
|
+
font-size: ${font.xs};
|
|
39
|
+
font-weight: 600;
|
|
40
|
+
line-height: 1.35;
|
|
41
|
+
letter-spacing: 0.04em;
|
|
42
|
+
text-transform: uppercase;
|
|
43
|
+
white-space: nowrap;
|
|
44
|
+
background: ${({ $tone }) => TONOS[$tone].fondo};
|
|
45
|
+
color: ${({ $tone }) => TONOS[$tone].texto};
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Píldora de estado: fondo lavado + texto del mismo tono, mayúsculas
|
|
50
|
+
* apretadas. Elicitado de las implementaciones ya duplicadas en tres
|
|
51
|
+
* productos (taboo-next, valle-verde, kaizen-next) — el look es el de
|
|
52
|
+
* valle-verde, que era el más resuelto de los tres.
|
|
53
|
+
*
|
|
54
|
+
* ```tsx
|
|
55
|
+
* <Badge tone="success">Activo</Badge>
|
|
56
|
+
* <Badge tone="danger" bordered>Vencido</Badge>
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* `bordered` es opcional: el fondo lavado solo ya es suficiente contraste
|
|
60
|
+
* para la mayoría de los casos (ver `bordered={false}`, el default). Se usa
|
|
61
|
+
* cuando la píldora flota sobre una superficie parecida a su propio fondo y
|
|
62
|
+
* necesita un borde para no perderse — no es una segunda variante estética,
|
|
63
|
+
* es el mismo tono con más peso.
|
|
64
|
+
*/
|
|
65
|
+
export function Badge({
|
|
66
|
+
tone = 'neutral',
|
|
67
|
+
bordered = false,
|
|
68
|
+
children,
|
|
69
|
+
className,
|
|
70
|
+
...rest
|
|
71
|
+
}: Props & Omit<HTMLAttributes<HTMLSpanElement>, keyof Props>) {
|
|
72
|
+
return (
|
|
73
|
+
<Raiz $tone={tone} $bordered={bordered} className={className} {...rest}>
|
|
74
|
+
{children}
|
|
75
|
+
</Raiz>
|
|
76
|
+
);
|
|
77
|
+
}
|
package/src/ui/index.ts
CHANGED