@carbon/styles 1.103.0 → 1.104.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.103.0",
4
+ "version": "1.104.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.49.0",
43
+ "@carbon/colors": "^11.50.0",
44
44
  "@carbon/feature-flags": "^1.2.0",
45
- "@carbon/grid": "^11.52.0",
46
- "@carbon/layout": "^11.50.0",
47
- "@carbon/motion": "^11.43.0",
48
- "@carbon/themes": "^11.70.0",
49
- "@carbon/type": "^11.56.0",
45
+ "@carbon/grid": "^11.53.0",
46
+ "@carbon/layout": "^11.51.0",
47
+ "@carbon/motion": "^11.44.0",
48
+ "@carbon/themes": "^11.71.0",
49
+ "@carbon/type": "^11.57.0",
50
50
  "@ibm/plex": "6.0.0-next.6",
51
51
  "@ibm/plex-mono": "1.1.0",
52
52
  "@ibm/plex-sans": "1.1.0",
@@ -59,7 +59,7 @@
59
59
  "@ibm/telemetry-js": "^1.5.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@carbon/test-utils": "^10.40.0",
62
+ "@carbon/test-utils": "^10.41.0",
63
63
  "autoprefixer": "^10.4.7",
64
64
  "browserslist-config-carbon": "^11.2.0",
65
65
  "css": "^3.0.0",
@@ -75,5 +75,5 @@
75
75
  "scss/**/*.css",
76
76
  "css/**/*.css"
77
77
  ],
78
- "gitHead": "aeaaa31889990fc76c7e0e8a29ec0bf96ce33f82"
78
+ "gitHead": "937649543e9cc6af9dfb6b53a2adb76760bca986"
79
79
  }
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Copyright IBM Corp. 2026
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @jest-environment node
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ const { SassRenderer } = require('@carbon/test-utils/scss');
13
+ const css = require('css');
14
+
15
+ const { render } = SassRenderer.create(__dirname);
16
+
17
+ describe('@carbon/styles/scss/layout', () => {
18
+ test('Public API', async () => {
19
+ const { get } = await render(`
20
+ @use 'sass:meta';
21
+ @use '../layout';
22
+
23
+ $_: get('api', (
24
+ mixins: (
25
+ emit-layout-tokens: meta.mixin-exists('emit-layout-tokens', 'layout'),
26
+ emit-layout-tokens-to-shadow-host: meta.mixin-exists('emit-layout-tokens-to-shadow-host', 'layout'),
27
+ ),
28
+ ));
29
+ `);
30
+
31
+ const { value: api } = get('api');
32
+ expect(api).toEqual({
33
+ mixins: {
34
+ 'emit-layout-tokens': true,
35
+ 'emit-layout-tokens-to-shadow-host': true,
36
+ },
37
+ });
38
+ });
39
+
40
+ test('emit-layout-tokens emits all size tokens', async () => {
41
+ const { result } = await render(`
42
+ @use '../layout';
43
+ .test {
44
+ @include layout.emit-layout-tokens();
45
+ }
46
+ `);
47
+
48
+ const output = result.css.toString();
49
+ expect(output).toContain('--cds-layout-size-height-xs');
50
+ expect(output).toContain('--cds-layout-size-height-sm');
51
+ expect(output).toContain('--cds-layout-size-height-md');
52
+ expect(output).toContain('--cds-layout-size-height-lg');
53
+ expect(output).toContain('--cds-layout-size-height-xl');
54
+ expect(output).toContain('--cds-layout-size-height-2xl');
55
+ });
56
+
57
+ test('emit-layout-tokens emits all density tokens', async () => {
58
+ const { result } = await render(`
59
+ @use '../layout';
60
+ .test {
61
+ @include layout.emit-layout-tokens();
62
+ }
63
+ `);
64
+
65
+ const output = result.css.toString();
66
+ expect(output).toContain('--cds-layout-density-padding-inline-condensed');
67
+ expect(output).toContain('--cds-layout-density-padding-inline-normal');
68
+ });
69
+
70
+ test('emit-layout-tokens emits min and max boundary tokens', async () => {
71
+ const { result } = await render(`
72
+ @use '../layout';
73
+ .test {
74
+ @include layout.emit-layout-tokens();
75
+ }
76
+ `);
77
+
78
+ const output = result.css.toString();
79
+ expect(output).toContain('--cds-layout-size-height-min');
80
+ expect(output).toContain('--cds-layout-size-height-max');
81
+ expect(output).toContain('--cds-layout-density-padding-inline-min');
82
+ expect(output).toContain('--cds-layout-density-padding-inline-max');
83
+ });
84
+
85
+ test('layout size classes set size context token', async () => {
86
+ const { result } = await render(`
87
+ @use '../layout';
88
+ `);
89
+
90
+ const { stylesheet } = css.parse(result.css.toString());
91
+
92
+ const findRule = (selector) =>
93
+ stylesheet.rules.find((rule) =>
94
+ rule.selectors?.some((s) => s.includes(selector))
95
+ );
96
+
97
+ const findDeclaration = (rule, property) =>
98
+ rule?.declarations?.find((d) => d.property.includes(property));
99
+
100
+ expect(
101
+ findDeclaration(
102
+ findRule('.cds--layout--size-sm'),
103
+ '--cds-layout-size-height-context'
104
+ )
105
+ ).toBeDefined();
106
+
107
+ expect(
108
+ findDeclaration(
109
+ findRule('.cds--layout--size-lg'),
110
+ '--cds-layout-size-height-context'
111
+ )
112
+ ).toBeDefined();
113
+ });
114
+
115
+ test('layout density classes set density context token', async () => {
116
+ const { result } = await render(`
117
+ @use '../layout';
118
+ `);
119
+
120
+ const { stylesheet } = css.parse(result.css.toString());
121
+
122
+ const findRule = (selector) =>
123
+ stylesheet.rules.find((rule) =>
124
+ rule.selectors?.some((s) => s.includes(selector))
125
+ );
126
+
127
+ const findDeclaration = (rule, property) =>
128
+ rule?.declarations?.find((d) => d.property.includes(property));
129
+
130
+ expect(
131
+ findDeclaration(
132
+ findRule('.cds--layout--density-condensed'),
133
+ '--cds-layout-density-padding-inline-context'
134
+ )
135
+ ).toBeDefined();
136
+
137
+ expect(
138
+ findDeclaration(
139
+ findRule('.cds--layout--density-normal'),
140
+ '--cds-layout-density-padding-inline-context'
141
+ )
142
+ ).toBeDefined();
143
+ });
144
+
145
+ test('layout constraint classes are generated for default, min and max', async () => {
146
+ const { result } = await render(`
147
+ @use '../layout';
148
+ `);
149
+
150
+ const output = result.css.toString();
151
+ expect(output).toContain('.cds--layout-constraint--size__default-md');
152
+ expect(output).toContain('.cds--layout-constraint--size__min-sm');
153
+ expect(output).toContain('.cds--layout-constraint--size__max-lg');
154
+ expect(output).toContain(
155
+ '.cds--layout-constraint--density__default-condensed'
156
+ );
157
+ expect(output).toContain('.cds--layout-constraint--density__min-normal');
158
+ expect(output).toContain('.cds--layout-constraint--density__max-normal');
159
+ });
160
+
161
+ test('emit-layout-tokens-to-shadow-host generates host selectors for size', async () => {
162
+ const { result } = await render(`
163
+ @use '../layout';
164
+ @include layout.emit-layout-tokens-to-shadow-host('cds-layout');
165
+ `);
166
+
167
+ const output = result.css.toString();
168
+ expect(output).toContain(':host(cds-layout[size=xs])');
169
+ expect(output).toContain(':host(cds-layout[size=sm])');
170
+ expect(output).toContain(':host(cds-layout[size=md])');
171
+ expect(output).toContain(':host(cds-layout[size=lg])');
172
+ expect(output).toContain(':host(cds-layout[size=xl])');
173
+ expect(output).toContain(':host(cds-layout[size="2xl"])');
174
+ expect(output).toContain('--cds-layout-size-height-context');
175
+ });
176
+
177
+ test('emit-layout-tokens-to-shadow-host generates host selectors for density', async () => {
178
+ const { result } = await render(`
179
+ @use '../layout';
180
+ @include layout.emit-layout-tokens-to-shadow-host('cds-layout');
181
+ `);
182
+
183
+ const output = result.css.toString();
184
+ expect(output).toContain(':host(cds-layout[density=condensed])');
185
+ expect(output).toContain(':host(cds-layout[density=normal])');
186
+ expect(output).toContain('--cds-layout-density-padding-inline-context');
187
+ });
188
+
189
+ test(':root emits layout tokens globally', async () => {
190
+ const { result } = await render(`
191
+ @use '../layout';
192
+ `);
193
+
194
+ const { stylesheet } = css.parse(result.css.toString());
195
+ const rootRule = stylesheet.rules.find((rule) =>
196
+ rule.selectors?.includes(':root')
197
+ );
198
+
199
+ expect(rootRule).toBeDefined();
200
+ expect(
201
+ rootRule.declarations.some((d) =>
202
+ d.property.includes('--cds-layout-size-height-xs')
203
+ )
204
+ ).toBe(true);
205
+ });
206
+ });
package/scss/_layout.scss CHANGED
@@ -103,6 +103,29 @@ $layout-tokens: (
103
103
  }
104
104
  }
105
105
 
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
+
106
129
  :root {
107
130
  @include emit-layout-tokens();
108
131
  }
@@ -1,5 +1,5 @@
1
1
  //
2
- // Copyright IBM Corp. 2022
2
+ // Copyright IBM Corp. 2022, 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.
@@ -56,6 +56,7 @@
56
56
  position: sticky;
57
57
  z-index: 1;
58
58
  display: flex;
59
+ box-sizing: border-box;
59
60
  align-items: center;
60
61
  inset-block-start: 0;
61
62
  padding-inline: layout.density('padding-inline');
@@ -120,7 +121,7 @@
120
121
  .#{$prefix}--contained-list--on-page .#{$prefix}--contained-list__header {
121
122
  @include type-style('heading-compact-01');
122
123
 
123
- background-color: $background;
124
+ background-color: $layer-background;
124
125
  block-size: layout.size('height');
125
126
  border-block-end: 1px solid $border-subtle;
126
127
  color: $text-primary;
@@ -91,7 +91,7 @@
91
91
  .#{$prefix}--list--unordered.#{$prefix}--list--nested
92
92
  > .#{$prefix}--list__item::before {
93
93
  // ▪ square
94
- content: '\0025AA';
94
+ content: '\0025AA\00FE0E';
95
95
  // offset to account for smaller ▪ vs –
96
96
  inset-inline-start: calc(-1 * #{$spacing-04});
97
97
  }