trdr-ds-install 1.9.0 → 2.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/package.json +1 -1
- package/plugins/trdr-design-system/skills/trdr-ds/SKILL.md +168 -2914
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/abas.json +36 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/badge.json +139 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/boleta.json +121 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/button.json +166 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/card.json +55 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/checkbox.json +82 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/combo-input.json +79 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/copy-button.json +88 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/dropdown.json +94 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/floating-menu.json +151 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/header.json +141 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/janela.json +245 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/news-card.json +124 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/radio-button.json +97 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/search-input.json +69 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/segmented-control.json +60 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/sidebar.json +109 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/stat-card.json +90 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/sub-menu-item.json +45 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/switch.json +89 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/tabela-cotacoes.json +91 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/tabela-ordens.json +81 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/table.json +119 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/text-input.json +159 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/components/tooltip.json +88 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/index.json +262 -0
- package/plugins/trdr-design-system/skills/trdr-ds/data/mappings.json +183 -0
- package/plugins/trdr-design-system/skills/trdr-ds/modes/report.md +139 -0
- package/plugins/trdr-design-system/skills/trdr-ds/modes/resume.md +46 -0
- package/plugins/trdr-design-system/skills/trdr-ds/modes/rollback.md +55 -0
- package/plugins/trdr-design-system/skills/trdr-ds/modes/status.md +37 -0
- package/plugins/trdr-design-system/skills/trdr-ds/modes/sync.md +48 -0
- package/plugins/trdr-design-system/skills/trdr-ds/phases/analyze.md +305 -0
- package/plugins/trdr-design-system/skills/trdr-ds/phases/components.md +204 -0
- package/plugins/trdr-design-system/skills/trdr-ds/phases/final.md +209 -0
- package/plugins/trdr-design-system/skills/trdr-ds/phases/foundation.md +195 -0
- package/plugins/trdr-design-system/skills/trdr-ds/phases/violations.md +183 -0
- package/plugins/trdr-design-system/skills/trdr-ds/templates/claude-md.md +88 -0
- package/plugins/trdr-design-system/skills/trdr-ds/templates/ds-analysis.md +88 -0
- package/plugins/trdr-design-system/skills/trdr-ds/templates/ds-migration.md +59 -0
- package/plugins/trdr-design-system/skills/trdr-ds/templates/ds-progress.md +57 -0
- package/plugins/trdr-design-system/skills/trdr-ds/templates/sprint-plan.md +68 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "radio-button",
|
|
3
|
+
"name": "Radio Button",
|
|
4
|
+
"figmaId": "1916:46361",
|
|
5
|
+
"category": "formulario",
|
|
6
|
+
"description": "Seleção única com 2 variantes: Input (círculo 16×16px) e Button (pill 24px). Estados: Default, Active, Focused, Disabled.",
|
|
7
|
+
"props": [
|
|
8
|
+
{
|
|
9
|
+
"name": "Variant",
|
|
10
|
+
"type": "enum",
|
|
11
|
+
"values": [
|
|
12
|
+
"Input",
|
|
13
|
+
"Button"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "State",
|
|
18
|
+
"type": "enum",
|
|
19
|
+
"values": [
|
|
20
|
+
"Default",
|
|
21
|
+
"Active",
|
|
22
|
+
"Focused",
|
|
23
|
+
"Disabled"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "Label",
|
|
28
|
+
"type": "boolean",
|
|
29
|
+
"values": [
|
|
30
|
+
"true",
|
|
31
|
+
"false"
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"dimensions": [
|
|
36
|
+
{
|
|
37
|
+
"label": "Input circle",
|
|
38
|
+
"width": "16px",
|
|
39
|
+
"height": "16px"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"label": "Button pill",
|
|
43
|
+
"height": "24px"
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"tokens": [
|
|
47
|
+
{
|
|
48
|
+
"property": "Circle On bg",
|
|
49
|
+
"token": "action-brand-default",
|
|
50
|
+
"value": "#00D4FF"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"property": "Circle Off bg",
|
|
54
|
+
"token": "surface-secondary",
|
|
55
|
+
"value": "#222222"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"property": "Circle border",
|
|
59
|
+
"token": "border-default",
|
|
60
|
+
"value": "#4A4A4A"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"property": "Dot (On)",
|
|
64
|
+
"token": "—",
|
|
65
|
+
"value": "#FFFFFF"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"property": "Focus ring",
|
|
69
|
+
"token": "border-focus",
|
|
70
|
+
"value": "#00D4FF"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"property": "Button border default",
|
|
74
|
+
"token": "border-subtle",
|
|
75
|
+
"value": "#222222"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"property": "Button border active",
|
|
79
|
+
"token": "border-default",
|
|
80
|
+
"value": "#4A4A4A"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"property": "Button bg active",
|
|
84
|
+
"token": "surface-brand",
|
|
85
|
+
"value": "#00D4FF29"
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
"anatomy": "[Input] → label > input[type=radio] hidden + círculo 16×16px + label text\n[Button] → button pill 24px height | border varia por estado",
|
|
89
|
+
"implemented": true,
|
|
90
|
+
"code": {
|
|
91
|
+
"html": "<!-- Input On -->\n<label class=\"trdr-radio-input\">\n <input type=\"radio\" name=\"mercado\" checked />\n <span class=\"trdr-radio-circle trdr-radio-circle-on\"></span>\n <span>WINQ25</span>\n</label>\n\n<!-- Input Off -->\n<label class=\"trdr-radio-input\">\n <input type=\"radio\" name=\"mercado\" />\n <span class=\"trdr-radio-circle\"></span>\n <span>WINFUT</span>\n</label>\n\n<!-- Button Default -->\n<button class=\"trdr-radio-button\">Label</button>\n\n<!-- Button Active -->\n<button class=\"trdr-radio-button trdr-radio-button-active\">Label</button>",
|
|
92
|
+
"css": ".trdr-radio-input {\n display: inline-flex; align-items: center;\n gap: var(--spacing-sm); cursor: pointer;\n font-family: var(--font-secondary); font-size: 12px; font-weight: 500;\n color: var(--content-primary);\n}\n\n.trdr-radio-circle {\n flex-shrink: 0; width: 16px; height: 16px;\n border-radius: var(--radius-full);\n border: 1px solid var(--border-default); /* #4A4A4A */\n background: var(--surface-secondary); /* #222222 */\n display: flex; align-items: center; justify-content: center;\n position: relative;\n transition: border-color 0.12s ease, background 0.12s ease;\n}\n\n.trdr-radio-circle-on {\n background: var(--action-brand-default);\n border-color: var(--action-brand-default);\n}\n\n.trdr-radio-circle-on::after {\n content: ''; width: 6px; height: 6px;\n border-radius: var(--radius-full);\n background: #ffffff;\n}\n\n.trdr-radio-button {\n display: inline-flex; align-items: center; justify-content: center;\n height: 24px; padding: 0 var(--spacing-sm); border-radius: 5px;\n border: 1px solid var(--border-subtle); /* #222222 */\n font-family: var(--font-secondary); font-size: 12px; font-weight: 500;\n color: var(--content-primary); cursor: pointer;\n transition: border-color 0.12s ease, background 0.12s ease;\n}\n\n.trdr-radio-button-active {\n background: var(--surface-brand); /* #00D4FF29 */\n border-color: var(--border-default);\n}\n\n.trdr-radio-button:focus-visible { outline: none; border-color: var(--border-focus); }",
|
|
93
|
+
"react": "import RadioButton from '@/components/ui/RadioButton'\nimport { useState } from 'react'\n\nexport default function Example() {\n const [selected, setSelected] = useState('winq25')\n\n return (\n <>\n {/* Input variant */}\n <RadioButton\n variant=\"input\"\n checked={selected === 'winq25'}\n label=\"WINQ25\"\n onChange={() => setSelected('winq25')}\n name=\"mercado\"\n />\n <RadioButton\n variant=\"input\"\n checked={selected === 'winfut'}\n label=\"WINFUT\"\n onChange={() => setSelected('winfut')}\n name=\"mercado\"\n />\n\n {/* Button variant */}\n <RadioButton variant=\"button\" label=\"Boleta\" state=\"active\" />\n <RadioButton variant=\"button\" label=\"Gráfico\" />\n <RadioButton variant=\"button\" label=\"Desativado\" state=\"disabled\" />\n </>\n )\n}",
|
|
94
|
+
"prompt": "Implemente o componente RadioButton do Design System TRDR com 2 variantes.\n\nVARIANTE INPUT (círculo):\n- Círculo: 16×16px, border-radius: 9999px (radius-full)\n- Off: bg=--surface-secondary (#222222), border=--border-default (#4A4A4A)\n- On: bg=--action-brand-default (#00D4FF), border=action-brand-default\n → Dot interno: 6×6px branco via ::after\n- Hover Off: border=--border-strong (#A4A4A4)\n- Focus: outline 2px --border-focus (#00D4FF) offset 2px\n\nVARIANTE BUTTON (pill):\n- Height: 24px, border-radius: 5px, padding: 0 8px\n- Default: border=--border-subtle (#222222)\n- Active: bg=--surface-brand (#00D4FF29), border=--border-default\n- Focused: border=--border-focus (#00D4FF)\n- Disabled: opacity 0.6, cursor not-allowed\n\nFONT: 12px / 500 / --font-secondary / --content-primary"
|
|
95
|
+
},
|
|
96
|
+
"dependencies": []
|
|
97
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "search-input",
|
|
3
|
+
"name": "SearchInput",
|
|
4
|
+
"figmaId": "—",
|
|
5
|
+
"category": "formulario",
|
|
6
|
+
"description": "Input de busca com ícone lupa à esquerda. Baseado no TextInput (.trdr-input) com wrapper posicional para o ícone. Modo controlado (value/onChange) ou URL-sync (paramName).",
|
|
7
|
+
"props": [
|
|
8
|
+
{
|
|
9
|
+
"name": "Placeholder",
|
|
10
|
+
"type": "string",
|
|
11
|
+
"values": [
|
|
12
|
+
"Buscar..."
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"name": "Mode",
|
|
17
|
+
"type": "enum",
|
|
18
|
+
"values": [
|
|
19
|
+
"Controlled",
|
|
20
|
+
"URL-sync"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"dimensions": [
|
|
25
|
+
{
|
|
26
|
+
"label": "Default",
|
|
27
|
+
"width": "100% (fill, max 400px)",
|
|
28
|
+
"height": "24px"
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"tokens": [
|
|
32
|
+
{
|
|
33
|
+
"property": "Icon color",
|
|
34
|
+
"token": "content-tertiary",
|
|
35
|
+
"value": "#A4A4A4"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"property": "Input BG",
|
|
39
|
+
"token": "surface-primary",
|
|
40
|
+
"value": "#141519"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"property": "Input border",
|
|
44
|
+
"token": "border-default",
|
|
45
|
+
"value": "#4A4A4A"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"property": "Input text",
|
|
49
|
+
"token": "content-primary",
|
|
50
|
+
"value": "#FFFFFF"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"property": "Placeholder",
|
|
54
|
+
"token": "content-disabled",
|
|
55
|
+
"value": "#4A4A4A"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"anatomy": "[div.trdr-search-input]\n ├── [svg.trdr-search-input-icon 16×16] ← absolute, left 10px, vertical-center\n └── [input.trdr-input] ← padding-left 36px para dar espaço ao ícone\n\nHerda todos os estilos de .trdr-input (TextInput)",
|
|
59
|
+
"implemented": true,
|
|
60
|
+
"code": {
|
|
61
|
+
"html": "<!-- Search Input -->\n<div class=\"trdr-search-input\">\n <svg class=\"trdr-search-input-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n </svg>\n <input type=\"text\" class=\"trdr-input\" placeholder=\"Buscar...\" />\n</div>",
|
|
62
|
+
"css": ".trdr-search-input {\n position: relative;\n width: 100%;\n}\n\n.trdr-search-input-icon {\n position: absolute;\n left: 10px;\n top: 50%;\n transform: translateY(-50%);\n color: var(--content-tertiary);\n pointer-events: none;\n}\n\n.trdr-search-input .trdr-input {\n padding-left: 36px;\n}",
|
|
63
|
+
"react": "import SearchInput from '@/components/ui/SearchInput'\n\nexport default function Example() {\n const [query, setQuery] = useState('')\n\n return (\n <>\n {/* Modo controlado */}\n <SearchInput\n value={query}\n onChange={setQuery}\n placeholder=\"Buscar tokens...\"\n />\n\n {/* Modo URL-sync (Next.js) */}\n <SearchInput paramName=\"q\" placeholder=\"Buscar...\" />\n </>\n )\n}",
|
|
64
|
+
"prompt": "Implemente o componente SearchInput do Design System TRDR.\n\nESPECIFICAÇÕES:\n- Wrapper: position relative, width 100%\n- Ícone: SVG lupa 16×16, position absolute, left 10px, top 50%, transform translateY(-50%), cor --content-tertiary\n- Input: classe .trdr-input (herda do TextInput), padding-left 36px para não sobrepor ícone\n\nTOKENS OBRIGATÓRIOS:\n- --content-tertiary (#A4A4A4) — ícone lupa\n- Herda tokens de .trdr-input: --surface-primary (bg), --border-default (border), --content-primary (text)\n\nDEPENDÊNCIA: TextInput (.trdr-input deve estar disponível no CSS)\n\nNOTAS:\n- Aceita modo controlado (value + onChange) ou URL-sync (paramName para query params Next.js)\n- NUNCA usar hex direto. NUNCA usar --scale-spacing-*."
|
|
65
|
+
},
|
|
66
|
+
"dependencies": [
|
|
67
|
+
"text-input"
|
|
68
|
+
]
|
|
69
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "segmented-control",
|
|
3
|
+
"name": "Segmented Control",
|
|
4
|
+
"figmaId": "1655:25490",
|
|
5
|
+
"category": "formulario",
|
|
6
|
+
"description": "Controle de abas compacto. De 2 a 6 tabs. Container arredondado com radius 64px.",
|
|
7
|
+
"props": [
|
|
8
|
+
{
|
|
9
|
+
"name": "Tabs",
|
|
10
|
+
"type": "enum",
|
|
11
|
+
"values": [
|
|
12
|
+
"2",
|
|
13
|
+
"3",
|
|
14
|
+
"4",
|
|
15
|
+
"5",
|
|
16
|
+
"6"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "State",
|
|
21
|
+
"type": "enum",
|
|
22
|
+
"values": [
|
|
23
|
+
"Default",
|
|
24
|
+
"Active"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"dimensions": [
|
|
29
|
+
{
|
|
30
|
+
"label": "Default",
|
|
31
|
+
"height": "28px"
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"tokens": [
|
|
35
|
+
{
|
|
36
|
+
"property": "Container BG",
|
|
37
|
+
"token": "surface.secondary",
|
|
38
|
+
"value": "#222222"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"property": "Tab ativa",
|
|
42
|
+
"token": "action.secondary.default",
|
|
43
|
+
"value": "#4A4A4A"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"property": "Tab inativa text",
|
|
47
|
+
"token": "content.tertiary",
|
|
48
|
+
"value": "#A4A4A4"
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"anatomy": "[Container radius-full bg surface.secondary]\n └── [Tab 1] [Tab 2] [Tab N...]\n Padding: 2px no container",
|
|
52
|
+
"implemented": true,
|
|
53
|
+
"code": {
|
|
54
|
+
"html": "<!-- 2 tabs -->\n<div class=\"trdr-segment-control\">\n <span class=\"trdr-segment trdr-segment-active\">Avançado</span>\n <span class=\"trdr-segment trdr-segment-inactive\">Simples</span>\n</div>\n\n<!-- 5 tabs -->\n<div class=\"trdr-segment-control\">\n <span class=\"trdr-segment trdr-segment-active\">Filtro 1</span>\n <span class=\"trdr-segment trdr-segment-inactive\">Filtro 2</span>\n <span class=\"trdr-segment trdr-segment-inactive\">Filtro 3</span>\n <span class=\"trdr-segment trdr-segment-inactive\">Filtro 4</span>\n <span class=\"trdr-segment trdr-segment-inactive\">Filtro 5</span>\n</div>",
|
|
55
|
+
"css": ".trdr-segment-control {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-sm); /* 8px */\n flex-wrap: wrap;\n}\n\n.trdr-segment {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: var(--spacing-sm) var(--spacing-md); /* 8px 12px */\n border-radius: var(--spacing-lg); /* 16px — pill */\n font-family: var(--font-secondary);\n font-size: 14px;\n font-weight: 400;\n line-height: 1.2;\n white-space: nowrap;\n cursor: pointer;\n transition: background-color 0.15s ease, color 0.15s ease;\n}\n\n.trdr-segment-active {\n background-color: var(--action-secondary-default); /* #4A4A4A */\n color: var(--content-primary); /* #FFFFFF */\n}\n\n.trdr-segment-inactive {\n background-color: var(--surface-secondary); /* #222222 */\n color: var(--content-tertiary); /* #A4A4A4 */\n}\n\n.trdr-segment-inactive:hover {\n color: var(--content-secondary); /* #E8E8E8 */\n}",
|
|
56
|
+
"react": "import { useState } from 'react'\n\nexport default function Example() {\n const [active, setActive] = useState('avancado')\n const tabs = [\n { id: 'avancado', label: 'Avançado' },\n { id: 'simples', label: 'Simples' },\n ]\n\n return (\n <div className=\"trdr-segment-control\">\n {tabs.map(tab => (\n <span\n key={tab.id}\n className={`trdr-segment ${active === tab.id ? 'trdr-segment-active' : 'trdr-segment-inactive'}`}\n onClick={() => setActive(tab.id)}\n >\n {tab.label}\n </span>\n ))}\n </div>\n )\n}",
|
|
57
|
+
"prompt": "Implemente o componente Segmented Control do Design System TRDR.\n\nESPECIFICAÇÕES:\n- Container (.trdr-segment-control): display inline-flex, gap 8px (--spacing-sm), flex-wrap wrap\n- Segment (.trdr-segment): padding 8px 12px (--spacing-sm/--spacing-md), border-radius 16px (pill), font 14px/400 Inter\n- Ativo (.trdr-segment-active): bg --action-secondary-default (#4A4A4A), color --content-primary (#FFFFFF)\n- Inativo (.trdr-segment-inactive): bg --surface-secondary (#222222), color --content-tertiary (#A4A4A4)\n- Hover inativo: color --content-secondary (#E8E8E8)\n- Transição: 0.15s ease em background-color e color\n\nUse classes CSS globais. Gerencie o estado ativo via useState no React."
|
|
58
|
+
},
|
|
59
|
+
"dependencies": []
|
|
60
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "sidebar",
|
|
3
|
+
"name": "Sidebar",
|
|
4
|
+
"figmaId": "—",
|
|
5
|
+
"category": "navegacao",
|
|
6
|
+
"description": "Navegação lateral genérica com grupos de itens, ícones Material Symbols, header com logo e footer com versão. Width 240px, sticky top 0, height 100vh.",
|
|
7
|
+
"props": [
|
|
8
|
+
{
|
|
9
|
+
"name": "Width",
|
|
10
|
+
"type": "enum",
|
|
11
|
+
"values": [
|
|
12
|
+
"240px (default)"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"dimensions": [
|
|
17
|
+
{
|
|
18
|
+
"label": "Default",
|
|
19
|
+
"width": "240px",
|
|
20
|
+
"height": "100vh"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"label": "Item",
|
|
24
|
+
"width": "100%",
|
|
25
|
+
"height": "32px"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"label": "Icon",
|
|
29
|
+
"width": "20px",
|
|
30
|
+
"height": "20px"
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"tokens": [
|
|
34
|
+
{
|
|
35
|
+
"property": "BG",
|
|
36
|
+
"token": "bg-secondary",
|
|
37
|
+
"value": "#0E0E0E"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"property": "Border",
|
|
41
|
+
"token": "border-subtle",
|
|
42
|
+
"value": "#222222"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"property": "Group label",
|
|
46
|
+
"token": "content-brand",
|
|
47
|
+
"value": "#00D4FF"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"property": "Item text",
|
|
51
|
+
"token": "content-secondary",
|
|
52
|
+
"value": "#E8E8E8"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"property": "Item hover text",
|
|
56
|
+
"token": "content-primary",
|
|
57
|
+
"value": "#FFFFFF"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"property": "Item hover BG",
|
|
61
|
+
"token": "surface-secondary",
|
|
62
|
+
"value": "#222222"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"property": "Item active text",
|
|
66
|
+
"token": "content-primary",
|
|
67
|
+
"value": "#FFFFFF"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"property": "Item active BG",
|
|
71
|
+
"token": "surface-secondary",
|
|
72
|
+
"value": "#222222"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"property": "Icon color",
|
|
76
|
+
"token": "content-tertiary",
|
|
77
|
+
"value": "#A4A4A4"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"property": "Icon active",
|
|
81
|
+
"token": "content-secondary",
|
|
82
|
+
"value": "#E8E8E8"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"property": "Version BG",
|
|
86
|
+
"token": "surface-brand",
|
|
87
|
+
"value": "#00D4FF29"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"property": "Version text",
|
|
91
|
+
"token": "content-brand",
|
|
92
|
+
"value": "#00D4FF"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"property": "Version label",
|
|
96
|
+
"token": "content-tertiary",
|
|
97
|
+
"value": "#A4A4A4"
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
"anatomy": "[aside.trdr-sidebar]\n ├── [div.trdr-sidebar-header] ← logo, padding 32px, border-bottom\n ├── [nav.trdr-sidebar-nav] ← flex-1, padding 32px 24px, gap 32px\n │ └── [div.trdr-sidebar-group] × N\n │ ├── [span.trdr-sidebar-group-label] ← 12px/400, brand, uppercase\n │ └── [ul.trdr-sidebar-list]\n │ └── [li > a.trdr-sidebar-item .trdr-sidebar-item-active?]\n │ ├── [span.trdr-sidebar-icon] ← Material Symbols 20px\n │ └── label text\n └── [div.trdr-sidebar-footer] ← border-top, flex, gap 8px\n ├── [span.trdr-sidebar-version] ← mono 11px, brand bg/text\n └── [span.trdr-sidebar-version-label] ← 11px, tertiary\n\nItem: height 32px, padding 0 8px, gap 8px, radius 4px, Inter 14px/400\nHover: text primary, bg surface-secondary\nActive: mesmos estilos de hover + icon secondary",
|
|
101
|
+
"implemented": true,
|
|
102
|
+
"code": {
|
|
103
|
+
"html": "<aside class=\"trdr-sidebar\">\n <div class=\"trdr-sidebar-header\">\n <img src=\"/logo.svg\" alt=\"Logo\" width=\"120\" />\n </div>\n\n <nav class=\"trdr-sidebar-nav\">\n <div class=\"trdr-sidebar-group\">\n <span class=\"trdr-sidebar-group-label\">Visão Geral</span>\n <ul class=\"trdr-sidebar-list\">\n <li>\n <a href=\"/\" class=\"trdr-sidebar-item trdr-sidebar-item-active\">\n <span class=\"trdr-sidebar-icon\">home</span>\n Home\n </a>\n </li>\n </ul>\n </div>\n\n <div class=\"trdr-sidebar-group\">\n <span class=\"trdr-sidebar-group-label\">Tokens</span>\n <ul class=\"trdr-sidebar-list\">\n <li>\n <a href=\"/tokens\" class=\"trdr-sidebar-item\">\n <span class=\"trdr-sidebar-icon\">grain</span>\n Primitivos\n </a>\n </li>\n <li>\n <a href=\"/semanticos\" class=\"trdr-sidebar-item\">\n <span class=\"trdr-sidebar-icon\">join_left</span>\n Semânticos\n </a>\n </li>\n </ul>\n </div>\n </nav>\n\n <div class=\"trdr-sidebar-footer\">\n <span class=\"trdr-sidebar-version\">v1.5</span>\n <span class=\"trdr-sidebar-version-label\">designtokens.md</span>\n </div>\n</aside>",
|
|
104
|
+
"css": ".trdr-sidebar {\n position: sticky;\n top: 0;\n height: 100vh;\n width: 240px;\n background-color: var(--bg-secondary);\n border-right: 1px solid var(--border-subtle);\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n overflow-x: hidden;\n flex-shrink: 0;\n}\n\n.trdr-sidebar-header {\n padding: 32px;\n border-bottom: 1px solid var(--border-subtle);\n flex-shrink: 0;\n}\n\n.trdr-sidebar-nav {\n flex: 1;\n padding: 32px 24px;\n display: flex;\n flex-direction: column;\n gap: 32px;\n overflow-y: auto;\n}\n\n.trdr-sidebar-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.trdr-sidebar-group-label {\n font-family: var(--font-secondary);\n font-size: 12px;\n font-weight: 400;\n color: var(--content-brand);\n text-transform: uppercase;\n letter-spacing: 0.02em;\n}\n\n.trdr-sidebar-list {\n list-style: none;\n display: flex;\n flex-direction: column;\n gap: 0;\n margin: 0;\n padding: 0;\n}\n\n.trdr-sidebar-item {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 32px;\n padding: 0 8px;\n font-family: var(--font-secondary);\n font-size: 14px;\n font-weight: 400;\n color: var(--content-secondary);\n border-radius: 4px;\n text-decoration: none;\n transition: color 0.12s ease, background-color 0.12s ease;\n}\n\n.trdr-sidebar-item:hover {\n color: var(--content-primary);\n background-color: var(--surface-secondary);\n}\n\n.trdr-sidebar-item-active {\n color: var(--content-primary);\n background-color: var(--surface-secondary);\n}\n\n.trdr-sidebar-icon {\n font-family: 'Material Symbols Outlined';\n font-weight: 300;\n font-style: normal;\n font-size: 20px;\n line-height: 20px;\n font-variation-settings: 'FILL' 0, 'wght' 300, 'GRAD' 0, 'opsz' 20;\n color: var(--content-tertiary);\n flex-shrink: 0;\n user-select: none;\n}\n\n.trdr-sidebar-item-active .trdr-sidebar-icon {\n color: var(--content-secondary);\n}\n\n.trdr-sidebar-footer {\n padding: 16px 24px;\n border-top: 1px solid var(--border-subtle);\n flex-shrink: 0;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.trdr-sidebar-version {\n font-family: var(--font-mono);\n font-size: 11px;\n color: var(--content-brand);\n background-color: var(--surface-brand);\n padding: 2px 6px;\n border-radius: 4px;\n}\n\n.trdr-sidebar-version-label {\n font-size: 11px;\n color: var(--content-tertiary);\n}",
|
|
105
|
+
"react": "// A Sidebar do Hub usa a versão com rotas hardcoded.\n// Para uso genérico, passe groups como prop:\n\ninterface SidebarGroup {\n label: string\n items: Array<{ href: string; label: string; icon: string; active?: boolean }>\n}\n\nfunction Sidebar({ groups }: { groups: SidebarGroup[] }) {\n return (\n <aside className=\"trdr-sidebar\">\n <div className=\"trdr-sidebar-header\">\n <img src=\"/logo.svg\" alt=\"Logo\" width={120} />\n </div>\n <nav className=\"trdr-sidebar-nav\">\n {groups.map(group => (\n <div key={group.label} className=\"trdr-sidebar-group\">\n <span className=\"trdr-sidebar-group-label\">{group.label}</span>\n <ul className=\"trdr-sidebar-list\">\n {group.items.map(item => (\n <li key={item.href}>\n <a\n href={item.href}\n className={`trdr-sidebar-item ${item.active ? 'trdr-sidebar-item-active' : ''}`}\n >\n <span className=\"trdr-sidebar-icon\">{item.icon}</span>\n {item.label}\n </a>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </nav>\n <div className=\"trdr-sidebar-footer\">\n <span className=\"trdr-sidebar-version\">v1.0</span>\n <span className=\"trdr-sidebar-version-label\">app</span>\n </div>\n </aside>\n )\n}",
|
|
106
|
+
"prompt": "Implemente o componente Sidebar do Design System TRDR.\n\nESPECIFICAÇÕES:\n- Container: sticky top 0, height 100vh, width 240px, bg --bg-secondary, border-right 1px --border-subtle, flex-col, overflow-y auto\n- Header: padding 32px, border-bottom 1px --border-subtle (logo aqui)\n- Nav: flex 1, padding 32px 24px, gap 32px entre grupos\n- Group label: Inter 12px/400, --content-brand, uppercase, letter-spacing 0.02em\n- Item: flex, gap 8px, height 32px, padding 0 8px, Inter 14px/400, --content-secondary, radius 4px\n- Item hover/active: text --content-primary, bg --surface-secondary\n- Icon: Material Symbols 20px, --content-tertiary (active: --content-secondary)\n- Footer: padding 16px 24px, border-top, flex, gap 8px\n- Version badge: mono 11px, --content-brand, bg --surface-brand, padding 2px 6px, radius 4px\n\nTOKENS OBRIGATÓRIOS:\n- --bg-secondary (#0E0E0E), --border-subtle (#222222), --surface-secondary (#222222)\n- --content-brand (#00D4FF), --content-secondary (#E8E8E8), --content-primary (#FFFFFF), --content-tertiary (#A4A4A4)\n- --surface-brand (#00D4FF29)\n- --font-secondary (Inter), --font-mono\n- Font Material Symbols Outlined para ícones\n\nNOTAS:\n- Aceitar groups como prop para ser genérico (não hardcodar nav items)\n- NUNCA usar hex direto. NUNCA usar --scale-spacing-*."
|
|
107
|
+
},
|
|
108
|
+
"dependencies": []
|
|
109
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "stat-card",
|
|
3
|
+
"name": "StatCard",
|
|
4
|
+
"figmaId": "—",
|
|
5
|
+
"category": "outros",
|
|
6
|
+
"description": "Card de estatística com valor destaque (36px bold), label e descrição opcional. Variante accent com gradient brand e cor de valor em brand.",
|
|
7
|
+
"props": [
|
|
8
|
+
{
|
|
9
|
+
"name": "Accent",
|
|
10
|
+
"type": "boolean",
|
|
11
|
+
"values": [
|
|
12
|
+
"true",
|
|
13
|
+
"false"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"dimensions": [
|
|
18
|
+
{
|
|
19
|
+
"label": "Default",
|
|
20
|
+
"width": "auto (fill)",
|
|
21
|
+
"height": "auto"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"tokens": [
|
|
25
|
+
{
|
|
26
|
+
"property": "BG",
|
|
27
|
+
"token": "bg-secondary",
|
|
28
|
+
"value": "#0E0E0E"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"property": "Border",
|
|
32
|
+
"token": "border-subtle",
|
|
33
|
+
"value": "#222222"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"property": "Radius",
|
|
37
|
+
"token": "radius-md",
|
|
38
|
+
"value": "8px"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"property": "Padding",
|
|
42
|
+
"token": "spacing-2xl",
|
|
43
|
+
"value": "24px"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"property": "Gap",
|
|
47
|
+
"token": "spacing-xs",
|
|
48
|
+
"value": "4px"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"property": "Value color",
|
|
52
|
+
"token": "content-primary",
|
|
53
|
+
"value": "#FFFFFF"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"property": "Value font",
|
|
57
|
+
"token": "font-primary",
|
|
58
|
+
"value": "JetBrains Mono"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"property": "Label color",
|
|
62
|
+
"token": "content-secondary",
|
|
63
|
+
"value": "#E8E8E8"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"property": "Desc color",
|
|
67
|
+
"token": "content-tertiary",
|
|
68
|
+
"value": "#A4A4A4"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"property": "Accent border",
|
|
72
|
+
"token": "action-brand-alpha",
|
|
73
|
+
"value": "#00D4FF29"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"property": "Accent value",
|
|
77
|
+
"token": "action-brand-default",
|
|
78
|
+
"value": "#00D4FF"
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"anatomy": "[div.trdr-stat-card .trdr-stat-card-accent?]\n ├── [div.trdr-stat-value] ← font-primary 36px/600, primary (accent: brand)\n ├── [div.trdr-stat-label] ← 13px/500, secondary\n └── [div.trdr-stat-desc?] ← 12px, tertiary, margin-top spacing-xs\n\nDefault: bg-secondary, border 1px subtle, radius-md, padding spacing-2xl, flex-col gap spacing-xs\nAccent: border action-brand-alpha, bg gradient 135deg brand-alpha → bg-secondary",
|
|
82
|
+
"implemented": true,
|
|
83
|
+
"code": {
|
|
84
|
+
"html": "<!-- Default -->\n<div class=\"trdr-stat-card\">\n <div class=\"trdr-stat-value\">292</div>\n <div class=\"trdr-stat-label\">Tokens</div>\n <div class=\"trdr-stat-desc\">Primitivos + semânticos</div>\n</div>\n\n<!-- Accent -->\n<div class=\"trdr-stat-card trdr-stat-card-accent\">\n <div class=\"trdr-stat-value\">20</div>\n <div class=\"trdr-stat-label\">Componentes</div>\n <div class=\"trdr-stat-desc\">Implementados com código</div>\n</div>",
|
|
85
|
+
"css": ".trdr-stat-card {\n background-color: var(--bg-secondary);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-md);\n padding: var(--spacing-2xl);\n display: flex;\n flex-direction: column;\n gap: var(--spacing-xs);\n}\n\n.trdr-stat-card-accent {\n border-color: var(--action-brand-alpha);\n background: linear-gradient(135deg, var(--action-brand-alpha) 0%, var(--bg-secondary) 100%);\n}\n\n.trdr-stat-value {\n font-family: var(--font-primary);\n font-size: 36px;\n font-weight: 600;\n color: var(--content-primary);\n line-height: 1;\n}\n\n.trdr-stat-card-accent .trdr-stat-value {\n color: var(--action-brand-default);\n}\n\n.trdr-stat-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--content-secondary);\n}\n\n.trdr-stat-desc {\n font-size: 12px;\n color: var(--content-tertiary);\n margin-top: var(--spacing-xs);\n}",
|
|
86
|
+
"react": "import StatCard from '@/components/ui/StatCard'\n\nexport default function Example() {\n return (\n <>\n {/* Default */}\n <StatCard value={292} label=\"Tokens\" description=\"Primitivos + semânticos\" />\n\n {/* Accent */}\n <StatCard value={20} label=\"Componentes\" description=\"Implementados com código\" accent />\n </>\n )\n}",
|
|
87
|
+
"prompt": "Implemente o componente StatCard do Design System TRDR.\n\nESPECIFICAÇÕES:\n- Container: bg --bg-secondary, border 1px --border-subtle, radius --radius-md (8px), padding --spacing-2xl (24px), flex-col, gap --spacing-xs (4px)\n- Value: font --font-primary, 36px/600, cor --content-primary, line-height 1\n- Label: 13px/500, cor --content-secondary\n- Desc: 12px, cor --content-tertiary, margin-top --spacing-xs\n\nVARIANTE ACCENT:\n- border-color: --action-brand-alpha (#00D4FF29)\n- bg: linear-gradient(135deg, --action-brand-alpha 0%, --bg-secondary 100%)\n- Value cor: --action-brand-default (#00D4FF)\n\nTOKENS OBRIGATÓRIOS:\n- --bg-secondary (#0E0E0E), --border-subtle (#222222), --radius-md (8px), --spacing-2xl (24px), --spacing-xs (4px)\n- --content-primary (#FFFFFF), --content-secondary (#E8E8E8), --content-tertiary (#A4A4A4)\n- --action-brand-alpha (#00D4FF29), --action-brand-default (#00D4FF)\n- --font-primary (JetBrains Mono)\n\nNOTAS:\n- NUNCA usar hex direto. NUNCA usar --scale-spacing-*."
|
|
88
|
+
},
|
|
89
|
+
"dependencies": []
|
|
90
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "sub-menu-item",
|
|
3
|
+
"name": "Sub-menu Item",
|
|
4
|
+
"figmaId": "1886:20967",
|
|
5
|
+
"category": "navegacao",
|
|
6
|
+
"description": "Item de sub-menu com estados Default, Hover e Pressed.",
|
|
7
|
+
"props": [
|
|
8
|
+
{
|
|
9
|
+
"name": "State",
|
|
10
|
+
"type": "enum",
|
|
11
|
+
"values": [
|
|
12
|
+
"Default",
|
|
13
|
+
"Hover",
|
|
14
|
+
"Pressed"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"dimensions": [
|
|
19
|
+
{
|
|
20
|
+
"label": "Default",
|
|
21
|
+
"width": "236px",
|
|
22
|
+
"height": "32px"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"tokens": [
|
|
26
|
+
{
|
|
27
|
+
"property": "BG hover",
|
|
28
|
+
"token": "surface.secondary",
|
|
29
|
+
"value": "#222222"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"property": "Text",
|
|
33
|
+
"token": "content.secondary",
|
|
34
|
+
"value": "#E8E8E8"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"implemented": true,
|
|
38
|
+
"code": {
|
|
39
|
+
"html": "<div class=\"trdr-sub-menu\">\n <div class=\"trdr-sub-menu-item trdr-sub-menu-item-active\">\n <span class=\"material-symbols-outlined\" style=\"font-size:20px;color:var(--content-tertiary)\">palette</span>\n <span>Todos os tokens</span>\n </div>\n <div class=\"trdr-sub-menu-item\">\n <span class=\"material-symbols-outlined\" style=\"font-size:20px;color:var(--content-tertiary)\">widgets</span>\n <span>Catálogo</span>\n </div>\n <div class=\"trdr-sub-menu-item\">\n <span class=\"material-symbols-outlined\" style=\"font-size:20px;color:var(--content-tertiary)\">smart_toy</span>\n <span>Guia & Regras</span>\n </div>\n</div>",
|
|
40
|
+
"css": ".trdr-sub-menu {\n display: flex;\n flex-direction: column;\n gap: 4px;\n width: 236px;\n background-color: var(--bg-secondary); /* #141519 */\n border: 1px solid var(--border-subtle); /* #222222 */\n border-radius: var(--radius-sm); /* 4px */\n padding: 8px;\n}\n\n.trdr-sub-menu-item {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 32px;\n padding: 0 8px;\n border-radius: 4px;\n cursor: pointer;\n font-family: var(--font-secondary);\n font-size: 14px;\n font-weight: 400;\n color: var(--content-secondary); /* #E8E8E8 */\n transition: background-color 0.1s;\n}\n\n.trdr-sub-menu-item:hover,\n.trdr-sub-menu-item-active {\n background-color: var(--surface-secondary); /* #222222 */\n}",
|
|
41
|
+
"react": "import { useState } from 'react'\n\nconst items = [\n { icon: 'palette', label: 'Todos os tokens' },\n { icon: 'widgets', label: 'Catálogo' },\n { icon: 'smart_toy', label: 'Guia & Regras' },\n]\n\nexport default function Example() {\n const [active, setActive] = useState(0)\n\n return (\n <div className=\"trdr-sub-menu\">\n {items.map(({ icon, label }, i) => (\n <div\n key={label}\n className={`trdr-sub-menu-item ${i === active ? 'trdr-sub-menu-item-active' : ''}`}\n onClick={() => setActive(i)}\n >\n <span\n className=\"material-symbols-outlined\"\n style={{ fontSize: 20, color: 'var(--content-tertiary)' }}\n >\n {icon}\n </span>\n <span>{label}</span>\n </div>\n ))}\n </div>\n )\n}",
|
|
42
|
+
"prompt": "Implemente o componente Sub-menu Item do Design System TRDR.\n\nESPECIFICAÇÕES:\n- Container (.trdr-sub-menu): flex-col, gap 4px, width 236px, bg --bg-secondary (#141519), border 1px --border-subtle (#222222), radius --radius-sm (4px), padding 8px\n- Item (.trdr-sub-menu-item): flex, gap 8px, height 32px, padding 0 8px, radius 4px, font 14px/400 Inter, color --content-secondary (#E8E8E8)\n- Hover / Ativo (.trdr-sub-menu-item-active): bg --surface-secondary (#222222)\n- Ícone: Material Symbols Outlined, font-size 20px, color --content-tertiary (#A4A4A4)\n- Transição: background-color 0.1s\n\nImplemente com estado ativo via useState."
|
|
43
|
+
},
|
|
44
|
+
"dependencies": []
|
|
45
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "switch",
|
|
3
|
+
"name": "Switch",
|
|
4
|
+
"figmaId": "1359:1740",
|
|
5
|
+
"category": "formulario",
|
|
6
|
+
"description": "Toggle on/off/mixed. Track de 32×16px com knob de 14px. Suporta estado indeterminado (mixed) com ícone de traço.",
|
|
7
|
+
"props": [
|
|
8
|
+
{
|
|
9
|
+
"name": "Type",
|
|
10
|
+
"type": "enum",
|
|
11
|
+
"values": [
|
|
12
|
+
"On",
|
|
13
|
+
"Off",
|
|
14
|
+
"Mixed"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Disabled",
|
|
19
|
+
"type": "boolean",
|
|
20
|
+
"values": [
|
|
21
|
+
"true",
|
|
22
|
+
"false"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"dimensions": [
|
|
27
|
+
{
|
|
28
|
+
"label": "Track",
|
|
29
|
+
"width": "32px",
|
|
30
|
+
"height": "16px"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"label": "Knob",
|
|
34
|
+
"width": "14px",
|
|
35
|
+
"height": "14px"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"label": "Componente total",
|
|
39
|
+
"height": "24px"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"tokens": [
|
|
43
|
+
{
|
|
44
|
+
"property": "Track On / Mixed",
|
|
45
|
+
"token": "action-brand-default",
|
|
46
|
+
"value": "#00D4FF"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"property": "Track Off",
|
|
50
|
+
"token": "surface-primary",
|
|
51
|
+
"value": "#4A4A4A"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"property": "Track Disabled",
|
|
55
|
+
"token": "surface-secondary",
|
|
56
|
+
"value": "#222222"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"property": "Knob",
|
|
60
|
+
"token": "—",
|
|
61
|
+
"value": "#FFFFFF"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"property": "Focus border",
|
|
65
|
+
"token": "border-focus",
|
|
66
|
+
"value": "#00D4FF"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"property": "Label padrão",
|
|
70
|
+
"token": "content-primary",
|
|
71
|
+
"value": "#FFFFFF"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"property": "Label disabled",
|
|
75
|
+
"token": "content-tertiary",
|
|
76
|
+
"value": "#A4A4A4"
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
"anatomy": "[button role=switch height=24px gap=8px]\n └── [Track 32×16px radius-full bg=action-brand-default|surface-primary]\n └── [Knob 14×14px radius-full white, esquerda=Off, direita=On]\n └── [Mixed: traço horizontal 8×1.5px branco centralizado]\n └── [Label 12px/500 font-secondary]",
|
|
80
|
+
"notes": "Knob: top=1px, left=1px (Off) ou right=1px (On). Foco via :focus-visible com outline border-focus.",
|
|
81
|
+
"implemented": true,
|
|
82
|
+
"code": {
|
|
83
|
+
"html": "<!-- On -->\n<button class=\"trdr-switch\" role=\"switch\" aria-checked=\"true\">\n <span class=\"trdr-switch-track trdr-switch-track-on\">\n <span class=\"trdr-switch-knob\"></span>\n </span>\n <span>Ativar notificações</span>\n</button>\n\n<!-- Off -->\n<button class=\"trdr-switch\" role=\"switch\" aria-checked=\"false\">\n <span class=\"trdr-switch-track\">\n <span class=\"trdr-switch-knob\"></span>\n </span>\n <span>Ativar notificações</span>\n</button>\n\n<!-- Mixed -->\n<button class=\"trdr-switch\" role=\"switch\" aria-checked=\"mixed\">\n <span class=\"trdr-switch-track trdr-switch-track-mixed\">\n <span class=\"trdr-switch-mixed-icon\">\n <span class=\"trdr-switch-mixed-dash\"></span>\n </span>\n </span>\n <span>Ativar notificações</span>\n</button>\n\n<!-- Disabled -->\n<button class=\"trdr-switch\" role=\"switch\" aria-checked=\"false\" disabled>\n <span class=\"trdr-switch-track\">\n <span class=\"trdr-switch-knob\"></span>\n </span>\n <span>Desativado</span>\n</button>",
|
|
84
|
+
"css": ".trdr-switch {\n display: inline-flex;\n align-items: center;\n gap: var(--spacing-sm); /* 8px */\n height: 24px;\n cursor: pointer;\n background: none;\n border: none;\n padding: 0;\n font-family: var(--font-secondary);\n font-size: 12px;\n font-weight: 500;\n color: var(--content-primary); /* #FFFFFF */\n letter-spacing: 0.2px;\n transition: color 0.15s ease;\n}\n\n.trdr-switch:disabled {\n cursor: not-allowed;\n color: var(--content-tertiary); /* #A4A4A4 */\n}\n\n.trdr-switch-track {\n position: relative;\n width: 32px;\n height: 16px;\n border-radius: var(--radius-full); /* 9999px */\n background-color: var(--surface-primary); /* #4A4A4A — Off */\n flex-shrink: 0;\n transition: background-color 0.15s ease;\n}\n\n.trdr-switch-track-on,\n.trdr-switch-track-mixed {\n background-color: var(--action-brand-default); /* #00D4FF */\n}\n\n.trdr-switch:disabled .trdr-switch-track {\n background-color: var(--surface-secondary); /* #222222 */\n}\n\n.trdr-switch:focus-visible .trdr-switch-track {\n outline: 1px solid var(--border-focus); /* #00D4FF */\n outline-offset: 2px;\n}\n\n.trdr-switch-knob {\n position: absolute;\n width: 14px;\n height: 14px;\n border-radius: var(--radius-full);\n background-color: #ffffff;\n top: 1px;\n left: 1px;\n transition: left 0.15s ease, right 0.15s ease;\n}\n\n.trdr-switch-track-on .trdr-switch-knob {\n left: auto;\n right: 1px;\n}\n\n.trdr-switch-mixed-icon {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.trdr-switch-mixed-dash {\n width: 8px;\n height: 1.5px;\n background-color: #ffffff;\n border-radius: 1px;\n}",
|
|
85
|
+
"react": "import Switch from '@/components/ui/Switch'\nimport { useState } from 'react'\n\nexport default function Example() {\n const [type, setType] = useState<'on' | 'off' | 'mixed'>('off')\n\n return (\n <Switch\n type={type}\n label=\"Ativar notificações\"\n onChange={setType}\n />\n )\n}\n\n// Disabled\n<Switch type=\"on\" label=\"Sempre ativo\" disabled />\n\n// Mixed (indeterminado)\n<Switch type=\"mixed\" label=\"Configuração parcial\" onChange={setType} />",
|
|
86
|
+
"prompt": "Implemente o componente Switch do Design System TRDR.\n\nESPECIFICAÇÕES PIXEL-PERFECT:\n- Track: 32×16px, border-radius: 9999px (--radius-full)\n- Knob: 14×14px, border-radius: 9999px, cor #FFFFFF\n- Knob Off: top=1px, left=1px | Knob On: top=1px, right=1px\n- Gap track→label: 8px (--spacing-sm)\n- Altura total: 24px\n- Label: 12px, weight 500, font-secondary\n\nTOKENS OBRIGATÓRIOS:\n- Track On/Mixed: --action-brand-default (#00D4FF)\n- Track Off: --surface-primary (#4A4A4A)\n- Track Disabled: --surface-secondary (#222222)\n- Knob: #FFFFFF (não tem token, é sempre branco)\n- Focus outline: --border-focus (#00D4FF)\n- Label padrão: --content-primary (#FFFFFF)\n- Label disabled: --content-tertiary (#A4A4A4)\n\nCOMPORTAMENTO:\n- role=\"switch\", aria-checked=\"true\"|\"false\"|\"mixed\"\n- Estado Mixed: traço horizontal 8×1.5px branco centralizado no track\n- Transição suave 0.15s no knob e background do track\n- :focus-visible com outline no track (não no botão inteiro)\n- :disabled: cursor not-allowed, label muted, track escurecido"
|
|
87
|
+
},
|
|
88
|
+
"dependencies": []
|
|
89
|
+
}
|