fokus-styles 2.4.0 → 2.6.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 (212) hide show
  1. package/dist/css/components.css +561 -83
  2. package/dist/css/components.min.css +1 -1
  3. package/dist/css/fokus-components.css +561 -83
  4. package/dist/css/fokus-components.min.css +1 -1
  5. package/dist/css/fokus-rtl.css +697 -83
  6. package/dist/css/fokus-rtl.min.css +1 -1
  7. package/dist/css/fokus-utilities.css +136 -0
  8. package/dist/css/fokus-utilities.min.css +1 -1
  9. package/dist/css/fokus.css +996 -258
  10. package/dist/css/fokus.min.css +1 -1
  11. package/dist/css/forms.css +300 -176
  12. package/dist/css/forms.min.css +1 -1
  13. package/dist/css/helpers.css +136 -0
  14. package/dist/css/helpers.min.css +1 -1
  15. package/dist/js/fokus.js +270 -25
  16. package/dist/js/fokus.min.js +18 -18
  17. package/package.json +17 -15
  18. package/packages/fokus-components/scss/components/_alerts.scss +128 -6
  19. package/packages/fokus-components/scss/components/_badges.scss +26 -10
  20. package/packages/fokus-components/scss/components/_index.scss +1 -0
  21. package/packages/fokus-components/scss/components/_popover.scss +131 -21
  22. package/packages/fokus-components/scss/components/_responsive.scss +23 -0
  23. package/packages/fokus-components/scss/components/_tag.scss +37 -14
  24. package/packages/fokus-components/scss/components/_toasts.scss +156 -11
  25. package/packages/fokus-components/scss/components/_tooltips.scss +70 -18
  26. package/packages/fokus-components/scss/forms/_check-radio-switch.scss +313 -215
  27. package/packages/fokus-components/scss/forms/_forms.scss +16 -0
  28. package/packages/fokus-js/js/carousel.d.ts +4 -0
  29. package/packages/fokus-js/js/carousel.js +8 -0
  30. package/packages/fokus-js/js/core/positioning.js +18 -9
  31. package/packages/fokus-js/js/dropdown.d.ts +4 -0
  32. package/packages/fokus-js/js/dropdown.js +7 -0
  33. package/packages/fokus-js/js/popover.js +26 -1
  34. package/packages/fokus-js/js/tabs.d.ts +3 -0
  35. package/packages/fokus-js/js/tabs.js +5 -0
  36. package/packages/fokus-js/js/tag.js +17 -0
  37. package/packages/fokus-js/js/toast.js +77 -3
  38. package/packages/fokus-js/js/tooltip.d.ts +8 -1
  39. package/packages/fokus-js/js/tooltip.js +106 -13
  40. package/packages/fokus-utilities/scss/utilities/_api.scss +48 -0
  41. package/CHANGELOG.md +0 -910
  42. package/dist/css/components.css.map +0 -1
  43. package/dist/css/components.min.css.map +0 -1
  44. package/dist/css/fokus-components.css.map +0 -1
  45. package/dist/css/fokus-components.min.css.map +0 -1
  46. package/dist/css/fokus-core.css.map +0 -1
  47. package/dist/css/fokus-core.min.css.map +0 -1
  48. package/dist/css/fokus-dark.css.map +0 -1
  49. package/dist/css/fokus-dark.min.css.map +0 -1
  50. package/dist/css/fokus-rtl.css.map +0 -1
  51. package/dist/css/fokus-rtl.min.css.map +0 -1
  52. package/dist/css/fokus-utilities.css.map +0 -1
  53. package/dist/css/fokus-utilities.min.css.map +0 -1
  54. package/dist/css/fokus.css.map +0 -1
  55. package/dist/css/fokus.min.css.map +0 -1
  56. package/dist/css/fonts.css.map +0 -1
  57. package/dist/css/fonts.min.css.map +0 -1
  58. package/dist/css/forms.css.map +0 -1
  59. package/dist/css/forms.min.css.map +0 -1
  60. package/dist/css/helpers.css.map +0 -1
  61. package/dist/css/helpers.min.css.map +0 -1
  62. package/dist/css/layout.css.map +0 -1
  63. package/dist/css/layout.min.css.map +0 -1
  64. package/dist/js/fokus.js.map +0 -7
  65. package/dist/js/fokus.min.js.map +0 -7
  66. package/docs/README.md +0 -86
  67. package/docs/comparison.md +0 -124
  68. package/docs/components/accordion.md +0 -104
  69. package/docs/components/alert-dialog.md +0 -99
  70. package/docs/components/alert.md +0 -59
  71. package/docs/components/avatar.md +0 -13
  72. package/docs/components/badge.md +0 -82
  73. package/docs/components/breadcrumb.md +0 -93
  74. package/docs/components/button-group.md +0 -13
  75. package/docs/components/button.md +0 -98
  76. package/docs/components/card.md +0 -111
  77. package/docs/components/carousel.md +0 -167
  78. package/docs/components/checkbox.md +0 -97
  79. package/docs/components/close-button.md +0 -13
  80. package/docs/components/code.md +0 -13
  81. package/docs/components/collapse.md +0 -78
  82. package/docs/components/combobox.md +0 -123
  83. package/docs/components/command-palette.md +0 -131
  84. package/docs/components/datatable.md +0 -173
  85. package/docs/components/datepicker.md +0 -137
  86. package/docs/components/divider.md +0 -57
  87. package/docs/components/dropdown.md +0 -103
  88. package/docs/components/empty-state.md +0 -65
  89. package/docs/components/file-upload-advanced.md +0 -116
  90. package/docs/components/file-upload.md +0 -93
  91. package/docs/components/icon-link.md +0 -13
  92. package/docs/components/input-group.md +0 -73
  93. package/docs/components/input.md +0 -90
  94. package/docs/components/list-group.md +0 -13
  95. package/docs/components/modal.md +0 -120
  96. package/docs/components/navbar.md +0 -74
  97. package/docs/components/nested-menu.md +0 -90
  98. package/docs/components/notification-center.md +0 -116
  99. package/docs/components/offcanvas.md +0 -102
  100. package/docs/components/pagination.md +0 -145
  101. package/docs/components/placeholder.md +0 -13
  102. package/docs/components/popover.md +0 -105
  103. package/docs/components/progress.md +0 -126
  104. package/docs/components/radio.md +0 -70
  105. package/docs/components/range.md +0 -83
  106. package/docs/components/rating.md +0 -91
  107. package/docs/components/ratio.md +0 -13
  108. package/docs/components/scrollspy.md +0 -13
  109. package/docs/components/segmented-control.md +0 -82
  110. package/docs/components/select.md +0 -89
  111. package/docs/components/skeleton.md +0 -70
  112. package/docs/components/stepper.md +0 -107
  113. package/docs/components/switch.md +0 -75
  114. package/docs/components/table.md +0 -90
  115. package/docs/components/tabs.md +0 -104
  116. package/docs/components/tag.md +0 -129
  117. package/docs/components/tile.md +0 -112
  118. package/docs/components/timeline.md +0 -78
  119. package/docs/components/toast.md +0 -95
  120. package/docs/components/tooltip.md +0 -77
  121. package/docs/components/tree-view.md +0 -118
  122. package/docs/contributing/contributing.md +0 -18
  123. package/docs/getting-started/installation.md +0 -70
  124. package/docs/getting-started/usage.md +0 -105
  125. package/docs/guides/accessibility.md +0 -102
  126. package/docs/guides/charts.md +0 -73
  127. package/docs/guides/dark-mode.md +0 -90
  128. package/docs/guides/icons.md +0 -99
  129. package/docs/guides/javascript-api.md +0 -9
  130. package/docs/guides/layout-advanced.md +0 -118
  131. package/docs/guides/migration-clarus-to-fokus.md +0 -48
  132. package/docs/guides/migration-external.md +0 -123
  133. package/docs/guides/migration-v1.md +0 -63
  134. package/docs/guides/print.md +0 -30
  135. package/docs/guides/rtl-and-system-preferences.md +0 -28
  136. package/docs/guides/theming.md +0 -140
  137. package/docs/guides/utility-api.md +0 -9
  138. package/docs/prompts/prompt-plan.md +0 -45
  139. package/docs/reference/accessibility-matrix.md +0 -77
  140. package/docs/reference/browser-support.md +0 -75
  141. package/docs/reference/contrast-report.md +0 -50
  142. package/docs/reference/definitions.md +0 -864
  143. package/docs/reference/design-tokens.md +0 -194
  144. package/docs/reference/scss-architecture.md +0 -227
  145. package/docs/reference/size-baseline.json +0 -34
  146. package/docs/reference/stability.md +0 -89
  147. package/docs/showcase.md +0 -25
  148. package/mockup/README.md +0 -41
  149. package/mockup/assets/carousel-planning.png +0 -0
  150. package/mockup/assets/carousel-workspace.png +0 -0
  151. package/mockup/assets/example-theme.css +0 -8
  152. package/mockup/assets/example-theme.js +0 -11
  153. package/mockup/assets/showcase-contracts.js +0 -84
  154. package/mockup/assets/showcase.css +0 -91
  155. package/mockup/assets/showcase.js +0 -724
  156. package/mockup/content-data.html +0 -9
  157. package/mockup/examples/accordion-tabs-toast.html +0 -149
  158. package/mockup/examples/alert-dialog.html +0 -84
  159. package/mockup/examples/alerts.html +0 -41
  160. package/mockup/examples/badges-alerts.html +0 -77
  161. package/mockup/examples/buttons.html +0 -58
  162. package/mockup/examples/cards.html +0 -132
  163. package/mockup/examples/carousel.html +0 -126
  164. package/mockup/examples/charts.html +0 -102
  165. package/mockup/examples/check-radio-switch.html +0 -144
  166. package/mockup/examples/collapse.html +0 -69
  167. package/mockup/examples/combobox.html +0 -60
  168. package/mockup/examples/command-palette.html +0 -64
  169. package/mockup/examples/datatable.html +0 -113
  170. package/mockup/examples/datepicker.html +0 -62
  171. package/mockup/examples/divider.html +0 -45
  172. package/mockup/examples/dropdown-tooltip.html +0 -77
  173. package/mockup/examples/empty-state.html +0 -56
  174. package/mockup/examples/file-drop.html +0 -74
  175. package/mockup/examples/file-upload-advanced.html +0 -68
  176. package/mockup/examples/forms-advanced.html +0 -77
  177. package/mockup/examples/hover-card.html +0 -86
  178. package/mockup/examples/icons.html +0 -157
  179. package/mockup/examples/input-group.html +0 -74
  180. package/mockup/examples/js-foundation.html +0 -215
  181. package/mockup/examples/layout.html +0 -134
  182. package/mockup/examples/modal-select.html +0 -127
  183. package/mockup/examples/nested-menu.html +0 -73
  184. package/mockup/examples/notification-center.html +0 -86
  185. package/mockup/examples/offcanvas-popover.html +0 -133
  186. package/mockup/examples/pagination-breadcrumbs.html +0 -92
  187. package/mockup/examples/range.html +0 -69
  188. package/mockup/examples/rating.html +0 -103
  189. package/mockup/examples/segmented-control.html +0 -96
  190. package/mockup/examples/skeletons.html +0 -82
  191. package/mockup/examples/spinner-progress.html +0 -130
  192. package/mockup/examples/stepper.html +0 -119
  193. package/mockup/examples/tables-navbar.html +0 -89
  194. package/mockup/examples/tag.html +0 -105
  195. package/mockup/examples/theming.html +0 -68
  196. package/mockup/examples/tile.html +0 -107
  197. package/mockup/examples/timeline.html +0 -108
  198. package/mockup/examples/tree-view.html +0 -68
  199. package/mockup/feedback-actions.html +0 -9
  200. package/mockup/forms.html +0 -13
  201. package/mockup/foundations.html +0 -7
  202. package/mockup/kitchen-sink.html +0 -696
  203. package/mockup/navigation-disclosure.html +0 -11
  204. package/mockup/overlays-commands.html +0 -12
  205. package/mockup/templates/README.md +0 -20
  206. package/mockup/templates/admin.html +0 -334
  207. package/mockup/templates/auth.html +0 -234
  208. package/mockup/templates/dashboard.html +0 -442
  209. package/mockup/templates/landing.html +0 -397
  210. package/packages/fokus-icons/package.json +0 -46
  211. package/scripts/migrate-fokus-map.json +0 -1366
  212. package/scripts/migrate-fokus.mjs +0 -97
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fokus-styles",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
4
4
  "description": "Fokus Styles is a complete CSS framework with components, utilities, vanilla JavaScript, icons, React wrappers, and a CLI.",
5
5
  "keywords": [
6
6
  "css",
@@ -82,25 +82,27 @@
82
82
  "fokus": "packages/fokus-cli/bin/fokus.mjs"
83
83
  },
84
84
  "files": [
85
- "assets",
86
- "dist",
87
- "scss",
85
+ "assets/fonts",
86
+ "dist/css/*.css",
87
+ "dist/js/*.js",
88
+ "scss/**/*.scss",
88
89
  "packages/fokus-core/scss",
89
90
  "packages/fokus-components/scss",
90
91
  "packages/fokus-utilities/scss",
91
92
  "packages/fokus-fonts/scss",
92
- "packages/fokus-js/js",
93
- "packages/fokus-icons",
94
- "packages/fokus-react/src",
95
- "packages/fokus-cli/bin",
96
- "packages/fokus-cli/lib",
97
- "docs",
98
- "scripts/migrate-fokus.mjs",
99
- "scripts/migrate-fokus-map.json",
100
- "mockup",
93
+ "packages/fokus-js/js/**/*.js",
94
+ "packages/fokus-js/js/**/*.d.ts",
95
+ "packages/fokus-icons/index.js",
96
+ "packages/fokus-icons/icons/**/*.js",
97
+ "packages/fokus-icons/svg/**/*.svg",
98
+ "packages/fokus-icons/LICENSE",
99
+ "packages/fokus-icons/LICENSE-LUCIDE.txt",
100
+ "packages/fokus-react/src/**/*.js",
101
+ "packages/fokus-react/src/**/*.d.ts",
102
+ "packages/fokus-cli/bin/**/*.mjs",
103
+ "packages/fokus-cli/lib/**/*.mjs",
101
104
  "LICENSE",
102
- "README.md",
103
- "CHANGELOG.md"
105
+ "README.md"
104
106
  ],
105
107
  "engines": {
106
108
  "node": ">=18"
@@ -2,23 +2,145 @@
2
2
 
3
3
  @layer components {
4
4
  .fs-alert {
5
+ --fs-alert-padding-block: 12px;
6
+ --fs-alert-padding-inline: 16px;
7
+ --fs-alert-gap: 12px;
8
+ --fs-alert-radius: var(--fs-radius-md, 6px);
9
+ --fs-alert-border-width: 1px;
10
+ --fs-alert-accent-width: 4px;
11
+ --fs-alert-icon-size: 20px;
12
+ --fs-alert-heading-gap: 4px;
13
+ --fs-alert-actions-gap: 8px;
14
+
5
15
  display: flex;
6
16
  align-items: flex-start;
7
- gap: 8px;
8
- padding: 12px 16px;
9
- border: 1px solid var(--fs-color-border);
10
- border-left: 5px solid var(--fs-color-border);
11
- border-radius: 0;
17
+ gap: var(--fs-alert-gap);
18
+ min-inline-size: 0;
19
+ padding-block: var(--fs-alert-padding-block);
20
+ padding-inline: var(--fs-alert-padding-inline);
21
+ border: var(--fs-alert-border-width) solid var(--fs-color-border);
22
+ border-inline-start: var(--fs-alert-accent-width) solid var(--fs-color-border);
23
+ border-radius: var(--fs-alert-radius);
12
24
  color: var(--fs-color-text);
13
25
  background-color: var(--fs-color-surface-raised);
14
26
  font-size: $font-size-sm;
15
27
  }
16
28
 
29
+ .fs-alert-inline {
30
+ --fs-alert-padding-block: 8px;
31
+ --fs-alert-padding-inline: 12px;
32
+ --fs-alert-gap: 8px;
33
+ --fs-alert-accent-width: 3px;
34
+ --fs-alert-icon-size: 16px;
35
+ }
36
+
37
+ .fs-alert-group {
38
+ display: grid;
39
+ gap: 12px;
40
+ min-inline-size: 0;
41
+ }
42
+
43
+ .fs-alert[aria-busy="true"],
44
+ .fs-alert.is-loading {
45
+ cursor: progress;
46
+ }
47
+
48
+ .fs-alert[aria-busy="true"] .fs-alert-actions,
49
+ .fs-alert.is-loading .fs-alert-actions {
50
+ opacity: 0.75;
51
+ }
52
+
53
+ .fs-alert .fs-spinner {
54
+ flex: 0 0 auto;
55
+ align-self: flex-start;
56
+ margin-block: 2px;
57
+ }
58
+
59
+ .fs-alert-icon {
60
+ display: inline-flex;
61
+ flex: 0 0 var(--fs-alert-icon-size);
62
+ align-items: center;
63
+ justify-content: center;
64
+ inline-size: var(--fs-alert-icon-size);
65
+ block-size: var(--fs-alert-icon-size);
66
+ color: currentcolor;
67
+ }
68
+
69
+ .fs-alert-icon .fs-icon,
70
+ .fs-alert-icon > svg {
71
+ inline-size: 100%;
72
+ block-size: 100%;
73
+ }
74
+
75
+ .fs-alert-content {
76
+ flex: 1 1 auto;
77
+ min-inline-size: 0;
78
+ }
79
+
80
+ .fs-alert-heading {
81
+ margin: 0 0 var(--fs-alert-heading-gap);
82
+ color: inherit;
83
+ font-size: inherit;
84
+ font-weight: $font-weight-semibold;
85
+ line-height: 1.35;
86
+ }
87
+
88
+ .fs-alert-text {
89
+ margin: 0;
90
+ line-height: 1.5;
91
+ }
92
+
93
+ .fs-alert-actions {
94
+ display: flex;
95
+ flex-wrap: wrap;
96
+ gap: var(--fs-alert-actions-gap);
97
+ align-items: center;
98
+ margin-block-start: var(--fs-alert-actions-gap);
99
+ }
100
+
101
+ .fs-alert-link {
102
+ color: inherit;
103
+ font-weight: $font-weight-medium;
104
+ text-decoration: underline;
105
+ text-underline-offset: 2px;
106
+ }
107
+
108
+ .fs-alert-close {
109
+ flex: 0 0 auto;
110
+ margin-inline-start: auto;
111
+ color: inherit;
112
+ }
113
+
17
114
  @each $name, $color in $theme-colors {
18
115
  .fs-alert-#{$name} {
19
116
  color: var(--fs-alert-#{$name}-text);
20
117
  background-color: var(--fs-alert-#{$name}-bg);
21
- border-color: var(--fs-color-#{$name});
118
+ border-color: var(--fs-color-border);
119
+ border-inline-start-color: var(--fs-color-#{$name});
120
+ }
121
+ }
122
+
123
+ @media (width <= 480px) {
124
+ .fs-alert {
125
+ --fs-alert-padding-inline: 12px;
126
+ }
127
+
128
+ .fs-alert-actions {
129
+ align-items: flex-start;
130
+ }
131
+ }
132
+
133
+ @media (forced-colors: active) {
134
+ .fs-alert {
135
+ border-color: CanvasText;
136
+ border-inline-start-color: Highlight;
137
+ color: CanvasText;
138
+ background-color: Canvas;
139
+ }
140
+
141
+ .fs-alert-link,
142
+ .fs-alert .fs-btn {
143
+ forced-color-adjust: none;
22
144
  }
23
145
  }
24
146
  }
@@ -10,7 +10,10 @@
10
10
  --fs-badge-bg: var(--fs-color-subtle);
11
11
  --fs-badge-border: transparent;
12
12
  --fs-badge-height: 22px;
13
- --fs-badge-radius: 0;
13
+ --fs-badge-radius: var(--fs-radius-sm);
14
+ --fs-badge-padding-inline: 8px;
15
+ --fs-badge-padding-block-start: 2px;
16
+ --fs-badge-padding-block-end: 2px;
14
17
 
15
18
  display: inline-flex;
16
19
  align-items: center;
@@ -18,9 +21,8 @@
18
21
  justify-content: center;
19
22
  min-height: var(--fs-badge-height);
20
23
 
21
- // O peso óptico da fonte fica ligeiramente abaixo do centro geométrico.
22
- // Um pixel extra abaixo reposiciona a linha de texto para cima.
23
- padding: 1px 8px 3px;
24
+ // O padding vertical simétrico mantém a linha de texto no centro geométrico.
25
+ padding: var(--fs-badge-padding-block-start) var(--fs-badge-padding-inline) var(--fs-badge-padding-block-end);
24
26
  border: 1px solid var(--fs-badge-border);
25
27
  border-radius: var(--fs-badge-radius);
26
28
  color: var(--fs-badge-color);
@@ -53,15 +55,19 @@
53
55
 
54
56
  .fs-badge-sm {
55
57
  --fs-badge-height: 18px;
58
+ --fs-badge-padding-inline: 6px;
59
+ --fs-badge-padding-block-start: 1px;
60
+ --fs-badge-padding-block-end: 1px;
56
61
 
57
- padding: 0 6px 2px;
58
62
  font-size: $font-size-xs;
59
63
  }
60
64
 
61
65
  .fs-badge-lg {
62
66
  --fs-badge-height: 26px;
67
+ --fs-badge-padding-inline: 10px;
68
+ --fs-badge-padding-block-start: 3px;
69
+ --fs-badge-padding-block-end: 3px;
63
70
 
64
- padding: 2px 10px 4px;
65
71
  font-size: $font-size-md;
66
72
  }
67
73
 
@@ -81,13 +87,20 @@
81
87
  font-variant-numeric: tabular-nums;
82
88
  }
83
89
 
90
+ .fs-badge-count-circle {
91
+ aspect-ratio: 1;
92
+ min-width: var(--fs-badge-height);
93
+ padding-inline: 0;
94
+ border-radius: 50%;
95
+ }
96
+
84
97
  .fs-badge-split {
85
98
  --fs-badge-split-label-bg: var(--fs-color-black);
86
99
  --fs-badge-split-label-color: var(--fs-color-white);
87
100
  --fs-badge-split-value-bg: var(--fs-color-primary);
88
101
  --fs-badge-split-value-color: #{color-contrast(map.get($theme-colors, primary))};
89
102
  --fs-badge-split-height: 22px;
90
- --fs-badge-split-radius: 0;
103
+ --fs-badge-split-radius: var(--fs-radius-sm);
91
104
 
92
105
  display: inline-flex;
93
106
  min-height: var(--fs-badge-split-height);
@@ -105,7 +118,8 @@
105
118
  display: inline-flex;
106
119
  align-items: center;
107
120
  min-height: var(--fs-badge-split-height);
108
- padding: 1px 8px 3px;
121
+ padding-block: 2px;
122
+ padding-inline: 8px;
109
123
  }
110
124
 
111
125
  .fs-badge-split-label {
@@ -143,11 +157,13 @@
143
157
 
144
158
  .fs-badge-split.fs-badge-sm .fs-badge-split-label,
145
159
  .fs-badge-split.fs-badge-sm .fs-badge-split-value {
146
- padding: 0 6px 2px;
160
+ padding-block: 1px;
161
+ padding-inline: 6px;
147
162
  }
148
163
 
149
164
  .fs-badge-split.fs-badge-lg .fs-badge-split-label,
150
165
  .fs-badge-split.fs-badge-lg .fs-badge-split-value {
151
- padding: 2px 10px 4px;
166
+ padding-block: 3px;
167
+ padding-inline: 10px;
152
168
  }
153
169
  }
@@ -44,3 +44,4 @@
44
44
  @use "placeholder";
45
45
  @use "progress";
46
46
  @use "scrollspy";
47
+ @use "responsive";
@@ -9,15 +9,31 @@
9
9
 
10
10
  @layer components {
11
11
  .fs-popover {
12
+ --fs-popover-width: 320px;
13
+ --fs-popover-max-width: min(var(--fs-popover-width), calc(100vw - 32px));
14
+ --fs-popover-padding-block: 12px;
15
+ --fs-popover-padding-inline: 14px;
16
+ --fs-popover-gap: 10px;
17
+ --fs-popover-radius: var(--fs-radius-md, 6px);
18
+ --fs-popover-shadow: var(--fs-shadow-md);
19
+ --fs-popover-icon-size: 20px;
20
+ --fs-popover-heading-gap: 4px;
21
+ --fs-popover-footer-gap: 8px;
22
+ --fs-popover-arrow-size: 8px;
23
+ --fs-popover-border-width: 1px;
24
+
12
25
  position: absolute;
13
26
  z-index: var(--fs-z-offcanvas);
14
27
  display: none;
15
- max-width: 280px;
28
+ inline-size: var(--fs-popover-width);
29
+ max-inline-size: var(--fs-popover-max-width);
30
+ min-inline-size: 0;
16
31
  color: var(--fs-color-text);
17
32
  background-color: var(--fs-color-surface);
18
- border: 1px solid var(--fs-color-border);
19
- border-radius: var(--fs-radius-md);
20
- box-shadow: var(--fs-shadow-md);
33
+ border: var(--fs-popover-border-width) solid var(--fs-color-border);
34
+ border-radius: var(--fs-popover-radius);
35
+ box-shadow: var(--fs-popover-shadow);
36
+ overflow-wrap: anywhere;
21
37
  }
22
38
 
23
39
  .fs-popover.is-open {
@@ -25,32 +41,89 @@
25
41
  }
26
42
 
27
43
  .fs-popover-header {
28
- padding: 10px 14px;
44
+ display: flex;
45
+ align-items: center;
46
+ gap: var(--fs-popover-gap);
47
+ min-inline-size: 0;
48
+ padding-block: var(--fs-popover-padding-block);
49
+ padding-inline: var(--fs-popover-padding-inline);
29
50
  background-color: var(--fs-color-subtle);
30
51
  border-bottom: 1px solid var(--fs-color-border);
31
- border-radius: var(--fs-radius-md) var(--fs-radius-md) 0 0;
52
+ border-radius: var(--fs-popover-radius) var(--fs-popover-radius) 0 0;
32
53
  font-size: $font-size-sm;
33
54
  font-weight: $font-weight-medium;
34
55
  }
35
56
 
36
57
  .fs-popover-body {
37
- padding: 14px;
58
+ min-inline-size: 0;
59
+ padding-block: var(--fs-popover-padding-block);
60
+ padding-inline: var(--fs-popover-padding-inline);
38
61
  font-size: $font-size-sm;
62
+ line-height: 1.5;
63
+ }
64
+
65
+ .fs-popover-icon {
66
+ display: inline-flex;
67
+ flex: 0 0 var(--fs-popover-icon-size);
68
+ align-items: center;
69
+ justify-content: center;
70
+ inline-size: var(--fs-popover-icon-size);
71
+ block-size: var(--fs-popover-icon-size);
72
+ color: currentcolor;
73
+ }
74
+
75
+ .fs-popover-icon .fs-icon,
76
+ .fs-popover-icon > svg {
77
+ inline-size: 100%;
78
+ block-size: 100%;
79
+ }
80
+
81
+ .fs-popover-heading {
82
+ display: flex;
83
+ flex: 1 1 auto;
84
+ flex-wrap: wrap;
85
+ align-items: baseline;
86
+ gap: var(--fs-popover-heading-gap);
87
+ min-inline-size: 0;
88
+ }
89
+
90
+ .fs-popover-title,
91
+ .fs-popover-meta,
92
+ .fs-popover-text {
93
+ min-inline-size: 0;
94
+ }
95
+
96
+ .fs-popover-meta {
97
+ color: var(--fs-color-muted);
98
+ font-size: $font-size-xs;
99
+ font-weight: $font-weight-regular;
100
+ }
101
+
102
+ .fs-popover-text {
103
+ margin: 0;
104
+ }
105
+
106
+ .fs-popover-close {
107
+ flex: 0 0 auto;
108
+ margin-inline-start: auto;
109
+ color: inherit;
39
110
  }
40
111
 
41
112
  .fs-popover-footer {
42
113
  display: flex;
43
114
  align-items: center;
44
115
  justify-content: flex-end;
45
- gap: 8px;
46
- padding: 10px 14px;
116
+ flex-wrap: wrap;
117
+ gap: var(--fs-popover-footer-gap);
118
+ padding-block: var(--fs-popover-padding-block);
119
+ padding-inline: var(--fs-popover-padding-inline);
47
120
  border-top: 1px solid var(--fs-color-border);
48
121
  }
49
122
 
50
123
  .fs-popover-arrow {
51
124
  position: absolute;
52
- width: 8px;
53
- height: 8px;
125
+ inline-size: var(--fs-popover-arrow-size);
126
+ block-size: var(--fs-popover-arrow-size);
54
127
  background-color: var(--fs-color-surface);
55
128
  border: 1px solid var(--fs-color-border);
56
129
  transform: rotate(45deg);
@@ -58,32 +131,32 @@
58
131
 
59
132
  .fs-popover[data-placement="top"] .fs-popover-arrow {
60
133
  bottom: -5px;
61
- left: 50%;
62
- margin-left: -4px;
134
+ inset-inline-start: var(--fs-popover-arrow-offset, 50%);
135
+ margin-inline-start: calc(var(--fs-popover-arrow-size) / -2);
63
136
  border-top: 0;
64
137
  border-left: 0;
65
138
  }
66
139
 
67
140
  .fs-popover[data-placement="bottom"] .fs-popover-arrow {
68
141
  top: -5px;
69
- left: 50%;
70
- margin-left: -4px;
142
+ inset-inline-start: var(--fs-popover-arrow-offset, 50%);
143
+ margin-inline-start: calc(var(--fs-popover-arrow-size) / -2);
71
144
  border-right: 0;
72
145
  border-bottom: 0;
73
146
  }
74
147
 
75
148
  .fs-popover[data-placement="left"] .fs-popover-arrow {
76
- top: 50%;
77
- right: -5px;
78
- margin-top: -4px;
149
+ inset-block-start: var(--fs-popover-arrow-offset, 50%);
150
+ inset-inline-end: calc(var(--fs-popover-arrow-size) / -2 - 1px);
151
+ margin-block-start: calc(var(--fs-popover-arrow-size) / -2);
79
152
  border-bottom: 0;
80
153
  border-left: 0;
81
154
  }
82
155
 
83
156
  .fs-popover[data-placement="right"] .fs-popover-arrow {
84
- top: 50%;
85
- left: -5px;
86
- margin-top: -4px;
157
+ inset-block-start: var(--fs-popover-arrow-offset, 50%);
158
+ inset-inline-start: calc(var(--fs-popover-arrow-size) / -2 - 1px);
159
+ margin-block-start: calc(var(--fs-popover-arrow-size) / -2);
87
160
  border-top: 0;
88
161
  border-right: 0;
89
162
  }
@@ -100,4 +173,41 @@
100
173
  display: flex;
101
174
  gap: 12px;
102
175
  }
176
+
177
+ .fs-popover[aria-busy="true"] {
178
+ cursor: progress;
179
+ }
180
+
181
+ @media (width <= 480px) {
182
+ .fs-popover {
183
+ --fs-popover-padding-inline: 12px;
184
+ --fs-popover-max-width: calc(100vw - 24px);
185
+ }
186
+
187
+ .fs-popover-footer {
188
+ align-items: flex-start;
189
+ }
190
+ }
191
+
192
+ @media (prefers-reduced-motion: reduce) {
193
+ .fs-popover {
194
+ transition: none;
195
+ }
196
+ }
197
+
198
+ @media (forced-colors: active) {
199
+ .fs-popover,
200
+ .fs-popover-arrow {
201
+ border-color: CanvasText;
202
+ color: CanvasText;
203
+ background-color: Canvas;
204
+ box-shadow: none;
205
+ }
206
+
207
+ .fs-popover-header,
208
+ .fs-popover-footer {
209
+ border-color: CanvasText;
210
+ background-color: Canvas;
211
+ }
212
+ }
103
213
  }
@@ -0,0 +1,23 @@
1
+ /* stylelint-disable declaration-block-single-line-max-declarations */
2
+ @layer components {
3
+ .fs-stack { display: flex; flex-direction: column; gap: var(--fs-stack-gap, var(--fs-space-3)); }
4
+ .fs-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--fs-cluster-gap, var(--fs-space-2)); }
5
+ .fs-responsive-media { width: 100%; height: auto; object-fit: cover; }
6
+
7
+ @media (width <= 639.98px) {
8
+ .fs-modal-dialog, .fs-offcanvas { max-width: 100%; margin-inline: 0; border-radius: 0; }
9
+ .fs-table-responsive { overflow-x: auto; -webkit-overflow-scrolling: touch; }
10
+ .fs-btn-group-responsive, .fs-btn-group-responsive > .fs-btn { width: 100%; }
11
+ .fs-btn-group-responsive { flex-direction: column; }
12
+ }
13
+
14
+ @media (width >= 640px) {
15
+ .fs-stack-md-row { flex-direction: row; align-items: center; }
16
+ }
17
+
18
+ @media (prefers-reduced-motion: reduce) { .fs-stack, .fs-cluster { scroll-behavior: auto; } }
19
+
20
+ @media (forced-colors: active) {
21
+ .fs-card, .fs-dropdown-menu, .fs-modal-content, .fs-offcanvas, .fs-toast { border: 1px solid CanvasText; box-shadow: none; }
22
+ }
23
+ }
@@ -8,8 +8,18 @@
8
8
  // o texto e o "x". O dismiss em si é feito por js/tag.js (FokusStyles.Tag).
9
9
  @layer components {
10
10
  .fs-tag {
11
+ --fs-tag-icon-size: var(--fs-tag-close-size);
12
+ --fs-tag-icon-glyph-size: 12px;
13
+ --fs-tag-icon-gap: 4px;
14
+ --fs-tag-icon-color: currentcolor;
15
+ --fs-tag-close-size: calc(var(--fs-badge-height) - 2px);
16
+ --fs-tag-close-gap: 4px;
17
+ --fs-tag-padding-inline-start: 8px;
18
+ --fs-tag-padding-inline-end: 2px;
19
+
11
20
  gap: 0;
12
- padding: 0 0 0 8px;
21
+ padding-inline-start: var(--fs-tag-padding-inline-start);
22
+ padding-inline-end: var(--fs-tag-padding-inline-end);
13
23
  }
14
24
 
15
25
  // O texto fica em um elemento próprio quando a tag puder ser truncada. A
@@ -30,25 +40,32 @@
30
40
 
31
41
  .fs-tag-icon {
32
42
  display: inline-grid;
33
- width: 12px;
34
- height: 12px;
35
- flex: 0 0 12px;
36
- margin-right: 4px;
43
+ width: var(--fs-tag-icon-size);
44
+ height: var(--fs-tag-icon-size);
45
+ flex: 0 0 var(--fs-tag-icon-size);
37
46
  place-items: center;
47
+ color: var(--fs-tag-icon-color);
48
+ margin-inline-end: var(--fs-tag-icon-gap);
49
+ }
50
+
51
+ .fs-tag-icon-end {
52
+ margin-inline-start: auto;
53
+ margin-inline-end: var(--fs-tag-icon-gap);
38
54
  }
39
55
 
40
56
  .fs-tag-icon .fs-icon {
41
- width: 12px;
42
- height: 12px;
57
+ display: block;
58
+ width: var(--fs-tag-icon-glyph-size);
59
+ height: var(--fs-tag-icon-glyph-size);
43
60
  stroke: currentcolor;
44
61
  }
45
62
 
46
63
  .fs-tag .fs-btn-close {
47
- width: calc(var(--fs-badge-height) - 2px);
48
- height: calc(var(--fs-badge-height) - 2px);
49
- flex: 0 0 calc(var(--fs-badge-height) - 2px);
50
- margin-left: 4px;
51
- border-radius: 0;
64
+ width: var(--fs-tag-close-size);
65
+ height: var(--fs-tag-close-size);
66
+ flex: 0 0 var(--fs-tag-close-size);
67
+ margin-inline-start: var(--fs-tag-close-gap);
68
+ border-radius: var(--fs-badge-radius);
52
69
  background-color: transparent;
53
70
 
54
71
  // Herda a cor de texto do badge (contraste automático por variante) em vez
@@ -61,7 +78,7 @@
61
78
 
62
79
  .fs-tag .fs-btn-close::before,
63
80
  .fs-tag .fs-btn-close::after {
64
- top: calc(50% + 1px);
81
+ top: 50%;
65
82
  width: 8px;
66
83
  }
67
84
 
@@ -143,6 +160,12 @@
143
160
  background-color: color-mix(in srgb, currentcolor 18%, transparent);
144
161
  }
145
162
 
163
+ // Um ícone inicial ocupa a área reservada à esquerda; reduzir o padding
164
+ // mantém a composição equilibrada sem empurrar o texto para dentro.
165
+ .fs-tag:has(> .fs-tag-icon:not(.fs-tag-icon-end)) {
166
+ --fs-tag-padding-inline-start: 2px;
167
+ }
168
+
146
169
  // Um botão de overflow representa as tags não exibidas. A abertura da lista
147
170
  // ou popover é responsabilidade da composição que o utiliza.
148
171
  .fs-tag-overflow {
@@ -200,7 +223,7 @@
200
223
  display: inline-grid;
201
224
  width: calc(var(--fs-badge-height) - 2px);
202
225
  height: calc(var(--fs-badge-height) - 2px);
203
- margin-left: 4px;
226
+ margin-inline-start: var(--fs-tag-close-gap);
204
227
  place-items: center;
205
228
  }
206
229