|
18 | 18 | background-color 150ms ease-in-out, |
19 | 19 | border-color 150ms ease-in-out, |
20 | 20 | color 150ms ease-in-out; |
21 | | - |
22 | | - /* Comfortable density asymmetric padding for visual text centering */ |
23 | | - /* These values compensate for font metrics (ascenders/descenders) */ |
24 | | - /* Empirically determined from Figma design */ |
25 | | - --_comfortable-padding-top: 0.313rem; /* 5px */ |
26 | | - --_comfortable-padding-bottom: 0.188rem; /* 3px */ |
27 | | - |
28 | | - /* Comfortable density icon-only padding to match label button heights */ |
29 | | - /* Formula: (target-height - icon-size) / 2 where target-height = label button height */ |
30 | | - /* Empirically determined from Figma design */ |
31 | | - --_comfortable-icon-padding-sm: 0.125rem; /* 2px: (20px - 16px) / 2 */ |
32 | | - --_comfortable-icon-padding-md: 0.188rem; /* 3px: (24px - 18px) / 2 */ |
33 | | - --_comfortable-icon-padding-lg: 0.5rem; /* 8px: (36px - 20px) / 2 */ |
34 | 21 | } |
35 | 22 |
|
36 | | - /* ===== SIZE VARIANTS (Button with label) ===== */ |
| 23 | + /* ===== SIZE VARIANTS ===== */ |
37 | 24 | /* |
38 | | - * Spacing adjusted from design tokens to compensate for icon negative margins |
39 | | - * Icons have margin-block: -0.25em and margin-inline: -0.1em for optical alignment |
40 | | - * |
41 | | - * Token reference (from --eds-selectable-space-*): |
42 | | - * - lg: horizontal=20px, vertical=16px (spacious) / 12px (comfortable) |
43 | | - * - md: horizontal=16px, vertical=12px (spacious) / 8px (comfortable) |
44 | | - * - sm: horizontal=12px, vertical=8px (spacious) / 6px (comfortable) |
| 25 | + * Button height is controlled by min-height. |
| 26 | + * The span keeps its natural line-height and is centered by flexbox. |
45 | 27 | * |
46 | | - * Adjustments made: |
47 | | - * - Vertical padding reduced by ~4px to account for icon negative margins |
48 | | - * - Gap values slightly adjusted for visual balance with icons |
| 28 | + * Spacious (default): sm=24px, md=36px, lg=44px |
| 29 | + * Comfortable: sm=20px, md=24px, lg=36px |
49 | 30 | */ |
50 | 31 |
|
51 | 32 | .eds-button[data-selectable-space='lg'] { |
52 | | - /* Base from token (16px spacious / 12px comfortable) → Adjusted: -4px vertical for icon margins */ |
53 | | - padding-block: calc(var(--eds-selectable-space-vertical) - 0.25rem); /* 16px → 12px / 12px → 8px */ |
54 | | - padding-inline: var(--eds-selectable-space-horizontal); /* 20px spacious / 16px comfortable */ |
| 33 | + min-height: 2.75rem; /* 44px */ |
| 34 | + padding-inline: var(--eds-selectable-space-horizontal); |
55 | 35 | gap: var(--eds-typography-gap-horizontal); |
56 | 36 | } |
57 | 37 |
|
58 | 38 | .eds-button[data-selectable-space='md'] { |
59 | | - /* Base from token (12px spacious / 8px comfortable) → Adjusted: -2px vertical for icon margins */ |
60 | | - padding-block: calc(var(--eds-selectable-space-vertical) - 0.125rem); /* 12px → 10px / 8px → 6px */ |
61 | | - padding-inline: var(--eds-selectable-space-horizontal); /* 16px spacious / 12px comfortable */ |
| 39 | + min-height: 2.25rem; /* 36px */ |
| 40 | + padding-inline: var(--eds-selectable-space-horizontal); |
62 | 41 | gap: var(--eds-typography-gap-horizontal); |
63 | 42 | } |
64 | 43 |
|
65 | 44 | .eds-button[data-selectable-space='sm'] { |
66 | | - /* Base from token (8px spacious / 6px comfortable) → Adjusted: -2px vertical for icon margins */ |
67 | | - padding-block: calc(var(--eds-selectable-space-vertical) - 0.125rem); /* 8px → 6px / 6px → 4px */ |
68 | | - padding-inline: var(--eds-selectable-space-horizontal); /* 12px spacious / 8px comfortable */ |
| 45 | + min-height: 1.5rem; /* 24px */ |
| 46 | + padding-inline: var(--eds-selectable-space-horizontal); |
69 | 47 | gap: var(--eds-typography-gap-horizontal); |
70 | 48 | } |
71 | 49 |
|
72 | | - /* ===== DENSITY OVERRIDES ===== */ |
73 | | - /* |
74 | | - * Note: Density-specific overrides are defined OUTSIDE @layer (after this block closes) |
75 | | - * to ensure they can override the typography tokens from @equinor/eds-tokens |
76 | | - */ |
| 50 | + /* Comfortable density */ |
77 | 51 |
|
78 | | - /* ===== ICON-ONLY BUTTON ===== */ |
79 | | - /* |
80 | | - * Icon-only buttons maintain same height as label buttons but adapt to density. |
81 | | - * Formula: padding = base-padding + (line-height - icon-size) / 2 |
82 | | - * |
83 | | - * This ensures icon buttons: |
84 | | - * - Match label button height in both spacious and comfortable density |
85 | | - * - Center the icon vertically regardless of density mode |
86 | | - * - Adapt automatically via --eds-typography-line-height-squished token |
87 | | - * |
88 | | - * Density behavior: |
89 | | - * - Spacious: Uses larger line-height → more padding → taller buttons |
90 | | - * - Comfortable: Uses smaller line-height → less padding → shorter buttons |
91 | | - */ |
92 | | - |
93 | | - .eds-button[data-icon-only] { |
94 | | - aspect-ratio: 1; |
| 52 | + [data-density='comfortable'] .eds-button[data-selectable-space='lg'] { |
| 53 | + min-height: 2.25rem; /* 36px */ |
95 | 54 | } |
96 | 55 |
|
97 | | - .eds-button[data-icon-only][data-selectable-space='lg'] { |
98 | | - /* Base padding from token minus icon compensation: (16px - 4px) = 12px spacious / (12px - 4px) = 8px comfortable */ |
99 | | - /* Adapts with line-height (20px spacious / 16px comfortable) */ |
100 | | - /* Target height: 44px spacious / 40px comfortable */ |
101 | | - --_base-padding: calc(var(--eds-selectable-space-vertical) - 0.25rem); |
102 | | - padding: calc( |
103 | | - var(--_base-padding) + |
104 | | - ( |
105 | | - var(--eds-typography-line-height-squished) - |
106 | | - var(--eds-typography-icon-size) |
107 | | - ) / |
108 | | - 2 |
109 | | - ); |
| 56 | + [data-density='comfortable'] .eds-button[data-selectable-space='md'] { |
| 57 | + min-height: 1.5rem; /* 24px */ |
110 | 58 | } |
111 | 59 |
|
112 | | - .eds-button[data-icon-only][data-selectable-space='md'] { |
113 | | - /* Base padding from token minus icon compensation: (12px - 2px) = 10px spacious / (8px - 2px) = 6px comfortable */ |
114 | | - /* Adapts with line-height (16px spacious / 12px comfortable) */ |
115 | | - /* Target height: 36px spacious / 32px comfortable */ |
116 | | - --_base-padding: calc(var(--eds-selectable-space-vertical) - 0.125rem); |
117 | | - padding: calc( |
118 | | - var(--_base-padding) + |
119 | | - ( |
120 | | - var(--eds-typography-line-height-squished) - |
121 | | - var(--eds-typography-icon-size) |
122 | | - ) / |
123 | | - 2 |
124 | | - ); |
| 60 | + [data-density='comfortable'] .eds-button[data-selectable-space='sm'] { |
| 61 | + min-height: 1.25rem; /* 20px */ |
125 | 62 | } |
126 | 63 |
|
127 | | - .eds-button[data-icon-only][data-selectable-space='sm'] { |
128 | | - /* Base padding from token minus icon compensation: (8px - 2px) = 6px spacious / (6px - 2px) = 4px comfortable */ |
129 | | - /* Line-height (12px) same for both densities */ |
130 | | - /* Target height: 24px (consistent across densities) */ |
131 | | - --_base-padding: calc(var(--eds-selectable-space-vertical) - 0.125rem); |
132 | | - padding: calc( |
133 | | - var(--_base-padding) + |
134 | | - ( |
135 | | - var(--eds-typography-line-height-squished) - |
136 | | - var(--eds-typography-icon-size) |
137 | | - ) / |
138 | | - 2 |
139 | | - ); |
| 64 | + /* ===== ICON-ONLY BUTTON ===== */ |
| 65 | + /* Height from size variant, aspect-ratio makes it square, flexbox centers icon */ |
| 66 | + |
| 67 | + .eds-button[data-icon-only] { |
| 68 | + aspect-ratio: 1; |
| 69 | + padding: 0; |
140 | 70 | } |
141 | 71 |
|
142 | 72 | /* ===== ROUND ICON-ONLY BUTTON ===== */ |
|
232 | 162 | flex-shrink: 0; |
233 | 163 | } |
234 | 164 |
|
235 | | - /* Icon-only buttons: remove negative margins, use padding for sizing */ |
| 165 | + /* Icon-only buttons: remove negative margins since flexbox handles centering */ |
236 | 166 | .eds-button[data-icon-only] .icon { |
237 | 167 | margin: 0; |
238 | 168 | } |
239 | 169 | } |
240 | 170 |
|
241 | | -/* ===== LABEL WRAPPER (TypographyNext) ===== */ |
242 | | -/* Outside @layer to override typography.css which sets display: block on [data-font-family] */ |
243 | | - |
244 | | -.eds-button { |
245 | | - display: inline-flex; |
246 | | -} |
247 | | - |
248 | | -.eds-button > span { |
249 | | - display: inline-flex; |
250 | | - align-items: center; |
251 | | - gap: inherit; |
252 | | -} |
253 | | - |
254 | | -/* Reset baseline padding and text-box-trim for proper centering */ |
255 | | -.eds-button > span[data-baseline] { |
256 | | - padding: 0; |
257 | | - /* Disable text-box-trim so text sits centered within its line-height box */ |
258 | | - /* Flexbox will then center the entire line-height box vertically in the button */ |
259 | | - text-box-trim: none; |
260 | | - text-box-edge: auto; |
261 | | -} |
262 | | - |
263 | | -/* Icon-only: span should not affect layout */ |
264 | | -.eds-button[data-icon-only] > span { |
265 | | - display: contents; |
266 | | -} |
267 | | - |
268 | | -/* ===== DENSITY OVERRIDES ===== */ |
269 | 171 | /* |
270 | | - * Comfortable density uses smaller font-sizes (one size down) and tighter spacing. |
| 172 | + * Outside @layer to override typography.css [data-font-family] { display: block }. |
| 173 | + * The span wraps text children via TypographyNext and needs inline-flex for |
| 174 | + * icon+text gap and vertical centering. |
271 | 175 | * |
272 | | - * Font-size mapping (from Figma): |
273 | | - * - small: XS (10.5px) instead of SM (12px) |
274 | | - * - default: SM (12px) instead of MD (14px) |
275 | | - * - large: MD (14px) instead of LG (16px) |
276 | | - * |
277 | | - * Target heights in comfortable mode: |
278 | | - * - small: 20px (4px × 2 + 12px line-height) |
279 | | - * - default: 24px (4px × 2 + 16px line-height) |
280 | | - * - large: 36px (8px × 2 + 20px line-height) |
281 | | - * |
282 | | - * These overrides are OUTSIDE @layer to ensure they can override the typography |
283 | | - * tokens from @equinor/eds-tokens/css/variables. |
| 176 | + * text-box/padding-block reset disables typography.css baseline padding — |
| 177 | + * button handles its own sizing via min-height + flexbox centering. |
284 | 178 | */ |
285 | 179 |
|
286 | | -[data-density='comfortable'] .eds-button[data-selectable-space='sm'][data-font-size='sm'], |
287 | | -[data-density='comfortable'] .eds-button[data-selectable-space='sm'] [data-font-size='sm'] { |
288 | | - /* Override line-height to maintain SM height (12px instead of XS's 12px) */ |
289 | | - --eds-typography-line-height: 0.75rem; /* 12px (SM line-height) */ |
290 | | - --eds-typography-line-height-squished: 0.75rem; /* 12px */ |
291 | | -} |
292 | | - |
293 | | -[data-density='comfortable'] .eds-button[data-selectable-space='sm'][data-font-size='sm'] { |
294 | | - /* Target: 20px = (5px + 3px) + 12px line-height */ |
295 | | - /* Asymmetric padding to visually center text (more top, less bottom) */ |
296 | | - padding-top: var(--_comfortable-padding-top); |
297 | | - padding-bottom: var(--_comfortable-padding-bottom); |
298 | | -} |
299 | | - |
300 | | -[data-density='comfortable'] .eds-button[data-selectable-space='md'][data-font-size='md'], |
301 | | -[data-density='comfortable'] .eds-button[data-selectable-space='md'] [data-font-size='md'] { |
302 | | - /* Override line-height to maintain MD height (16px instead of SM's 12px) */ |
303 | | - --eds-typography-line-height: 1rem; /* 16px (MD line-height, NOT SM) */ |
304 | | - --eds-typography-line-height-squished: 1rem; /* 16px */ |
305 | | -} |
306 | | - |
307 | | -[data-density='comfortable'] .eds-button[data-selectable-space='md'][data-font-size='md'] { |
308 | | - /* Target: 24px = (5px + 3px) + 16px line-height */ |
309 | | - /* Asymmetric padding to visually center text (more top, less bottom) */ |
310 | | - padding-top: var(--_comfortable-padding-top); |
311 | | - padding-bottom: var(--_comfortable-padding-bottom); |
312 | | -} |
313 | | - |
314 | | -[data-density='comfortable'] .eds-button[data-selectable-space='lg'][data-font-size='lg'], |
315 | | -[data-density='comfortable'] .eds-button[data-selectable-space='lg'] [data-font-size='lg'] { |
316 | | - /* Override line-height to maintain LG height (20px instead of MD's 16px) */ |
317 | | - --eds-typography-line-height: 1.25rem; /* 20px (LG line-height, NOT MD) */ |
318 | | - --eds-typography-line-height-squished: 1.25rem; /* 20px */ |
319 | | -} |
320 | | - |
321 | | -[data-density='comfortable'] .eds-button[data-selectable-space='lg'][data-font-size='lg'] { |
322 | | - /* Target: 36px = (8px × 2) + 20px */ |
323 | | - /* Token gives 12px in comfortable mode, minus icon compensation = 8px */ |
324 | | - padding-block: calc(var(--eds-selectable-space-vertical) - 0.25rem); /* 12px → 8px */ |
325 | | -} |
326 | | - |
327 | | -/* Icon-only button overrides for comfortable density */ |
328 | | -/* Set fixed padding to ensure square buttons that match labeled button heights */ |
329 | | -/* Formula: padding = (target-height - icon-size) / 2 */ |
330 | | - |
331 | | -[data-density='comfortable'] .eds-button[data-icon-only][data-selectable-space='sm'] { |
332 | | - /* Target: 20×20px to match labeled small button (20px height) */ |
333 | | - /* Icon size: 16px, padding needed: (20 - 16) / 2 = 2px */ |
334 | | - padding: var(--_comfortable-icon-padding-sm); |
335 | | -} |
336 | | - |
337 | | -[data-density='comfortable'] .eds-button[data-icon-only][data-selectable-space='md'] { |
338 | | - /* Target: 24×24px to match labeled default button (24px height) */ |
339 | | - /* Icon size: 18px, padding needed: (24 - 18) / 2 = 3px */ |
340 | | - padding: var(--_comfortable-icon-padding-md); |
| 180 | +.eds-button > span { |
| 181 | + display: inline-flex; |
| 182 | + align-items: center; |
| 183 | + gap: var(--eds-typography-gap-horizontal); |
| 184 | + text-box: normal; |
| 185 | + padding-block: 0; |
341 | 186 | } |
342 | 187 |
|
343 | | -[data-density='comfortable'] .eds-button[data-icon-only][data-selectable-space='lg'] { |
344 | | - /* Target: 36×36px to match labeled large button (36px height) */ |
345 | | - /* Icon size: 20px, padding needed: (36 - 20) / 2 = 8px */ |
346 | | - padding: var(--_comfortable-icon-padding-lg); |
347 | | -} |
0 commit comments