@patternfly/react-core 6.7.0-prerelease.2 → 6.7.0-prerelease.4

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.
Files changed (220) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/components/package.json +1 -1
  3. package/deprecated/package.json +1 -1
  4. package/dist/dynamic/components/AboutModal/package.json +1 -1
  5. package/dist/dynamic/components/Accordion/package.json +1 -1
  6. package/dist/dynamic/components/ActionList/package.json +1 -1
  7. package/dist/dynamic/components/Alert/package.json +1 -1
  8. package/dist/dynamic/components/Avatar/package.json +1 -1
  9. package/dist/dynamic/components/BackToTop/package.json +1 -1
  10. package/dist/dynamic/components/Backdrop/package.json +1 -1
  11. package/dist/dynamic/components/BackgroundImage/package.json +1 -1
  12. package/dist/dynamic/components/Badge/package.json +1 -1
  13. package/dist/dynamic/components/Banner/package.json +1 -1
  14. package/dist/dynamic/components/Brand/package.json +1 -1
  15. package/dist/dynamic/components/Breadcrumb/package.json +1 -1
  16. package/dist/dynamic/components/Button/package.json +1 -1
  17. package/dist/dynamic/components/CalendarMonth/package.json +1 -1
  18. package/dist/dynamic/components/Card/package.json +1 -1
  19. package/dist/dynamic/components/Checkbox/package.json +1 -1
  20. package/dist/dynamic/components/ClipboardCopy/package.json +1 -1
  21. package/dist/dynamic/components/CodeBlock/package.json +1 -1
  22. package/dist/dynamic/components/Compass/package.json +1 -1
  23. package/dist/dynamic/components/Content/package.json +1 -1
  24. package/dist/dynamic/components/DataList/package.json +1 -1
  25. package/dist/dynamic/components/DatePicker/package.json +1 -1
  26. package/dist/dynamic/components/DescriptionList/package.json +1 -1
  27. package/dist/dynamic/components/Divider/package.json +1 -1
  28. package/dist/dynamic/components/Drawer/package.json +1 -1
  29. package/dist/dynamic/components/Dropdown/package.json +1 -1
  30. package/dist/dynamic/components/DualListSelector/package.json +1 -1
  31. package/dist/dynamic/components/EmptyState/package.json +1 -1
  32. package/dist/dynamic/components/ExpandableSection/package.json +1 -1
  33. package/dist/dynamic/components/FileUpload/package.json +1 -1
  34. package/dist/dynamic/components/Form/package.json +1 -1
  35. package/dist/dynamic/components/FormSelect/package.json +1 -1
  36. package/dist/dynamic/components/HelperText/package.json +1 -1
  37. package/dist/dynamic/components/Hero/package.json +1 -1
  38. package/dist/dynamic/components/Hint/package.json +1 -1
  39. package/dist/dynamic/components/Icon/package.json +1 -1
  40. package/dist/dynamic/components/InputGroup/package.json +1 -1
  41. package/dist/dynamic/components/JumpLinks/package.json +1 -1
  42. package/dist/dynamic/components/Label/package.json +1 -1
  43. package/dist/dynamic/components/List/package.json +1 -1
  44. package/dist/dynamic/components/LoginPage/package.json +1 -1
  45. package/dist/dynamic/components/Masthead/package.json +1 -1
  46. package/dist/dynamic/components/Menu/package.json +1 -1
  47. package/dist/dynamic/components/MenuToggle/package.json +1 -1
  48. package/dist/dynamic/components/Modal/package.json +1 -1
  49. package/dist/dynamic/components/MultipleFileUpload/package.json +1 -1
  50. package/dist/dynamic/components/Nav/package.json +1 -1
  51. package/dist/dynamic/components/NotificationBadge/package.json +1 -1
  52. package/dist/dynamic/components/NotificationDrawer/package.json +1 -1
  53. package/dist/dynamic/components/NumberInput/package.json +1 -1
  54. package/dist/dynamic/components/OverflowMenu/package.json +1 -1
  55. package/dist/dynamic/components/Page/package.json +1 -1
  56. package/dist/dynamic/components/Pagination/package.json +1 -1
  57. package/dist/dynamic/components/Panel/package.json +1 -1
  58. package/dist/dynamic/components/Popover/package.json +1 -1
  59. package/dist/dynamic/components/Progress/package.json +1 -1
  60. package/dist/dynamic/components/ProgressStepper/package.json +1 -1
  61. package/dist/dynamic/components/Radio/package.json +1 -1
  62. package/dist/dynamic/components/SearchInput/package.json +1 -1
  63. package/dist/dynamic/components/Select/package.json +1 -1
  64. package/dist/dynamic/components/Sidebar/package.json +1 -1
  65. package/dist/dynamic/components/SimpleList/package.json +1 -1
  66. package/dist/dynamic/components/Skeleton/package.json +1 -1
  67. package/dist/dynamic/components/SkipToContent/package.json +1 -1
  68. package/dist/dynamic/components/Slider/package.json +1 -1
  69. package/dist/dynamic/components/Spinner/package.json +1 -1
  70. package/dist/dynamic/components/Switch/package.json +1 -1
  71. package/dist/dynamic/components/Tabs/package.json +1 -1
  72. package/dist/dynamic/components/TextArea/package.json +1 -1
  73. package/dist/dynamic/components/TextInput/package.json +1 -1
  74. package/dist/dynamic/components/TextInputGroup/package.json +1 -1
  75. package/dist/dynamic/components/TimePicker/package.json +1 -1
  76. package/dist/dynamic/components/Timestamp/package.json +1 -1
  77. package/dist/dynamic/components/Title/package.json +1 -1
  78. package/dist/dynamic/components/ToggleGroup/package.json +1 -1
  79. package/dist/dynamic/components/Toolbar/package.json +1 -1
  80. package/dist/dynamic/components/Tooltip/package.json +1 -1
  81. package/dist/dynamic/components/TreeView/package.json +1 -1
  82. package/dist/dynamic/components/Truncate/package.json +1 -1
  83. package/dist/dynamic/components/Wizard/hooks/package.json +1 -1
  84. package/dist/dynamic/components/Wizard/package.json +1 -1
  85. package/dist/dynamic/deprecated/components/Chip/package.json +1 -1
  86. package/dist/dynamic/deprecated/components/DragDrop/package.json +1 -1
  87. package/dist/dynamic/deprecated/components/DualListSelector/package.json +1 -1
  88. package/dist/dynamic/deprecated/components/Modal/package.json +1 -1
  89. package/dist/dynamic/deprecated/components/Tile/package.json +1 -1
  90. package/dist/dynamic/deprecated/components/Wizard/package.json +1 -1
  91. package/dist/dynamic/deprecated/components/package.json +1 -1
  92. package/dist/dynamic/helpers/AnimationsProvider/AnimationsProvider/package.json +1 -1
  93. package/dist/dynamic/helpers/AnimationsProvider/package.json +1 -1
  94. package/dist/dynamic/helpers/FocusTrap/FocusTrap/package.json +1 -1
  95. package/dist/dynamic/helpers/GenerateId/GenerateId/package.json +1 -1
  96. package/dist/dynamic/helpers/KeyboardHandler/package.json +1 -1
  97. package/dist/dynamic/helpers/OUIA/ouia/package.json +1 -1
  98. package/dist/dynamic/helpers/Popper/Popper/package.json +1 -1
  99. package/dist/dynamic/helpers/SSRSafeIds/SSRSafeIds/package.json +1 -1
  100. package/dist/dynamic/helpers/constants/package.json +1 -1
  101. package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
  102. package/dist/dynamic/helpers/fileUtils/package.json +1 -1
  103. package/dist/dynamic/helpers/htmlConstants/package.json +1 -1
  104. package/dist/dynamic/helpers/inert/package.json +1 -1
  105. package/dist/dynamic/helpers/package.json +1 -1
  106. package/dist/dynamic/helpers/resizeObserver/package.json +1 -1
  107. package/dist/dynamic/helpers/typeUtils/package.json +1 -1
  108. package/dist/dynamic/helpers/useInterval/package.json +1 -1
  109. package/dist/dynamic/helpers/useIsomorphicLayout/package.json +1 -1
  110. package/dist/dynamic/helpers/useSSRSafeId/package.json +1 -1
  111. package/dist/dynamic/helpers/useUnmountEffect/package.json +1 -1
  112. package/dist/dynamic/helpers/util/package.json +1 -1
  113. package/dist/dynamic/layouts/Bullseye/package.json +1 -1
  114. package/dist/dynamic/layouts/Flex/package.json +1 -1
  115. package/dist/dynamic/layouts/Gallery/package.json +1 -1
  116. package/dist/dynamic/layouts/Grid/package.json +1 -1
  117. package/dist/dynamic/layouts/Level/package.json +1 -1
  118. package/dist/dynamic/layouts/Split/package.json +1 -1
  119. package/dist/dynamic/layouts/Stack/package.json +1 -1
  120. package/dist/dynamic/styles/package.json +1 -1
  121. package/dist/esm/components/Button/Button.d.ts +1 -3
  122. package/dist/esm/components/Button/Button.d.ts.map +1 -1
  123. package/dist/esm/components/Button/Button.js +2 -2
  124. package/dist/esm/components/Button/Button.js.map +1 -1
  125. package/dist/esm/components/Compass/Compass.d.ts +3 -7
  126. package/dist/esm/components/Compass/Compass.d.ts.map +1 -1
  127. package/dist/esm/components/Compass/Compass.js +2 -2
  128. package/dist/esm/components/Compass/Compass.js.map +1 -1
  129. package/dist/esm/components/MenuToggle/MenuToggle.d.ts +0 -2
  130. package/dist/esm/components/MenuToggle/MenuToggle.d.ts.map +1 -1
  131. package/dist/esm/components/MenuToggle/MenuToggle.js +2 -3
  132. package/dist/esm/components/MenuToggle/MenuToggle.js.map +1 -1
  133. package/dist/esm/components/Nav/Nav.d.ts +1 -1
  134. package/dist/esm/components/Nav/Nav.d.ts.map +1 -1
  135. package/dist/esm/components/Nav/Nav.js +2 -2
  136. package/dist/esm/components/Nav/Nav.js.map +1 -1
  137. package/dist/esm/components/Page/Page.d.ts +3 -7
  138. package/dist/esm/components/Page/Page.d.ts.map +1 -1
  139. package/dist/esm/components/Page/Page.js +3 -4
  140. package/dist/esm/components/Page/Page.js.map +1 -1
  141. package/dist/esm/components/Toolbar/Toolbar.d.ts +11 -1
  142. package/dist/esm/components/Toolbar/Toolbar.d.ts.map +1 -1
  143. package/dist/esm/components/Toolbar/Toolbar.js +60 -20
  144. package/dist/esm/components/Toolbar/Toolbar.js.map +1 -1
  145. package/dist/esm/components/Toolbar/ToolbarItem.d.ts +1 -0
  146. package/dist/esm/components/Toolbar/ToolbarItem.d.ts.map +1 -1
  147. package/dist/esm/components/Toolbar/ToolbarItem.js.map +1 -1
  148. package/dist/esm/components/Toolbar/ToolbarToggleGroup.d.ts +1 -1
  149. package/dist/esm/components/Toolbar/ToolbarToggleGroup.d.ts.map +1 -1
  150. package/dist/esm/components/Toolbar/ToolbarToggleGroup.js +9 -9
  151. package/dist/esm/components/Toolbar/ToolbarToggleGroup.js.map +1 -1
  152. package/dist/esm/components/Toolbar/ToolbarUtils.d.ts +4 -0
  153. package/dist/esm/components/Toolbar/ToolbarUtils.d.ts.map +1 -1
  154. package/dist/esm/components/Toolbar/ToolbarUtils.js.map +1 -1
  155. package/dist/js/components/Button/Button.d.ts +1 -3
  156. package/dist/js/components/Button/Button.d.ts.map +1 -1
  157. package/dist/js/components/Button/Button.js +2 -2
  158. package/dist/js/components/Button/Button.js.map +1 -1
  159. package/dist/js/components/Compass/Compass.d.ts +3 -7
  160. package/dist/js/components/Compass/Compass.d.ts.map +1 -1
  161. package/dist/js/components/Compass/Compass.js +2 -2
  162. package/dist/js/components/Compass/Compass.js.map +1 -1
  163. package/dist/js/components/MenuToggle/MenuToggle.d.ts +0 -2
  164. package/dist/js/components/MenuToggle/MenuToggle.d.ts.map +1 -1
  165. package/dist/js/components/MenuToggle/MenuToggle.js +2 -3
  166. package/dist/js/components/MenuToggle/MenuToggle.js.map +1 -1
  167. package/dist/js/components/Nav/Nav.d.ts +1 -1
  168. package/dist/js/components/Nav/Nav.d.ts.map +1 -1
  169. package/dist/js/components/Nav/Nav.js +2 -2
  170. package/dist/js/components/Nav/Nav.js.map +1 -1
  171. package/dist/js/components/Page/Page.d.ts +3 -7
  172. package/dist/js/components/Page/Page.d.ts.map +1 -1
  173. package/dist/js/components/Page/Page.js +3 -4
  174. package/dist/js/components/Page/Page.js.map +1 -1
  175. package/dist/js/components/Toolbar/Toolbar.d.ts +11 -1
  176. package/dist/js/components/Toolbar/Toolbar.d.ts.map +1 -1
  177. package/dist/js/components/Toolbar/Toolbar.js +59 -19
  178. package/dist/js/components/Toolbar/Toolbar.js.map +1 -1
  179. package/dist/js/components/Toolbar/ToolbarItem.d.ts +1 -0
  180. package/dist/js/components/Toolbar/ToolbarItem.d.ts.map +1 -1
  181. package/dist/js/components/Toolbar/ToolbarItem.js.map +1 -1
  182. package/dist/js/components/Toolbar/ToolbarToggleGroup.d.ts +1 -1
  183. package/dist/js/components/Toolbar/ToolbarToggleGroup.d.ts.map +1 -1
  184. package/dist/js/components/Toolbar/ToolbarToggleGroup.js +8 -8
  185. package/dist/js/components/Toolbar/ToolbarToggleGroup.js.map +1 -1
  186. package/dist/js/components/Toolbar/ToolbarUtils.d.ts +4 -0
  187. package/dist/js/components/Toolbar/ToolbarUtils.d.ts.map +1 -1
  188. package/dist/js/components/Toolbar/ToolbarUtils.js.map +1 -1
  189. package/dist/styles/base-no-reset.css +1 -1
  190. package/dist/styles/base.css +1 -1
  191. package/dist/umd/assets/{output-BPcxNyfB.css → output-DDYpZoPY.css} +19616 -19608
  192. package/dist/umd/react-core.min.js +3 -3
  193. package/helpers/package.json +1 -1
  194. package/layouts/package.json +1 -1
  195. package/next/package.json +1 -1
  196. package/package.json +6 -6
  197. package/src/components/Button/Button.tsx +2 -5
  198. package/src/components/Button/__tests__/Button.test.tsx +8 -19
  199. package/src/components/Button/__tests__/__snapshots__/Button.test.tsx.snap +1 -1
  200. package/src/components/Compass/Compass.tsx +5 -11
  201. package/src/components/Compass/__tests__/Compass.test.tsx +3 -23
  202. package/src/components/MenuToggle/MenuToggle.tsx +0 -5
  203. package/src/components/MenuToggle/__tests__/MenuToggle.test.tsx +8 -19
  204. package/src/components/Nav/Nav.tsx +3 -3
  205. package/src/components/Nav/__tests__/Nav.test.tsx +8 -8
  206. package/src/components/Nav/examples/Nav.md +1 -1
  207. package/src/components/Page/Page.tsx +5 -12
  208. package/src/components/Page/__tests__/Page.test.tsx +4 -30
  209. package/src/components/Toolbar/Toolbar.tsx +120 -57
  210. package/src/components/Toolbar/ToolbarItem.tsx +1 -0
  211. package/src/components/Toolbar/ToolbarToggleGroup.tsx +10 -9
  212. package/src/components/Toolbar/ToolbarUtils.tsx +4 -0
  213. package/src/components/Toolbar/__tests__/Toolbar.test.tsx +38 -0
  214. package/src/components/Toolbar/__tests__/ToolbarToggleGroup.test.tsx +22 -1
  215. package/src/components/Toolbar/examples/Toolbar.md +16 -0
  216. package/src/components/Toolbar/examples/ToolbarContainerQuery.css +8 -0
  217. package/src/components/Toolbar/examples/ToolbarContainerQuery.tsx +35 -0
  218. package/src/demos/Compass/examples/CompassDockDemo.tsx +25 -43
  219. package/src/demos/Nav.md +3 -3
  220. package/src/demos/examples/Nav/NavDockedNav.tsx +25 -43
@@ -3,7 +3,8 @@ import styles from '@patternfly/react-styles/css/components/Toolbar/toolbar';
3
3
  import { css } from '@patternfly/react-styles';
4
4
  import { ToolbarContext } from './ToolbarUtils';
5
5
  import { ToolbarLabelGroupContent } from './ToolbarLabelGroupContent';
6
- import { formatBreakpointMods, canUseDOM } from '../../helpers/util';
6
+ import { formatBreakpointMods, canUseDOM, getBreakpoint } from '../../helpers/util';
7
+ import { getResizeObserver } from '../../helpers/resizeObserver';
7
8
  import { getOUIAProps, OUIAProps } from '../../helpers';
8
9
  import { SSRSafeIds } from '../../helpers/SSRSafeIds/SSRSafeIds';
9
10
  import { PageContext } from '../Page/PageContext';
@@ -34,6 +35,8 @@ export interface ToolbarProps extends React.HTMLProps<HTMLDivElement>, OUIAProps
34
35
  children?: React.ReactNode;
35
36
  /** Id of the data toolbar */
36
37
  id?: string;
38
+ /** Flag indicating if the toolbar is a container for CSS container queries */
39
+ isContainer?: boolean;
37
40
  /** Flag indicating the toolbar height should expand to the full height of the container */
38
41
  isFullHeight?: boolean;
39
42
  /** Flag indicating the toolbar is static */
@@ -84,6 +87,9 @@ interface FilterInfo {
84
87
  class Toolbar extends Component<ToolbarProps, ToolbarState> {
85
88
  static displayName = 'Toolbar';
86
89
  labelGroupContentRef = createRef<HTMLDivElement>();
90
+ toolbarRef = createRef<HTMLDivElement>();
91
+ resizeObserver: () => void = () => {};
92
+ containerBreakpoint: ReturnType<typeof getBreakpoint>;
87
93
  staticFilterInfo = {};
88
94
  hasNoPadding = false;
89
95
  state = {
@@ -100,8 +106,8 @@ class Toolbar extends Component<ToolbarProps, ToolbarState> {
100
106
  }));
101
107
  };
102
108
 
103
- closeExpandableContent = (e: any) => {
104
- if (e.target.innerWidth !== this.state.windowWidth) {
109
+ closeExpandableContent = (e?: any) => {
110
+ if (e && e.target.innerWidth !== this.state.windowWidth) {
105
111
  this.setState(() => ({
106
112
  isManagedToggleExpanded: false,
107
113
  windowWidth: e.target.innerWidth
@@ -109,19 +115,58 @@ class Toolbar extends Component<ToolbarProps, ToolbarState> {
109
115
  }
110
116
  };
111
117
 
118
+ closeExpandableContentOnContainerResize = () => {
119
+ const containerWidth = this.toolbarRef.current?.clientWidth;
120
+ if (!containerWidth) {
121
+ return;
122
+ }
123
+
124
+ const breakpoint = getBreakpoint(containerWidth);
125
+ const isInitialMeasurement = this.containerBreakpoint === undefined;
126
+ if (breakpoint !== this.containerBreakpoint) {
127
+ this.containerBreakpoint = breakpoint;
128
+ if (!isInitialMeasurement && this.state.isManagedToggleExpanded) {
129
+ this.setState({ isManagedToggleExpanded: false });
130
+ }
131
+ }
132
+ };
133
+
134
+ setupResizeHandling = () => {
135
+ if (!this.isToggleManaged() || !canUseDOM) {
136
+ return;
137
+ }
138
+
139
+ this.containerBreakpoint = undefined;
140
+ const reference = this.props.isContainer ? this.toolbarRef.current : undefined;
141
+ const handler = this.props.isContainer ? this.closeExpandableContentOnContainerResize : this.closeExpandableContent;
142
+
143
+ this.resizeObserver = getResizeObserver(reference, handler, true);
144
+ };
145
+
146
+ cleanupResizeHandling = () => {
147
+ this.resizeObserver();
148
+ this.resizeObserver = () => {};
149
+ };
150
+
112
151
  componentDidMount() {
113
152
  if (canUseDOM) {
114
153
  this.setState({ windowWidth: window.innerWidth });
115
154
  }
116
- if (this.isToggleManaged() && canUseDOM) {
117
- window.addEventListener('resize', this.closeExpandableContent);
155
+ this.setupResizeHandling();
156
+ }
157
+
158
+ componentDidUpdate(prevProps: ToolbarProps) {
159
+ const wasToggleManaged = !(prevProps.isExpanded || !!prevProps.toggleIsExpanded);
160
+ const isToggleManaged = this.isToggleManaged();
161
+
162
+ if (prevProps.isContainer !== this.props.isContainer || wasToggleManaged !== isToggleManaged) {
163
+ this.cleanupResizeHandling();
164
+ this.setupResizeHandling();
118
165
  }
119
166
  }
120
167
 
121
168
  componentWillUnmount() {
122
- if (this.isToggleManaged() && canUseDOM) {
123
- window.removeEventListener('resize', this.closeExpandableContent);
124
- }
169
+ this.cleanupResizeHandling();
125
170
  }
126
171
 
127
172
  updateNumberFilters = (categoryName: string, numberOfFilters: number) => {
@@ -146,6 +191,7 @@ class Toolbar extends Component<ToolbarProps, ToolbarState> {
146
191
  toggleIsExpanded,
147
192
  className,
148
193
  children,
194
+ isContainer,
149
195
  isFullHeight,
150
196
  isStatic,
151
197
  isStickyBase,
@@ -169,56 +215,73 @@ class Toolbar extends Component<ToolbarProps, ToolbarState> {
169
215
 
170
216
  return (
171
217
  <PageContext.Consumer>
172
- {({ width, getBreakpoint }) => (
173
- <div
174
- className={css(
175
- styles.toolbar,
176
- hasNoPadding && styles.modifiers.noPadding,
177
- isFullHeight && styles.modifiers.fullHeight,
178
- isStatic && styles.modifiers.static,
179
- isSticky && styles.modifiers.sticky,
180
- isStickyBase && styles.modifiers.stickyBase,
181
- isStickyStuck && styles.modifiers.stickyStuck,
182
- isVertical && styles.modifiers.vertical,
183
- formatBreakpointMods(inset, styles, '', getBreakpoint(width)),
184
- colorVariant === 'primary' && styles.modifiers.primary,
185
- colorVariant === 'secondary' && styles.modifiers.secondary,
186
- colorVariant === 'no-background' && styles.modifiers.noBackground,
187
- className
188
- )}
189
- id={randomId}
190
- {...getOUIAProps(Toolbar.displayName, ouiaId !== undefined ? ouiaId : generatedOuiaId)}
191
- {...props}
192
- >
193
- <ToolbarContext.Provider
194
- value={{
195
- isExpanded,
196
- toggleIsExpanded: isToggleManaged ? this.toggleIsExpanded : toggleIsExpanded,
197
- labelGroupContentRef: this.labelGroupContentRef,
198
- updateNumberFilters: this.updateNumberFilters,
199
- numberOfFilters,
200
- clearAllFilters,
201
- clearFiltersButtonText,
202
- showClearFiltersButton,
203
- toolbarId: randomId,
204
- customLabelGroupContent
205
- }}
218
+ {(pageContext) => {
219
+ const toolbarContent = (
220
+ <div
221
+ className={css(
222
+ styles.toolbar,
223
+ hasNoPadding && styles.modifiers.noPadding,
224
+ isContainer && styles.modifiers.container,
225
+ isFullHeight && styles.modifiers.fullHeight,
226
+ isStatic && styles.modifiers.static,
227
+ isSticky && styles.modifiers.sticky,
228
+ isStickyBase && styles.modifiers.stickyBase,
229
+ isStickyStuck && styles.modifiers.stickyStuck,
230
+ isVertical && styles.modifiers.vertical,
231
+ formatBreakpointMods(
232
+ inset,
233
+ styles,
234
+ '',
235
+ !isContainer ? pageContext.getBreakpoint(pageContext.width) : undefined
236
+ ),
237
+ colorVariant === 'primary' && styles.modifiers.primary,
238
+ colorVariant === 'secondary' && styles.modifiers.secondary,
239
+ colorVariant === 'no-background' && styles.modifiers.noBackground,
240
+ className
241
+ )}
242
+ id={randomId}
243
+ ref={this.toolbarRef}
244
+ {...getOUIAProps(Toolbar.displayName, ouiaId !== undefined ? ouiaId : generatedOuiaId)}
245
+ {...props}
206
246
  >
207
- {children}
208
- <ToolbarLabelGroupContent
209
- isExpanded={isExpanded}
210
- labelGroupContentRef={this.labelGroupContentRef}
211
- clearAllFilters={clearAllFilters}
212
- showClearFiltersButton={showClearFiltersButton}
213
- clearFiltersButtonText={clearFiltersButtonText}
214
- numberOfFilters={numberOfFilters}
215
- numberOfFiltersText={numberOfFiltersText}
216
- collapseListedFiltersBreakpoint={collapseListedFiltersBreakpoint}
217
- customLabelGroupContent={customLabelGroupContent}
218
- />
219
- </ToolbarContext.Provider>
220
- </div>
221
- )}
247
+ <ToolbarContext.Provider
248
+ value={{
249
+ isExpanded,
250
+ toggleIsExpanded: isToggleManaged ? this.toggleIsExpanded : toggleIsExpanded,
251
+ labelGroupContentRef: this.labelGroupContentRef,
252
+ updateNumberFilters: this.updateNumberFilters,
253
+ numberOfFilters,
254
+ clearAllFilters,
255
+ clearFiltersButtonText,
256
+ showClearFiltersButton,
257
+ toolbarId: randomId,
258
+ customLabelGroupContent,
259
+ isContainer,
260
+ toolbarRef: this.toolbarRef
261
+ }}
262
+ >
263
+ {children}
264
+ <ToolbarLabelGroupContent
265
+ isExpanded={isExpanded}
266
+ labelGroupContentRef={this.labelGroupContentRef}
267
+ clearAllFilters={clearAllFilters}
268
+ showClearFiltersButton={showClearFiltersButton}
269
+ clearFiltersButtonText={clearFiltersButtonText}
270
+ numberOfFilters={numberOfFilters}
271
+ numberOfFiltersText={numberOfFiltersText}
272
+ collapseListedFiltersBreakpoint={collapseListedFiltersBreakpoint}
273
+ customLabelGroupContent={customLabelGroupContent}
274
+ />
275
+ </ToolbarContext.Provider>
276
+ </div>
277
+ );
278
+
279
+ return isContainer ? (
280
+ <PageContext.Provider value={{ ...pageContext, width: null }}>{toolbarContent}</PageContext.Provider>
281
+ ) : (
282
+ toolbarContent
283
+ );
284
+ }}
222
285
  </PageContext.Consumer>
223
286
  );
224
287
  };
@@ -21,6 +21,7 @@ export interface ToolbarItemProps extends React.HTMLProps<HTMLDivElement> {
21
21
  /** Visibility at various width breakpoints. */
22
22
  visibility?: {
23
23
  default?: 'hidden' | 'visible';
24
+ sm?: 'hidden' | 'visible';
24
25
  md?: 'hidden' | 'visible';
25
26
  lg?: 'hidden' | 'visible';
26
27
  xl?: 'hidden' | 'visible';
@@ -3,12 +3,11 @@ import * as ReactDOM from 'react-dom';
3
3
  import styles from '@patternfly/react-styles/css/components/Toolbar/toolbar';
4
4
  import { css } from '@patternfly/react-styles';
5
5
  import { ToolbarGroupProps } from './ToolbarGroup';
6
- import { ToolbarContext, ToolbarContentContext } from './ToolbarUtils';
6
+ import { globalBreakpoints, ToolbarContext, ToolbarContentContext } from './ToolbarUtils';
7
7
  import { Button } from '../Button';
8
- import globalBreakpointLg from '@patternfly/react-tokens/dist/esm/t_global_breakpoint_lg';
9
8
  import { formatBreakpointMods, toCamel } from '../../helpers/util';
10
- import { PageContext } from '../Page/PageContext';
11
9
  import { ToolbarExpandableContent } from './ToolbarExpandableContent';
10
+ import { PageContext } from '../Page/PageContext';
12
11
 
13
12
  export interface ToolbarToggleGroupProps extends ToolbarGroupProps {
14
13
  /** Flag indicating when toggle group is expanded for non-managed toolbar toggle groups. */
@@ -156,10 +155,9 @@ class ToolbarToggleGroup extends Component<ToolbarToggleGroupProps> {
156
155
  toggleRef = createRef<HTMLButtonElement>();
157
156
  expandableContentRef = createRef<HTMLDivElement>();
158
157
 
159
- isContentPopup = () => {
160
- const viewportSize = typeof window !== 'undefined' ? window.innerWidth : 1200;
161
- const lgBreakpointValue = parseInt(globalBreakpointLg.value);
162
- return viewportSize < lgBreakpointValue;
158
+ isContentPopup = (width?: number) => {
159
+ const size = width ?? (typeof window !== 'undefined' ? window.innerWidth : 1200);
160
+ return size < globalBreakpoints.lg;
163
161
  };
164
162
 
165
163
  render() {
@@ -191,7 +189,7 @@ class ToolbarToggleGroup extends Component<ToolbarToggleGroupProps> {
191
189
  <PageContext.Consumer>
192
190
  {({ width, getBreakpoint }) => (
193
191
  <ToolbarContext.Consumer>
194
- {({ toggleIsExpanded: managedOnToggle }) => {
192
+ {({ toggleIsExpanded: managedOnToggle, isContainer, toolbarRef }) => {
195
193
  const _onToggle = onToggle !== undefined ? onToggle : managedOnToggle;
196
194
 
197
195
  return (
@@ -238,7 +236,10 @@ class ToolbarToggleGroup extends Component<ToolbarToggleGroupProps> {
238
236
  onClick={_onToggle}
239
237
  aria-label="Show Filters"
240
238
  {...(_isExpanded && { 'aria-expanded': true })}
241
- aria-haspopup={_isExpanded && this.isContentPopup()}
239
+ aria-haspopup={
240
+ _isExpanded &&
241
+ this.isContentPopup(isContainer ? toolbarRef?.current?.clientWidth : undefined)
242
+ }
242
243
  aria-controls={_isExpanded ? expandableContentId : undefined}
243
244
  ref={this.toggleRef}
244
245
  icon={toggleIcon}
@@ -15,6 +15,10 @@ export interface ToolbarContextProps {
15
15
  showClearFiltersButton?: boolean;
16
16
  toolbarId?: string;
17
17
  customLabelGroupContent?: React.ReactNode;
18
+ /** Flag indicating if the toolbar is a container */
19
+ isContainer?: boolean;
20
+ /** Ref to the toolbar root element */
21
+ toolbarRef?: RefObject<HTMLDivElement | null>;
18
22
  }
19
23
 
20
24
  export const ToolbarContext = createContext<ToolbarContextProps>({
@@ -299,4 +299,42 @@ describe('Toolbar', () => {
299
299
  );
300
300
  expect(screen.getByTestId('toolbar-sticky-stuck')).toHaveClass(styles.modifiers.stickyStuck);
301
301
  });
302
+
303
+ it('renders the container modifier when isContainer is true', () => {
304
+ render(<Toolbar isContainer data-testid="toolbar-container" />);
305
+
306
+ expect(screen.getByTestId('toolbar-container')).toHaveClass(styles.modifiers.container);
307
+ });
308
+
309
+ it('renders all responsive visibility modifiers', () => {
310
+ render(<ToolbarItem data-testid="toolbar-item" visibility={{ md: 'hidden', xl: 'visible' }} />);
311
+
312
+ const item = screen.getByTestId('toolbar-item');
313
+
314
+ expect(item).toHaveClass('pf-m-hidden-on-md');
315
+ expect(item).toHaveClass('pf-m-visible-on-xl');
316
+ });
317
+
318
+ it('renders all responsive row wrap modifiers', () => {
319
+ render(<ToolbarContent data-testid="toolbar-content" rowWrap={{ md: 'nowrap', xl: 'wrap' }} />);
320
+
321
+ const contentSection = screen.getByTestId('toolbar-content').querySelector('div');
322
+
323
+ expect(contentSection).toHaveClass('pf-m-nowrap-on-md');
324
+ expect(contentSection).toHaveClass('pf-m-wrap-on-xl');
325
+ });
326
+
327
+ it('renders the toggle group breakpoint modifier', () => {
328
+ render(
329
+ <Toolbar>
330
+ <ToolbarContent>
331
+ <ToolbarToggleGroup data-testid="toolbar-toggle-group" breakpoint="xl" toggleIcon={<span />}>
332
+ Content
333
+ </ToolbarToggleGroup>
334
+ </ToolbarContent>
335
+ </Toolbar>
336
+ );
337
+
338
+ expect(screen.getByTestId('toolbar-toggle-group')).toHaveClass('pf-m-show-on-xl');
339
+ });
302
340
  });
@@ -1,5 +1,6 @@
1
1
  import { Fragment } from 'react';
2
- import { render } from '@testing-library/react';
2
+ import { fireEvent, render, screen } from '@testing-library/react';
3
+ import '@testing-library/jest-dom';
3
4
  import { ToolbarToggleGroup } from '../ToolbarToggleGroup';
4
5
  import { Toolbar } from '../Toolbar';
5
6
  import { ToolbarContent } from '../ToolbarContent';
@@ -25,4 +26,24 @@ describe('ToolbarToggleGroup', () => {
25
26
 
26
27
  expect(myMock).toHaveBeenCalled();
27
28
  });
29
+
30
+ it('sets aria-haspopup when expandable content is a popup in a narrow toolbar container', () => {
31
+ const clientWidthMock = jest.spyOn(HTMLElement.prototype, 'clientWidth', 'get').mockReturnValue(600);
32
+
33
+ render(
34
+ <Toolbar isContainer>
35
+ <ToolbarContent>
36
+ <ToolbarToggleGroup breakpoint="lg" toggleIcon={<span />}>
37
+ Filter controls
38
+ </ToolbarToggleGroup>
39
+ </ToolbarContent>
40
+ </Toolbar>
41
+ );
42
+
43
+ const toggle = screen.getByRole('button', { name: 'Show Filters' });
44
+ fireEvent.click(toggle);
45
+
46
+ expect(toggle).toHaveAttribute('aria-haspopup', 'true');
47
+ clientWidthMock.mockRestore();
48
+ });
28
49
  });
@@ -6,6 +6,7 @@ section: components
6
6
  ---
7
7
 
8
8
  import { Fragment, useState, useLayoutEffect, useRef } from 'react';
9
+ import './ToolbarContainerQuery.css';
9
10
 
10
11
  import EditIcon from '@patternfly/react-icons/dist/esm/icons/edit-icon';
11
12
  import RhUiCopyFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-copy-fill-icon';
@@ -78,6 +79,21 @@ To change the background color of a toolbar, use the `colorVariant` property on
78
79
 
79
80
  ```
80
81
 
82
+ ## Responsive toolbar behavior
83
+
84
+ Toolbar width-based responsive modifiers use `@container` CSS queries with the global PatternFly breakpoints. Responsive inset modifiers (via the `inset` property) are an exception and use viewport media queries. Insets are an exception and rely on viewport media queries.
85
+
86
+ By default, the PatternFly CSS establishes the `container-name` property with a value of `pf-v6-contain-toolbar` on `:root`, so the breakpoints behave like viewport breakpoints.
87
+
88
+ Alternatively, if another wrapping element creates a container in the CSS with a `container-name` property value of `pf-v6-contain-toolbar` and `container-type` value of `inline-size` or `size` , the breakpoints will apply to that container's width instead.
89
+
90
+ ### Toolbar as container
91
+ Add `isContainer` to the toolbar so width-based modifiers respond to the toolbar's width. Resize the dashed box in this example to see items and groups show and hide at the global breakpoints.
92
+
93
+ ```ts file="./ToolbarContainerQuery.tsx"
94
+
95
+ ```
96
+
81
97
  ## Examples with toggle groups and filters
82
98
 
83
99
  The following examples use toggle groups to allow for more responsive and complex toolbars with multiple items and groups of items. To visualize responsive toolbar behavior in the following examples, resize the browser to a smaller screen width.
@@ -0,0 +1,8 @@
1
+ .toolbar-container-query-resize {
2
+ width: 100%;
3
+ min-width: 300px;
4
+ padding: var(--pf-t--global--spacer--sm);
5
+ overflow: auto;
6
+ resize: horizontal;
7
+ border: var(--pf-t--global--border--width--extra-strong) dashed var(--pf-t--global--border--color--default);
8
+ }
@@ -0,0 +1,35 @@
1
+ import { Button, Toolbar, ToolbarContent, ToolbarGroup, ToolbarItem } from '@patternfly/react-core';
2
+
3
+ export const ToolbarContainerQuery: React.FunctionComponent = () => (
4
+ <div className="toolbar-container-query-resize">
5
+ <Toolbar id="toolbar-container-query-example" isContainer>
6
+ <ToolbarContent>
7
+ <ToolbarItem visibility={{ md: 'hidden' }}>
8
+ <Button variant="secondary">Hide on md</Button>
9
+ </ToolbarItem>
10
+ <ToolbarItem>
11
+ <Button variant="secondary">Item</Button>
12
+ </ToolbarItem>
13
+ <ToolbarItem visibility={{ default: 'hidden', sm: 'visible' }}>
14
+ <Button variant="secondary">Show on sm</Button>
15
+ </ToolbarItem>
16
+ <ToolbarGroup visibility={{ xl: 'hidden' }}>
17
+ <ToolbarItem>
18
+ <Button variant="secondary">Hide group on xl</Button>
19
+ </ToolbarItem>
20
+ <ToolbarItem>
21
+ <Button variant="secondary">Hide group on xl</Button>
22
+ </ToolbarItem>
23
+ </ToolbarGroup>
24
+ <ToolbarGroup visibility={{ default: 'hidden', lg: 'visible' }}>
25
+ <ToolbarItem>
26
+ <Button variant="secondary">Show group on lg</Button>
27
+ </ToolbarItem>
28
+ <ToolbarItem>
29
+ <Button variant="secondary">Show group on lg</Button>
30
+ </ToolbarItem>
31
+ </ToolbarGroup>
32
+ </ToolbarContent>
33
+ </Toolbar>
34
+ </div>
35
+ );
@@ -51,8 +51,7 @@ export const CompassDockDemo: React.FunctionComponent = () => {
51
51
  const [activeItem, setActiveItem] = useState<number>(0);
52
52
  const [isNavGroupExpanded, setIsNavGroupExpanded] = useState(false);
53
53
  const [isDockExpanded, setIsDockExpanded] = useState(false);
54
- const [isDockTextExpanded, setIsDockTextExpanded] = useState(false);
55
- const [isDockExpandableExpanded, setIsDockExpandableExpanded] = useState(false);
54
+ const [isDockOverlay, setIsDockOverlay] = useState(false);
56
55
  const [isMobile, setIsMobile] = useState(false);
57
56
 
58
57
  useEffect(() => {
@@ -69,7 +68,7 @@ export const CompassDockDemo: React.FunctionComponent = () => {
69
68
  }, []);
70
69
 
71
70
  const handleDockClickOutside = (event: MouseEvent) => {
72
- if ((!isMobile && !isDockExpandableExpanded) || (isMobile && !isDockExpanded)) {
71
+ if (!isDockExpanded) {
73
72
  return;
74
73
  }
75
74
 
@@ -80,21 +79,22 @@ export const CompassDockDemo: React.FunctionComponent = () => {
80
79
  dockedMastheadElement &&
81
80
  !dockedMastheadElement.contains(event.target as Node) &&
82
81
  !dockedMobileMastheadToggle?.contains(event.target as Node) &&
83
- (isDockExpandableExpanded || isDockExpanded)
82
+ isDockExpanded &&
83
+ (isDockOverlay || isMobile)
84
84
  ) {
85
- setIsDockExpandableExpanded(false);
86
85
  setIsDockExpanded(false);
86
+ setIsDockOverlay(false);
87
87
  }
88
88
  };
89
89
 
90
90
  const handleDockKeydown = (_event: KeyboardEvent) => {
91
- if ((!isMobile && !isDockExpandableExpanded) || (isMobile && !isDockExpanded)) {
91
+ if (!isDockExpanded) {
92
92
  return;
93
93
  }
94
94
 
95
95
  if (_event.key === 'Escape') {
96
- setIsDockExpandableExpanded(false);
97
96
  setIsDockExpanded(false);
97
+ setIsDockOverlay(false);
98
98
  }
99
99
  };
100
100
 
@@ -106,18 +106,17 @@ export const CompassDockDemo: React.FunctionComponent = () => {
106
106
  window.removeEventListener('click', handleDockClickOutside);
107
107
  window.removeEventListener('keydown', handleDockKeydown);
108
108
  };
109
- }, [isDockExpandableExpanded, isDockTextExpanded, isDockExpanded, isMobile]);
109
+ }, [isDockOverlay, isDockExpanded, isMobile]);
110
110
 
111
111
  const onNavSelect = (_event: React.FormEvent<HTMLInputElement>, selectedItem: NavOnSelectProps) => {
112
112
  typeof selectedItem.itemId === 'number' && setActiveItem(selectedItem.itemId);
113
113
 
114
- if (!isMobile && isDockTextExpanded) {
114
+ if (isDockExpanded && !isDockOverlay && !isMobile) {
115
115
  return;
116
116
  }
117
117
 
118
- setIsDockExpandableExpanded(false);
119
- setIsDockTextExpanded(false);
120
118
  setIsDockExpanded(false);
119
+ setIsDockOverlay(false);
121
120
  };
122
121
 
123
122
  const navItem1Ref = useRef<HTMLAnchorElement>(null);
@@ -141,45 +140,29 @@ export const CompassDockDemo: React.FunctionComponent = () => {
141
140
  };
142
141
 
143
142
  const onToggleDock = () => {
144
- if (isMobile) {
145
- setIsDockExpanded(!isDockExpanded);
143
+ const nextState = !isDockExpanded;
144
+ if (!nextState) {
145
+ setIsDockOverlay(false);
146
+ }
147
+ setIsDockExpanded(nextState);
146
148
 
149
+ if (isMobile) {
147
150
  if (isDockExpanded) {
148
151
  setTimeout(() => {
149
152
  mobileToggleRef.current?.focus();
150
153
  }, 200);
151
154
  }
152
- } else {
153
- const nextDockTextExpanded = !isDockTextExpanded;
154
- setIsDockTextExpanded(nextDockTextExpanded);
155
-
156
- if (!nextDockTextExpanded) {
157
- setIsDockExpandableExpanded(false);
158
- }
159
-
160
- if (isDockExpandableExpanded) {
161
- setIsDockExpandableExpanded(false);
162
- setIsDockTextExpanded(false);
163
- }
164
155
  }
165
156
  };
166
157
 
167
158
  const onToggleNavGroup = (_event: React.MouseEvent<HTMLButtonElement>, isExpanded: boolean) => {
168
- if (!isDockExpandableExpanded && !isDockTextExpanded && !isDockExpanded) {
159
+ if (!isDockExpanded) {
169
160
  setIsNavGroupExpanded(true);
161
+ setIsDockOverlay(true);
162
+ setIsDockExpanded(true);
170
163
  } else {
171
164
  setIsNavGroupExpanded(isExpanded);
172
165
  }
173
-
174
- if (!isMobile) {
175
- if (!isDockExpandableExpanded && !isDockTextExpanded) {
176
- setIsDockExpandableExpanded(true);
177
- }
178
-
179
- if (!isDockTextExpanded) {
180
- setIsDockTextExpanded(false);
181
- }
182
- }
183
166
  };
184
167
 
185
168
  const mobileTextLogo = (
@@ -315,7 +298,7 @@ export const CompassDockDemo: React.FunctionComponent = () => {
315
298
  isHamburger
316
299
  onClick={onToggleDock}
317
300
  aria-label="Global navigation"
318
- isExpanded={isDockTextExpanded}
301
+ isExpanded={isDockExpanded}
319
302
  />
320
303
  </MastheadToggle>
321
304
  <MastheadBrand>
@@ -409,7 +392,7 @@ export const CompassDockDemo: React.FunctionComponent = () => {
409
392
  </NavItem>
410
393
  </NavList>
411
394
  </Nav>
412
- {!isDockTextExpanded && !isDockExpanded && !isDockExpandableExpanded && (
395
+ {!isDockExpanded && (
413
396
  <>
414
397
  <Tooltip aria="none" aria-live="off" triggerRef={navItem1Ref} content="System panel"></Tooltip>
415
398
  <Tooltip aria="none" aria-live="off" triggerRef={navItem2Ref} content="Policy"></Tooltip>
@@ -426,7 +409,7 @@ export const CompassDockDemo: React.FunctionComponent = () => {
426
409
  gap={{ default: 'gapNone', md: 'gapMd' }}
427
410
  >
428
411
  <ToolbarItem>
429
- {isDockTextExpanded || isDockExpanded ? (
412
+ {isDockExpanded ? (
430
413
  <MenuToggle
431
414
  ref={appsRef}
432
415
  variant="plain"
@@ -451,7 +434,7 @@ export const CompassDockDemo: React.FunctionComponent = () => {
451
434
  )}
452
435
  </ToolbarItem>
453
436
  <ToolbarItem>
454
- {isDockTextExpanded || isDockExpanded ? (
437
+ {isDockExpanded ? (
455
438
  <Button ref={settingsRef} aria-label="Settings" isSettings variant="plain" isDocked>
456
439
  Settings
457
440
  </Button>
@@ -464,7 +447,7 @@ export const CompassDockDemo: React.FunctionComponent = () => {
464
447
  )}
465
448
  </ToolbarItem>
466
449
  <ToolbarItem>
467
- {isDockTextExpanded || isDockExpanded ? (
450
+ {isDockExpanded ? (
468
451
  <MenuToggle
469
452
  ref={helpRef}
470
453
  variant="plain"
@@ -514,8 +497,7 @@ export const CompassDockDemo: React.FunctionComponent = () => {
514
497
  masthead={mobileMasthead}
515
498
  dock={dockContent}
516
499
  isDockExpanded={isDockExpanded}
517
- isDockExpandableExpanded={isDockExpandableExpanded}
518
- isDockTextExpanded={isDockTextExpanded}
500
+ isDockOverlay={isDockOverlay}
519
501
  main={mainContent}
520
502
  backgroundSrcDark="/assets/images/pf-background.svg"
521
503
  backgroundSrcLight="/assets/images/pf-background.svg"
package/src/demos/Nav.md CHANGED
@@ -87,15 +87,15 @@ To save space in the UI, you can use docked navigation to replace text-labeled n
87
87
 
88
88
  This demo includes the following features:
89
89
 
90
- 1. A [page](/components/page) component with a docked layout, enabled via `variant="docked"`. Control the mobile overlay with `isDockExpanded` and the desktop label visibility with `isDockTextExpanded`.
90
+ 1. A [page](/components/page) component with a docked layout, enabled via `variant="docked"`. Control the expanded state of the dock with `isDockExpanded` and the set whether the dock is an overlay with `isDockOverlay`. The expanded docked nav is automatically an overlay in mobile.
91
91
 
92
92
  2. Two separate [masthead](/components/masthead) components:
93
93
  - **Horizontal mobile masthead**: Shown on small viewports using `display={{ default: 'inline' }}`, with a hamburger menu toggle button, brand logo, and action buttons that should be immediately visible to users.
94
94
  - **Vertical docked masthead**: Uses `variant="docked"` to create a thinner navigation sidebar with a hamburger menu toggle button, nav items, and action buttons.
95
95
 
96
- 3. A [navigation](/components/navigation) component with `variant="docked"` and multiple `<NavItem>` components that must include both icons and text labels. To control text visibility, `isTextExpanded={isDockTextExpanded}` is passed to the `<Nav>` component.
96
+ 3. A [navigation](/components/navigation) component with `variant="docked"` and multiple `<NavItem>` components that must include both icons and text labels. To control text visibility, `isExpanded={isDockExpanded}` is passed to the `<Nav>` component.
97
97
 
98
- 4. [Button](/components/button) and [menu toggle](/components/menus/menu-toggle) components, which use `isDocked` and `isTextExpanded` to toggle between icon-only and text+icon styles. When the nav is docked, and only icons are shown, [tooltips](/components/tooltip) must provide full text labels for the navigation items, buttons, and menu toggles.
98
+ 4. [Button](/components/button) and [menu toggle](/components/menus/menu-toggle) components, which use `isDocked` and `isExpanded` to toggle between icon-only and text+icon styles. When the nav is docked, and only icons are shown, [tooltips](/components/tooltip) must provide full text labels for the navigation items, buttons, and menu toggles.
99
99
 
100
100
  5. A `<MastheadLogo>` component that uses `isCompact` to show an icon-only logo when the dock is collapsed, and a full logo with text when expanded.
101
101