@inchurch/matcha-theme 20.0.8 → 20.276.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.
Files changed (99) hide show
  1. package/abstracts/_colors.scss +404 -404
  2. package/abstracts/_elevation.scss +102 -102
  3. package/abstracts/_functions.scss +1212 -1212
  4. package/abstracts/_media-breakpoint.scss +23 -23
  5. package/abstracts/_typography.scss +127 -127
  6. package/base/_reset.scss +438 -438
  7. package/components/app-page-header.scss +260 -0
  8. package/components/matcha-accordion.scss +294 -157
  9. package/components/matcha-avatar.scss +171 -31
  10. package/components/matcha-badge.scss +4 -4
  11. package/components/matcha-breadcrumb.scss +232 -126
  12. package/components/matcha-button-toggle.scss +44 -0
  13. package/components/matcha-buttons.scss +908 -784
  14. package/components/matcha-calendar.scss +70 -2
  15. package/components/matcha-cards.scss +28 -2
  16. package/components/matcha-checkbox.scss +191 -490
  17. package/components/matcha-chip.scss +297 -212
  18. package/components/matcha-command-palette.scss +291 -63
  19. package/components/matcha-crop.scss +407 -172
  20. package/components/matcha-date.scss +81 -81
  21. package/components/matcha-divider.scss +86 -31
  22. package/components/matcha-drawer.scss +201 -50
  23. package/components/matcha-drop-image.scss +14 -0
  24. package/components/matcha-drop-list.scss +42 -1
  25. package/components/matcha-empty-state.scss +195 -83
  26. package/components/matcha-flag.scss +93 -52
  27. package/components/matcha-footer.scss +68 -164
  28. package/components/matcha-form-field.scss +52 -0
  29. package/components/matcha-form-section.scss +101 -101
  30. package/components/matcha-header.scss +135 -325
  31. package/components/matcha-highlight.scss +65 -197
  32. package/components/matcha-hint-text.scss +21 -0
  33. package/components/matcha-horizontal-tree.scss +317 -317
  34. package/components/matcha-icon.scss +17 -25
  35. package/components/matcha-list.scss +5 -5
  36. package/components/matcha-menu.scss +13 -0
  37. package/components/matcha-modal.scss +58 -84
  38. package/components/matcha-nav.scss +361 -230
  39. package/components/matcha-notification.scss +413 -197
  40. package/components/matcha-option.scss +79 -23
  41. package/components/matcha-paginator.scss +689 -235
  42. package/components/matcha-panel.scss +42 -26
  43. package/components/matcha-profile-card.scss +50 -50
  44. package/components/matcha-progress-bar.scss +257 -153
  45. package/components/matcha-radio.scss +244 -452
  46. package/components/matcha-scrollbox-shadow.scss +122 -122
  47. package/components/matcha-select.scss +3 -3
  48. package/components/matcha-skeleton.scss +18 -0
  49. package/components/matcha-slide-toggle.scss +47 -2
  50. package/components/matcha-slider.scss +172 -75
  51. package/components/matcha-snack-bar.scss +114 -121
  52. package/components/matcha-spinner.scss +76 -57
  53. package/components/matcha-status-pill.scss +82 -0
  54. package/components/matcha-stepper.scss +377 -177
  55. package/components/matcha-table.scss +569 -785
  56. package/components/matcha-tabs.scss +624 -469
  57. package/components/matcha-text-editor.scss +98 -144
  58. package/components/matcha-toolbar.scss +359 -206
  59. package/components/matcha-tooltip.scss +156 -62
  60. package/components/matcha-tree-view.scss +189 -0
  61. package/components/matcha-uploader.scss +240 -62
  62. package/fonts/manrope/manrope-latin-ext.woff2 +0 -0
  63. package/fonts/manrope/manrope-latin.woff2 +0 -0
  64. package/layout/matcha-page-layout.scss +776 -0
  65. package/main.scss +232 -261
  66. package/package.json +1 -1
  67. package/tokens/_animations-tokens.scss +37 -37
  68. package/tokens/_breakpoints-tokens.scss +35 -26
  69. package/tokens/_color-tokens.scss +1152 -1152
  70. package/tokens/_css-custom-properties.scss +650 -568
  71. package/tokens/_spacing-tokens.scss +94 -94
  72. package/vendors/angular-editor.scss +56 -56
  73. package/vendors/angular-material-fixes.scss +297 -297
  74. package/vendors/charts.scss +92 -92
  75. package/vendors/ng5-slider.scss +56 -56
  76. package/vendors/ngx-material-timepicker.scss +50 -50
  77. package/fonts/CircularStd-Black.eot +0 -0
  78. package/fonts/CircularStd-Black.svg +0 -3426
  79. package/fonts/CircularStd-Black.ttf +0 -0
  80. package/fonts/CircularStd-Black.woff +0 -0
  81. package/fonts/CircularStd-Black.woff2 +0 -0
  82. package/fonts/CircularStd-Bold.eot +0 -0
  83. package/fonts/CircularStd-Bold.otf +0 -0
  84. package/fonts/CircularStd-Bold.svg +0 -13532
  85. package/fonts/CircularStd-Bold.ttf +0 -0
  86. package/fonts/CircularStd-Bold.woff +0 -0
  87. package/fonts/CircularStd-Bold.woff2 +0 -0
  88. package/fonts/CircularStd-Medium.eot +0 -0
  89. package/fonts/CircularStd-Medium.otf +0 -0
  90. package/fonts/CircularStd-Medium.svg +0 -13511
  91. package/fonts/CircularStd-Medium.ttf +0 -0
  92. package/fonts/CircularStd-Medium.woff +0 -0
  93. package/fonts/CircularStd-Medium.woff2 +0 -0
  94. package/fonts/CircularStd-Regular.eot +0 -0
  95. package/fonts/CircularStd-Regular.otf +0 -0
  96. package/fonts/CircularStd-Regular.svg +0 -2378
  97. package/fonts/CircularStd-Regular.ttf +0 -0
  98. package/fonts/CircularStd-Regular.woff +0 -0
  99. package/fonts/CircularStd-Regular.woff2 +0 -0
@@ -10,46 +10,71 @@
10
10
  align-items: center;
11
11
  justify-content: center;
12
12
  position: relative;
13
- overflow: hidden;
13
+ // SEM overflow:hidden — o status indicator fica no canto fora do círculo
14
+ // visível e seria cortado. A <img> com border-radius inherit já se arredonda
15
+ // sozinha; SVG e Initials ficam dentro dos bounds.
14
16
  border-radius: var(--matcha-radius-pill, 9999px);
15
17
 
16
18
  font-weight: var(--matcha-weight-medium, 500);
17
19
  user-select: none;
18
20
  flex-shrink: 0;
21
+ }
22
+
23
+ // =============================================================================
24
+ // Ring colored (additive) — controlado pelo [ring] @Input do component.
25
+ // 2px solid + halo alpha externo. Não ocupa layout (box-shadow puro).
26
+ //
27
+ // Aplicado no .matcha-avatar INNER (não no host) porque o inner é quem tem
28
+ // width/height/border-radius:pill — box-shadow segue o radius desse elemento
29
+ // e renderiza circular. No host (inline default) sairia retangular.
30
+ // =============================================================================
31
+ matcha-avatar[ring] .matcha-avatar {
32
+ box-shadow:
33
+ 0 0 0 2px transparent,
34
+ 0 0 0 3px var(--matcha-avatar-ring-color, currentColor);
35
+ }
19
36
 
20
- // ── Sizes (aligned with Figma) ──
37
+ matcha-avatar[ring]:not([ring="neutral"]) .matcha-avatar {
38
+ box-shadow:
39
+ 0 0 0 2px transparent,
40
+ 0 0 0 3px var(--matcha-avatar-ring-color, currentColor),
41
+ 0 0 0 5px var(--matcha-avatar-ring-halo, transparent);
42
+ }
43
+
44
+ // ── Variants (sizes, initials, icon, disabled) — nested em .matcha-avatar pra
45
+ // usar `&.matcha-avatar-*` syntax. Bloco separado do base styles (linha 8-21)
46
+ // porque matcha-avatar[ring] (acima) é regra absoluta, não nested.
47
+ .matcha-avatar {
48
+ // ── Sizes — Canonical 5-step scale: tiny 24 · small 40 · medium 56 · large 80 · huge 96.
49
+ // Abbreviations kept as @deprecated aliases, mapped BY PIXEL SIZE (old 32px `sm` dropped → tiny).
50
+ // NOTE: --matcha-avatar-* tokens still carry the legacy abbreviated names; re-tier them to
51
+ // tiny/small/medium/large/huge on the Figma/DSV3 side (token rename is design-driven).
52
+ &.matcha-avatar-tiny,
21
53
  &.matcha-avatar-xs,
22
- &.matcha-avatar-tiny {
54
+ &.matcha-avatar-sm {
23
55
  width: var(--matcha-avatar-xs, 24px);
24
56
  height: var(--matcha-avatar-xs, 24px);
25
57
  font-size: var(--matcha-text-2xs, 10px);
26
58
  line-height: 1;
27
59
  }
28
60
 
29
- &.matcha-avatar-sm,
30
- &.matcha-avatar-small {
31
- width: var(--matcha-avatar-sm, 32px);
32
- height: var(--matcha-avatar-sm, 32px);
33
- font-size: var(--matcha-text-sm, 12px);
34
- line-height: 1;
35
- }
36
-
37
- &.matcha-avatar-md,
38
- &.matcha-avatar-medium {
61
+ &.matcha-avatar-small,
62
+ &.matcha-avatar-md {
39
63
  width: var(--matcha-avatar-md, 40px);
40
64
  height: var(--matcha-avatar-md, 40px);
41
65
  font-size: var(--matcha-text-md, 14px);
42
66
  line-height: 1;
43
67
  }
44
68
 
45
- &.matcha-avatar-lg,
46
- &.matcha-avatar-large {
69
+ &.matcha-avatar-medium,
70
+ &.matcha-avatar-lg {
47
71
  width: var(--matcha-avatar-lg, 56px);
48
72
  height: var(--matcha-avatar-lg, 56px);
49
73
  font-size: var(--matcha-text-2xl, 20px);
50
74
  line-height: 1;
51
75
  }
52
76
 
77
+ &.matcha-avatar-large,
53
78
  &.matcha-avatar-xl {
54
79
  width: var(--matcha-avatar-xl, 80px);
55
80
  height: var(--matcha-avatar-xl, 80px);
@@ -57,8 +82,8 @@
57
82
  line-height: 1;
58
83
  }
59
84
 
60
- &.matcha-avatar-2xl,
61
- &.matcha-avatar-huge {
85
+ &.matcha-avatar-huge,
86
+ &.matcha-avatar-2xl {
62
87
  width: var(--matcha-avatar-2xl, 96px);
63
88
  height: var(--matcha-avatar-2xl, 96px);
64
89
  font-size: var(--matcha-text-4xl, 32px);
@@ -94,14 +119,94 @@
94
119
  }
95
120
  }
96
121
 
122
+ // ── Placeholder — vazado canônico (Figma matcha/avatar 5668:32088) ──────────
123
+ // SVG usa fill-rule=evenodd: disco preenchido com currentColor + silhueta vazada.
124
+ // `currentColor` do disco precisa ser a COR DA MARCA (não o contrast da .color class
125
+ // global, que é branco/preto). Override aqui força o token de palette.
126
+ .matcha-avatar.matcha-avatar--placeholder {
127
+ background: transparent !important;
128
+
129
+ &.light-blue { color: var(--matcha-color-palette-light-blue) !important; }
130
+ &.pink { color: var(--matcha-color-palette-pink) !important; }
131
+ &.teal { color: var(--matcha-color-palette-teal) !important; }
132
+ &.purple { color: var(--matcha-color-palette-purple) !important; }
133
+ &.orange { color: var(--matcha-color-palette-orange) !important; }
134
+ &.yellow { color: var(--matcha-color-palette-yellow) !important; }
135
+ &.neutral { color: var(--matcha-color-icon-default) !important; }
136
+ }
137
+
138
+ // Neutral em Initials — cinza canônico Figma (icon-default).
139
+ .matcha-avatar:not(.matcha-avatar--placeholder).neutral {
140
+ background: var(--matcha-color-icon-default);
141
+ }
142
+
143
+ // ── Initials — bg + fg por palette canônica Figma DSV3 (6 cores) ────────────
144
+ // O palette inverte por tema (light=tons saturados, dark=tons claros). text-primary
145
+ // também inverte (#1a1d21 light / #e8eaed dark). Combinar os dois → contraste péssimo
146
+ // em dark mode (1.2-2.9:1 FAIL). Por isso fg é fixed-per-color, não token-based.
147
+ //
148
+ // Light mode: pink/teal/purple bg escuros → fg branco. light-blue/orange/yellow bg
149
+ // claros → fg preto (light-blue precisa #000 puro pra AA por 0.08).
150
+ // Dark mode: todos os bg ficam lighter → fg preto funciona em tudo (5-12:1).
151
+
152
+ .matcha-avatar:not(.matcha-avatar--placeholder) {
153
+ // Backgrounds (mesmo seletor pros 2 temas — palette token já inverte sozinho).
154
+ &.light-blue { background: var(--matcha-color-palette-light-blue); }
155
+ &.pink { background: var(--matcha-color-palette-pink); }
156
+ &.teal { background: var(--matcha-color-palette-teal); }
157
+ &.purple { background: var(--matcha-color-palette-purple); }
158
+ &.orange { background: var(--matcha-color-palette-orange); }
159
+ &.yellow { background: var(--matcha-color-palette-yellow); }
160
+ }
161
+
162
+ // Light mode — bgs saturados (pink/teal/purple = escuros), fg branco passa AA.
163
+ // orange/yellow/light-blue = claros, fg precisa ser dark (#000 pra light-blue por margem).
164
+ .theme-default-light .matcha-avatar:not(.matcha-avatar--placeholder) {
165
+ &.light-blue { color: #000; } // 5.42:1 AA
166
+ &.pink { color: #fff; } // 4.95:1 AA
167
+ &.teal { color: #fff; } // 5.32:1 AA
168
+ &.purple { color: #fff; } // 6.30:1 AA
169
+ &.orange { color: #1a1a1a; } // 4.59:1 AA
170
+ &.yellow { color: #1a1a1a; } // 8.52:1 AAA
171
+ &.neutral { color: #fff; } // icon-default #5f656b vs #fff = 5.18:1 AA
172
+ }
173
+
174
+ // Dark mode — todos os bgs ficam lighter (#54c5f7, #e46291, #4fb7ad, etc).
175
+ // Texto branco falha em todos. Texto dark funciona em todos.
176
+ .theme-default-dark .matcha-avatar:not(.matcha-avatar--placeholder) {
177
+ &.light-blue { color: #1a1a1a; } // 8.87:1 AAA
178
+ &.pink { color: #1a1a1a; } // 5.35:1 AA
179
+ &.teal { color: #1a1a1a; } // 7.22:1 AAA
180
+ &.purple { color: #1a1a1a; } // 4.98:1 AA
181
+ &.orange { color: #1a1a1a; } // 8.58:1 AAA
182
+ &.yellow { color: #1a1a1a; } // 11.94:1 AAA
183
+ &.neutral { color: #1a1a1a; } // icon-default #9aa0a6 vs #1a1a1a = 5.97:1 AA
184
+ }
185
+
186
+ // ── Screen reader only utility (visualmente oculto, lido por AT) ────────────
187
+ .matcha-avatar-sr-only {
188
+ position: absolute;
189
+ width: 1px;
190
+ height: 1px;
191
+ padding: 0;
192
+ margin: -1px;
193
+ overflow: hidden;
194
+ clip: rect(0, 0, 0, 0);
195
+ white-space: nowrap;
196
+ border: 0;
197
+ }
198
+
97
199
  // ── Status indicator ────────────────────────────────────────────────────────
200
+ // Cores estruturais (online/offline/busy) ficam fora do mixin pra renderizar
201
+ // independente de classe de tema (`theme-default-light`, etc.). Tokens com
202
+ // fallback hardcoded resolvem o caso de tema não inicializado.
98
203
 
99
204
  .matcha-avatar-status {
100
205
  position: absolute;
101
206
  bottom: 0;
102
207
  right: 0;
103
208
  border-radius: var(--matcha-radius-pill, 9999px);
104
- border: var(--matcha-border-thin, 2px) solid var(--matcha-color-surface, white);
209
+ border: var(--matcha-border-thin, 2px) solid var(--matcha-color-surface-card, #fff);
105
210
  box-sizing: border-box;
106
211
 
107
212
  // Size scales with avatar
@@ -121,41 +226,76 @@
121
226
 
122
227
  .matcha-avatar-2xl &,
123
228
  .matcha-avatar-huge & { width: var(--matcha-avatar-status-2xl, 18px); height: var(--matcha-avatar-status-2xl, 18px); }
229
+
230
+ // Cores estruturais — fallback hardcoded pra funcionar mesmo sem tema.
231
+ &.matcha-avatar-status--online { background-color: var(--matcha-color-success, #16a34a); }
232
+ &.matcha-avatar-status--offline { background-color: var(--matcha-color-text-placeholder, #9ca3af); }
233
+ &.matcha-avatar-status--busy { background-color: var(--matcha-color-danger, #dc2626); }
124
234
  }
125
235
 
126
236
  // ── Theme mixin ─────────────────────────────────────────────────────────────
127
237
 
128
238
  @mixin matcha-avatar-theme($theme) {
129
239
  .matcha-avatar {
130
- .matcha-avatar-icon {
131
- color: var(--matcha-color-text-placeholder, #{getGrey($theme)});
132
- }
240
+ // Placeholder: SVG usa fill="currentColor" e herda do host. A classe de
241
+ // cor (.blue/.orange/etc) define color=foreground + background=cor cheia,
242
+ // então o icon vazado fica visível na cor escolhida pelo usuário.
243
+ // Sem fallback hardcoded aqui — quando o user não passa color, o @Input
244
+ // default 'blue' resolve via .blue do matcha-style.css.
133
245
 
134
246
  &.matcha-avatar--disabled,
135
247
  &.color-disabled {
136
248
  background-color: var(--matcha-color-disabled-bg, #{getDisabled($theme)});
137
249
  color: var(--matcha-color-disabled-fg, #{getDisabledContrast($theme)});
138
-
139
- .matcha-avatar-icon {
140
- color: var(--matcha-color-disabled-fg, #{getDisabledContrast($theme)});
141
- }
142
250
  }
143
251
  }
144
252
 
145
- // ── Status colors ──
253
+ // Status border-color por tema (estrutural já resolve cores de fundo via tokens).
146
254
  .matcha-avatar-status {
147
- border-color: var(--matcha-color-surface, #{getSurface($theme)});
255
+ border-color: var(--matcha-color-surface-card, #{getSurface($theme)});
256
+ }
257
+ }
258
+
259
+ // =============================================================================
260
+ // A11y / modernity media queries
261
+ // =============================================================================
148
262
 
149
- &.matcha-avatar-status--online {
150
- background-color: var(--matcha-color-success, #{getSuccess($theme)});
263
+ // Forced colors (Windows High Contrast) — bg colors podem virar invisíveis,
264
+ // usar SelectedItem/Highlight pros estados, CanvasText/Canvas pra borders.
265
+ @media (forced-colors: active) {
266
+ .matcha-avatar {
267
+ border: 1px solid CanvasText;
268
+
269
+ &.matcha-avatar--disabled,
270
+ &.color-disabled {
271
+ opacity: 0.5;
272
+ border-color: GrayText;
151
273
  }
274
+ }
275
+
276
+ // Status dot — em high-contrast as 3 cores ficam idênticas. Compensamos
277
+ // com pattern visual: online=fill, offline=outline, busy=outline duplo.
278
+ .matcha-avatar-status {
279
+ background: SelectedItem !important;
280
+ border: 2px solid Canvas !important;
152
281
 
153
282
  &.matcha-avatar-status--offline {
154
- background-color: var(--matcha-color-text-placeholder, #{getGrey($theme)});
283
+ background: Canvas !important;
284
+ border: 2px solid CanvasText !important;
155
285
  }
156
286
 
157
287
  &.matcha-avatar-status--busy {
158
- background-color: var(--matcha-color-danger, #{getDanger($theme)});
288
+ background: SelectedItem !important;
289
+ box-shadow: 0 0 0 2px Canvas, 0 0 0 4px CanvasText;
159
290
  }
160
291
  }
161
292
  }
293
+
294
+ // Reduced motion — mata todas transitions/animations.
295
+ @media (prefers-reduced-motion: reduce) {
296
+ .matcha-avatar,
297
+ .matcha-avatar-status {
298
+ transition: none !important;
299
+ animation: none !important;
300
+ }
301
+ }
@@ -44,8 +44,8 @@
44
44
  min-width: var(--matcha-space-250, 20px);
45
45
  height: var(--matcha-space-250, 20px);
46
46
  padding: 1px var(--matcha-space-050, 4px);
47
- font-size: var(--matcha-text-caption, 11px);
48
- line-height: var(--matcha-leading-caption, 14px);
47
+ font-size: var(--matcha-text-p-tiny, 11px);
48
+ line-height: var(--matcha-leading-p-tiny, 14px);
49
49
  font-weight: var(--matcha-weight-regular, 400);
50
50
  letter-spacing: 0;
51
51
  border-width: var(--matcha-border-thin, 2px);
@@ -56,8 +56,8 @@
56
56
  .matcha-badge--label {
57
57
  position: static;
58
58
  padding: var(--matcha-space-025, 2px) var(--matcha-space-100, 8px);
59
- font-size: var(--matcha-text-caption, 11px);
60
- line-height: var(--matcha-leading-caption, 14px);
59
+ font-size: var(--matcha-text-p-tiny, 11px);
60
+ line-height: var(--matcha-leading-p-tiny, 14px);
61
61
  font-weight: var(--matcha-weight-regular, 400);
62
62
  gap: var(--matcha-space-050, 4px);
63
63
  }
@@ -1,126 +1,232 @@
1
- @use "sass:map";
2
-
3
- // =============================================================================
4
- // matcha-breadcrumb.scss — Navigation breadcrumb trail
5
- // Aligned with Figma matcha/breadcrumb/item:
6
- // Estado(3: Link, Atual, Disabled) × Ícone?(2: Yes, No)
7
- // Separator: matcha/icon/chevron (Right) between items
8
- // =============================================================================
9
-
10
- @mixin matcha-breadcrumb-theme($theme) {
11
- $is-dark: map.get($theme, is-dark);
12
-
13
- matcha-breadcrumb {
14
- // ── Link items ──
15
- .breadcrumb-item-link {
16
- background: var(--matcha-color-surface-2, #{getSurfaceAlpha($theme)});
17
- color: var(--matcha-color-text-label, #{getBlueGrey($theme)});
18
-
19
- &:hover:not([disabled]):not(.disabled) {
20
- .breadcrumb-state {
21
- opacity: var(--matcha-state-hover, 0.08);
22
- }
23
- }
24
-
25
- &:active:not([disabled]):not(.disabled) {
26
- .breadcrumb-state {
27
- opacity: var(--matcha-state-active, 0.12);
28
- }
29
- }
30
-
31
- &:focus-visible {
32
- outline: var(--matcha-state-focus-ring-width, 2px) solid var(--matcha-color-accent, #{getAccent($theme)});
33
- outline-offset: var(--matcha-state-focus-ring-offset, 2px);
34
- }
35
- }
36
-
37
- // ── Current page ──
38
- .breadcrumb-item-current {
39
- color: var(--matcha-color-fg, #{getForeground($theme)});
40
- }
41
-
42
- // ── Separator ──
43
- .breadcrumb-separator {
44
- color: var(--matcha-color-text-label, #{getBlueGrey($theme)});
45
- }
46
-
47
- // ── Disabled ──
48
- .breadcrumb-item-link.disabled {
49
- opacity: 0.5;
50
- pointer-events: none;
51
- }
52
- }
53
- }
54
-
55
- // ── Layout ──────────────────────────────────────────────────────────────────
56
-
57
- matcha-breadcrumb {
58
- display: flex;
59
- align-items: center;
60
- gap: var(--matcha-space-100, 8px);
61
-
62
- // ── Breadcrumb item (link) ──
63
- .breadcrumb-item-link {
64
- display: flex;
65
- align-items: center;
66
- gap: var(--matcha-space-100, 8px);
67
- padding: var(--matcha-space-150, 12px);
68
- border: none;
69
- border-radius: var(--matcha-radius-lg, 8px);
70
- cursor: pointer;
71
- font-family: var(--matcha-font-family);
72
- font-size: var(--matcha-text-body-md, 14px);
73
- font-weight: var(--matcha-weight-regular, 400);
74
- line-height: var(--matcha-leading-body-md, 20px);
75
- white-space: nowrap;
76
- text-decoration: none;
77
- position: relative;
78
- overflow: hidden;
79
-
80
- // State layer
81
- .breadcrumb-state {
82
- position: absolute;
83
- inset: 0;
84
- background: currentColor;
85
- opacity: 0;
86
- border-radius: inherit;
87
- pointer-events: none;
88
- transition: opacity var(--matcha-duration-instant, 80ms) linear;
89
- }
90
-
91
- matcha-icon {
92
- flex-shrink: 0;
93
- }
94
- }
95
-
96
- // ── Current page ──
97
- .breadcrumb-item-current {
98
- display: flex;
99
- align-items: center;
100
- gap: var(--matcha-space-100, 8px);
101
- padding: var(--matcha-space-150, 12px) 0;
102
- font-family: var(--matcha-font-family);
103
- font-size: var(--matcha-text-body-md, 14px);
104
- font-weight: var(--matcha-weight-medium, 500);
105
- line-height: var(--matcha-leading-body-md, 20px);
106
- white-space: nowrap;
107
-
108
- matcha-icon {
109
- flex-shrink: 0;
110
- }
111
- }
112
-
113
- // ── Separator ──
114
- .breadcrumb-separator {
115
- flex-shrink: 0;
116
- width: var(--matcha-icon-size-sm, 16px);
117
- height: var(--matcha-icon-size-sm, 16px);
118
- }
119
- }
120
-
121
- // ── Reduced motion ──────────────────────────────────────────────────────────
122
- @media (prefers-reduced-motion: reduce) {
123
- matcha-breadcrumb .breadcrumb-state {
124
- transition: none;
125
- }
126
- }
1
+ @use "sass:map";
2
+
3
+ // =============================================================================
4
+ // matcha-breadcrumb.scss — Navigation breadcrumb trail (Figma DSV3 15831:35)
5
+ //
6
+ // Estado(3: Link, Atual, Disabled) × Ícone?(2: Yes, No) = 6 variantes
7
+ // Link/Disabled — bg surface-2, p 12, radius lg, text/secondary, Regular 14/20
8
+ // Atual — sem bg, py 12 (sem px), text/primary, Medium 14/20
9
+ // Separador — matcha/icon/chevron variant=right entre itens
10
+ // =============================================================================
11
+
12
+ @mixin matcha-breadcrumb-theme($theme) {
13
+ $is-dark: map.get($theme, is-dark);
14
+
15
+ matcha-breadcrumb {
16
+ // ── Link items (clicáveis) ──
17
+ .breadcrumb-item-link {
18
+ // Figma DSV3: bg = matcha/color/elevation/surface-2 (canônico)
19
+ background: var(--matcha-color-elevation-surface-2, #{getSurfaceAlpha($theme)});
20
+ color: var(--matcha-color-text-secondary, #{getBlueGrey($theme)});
21
+
22
+ &:hover:not([disabled]):not(.disabled) {
23
+ .breadcrumb-state {
24
+ opacity: var(--matcha-state-hover, 0.08);
25
+ }
26
+ }
27
+
28
+ &:active:not([disabled]):not(.disabled) {
29
+ .breadcrumb-state {
30
+ opacity: var(--matcha-state-active, 0.12);
31
+ }
32
+ }
33
+
34
+ &:focus-visible {
35
+ outline: var(--matcha-state-focus-ring-width, 2px) solid var(--matcha-color-accent, #{getAccent($theme)});
36
+ outline-offset: var(--matcha-state-focus-ring-offset, 2px);
37
+ }
38
+ }
39
+
40
+ // ── Página atual ──
41
+ .breadcrumb-item-current {
42
+ color: var(--matcha-color-text-primary, #{getForeground($theme)});
43
+ }
44
+
45
+ // ── Separator (chevron) ──
46
+ .breadcrumb-separator {
47
+ color: var(--matcha-color-icon-default, #{getBlueGrey($theme)});
48
+ }
49
+
50
+ // ── Disabled (real disabled — não confundir com ellipsis) ──
51
+ .breadcrumb-item-link--disabled {
52
+ opacity: var(--matcha-opacity-disabled, 0.5);
53
+ pointer-events: none;
54
+ }
55
+
56
+ // ── Ellipsis (…) — visibilidade NORMAL (não é disabled).
57
+ // Quando clicável (maxItems ativo), tem hover/focus state-layer normal.
58
+ // Quando estático (--static), só muda cursor pra default.
59
+ .breadcrumb-ellipsis {
60
+ // Mantém color/bg do Link. Sem opacity reduzida.
61
+ color: var(--matcha-color-text-secondary, #{getBlueGrey($theme)});
62
+
63
+ &--static {
64
+ cursor: default;
65
+ pointer-events: none;
66
+ }
67
+ }
68
+ }
69
+ }
70
+
71
+ // ── Layout ──────────────────────────────────────────────────────────────────
72
+
73
+ matcha-breadcrumb {
74
+ display: flex;
75
+ align-items: center;
76
+ }
77
+
78
+ matcha-breadcrumb {
79
+ .breadcrumb-list {
80
+ display: flex;
81
+ align-items: center;
82
+ list-style: none;
83
+ margin: 0;
84
+ padding: 0;
85
+ gap: var(--matcha-space-100, 8px);
86
+ }
87
+
88
+ .breadcrumb-li {
89
+ display: flex;
90
+ align-items: center;
91
+ gap: var(--matcha-space-100, 8px);
92
+ }
93
+
94
+ // ── Item link (Link/Disabled/Ellipsis) ──
95
+ // Figma: pad 12, radius lg, gap 8 (com ícone) ou 0 (sem). gap controlado por
96
+ // `> matcha-icon + span` (presença do ícone como sibling).
97
+ .breadcrumb-item-link {
98
+ display: flex;
99
+ align-items: center;
100
+ gap: 0;
101
+ padding: var(--matcha-space-150, 12px);
102
+ border: none;
103
+ border-radius: var(--matcha-radius-lg, 8px);
104
+ cursor: pointer;
105
+ font-family: var(--matcha-font-family);
106
+ font-size: var(--matcha-text-body-md, 14px);
107
+ font-weight: var(--matcha-weight-regular, 400);
108
+ line-height: var(--matcha-leading-body-md, 20px);
109
+ text-decoration: none;
110
+ position: relative;
111
+ overflow: hidden;
112
+ box-sizing: border-box;
113
+
114
+ // Gap 8 só quando o ícone está presente (Figma: gap=0 sem ícone)
115
+ > matcha-icon + .breadcrumb-text {
116
+ margin-left: var(--matcha-space-100, 8px);
117
+ }
118
+
119
+ // State layer (hover/active overlay)
120
+ .breadcrumb-state {
121
+ position: absolute;
122
+ inset: 0;
123
+ background: currentColor;
124
+ opacity: 0;
125
+ border-radius: inherit;
126
+ pointer-events: none;
127
+ transition: opacity var(--matcha-duration-instant, 80ms) linear;
128
+ }
129
+
130
+ matcha-icon {
131
+ flex-shrink: 0;
132
+ }
133
+ }
134
+
135
+ // ── Página atual ──
136
+ // Figma: SEM bg, py 12 (sem px), Medium 500, gap 8/0 igual ao link.
137
+ .breadcrumb-item-current {
138
+ display: flex;
139
+ align-items: center;
140
+ gap: 0;
141
+ padding: var(--matcha-space-150, 12px) 0;
142
+ font-family: var(--matcha-font-family);
143
+ font-size: var(--matcha-text-body-md, 14px);
144
+ font-weight: var(--matcha-weight-medium, 500);
145
+ line-height: var(--matcha-leading-body-md, 20px);
146
+ box-sizing: border-box;
147
+
148
+ > matcha-icon + .breadcrumb-text {
149
+ margin-left: var(--matcha-space-100, 8px);
150
+ }
151
+
152
+ matcha-icon {
153
+ flex-shrink: 0;
154
+ }
155
+ }
156
+
157
+ // ── Texto do item — single-line + truncate quando max-width está setado ──
158
+ .breadcrumb-text {
159
+ overflow: hidden;
160
+ text-overflow: ellipsis;
161
+ white-space: nowrap;
162
+ min-width: 0;
163
+ display: inline-block;
164
+ max-width: 100%;
165
+ }
166
+
167
+ // ── Separator ──
168
+ .breadcrumb-separator {
169
+ flex-shrink: 0;
170
+ width: var(--matcha-icon-size-sm, 16px);
171
+ height: var(--matcha-icon-size-sm, 16px);
172
+ }
173
+ }
174
+
175
+ // ── Reduced motion ──────────────────────────────────────────────────────────
176
+ @media (prefers-reduced-motion: reduce) {
177
+ matcha-breadcrumb .breadcrumb-state {
178
+ transition: none;
179
+ }
180
+ }
181
+
182
+ // ── Mobile responsive ───────────────────────────────────────────────────────
183
+ // Em viewports estreitas, items longos sem maxWidth podem estourar. flex-wrap
184
+ // nowrap + overflow-x evita quebra de linha; consumer deve usar maxItems pra
185
+ // auto-truncar trail. Default sem max-width = nowrap horizontal (scroll se
186
+ // container permite, senão clip).
187
+ @media (max-width: 639px) {
188
+ matcha-breadcrumb .breadcrumb-list {
189
+ flex-wrap: nowrap;
190
+ overflow-x: auto;
191
+ overflow-y: hidden;
192
+ scrollbar-width: none; // Firefox
193
+ -ms-overflow-style: none; // IE/Edge legacy
194
+ &::-webkit-scrollbar { display: none; }
195
+ }
196
+ }
197
+
198
+ // ── Forced colors (Windows High Contrast) ──
199
+ @media (forced-colors: active) {
200
+ matcha-breadcrumb {
201
+ .breadcrumb-item-link {
202
+ background: Canvas !important;
203
+ color: LinkText !important;
204
+ border: 1px solid CanvasText;
205
+
206
+ &:hover, &:focus { color: ActiveText !important; }
207
+ }
208
+
209
+ .breadcrumb-item-current {
210
+ color: CanvasText !important;
211
+ background: transparent !important;
212
+ }
213
+
214
+ .breadcrumb-separator {
215
+ color: GrayText !important;
216
+ }
217
+
218
+ .breadcrumb-item-link:focus-visible {
219
+ outline: 2px solid CanvasText !important;
220
+ }
221
+ }
222
+ }
223
+
224
+ // ── Print ──
225
+ // Breadcrumb é navigation chrome — some em impressão (página impressa não
226
+ // precisa de "como cheguei aqui").
227
+ @media print {
228
+ matcha-breadcrumb {
229
+ display: none !important;
230
+ }
231
+ }
232
+