@gob-ds/gob-ds 1.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.
- package/.editorconfig +17 -0
- package/.storybook/main.ts +19 -0
- package/.storybook/preview.ts +18 -0
- package/.storybook/tsconfig.doc.json +10 -0
- package/.storybook/tsconfig.json +11 -0
- package/.storybook/typings.d.ts +4 -0
- package/.vscode/extensions.json +4 -0
- package/.vscode/launch.json +20 -0
- package/.vscode/mcp.json +9 -0
- package/.vscode/tasks.json +42 -0
- package/README.md +0 -0
- package/angular.json +113 -0
- package/documentation.json +1472 -0
- package/package.json +65 -0
- package/public/favicon.ico +0 -0
- package/src/app/app.config.server.ts +12 -0
- package/src/app/app.config.ts +12 -0
- package/src/app/app.html +342 -0
- package/src/app/app.routes.server.ts +8 -0
- package/src/app/app.routes.ts +3 -0
- package/src/app/app.scss +0 -0
- package/src/app/app.spec.ts +23 -0
- package/src/app/app.ts +12 -0
- package/src/app/lib/alert-dialog/alert-dialog.component.html +35 -0
- package/src/app/lib/alert-dialog/alert-dialog.component.scss +94 -0
- package/src/app/lib/alert-dialog/alert-dialog.component.ts +144 -0
- package/src/app/lib/badge/badge.component.ts +25 -0
- package/src/app/lib/badge/badge.scss +50 -0
- package/src/app/lib/button/button.component.html +35 -0
- package/src/app/lib/button/button.component.scss +226 -0
- package/src/app/lib/button/button.component.ts +70 -0
- package/src/app/lib/checkbox/checkbox.component.html +34 -0
- package/src/app/lib/checkbox/checkbox.component.scss +80 -0
- package/src/app/lib/checkbox/checkbox.component.ts +84 -0
- package/src/app/lib/input/input.component.html +43 -0
- package/src/app/lib/input/input.component.scss +181 -0
- package/src/app/lib/input/input.component.ts +87 -0
- package/src/app/lib/search/search.component.html +30 -0
- package/src/app/lib/search/search.component.scss +102 -0
- package/src/app/lib/search/search.component.ts +73 -0
- package/src/index.html +13 -0
- package/src/main.server.ts +8 -0
- package/src/main.ts +6 -0
- package/src/server.ts +68 -0
- package/src/stories/Configure.mdx +364 -0
- package/src/stories/assets/accessibility.png +0 -0
- package/src/stories/assets/accessibility.svg +1 -0
- package/src/stories/assets/addon-library.png +0 -0
- package/src/stories/assets/assets.png +0 -0
- package/src/stories/assets/avif-test-image.avif +0 -0
- package/src/stories/assets/context.png +0 -0
- package/src/stories/assets/discord.svg +1 -0
- package/src/stories/assets/docs.png +0 -0
- package/src/stories/assets/figma-plugin.png +0 -0
- package/src/stories/assets/github.svg +1 -0
- package/src/stories/assets/share.png +0 -0
- package/src/stories/assets/styling.png +0 -0
- package/src/stories/assets/testing.png +0 -0
- package/src/stories/assets/theming.png +0 -0
- package/src/stories/assets/tutorials.svg +1 -0
- package/src/stories/assets/youtube.svg +1 -0
- package/src/stories/components/alert-dialog.stories.ts +60 -0
- package/src/stories/components/badge.stories.ts +111 -0
- package/src/stories/components/button.stories.ts +329 -0
- package/src/stories/components/checkbox.stories.ts +102 -0
- package/src/stories/components/input.stories.ts +100 -0
- package/src/stories/components/search.stories.ts +81 -0
- package/src/stories/user.ts +3 -0
- package/src/styles.scss +14 -0
- package/src/tokens/stories/borders.stories.ts +118 -0
- package/src/tokens/stories/colors.stories.ts +90 -0
- package/src/tokens/stories/shadows.stories.ts +93 -0
- package/src/tokens/stories/spacing.stories.ts +55 -0
- package/src/tokens/stories/typography.stories.ts +76 -0
- package/src/tokens/styles/_borders.scss +16 -0
- package/src/tokens/styles/_colors.scss +76 -0
- package/src/tokens/styles/_shadows.scss +9 -0
- package/src/tokens/styles/_spacing.scss +17 -0
- package/src/tokens/styles/_typography.scss +34 -0
- package/src/tokens/styles/tokens.scss +5 -0
- package/src/tokens/tokens.ts +42 -0
- package/tsconfig.app.json +17 -0
- package/tsconfig.json +33 -0
- package/tsconfig.spec.json +15 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
2
|
+
import { Component } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
const radiusScale = [
|
|
5
|
+
{ token: '--radius-none', value: '0', px: '0px', label: 'None', usage: 'Tablas, layouts' },
|
|
6
|
+
{ token: '--radius-sm', value: '0.125rem', px: '2px', label: 'SM', usage: 'Badges, tags pequeños' },
|
|
7
|
+
{ token: '--radius-md', value: '0.375rem', px: '6px', label: 'MD', usage: 'Inputs, botones' },
|
|
8
|
+
{ token: '--radius-lg', value: '0.5rem', px: '8px', label: 'LG', usage: 'Cards, panels' },
|
|
9
|
+
{ token: '--radius-xl', value: '0.75rem', px: '12px', label: 'XL', usage: 'Modals, drawers' },
|
|
10
|
+
{ token: '--radius-2xl', value: '1rem', px: '16px', label: '2XL', usage: 'Contenedores grandes' },
|
|
11
|
+
{ token: '--radius-full', value: '9999px', px: '9999px', label: 'Full', usage: 'Pills, avatares, toggles' },
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
const borderWidths = [
|
|
15
|
+
{ token: '--border-width-thin', value: '1px', label: 'Thin', usage: 'Bordes por defecto, dividers' },
|
|
16
|
+
{ token: '--border-width-medium', value: '2px', label: 'Medium', usage: 'Focus rings, selected states' },
|
|
17
|
+
{ token: '--border-width-thick', value: '4px', label: 'Thick', usage: 'Acentos, indicadores activos' },
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const borderColors = [
|
|
21
|
+
{ token: '--color-border', value: '#E5E7EB', label: 'Default', textDark: true },
|
|
22
|
+
{ token: '--color-border-focused', value: '#3B82F6', label: 'Focused' },
|
|
23
|
+
{ token: '--color-danger', value: '#EF4444', label: 'Danger' },
|
|
24
|
+
{ token: '--color-success', value: '#22C55E', label: 'Success' },
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
@Component({
|
|
28
|
+
standalone: true,
|
|
29
|
+
selector: 'story-borders',
|
|
30
|
+
template: `
|
|
31
|
+
<div style="padding: 32px; font-family: sans-serif; min-height: 100vh;">
|
|
32
|
+
<h1 style="font-size: 28px; font-weight: 700; margin: 0 0 8px; color: #111827;">⬜ Border Tokens</h1>
|
|
33
|
+
<p style="color: #6B7280; margin: 0 0 48px;">
|
|
34
|
+
Radios, grosores y colores de borde del sistema.
|
|
35
|
+
</p>
|
|
36
|
+
|
|
37
|
+
<!-- Border Radius -->
|
|
38
|
+
<h2 style="font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: #9CA3AF; margin: 0 0 24px;">
|
|
39
|
+
Border Radius
|
|
40
|
+
</h2>
|
|
41
|
+
<div style="display: flex; flex-wrap: wrap; gap: 24px; margin-bottom: 56px; align-items: flex-end;">
|
|
42
|
+
@for (item of radiusScale; track item.token) {
|
|
43
|
+
<div style="display: flex; flex-direction: column; align-items: center; gap: 12px;">
|
|
44
|
+
<div
|
|
45
|
+
[style.border-radius]="item.value"
|
|
46
|
+
style="width: 80px; height: 80px; background: #3B82F6; opacity: 0.15; border: 2px solid #3B82F6;">
|
|
47
|
+
</div>
|
|
48
|
+
<div style="text-align: center;">
|
|
49
|
+
<div style="font-size: 12px; font-weight: 600; color: #374151;">{{ item.label }}</div>
|
|
50
|
+
<div style="font-size: 11px; color: #9CA3AF;">{{ item.px }}</div>
|
|
51
|
+
<div style="font-size: 10px; color: #D1D5DB; margin-top: 2px; max-width: 90px;">{{ item.usage }}</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
}
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<!-- Border Widths -->
|
|
58
|
+
<h2 style="font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: #9CA3AF; margin: 0 0 24px;">
|
|
59
|
+
Border Width
|
|
60
|
+
</h2>
|
|
61
|
+
<div style="display: flex; flex-direction: column; gap: 16px; margin-bottom: 56px;">
|
|
62
|
+
@for (item of borderWidths; track item.token) {
|
|
63
|
+
<div style="display: flex; align-items: center; gap: 24px; padding-bottom: 16px; border-bottom: 1px solid #F3F4F6;">
|
|
64
|
+
<div style="width: 200px; flex-shrink: 0;">
|
|
65
|
+
<div style="font-size: 12px; font-weight: 500; color: #374151;">{{ item.token }}</div>
|
|
66
|
+
<div style="font-size: 11px; color: #9CA3AF; margin-top: 2px;">{{ item.value }} · {{ item.usage }}</div>
|
|
67
|
+
</div>
|
|
68
|
+
<div
|
|
69
|
+
style="flex: 1; max-width: 320px; height: 40px; border-radius: 8px; background: #F9FAFB;"
|
|
70
|
+
[style.border]="item.value + ' solid #3B82F6'">
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
}
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<!-- Border Colors -->
|
|
77
|
+
<h2 style="font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: #9CA3AF; margin: 0 0 24px;">
|
|
78
|
+
Border Colors
|
|
79
|
+
</h2>
|
|
80
|
+
<div style="display: flex; flex-wrap: wrap; gap: 16px;">
|
|
81
|
+
@for (item of borderColors; track item.token) {
|
|
82
|
+
<div style="display: flex; flex-direction: column; gap: 10px; width: 160px;">
|
|
83
|
+
<div
|
|
84
|
+
style="height: 64px; border-radius: 8px; background: #F9FAFB; border: 2px solid;"
|
|
85
|
+
[style.border-color]="item.value">
|
|
86
|
+
</div>
|
|
87
|
+
<div>
|
|
88
|
+
<div style="font-size: 12px; font-weight: 600; color: #374151;">{{ item.label }}</div>
|
|
89
|
+
<div style="font-size: 11px; color: #9CA3AF;">{{ item.token }}</div>
|
|
90
|
+
<div
|
|
91
|
+
style="display: inline-block; font-size: 10px; padding: 2px 6px; border-radius: 4px; margin-top: 4px; font-weight: 500;"
|
|
92
|
+
[style.background]="item.value"
|
|
93
|
+
[style.color]="item.textDark ? '#111827' : '#ffffff'">
|
|
94
|
+
{{ item.value }}
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
}
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
`,
|
|
102
|
+
})
|
|
103
|
+
class BordersDocComponent {
|
|
104
|
+
radiusScale = radiusScale;
|
|
105
|
+
borderWidths = borderWidths;
|
|
106
|
+
borderColors = borderColors;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const meta: Meta<BordersDocComponent> = {
|
|
110
|
+
title: 'Tokens/Borders',
|
|
111
|
+
component: BordersDocComponent,
|
|
112
|
+
parameters: { layout: 'fullscreen' },
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export default meta;
|
|
116
|
+
type Story = StoryObj<BordersDocComponent>;
|
|
117
|
+
|
|
118
|
+
export const Estilos: Story = {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
2
|
+
import { Component } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
const colorGroups = [
|
|
5
|
+
{
|
|
6
|
+
name: 'Primarios',
|
|
7
|
+
tokens: [
|
|
8
|
+
{ name: '--color-blue-50', value: '#EFF6FF', textDark: true },
|
|
9
|
+
{ name: '--color-blue-100', value: '#DBEAFE', textDark: true },
|
|
10
|
+
{ name: '--color-blue-500', value: '#3B82F6' },
|
|
11
|
+
{ name: '--color-blue-600', value: '#2563EB' },
|
|
12
|
+
{ name: '--color-blue-700', value: '#1D4ED8' },
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'Grises',
|
|
17
|
+
tokens: [
|
|
18
|
+
{ name: '--color-gray-50', value: '#F9FAFB', textDark: true },
|
|
19
|
+
{ name: '--color-gray-100', value: '#F3F4F6', textDark: true },
|
|
20
|
+
{ name: '--color-gray-200', value: '#E5E7EB', textDark: true },
|
|
21
|
+
{ name: '--color-gray-400', value: '#9CA3AF', textDark: true },
|
|
22
|
+
{ name: '--color-gray-600', value: '#4B5563' },
|
|
23
|
+
{ name: '--color-gray-800', value: '#1F2937' },
|
|
24
|
+
{ name: '--color-gray-900', value: '#111827' },
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'Semánticos',
|
|
29
|
+
tokens: [
|
|
30
|
+
{ name: '--color-danger', value: '#EF4444' },
|
|
31
|
+
{ name: '--color-success', value: '#22C55E' },
|
|
32
|
+
{ name: '--color-warning', value: '#FACC15', textDark: true },
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
@Component({
|
|
38
|
+
standalone: true,
|
|
39
|
+
selector: 'story-colors',
|
|
40
|
+
template: `
|
|
41
|
+
<div style="padding: 32px; font-family: sans-serif;">
|
|
42
|
+
<h1 style="font-size: 28px; font-weight: 700; margin: 0 0 8px;">🎨 Color Tokens</h1>
|
|
43
|
+
<p style="color: #6B7280; margin: 0 0 40px;">
|
|
44
|
+
Usá siempre los tokens CSS en lugar de valores directos. Ejemplo: <code style="background:#F3F4F6; padding: 2px 6px; border-radius: 4px;">color: var(--color-primary)</code>
|
|
45
|
+
</p>
|
|
46
|
+
|
|
47
|
+
@for (group of colorGroups; track group.name) {
|
|
48
|
+
<div style="margin-bottom: 40px;">
|
|
49
|
+
<h2 style="font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: #9CA3AF; margin: 0 0 16px;">
|
|
50
|
+
{{ group.name }}
|
|
51
|
+
</h2>
|
|
52
|
+
<div style="display: flex; flex-wrap: wrap; gap: 12px;">
|
|
53
|
+
@for (token of group.tokens; track token.name) {
|
|
54
|
+
<div style="display: flex; flex-direction: column; width: 140px;">
|
|
55
|
+
<div
|
|
56
|
+
[style.background]="token.value"
|
|
57
|
+
[style.color]="token.textDark ? '#111827' : '#ffffff'"
|
|
58
|
+
style="height: 80px; border-radius: 10px; border: 1px solid rgba(0,0,0,0.07); display: flex; align-items: flex-end; padding: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.08);">
|
|
59
|
+
<span style="font-size: 11px; font-weight: 500; opacity: 0.8;">{{ token.value }}</span>
|
|
60
|
+
</div>
|
|
61
|
+
<span style="font-size: 12px; color: #374151; margin-top: 8px; word-break: break-all;">{{ token.name }}</span>
|
|
62
|
+
</div>
|
|
63
|
+
}
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
}
|
|
67
|
+
</div>
|
|
68
|
+
`,
|
|
69
|
+
})
|
|
70
|
+
class ColorsDocComponent {
|
|
71
|
+
colorGroups = colorGroups;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const meta: Meta<ColorsDocComponent> = {
|
|
75
|
+
title: 'Tokens/Colors',
|
|
76
|
+
component: ColorsDocComponent,
|
|
77
|
+
parameters: {
|
|
78
|
+
layout: 'fullscreen',
|
|
79
|
+
docs: {
|
|
80
|
+
description: {
|
|
81
|
+
component: 'Paleta de colores del sistema de diseño.',
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export default meta;
|
|
88
|
+
type Story = StoryObj<ColorsDocComponent>;
|
|
89
|
+
|
|
90
|
+
export const Paleta: Story = {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
2
|
+
import { Component } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
const shadowScale = [
|
|
5
|
+
{
|
|
6
|
+
token: '--shadow-xs',
|
|
7
|
+
value: '0 1px 2px 0 rgb(0 0 0 / 0.05)',
|
|
8
|
+
label: 'XS',
|
|
9
|
+
usage: 'Tooltips, badges',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
token: '--shadow-sm',
|
|
13
|
+
value: '0 1px 3px 0 rgb(0 0 0 / 0.10), 0 1px 2px -1px rgb(0 0 0 / 0.10)',
|
|
14
|
+
label: 'SM',
|
|
15
|
+
usage: 'Botones, inputs',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
token: '--shadow-md',
|
|
19
|
+
value: '0 4px 6px -1px rgb(0 0 0 / 0.10), 0 2px 4px -2px rgb(0 0 0 / 0.10)',
|
|
20
|
+
label: 'MD',
|
|
21
|
+
usage: 'Cards, dropdowns',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
token: '--shadow-lg',
|
|
25
|
+
value: '0 10px 15px -3px rgb(0 0 0 / 0.10), 0 4px 6px -4px rgb(0 0 0 / 0.10)',
|
|
26
|
+
label: 'LG',
|
|
27
|
+
usage: 'Modals, popovers',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
token: '--shadow-xl',
|
|
31
|
+
value: '0 20px 25px -5px rgb(0 0 0 / 0.10), 0 8px 10px -6px rgb(0 0 0 / 0.10)',
|
|
32
|
+
label: 'XL',
|
|
33
|
+
usage: 'Drawers, sidebars',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
token: '--shadow-inner',
|
|
37
|
+
value: 'inset 0 2px 4px 0 rgb(0 0 0 / 0.05)',
|
|
38
|
+
label: 'Inner',
|
|
39
|
+
usage: 'Inputs activos, wells',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
token: '--shadow-none',
|
|
43
|
+
value: '0 0 #0000',
|
|
44
|
+
label: 'None',
|
|
45
|
+
usage: 'Reset explícito',
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
@Component({
|
|
50
|
+
standalone: true,
|
|
51
|
+
selector: 'story-shadows',
|
|
52
|
+
template: `
|
|
53
|
+
<div style="padding: 32px; font-family: sans-serif; background: #F9FAFB; min-height: 100vh;">
|
|
54
|
+
<h1 style="font-size: 28px; font-weight: 700; margin: 0 0 8px; color: #111827;">🌑 Shadow Tokens</h1>
|
|
55
|
+
<p style="color: #6B7280; margin: 0 0 40px;">
|
|
56
|
+
Elevación y profundidad. Usá sombras más grandes para elementos que flotan sobre el contenido.
|
|
57
|
+
</p>
|
|
58
|
+
|
|
59
|
+
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 32px;">
|
|
60
|
+
@for (item of shadowScale; track item.token) {
|
|
61
|
+
<div style="display: flex; flex-direction: column; gap: 16px;">
|
|
62
|
+
<div
|
|
63
|
+
[style.box-shadow]="item.value"
|
|
64
|
+
style="background: #ffffff; border-radius: 12px; height: 100px; display: flex; align-items: center; justify-content: center;">
|
|
65
|
+
<span style="font-size: 18px; font-weight: 700; color: #D1D5DB;">{{ item.label }}</span>
|
|
66
|
+
</div>
|
|
67
|
+
<div>
|
|
68
|
+
<div style="font-size: 12px; font-weight: 600; color: #374151;">{{ item.token }}</div>
|
|
69
|
+
<div style="font-size: 11px; color: #9CA3AF; margin-top: 2px;">{{ item.usage }}</div>
|
|
70
|
+
<code style="font-size: 10px; color: #6B7280; margin-top: 6px; display: block; word-break: break-all; line-height: 1.5;">
|
|
71
|
+
{{ item.value }}
|
|
72
|
+
</code>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
}
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
`,
|
|
79
|
+
})
|
|
80
|
+
class ShadowsDocComponent {
|
|
81
|
+
shadowScale = shadowScale;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const meta: Meta<ShadowsDocComponent> = {
|
|
85
|
+
title: 'Tokens/Shadows',
|
|
86
|
+
component: ShadowsDocComponent,
|
|
87
|
+
parameters: { layout: 'fullscreen' },
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export default meta;
|
|
91
|
+
type Story = StoryObj<ShadowsDocComponent>;
|
|
92
|
+
|
|
93
|
+
export const Elevacion: Story = {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
2
|
+
import { Component } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
const spacingScale = [
|
|
5
|
+
{ token: '--space-1', value: '0.25rem', px: 4 },
|
|
6
|
+
{ token: '--space-2', value: '0.5rem', px: 8 },
|
|
7
|
+
{ token: '--space-3', value: '0.75rem', px: 12 },
|
|
8
|
+
{ token: '--space-4', value: '1rem', px: 16 },
|
|
9
|
+
{ token: '--space-5', value: '1.25rem', px: 20 },
|
|
10
|
+
{ token: '--space-6', value: '1.5rem', px: 24 },
|
|
11
|
+
{ token: '--space-8', value: '2rem', px: 32 },
|
|
12
|
+
{ token: '--space-10', value: '2.5rem', px: 40 },
|
|
13
|
+
{ token: '--space-12', value: '3rem', px: 48 },
|
|
14
|
+
{ token: '--space-16', value: '4rem', px: 64 },
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
@Component({
|
|
18
|
+
standalone: true,
|
|
19
|
+
selector: 'story-spacing',
|
|
20
|
+
template: `
|
|
21
|
+
<div style="padding: 32px; font-family: sans-serif;">
|
|
22
|
+
<h1 style="font-size: 28px; font-weight: 700; margin: 0 0 8px;">📐 Spacing Tokens</h1>
|
|
23
|
+
<p style="color: #6B7280; margin: 0 0 40px;">Sistema de espaciado basado en múltiplos de 4px.</p>
|
|
24
|
+
|
|
25
|
+
<div style="display: flex; flex-direction: column; gap: 12px;">
|
|
26
|
+
@for (item of spacingScale; track item.token) {
|
|
27
|
+
<div style="display: flex; align-items: center; gap: 20px;">
|
|
28
|
+
<div style="width: 180px; flex-shrink: 0;">
|
|
29
|
+
<div style="font-size: 12px; font-weight: 500; color: #374151;">{{ item.token }}</div>
|
|
30
|
+
<div style="font-size: 11px; color: #9CA3AF;">{{ item.value }} · {{ item.px }}px</div>
|
|
31
|
+
</div>
|
|
32
|
+
<div
|
|
33
|
+
[style.width.px]="item.px"
|
|
34
|
+
style="height: 24px; background: #3B82F6; border-radius: 4px; flex-shrink: 0;">
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
}
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
`,
|
|
41
|
+
})
|
|
42
|
+
class SpacingDocComponent {
|
|
43
|
+
spacingScale = spacingScale;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const meta: Meta<SpacingDocComponent> = {
|
|
47
|
+
title: 'Tokens/Spacing',
|
|
48
|
+
component: SpacingDocComponent,
|
|
49
|
+
parameters: { layout: 'fullscreen' },
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default meta;
|
|
53
|
+
type Story = StoryObj<SpacingDocComponent>;
|
|
54
|
+
|
|
55
|
+
export const Escala: Story = {};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
2
|
+
import { Component } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
const typeScale = [
|
|
5
|
+
{ token: '--font-size-xs', size: '0.75rem', px: '12px', label: 'XS - Caption' },
|
|
6
|
+
{ token: '--font-size-sm', size: '0.875rem', px: '14px', label: 'SM - Body small' },
|
|
7
|
+
{ token: '--font-size-md', size: '1rem', px: '16px', label: 'MD - Body (base)' },
|
|
8
|
+
{ token: '--font-size-lg', size: '1.125rem', px: '18px', label: 'LG - Body large' },
|
|
9
|
+
{ token: '--font-size-xl', size: '1.25rem', px: '20px', label: 'XL - Subtitle' },
|
|
10
|
+
{ token: '--font-size-2xl', size: '1.5rem', px: '24px', label: '2XL - Heading S' },
|
|
11
|
+
{ token: '--font-size-3xl', size: '1.875rem', px: '30px', label: '3XL - Heading M' },
|
|
12
|
+
{ token: '--font-size-4xl', size: '2.25rem', px: '36px', label: '4XL - Heading L' },
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const weights = [
|
|
16
|
+
{ token: '--font-weight-regular', value: '400', label: 'Regular' },
|
|
17
|
+
{ token: '--font-weight-medium', value: '500', label: 'Medium' },
|
|
18
|
+
{ token: '--font-weight-semibold', value: '600', label: 'Semibold' },
|
|
19
|
+
{ token: '--font-weight-bold', value: '700', label: 'Bold' },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
@Component({
|
|
23
|
+
standalone: true,
|
|
24
|
+
selector: 'story-typography',
|
|
25
|
+
template: `
|
|
26
|
+
<div style="padding: 32px; font-family: sans-serif; max-width: 800px;">
|
|
27
|
+
<h1 style="font-size: 28px; font-weight: 700; margin: 0 0 8px;">✍️ Typography Tokens</h1>
|
|
28
|
+
<p style="color: #6B7280; margin: 0 0 40px;">Escala tipográfica y pesos del sistema.</p>
|
|
29
|
+
|
|
30
|
+
<h2 style="font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: #9CA3AF; margin: 0 0 20px;">Escala de tamaños</h2>
|
|
31
|
+
<div style="display: flex; flex-direction: column; gap: 20px; margin-bottom: 48px;">
|
|
32
|
+
@for (item of typeScale; track item.token) {
|
|
33
|
+
<div style="display: flex; align-items: baseline; gap: 24px; padding-bottom: 20px; border-bottom: 1px solid #F3F4F6;">
|
|
34
|
+
<div style="width: 220px; flex-shrink: 0;">
|
|
35
|
+
<div style="font-size: 11px; color: #9CA3AF;">{{ item.token }}</div>
|
|
36
|
+
<div style="font-size: 11px; color: #D1D5DB;">{{ item.size }} · {{ item.px }}</div>
|
|
37
|
+
</div>
|
|
38
|
+
<div [style.font-size]="item.size" style="color: #111827; line-height: 1.2;">
|
|
39
|
+
{{ item.label }}
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
}
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<h2 style="font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: #9CA3AF; margin: 0 0 20px;">Font Weights</h2>
|
|
46
|
+
<div style="display: flex; flex-direction: column; gap: 16px;">
|
|
47
|
+
@for (w of weights; track w.token) {
|
|
48
|
+
<div style="display: flex; align-items: center; gap: 24px; padding-bottom: 16px; border-bottom: 1px solid #F3F4F6;">
|
|
49
|
+
<div style="width: 220px; flex-shrink: 0;">
|
|
50
|
+
<div style="font-size: 11px; color: #9CA3AF;">{{ w.token }}</div>
|
|
51
|
+
<div style="font-size: 11px; color: #D1D5DB;">{{ w.value }}</div>
|
|
52
|
+
</div>
|
|
53
|
+
<div [style.font-weight]="w.value" style="font-size: 20px; color: #111827;">
|
|
54
|
+
{{ w.label }} — The quick brown fox
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
}
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
`,
|
|
61
|
+
})
|
|
62
|
+
class TypographyDocComponent {
|
|
63
|
+
typeScale = typeScale;
|
|
64
|
+
weights = weights;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const meta: Meta<TypographyDocComponent> = {
|
|
68
|
+
title: 'Tokens/Typography',
|
|
69
|
+
component: TypographyDocComponent,
|
|
70
|
+
parameters: { layout: 'fullscreen' },
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default meta;
|
|
74
|
+
type Story = StoryObj<TypographyDocComponent>;
|
|
75
|
+
|
|
76
|
+
export const Escala: Story = {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
// Radius
|
|
3
|
+
--radius-none: 0;
|
|
4
|
+
--radius-xs: 0.0625rem; // 1px
|
|
5
|
+
--radius-sm: 0.125rem; // 2px
|
|
6
|
+
--radius-md: 0.375rem; // 6px
|
|
7
|
+
--radius-lg: 0.5rem; // 8px
|
|
8
|
+
--radius-xl: 0.75rem; // 12px
|
|
9
|
+
--radius-2xl: 1rem; // 16px
|
|
10
|
+
--radius-full: 9999px;
|
|
11
|
+
|
|
12
|
+
// Border widths
|
|
13
|
+
--border-width-thin: 1px;
|
|
14
|
+
--border-width-medium: 2px;
|
|
15
|
+
--border-width-thick: 4px;
|
|
16
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
// ─── Brand (derivado de #002F54) ───────────────────────────
|
|
3
|
+
--color-brand-50: #E6EEF5;
|
|
4
|
+
--color-brand-100: #CCDDE9;
|
|
5
|
+
--color-brand-200: #99BBD4;
|
|
6
|
+
--color-brand-300: #6699BE;
|
|
7
|
+
--color-brand-400: #3377A9;
|
|
8
|
+
--color-brand-500: #005593;
|
|
9
|
+
--color-brand-600: #003F6E;
|
|
10
|
+
--color-brand-700: #002F54;
|
|
11
|
+
--color-brand-800: #001F38;
|
|
12
|
+
--color-brand-900: #000F1C;
|
|
13
|
+
--color-brand-950: #00070D;
|
|
14
|
+
|
|
15
|
+
--color-white: #FFFFFF;
|
|
16
|
+
--search-bg: #F3F4F6;
|
|
17
|
+
|
|
18
|
+
// ─── Neutral scale ─────────────────────────────
|
|
19
|
+
--color-neutral-50: #F6F7F8;
|
|
20
|
+
--color-neutral-200: #E3E9F5;
|
|
21
|
+
--color-neutral-300: #C3CAD7;
|
|
22
|
+
--color-neutral-500: #A4ACBA;
|
|
23
|
+
--color-neutral-600: #878E9D;
|
|
24
|
+
--color-neutral-700: #6B7280;
|
|
25
|
+
--color-neutral-800: #505763;
|
|
26
|
+
--color-neutral-900: #373C46;
|
|
27
|
+
|
|
28
|
+
// ─── Status semantic colors ──────────────────
|
|
29
|
+
// Live → Green
|
|
30
|
+
--color-status-success-bg: #ECFEF6;
|
|
31
|
+
--color-status-success-text: #004E3B;
|
|
32
|
+
--color-status-success-border: #ADDFCB;
|
|
33
|
+
|
|
34
|
+
// Inactive → Yellow/Orange
|
|
35
|
+
--color-status-warning-bg: #FEFCE8;
|
|
36
|
+
--color-status-warning-text: #733E0A;
|
|
37
|
+
--color-status-warning-border: #F1D9A0;
|
|
38
|
+
|
|
39
|
+
// Neutral → Gray
|
|
40
|
+
--color-status-neutral-bg: #F9FAFB;
|
|
41
|
+
--color-status-neutral-text: #101828;
|
|
42
|
+
--color-status-neutral-border: #CFD1D7;
|
|
43
|
+
|
|
44
|
+
// Default → Blue
|
|
45
|
+
--color-status-default-bg: #EFF6FF;
|
|
46
|
+
--color-status-default-text: #1C398E;
|
|
47
|
+
--color-status-default-border: #B7D3FF;
|
|
48
|
+
|
|
49
|
+
// Error → Red
|
|
50
|
+
--color-status-error-bg: #FEF3F3;
|
|
51
|
+
--color-status-error-text: #82181A;
|
|
52
|
+
--color-status-error-border: #FCC8C8;
|
|
53
|
+
--color-status-error: #a21315;
|
|
54
|
+
|
|
55
|
+
// ─── Semánticos generales ──────────────────────────────────
|
|
56
|
+
--color-primary: var(--color-brand-700);
|
|
57
|
+
--color-primary-hover: var(--color-brand-800);
|
|
58
|
+
--color-primary-subtle: var(--color-brand-50);
|
|
59
|
+
|
|
60
|
+
// Text
|
|
61
|
+
--color-text-primary: var(--color-neutral-900);
|
|
62
|
+
--color-text-secondary: var(--color-neutral-700);
|
|
63
|
+
--color-text-tertiary: var(--color-neutral-600);
|
|
64
|
+
--color-text-disabled: var(--color-neutral-500);
|
|
65
|
+
--color-text-inverse: var(--color-white);
|
|
66
|
+
|
|
67
|
+
// Backgrounds / surfaces
|
|
68
|
+
--color-bg-default: var(--color-white);
|
|
69
|
+
--color-bg-subtle: var(--color-neutral-50);
|
|
70
|
+
--color-bg-muted: var(--color-neutral-200);
|
|
71
|
+
|
|
72
|
+
// Borders / dividers
|
|
73
|
+
--color-border-subtle: var(--color-neutral-200);
|
|
74
|
+
--color-border: var(--color-neutral-300);
|
|
75
|
+
--color-border-strong: var(--color-neutral-500);
|
|
76
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
3
|
+
--shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.10), 0 1px 2px -1px rgb(0 0 0 / 0.10);
|
|
4
|
+
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.10), 0 2px 4px -2px rgb(0 0 0 / 0.10);
|
|
5
|
+
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.10), 0 4px 6px -4px rgb(0 0 0 / 0.10);
|
|
6
|
+
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.10), 0 8px 10px -6px rgb(0 0 0 / 0.10);
|
|
7
|
+
--shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
|
|
8
|
+
--shadow-none: 0 0 #0000;
|
|
9
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--space-0: 0;
|
|
3
|
+
--space-0-5: 0.125rem; // 2px
|
|
4
|
+
--space-1: 0.25rem; // 4px
|
|
5
|
+
--space-1-5: 0.375rem; // 6px
|
|
6
|
+
--space-2: 0.5rem; // 8px
|
|
7
|
+
--space-3: 0.75rem; // 12px
|
|
8
|
+
--space-4: 1rem; // 16px
|
|
9
|
+
--space-5: 1.25rem; // 20px
|
|
10
|
+
--space-6: 1.5rem; // 24px
|
|
11
|
+
--space-8: 2rem; // 32px
|
|
12
|
+
--space-10: 2.5rem; // 40px
|
|
13
|
+
--space-12: 3rem; // 48px
|
|
14
|
+
--space-16: 4rem; // 64px
|
|
15
|
+
--space-20: 5rem; // 80px
|
|
16
|
+
--space-24: 6rem; // 96px
|
|
17
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap");
|
|
2
|
+
|
|
3
|
+
:root {
|
|
4
|
+
--font-family-sans: 'Roboto', system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
|
|
5
|
+
--font-family-mono: 'JetBrains Mono', 'Fira Code', monospace;
|
|
6
|
+
|
|
7
|
+
/* Font sizes (base = 14px) */
|
|
8
|
+
--font-size-xs: 0.6875rem; /* 11px */
|
|
9
|
+
--font-size-sm: 0.75rem; /* 12px */
|
|
10
|
+
--font-size-md: 0.875rem; /* 14px (BASE) */
|
|
11
|
+
--font-size-lg: 1rem; /* 16px */
|
|
12
|
+
--font-size-xl: 1.125rem; /* 18px */
|
|
13
|
+
--font-size-2xl: 1.25rem; /* 20px */
|
|
14
|
+
--font-size-3xl: 1.5rem; /* 24px */
|
|
15
|
+
--font-size-4xl: 1.875rem; /* 30px */
|
|
16
|
+
--font-size-5xl: 2.25rem; /* 36px */
|
|
17
|
+
|
|
18
|
+
/* Font weights */
|
|
19
|
+
--font-weight-regular: 400;
|
|
20
|
+
--font-weight-medium: 500;
|
|
21
|
+
--font-weight-semibold: 600;
|
|
22
|
+
--font-weight-bold: 700;
|
|
23
|
+
|
|
24
|
+
/* Line heights */
|
|
25
|
+
--line-height-tight: 1.15;
|
|
26
|
+
--line-height-normal: 1.35;
|
|
27
|
+
--line-height-loose: 1.6;
|
|
28
|
+
|
|
29
|
+
/* Letter spacing */
|
|
30
|
+
--letter-spacing-tight: -0.025em;
|
|
31
|
+
--letter-spacing-normal: 0em;
|
|
32
|
+
--letter-spacing-wide: 0.025em;
|
|
33
|
+
--letter-spacing-wider: 0.05em;
|
|
34
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export const colorTokens = {
|
|
2
|
+
primitive: {
|
|
3
|
+
'blue-50': '#EFF6FF',
|
|
4
|
+
'blue-100': '#DBEAFE',
|
|
5
|
+
'blue-500': '#3B82F6',
|
|
6
|
+
'blue-600': '#2563EB',
|
|
7
|
+
'blue-700': '#1D4ED8',
|
|
8
|
+
'gray-50': '#F9FAFB',
|
|
9
|
+
'gray-100': '#F3F4F6',
|
|
10
|
+
'gray-200': '#E5E7EB',
|
|
11
|
+
'gray-400': '#9CA3AF',
|
|
12
|
+
'gray-600': '#4B5563',
|
|
13
|
+
'gray-800': '#1F2937',
|
|
14
|
+
'gray-900': '#111827',
|
|
15
|
+
'red-500': '#EF4444',
|
|
16
|
+
'green-500': '#22C55E',
|
|
17
|
+
'yellow-400': '#FACC15',
|
|
18
|
+
},
|
|
19
|
+
semantic: {
|
|
20
|
+
'primary': 'var(--color-primary)',
|
|
21
|
+
'danger': 'var(--color-danger)',
|
|
22
|
+
'success': 'var(--color-success)',
|
|
23
|
+
'text-primary': 'var(--color-text-primary)',
|
|
24
|
+
'text-secondary': 'var(--color-text-secondary)',
|
|
25
|
+
'bg-default': 'var(--color-bg-default)',
|
|
26
|
+
'border': 'var(--color-border)',
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const spacingTokens = {
|
|
31
|
+
'0': '0',
|
|
32
|
+
'1': '0.25rem',
|
|
33
|
+
'2': '0.5rem',
|
|
34
|
+
'3': '0.75rem',
|
|
35
|
+
'4': '1rem',
|
|
36
|
+
'5': '1.25rem',
|
|
37
|
+
'6': '1.5rem',
|
|
38
|
+
'8': '2rem',
|
|
39
|
+
'10': '2.5rem',
|
|
40
|
+
'12': '3rem',
|
|
41
|
+
'16': '4rem',
|
|
42
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
|
2
|
+
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
|
3
|
+
{
|
|
4
|
+
"extends": "./tsconfig.json",
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"outDir": "./out-tsc/app",
|
|
7
|
+
"types": [
|
|
8
|
+
"node"
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
"include": [
|
|
12
|
+
"src/**/*.ts"
|
|
13
|
+
],
|
|
14
|
+
"exclude": [
|
|
15
|
+
"src/**/*.spec.ts"
|
|
16
|
+
]
|
|
17
|
+
}
|