@carbon/styles 1.110.1 → 1.111.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@carbon/styles",
3
3
  "description": "Styles for the Carbon Design System",
4
- "version": "1.110.1",
4
+ "version": "1.111.0",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
@@ -40,13 +40,13 @@
40
40
  }
41
41
  },
42
42
  "dependencies": {
43
- "@carbon/colors": "^11.53.0",
44
- "@carbon/feature-flags": "^1.4.0",
45
- "@carbon/grid": "^11.57.0",
46
- "@carbon/layout": "^11.54.0",
47
- "@carbon/motion": "^11.47.0",
48
- "@carbon/themes": "^11.76.1",
49
- "@carbon/type": "^11.62.0",
43
+ "@carbon/colors": "^11.54.0",
44
+ "@carbon/feature-flags": "^1.5.0",
45
+ "@carbon/grid": "^11.58.0",
46
+ "@carbon/layout": "^11.55.0",
47
+ "@carbon/motion": "^11.48.0",
48
+ "@carbon/themes": "^11.77.0",
49
+ "@carbon/type": "^11.63.0",
50
50
  "@ibm/plex": "6.4.1",
51
51
  "@ibm/plex-mono": "1.1.0",
52
52
  "@ibm/plex-sans": "1.1.0",
@@ -75,5 +75,5 @@
75
75
  "scss/**/*.css",
76
76
  "css/**/*.css"
77
77
  ],
78
- "gitHead": "1110000e8374c35b7e040b09a7e292b2227f331d"
78
+ "gitHead": "5102bd860864c2580048183ffaf50d1ffd4400b5"
79
79
  }
@@ -22,6 +22,7 @@ describe('@carbon/styles/scss/layout', () => {
22
22
 
23
23
  $_: get('api', (
24
24
  mixins: (
25
+ emit-layout-context-classes: meta.mixin-exists('emit-layout-context-classes', 'layout'),
25
26
  emit-layout-tokens: meta.mixin-exists('emit-layout-tokens', 'layout'),
26
27
  emit-layout-tokens-to-shadow-host: meta.mixin-exists('emit-layout-tokens-to-shadow-host', 'layout'),
27
28
  ),
@@ -31,6 +32,7 @@ describe('@carbon/styles/scss/layout', () => {
31
32
  const { value: api } = get('api');
32
33
  expect(api).toEqual({
33
34
  mixins: {
35
+ 'emit-layout-context-classes': true,
34
36
  'emit-layout-tokens': true,
35
37
  'emit-layout-tokens-to-shadow-host': true,
36
38
  },
@@ -204,3 +206,90 @@ describe('@carbon/styles/scss/layout', () => {
204
206
  ).toBe(true);
205
207
  });
206
208
  });
209
+
210
+ describe('@carbon/styles/scss/utilities/layout', () => {
211
+ test('Public API', async () => {
212
+ const { get } = await render(`
213
+ @use 'sass:meta';
214
+ @use '../utilities/layout';
215
+
216
+ $_: get('api', (
217
+ functions: (
218
+ size: meta.function-exists('size', 'layout'),
219
+ density: meta.function-exists('density', 'layout'),
220
+ ),
221
+ mixins: (
222
+ emit-layout-context-classes: meta.mixin-exists('emit-layout-context-classes', 'layout'),
223
+ emit-layout-tokens: meta.mixin-exists('emit-layout-tokens', 'layout'),
224
+ emit-layout-tokens-to-shadow-host: meta.mixin-exists('emit-layout-tokens-to-shadow-host', 'layout'),
225
+ redefine-tokens: meta.mixin-exists('redefine-tokens', 'layout'),
226
+ use: meta.mixin-exists('use', 'layout'),
227
+ ),
228
+ ));
229
+ `);
230
+
231
+ const { value: api } = get('api');
232
+ expect(api).toEqual({
233
+ functions: {
234
+ size: true,
235
+ density: true,
236
+ },
237
+ mixins: {
238
+ 'emit-layout-context-classes': true,
239
+ 'emit-layout-tokens': true,
240
+ 'emit-layout-tokens-to-shadow-host': true,
241
+ 'redefine-tokens': true,
242
+ use: true,
243
+ },
244
+ });
245
+ });
246
+
247
+ test('does not emit layout styles when used', async () => {
248
+ const { result } = await render(`
249
+ @use '../utilities/layout';
250
+ `);
251
+
252
+ const output = result.css.toString();
253
+ expect(output).not.toContain(':root');
254
+ expect(output).not.toContain('.cds--layout--size-sm');
255
+ expect(output).not.toContain('.cds--layout-constraint--size__default-md');
256
+ });
257
+
258
+ test('emit-layout-context-classes emits only context classes', async () => {
259
+ const { result } = await render(`
260
+ @use '../utilities/layout';
261
+
262
+ @include layout.emit-layout-context-classes();
263
+ `);
264
+
265
+ const output = result.css.toString();
266
+ expect(output).toContain('.cds--layout--size-sm');
267
+ expect(output).toContain('--cds-layout-size-height-context');
268
+ expect(output).not.toContain(':root');
269
+ expect(output).not.toContain('.cds--layout--density-normal');
270
+ expect(output).not.toContain('.cds--layout-constraint--size__default-md');
271
+ });
272
+
273
+ test('utility mixins and functions compile without emitting layout classes', async () => {
274
+ const { result } = await render(`
275
+ @use '../utilities/layout';
276
+
277
+ .test {
278
+ @include layout.use('size', $default: 'md', $min: 'sm', $max: 'lg');
279
+ @include layout.use('density', $default: 'normal');
280
+ block-size: layout.size('height');
281
+ padding-inline: layout.density('padding-inline');
282
+ }
283
+ `);
284
+
285
+ const output = result.css.toString();
286
+ expect(output).toContain('--cds-layout-size-height-local');
287
+ expect(output).toContain('--cds-layout-density-padding-inline-local');
288
+ expect(output).toContain('block-size: var(--cds-layout-size-height-local)');
289
+ expect(output).toContain(
290
+ 'padding-inline: var(--cds-layout-density-padding-inline-local)'
291
+ );
292
+ expect(output).not.toContain('.cds--layout--size-sm');
293
+ expect(output).not.toContain('.cds--layout-constraint--size__default-md');
294
+ });
295
+ });
@@ -10,6 +10,7 @@
10
10
  'enable-css-custom-properties': true,
11
11
  'enable-css-grid': true,
12
12
  'enable-v11-release': true,
13
+ 'enable-v12-release': false,
13
14
  'enable-experimental-tile-contrast': false,
14
15
  'enable-tile-contrast': false,
15
16
  'enable-v12-tile-radio-icons': false,
package/scss/_layout.scss CHANGED
@@ -5,76 +5,20 @@
5
5
  // LICENSE file in the root directory of this source tree.
6
6
  //
7
7
 
8
+ @forward './utilities/layout';
9
+
8
10
  @use 'sass:map';
9
11
  @use 'sass:list';
10
12
 
11
13
  @use './config' as *;
12
14
  @use './utilities/custom-property';
13
- @use './utilities/convert';
14
- @use './spacing' as *;
15
-
16
- $layout-tokens: (
17
- size: (
18
- height: (
19
- xs: convert.to-rem(24px),
20
- sm: convert.to-rem(32px),
21
- md: convert.to-rem(40px),
22
- lg: convert.to-rem(48px),
23
- xl: convert.to-rem(64px),
24
- 2xl: convert.to-rem(80px),
25
- ),
26
- ),
27
- density: (
28
- padding-inline: (
29
- condensed: $spacing-03,
30
- normal: $spacing-05,
31
- ),
32
- ),
33
- );
34
-
35
- @mixin emit-layout-tokens {
36
- @each $group, $properties in $layout-tokens {
37
- @each $property, $steps in $properties {
38
- @each $step, $value in $steps {
39
- @include custom-property.declaration(
40
- 'layout-#{$group}-#{$property}-#{$step}',
41
- $value
42
- );
43
- }
44
-
45
- // CSS max() doesn't accept '0' as a value without a unit
46
- // stylelint-disable length-zero-no-unit
47
- @include custom-property.declaration(
48
- 'layout-#{$group}-#{$property}-min',
49
- 0px
50
- );
51
- // stylelint-enable length-zero-no-unit
52
-
53
- @include custom-property.declaration(
54
- 'layout-#{$group}-#{$property}-max',
55
- 999999999px
56
- );
57
- }
58
- }
59
- }
15
+ @use './utilities/layout' as *;
60
16
 
61
17
  @each $group, $properties in $layout-tokens {
18
+ @include emit-layout-context-classes($group);
19
+
62
20
  @each $property, $steps in $properties {
63
21
  @each $step, $value in $steps {
64
- .#{$prefix}--layout--#{$group}-#{$step} {
65
- @include custom-property.declaration(
66
- 'layout-#{$group}-#{$property}-context',
67
- custom-property.get-var(
68
- 'layout-#{$group}-#{$property}-#{$step}',
69
- $value
70
- )
71
- );
72
- @include custom-property.declaration(
73
- 'layout-#{$group}-#{$property}',
74
- custom-property.get-var('layout-#{$group}-#{$property}-context')
75
- );
76
- }
77
-
78
22
  .#{$prefix}--layout-constraint--#{$group}__default-#{$step} {
79
23
  @include custom-property.declaration(
80
24
  'layout-#{$group}-#{$property}',
@@ -103,29 +47,6 @@ $layout-tokens: (
103
47
  }
104
48
  }
105
49
 
106
- /// Emits layout context tokens for shadow host elements.
107
- @mixin emit-layout-tokens-to-shadow-host($host-selector) {
108
- @each $group, $properties in $layout-tokens {
109
- @each $property, $steps in $properties {
110
- @each $step, $value in $steps {
111
- :host(#{$host-selector}[#{$group}='#{$step}']) {
112
- @include custom-property.declaration(
113
- 'layout-#{$group}-#{$property}-context',
114
- custom-property.get-var(
115
- 'layout-#{$group}-#{$property}-#{$step}',
116
- $value
117
- )
118
- );
119
- @include custom-property.declaration(
120
- 'layout-#{$group}-#{$property}',
121
- custom-property.get-var('layout-#{$group}-#{$property}-context')
122
- );
123
- }
124
- }
125
- }
126
- }
127
- }
128
-
129
50
  :root {
130
51
  @include emit-layout-tokens();
131
52
  }
@@ -1,5 +1,5 @@
1
1
  //
2
- // Copyright IBM Corp. 2016, 2023
2
+ // Copyright IBM Corp. 2016, 2026
3
3
  //
4
4
  // This source code is licensed under the Apache-2.0 license found in the
5
5
  // LICENSE file in the root directory of this source tree.
@@ -10,6 +10,8 @@
10
10
  @use '../../config' as *;
11
11
  @use '../../spacing' as *;
12
12
  @use '../../colors' as *;
13
+ @use '../../utilities/focus-outline';
14
+ @use '../../utilities/button-reset';
13
15
  @use './tokens' as *;
14
16
 
15
17
  /// icon-indicator styles
@@ -20,16 +22,20 @@
20
22
  @include type-style('body-compact-01');
21
23
 
22
24
  display: flex;
25
+ align-items: center;
23
26
  color: $text-secondary;
27
+ gap: $spacing-03;
28
+ line-height: unset;
24
29
  }
25
30
 
26
31
  .#{$prefix}--icon-indicator svg {
27
32
  align-self: center;
28
- margin-inline-end: $spacing-03;
29
33
  }
30
34
 
31
35
  .#{$prefix}--icon-indicator--20 {
32
36
  @include type-style('body-compact-02');
37
+
38
+ line-height: unset;
33
39
  }
34
40
 
35
41
  .#{$prefix}--icon-indicator--failed {
@@ -87,4 +93,18 @@
87
93
  .#{$prefix}--icon-indicator--informative {
88
94
  fill: $status-blue;
89
95
  }
96
+
97
+ .#{$prefix}--icon-indicator__button {
98
+ @include button-reset.reset($width: false);
99
+
100
+ display: flex;
101
+
102
+ &:focus {
103
+ @include focus-outline.focus-outline;
104
+ }
105
+ }
106
+
107
+ .#{$prefix}--icon-indicator .#{$prefix}--definition-tooltip {
108
+ padding-block: $spacing-01;
109
+ }
90
110
  }
@@ -206,6 +206,10 @@
206
206
  color: $text-on-color;
207
207
  }
208
208
 
209
+ .#{$prefix}--menu-item--danger:focus {
210
+ box-shadow: inset 0 0 0 convert.to-rem(3px) $background;
211
+ }
212
+
209
213
  // MenuItemDivider
210
214
 
211
215
  .#{$prefix}--menu-item-divider {
@@ -1,5 +1,5 @@
1
1
  //
2
- // Copyright IBM Corp. 2016, 2023
2
+ // Copyright IBM Corp. 2016, 2026
3
3
  //
4
4
  // This source code is licensed under the Apache-2.0 license found in the
5
5
  // LICENSE file in the root directory of this source tree.
@@ -21,6 +21,7 @@
21
21
  @use '../../utilities/convert';
22
22
  @use '../../utilities/z-index' as *;
23
23
  @use '../../utilities/custom-property';
24
+ @use '../../utilities/layout';
24
25
 
25
26
  /// Overflow menu styles
26
27
  /// @access public
@@ -28,6 +29,7 @@
28
29
  @mixin overflow-menu {
29
30
  .#{$prefix}--overflow-menu,
30
31
  .#{$prefix}--overflow-menu__trigger {
32
+ @include layout.use('size', $default: 'md', $min: 'xs', $max: 'lg');
31
33
  @include button-reset.reset;
32
34
  @include component-reset.reset;
33
35
  @include focus-outline('reset');
@@ -36,10 +38,10 @@
36
38
  display: flex;
37
39
  align-items: center;
38
40
  justify-content: center;
39
- block-size: $spacing-08;
41
+ block-size: layout.size('height');
40
42
  cursor: pointer;
41
- inline-size: $spacing-08;
42
- min-block-size: $spacing-08;
43
+ inline-size: layout.size('height');
44
+ min-block-size: layout.size('height');
43
45
  transition:
44
46
  outline $duration-fast-02 motion(entrance, productive),
45
47
  background-color $duration-fast-02 motion(entrance, productive);
@@ -57,23 +59,6 @@
57
59
  margin-block-start: 0;
58
60
  }
59
61
 
60
- .#{$prefix}--overflow-menu--xs {
61
- block-size: $spacing-06;
62
- inline-size: $spacing-06;
63
- min-block-size: $spacing-06;
64
- }
65
-
66
- .#{$prefix}--overflow-menu--sm {
67
- block-size: $spacing-07;
68
- inline-size: $spacing-07;
69
- min-block-size: $spacing-07;
70
- }
71
-
72
- .#{$prefix}--overflow-menu--lg {
73
- block-size: $spacing-09;
74
- inline-size: $spacing-09;
75
- }
76
-
77
62
  // Overwrite Icon Tooltip focus styles
78
63
  .#{$prefix}--overflow-menu__trigger.#{$prefix}--tooltip--a11y.#{$prefix}--tooltip__trigger:focus {
79
64
  @include focus-outline('outline');
@@ -109,6 +94,7 @@
109
94
  }
110
95
 
111
96
  .#{$prefix}--overflow-menu-options {
97
+ @include layout.use('size', $default: 'md', $min: 'xs', $max: 'lg');
112
98
  @include component-reset.reset;
113
99
  @include box-shadow;
114
100
 
@@ -157,68 +143,32 @@
157
143
  .#{$prefix}--breadcrumb-menu-options
158
144
  )::after {
159
145
  block-size: convert.to-rem(3px);
160
- inline-size: $spacing-08;
146
+ inline-size: layout.size('height');
161
147
  inset-block-start: convert.to-rem(-3px);
162
148
  inset-inline-start: 0;
163
149
  }
164
150
 
165
151
  .#{$prefix}--overflow-menu-options[data-floating-menu-direction='top']::after {
166
152
  block-size: $spacing-03;
167
- inline-size: $spacing-08;
153
+ inline-size: layout.size('height');
168
154
  inset-block-end: -$spacing-03;
169
155
  inset-inline-start: 0;
170
156
  }
171
157
 
172
158
  .#{$prefix}--overflow-menu-options[data-floating-menu-direction='left']::after {
173
- block-size: $spacing-08;
159
+ block-size: layout.size('height');
174
160
  inline-size: convert.to-rem(6px);
175
161
  inset-block-start: 0;
176
162
  inset-inline-end: convert.to-rem(-6px);
177
163
  }
178
164
 
179
165
  .#{$prefix}--overflow-menu-options[data-floating-menu-direction='right']::after {
180
- block-size: $spacing-08;
166
+ block-size: layout.size('height');
181
167
  inline-size: convert.to-rem(6px);
182
168
  inset-block-start: 0;
183
169
  inset-inline-start: convert.to-rem(-6px);
184
170
  }
185
171
 
186
- .#{$prefix}--overflow-menu-options--xs.#{$prefix}--overflow-menu-options {
187
- &[data-floating-menu-direction='bottom']::after,
188
- &[data-floating-menu-direction='top']::after {
189
- inline-size: $spacing-06;
190
- }
191
-
192
- &[data-floating-menu-direction='left']::after,
193
- &[data-floating-menu-direction='right']::after {
194
- block-size: $spacing-06;
195
- }
196
- }
197
-
198
- .#{$prefix}--overflow-menu-options--sm.#{$prefix}--overflow-menu-options {
199
- &[data-floating-menu-direction='bottom']::after,
200
- &[data-floating-menu-direction='top']::after {
201
- inline-size: $spacing-07;
202
- }
203
-
204
- &[data-floating-menu-direction='left']::after,
205
- &[data-floating-menu-direction='right']::after {
206
- block-size: $spacing-07;
207
- }
208
- }
209
-
210
- .#{$prefix}--overflow-menu-options--lg.#{$prefix}--overflow-menu-options {
211
- &[data-floating-menu-direction='bottom']::after,
212
- &[data-floating-menu-direction='top']::after {
213
- inline-size: $spacing-09;
214
- }
215
-
216
- &[data-floating-menu-direction='left']::after,
217
- &[data-floating-menu-direction='right']::after {
218
- block-size: $spacing-09;
219
- }
220
- }
221
-
222
172
  .#{$prefix}--overflow-menu--flip.#{$prefix}--overflow-menu-options[data-floating-menu-direction='top']::after,
223
173
  .#{$prefix}--overflow-menu--flip.#{$prefix}--overflow-menu-options[data-floating-menu-direction='bottom']::after {
224
174
  inset-inline: auto 0;
@@ -244,26 +194,11 @@
244
194
  align-items: center;
245
195
  padding: 0;
246
196
  background-color: transparent;
247
- block-size: $spacing-08;
197
+ block-size: layout.size('height');
248
198
  inline-size: 100%;
249
199
  transition: background-color $duration-fast-02 motion(entrance, productive);
250
200
  }
251
201
 
252
- .#{$prefix}--overflow-menu-options--xs
253
- .#{$prefix}--overflow-menu-options__option {
254
- block-size: $spacing-06;
255
- }
256
-
257
- .#{$prefix}--overflow-menu-options--sm
258
- .#{$prefix}--overflow-menu-options__option {
259
- block-size: $spacing-07;
260
- }
261
-
262
- .#{$prefix}--overflow-menu-options--lg
263
- .#{$prefix}--overflow-menu-options__option {
264
- block-size: $spacing-09;
265
- }
266
-
267
202
  .#{$prefix}--overflow-menu--divider {
268
203
  border-block-start: 1px solid $border-subtle;
269
204
  }
@@ -344,6 +279,11 @@
344
279
  }
345
280
  }
346
281
 
282
+ .#{$prefix}--overflow-menu-options__option--danger
283
+ .#{$prefix}--overflow-menu-options__btn:focus {
284
+ box-shadow: inset 0 0 0 convert.to-rem(3px) $background;
285
+ }
286
+
347
287
  .#{$prefix}--overflow-menu-options__option--disabled:hover {
348
288
  background-color: $layer;
349
289
  cursor: not-allowed;
@@ -1,5 +1,5 @@
1
1
  //
2
- // Copyright IBM Corp. 2016, 2023
2
+ // Copyright IBM Corp. 2016, 2026
3
3
  //
4
4
  // This source code is licensed under the Apache-2.0 license found in the
5
5
  // LICENSE file in the root directory of this source tree.
@@ -10,6 +10,8 @@
10
10
  @use '../../config' as *;
11
11
  @use '../../spacing' as *;
12
12
  @use '../../colors' as *;
13
+ @use '../../utilities/focus-outline';
14
+ @use '../../utilities/button-reset';
13
15
  @use '../icon-indicator/tokens' as *;
14
16
 
15
17
  /// shape-indicator styles
@@ -20,16 +22,20 @@
20
22
  @include type-style('helper-text-01');
21
23
 
22
24
  display: flex;
25
+ align-items: center;
23
26
  color: $text-secondary;
27
+ gap: $spacing-03;
28
+ line-height: unset;
24
29
  }
25
30
 
26
31
  .#{$prefix}--shape-indicator svg {
27
32
  align-self: center;
28
- margin-inline-end: $spacing-03;
29
33
  }
30
34
 
31
35
  .#{$prefix}--shape-indicator--14 {
32
36
  @include type-style('body-compact-01');
37
+
38
+ line-height: unset;
33
39
  }
34
40
 
35
41
  .#{$prefix}--shape-indicator--failed {
@@ -89,4 +95,18 @@
89
95
  .#{$prefix}--shape-indicator--draft {
90
96
  fill: $status-gray;
91
97
  }
98
+
99
+ .#{$prefix}--shape-indicator__button {
100
+ @include button-reset.reset($width: false);
101
+
102
+ display: flex;
103
+
104
+ &:focus {
105
+ @include focus-outline.focus-outline;
106
+ }
107
+ }
108
+
109
+ .#{$prefix}--shape-indicator .#{$prefix}--definition-tooltip {
110
+ padding-block: $spacing-01;
111
+ }
92
112
  }
@@ -200,7 +200,7 @@
200
200
  }
201
201
 
202
202
  @if not(
203
- enabled('enable-v12-structured-list-visible-icons') and
203
+ enabled('enable-v12-structured-list-visible-icons') or
204
204
  $enable-v12-structured-list-visible-icons
205
205
  )
206
206
  {
@@ -8,8 +8,28 @@
8
8
  @use 'sass:map';
9
9
 
10
10
  @use '../config';
11
- @use '../layout' as *;
12
11
  @use './custom-property';
12
+ @use './convert';
13
+ @use '../spacing' as *;
14
+
15
+ $layout-tokens: (
16
+ size: (
17
+ height: (
18
+ xs: convert.to-rem(24px),
19
+ sm: convert.to-rem(32px),
20
+ md: convert.to-rem(40px),
21
+ lg: convert.to-rem(48px),
22
+ xl: convert.to-rem(64px),
23
+ 2xl: convert.to-rem(80px),
24
+ ),
25
+ ),
26
+ density: (
27
+ padding-inline: (
28
+ condensed: $spacing-03,
29
+ normal: $spacing-05,
30
+ ),
31
+ ),
32
+ );
13
33
 
14
34
  /// Enables the use of contextual layout tokens within a component. This mixin should be
15
35
  /// included on the outermost selector of the component.
@@ -113,3 +133,79 @@
113
133
  @function density($property) {
114
134
  @return -group('density', $property);
115
135
  }
136
+
137
+ /// Emits layout context class rules for a layout group.
138
+ @mixin emit-layout-context-classes($group: size) {
139
+ $properties: map.get($layout-tokens, $group);
140
+
141
+ @if not $properties {
142
+ @error 'Unknown layout group: #{$group}';
143
+ }
144
+
145
+ @each $property, $steps in $properties {
146
+ @each $step, $value in $steps {
147
+ .#{config.$prefix}--layout--#{$group}-#{$step} {
148
+ @include custom-property.declaration(
149
+ 'layout-#{$group}-#{$property}-context',
150
+ custom-property.get-var(
151
+ 'layout-#{$group}-#{$property}-#{$step}',
152
+ $value
153
+ )
154
+ );
155
+ @include custom-property.declaration(
156
+ 'layout-#{$group}-#{$property}',
157
+ custom-property.get-var('layout-#{$group}-#{$property}-context')
158
+ );
159
+ }
160
+ }
161
+ }
162
+ }
163
+
164
+ @mixin emit-layout-tokens {
165
+ @each $group, $properties in $layout-tokens {
166
+ @each $property, $steps in $properties {
167
+ @each $step, $value in $steps {
168
+ @include custom-property.declaration(
169
+ 'layout-#{$group}-#{$property}-#{$step}',
170
+ $value
171
+ );
172
+ }
173
+
174
+ // CSS max() doesn't accept '0' as a value without a unit
175
+ // stylelint-disable length-zero-no-unit
176
+ @include custom-property.declaration(
177
+ 'layout-#{$group}-#{$property}-min',
178
+ 0px
179
+ );
180
+ // stylelint-enable length-zero-no-unit
181
+
182
+ @include custom-property.declaration(
183
+ 'layout-#{$group}-#{$property}-max',
184
+ 999999999px
185
+ );
186
+ }
187
+ }
188
+ }
189
+
190
+ /// Emits layout context tokens for shadow host elements.
191
+ @mixin emit-layout-tokens-to-shadow-host($host-selector) {
192
+ @each $group, $properties in $layout-tokens {
193
+ @each $property, $steps in $properties {
194
+ @each $step, $value in $steps {
195
+ :host(#{$host-selector}[#{$group}='#{$step}']) {
196
+ @include custom-property.declaration(
197
+ 'layout-#{$group}-#{$property}-context',
198
+ custom-property.get-var(
199
+ 'layout-#{$group}-#{$property}-#{$step}',
200
+ $value
201
+ )
202
+ );
203
+ @include custom-property.declaration(
204
+ 'layout-#{$group}-#{$property}',
205
+ custom-property.get-var('layout-#{$group}-#{$property}-context')
206
+ );
207
+ }
208
+ }
209
+ }
210
+ }
211
+ }