@redis-ui/components 47.1.0 → 47.3.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.
@@ -9,12 +9,13 @@ var ButtonGroupWrapper = styled_components.default.div.withConfig({
9
9
  })([
10
10
  "display:flex;align-items:stretch;border-radius:",
11
11
  ";border:",
12
+ ";background-color:",
12
13
  ";overflow:hidden;width:fit-content;font-size:",
13
14
  ";font-style:",
14
15
  ";font-weight:",
15
16
  ";padding:",
16
17
  ";gap:",
17
18
  ";"
18
- ], () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.borderRadius, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.border, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.fontSize, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.fontStyle, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.fontWeight, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.padding, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.gap);
19
+ ], () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.borderRadius, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.border, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.bgColor, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.fontSize, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.fontStyle, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.fontWeight, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.padding, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.gap);
19
20
  //#endregion
20
21
  exports.ButtonGroupWrapper = ButtonGroupWrapper;
@@ -7,12 +7,13 @@ var ButtonGroupWrapper = _styled.div.withConfig({
7
7
  })([
8
8
  "display:flex;align-items:stretch;border-radius:",
9
9
  ";border:",
10
+ ";background-color:",
10
11
  ";overflow:hidden;width:fit-content;font-size:",
11
12
  ";font-style:",
12
13
  ";font-weight:",
13
14
  ";padding:",
14
15
  ";gap:",
15
16
  ";"
16
- ], () => useTheme().components.buttonGroup.borderRadius, () => useTheme().components.buttonGroup.border, () => useTheme().components.buttonGroup.fontSize, () => useTheme().components.buttonGroup.fontStyle, () => useTheme().components.buttonGroup.fontWeight, () => useTheme().components.buttonGroup.padding, () => useTheme().components.buttonGroup.gap);
17
+ ], () => useTheme().components.buttonGroup.borderRadius, () => useTheme().components.buttonGroup.border, () => useTheme().components.buttonGroup.bgColor, () => useTheme().components.buttonGroup.fontSize, () => useTheme().components.buttonGroup.fontStyle, () => useTheme().components.buttonGroup.fontWeight, () => useTheme().components.buttonGroup.padding, () => useTheme().components.buttonGroup.gap);
17
18
  //#endregion
18
19
  export { ButtonGroupWrapper };
@@ -9,14 +9,18 @@ var Button = styled_components.default.button.withConfig({
9
9
  displayName: "Buttonstyle__Button",
10
10
  componentId: "RedisUI__sc-m6kucg-0"
11
11
  })([
12
- "cursor:pointer;border:none;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;line-height:1.25;max-width:100%;min-width:",
12
+ "cursor:pointer;border-style:solid;border-width:",
13
+ ";font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;line-height:1.25;max-width:100%;min-width:",
13
14
  ";text-align:center;text-decoration:none;transition:color 0.13s ease-in-out,background-color 0.13s ease-in-out,border-color 0.13s ease-in-out,box-shadow 0.13s ease-in-out;@media (prefers-reduced-motion:reduce){transition:none;}user-select:none;vertical-align:middle;white-space:nowrap;display:flex;border-radius:",
14
15
  ";padding:",
15
16
  ";justify-content:center;align-items:center;gap:",
16
- ";&:not(:last-child){border-inline-end:",
17
- ";}&:disabled{cursor:not-allowed;}",
17
+ ";&:disabled{cursor:not-allowed;}",
18
18
  " ",
19
19
  ";"
20
- ], () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.button.minWidth, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.button.borderRadius, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.button.padding, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.button.gap, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.button.border, ({ isSelected }) => require_Button_style_utils.getButtonStatesStyle((0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.button.toggleStates[isSelected ? "on" : "off"], [require_css_utils.tokenMaps.bgColor, require_css_utils.tokenMaps.textColor]), (0, _redislabsdev_redis_ui_styles.getFocusStyle)("-2px"));
20
+ ], () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.button.borderWidth ?? "0", () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.button.minWidth, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.button.borderRadius, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.button.padding, () => (0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.button.gap, ({ isSelected }) => require_Button_style_utils.getButtonStatesStyle((0, _redislabsdev_redis_ui_styles.useTheme)().components.buttonGroup.button.toggleStates[isSelected ? "on" : "off"], [
21
+ require_css_utils.tokenMaps.bgColor,
22
+ require_css_utils.tokenMaps.textColor,
23
+ require_css_utils.tokenMaps.borderColor
24
+ ]), (0, _redislabsdev_redis_ui_styles.getFocusStyle)("-2px"));
21
25
  //#endregion
22
26
  exports.Button = Button;
@@ -7,14 +7,18 @@ var Button = _styled.button.withConfig({
7
7
  displayName: "Buttonstyle__Button",
8
8
  componentId: "RedisUI__sc-m6kucg-0"
9
9
  })([
10
- "cursor:pointer;border:none;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;line-height:1.25;max-width:100%;min-width:",
10
+ "cursor:pointer;border-style:solid;border-width:",
11
+ ";font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;line-height:1.25;max-width:100%;min-width:",
11
12
  ";text-align:center;text-decoration:none;transition:color 0.13s ease-in-out,background-color 0.13s ease-in-out,border-color 0.13s ease-in-out,box-shadow 0.13s ease-in-out;@media (prefers-reduced-motion:reduce){transition:none;}user-select:none;vertical-align:middle;white-space:nowrap;display:flex;border-radius:",
12
13
  ";padding:",
13
14
  ";justify-content:center;align-items:center;gap:",
14
- ";&:not(:last-child){border-inline-end:",
15
- ";}&:disabled{cursor:not-allowed;}",
15
+ ";&:disabled{cursor:not-allowed;}",
16
16
  " ",
17
17
  ";"
18
- ], () => useTheme().components.buttonGroup.button.minWidth, () => useTheme().components.buttonGroup.button.borderRadius, () => useTheme().components.buttonGroup.button.padding, () => useTheme().components.buttonGroup.button.gap, () => useTheme().components.buttonGroup.button.border, ({ isSelected }) => getButtonStatesStyle(useTheme().components.buttonGroup.button.toggleStates[isSelected ? "on" : "off"], [tokenMaps.bgColor, tokenMaps.textColor]), getFocusStyle("-2px"));
18
+ ], () => useTheme().components.buttonGroup.button.borderWidth ?? "0", () => useTheme().components.buttonGroup.button.minWidth, () => useTheme().components.buttonGroup.button.borderRadius, () => useTheme().components.buttonGroup.button.padding, () => useTheme().components.buttonGroup.button.gap, ({ isSelected }) => getButtonStatesStyle(useTheme().components.buttonGroup.button.toggleStates[isSelected ? "on" : "off"], [
19
+ tokenMaps.bgColor,
20
+ tokenMaps.textColor,
21
+ tokenMaps.borderColor
22
+ ]), getFocusStyle("-2px"));
19
23
  //#endregion
20
24
  export { Button };
@@ -9,8 +9,6 @@ var Title = ({ children, ...rest }) => {
9
9
  ...rest,
10
10
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Title_style.Label, {
11
11
  size: "M",
12
- variant: "semiBold",
13
- color: "secondary",
14
12
  component: "span",
15
13
  $isExpanded: isExpanded,
16
14
  $transitionEnd: transitionEnd,
@@ -8,8 +8,6 @@ var Title = ({ children, ...rest }) => {
8
8
  ...rest,
9
9
  children: /* @__PURE__ */ jsx(Label, {
10
10
  size: "M",
11
- variant: "semiBold",
12
- color: "secondary",
13
11
  component: "span",
14
12
  $isExpanded: isExpanded,
15
13
  $transitionEnd: transitionEnd,
@@ -13,7 +13,13 @@ var Container = styled_components.default.div.withConfig({
13
13
  var Label = (0, styled_components.default)(require_Typography.default.Body).withConfig({
14
14
  displayName: "Titlestyle__Label",
15
15
  componentId: "RedisUI__sc-1qd2bt1-1"
16
- })(["display:block;white-space:nowrap;transition:opacity 0.4s;@media (prefers-reduced-motion:reduce){transition:none;}opacity:", ";"], ({ $isExpanded, $transitionEnd }) => $isExpanded && $transitionEnd ? "1" : "0");
16
+ })([
17
+ "display:block;white-space:nowrap;transition:opacity 0.4s;@media (prefers-reduced-motion:reduce){transition:none;}opacity:",
18
+ ";",
19
+ ""
20
+ ], ({ $isExpanded, $transitionEnd }) => $isExpanded && $transitionEnd ? "1" : "0", () => require_SideBar_utils.useStateStyle((theme) => styled_components.css`
21
+ color: ${theme.groupTitle.textColor};
22
+ `));
17
23
  //#endregion
18
24
  exports.Container = Container;
19
25
  exports.Label = Label;
@@ -11,6 +11,12 @@ var Container = _styled.div.withConfig({
11
11
  var Label = _styled(Typography.Body).withConfig({
12
12
  displayName: "Titlestyle__Label",
13
13
  componentId: "RedisUI__sc-1qd2bt1-1"
14
- })(["display:block;white-space:nowrap;transition:opacity 0.4s;@media (prefers-reduced-motion:reduce){transition:none;}opacity:", ";"], ({ $isExpanded, $transitionEnd }) => $isExpanded && $transitionEnd ? "1" : "0");
14
+ })([
15
+ "display:block;white-space:nowrap;transition:opacity 0.4s;@media (prefers-reduced-motion:reduce){transition:none;}opacity:",
16
+ ";",
17
+ ""
18
+ ], ({ $isExpanded, $transitionEnd }) => $isExpanded && $transitionEnd ? "1" : "0", () => useStateStyle((theme) => css`
19
+ color: ${theme.groupTitle.textColor};
20
+ `));
15
21
  //#endregion
16
22
  export { Container, Label };
@@ -53,6 +53,17 @@ var SideBarItem = styled_components.default.li.withConfig({
53
53
  fallbackTokens: states.normal
54
54
  })}
55
55
  }
56
+
57
+ &[data-state='active']::before {
58
+ content: '';
59
+ position: absolute;
60
+ left: ${theme.activeIndicator.left};
61
+ top: ${theme.activeIndicator.top};
62
+ bottom: ${theme.activeIndicator.bottom};
63
+ width: ${theme.activeIndicator.width};
64
+ background-color: ${theme.activeIndicator.bgColor};
65
+ border-radius: ${theme.activeIndicator.borderRadius};
66
+ }
56
67
  `;
57
68
  });
58
69
  });
@@ -51,6 +51,17 @@ var SideBarItem = _styled.li.withConfig({
51
51
  fallbackTokens: states.normal
52
52
  })}
53
53
  }
54
+
55
+ &[data-state='active']::before {
56
+ content: '';
57
+ position: absolute;
58
+ left: ${theme.activeIndicator.left};
59
+ top: ${theme.activeIndicator.top};
60
+ bottom: ${theme.activeIndicator.bottom};
61
+ width: ${theme.activeIndicator.width};
62
+ background-color: ${theme.activeIndicator.bgColor};
63
+ border-radius: ${theme.activeIndicator.borderRadius};
64
+ }
54
65
  `;
55
66
  });
56
67
  });
@@ -6,6 +6,6 @@ styled_components = require_runtime.__toESM(styled_components, 1);
6
6
  var ScrollContainer = (0, styled_components.default)(require_FlexGroup.FlexGroup).withConfig({
7
7
  displayName: "ScrollContainerstyle__ScrollContainer",
8
8
  componentId: "RedisUI__sc-15iez38-0"
9
- })(["overflow-y:auto;overflow-x:hidden;"]);
9
+ })(["overflow-y:auto;overflow-x:hidden;scrollbar-gutter:stable;"]);
10
10
  //#endregion
11
11
  exports.ScrollContainer = ScrollContainer;
@@ -4,6 +4,6 @@ import _styled from "styled-components";
4
4
  var ScrollContainer = _styled(FlexGroup).withConfig({
5
5
  displayName: "ScrollContainerstyle__ScrollContainer",
6
6
  componentId: "RedisUI__sc-15iez38-0"
7
- })(["overflow-y:auto;overflow-x:hidden;"]);
7
+ })(["overflow-y:auto;overflow-x:hidden;scrollbar-gutter:stable;"]);
8
8
  //#endregion
9
9
  export { ScrollContainer };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@redis-ui/components",
3
3
  "license": "UNLICENSED",
4
- "version": "47.1.0",
4
+ "version": "47.3.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "repository": "git@github.com:redislabsdev/redis-ui.git",
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "peerDependencies": {
32
32
  "@redis-ui/icons": "^8.0.0",
33
- "@redis-ui/styles": "^16.2.0",
33
+ "@redis-ui/styles": "^16.4.0",
34
34
  "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
35
35
  "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0",
36
36
  "styled-components": "^5.0.0"
@@ -53,7 +53,8 @@ import { InfoIcon, ShardIcon, StarsIcon } from '@redis-ui/icons';
53
53
  const items = [
54
54
  { value: 'item1', label: 'Button 1', icon: ShardIcon, disabled: true },
55
55
  { value: 'item2', label: 'Button 2', icon: StarsIcon },
56
- { value: 'item3', label: 'Button 3' }
56
+ { value: 'item3', label: 'Button 3' },
57
+ { value: 'item4', label: 'Button 4' }
57
58
  ];
58
59
 
59
60
  const [selected, setSelected] = useState<string>(items[0].value);
@@ -13,7 +13,7 @@ import { SideBar } from '@redis-ui/components';
13
13
  | Prop | Type | Default | Description |
14
14
  |------|------|---------|-------------|
15
15
  | isExpanded | `boolean` | *required* | Controls whether the sidebar is expanded or collapsed |
16
- | expandedWidth | `string` | theme value | Overrides the sidebar width when expanded (falls back to the theme's `sideBar.expanded.width`, e.g. `20rem` in the light theme) |
16
+ | expandedWidth | `string` | design-system default | Overrides the sidebar width when expanded |
17
17
 
18
18
  The component also accepts all `FlexGroupProps` except `direction`, which is fixed to a vertical sidebar layout.
19
19
 
@@ -29,10 +29,10 @@ The component also accepts all `FlexGroupProps` except `direction`, which is fix
29
29
  - `SideBar.Item` - Navigation item with tooltip support when collapsed.
30
30
  - `SideBar.Item.Icon` - Icon slot for a sidebar item.
31
31
  - `SideBar.Item.Text` - Text slot for a sidebar item.
32
- - `SideBar.Item.Button` - Compact action button that stays mounted in the DOM and is visually hidden (fades out and becomes non-interactive) when the sidebar is collapsed.
33
- - `SideBar.Item.Badge` - Badge slot rendered to the right of `Item.Text` (e.g. `NEW`, `BETA`). Stays mounted in the DOM and fades out when the sidebar is collapsed.
32
+ - `SideBar.Item.Button` - Compact action button rendered inside a sidebar item.
33
+ - `SideBar.Item.Badge` - Badge slot rendered to the right of `Item.Text` (e.g. `NEW`, `BETA`).
34
34
  - `SideBar.Group` - Wrapper around a section's `Group.Title` and items. Use one `SideBar.Group` per logical section.
35
- - `SideBar.Group.Title` - Section label rendered above a group of items. Visible when the sidebar is expanded; the row stays mounted (text fades out) when collapsed so items don't jump around during the transition.
35
+ - `SideBar.Group.Title` - Section label rendered above a group of items.
36
36
  - `SideBar.Footer` - Footer wrapper for metadata, links, and text.
37
37
  - `SideBar.Footer.MetaData` - Footer metadata container.
38
38
  - `SideBar.Footer.Link` - Footer link rendered as body text.
@@ -56,11 +56,11 @@ The logo also accepts standard `HTMLAttributes<HTMLSpanElement>` except `childre
56
56
 
57
57
  ### SideBar.ItemsContainer Props
58
58
 
59
- This component inherits `FlexGroupProps` except `direction`. It renders a column list container with `gap="0"`, `flex="none"`, and `selfAlign="stretch"`.
59
+ This component inherits `FlexGroupProps` except `direction`. Use it to render a vertical list of sidebar items.
60
60
 
61
61
  ### SideBar.ScrollContainer Props
62
62
 
63
- This component inherits `FlexGroupProps` except `direction`. It renders a flexible column container with `gap="0"`, `flex="1"`, and `selfAlign="stretch"`.
63
+ This component inherits `FlexGroupProps` except `direction`. Use it for sidebar content that should scroll when vertical space is constrained.
64
64
 
65
65
  ### SideBar.Divider Props
66
66
 
@@ -77,7 +77,7 @@ The divider also accepts standard `HTMLAttributes<HTMLDivElement>` except `child
77
77
  | Prop | Type | Default | Description |
78
78
  |------|------|---------|-------------|
79
79
  | tooltipProps | `SideBarTooltipProps` | *required* | Tooltip configuration used when the sidebar is collapsed |
80
- | isActive | `boolean` | `false` | Marks the item as the active route/item |
80
+ | isActive | `boolean` | `false` | Marks the item as the active route/item and applies the design-system active visual treatment |
81
81
 
82
82
  The item also accepts standard `HTMLAttributes<HTMLLIElement>`.
83
83
  The tooltip text is used as the collapsed label and tooltip placement defaults to `right`.
@@ -90,15 +90,15 @@ The tooltip text is used as the collapsed label and tooltip placement defaults t
90
90
 
91
91
  ### SideBar.Item.Text Props
92
92
 
93
- This slot inherits `TypographyBodyProps`. It renders a `Typography.Body` element with `component="span"`, `ellipsis`, and `tooltipOnEllipsis` enabled.
93
+ This slot inherits `TypographyBodyProps`. Use it for the sidebar item text label.
94
94
 
95
95
  ### SideBar.Item.Button Props
96
96
 
97
- This slot inherits all `ActionIconButtonProps` and defaults `size` to `M`. It stays mounted in the DOM in both states. When the sidebar is collapsed (or while the expand/collapse transition is running) it fades to `opacity: 0`, gets `pointer-events: none`, and is forced to `tabIndex={-1}` and `aria-hidden={true}` so it is removed from the normal tab order and hidden from assistive tech while hidden. Consumer-provided `tabIndex` and `aria-hidden` are intentionally overridden in this state.
97
+ This slot inherits all `ActionIconButtonProps` and defaults `size` to `M`. It is available when the sidebar is expanded and hidden while collapsed.
98
98
 
99
99
  ### SideBar.Item.Badge Props
100
100
 
101
- This slot inherits all `BadgeProps` from the base `Badge` component. The badge stays in the DOM in both states; when the sidebar is collapsed (or while the expand/collapse transition is running) it fades to `opacity: 0`, so consumers don't need to gate it themselves.
101
+ This slot inherits all `BadgeProps` from the base `Badge` component. It is shown next to item text when the sidebar is expanded and hidden while collapsed.
102
102
 
103
103
  ### SideBar.Group Props
104
104
 
@@ -110,8 +110,7 @@ This wrapper accepts standard `HTMLAttributes<HTMLDivElement>`. Place a `SideBar
110
110
  |------|------|---------|-------------|
111
111
  | children | `React.ReactNode` | *required* | Title text shown above the group of items |
112
112
 
113
- The group title also accepts standard `HTMLAttributes<HTMLDivElement>` except `children`.
114
- The label is rendered as a `Typography.Body` (size `M`, `semiBold`, `secondary` color, `span` element). When the sidebar is collapsed, the row stays in the DOM with its theme-driven padding so the items below don't jump, and the label fades to `opacity: 0` once the expand/collapse transition completes (mirroring the `SideBar.Item.Text` pattern).
113
+ The group title also accepts standard `HTMLAttributes<HTMLDivElement>` except `children`. It is shown when the sidebar is expanded and hidden while collapsed.
115
114
 
116
115
  ### SideBar.Button Props
117
116
 
@@ -150,7 +149,7 @@ The link also accepts standard `AnchorHTMLAttributes<HTMLAnchorElement>` except
150
149
  |------|------|---------|-------------|
151
150
  | children | `React.ReactNode` | *required* | Footer text content |
152
151
 
153
- This slot inherits `TypographyBodyProps` except `children` and renders a small body-text footer line.
152
+ This slot inherits `TypographyBodyProps` except `children` and renders footer text.
154
153
 
155
154
  ## Examples
156
155
 
@@ -272,9 +271,7 @@ const [activeLink, setActiveLink] = useState(items.top[0].content);
272
271
 
273
272
  ### Groups
274
273
 
275
- > Sidebar items split into groups, each with a title label. When the sidebar is expanded, the group title is shown above its items; when collapsed, the title row stays mounted but the label fades out so the items below don't jump during the expand/collapse transition.
276
- >
277
- > A group with no title omits the `SideBar.Group.Title` element entirely, as shown by the first group below. Items inside a group may also render an optional `SideBar.Item.Badge` (e.g. `NEW`, `BETA`) to the right of the text — it stays mounted and fades out when the sidebar is collapsed.
274
+ > Sidebar items can be split into groups, each with an optional title label. Items inside a group may also render an optional `SideBar.Item.Badge` (e.g. `NEW`, `BETA`) to the right of the text.
278
275
 
279
276
  ```tsx
280
277
  import { SideBar } from '@redis-ui/components';
@@ -541,14 +538,15 @@ const [expanded, setExpanded] = useState(true);
541
538
  ## Notes
542
539
 
543
540
  - `SideBar` is a collapsible navigation shell with a fixed header/footer layout and grouped content in the middle.
544
- - The expanded and collapsed widths default to the theme (`sideBar.expanded.width` / `sideBar.collapsed.width`). Hosts can override the expanded width by passing the `expandedWidth` prop; the collapsed state always uses the theme value.
541
+ - Hosts can override the expanded width by passing the `expandedWidth` prop.
545
542
  - `SideBar.Header` needs an `onToggle` handler and should usually render `SideBar.SideBarLogo` inside it.
546
543
  - `SideBar.Footer` is typically used with `Footer.MetaData`; that metadata area is hidden when the sidebar is collapsed.
547
544
  - `SideBar.ScrollContainer` is intended for the middle content when vertical space is constrained, and the docs recommend using only one per sidebar.
548
545
  - `SideBar.Split` can be used either directly under `SideBar` or under `SideBar.ScrollContainer`, but the two patterns should not be mixed.
549
546
  - `SideBar.Divider` supports `noMargin`, `fullWidth`, and `fullWidthWhenExpanded` for layout tuning.
550
547
  - `SideBar.Item` wraps collapsed items in a tooltip and exposes `Item.Icon`, `Item.Text`, `Item.Button`, and `Item.Badge` for composition.
551
- - `SideBar.Item.Button` stays mounted in the DOM in both states and defaults its size to `M`; when collapsed (or mid-transition) it is visually hidden via opacity, gets `pointer-events: none`, and is forced to `tabIndex={-1}` + `aria-hidden={true}` so it is removed from the tab order and hidden from assistive tech (consumer `tabIndex`/`aria-hidden` are intentionally overridden in the hidden state).
548
+ - `SideBar.Item` supports the `isActive` prop for marking the current route or selected item.
549
+ - `SideBar.Item.Button` defaults its size to `M`.
552
550
  - `SideBar.Button` is the root collapsible action button, and it defaults to `PlusIcon` when no collapsed icon is provided.
553
551
  - `SideBar.Group` wraps a section's `Group.Title` (optional) and items so the title and the items stay together as one logical unit.
554
- - `SideBar.Group.Title` labels a group of items with a semibold, secondary-color body label. Its row keeps its theme-driven padding in both states so the items below never jump; the label itself fades out via opacity when the sidebar is collapsed (matching `SideBar.Item.Text`). Pair it with `SideBar.Item.Badge` next to `Item.Text` if you need to mark individual items as `NEW`, `BETA`, etc.
552
+ - `SideBar.Group.Title` labels a group of items. Pair `SideBar.Item.Badge` with `Item.Text` if you need to mark individual items as `NEW`, `BETA`, etc.