@carbon-labs/react-ui-shell 0.62.0 → 0.64.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.
@@ -168,7 +168,7 @@ function SideNavRenderFunction({
168
168
  } else if (firstElement) {
169
169
  firstElement.tabIndex = 0;
170
170
  if (slotElement) {
171
- const firstElementAfterSlot = slotElement.nextElementSibling?.nextElementSibling?.querySelector('a, button');
171
+ const firstElementAfterSlot = slotElement.nextElementSibling?.querySelector('a, button');
172
172
  if (firstElementAfterSlot) {
173
173
  firstElementAfterSlot.tabIndex = 0;
174
174
  }
@@ -345,7 +345,7 @@ function SideNavRenderFunction({
345
345
  const target = event.target;
346
346
  const isNavItemClick = target.closest(`.${prefix}--side-nav a, .${prefix}--side-nav button`);
347
347
  const isInRail = isNavItemClick?.closest(`.${prefix}--side-nav--rail`);
348
- if (isNavItemClick) {
348
+ if (isNavItemClick && !isNavItemClick.classList.contains(`${prefix}--side-nav__submenu`)) {
349
349
  isInRail ? handleToggle(false, false) : onSideNavBlur?.();
350
350
  }
351
351
  });
@@ -69,6 +69,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
69
69
  [`${prefix}--side-nav__item`]: true,
70
70
  [`${prefix}--side-nav__item--primary`]: primary,
71
71
  [`${prefix}--side-nav__item--active`]: !primary && (active || hasActiveDescendant(children) && !isExpanded),
72
+ [`${prefix}--side-nav__item--has-active-descendant`]: active || hasActiveDescendant(children) && !isExpanded,
72
73
  [`${prefix}--side-nav__item--icon`]: IconElement,
73
74
  [`${prefix}--side-nav__item--large`]: large,
74
75
  [customClassName]: !!customClassName
@@ -154,7 +155,9 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
154
155
  firstLink.current = firstLinkElement?.getAttribute('href') ?? '';
155
156
  }
156
157
  }
157
- if (depth === 0) return;
158
+ if (depth === 0) {
159
+ return;
160
+ }
158
161
 
159
162
  // if depth is more than 0, that means its nested, thus we set treeview mode
160
163
  setIsTreeview?.(true);
@@ -185,7 +188,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
185
188
  if (match(event, Tab)) {
186
189
  const slotElement = node.closest(`.${prefix}--side-nav__slot`);
187
190
  if (slotElement) {
188
- (slotElement.nextElementSibling?.nextElementSibling?.querySelector('a, button')).tabIndex = 0;
191
+ (slotElement.nextElementSibling?.querySelector('a, button')).tabIndex = 0;
189
192
  }
190
193
  }
191
194
  if (match(event, ArrowLeft$1)) {
@@ -170,7 +170,7 @@ function SideNavRenderFunction({
170
170
  } else if (firstElement) {
171
171
  firstElement.tabIndex = 0;
172
172
  if (slotElement) {
173
- const firstElementAfterSlot = slotElement.nextElementSibling?.nextElementSibling?.querySelector('a, button');
173
+ const firstElementAfterSlot = slotElement.nextElementSibling?.querySelector('a, button');
174
174
  if (firstElementAfterSlot) {
175
175
  firstElementAfterSlot.tabIndex = 0;
176
176
  }
@@ -347,7 +347,7 @@ function SideNavRenderFunction({
347
347
  const target = event.target;
348
348
  const isNavItemClick = target.closest(`.${prefix}--side-nav a, .${prefix}--side-nav button`);
349
349
  const isInRail = isNavItemClick?.closest(`.${prefix}--side-nav--rail`);
350
- if (isNavItemClick) {
350
+ if (isNavItemClick && !isNavItemClick.classList.contains(`${prefix}--side-nav__submenu`)) {
351
351
  isInRail ? handleToggle(false, false) : onSideNavBlur?.();
352
352
  }
353
353
  });
@@ -71,6 +71,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
71
71
  [`${prefix}--side-nav__item`]: true,
72
72
  [`${prefix}--side-nav__item--primary`]: primary,
73
73
  [`${prefix}--side-nav__item--active`]: !primary && (active || hasActiveDescendant(children) && !isExpanded),
74
+ [`${prefix}--side-nav__item--has-active-descendant`]: active || hasActiveDescendant(children) && !isExpanded,
74
75
  [`${prefix}--side-nav__item--icon`]: IconElement,
75
76
  [`${prefix}--side-nav__item--large`]: large,
76
77
  [customClassName]: !!customClassName
@@ -156,7 +157,9 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
156
157
  firstLink.current = firstLinkElement?.getAttribute('href') ?? '';
157
158
  }
158
159
  }
159
- if (depth === 0) return;
160
+ if (depth === 0) {
161
+ return;
162
+ }
160
163
 
161
164
  // if depth is more than 0, that means its nested, thus we set treeview mode
162
165
  setIsTreeview?.(true);
@@ -187,7 +190,7 @@ const SideNavMenu = /*#__PURE__*/React__default.forwardRef(function SideNavMenu(
187
190
  if (match.match(event, keys.Tab)) {
188
191
  const slotElement = node.closest(`.${prefix}--side-nav__slot`);
189
192
  if (slotElement) {
190
- (slotElement.nextElementSibling?.nextElementSibling?.querySelector('a, button')).tabIndex = 0;
193
+ (slotElement.nextElementSibling?.querySelector('a, button')).tabIndex = 0;
191
194
  }
192
195
  }
193
196
  if (match.match(event, keys.ArrowLeft)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carbon-labs/react-ui-shell",
3
- "version": "0.62.0",
3
+ "version": "0.64.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
@@ -42,5 +42,5 @@
42
42
  "dependencies": {
43
43
  "@ibm/telemetry-js": "^1.9.1"
44
44
  },
45
- "gitHead": "9656b7b03d0232cdda3cf200d972eaf727a35fbc"
45
+ "gitHead": "3bf6978c6066837bfd877816ee4c520031cb5fe3"
46
46
  }
@@ -51,6 +51,43 @@ div:has(.#{$prefix}--header)
51
51
  margin-inline-end: $spacing-05;
52
52
  }
53
53
 
54
+ .#{$prefix}--side-nav__item--active.#{$prefix}--side-nav__item--has-active-descendant
55
+ .#{$prefix}--side-nav__submenu:not(
56
+ .#{$prefix}--side-nav__item--has-active-descendant
57
+ )[aria-expanded='false'] {
58
+ background-color: transparent;
59
+
60
+ &::before {
61
+ display: none;
62
+ }
63
+ }
64
+
65
+ .#{$prefix}--side-nav__item--active.#{$prefix}--side-nav__item--has-active-descendant[aria-expanded='false']
66
+ .#{$prefix}--side-nav__submenu[aria-expanded='false'],
67
+ .#{$prefix}--side-nav__item--active
68
+ .#{$prefix}--side-nav__item--has-active-descendant
69
+ .#{$prefix}--side-nav__submenu.#{$prefix}--side-nav__submenu--active[aria-expanded='false'] {
70
+ position: relative;
71
+ background-color: $background-selected;
72
+ color: $text-primary;
73
+
74
+ &::before {
75
+ position: absolute;
76
+ display: block;
77
+ background-color: $border-interactive;
78
+ content: '';
79
+ inline-size: 3px;
80
+ inset-block: 0;
81
+ inset-inline-start: 0;
82
+ }
83
+ }
84
+
85
+ .#{$prefix}--side-nav__item--active
86
+ .#{$prefix}--side-nav__submenu:not(.#{$prefix}--side-nav__submenu--active)
87
+ > .#{$prefix}--side-nav__submenu-title {
88
+ font-weight: 500;
89
+ }
90
+
54
91
  .#{$prefix}--side-nav__submenu.#{$prefix}--side-nav__submenu--active {
55
92
  > span {
56
93
  color: $text-primary;
@@ -71,8 +108,29 @@ div:has(.#{$prefix}--header)
71
108
  }
72
109
  }
73
110
 
111
+ @include breakpoint-down(md) {
112
+ .#{$prefix}--side-nav__submenu {
113
+ padding: 0 $spacing-05 0 convert.to-rem(14px);
114
+ }
115
+
116
+ .#{$prefix}--side-nav__submenu,
117
+ .#{$prefix}--side-nav__link,
118
+ .#{$prefix}--side-nav__menu a.#{$prefix}--side-nav__link {
119
+ block-size: $spacing-08;
120
+ }
121
+
122
+ .#{$prefix}--side-nav__icon {
123
+ margin-inline-end: convert.to-rem(14px);
124
+ }
125
+
126
+ .#{$prefix}--side-nav__icon > svg {
127
+ block-size: convert.to-rem(20px);
128
+ inline-size: convert.to-rem(20px);
129
+ }
130
+ }
131
+
74
132
  // SideNavMenu
75
- // Level 2
133
+ // Level 2 / Doublewide Level 3
76
134
  // without icon
77
135
  .#{$prefix}--side-nav__submenu
78
136
  + .#{$prefix}--side-nav__menu
@@ -85,12 +143,61 @@ div:has(.#{$prefix}--header)
85
143
  .#{$prefix}--side-nav__submenu
86
144
  + .#{$prefix}--side-nav__menu
87
145
  > .#{$prefix}--side-nav__item--icon
88
- .#{$prefix}--side-nav__submenu {
146
+ > .#{$prefix}--side-nav__submenu {
89
147
  padding-inline-start: $spacing-09;
90
148
  }
91
149
 
150
+ // Level 3 / Doublewide Level 4
151
+ // without icon, icon not supported at this level
152
+ .#{$prefix}--side-nav__submenu
153
+ + .#{$prefix}--side-nav__menu
154
+ > .#{$prefix}--side-nav__item
155
+ .#{$prefix}--side-nav__menu
156
+ > .#{$prefix}--side-nav__item
157
+ .#{$prefix}--side-nav__submenu {
158
+ padding-inline-start: $spacing-11;
159
+ }
160
+
161
+ // with icon parent at level 2
162
+ .#{$prefix}--side-nav__item--icon
163
+ > .#{$prefix}--side-nav__submenu
164
+ + .#{$prefix}--side-nav__menu
165
+ > .#{$prefix}--side-nav__item--icon
166
+ > .#{$prefix}--side-nav__submenu
167
+ + .#{$prefix}--side-nav__menu
168
+ > .#{$prefix}--side-nav__item
169
+ > .#{$prefix}--side-nav__submenu {
170
+ padding-inline-start: $spacing-12;
171
+ }
172
+
173
+ // Level 4 / / Doesn't exist in doublewide
174
+ // without icon, icon not supported at this level
175
+ .#{$prefix}--side-nav__submenu
176
+ + .#{$prefix}--side-nav__menu
177
+ > .#{$prefix}--side-nav__item
178
+ .#{$prefix}--side-nav__menu
179
+ > .#{$prefix}--side-nav__item
180
+ .#{$prefix}--side-nav__menu
181
+ > .#{$prefix}--side-nav__item
182
+ .#{$prefix}--side-nav__submenu {
183
+ padding-inline-start: $spacing-12;
184
+ }
185
+
186
+ // with icon parent at level 2
187
+ .#{$prefix}--side-nav__item--icon
188
+ > .#{$prefix}--side-nav__submenu
189
+ + .#{$prefix}--side-nav__menu
190
+ > .#{$prefix}--side-nav__item--icon
191
+ .#{$prefix}--side-nav__menu
192
+ > .#{$prefix}--side-nav__item
193
+ .#{$prefix}--side-nav__menu
194
+ > .#{$prefix}--side-nav__item
195
+ .#{$prefix}--side-nav__submenu {
196
+ padding-inline-start: convert.to-rem(112px);
197
+ }
198
+
92
199
  // Nested SideNavMenuItem
93
- // Level 2
200
+ // Level 2 / Doublewide Level 3
94
201
  // without icon
95
202
  .#{$prefix}--side-nav__item.#{$prefix}--side-nav__item--icon
96
203
  a.#{$prefix}--side-nav__link {
@@ -116,14 +223,23 @@ div:has(.#{$prefix}--header)
116
223
  padding-inline-start: $spacing-09;
117
224
  }
118
225
 
119
- // with icon inside primary menu (double wide)
226
+ // with icon inside primary menu (double wide), Level 2
120
227
  .#{$prefix}--side-nav__item.#{$prefix}--side-nav__item--icon
121
- .cds--side-nav__menu-secondary-wrapper
228
+ .#{$prefix}--side-nav__menu-secondary-wrapper
122
229
  a.#{$prefix}--side-nav__link:has(.#{$prefix}--side-nav__icon) {
123
230
  padding-inline-start: $spacing-05;
124
231
  }
125
232
 
126
- // Level 3
233
+ @include breakpoint-down(md) {
234
+ // with icon inside primary menu (double wide)
235
+ .#{$prefix}--side-nav__item.#{$prefix}--side-nav__item--icon
236
+ .#{$prefix}--side-nav__menu-secondary-wrapper
237
+ a.#{$prefix}--side-nav__link:has(.#{$prefix}--side-nav__icon) {
238
+ padding-inline-start: convert.to-rem(14px);
239
+ }
240
+ }
241
+
242
+ // Level 3 / Doublewide level 4
127
243
  // without icon parent
128
244
  .#{$prefix}--side-nav__menu
129
245
  .#{$prefix}--side-nav__menu
@@ -138,6 +254,46 @@ div:has(.#{$prefix}--header)
138
254
  padding-inline-start: $spacing-12;
139
255
  }
140
256
 
257
+ // Level 4 / Doublewide level 5
258
+ // without icon parent
259
+ .#{$prefix}--side-nav__menu
260
+ .#{$prefix}--side-nav__menu
261
+ .#{$prefix}--side-nav__menu
262
+ a.#{$prefix}--side-nav__link {
263
+ padding-inline-start: $spacing-12;
264
+ }
265
+
266
+ // with icon parent at level 2
267
+ .#{$prefix}--side-nav__item--icon
268
+ .#{$prefix}--side-nav__menu
269
+ .#{$prefix}--side-nav__item--icon
270
+ .#{$prefix}--side-nav__menu
271
+ .#{$prefix}--side-nav__menu
272
+ a.#{$prefix}--side-nav__link {
273
+ padding-inline-start: convert.to-rem(112px);
274
+ }
275
+
276
+ // Level 5 / Doesn't exist in doublewide
277
+ .#{$prefix}--side-nav__item--icon
278
+ .#{$prefix}--side-nav__menu
279
+ .#{$prefix}--side-nav__menu
280
+ .#{$prefix}--side-nav__menu
281
+ .#{$prefix}--side-nav__menu
282
+ a.#{$prefix}--side-nav__link {
283
+ padding-inline-start: convert.to-rem(112px);
284
+ }
285
+
286
+ // with icon parent at level 2
287
+ .#{$prefix}--side-nav__item--icon
288
+ .#{$prefix}--side-nav__menu
289
+ .#{$prefix}--side-nav__item--icon
290
+ .#{$prefix}--side-nav__menu
291
+ .#{$prefix}--side-nav__menu
292
+ .#{$prefix}--side-nav__menu
293
+ a.#{$prefix}--side-nav__link {
294
+ padding-inline-start: convert.to-rem(128px);
295
+ }
296
+
141
297
  .#{$prefix}--side-nav__menu-secondary-wrapper {
142
298
  position: absolute;
143
299
  background-color: $layer-01;
@@ -426,7 +582,7 @@ div:has(.#{$prefix}--header)
426
582
  .#{$prefix}--side-nav__slot {
427
583
  display: flex;
428
584
  align-items: center;
429
- margin: 0 $spacing-05;
585
+ margin: 0 $spacing-05 $spacing-05;
430
586
  block-size: 2rem;
431
587
  }
432
588