@dgplsoares/singulai-ds-mcp 0.1.0 → 0.2.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.
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "0.1.0",
3
- "generated_at": "2026-05-08",
2
+ "version": "0.2.0",
3
+ "generated_at": "2026-05-11",
4
4
  "design_system": {
5
5
  "name": "Singulai Design System",
6
6
  "version": "DS-2.1",
@@ -22,48 +22,312 @@
22
22
  ]
23
23
  },
24
24
  "types": {
25
- "ButtonVariant": ["primary-cta", "solid", "outline", "action", "icon", "submit", "sidebar", "modal-cancel"],
26
- "ButtonSize": ["sm", "md", "lg"],
27
- "ButtonVariantColor": ["primary", "secondary", "tertiary", "success", "danger", "warning", "dark", "goal", "apex"],
28
- "ButtonType": ["button", "submit", "reset"],
29
- "CardVariant": ["default", "dashboard", "with-tabs", "simple", "inner-card"],
30
- "CardState": ["default", "loading", "empty", "error"],
31
- "FormFieldVariant": ["text", "textarea", "select", "toggle", "search"],
32
- "FormFieldSize": ["sm", "md", "lg"],
33
- "FormFieldType": ["text", "email", "password", "number", "tel", "url"],
34
- "IconNeumorphicSize": ["sm", "md", "lg"],
35
- "IconNeumorphicVariant": ["default", "apex", "success", "warning", "danger", "info", "purple"],
36
- "PageHeaderVariant": ["default", "module-dashboard", "screen-list", "screen-create", "screen-detail"],
37
- "PageLayoutVariant": ["dashboard", "list", "wizard", "tabs-internas", "detail-fullwidth"],
38
- "AiAssistantLayoutState": ["closed", "open"],
39
- "NavFooterPanel": ["navegue", "ai", "alertas", "conta"],
40
- "AiTab": ["current", "new", "chats"],
41
- "SidebarState": ["expanded", "collapsed"],
42
- "StatsbarCardVariant": ["success", "purple", "warning", "info", "danger", "neutral"],
43
- "StatsbarCardDeltaDirection": ["up", "down"]
25
+ "ButtonVariant": [
26
+ "primary-cta",
27
+ "solid",
28
+ "outline",
29
+ "action",
30
+ "icon",
31
+ "submit",
32
+ "sidebar",
33
+ "modal-cancel"
34
+ ],
35
+ "ButtonSize": [
36
+ "sm",
37
+ "md",
38
+ "lg"
39
+ ],
40
+ "ButtonVariantColor": [
41
+ "primary",
42
+ "secondary",
43
+ "tertiary",
44
+ "success",
45
+ "danger",
46
+ "warning",
47
+ "dark",
48
+ "goal",
49
+ "apex"
50
+ ],
51
+ "ButtonType": [
52
+ "button",
53
+ "submit",
54
+ "reset"
55
+ ],
56
+ "CardVariant": [
57
+ "default",
58
+ "dashboard",
59
+ "with-tabs",
60
+ "simple",
61
+ "inner-card"
62
+ ],
63
+ "CardState": [
64
+ "default",
65
+ "loading",
66
+ "empty",
67
+ "error"
68
+ ],
69
+ "FormFieldVariant": [
70
+ "text",
71
+ "textarea",
72
+ "select",
73
+ "toggle",
74
+ "search"
75
+ ],
76
+ "FormFieldSize": [
77
+ "sm",
78
+ "md",
79
+ "lg"
80
+ ],
81
+ "FormFieldType": [
82
+ "text",
83
+ "email",
84
+ "password",
85
+ "number",
86
+ "tel",
87
+ "url"
88
+ ],
89
+ "IconNeumorphicSize": [
90
+ "sm",
91
+ "md",
92
+ "lg"
93
+ ],
94
+ "IconNeumorphicVariant": [
95
+ "default",
96
+ "apex",
97
+ "success",
98
+ "warning",
99
+ "danger",
100
+ "info",
101
+ "purple"
102
+ ],
103
+ "PageHeaderVariant": [
104
+ "default",
105
+ "module-dashboard",
106
+ "screen-list",
107
+ "screen-create",
108
+ "screen-detail"
109
+ ],
110
+ "ProgressBarSize": [
111
+ "sm",
112
+ "md",
113
+ "lg"
114
+ ],
115
+ "ProgressBarVariant": [
116
+ "apex",
117
+ "success",
118
+ "warning",
119
+ "danger",
120
+ "info",
121
+ "purple",
122
+ "pink",
123
+ "neutral"
124
+ ],
125
+ "PageLayoutVariant": [
126
+ "dashboard",
127
+ "list",
128
+ "wizard",
129
+ "tabs-internas",
130
+ "detail-fullwidth"
131
+ ],
132
+ "AiAssistantLayoutState": [
133
+ "closed",
134
+ "open"
135
+ ],
136
+ "NavFooterPanel": [
137
+ "navegue",
138
+ "ai",
139
+ "alertas",
140
+ "conta"
141
+ ],
142
+ "AiTab": [
143
+ "current",
144
+ "new",
145
+ "chats"
146
+ ],
147
+ "SidebarState": [
148
+ "expanded",
149
+ "collapsed"
150
+ ],
151
+ "StatsbarCardVariant": [
152
+ "success",
153
+ "purple",
154
+ "warning",
155
+ "info",
156
+ "danger",
157
+ "neutral"
158
+ ],
159
+ "StatsbarCardDeltaDirection": [
160
+ "up",
161
+ "down"
162
+ ],
163
+ "ToastVariant": [
164
+ "success",
165
+ "info",
166
+ "warning",
167
+ "error"
168
+ ],
169
+ "ModalConfirmVariant": [
170
+ "info",
171
+ "success",
172
+ "warning",
173
+ "danger"
174
+ ],
175
+ "ChartType": [
176
+ "line",
177
+ "bar",
178
+ "pie",
179
+ "area",
180
+ "doughnut"
181
+ ],
182
+ "BadgeVariant": [
183
+ "apex",
184
+ "success",
185
+ "warning",
186
+ "danger",
187
+ "info",
188
+ "purple",
189
+ "pink",
190
+ "neutral"
191
+ ],
192
+ "BadgeSize": [
193
+ "sm",
194
+ "md"
195
+ ],
196
+ "BadgeShape": [
197
+ "pill",
198
+ "rounded"
199
+ ],
200
+ "EmptyStateVariant": [
201
+ "default",
202
+ "no-results",
203
+ "no-data",
204
+ "error"
205
+ ],
206
+ "EmptyStateSize": [
207
+ "sm",
208
+ "md",
209
+ "lg"
210
+ ],
211
+ "ThumbnailAvatarSize": [
212
+ "xs",
213
+ "sm",
214
+ "md",
215
+ "lg"
216
+ ],
217
+ "SkeletonVariant": [
218
+ "line",
219
+ "circle",
220
+ "rect",
221
+ "card",
222
+ "row",
223
+ "chart",
224
+ "statsbar",
225
+ "list-item"
226
+ ],
227
+ "DropdownMenuPosition": [
228
+ "bottom-start",
229
+ "bottom-end",
230
+ "top-start",
231
+ "top-end"
232
+ ],
233
+ "PipelineFunnelDeltaDirection": [
234
+ "up",
235
+ "down"
236
+ ]
44
237
  },
45
238
  "components": [
46
239
  {
47
240
  "name": "ButtonComponent",
48
241
  "selector": "ds-button",
49
242
  "description": "Botão unificado do DS — 8 variants estruturais (solid, outline, icon, sidebar, etc.) × 9 cores semânticas. Suporta ícones left/right (heroicons ou imagens), estados loading/disabled e flag active para nav-items.",
50
- "tags": ["button", "cta", "action", "form", "navigation", "icon", "loading"],
243
+ "tags": [
244
+ "button",
245
+ "cta",
246
+ "action",
247
+ "form",
248
+ "navigation",
249
+ "icon",
250
+ "loading"
251
+ ],
51
252
  "props": [
52
- { "name": "variant", "type": "ButtonVariant", "required": true, "description": "Tipo estrutural do botão." },
53
- { "name": "size", "type": "ButtonSize", "default": "'md'", "description": "Tamanho." },
54
- { "name": "variantColor", "type": "ButtonVariantColor", "default": "'apex'", "description": "Cor semântica." },
55
- { "name": "type", "type": "ButtonType", "default": "'button'", "description": "Atributo HTML type." },
56
- { "name": "iconLeft", "type": "string | null", "default": "null", "description": "Nome de ícone heroX (left)." },
57
- { "name": "iconImageSrc", "type": "string | null", "default": "null", "description": "Path de SVG/PNG (left). Tem precedência sobre iconLeft." },
58
- { "name": "iconImageSize", "type": "string", "default": "'20px'", "description": "Tamanho do ícone via path." },
59
- { "name": "iconRight", "type": "string | null", "default": "null", "description": "Nome de ícone heroX (right)." },
60
- { "name": "disabled", "type": "boolean", "default": "false", "description": "Estado disabled." },
61
- { "name": "loading", "type": "boolean", "default": "false", "description": "Mostra spinner e desabilita interação." },
62
- { "name": "ariaLabel", "type": "string | null", "default": "null", "description": "Aria-label customizado." },
63
- { "name": "active", "type": "boolean", "default": "false", "description": "Estado active (sidebar nav, toggle, etc.)." }
253
+ {
254
+ "name": "variant",
255
+ "type": "ButtonVariant",
256
+ "required": true,
257
+ "description": "Tipo estrutural do botão."
258
+ },
259
+ {
260
+ "name": "size",
261
+ "type": "ButtonSize",
262
+ "default": "'md'",
263
+ "description": "Tamanho."
264
+ },
265
+ {
266
+ "name": "variantColor",
267
+ "type": "ButtonVariantColor",
268
+ "default": "'apex'",
269
+ "description": "Cor semântica."
270
+ },
271
+ {
272
+ "name": "type",
273
+ "type": "ButtonType",
274
+ "default": "'button'",
275
+ "description": "Atributo HTML type."
276
+ },
277
+ {
278
+ "name": "iconLeft",
279
+ "type": "string | null",
280
+ "default": "null",
281
+ "description": "Nome de ícone heroX (left)."
282
+ },
283
+ {
284
+ "name": "iconImageSrc",
285
+ "type": "string | null",
286
+ "default": "null",
287
+ "description": "Path de SVG/PNG (left). Tem precedência sobre iconLeft."
288
+ },
289
+ {
290
+ "name": "iconImageSize",
291
+ "type": "string",
292
+ "default": "'20px'",
293
+ "description": "Tamanho do ícone via path."
294
+ },
295
+ {
296
+ "name": "iconRight",
297
+ "type": "string | null",
298
+ "default": "null",
299
+ "description": "Nome de ícone heroX (right)."
300
+ },
301
+ {
302
+ "name": "disabled",
303
+ "type": "boolean",
304
+ "default": "false",
305
+ "description": "Estado disabled."
306
+ },
307
+ {
308
+ "name": "loading",
309
+ "type": "boolean",
310
+ "default": "false",
311
+ "description": "Mostra spinner e desabilita interação."
312
+ },
313
+ {
314
+ "name": "ariaLabel",
315
+ "type": "string | null",
316
+ "default": "null",
317
+ "description": "Aria-label customizado."
318
+ },
319
+ {
320
+ "name": "active",
321
+ "type": "boolean",
322
+ "default": "false",
323
+ "description": "Estado active (sidebar nav, toggle, etc.)."
324
+ }
64
325
  ],
65
326
  "outputs": [
66
- { "name": "clicked", "type": "EventEmitter<MouseEvent>" }
327
+ {
328
+ "name": "clicked",
329
+ "type": "EventEmitter<MouseEvent>"
330
+ }
67
331
  ],
68
332
  "examples": [
69
333
  "<ds-button variant=\"solid\" variantColor=\"primary\" (clicked)=\"onSave()\">Salvar</ds-button>",
@@ -75,15 +339,56 @@
75
339
  "name": "CardComponent",
76
340
  "selector": "ds-card",
77
341
  "description": "Container genérico do DS — 5 variants de chrome (default, dashboard, with-tabs, simple, inner-card) com slots para título, ícone, tabs de navegação interna e dropdown de ações.",
78
- "tags": ["card", "container", "panel", "tabs", "dropdown"],
342
+ "tags": [
343
+ "card",
344
+ "container",
345
+ "panel",
346
+ "tabs",
347
+ "dropdown"
348
+ ],
79
349
  "props": [
80
- { "name": "title", "type": "string | null", "default": "null", "description": "Título no header." },
81
- { "name": "icon", "type": "string | null", "default": "null", "description": "Ícone heroX no header." },
82
- { "name": "variant", "type": "CardVariant", "default": "'default'", "description": "Variant de chrome." },
83
- { "name": "state", "type": "CardState", "default": "'default'", "description": "Estado: default, loading, empty, error." },
84
- { "name": "navTabs", "type": "CardNavTab[] | null", "default": "null", "description": "Tabs de navegação interna (variant with-tabs)." },
85
- { "name": "dropdownItems", "type": "CardDropdownItem[] | null", "default": "null", "description": "Itens de dropdown de ações no header." },
86
- { "name": "ariaLabel", "type": "string | null", "default": "null", "description": "Aria-label customizado." }
350
+ {
351
+ "name": "title",
352
+ "type": "string | null",
353
+ "default": "null",
354
+ "description": "Título no header."
355
+ },
356
+ {
357
+ "name": "icon",
358
+ "type": "string | null",
359
+ "default": "null",
360
+ "description": "Ícone heroX no header."
361
+ },
362
+ {
363
+ "name": "variant",
364
+ "type": "CardVariant",
365
+ "default": "'default'",
366
+ "description": "Variant de chrome."
367
+ },
368
+ {
369
+ "name": "state",
370
+ "type": "CardState",
371
+ "default": "'default'",
372
+ "description": "Estado: default, loading, empty, error."
373
+ },
374
+ {
375
+ "name": "navTabs",
376
+ "type": "CardNavTab[] | null",
377
+ "default": "null",
378
+ "description": "Tabs de navegação interna (variant with-tabs)."
379
+ },
380
+ {
381
+ "name": "dropdownItems",
382
+ "type": "CardDropdownItem[] | null",
383
+ "default": "null",
384
+ "description": "Itens de dropdown de ações no header."
385
+ },
386
+ {
387
+ "name": "ariaLabel",
388
+ "type": "string | null",
389
+ "default": "null",
390
+ "description": "Aria-label customizado."
391
+ }
87
392
  ],
88
393
  "examples": [
89
394
  "<ds-card title=\"Receita mensal\" icon=\"heroChartBar\">\n <p>R$ 12.480,00</p>\n</ds-card>",
@@ -94,10 +399,25 @@
94
399
  "name": "CardPanelComponent",
95
400
  "selector": "ds-card-panel",
96
401
  "description": "Painel containerizado simples com título obrigatório e estado de loading. Útil para sub-seções dentro de páginas.",
97
- "tags": ["panel", "container", "loading", "section"],
402
+ "tags": [
403
+ "panel",
404
+ "container",
405
+ "loading",
406
+ "section"
407
+ ],
98
408
  "props": [
99
- { "name": "title", "type": "string", "required": true, "description": "Título do painel." },
100
- { "name": "loading", "type": "boolean", "default": "false", "description": "Estado de loading." }
409
+ {
410
+ "name": "title",
411
+ "type": "string",
412
+ "required": true,
413
+ "description": "Título do painel."
414
+ },
415
+ {
416
+ "name": "loading",
417
+ "type": "boolean",
418
+ "default": "false",
419
+ "description": "Estado de loading."
420
+ }
101
421
  ],
102
422
  "examples": [
103
423
  "<ds-card-panel title=\"Pagamentos pendentes\">\n <ds-data-table [rows]=\"rows()\" />\n</ds-card-panel>"
@@ -107,28 +427,124 @@
107
427
  "name": "FormFieldComponent",
108
428
  "selector": "ds-form-field",
109
429
  "description": "Campo de formulário unificado — 5 variants (text, textarea, select, toggle, search) com ControlValueAccessor para integração com Reactive Forms e Template-driven forms. Suporta hint, errorMessage, required, loading e estados disabled.",
110
- "tags": ["form", "input", "textarea", "select", "toggle", "search", "validation", "reactive-forms", "ngmodel"],
430
+ "tags": [
431
+ "form",
432
+ "input",
433
+ "textarea",
434
+ "select",
435
+ "toggle",
436
+ "search",
437
+ "validation",
438
+ "reactive-forms",
439
+ "ngmodel"
440
+ ],
111
441
  "props": [
112
- { "name": "variant", "type": "FormFieldVariant", "required": true, "description": "Tipo do campo." },
113
- { "name": "size", "type": "FormFieldSize", "default": "'md'", "description": "Tamanho." },
114
- { "name": "type", "type": "FormFieldType", "default": "'text'", "description": "Atributo HTML type (apenas variant=text)." },
115
- { "name": "label", "type": "string | null", "default": "null", "description": "Label exibido acima do campo." },
116
- { "name": "placeholder", "type": "string", "default": "''", "description": "Placeholder." },
117
- { "name": "hint", "type": "string | null", "default": "null", "description": "Hint abaixo do campo." },
118
- { "name": "errorMessage", "type": "string | null", "default": "null", "description": "Mensagem de erro (override do estado interno)." },
119
- { "name": "required", "type": "boolean", "default": "false", "description": "Marca como obrigatório (asterisco + aria-required)." },
120
- { "name": "disabled", "type": "boolean", "default": "false", "description": "Estado disabled." },
121
- { "name": "loading", "type": "boolean", "default": "false", "description": "Spinner no canto direito." },
122
- { "name": "rows", "type": "number", "default": "4", "description": "Linhas (apenas variant=textarea)." },
123
- { "name": "maxLength", "type": "number | null", "default": "null", "description": "Máximo de caracteres." },
124
- { "name": "options", "type": "FormFieldOption[] | null", "default": "null", "description": "Opções (apenas variant=select)." },
125
- { "name": "externalDescribedBy", "type": "string | null", "default": "null", "description": "Prefix de aria-describedby externo." },
126
- { "name": "chevronDownIconSrc", "type": "string", "default": "'branding/icons/form/chevron-down.svg'", "description": "Override do ícone chevron (split-ready)." },
127
- { "name": "searchIconSrc", "type": "string", "default": "'branding/icons/form/search.svg'", "description": "Override do ícone search (split-ready)." }
442
+ {
443
+ "name": "variant",
444
+ "type": "FormFieldVariant",
445
+ "required": true,
446
+ "description": "Tipo do campo."
447
+ },
448
+ {
449
+ "name": "size",
450
+ "type": "FormFieldSize",
451
+ "default": "'md'",
452
+ "description": "Tamanho."
453
+ },
454
+ {
455
+ "name": "type",
456
+ "type": "FormFieldType",
457
+ "default": "'text'",
458
+ "description": "Atributo HTML type (apenas variant=text)."
459
+ },
460
+ {
461
+ "name": "label",
462
+ "type": "string | null",
463
+ "default": "null",
464
+ "description": "Label exibido acima do campo."
465
+ },
466
+ {
467
+ "name": "placeholder",
468
+ "type": "string",
469
+ "default": "''",
470
+ "description": "Placeholder."
471
+ },
472
+ {
473
+ "name": "hint",
474
+ "type": "string | null",
475
+ "default": "null",
476
+ "description": "Hint abaixo do campo."
477
+ },
478
+ {
479
+ "name": "errorMessage",
480
+ "type": "string | null",
481
+ "default": "null",
482
+ "description": "Mensagem de erro (override do estado interno)."
483
+ },
484
+ {
485
+ "name": "required",
486
+ "type": "boolean",
487
+ "default": "false",
488
+ "description": "Marca como obrigatório (asterisco + aria-required)."
489
+ },
490
+ {
491
+ "name": "disabled",
492
+ "type": "boolean",
493
+ "default": "false",
494
+ "description": "Estado disabled."
495
+ },
496
+ {
497
+ "name": "loading",
498
+ "type": "boolean",
499
+ "default": "false",
500
+ "description": "Spinner no canto direito."
501
+ },
502
+ {
503
+ "name": "rows",
504
+ "type": "number",
505
+ "default": "4",
506
+ "description": "Linhas (apenas variant=textarea)."
507
+ },
508
+ {
509
+ "name": "maxLength",
510
+ "type": "number | null",
511
+ "default": "null",
512
+ "description": "Máximo de caracteres."
513
+ },
514
+ {
515
+ "name": "options",
516
+ "type": "FormFieldOption[] | null",
517
+ "default": "null",
518
+ "description": "Opções (apenas variant=select)."
519
+ },
520
+ {
521
+ "name": "externalDescribedBy",
522
+ "type": "string | null",
523
+ "default": "null",
524
+ "description": "Prefix de aria-describedby externo."
525
+ },
526
+ {
527
+ "name": "chevronDownIconSrc",
528
+ "type": "string",
529
+ "default": "'branding/icons/form/chevron-down.svg'",
530
+ "description": "Override do ícone chevron (split-ready)."
531
+ },
532
+ {
533
+ "name": "searchIconSrc",
534
+ "type": "string",
535
+ "default": "'branding/icons/form/search.svg'",
536
+ "description": "Override do ícone search (split-ready)."
537
+ }
128
538
  ],
129
539
  "outputs": [
130
- { "name": "valueChange", "type": "EventEmitter<unknown>" },
131
- { "name": "blurred", "type": "EventEmitter<FocusEvent>" }
540
+ {
541
+ "name": "valueChange",
542
+ "type": "EventEmitter<unknown>"
543
+ },
544
+ {
545
+ "name": "blurred",
546
+ "type": "EventEmitter<FocusEvent>"
547
+ }
132
548
  ],
133
549
  "examples": [
134
550
  "<ds-form-field variant=\"text\" label=\"Nome\" formControlName=\"name\" [required]=\"true\" />",
@@ -141,13 +557,43 @@
141
557
  "name": "IconNeumorphicComponent",
142
558
  "selector": "ds-icon-neumorphic",
143
559
  "description": "Ícone em moldura neumorphic — 3 sizes (sm 28px, md 40px, lg 50px) × 7 variants de cor. Aceita ícone heroX (icon prop) ou path de SVG/PNG (iconImageSrc). Bounding-box quadrada com object-fit:contain garante render correto em mobile.",
144
- "tags": ["icon", "neumorphic", "decoration", "kpi"],
560
+ "tags": [
561
+ "icon",
562
+ "neumorphic",
563
+ "decoration",
564
+ "kpi"
565
+ ],
145
566
  "props": [
146
- { "name": "icon", "type": "string | null", "default": "null", "description": "Nome de ícone heroX (use APENAS se não houver iconImageSrc)." },
147
- { "name": "iconImageSrc", "type": "string | null", "default": "null", "description": "Path de SVG/PNG. Tem precedência sobre icon." },
148
- { "name": "size", "type": "IconNeumorphicSize", "default": "'md'", "description": "Tamanho do container." },
149
- { "name": "variant", "type": "IconNeumorphicVariant", "default": "'default'", "description": "Variant de cor do ícone interno." },
150
- { "name": "ariaLabel", "type": "string | null", "default": "null", "description": "Aria-label. Sem isso, o container é decorativo." }
567
+ {
568
+ "name": "icon",
569
+ "type": "string | null",
570
+ "default": "null",
571
+ "description": "Nome de ícone heroX (use APENAS se não houver iconImageSrc)."
572
+ },
573
+ {
574
+ "name": "iconImageSrc",
575
+ "type": "string | null",
576
+ "default": "null",
577
+ "description": "Path de SVG/PNG. Tem precedência sobre icon."
578
+ },
579
+ {
580
+ "name": "size",
581
+ "type": "IconNeumorphicSize",
582
+ "default": "'md'",
583
+ "description": "Tamanho do container."
584
+ },
585
+ {
586
+ "name": "variant",
587
+ "type": "IconNeumorphicVariant",
588
+ "default": "'default'",
589
+ "description": "Variant de cor do ícone interno."
590
+ },
591
+ {
592
+ "name": "ariaLabel",
593
+ "type": "string | null",
594
+ "default": "null",
595
+ "description": "Aria-label. Sem isso, o container é decorativo."
596
+ }
151
597
  ],
152
598
  "examples": [
153
599
  "<ds-icon-neumorphic icon=\"heroChartBar\" size=\"md\" variant=\"apex\" />",
@@ -158,15 +604,57 @@
158
604
  "name": "PageLayoutComponent",
159
605
  "selector": "ds-page-layout",
160
606
  "description": "Skeleton root das telas autenticadas. Container de viewport (100dvh) que organiza sidebar (desktop) + main scrollable + nav-footer (mobile) + AI Assistant overlay. Mobile-first com overscroll-behavior:none.",
161
- "tags": ["layout", "shell", "skeleton", "viewport", "responsive", "mobile-first"],
607
+ "tags": [
608
+ "layout",
609
+ "shell",
610
+ "skeleton",
611
+ "viewport",
612
+ "responsive",
613
+ "mobile-first"
614
+ ],
162
615
  "props": [
163
- { "name": "variant", "type": "PageLayoutVariant", "default": "'dashboard'", "description": "Variant do layout (afeta padding/scroll do main)." },
164
- { "name": "aiAssistantState", "type": "AiAssistantLayoutState", "default": "'closed'", "description": "Estado do AI Assistant (closed | open)." },
165
- { "name": "sidebarWidth", "type": "string", "default": "'280px'", "description": "Largura da sidebar expandida." },
166
- { "name": "aiAssistantWidth", "type": "string", "default": "'400px'", "description": "Largura do AI Assistant aberto." },
167
- { "name": "mainAriaLabel", "type": "string", "default": "'Conteudo principal'", "description": "Aria-label do <main>." },
168
- { "name": "dashboardActive", "type": "boolean", "default": "false", "description": "True quando rota = /dashboard (afeta nav-footer)." },
169
- { "name": "aiMaximized", "type": "boolean", "default": "false", "description": "AI Assistant em modo maximizado." }
616
+ {
617
+ "name": "variant",
618
+ "type": "PageLayoutVariant",
619
+ "default": "'dashboard'",
620
+ "description": "Variant do layout (afeta padding/scroll do main)."
621
+ },
622
+ {
623
+ "name": "aiAssistantState",
624
+ "type": "AiAssistantLayoutState",
625
+ "default": "'closed'",
626
+ "description": "Estado do AI Assistant (closed | open)."
627
+ },
628
+ {
629
+ "name": "sidebarWidth",
630
+ "type": "string",
631
+ "default": "'280px'",
632
+ "description": "Largura da sidebar expandida."
633
+ },
634
+ {
635
+ "name": "aiAssistantWidth",
636
+ "type": "string",
637
+ "default": "'400px'",
638
+ "description": "Largura do AI Assistant aberto."
639
+ },
640
+ {
641
+ "name": "mainAriaLabel",
642
+ "type": "string",
643
+ "default": "'Conteudo principal'",
644
+ "description": "Aria-label do <main>."
645
+ },
646
+ {
647
+ "name": "dashboardActive",
648
+ "type": "boolean",
649
+ "default": "false",
650
+ "description": "True quando rota = /dashboard (afeta nav-footer)."
651
+ },
652
+ {
653
+ "name": "aiMaximized",
654
+ "type": "boolean",
655
+ "default": "false",
656
+ "description": "AI Assistant em modo maximizado."
657
+ }
170
658
  ],
171
659
  "examples": [
172
660
  "<ds-page-layout variant=\"dashboard\">\n <ds-sidebar-left-nav page-layout-sidebar [menuItems]=\"items\" />\n <ds-page-header page-layout-header title=\"Dashboard\" />\n <main page-layout-main>...</main>\n</ds-page-layout>"
@@ -176,18 +664,74 @@
176
664
  "name": "PageHeaderComponent",
177
665
  "selector": "ds-page-header",
178
666
  "description": "Header sticky presente em todas as telas autenticadas. Estrutura em 3 zonas: navegação (back/forward + título), breadcrumbs (centro), actions (direita). Variant module-dashboard tem botões Reorganizar/Personalizar.",
179
- "tags": ["header", "navigation", "breadcrumbs", "title", "sticky"],
667
+ "tags": [
668
+ "header",
669
+ "navigation",
670
+ "breadcrumbs",
671
+ "title",
672
+ "sticky"
673
+ ],
180
674
  "props": [
181
- { "name": "variant", "type": "PageHeaderVariant", "default": "'module-dashboard'", "description": "Variant do header." },
182
- { "name": "title", "type": "string", "required": true, "description": "Título da tela." },
183
- { "name": "icon", "type": "string | null", "default": "null", "description": "Ícone heroX antes do título." },
184
- { "name": "breadcrumbs", "type": "PageHeaderBreadcrumb[]", "default": "[]", "description": "Caminho de navegação." },
185
- { "name": "canGoBack", "type": "boolean", "default": "false", "description": "Habilita botão voltar." },
186
- { "name": "canGoForward", "type": "boolean", "default": "false", "description": "Habilita botão avançar." },
187
- { "name": "reorganizeActive", "type": "boolean", "default": "false", "description": "Estado active do botão Reorganizar." },
188
- { "name": "customizeActive", "type": "boolean", "default": "false", "description": "Estado active do botão Personalizar." },
189
- { "name": "mobileLogoSrc", "type": "string", "default": "'branding/logo-singulai-icon.png'", "description": "Logo mobile (split-ready)." },
190
- { "name": "mobileLogoAlt", "type": "string", "default": "'Singulai'", "description": "Alt text do logo mobile." }
675
+ {
676
+ "name": "variant",
677
+ "type": "PageHeaderVariant",
678
+ "default": "'module-dashboard'",
679
+ "description": "Variant do header."
680
+ },
681
+ {
682
+ "name": "title",
683
+ "type": "string",
684
+ "required": true,
685
+ "description": "Título da tela."
686
+ },
687
+ {
688
+ "name": "icon",
689
+ "type": "string | null",
690
+ "default": "null",
691
+ "description": "Ícone heroX antes do título."
692
+ },
693
+ {
694
+ "name": "breadcrumbs",
695
+ "type": "PageHeaderBreadcrumb[]",
696
+ "default": "[]",
697
+ "description": "Caminho de navegação."
698
+ },
699
+ {
700
+ "name": "canGoBack",
701
+ "type": "boolean",
702
+ "default": "false",
703
+ "description": "Habilita botão voltar."
704
+ },
705
+ {
706
+ "name": "canGoForward",
707
+ "type": "boolean",
708
+ "default": "false",
709
+ "description": "Habilita botão avançar."
710
+ },
711
+ {
712
+ "name": "reorganizeActive",
713
+ "type": "boolean",
714
+ "default": "false",
715
+ "description": "Estado active do botão Reorganizar."
716
+ },
717
+ {
718
+ "name": "customizeActive",
719
+ "type": "boolean",
720
+ "default": "false",
721
+ "description": "Estado active do botão Personalizar."
722
+ },
723
+ {
724
+ "name": "mobileLogoSrc",
725
+ "type": "string",
726
+ "default": "'branding/logo-singulai-icon.png'",
727
+ "description": "Logo mobile (split-ready)."
728
+ },
729
+ {
730
+ "name": "mobileLogoAlt",
731
+ "type": "string",
732
+ "default": "'Singulai'",
733
+ "description": "Alt text do logo mobile."
734
+ }
191
735
  ],
192
736
  "examples": [
193
737
  "<ds-page-header title=\"Cursos\" icon=\"heroBookOpen\" [breadcrumbs]=\"[{label: 'Ensino'}, {label: 'Cursos'}]\" />"
@@ -197,23 +741,86 @@
197
741
  "name": "SidebarLeftNavComponent",
198
742
  "selector": "ds-sidebar-left-nav",
199
743
  "description": "Sidebar principal collapsible — 5 estados visuais (collapsed 44px / expanded ~280px / item-active / item-default / item-hover). Persiste expanded/collapsed em localStorage. Submenus expansíveis com mutex (apenas 1 aberto por vez).",
200
- "tags": ["sidebar", "navigation", "menu", "collapsible", "submenu"],
744
+ "tags": [
745
+ "sidebar",
746
+ "navigation",
747
+ "menu",
748
+ "collapsible",
749
+ "submenu"
750
+ ],
201
751
  "props": [
202
- { "name": "menuItems", "type": "SidebarMenuItem[]", "default": "[]", "description": "Items do menu raiz com submenus." },
203
- { "name": "user", "type": "SidebarUser | null", "default": "null", "description": "Usuário logado (footer avatar)." },
204
- { "name": "initialState", "type": "SidebarState", "default": "'collapsed'", "description": "Estado inicial. Override do localStorage." },
205
- { "name": "logoFullSrc", "type": "string", "default": "'branding/logo-singulai-full.png'", "description": "Logo completo (expanded — split-ready)." },
206
- { "name": "logoIconSrc", "type": "string", "default": "'branding/logo-singulai-icon.png'", "description": "Logo ícone (collapsed — split-ready)." },
207
- { "name": "logoAlt", "type": "string", "default": "'Singulai'", "description": "Alt do logo (split-ready)." },
208
- { "name": "menuToggleExpandedIconSrc", "type": "string", "default": "'branding/icons/icon-menu-expanded.svg'", "description": "Ícone toggle expandido (split-ready)." },
209
- { "name": "menuToggleCollapsedIconSrc", "type": "string", "default": "'branding/icons/icon-menu-default.svg'", "description": "Ícone toggle colapsado (split-ready)." },
210
- { "name": "userIconSrc", "type": "string", "default": "'branding/icons/menu/user.svg'", "description": "Ícone usuário no footer (split-ready)." }
752
+ {
753
+ "name": "menuItems",
754
+ "type": "SidebarMenuItem[]",
755
+ "default": "[]",
756
+ "description": "Items do menu raiz com submenus."
757
+ },
758
+ {
759
+ "name": "user",
760
+ "type": "SidebarUser | null",
761
+ "default": "null",
762
+ "description": "Usuário logado (footer avatar)."
763
+ },
764
+ {
765
+ "name": "initialState",
766
+ "type": "SidebarState",
767
+ "default": "'collapsed'",
768
+ "description": "Estado inicial. Override do localStorage."
769
+ },
770
+ {
771
+ "name": "logoFullSrc",
772
+ "type": "string",
773
+ "default": "'branding/logo-singulai-full.png'",
774
+ "description": "Logo completo (expanded — split-ready)."
775
+ },
776
+ {
777
+ "name": "logoIconSrc",
778
+ "type": "string",
779
+ "default": "'branding/logo-singulai-icon.png'",
780
+ "description": "Logo ícone (collapsed — split-ready)."
781
+ },
782
+ {
783
+ "name": "logoAlt",
784
+ "type": "string",
785
+ "default": "'Singulai'",
786
+ "description": "Alt do logo (split-ready)."
787
+ },
788
+ {
789
+ "name": "menuToggleExpandedIconSrc",
790
+ "type": "string",
791
+ "default": "'branding/icons/icon-menu-expanded.svg'",
792
+ "description": "Ícone toggle expandido (split-ready)."
793
+ },
794
+ {
795
+ "name": "menuToggleCollapsedIconSrc",
796
+ "type": "string",
797
+ "default": "'branding/icons/icon-menu-default.svg'",
798
+ "description": "Ícone toggle colapsado (split-ready)."
799
+ },
800
+ {
801
+ "name": "userIconSrc",
802
+ "type": "string",
803
+ "default": "'branding/icons/menu/user.svg'",
804
+ "description": "Ícone usuário no footer (split-ready)."
805
+ }
211
806
  ],
212
807
  "outputs": [
213
- { "name": "stateChange", "type": "EventEmitter<SidebarState>" },
214
- { "name": "searchClick", "type": "EventEmitter<void>" },
215
- { "name": "accountClick", "type": "EventEmitter<void>" },
216
- { "name": "submenuItemClick", "type": "EventEmitter<string>" }
808
+ {
809
+ "name": "stateChange",
810
+ "type": "EventEmitter<SidebarState>"
811
+ },
812
+ {
813
+ "name": "searchClick",
814
+ "type": "EventEmitter<void>"
815
+ },
816
+ {
817
+ "name": "accountClick",
818
+ "type": "EventEmitter<void>"
819
+ },
820
+ {
821
+ "name": "submenuItemClick",
822
+ "type": "EventEmitter<string>"
823
+ }
217
824
  ],
218
825
  "examples": [
219
826
  "<ds-sidebar-left-nav [menuItems]=\"items\" [user]=\"currentUser()\" (accountClick)=\"openAccount()\" />"
@@ -223,21 +830,77 @@
223
830
  "name": "NavFooterComponent",
224
831
  "selector": "ds-nav-footer",
225
832
  "description": "Bottom navigation mobile com 5 botões (Dashboard / Navegue / Agente IA / Alertas / Conta). Painéis crescem para cima com mutex (apenas 1 aberto por vez). Visível apenas <992px via @media SCSS.",
226
- "tags": ["navigation", "mobile", "bottom-nav", "footer", "tab-bar", "panels"],
833
+ "tags": [
834
+ "navigation",
835
+ "mobile",
836
+ "bottom-nav",
837
+ "footer",
838
+ "tab-bar",
839
+ "panels"
840
+ ],
227
841
  "props": [
228
- { "name": "activePanel", "type": "NavFooterPanel | null", "default": "null", "description": "Painel atualmente aberto (mutex)." },
229
- { "name": "dashboardActive", "type": "boolean", "default": "false", "description": "Dashboard active (rota = /dashboard)." },
230
- { "name": "navegueActive", "type": "boolean", "default": "false", "description": "Navegue active (rota raiz que não /dashboard)." },
231
- { "name": "homeIconSrc", "type": "string", "default": "'branding/icons/nav-footer/01-home.svg'", "description": "Ícone Home (split-ready)." },
232
- { "name": "navegueIconSrc", "type": "string", "default": "'branding/icons/nav-footer/02-navegue.svg'", "description": "Ícone Navegue (split-ready)." },
233
- { "name": "aiIconSrc", "type": "string", "default": "'branding/icons/nav-footer/03-agente-ia.svg'", "description": "Ícone AI (split-ready)." },
234
- { "name": "alertasIconSrc", "type": "string", "default": "'branding/icons/nav-footer/04-alertas.svg'", "description": "Ícone Alertas (split-ready)." },
235
- { "name": "contaIconSrc", "type": "string", "default": "'branding/icons/nav-footer/05-conta.svg'", "description": "Ícone Conta (split-ready)." }
842
+ {
843
+ "name": "activePanel",
844
+ "type": "NavFooterPanel | null",
845
+ "default": "null",
846
+ "description": "Painel atualmente aberto (mutex)."
847
+ },
848
+ {
849
+ "name": "dashboardActive",
850
+ "type": "boolean",
851
+ "default": "false",
852
+ "description": "Dashboard active (rota = /dashboard)."
853
+ },
854
+ {
855
+ "name": "navegueActive",
856
+ "type": "boolean",
857
+ "default": "false",
858
+ "description": "Navegue active (rota raiz que não /dashboard)."
859
+ },
860
+ {
861
+ "name": "homeIconSrc",
862
+ "type": "string",
863
+ "default": "'branding/icons/nav-footer/01-home.svg'",
864
+ "description": "Ícone Home (split-ready)."
865
+ },
866
+ {
867
+ "name": "navegueIconSrc",
868
+ "type": "string",
869
+ "default": "'branding/icons/nav-footer/02-navegue.svg'",
870
+ "description": "Ícone Navegue (split-ready)."
871
+ },
872
+ {
873
+ "name": "aiIconSrc",
874
+ "type": "string",
875
+ "default": "'branding/icons/nav-footer/03-agente-ia.svg'",
876
+ "description": "Ícone AI (split-ready)."
877
+ },
878
+ {
879
+ "name": "alertasIconSrc",
880
+ "type": "string",
881
+ "default": "'branding/icons/nav-footer/04-alertas.svg'",
882
+ "description": "Ícone Alertas (split-ready)."
883
+ },
884
+ {
885
+ "name": "contaIconSrc",
886
+ "type": "string",
887
+ "default": "'branding/icons/nav-footer/05-conta.svg'",
888
+ "description": "Ícone Conta (split-ready)."
889
+ }
236
890
  ],
237
891
  "outputs": [
238
- { "name": "panelToggle", "type": "EventEmitter<NavFooterPanel>" },
239
- { "name": "dashboardClick", "type": "EventEmitter<void>" },
240
- { "name": "closePanels", "type": "EventEmitter<void>" }
892
+ {
893
+ "name": "panelToggle",
894
+ "type": "EventEmitter<NavFooterPanel>"
895
+ },
896
+ {
897
+ "name": "dashboardClick",
898
+ "type": "EventEmitter<void>"
899
+ },
900
+ {
901
+ "name": "closePanels",
902
+ "type": "EventEmitter<void>"
903
+ }
241
904
  ],
242
905
  "examples": [
243
906
  "<ds-nav-footer page-layout-nav-footer [activePanel]=\"layout.navFooterPanel()\" (panelToggle)=\"layout.togglePanel($event)\" />"
@@ -247,38 +910,182 @@
247
910
  "name": "AiAssistantPanelComponent",
248
911
  "selector": "ds-ai-assistant-panel",
249
912
  "description": "Painel lateral do Agente IA — header com tabs (current/new/chats) + créditos pill + actions (settings, maximize/minimize, close) + timeline de mensagens + action prompts + composer. Modo embedded para projeção em mobile bottom-sheet.",
250
- "tags": ["ai", "assistant", "chat", "panel", "agent", "llm"],
913
+ "tags": [
914
+ "ai",
915
+ "assistant",
916
+ "chat",
917
+ "panel",
918
+ "agent",
919
+ "llm"
920
+ ],
251
921
  "props": [
252
- { "name": "showTitle", "type": "boolean", "default": "false", "description": "Exibe label 'Agente IA' (true=desktop, false=mobile)." },
253
- { "name": "credits", "type": "number", "default": "0", "description": "Saldo de créditos IA na pill." },
254
- { "name": "messages", "type": "AiMessage[]", "default": "[]", "description": "Mensagens da timeline." },
255
- { "name": "actionPrompts", "type": "string[]", "default": "[]", "description": "Sugestões de prompts clicáveis." },
256
- { "name": "activeTab", "type": "AiTab", "default": "'current'", "description": "Tab ativo." },
257
- { "name": "hasCurrentChat", "type": "boolean", "default": "true", "description": "Mostra tab 'Chat atual...' closable." },
258
- { "name": "currentChatLabel", "type": "string", "default": "'Chat atual...'", "description": "Label do tab atual." },
259
- { "name": "maximized", "type": "boolean", "default": "false", "description": "Visual do botão maximize (icon contract vs expand)." },
260
- { "name": "embedded", "type": "boolean", "default": "false", "description": "Modo embedded (remove card chrome — para nesting em mobile bottom-sheet)." },
261
- { "name": "settingsIconSrc", "type": "string", "default": "'branding/icons/ai-assistant/settings.svg'", "description": "Ícone settings (split-ready)." },
262
- { "name": "maximizeIconSrc", "type": "string", "default": "'branding/icons/ai-assistant/maximize.svg'", "description": "Ícone maximize (split-ready)." },
263
- { "name": "minimizeIconSrc", "type": "string", "default": "'branding/icons/ai-assistant/minimize.svg'", "description": "Ícone minimize (split-ready)." },
264
- { "name": "closeIconSrc", "type": "string", "default": "'branding/icons/ai-assistant/close.svg'", "description": "Ícone close (split-ready)." }
922
+ {
923
+ "name": "showTitle",
924
+ "type": "boolean",
925
+ "default": "false",
926
+ "description": "Exibe label 'Agente IA' (true=desktop, false=mobile)."
927
+ },
928
+ {
929
+ "name": "credits",
930
+ "type": "number",
931
+ "default": "0",
932
+ "description": "Saldo de créditos IA na pill."
933
+ },
934
+ {
935
+ "name": "messages",
936
+ "type": "AiMessage[]",
937
+ "default": "[]",
938
+ "description": "Mensagens da timeline."
939
+ },
940
+ {
941
+ "name": "actionPrompts",
942
+ "type": "string[]",
943
+ "default": "[]",
944
+ "description": "Sugestões de prompts clicáveis."
945
+ },
946
+ {
947
+ "name": "activeTab",
948
+ "type": "AiTab",
949
+ "default": "'current'",
950
+ "description": "Tab ativo."
951
+ },
952
+ {
953
+ "name": "hasCurrentChat",
954
+ "type": "boolean",
955
+ "default": "true",
956
+ "description": "Mostra tab 'Chat atual...' closable."
957
+ },
958
+ {
959
+ "name": "currentChatLabel",
960
+ "type": "string",
961
+ "default": "'Chat atual...'",
962
+ "description": "Label do tab atual."
963
+ },
964
+ {
965
+ "name": "maximized",
966
+ "type": "boolean",
967
+ "default": "false",
968
+ "description": "Visual do botão maximize (icon contract vs expand)."
969
+ },
970
+ {
971
+ "name": "embedded",
972
+ "type": "boolean",
973
+ "default": "false",
974
+ "description": "Modo embedded (remove card chrome — para nesting em mobile bottom-sheet)."
975
+ },
976
+ {
977
+ "name": "settingsIconSrc",
978
+ "type": "string",
979
+ "default": "'branding/icons/ai-assistant/settings.svg'",
980
+ "description": "Ícone settings (split-ready)."
981
+ },
982
+ {
983
+ "name": "maximizeIconSrc",
984
+ "type": "string",
985
+ "default": "'branding/icons/ai-assistant/maximize.svg'",
986
+ "description": "Ícone maximize (split-ready)."
987
+ },
988
+ {
989
+ "name": "minimizeIconSrc",
990
+ "type": "string",
991
+ "default": "'branding/icons/ai-assistant/minimize.svg'",
992
+ "description": "Ícone minimize (split-ready)."
993
+ },
994
+ {
995
+ "name": "closeIconSrc",
996
+ "type": "string",
997
+ "default": "'branding/icons/ai-assistant/close.svg'",
998
+ "description": "Ícone close (split-ready)."
999
+ }
265
1000
  ],
266
1001
  "examples": [
267
1002
  "<ds-ai-assistant-panel page-layout-ai [showTitle]=\"true\" [credits]=\"creditsLeft()\" [messages]=\"chatMessages()\" [actionPrompts]=\"suggestions()\" />"
268
1003
  ]
269
1004
  },
1005
+ {
1006
+ "name": "ProgressBarComponent",
1007
+ "selector": "ds-progress-bar",
1008
+ "description": "Barra de progresso visual genérica — chrome neumorphic aninhado (container externo + track + fill). 8 variants de cor (apex/success/warning/danger/info/purple/pink/neutral) × 3 sizes (sm 6px / md 10px padrão / lg 14px). Renderiza apenas a barra; label/valor/delta ficam fora do componente — caller compõe. Visual baseado em Figma 1042:28527 (Uso do Plano) e 1042:28755 (Funil de Vendas).",
1009
+ "tags": [
1010
+ "progress",
1011
+ "bar",
1012
+ "indicator",
1013
+ "loading",
1014
+ "kpi",
1015
+ "feedback"
1016
+ ],
1017
+ "props": [
1018
+ {
1019
+ "name": "value",
1020
+ "type": "number",
1021
+ "required": true,
1022
+ "description": "Valor atual (numerador)."
1023
+ },
1024
+ {
1025
+ "name": "max",
1026
+ "type": "number",
1027
+ "default": "100",
1028
+ "description": "Máximo possível (denominador). Default 100 = uso percentual direto."
1029
+ },
1030
+ {
1031
+ "name": "variant",
1032
+ "type": "ProgressBarVariant",
1033
+ "default": "'apex'",
1034
+ "description": "Variant de cor do fill."
1035
+ },
1036
+ {
1037
+ "name": "size",
1038
+ "type": "ProgressBarSize",
1039
+ "default": "'md'",
1040
+ "description": "Tamanho da barra. md (10px height) bate com o Figma do dashboard."
1041
+ },
1042
+ {
1043
+ "name": "ariaLabel",
1044
+ "type": "string | null",
1045
+ "default": "null",
1046
+ "description": "Aria-label customizado. Default: aria-valuenow + aria-valuetext (\"X de Y\") já garantem screen reader."
1047
+ }
1048
+ ],
1049
+ "examples": [
1050
+ "<ds-progress-bar [value]=\"78\" variant=\"success\" size=\"md\" />",
1051
+ "<ds-progress-bar [value]=\"42\" [max]=\"60\" variant=\"purple\" />",
1052
+ "<ds-progress-bar [value]=\"920\" [max]=\"1000\" variant=\"danger\" ariaLabel=\"Créditos IA usados\" />"
1053
+ ]
1054
+ },
270
1055
  {
271
1056
  "name": "SegmentedTabsComponent",
272
1057
  "selector": "ds-segmented-tabs",
273
1058
  "description": "Tabs segmentados pill-style com items closable opcionais e radius dinâmico baseado em $first/$last. Generic <K> para tipagem das keys (ex: 'day' | 'week' | 'month').",
274
- "tags": ["tabs", "segmented", "pills", "filter", "period"],
1059
+ "tags": [
1060
+ "tabs",
1061
+ "segmented",
1062
+ "pills",
1063
+ "filter",
1064
+ "period"
1065
+ ],
275
1066
  "props": [
276
- { "name": "items", "type": "SegmentedTabItem<K>[]", "required": true, "description": "Items dos tabs (key + label + closable opcional)." },
277
- { "name": "activeKey", "type": "K | null", "default": "null", "description": "Key do tab ativo." }
1067
+ {
1068
+ "name": "items",
1069
+ "type": "SegmentedTabItem<K>[]",
1070
+ "required": true,
1071
+ "description": "Items dos tabs (key + label + closable opcional)."
1072
+ },
1073
+ {
1074
+ "name": "activeKey",
1075
+ "type": "K | null",
1076
+ "default": "null",
1077
+ "description": "Key do tab ativo."
1078
+ }
278
1079
  ],
279
1080
  "outputs": [
280
- { "name": "tabSelect", "type": "EventEmitter<K>" },
281
- { "name": "tabClose", "type": "EventEmitter<K>" }
1081
+ {
1082
+ "name": "tabSelect",
1083
+ "type": "EventEmitter<K>"
1084
+ },
1085
+ {
1086
+ "name": "tabClose",
1087
+ "type": "EventEmitter<K>"
1088
+ }
282
1089
  ],
283
1090
  "examples": [
284
1091
  "<ds-segmented-tabs [items]=\"[{key:'day',label:'Dia'},{key:'week',label:'Semana'}]\" [activeKey]=\"'week'\" (tabSelect)=\"setPeriod($event)\" />"
@@ -288,17 +1095,68 @@
288
1095
  "name": "StatsbarCardComponent",
289
1096
  "selector": "ds-statsbar-card",
290
1097
  "description": "Card de KPI para statsbar — title + value + delta (com seta up/down) + ícone neumorphic embutido. 6 variants de cor (success/purple/warning/info/danger/neutral). Polaridade invertida disponível (delta down como positivo).",
291
- "tags": ["kpi", "statsbar", "metric", "card", "dashboard"],
1098
+ "tags": [
1099
+ "kpi",
1100
+ "statsbar",
1101
+ "metric",
1102
+ "card",
1103
+ "dashboard"
1104
+ ],
292
1105
  "props": [
293
- { "name": "title", "type": "string", "required": true, "description": "Título do KPI." },
294
- { "name": "value", "type": "string | number", "required": true, "description": "Valor principal." },
295
- { "name": "delta", "type": "string | null", "default": "null", "description": "Variação (ex: '+12%' ou 'R$ 480')." },
296
- { "name": "deltaDirection", "type": "StatsbarCardDeltaDirection", "default": "'up'", "description": "Seta do delta." },
297
- { "name": "inversePolarity", "type": "boolean", "default": "false", "description": "Inverte semântica de cor (delta down como positivo)." },
298
- { "name": "variant", "type": "StatsbarCardVariant", "default": "'neutral'", "description": "Variant de cor do ícone." },
299
- { "name": "iconImageSrc", "type": "string | null", "default": "null", "description": "Path do ícone (ex: 'branding/icons/statsbar/01-revenue.svg')." },
300
- { "name": "iconWidth", "type": "number", "default": "22", "description": "Largura intrínseca do SVG (HTML attr para mobile)." },
301
- { "name": "iconHeight", "type": "number", "default": "22", "description": "Altura intrínseca do SVG (HTML attr para mobile)." }
1106
+ {
1107
+ "name": "title",
1108
+ "type": "string",
1109
+ "required": true,
1110
+ "description": "Título do KPI."
1111
+ },
1112
+ {
1113
+ "name": "value",
1114
+ "type": "string | number",
1115
+ "required": true,
1116
+ "description": "Valor principal."
1117
+ },
1118
+ {
1119
+ "name": "delta",
1120
+ "type": "string | null",
1121
+ "default": "null",
1122
+ "description": "Variação (ex: '+12%' ou 'R$ 480')."
1123
+ },
1124
+ {
1125
+ "name": "deltaDirection",
1126
+ "type": "StatsbarCardDeltaDirection",
1127
+ "default": "'up'",
1128
+ "description": "Seta do delta."
1129
+ },
1130
+ {
1131
+ "name": "inversePolarity",
1132
+ "type": "boolean",
1133
+ "default": "false",
1134
+ "description": "Inverte semântica de cor (delta down como positivo)."
1135
+ },
1136
+ {
1137
+ "name": "variant",
1138
+ "type": "StatsbarCardVariant",
1139
+ "default": "'neutral'",
1140
+ "description": "Variant de cor do ícone."
1141
+ },
1142
+ {
1143
+ "name": "iconImageSrc",
1144
+ "type": "string | null",
1145
+ "default": "null",
1146
+ "description": "Path do ícone (ex: 'branding/icons/statsbar/01-revenue.svg')."
1147
+ },
1148
+ {
1149
+ "name": "iconWidth",
1150
+ "type": "number",
1151
+ "default": "22",
1152
+ "description": "Largura intrínseca do SVG (HTML attr para mobile)."
1153
+ },
1154
+ {
1155
+ "name": "iconHeight",
1156
+ "type": "number",
1157
+ "default": "22",
1158
+ "description": "Altura intrínseca do SVG (HTML attr para mobile)."
1159
+ }
302
1160
  ],
303
1161
  "examples": [
304
1162
  "<ds-statsbar-card title=\"Receita\" [value]=\"12480\" delta=\"+12%\" deltaDirection=\"up\" variant=\"success\" iconImageSrc=\"branding/icons/statsbar/01-revenue.svg\" />"
@@ -308,14 +1166,38 @@
308
1166
  "name": "AiAssistantButtonComponent",
309
1167
  "selector": "ds-ai-assistant-button",
310
1168
  "description": "Botão de toggle do AI Assistant para o combo do header (32px height). Estado active (panel aberto) com triple-ring neumorphic + bg #EFF3F8.",
311
- "tags": ["ai", "button", "toggle", "header", "combo"],
1169
+ "tags": [
1170
+ "ai",
1171
+ "button",
1172
+ "toggle",
1173
+ "header",
1174
+ "combo"
1175
+ ],
312
1176
  "props": [
313
- { "name": "ariaLabel", "type": "string", "default": "'Abrir Assistente IA'", "description": "Aria-label." },
314
- { "name": "active", "type": "boolean", "default": "false", "description": "AI Assistant panel aberto." },
315
- { "name": "sparklesIconSrc", "type": "string", "default": "'branding/icons/sparkles.svg'", "description": "Override do ícone sparkles (split-ready)." }
1177
+ {
1178
+ "name": "ariaLabel",
1179
+ "type": "string",
1180
+ "default": "'Abrir Assistente IA'",
1181
+ "description": "Aria-label."
1182
+ },
1183
+ {
1184
+ "name": "active",
1185
+ "type": "boolean",
1186
+ "default": "false",
1187
+ "description": "AI Assistant panel aberto."
1188
+ },
1189
+ {
1190
+ "name": "sparklesIconSrc",
1191
+ "type": "string",
1192
+ "default": "'branding/icons/sparkles.svg'",
1193
+ "description": "Override do ícone sparkles (split-ready)."
1194
+ }
316
1195
  ],
317
1196
  "outputs": [
318
- { "name": "clicked", "type": "EventEmitter<MouseEvent>" }
1197
+ {
1198
+ "name": "clicked",
1199
+ "type": "EventEmitter<MouseEvent>"
1200
+ }
319
1201
  ],
320
1202
  "examples": [
321
1203
  "<ds-ai-assistant-button [active]=\"aiState() === 'open'\" (clicked)=\"toggleAi()\" />"
@@ -325,14 +1207,39 @@
325
1207
  "name": "DarkModeButtonComponent",
326
1208
  "selector": "ds-dark-mode-button",
327
1209
  "description": "Toggle de tema (light/dark) para o combo do header. Composite SVG com lua + cone de luz rotacionado + 2 estrelas em cruz, todos com filter neumorphic unificado.",
328
- "tags": ["theme", "dark-mode", "button", "toggle", "header", "combo"],
1210
+ "tags": [
1211
+ "theme",
1212
+ "dark-mode",
1213
+ "button",
1214
+ "toggle",
1215
+ "header",
1216
+ "combo"
1217
+ ],
329
1218
  "props": [
330
- { "name": "ariaLabel", "type": "string", "default": "'Alternar tema claro/escuro'", "description": "Aria-label." },
331
- { "name": "moonIconSrc", "type": "string", "default": "'branding/icons/moon-vector217.svg'", "description": "Lua principal (split-ready)." },
332
- { "name": "moonGlowIconSrc", "type": "string", "default": "'branding/icons/moon-vector.svg'", "description": "Cone de luz (split-ready)." }
1219
+ {
1220
+ "name": "ariaLabel",
1221
+ "type": "string",
1222
+ "default": "'Alternar tema claro/escuro'",
1223
+ "description": "Aria-label."
1224
+ },
1225
+ {
1226
+ "name": "moonIconSrc",
1227
+ "type": "string",
1228
+ "default": "'branding/icons/moon-vector217.svg'",
1229
+ "description": "Lua principal (split-ready)."
1230
+ },
1231
+ {
1232
+ "name": "moonGlowIconSrc",
1233
+ "type": "string",
1234
+ "default": "'branding/icons/moon-vector.svg'",
1235
+ "description": "Cone de luz (split-ready)."
1236
+ }
333
1237
  ],
334
1238
  "outputs": [
335
- { "name": "clicked", "type": "EventEmitter<MouseEvent>" }
1239
+ {
1240
+ "name": "clicked",
1241
+ "type": "EventEmitter<MouseEvent>"
1242
+ }
336
1243
  ],
337
1244
  "examples": [
338
1245
  "<ds-dark-mode-button (clicked)=\"themeService.toggle()\" />"
@@ -342,17 +1249,799 @@
342
1249
  "name": "NotificationsButtonComponent",
343
1250
  "selector": "ds-notifications-button",
344
1251
  "description": "Botão de sino de notificações para o combo do header (32px). Renderiza apenas o SVG bell com filter neumorphic.",
345
- "tags": ["notifications", "bell", "button", "header", "combo"],
1252
+ "tags": [
1253
+ "notifications",
1254
+ "bell",
1255
+ "button",
1256
+ "header",
1257
+ "combo"
1258
+ ],
346
1259
  "props": [
347
- { "name": "ariaLabel", "type": "string", "default": "'Notificacoes'", "description": "Aria-label." },
348
- { "name": "bellIconSrc", "type": "string", "default": "'branding/icons/bell.svg'", "description": "Override do ícone bell (split-ready)." }
1260
+ {
1261
+ "name": "ariaLabel",
1262
+ "type": "string",
1263
+ "default": "'Notificacoes'",
1264
+ "description": "Aria-label."
1265
+ },
1266
+ {
1267
+ "name": "bellIconSrc",
1268
+ "type": "string",
1269
+ "default": "'branding/icons/bell.svg'",
1270
+ "description": "Override do ícone bell (split-ready)."
1271
+ }
349
1272
  ],
350
1273
  "outputs": [
351
- { "name": "clicked", "type": "EventEmitter<MouseEvent>" }
1274
+ {
1275
+ "name": "clicked",
1276
+ "type": "EventEmitter<MouseEvent>"
1277
+ }
352
1278
  ],
353
1279
  "examples": [
354
1280
  "<ds-notifications-button (clicked)=\"openNotifications()\" />"
355
1281
  ]
1282
+ },
1283
+ {
1284
+ "name": "ToastComponent",
1285
+ "selector": "ds-toast",
1286
+ "description": "Toast individual de notificação (item visual). 4 variants (success/info/warning/error) — cada uma com ícone heroicons + cor de accent na border-left + cor do ícone. Card neumorphic-light com border-left 4px colorido + ícone esquerda + mensagem centro + botão X dismiss à direita. NÃO usar diretamente — sempre via ToastService que renderiza via <ds-toast-host>. Suporte ARIA: role='alert' (error) ou 'status' (outras), aria-live assertive/polite.",
1287
+ "tags": [
1288
+ "toast",
1289
+ "notification",
1290
+ "feedback",
1291
+ "alert",
1292
+ "snackbar"
1293
+ ],
1294
+ "props": [
1295
+ {
1296
+ "name": "variant",
1297
+ "type": "ToastVariant",
1298
+ "required": true,
1299
+ "description": "Variant visual: success (verde), info (azul), warning (laranja), error (vermelho)."
1300
+ },
1301
+ {
1302
+ "name": "message",
1303
+ "type": "string",
1304
+ "required": true,
1305
+ "description": "Mensagem textual (sem HTML)."
1306
+ }
1307
+ ],
1308
+ "outputs": [
1309
+ {
1310
+ "name": "dismissed",
1311
+ "type": "EventEmitter<void>",
1312
+ "description": "Emitido quando o usuário clica no botão X. Host consome e chama ToastService.dismiss(id)."
1313
+ }
1314
+ ],
1315
+ "examples": [
1316
+ "// Não use diretamente — use ToastService:",
1317
+ "const toast = inject(ToastService);",
1318
+ "toast.success('Curso criado!');",
1319
+ "toast.error('Falha ao salvar.');"
1320
+ ]
1321
+ },
1322
+ {
1323
+ "name": "ModalConfirmComponent",
1324
+ "selector": "ds-modal-confirm",
1325
+ "description": "Modal de confirmação centralizado. Caso de uso primário: confirmar delete de registros (regra de produto: TODA operação de delete usa este modal). Wrapper thin de <app-modal-dialog> aplicando override visual canônico (Figma 805:4558): header com título colorido na variant + body 2 níveis (bold question + record name medium gray) + botão confirmar com chevron-right + paleta danger #935050 (burgundy). 4 variants semânticas: info/success/warning/danger (default). Internamente delega backdrop/ESC/focus/scroll-lock ao app-modal-dialog. Caller controla [isOpen] via signal.",
1326
+ "tags": [
1327
+ "modal",
1328
+ "confirm",
1329
+ "dialog",
1330
+ "delete",
1331
+ "alert",
1332
+ "confirmation"
1333
+ ],
1334
+ "props": [
1335
+ {
1336
+ "name": "isOpen",
1337
+ "type": "boolean",
1338
+ "required": true,
1339
+ "description": "Estado de abertura. Caller controla via signal e seta false ao receber (cancelled) ou (confirmed)."
1340
+ },
1341
+ {
1342
+ "name": "variant",
1343
+ "type": "ModalConfirmVariant",
1344
+ "default": "'danger'",
1345
+ "description": "Variant semântica + visual. Default danger porque delete é o caso predominante."
1346
+ },
1347
+ {
1348
+ "name": "title",
1349
+ "type": "string",
1350
+ "required": true,
1351
+ "description": "Título do header (cor herda da variant via SCSS)."
1352
+ },
1353
+ {
1354
+ "name": "message",
1355
+ "type": "string",
1356
+ "required": true,
1357
+ "description": "Pergunta principal em bold no body (ex: 'Confirma que deseja excluir o registro abaixo?')."
1358
+ },
1359
+ {
1360
+ "name": "recordName",
1361
+ "type": "string | null",
1362
+ "default": "null",
1363
+ "description": "Nome do registro a confirmar ação (sub-message medium gray no body). Quando null, mostra só [message]."
1364
+ },
1365
+ {
1366
+ "name": "confirmLabel",
1367
+ "type": "string | null",
1368
+ "default": "null",
1369
+ "description": "Label do botão confirmar. Default depende da variant: danger='Excluir', warning='Continuar', info='OK', success='Confirmar'."
1370
+ },
1371
+ {
1372
+ "name": "cancelLabel",
1373
+ "type": "string",
1374
+ "default": "'Cancelar'",
1375
+ "description": "Label do botão cancelar."
1376
+ }
1377
+ ],
1378
+ "outputs": [
1379
+ {
1380
+ "name": "confirmed",
1381
+ "type": "EventEmitter<void>",
1382
+ "description": "Emitido ao clicar no botão confirmar. Caller deve setar [isOpen]=false."
1383
+ },
1384
+ {
1385
+ "name": "cancelled",
1386
+ "type": "EventEmitter<void>",
1387
+ "description": "Emitido ao cancelar (botão Cancelar OU backdrop OU ESC OU X). Caller deve setar [isOpen]=false."
1388
+ }
1389
+ ],
1390
+ "examples": [
1391
+ "<ds-modal-confirm",
1392
+ " [isOpen]=\"showDeleteConfirm()\"",
1393
+ " variant=\"danger\"",
1394
+ " title=\"Excluir Curso\"",
1395
+ " message=\"Confirma que deseja excluir o registro abaixo?\"",
1396
+ " [recordName]=\"course().name\"",
1397
+ " (confirmed)=\"onDeleteConfirmed()\"",
1398
+ " (cancelled)=\"showDeleteConfirm.set(false)\"",
1399
+ "/>"
1400
+ ]
1401
+ },
1402
+ {
1403
+ "name": "DatatableComponent",
1404
+ "selector": "ds-datatable",
1405
+ "description": "Tabela de dados com search, sort, paginação client/server-side, filters, bulk actions, custom cells (badge/avatar/composite/progress/switch/actions), templates customizados. Wrapper thin (config-only) de <app-data-table> existente em /shared/components/. Visual override aplicado via SCSS para alinhar com Figma 862:10798 (paleta: headers #516D87, cells #5C6F8E, border #DFE3EA, dividers #D5DCE6). Re-exporta DataTableConfig<T>, ColumnDef<T>, RowAction<T>, etc. de shared. Aceita um único [config] object — não duplica as ~30 props internas.",
1406
+ "tags": [
1407
+ "datatable",
1408
+ "data-table",
1409
+ "table",
1410
+ "list",
1411
+ "grid",
1412
+ "pagination",
1413
+ "sort",
1414
+ "search",
1415
+ "filter"
1416
+ ],
1417
+ "props": [
1418
+ {
1419
+ "name": "data",
1420
+ "type": "T[]",
1421
+ "default": "[]",
1422
+ "description": "Array de dados a renderizar. Generic <T> para tipagem das linhas."
1423
+ },
1424
+ {
1425
+ "name": "config",
1426
+ "type": "DataTableConfig<T>",
1427
+ "required": true,
1428
+ "description": "Configuração completa: columns, rowActions, bulkActions, searchable, sortable, paginated, server-side mode, filterDropdown, addButton, etc."
1429
+ },
1430
+ {
1431
+ "name": "loading",
1432
+ "type": "boolean",
1433
+ "default": "false",
1434
+ "description": "Estado de loading (mostra skeleton)."
1435
+ },
1436
+ {
1437
+ "name": "error",
1438
+ "type": "string | null",
1439
+ "default": "null",
1440
+ "description": "Mensagem de erro (renderiza estado de erro)."
1441
+ },
1442
+ {
1443
+ "name": "externalFilter",
1444
+ "type": "((item: T) => boolean) | null",
1445
+ "default": "null",
1446
+ "description": "Filtro externo customizado (predicate por item)."
1447
+ }
1448
+ ],
1449
+ "outputs": [
1450
+ {
1451
+ "name": "stateChange",
1452
+ "type": "EventEmitter<DataTableStateChange>",
1453
+ "description": "Mudança consolidada (search/sort/pagination/filters)."
1454
+ },
1455
+ {
1456
+ "name": "rowClick",
1457
+ "type": "EventEmitter<T>",
1458
+ "description": "Click em uma linha."
1459
+ },
1460
+ {
1461
+ "name": "selectionChange",
1462
+ "type": "EventEmitter<T[]>",
1463
+ "description": "Mudança de seleção (modo selectable)."
1464
+ },
1465
+ {
1466
+ "name": "reload",
1467
+ "type": "EventEmitter<void>",
1468
+ "description": "Solicitação de reload (botão de reload da toolbar)."
1469
+ },
1470
+ {
1471
+ "name": "pageChange",
1472
+ "type": "EventEmitter<PageChangeEvent>",
1473
+ "description": "Server-side: mudança de página."
1474
+ },
1475
+ {
1476
+ "name": "sortChange",
1477
+ "type": "EventEmitter<SortChangeEvent>",
1478
+ "description": "Server-side: mudança de ordenação."
1479
+ },
1480
+ {
1481
+ "name": "searchChange",
1482
+ "type": "EventEmitter<SearchChangeEvent>",
1483
+ "description": "Server-side: mudança de busca."
1484
+ },
1485
+ {
1486
+ "name": "filterChange",
1487
+ "type": "EventEmitter<FilterChangeEvent>",
1488
+ "description": "Server-side: mudança de filtro dropdown."
1489
+ },
1490
+ {
1491
+ "name": "switchChange",
1492
+ "type": "EventEmitter<SwitchChangeEvent<T>>",
1493
+ "description": "Mudança em coluna switch (toggle ativo/inativo)."
1494
+ }
1495
+ ],
1496
+ "examples": [
1497
+ "const tableConfig: DataTableConfig<Course> = {",
1498
+ " columns: [",
1499
+ " { key: 'name', label: 'Curso', type: 'text', sortable: true },",
1500
+ " { key: 'isActive', label: 'Status', type: 'switch', switchConfig: { activeLabel: 'Ativo' } },",
1501
+ " { key: 'level', label: 'Nivel', type: 'badge' },",
1502
+ " ],",
1503
+ " searchable: true,",
1504
+ " paginated: true,",
1505
+ " initialPageSize: 20,",
1506
+ "};",
1507
+ "",
1508
+ "<ds-datatable",
1509
+ " [data]=\"courses()\"",
1510
+ " [config]=\"tableConfig\"",
1511
+ " [loading]=\"isLoading()\"",
1512
+ " (rowClick)=\"onRowClick($event)\"",
1513
+ "/>"
1514
+ ]
1515
+ },
1516
+ {
1517
+ "name": "ChartComponent",
1518
+ "selector": "ds-chart",
1519
+ "description": "Wrapper config-only sobre <app-chart-widget> (Chart.js v4.5.1) — 5 tipos: line, bar, area, pie, doughnut. Chrome neumorphic canônico (border #DFE3EA + radius 10 + bg semi-transparente + inner shadow white) inspirado no Figma 1042:28615 (card 'Receitas por Periodo'). Aplica defaults DS: paleta tokens (apex, success, warning, danger, purple, info), tooltip neumorphic (bg branco + texto escuro + border DS), eixos Manrope SemiBold 12px com cor #5C6F8E. Caller pode sobrescrever qualquer default via ChartConfig (props additive).",
1520
+ "tags": [
1521
+ "chart",
1522
+ "graph",
1523
+ "line",
1524
+ "area",
1525
+ "pie",
1526
+ "doughnut",
1527
+ "bar",
1528
+ "chartjs",
1529
+ "data-viz"
1530
+ ],
1531
+ "props": [
1532
+ {
1533
+ "name": "config",
1534
+ "type": "ChartConfig",
1535
+ "required": true,
1536
+ "description": "Configuração do chart (chartType, height, colors, showLegend, showGrid, tooltipBackgroundColor, axisLabelColor, etc.)."
1537
+ },
1538
+ {
1539
+ "name": "data",
1540
+ "type": "ChartData | null",
1541
+ "default": "null",
1542
+ "description": "Dados do chart (labels + datasets array). null mostra placeholder 'Sem dados'."
1543
+ }
1544
+ ],
1545
+ "outputs": [],
1546
+ "examples": [
1547
+ "// Area chart single series — Receitas por Periodo",
1548
+ "const config: ChartConfig = { type: 'chart', chartType: 'area', height: 240 };",
1549
+ "const data: ChartData = {",
1550
+ " labels: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun'],",
1551
+ " datasets: [{ label: 'Receita', data: [65, 78, 90, 80, 95, 110] }],",
1552
+ "};",
1553
+ "<ds-chart [config]=\"config\" [data]=\"data\" />",
1554
+ "",
1555
+ "// Pie chart — Top Itens (6 slices, paleta DS automatica)",
1556
+ "<ds-chart",
1557
+ " [config]=\"{ type: 'chart', chartType: 'pie', height: 280, showLegend: true }\"",
1558
+ " [data]=\"topItensData\"",
1559
+ "/>"
1560
+ ]
1561
+ },
1562
+ {
1563
+ "name": "ToastHostComponent",
1564
+ "selector": "ds-toast-host",
1565
+ "description": "Container singleton que renderiza o stack do ToastService. Posiciona-se fixed top-right (top:70px right:70px desktop / top:16px right:16px mobile). Stack vertical (gap 12px), max 5 toasts visíveis (FIFO drop). Animação de entrada slide-in da direita + fade (300ms ease-out). Respeita prefers-reduced-motion. Instanciar UMA vez no shell da app: <ds-toast-host /> em app.component.html.",
1566
+ "tags": [
1567
+ "toast",
1568
+ "host",
1569
+ "container",
1570
+ "queue",
1571
+ "singleton"
1572
+ ],
1573
+ "props": [],
1574
+ "outputs": [],
1575
+ "examples": [
1576
+ "<!-- Em app.component.html, uma vez só: -->",
1577
+ "<ds-toast-host />"
1578
+ ]
1579
+ },
1580
+ {
1581
+ "name": "BadgeComponent",
1582
+ "selector": "ds-badge",
1583
+ "description": "Badge pill/rounded de status, categoria ou tag. 8 variants de cor padronizadas com <ds-progress-bar> (apex/success/warning/danger/info/purple/pink/neutral) × 2 sizes (sm/md) × 2 shapes (pill 50px / rounded 8px). Substitui badges inline duplicados nas mini-tables IMPL-6/11/13 do dashboard (Leads/Tickets/Campaigns). Conteudo via <ng-content> — caller injeta texto e/ou icone.",
1584
+ "tags": [
1585
+ "badge",
1586
+ "tag",
1587
+ "status",
1588
+ "label",
1589
+ "chip",
1590
+ "pill",
1591
+ "listagem"
1592
+ ],
1593
+ "props": [
1594
+ {
1595
+ "name": "variant",
1596
+ "type": "BadgeVariant",
1597
+ "default": "'neutral'",
1598
+ "description": "Cor (8 opcoes alinhadas com ds-progress-bar)."
1599
+ },
1600
+ {
1601
+ "name": "size",
1602
+ "type": "BadgeSize",
1603
+ "default": "'sm'",
1604
+ "description": "Tamanho. sm = 10px font (mini-tables default), md = 11px."
1605
+ },
1606
+ {
1607
+ "name": "shape",
1608
+ "type": "BadgeShape",
1609
+ "default": "'pill'",
1610
+ "description": "pill (50px radius) ou rounded (8px radius, usado em status com icone do Figma 627-3162)."
1611
+ },
1612
+ {
1613
+ "name": "ariaLabel",
1614
+ "type": "string | null",
1615
+ "default": "null",
1616
+ "description": "Aria-label opcional para screen readers."
1617
+ }
1618
+ ],
1619
+ "outputs": [],
1620
+ "examples": [
1621
+ "<ds-badge variant=\"success\">Ativo</ds-badge>",
1622
+ "<ds-badge variant=\"warning\" size=\"md\">Pendente</ds-badge>",
1623
+ "<ds-badge variant=\"info\" shape=\"rounded\"><ng-icon name=\"heroBookOpen\" />Arquivo PDF</ds-badge>"
1624
+ ]
1625
+ },
1626
+ {
1627
+ "name": "EmptyStateComponent",
1628
+ "selector": "ds-empty-state",
1629
+ "description": "Placeholder padronizado para listagens vazias, buscas sem resultado, recursos nao criados ou erros de carregamento. Pattern visual: icone centralizado em cima + title + description (opcional) + CTA (opcional) abaixo. NAO inclui envelope/card chrome — e apenas o conteudo interno. Caller decide se envolve em <ds-card-panel> body, offcanvas, full page, etc. Cor de icone unificada #5C6F8E em todas as variants (variants permanecem semanticas para ARIA/analytics).",
1630
+ "tags": [
1631
+ "empty-state",
1632
+ "placeholder",
1633
+ "no-results",
1634
+ "empty",
1635
+ "listagem",
1636
+ "loading",
1637
+ "error"
1638
+ ],
1639
+ "props": [
1640
+ {
1641
+ "name": "icon",
1642
+ "type": "string | null",
1643
+ "default": "null",
1644
+ "description": "Heroicon name (ex: 'heroInbox', 'heroVideoCamera'). Mutuamente exclusivo com iconImageSrc. Caller registra via provideIcons()."
1645
+ },
1646
+ {
1647
+ "name": "iconImageSrc",
1648
+ "type": "string | null",
1649
+ "default": "null",
1650
+ "description": "Path de SVG (relativo a public/). Mutuamente exclusivo com icon. Use quando nao ha equivalente heroicon."
1651
+ },
1652
+ {
1653
+ "name": "title",
1654
+ "type": "string",
1655
+ "required": true,
1656
+ "description": "Title principal — obrigatorio."
1657
+ },
1658
+ {
1659
+ "name": "description",
1660
+ "type": "string | null",
1661
+ "default": "null",
1662
+ "description": "Description opcional — linha de contexto abaixo do title."
1663
+ },
1664
+ {
1665
+ "name": "ctaLabel",
1666
+ "type": "string | null",
1667
+ "default": "null",
1668
+ "description": "Label do botao CTA. Quando ausente, CTA nao e renderizado."
1669
+ },
1670
+ {
1671
+ "name": "ctaIcon",
1672
+ "type": "string | null",
1673
+ "default": "null",
1674
+ "description": "Icone do CTA (heroicon). Renderizado a esquerda do label."
1675
+ },
1676
+ {
1677
+ "name": "variant",
1678
+ "type": "EmptyStateVariant",
1679
+ "default": "'default'",
1680
+ "description": "Variant semantica (default/no-results/no-data/error)."
1681
+ },
1682
+ {
1683
+ "name": "size",
1684
+ "type": "EmptyStateSize",
1685
+ "default": "'sm'",
1686
+ "description": "sm (Figma 764-6987 em card-panel body), md (full page), lg (404 page)."
1687
+ },
1688
+ {
1689
+ "name": "ctaAriaLabel",
1690
+ "type": "string | null",
1691
+ "default": "null",
1692
+ "description": "Aria-label do CTA. Fallback para ctaLabel."
1693
+ }
1694
+ ],
1695
+ "outputs": [
1696
+ {
1697
+ "name": "ctaClick",
1698
+ "type": "EventEmitter<void>",
1699
+ "description": "Emitido ao clicar no CTA."
1700
+ }
1701
+ ],
1702
+ "examples": [
1703
+ "<ds-empty-state icon=\"heroVideoCamera\" title=\"Nenhuma live vinculada\" size=\"sm\" />",
1704
+ "<ds-empty-state icon=\"heroMagnifyingGlass\" variant=\"no-results\" title=\"Nenhum resultado encontrado\" description=\"Tente outros termos.\" ctaLabel=\"Limpar filtros\" (ctaClick)=\"onClearFilters()\" />",
1705
+ "<ds-empty-state icon=\"heroExclamationTriangle\" variant=\"error\" title=\"Erro ao carregar\" ctaLabel=\"Tentar novamente\" ctaIcon=\"heroArrowPath\" size=\"md\" (ctaClick)=\"onRetry()\" />"
1706
+ ]
1707
+ },
1708
+ {
1709
+ "name": "ThumbnailAvatarComponent",
1710
+ "selector": "ds-thumbnail-avatar",
1711
+ "description": "Avatar quadrado-arredondado com gradiente top-down (#5C8DE2 -> #27467C) e iniciais brancas centralizadas, OU imagem cobrindo o container quando 'src' presente. Diferencia-se do cell type='avatar' do <app-data-table> que usa circle + gradient Tailwind blue/purple. Pattern visual extraido do Figma 875-21663. Usado em rows de datatable, comentarios, cards de perfil.",
1712
+ "tags": [
1713
+ "avatar",
1714
+ "thumbnail",
1715
+ "profile",
1716
+ "user",
1717
+ "rounded-square",
1718
+ "placeholder"
1719
+ ],
1720
+ "props": [
1721
+ {
1722
+ "name": "name",
1723
+ "type": "string",
1724
+ "required": true,
1725
+ "description": "Nome completo do usuario/entidade. Usado para gerar iniciais (fallback) e como alt da imagem quando src presente."
1726
+ },
1727
+ {
1728
+ "name": "src",
1729
+ "type": "string | null",
1730
+ "default": "null",
1731
+ "description": "URL da imagem. Quando ausente OU vazia, renderiza fallback com iniciais."
1732
+ },
1733
+ {
1734
+ "name": "size",
1735
+ "type": "ThumbnailAvatarSize",
1736
+ "default": "'md'",
1737
+ "description": "xs (24px/6r/10f), sm (32/8/12), md (40/10/16 — Figma), lg (56/12/22)."
1738
+ },
1739
+ {
1740
+ "name": "ariaLabel",
1741
+ "type": "string | null",
1742
+ "default": "null",
1743
+ "description": "Aria-label custom. Fallback para name."
1744
+ }
1745
+ ],
1746
+ "outputs": [],
1747
+ "examples": [
1748
+ "<ds-thumbnail-avatar name=\"Joao da Silva\" size=\"md\" />",
1749
+ "<ds-thumbnail-avatar name=\"Maria\" src=\"/img/maria.jpg\" size=\"sm\" />",
1750
+ "<ds-thumbnail-avatar name=\"Ana Beatriz\" size=\"lg\" />"
1751
+ ]
1752
+ },
1753
+ {
1754
+ "name": "SkeletonComponent",
1755
+ "selector": "ds-skeleton",
1756
+ "description": "Placeholder shimmer reutilizavel para estados de loading. 3 primitivos (line/circle/rect com width/height/radius custom) + 5 composites pre-baked (card/row/chart/statsbar/list-item). Pattern shimmer canonico extraido de <ds-card-panel>: linear-gradient #E5EBF2 -> #F3F6FB com background-size 200% e animation 1.6s ease-in-out infinite. Elimina duplicacao de skeletons espalhados (Tailwind animate-pulse em data-table/stats-bar, gradients custom em features).",
1757
+ "tags": [
1758
+ "skeleton",
1759
+ "loading",
1760
+ "placeholder",
1761
+ "shimmer",
1762
+ "empty",
1763
+ "loader"
1764
+ ],
1765
+ "props": [
1766
+ {
1767
+ "name": "variant",
1768
+ "type": "SkeletonVariant",
1769
+ "required": true,
1770
+ "description": "Tipo: primitivo (line/circle/rect) OU composite (card/row/chart/statsbar/list-item)."
1771
+ },
1772
+ {
1773
+ "name": "width",
1774
+ "type": "string | null",
1775
+ "default": "null",
1776
+ "description": "CSS width (ex: '80%', '120px'). Aplicado em primitivos. Em circle usado tambem como height (mantem 1:1)."
1777
+ },
1778
+ {
1779
+ "name": "height",
1780
+ "type": "string | null",
1781
+ "default": "null",
1782
+ "description": "CSS height. Aplicado em line/rect. Default line = 14px."
1783
+ },
1784
+ {
1785
+ "name": "radius",
1786
+ "type": "string | null",
1787
+ "default": "null",
1788
+ "description": "CSS border-radius. Aplicado apenas em rect. Line/circle ja tem radius fixos (4px/50%)."
1789
+ },
1790
+ {
1791
+ "name": "count",
1792
+ "type": "number",
1793
+ "default": "1",
1794
+ "description": "Repeticoes. Aplicado em variants que aceitam multiplos (row/list-item/line)."
1795
+ },
1796
+ {
1797
+ "name": "ariaLabel",
1798
+ "type": "string",
1799
+ "default": "'Carregando...'",
1800
+ "description": "Aria-label para screen readers."
1801
+ }
1802
+ ],
1803
+ "outputs": [],
1804
+ "examples": [
1805
+ "<ds-skeleton variant=\"line\" width=\"80%\" />",
1806
+ "<ds-skeleton variant=\"circle\" width=\"40px\" />",
1807
+ "<ds-skeleton variant=\"card\" />",
1808
+ "<ds-skeleton variant=\"row\" [count]=\"5\" />",
1809
+ "<ds-skeleton variant=\"statsbar\" />"
1810
+ ]
1811
+ },
1812
+ {
1813
+ "name": "DropdownMenuComponent",
1814
+ "selector": "ds-dropdown-menu",
1815
+ "description": "Overlay menu reusavel ancorado num trigger projetado (button kebab, link, etc). Implementacao via CDK Overlay (FlexibleConnectedPositionStrategy) — fecha em click fora, ESC, e click no item. Items podem ser action button, divider (separator) ou header (section title nao-clicavel). Suporte multi-select via 'keepOpen' (item nao fecha menu ao click). Usado em header do <ds-card variant='dashboard'> (botao kebab), filtros de listagem, account dropdown.",
1816
+ "tags": [
1817
+ "dropdown",
1818
+ "menu",
1819
+ "overlay",
1820
+ "kebab",
1821
+ "actions",
1822
+ "options",
1823
+ "contextual"
1824
+ ],
1825
+ "props": [
1826
+ {
1827
+ "name": "items",
1828
+ "type": "DropdownMenuItem[]",
1829
+ "required": true,
1830
+ "description": "Array de items (action/divider/header). Cada item: {key, label, icon?, iconImageSrc?, variant?, disabled?, divider?, header?, keepOpen?}."
1831
+ },
1832
+ {
1833
+ "name": "position",
1834
+ "type": "DropdownMenuPosition",
1835
+ "default": "'bottom-end'",
1836
+ "description": "Posicao relativa ao trigger: bottom-start | bottom-end | top-start | top-end."
1837
+ },
1838
+ {
1839
+ "name": "ariaLabel",
1840
+ "type": "string",
1841
+ "default": "'Menu de opcoes'",
1842
+ "description": "Aria-label do menu."
1843
+ },
1844
+ {
1845
+ "name": "minWidth",
1846
+ "type": "string",
1847
+ "default": "'180px'",
1848
+ "description": "Largura minima CSS (ex: '180px', '240px')."
1849
+ }
1850
+ ],
1851
+ "outputs": [
1852
+ {
1853
+ "name": "itemSelect",
1854
+ "type": "EventEmitter<string>",
1855
+ "description": "Emitido com a `key` do item selecionado."
1856
+ },
1857
+ {
1858
+ "name": "openChange",
1859
+ "type": "EventEmitter<boolean>",
1860
+ "description": "Emitido quando estado open/close muda."
1861
+ }
1862
+ ],
1863
+ "publicMethods": [
1864
+ {
1865
+ "name": "toggle",
1866
+ "signature": "(): void",
1867
+ "description": "Toggle aberto/fechado. Public para uso imperativo via @ViewChild."
1868
+ },
1869
+ {
1870
+ "name": "open",
1871
+ "signature": "(): void",
1872
+ "description": "Abre o dropdown imperativamente."
1873
+ },
1874
+ {
1875
+ "name": "close",
1876
+ "signature": "(): void",
1877
+ "description": "Fecha o dropdown imperativamente."
1878
+ }
1879
+ ],
1880
+ "examples": [
1881
+ "<ds-dropdown-menu [items]=\"menuItems\" position=\"bottom-end\" (itemSelect)=\"onMenuClick($event)\"><button trigger>⋮</button></ds-dropdown-menu>",
1882
+ "// Items com divider e variant:\n[{key:'edit',label:'Editar',icon:'heroPencil'},{key:'_',divider:true,label:''},{key:'delete',label:'Excluir',icon:'heroTrash',variant:'danger'}]"
1883
+ ]
1884
+ },
1885
+ {
1886
+ "name": "PipelineFunnelComponent",
1887
+ "selector": "ds-pipeline-funnel",
1888
+ "description": "Lista vertical de buckets com label + value + delta + barra de progresso colorida. Reusa <ds-progress-bar> internamente — todas as 8 variants de cor disponiveis. Cada item renderiza: [label] [value deltaPercent% up/down] em cima + progress bar colorida embaixo. Suporta polaridade invertida (deltaPercent up vira vermelho — util quando aumento e ruim, ex: tickets em aberto). Usado em cards 'Funil de Vendas' (Figma 1042:28755) e 'Pipeline SDR IA' (Figma 1042:28890) do dashboard.",
1889
+ "tags": [
1890
+ "pipeline",
1891
+ "funnel",
1892
+ "kpi",
1893
+ "dashboard",
1894
+ "progress",
1895
+ "sdr",
1896
+ "sales",
1897
+ "vertical-list"
1898
+ ],
1899
+ "props": [
1900
+ {
1901
+ "name": "items",
1902
+ "type": "PipelineFunnelItem[]",
1903
+ "required": true,
1904
+ "description": "Array de buckets. Cada item: {key, label, value, percent (0-100), variant (ProgressBarVariant), deltaPercent?, deltaDirection?, inversePolarity?, labelColor?}."
1905
+ },
1906
+ {
1907
+ "name": "ariaLabel",
1908
+ "type": "string",
1909
+ "default": "'Pipeline de etapas'",
1910
+ "description": "Aria-label do container."
1911
+ }
1912
+ ],
1913
+ "outputs": [],
1914
+ "examples": [
1915
+ "<ds-pipeline-funnel [items]=\"funilItems\" />",
1916
+ "// Items com polaridade invertida (tickets em aberto):\n[{key:'open',label:'Em aberto',value:42,percent:80,variant:'danger',deltaPercent:15,deltaDirection:'up',inversePolarity:true}]"
1917
+ ]
1918
+ }
1919
+ ],
1920
+ "services": [
1921
+ {
1922
+ "name": "ToastService",
1923
+ "providedIn": "root",
1924
+ "description": "Service global de notificações toastr-style. Singleton. API pública simples: 4 métodos por variant — toast.success(msg), toast.info(msg), toast.warning(msg), toast.error(msg). Sem options object por chamada (decisão A1). Duração fixa por variant: 4s para success/info/warning, 6s para error. Max 5 toasts simultâneos (FIFO drop quando excedido). Dismiss manual via botão X cancela timer interno. Renderizado pelo <ds-toast-host /> que vive no shell da app.",
1925
+ "tags": [
1926
+ "toast",
1927
+ "notification",
1928
+ "service",
1929
+ "feedback"
1930
+ ],
1931
+ "methods": [
1932
+ {
1933
+ "name": "success",
1934
+ "signature": "(message: string): void",
1935
+ "description": "Notificação verde. Auto-destroy 4s."
1936
+ },
1937
+ {
1938
+ "name": "info",
1939
+ "signature": "(message: string): void",
1940
+ "description": "Notificação azul. Auto-destroy 4s."
1941
+ },
1942
+ {
1943
+ "name": "warning",
1944
+ "signature": "(message: string): void",
1945
+ "description": "Notificação laranja. Auto-destroy 4s."
1946
+ },
1947
+ {
1948
+ "name": "error",
1949
+ "signature": "(message: string): void",
1950
+ "description": "Notificação vermelha. Auto-destroy 6s (mais tempo para ler)."
1951
+ },
1952
+ {
1953
+ "name": "dismiss",
1954
+ "signature": "(id: number): void",
1955
+ "description": "Dismiss programático pelo id. Usado internamente pelo <ds-toast> ao receber click no X."
1956
+ }
1957
+ ],
1958
+ "examples": [
1959
+ "import { ToastService } from '@/design-system';",
1960
+ "",
1961
+ "export class MyComponent {",
1962
+ " private readonly toast = inject(ToastService);",
1963
+ "",
1964
+ " onSave() {",
1965
+ " this.api.save().subscribe({",
1966
+ " next: () => this.toast.success('Salvo!'),",
1967
+ " error: () => this.toast.error('Falha ao salvar.'),",
1968
+ " });",
1969
+ " }",
1970
+ "}"
1971
+ ]
1972
+ },
1973
+ {
1974
+ "name": "NavigationHistoryService",
1975
+ "providedIn": "root",
1976
+ "description": "Service singleton que rastreia o histórico de navegação do Angular Router. Mantém duas pilhas (pastUrls + futureUrls) sincronizadas com o browser via NavigationStart trigger detection (imperative vs popstate). <ds-page-header> consome canGoBack()/canGoForward() automaticamente para habilitar/desabilitar os botões voltar/avançar. Stack limitado a 50 entradas (FIFO). SSR-safe: sem Router fica no-op silencioso. Caller chama reset() após CRUD create para zerar o histórico.",
1977
+ "tags": [
1978
+ "navigation",
1979
+ "history",
1980
+ "router",
1981
+ "service",
1982
+ "back-button"
1983
+ ],
1984
+ "signals": [
1985
+ {
1986
+ "name": "canGoBack",
1987
+ "type": "Signal<boolean>",
1988
+ "description": "True quando há URL anterior na pilha (botão back habilita)."
1989
+ },
1990
+ {
1991
+ "name": "canGoForward",
1992
+ "type": "Signal<boolean>",
1993
+ "description": "True quando há URL futura disponível após back() (botão forward habilita)."
1994
+ },
1995
+ {
1996
+ "name": "pastUrls",
1997
+ "type": "Signal<string[]>",
1998
+ "description": "Snapshot read-only da pilha de URLs anteriores."
1999
+ },
2000
+ {
2001
+ "name": "futureUrls",
2002
+ "type": "Signal<string[]>",
2003
+ "description": "Snapshot read-only da pilha de URLs futuras."
2004
+ },
2005
+ {
2006
+ "name": "currentUrl",
2007
+ "type": "Signal<string | null>",
2008
+ "description": "URL atual rastreada (null antes da primeira NavigationEnd)."
2009
+ }
2010
+ ],
2011
+ "methods": [
2012
+ {
2013
+ "name": "back",
2014
+ "signature": "(): void",
2015
+ "description": "Navega para a URL anterior usando o Router. NOOP se !canGoBack."
2016
+ },
2017
+ {
2018
+ "name": "forward",
2019
+ "signature": "(): void",
2020
+ "description": "Navega para a URL futura. NOOP se !canGoForward."
2021
+ },
2022
+ {
2023
+ "name": "reset",
2024
+ "signature": "(): void",
2025
+ "description": "Limpa ambas as pilhas. Chamar após CRUD create — desabilita o botão back até navegar novamente."
2026
+ }
2027
+ ],
2028
+ "examples": [
2029
+ "import { NavigationHistoryService } from '@/design-system';",
2030
+ "",
2031
+ "export class CourseCreatePage {",
2032
+ " private readonly navHistory = inject(NavigationHistoryService);",
2033
+ " private readonly router = inject(Router);",
2034
+ "",
2035
+ " async onSave() {",
2036
+ " await this.api.create(this.form.value);",
2037
+ " this.navHistory.reset(); // botão back desabilita",
2038
+ " void this.router.navigate(['/courses']);",
2039
+ " }",
2040
+ "}",
2041
+ "",
2042
+ "<!-- O <ds-page-header> consome o service automaticamente: -->",
2043
+ "<ds-page-header title=\"Cursos\" />"
2044
+ ]
356
2045
  }
357
2046
  ]
358
2047
  }