@carbon/react 1.32.0-rc.0 → 1.33.0-rc.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.
Files changed (86) hide show
  1. package/README.md +22 -7
  2. package/es/components/ComboBox/ComboBox.js +43 -10
  3. package/es/components/ContentSwitcher/ContentSwitcher.js +5 -5
  4. package/es/components/DataTable/DataTable.js +110 -130
  5. package/es/components/DataTable/Table.js +1 -1
  6. package/es/components/DatePicker/DatePicker.d.ts +14 -13
  7. package/es/components/DatePicker/DatePicker.js +3 -0
  8. package/es/components/DatePickerInput/DatePickerInput.d.ts +2 -2
  9. package/es/components/Dropdown/Dropdown.js +31 -6
  10. package/es/components/FileUploader/FileUploader.Skeleton.d.ts +29 -0
  11. package/es/components/FileUploader/FileUploader.d.ts +175 -0
  12. package/es/components/FileUploader/FileUploader.js +3 -3
  13. package/es/components/FileUploader/FileUploaderButton.d.ts +140 -0
  14. package/es/components/FileUploader/FileUploaderButton.js +11 -7
  15. package/es/components/FileUploader/FileUploaderDropContainer.d.ts +139 -0
  16. package/es/components/FileUploader/FileUploaderDropContainer.js +3 -3
  17. package/es/components/FileUploader/FileUploaderItem.d.ts +110 -0
  18. package/es/components/FileUploader/Filename.d.ts +71 -0
  19. package/es/components/FileUploader/Filename.js +6 -4
  20. package/es/components/InlineCheckbox/InlineCheckbox.js +3 -1
  21. package/es/components/Loading/Loading.d.ts +65 -0
  22. package/es/components/Notification/Notification.d.ts +4 -4
  23. package/es/components/Notification/Notification.js +3 -3
  24. package/es/components/OverflowMenu/OverflowMenu.js +36 -41
  25. package/es/components/Slider/Slider.js +59 -68
  26. package/es/components/Tabs/Tabs.d.ts +9 -1
  27. package/es/components/Tabs/Tabs.js +16 -3
  28. package/es/components/Toggle/Toggle.d.ts +129 -0
  29. package/es/components/Toggle/Toggle.js +2 -2
  30. package/es/components/Toggle/index.d.ts +11 -0
  31. package/es/components/UIShell/HeaderMenu.js +29 -36
  32. package/es/components/UIShell/HeaderName.d.ts +39 -0
  33. package/es/components/UIShell/HeaderName.js +2 -7
  34. package/es/components/UIShell/HeaderPanel.js +61 -5
  35. package/es/components/UIShell/Link.js +2 -1
  36. package/es/components/UIShell/SideNav.d.ts +1 -1
  37. package/es/components/UIShell/Switcher.js +45 -5
  38. package/es/components/UIShell/SwitcherItem.js +45 -6
  39. package/es/index.js +1 -1
  40. package/es/internal/FloatingMenu.js +47 -51
  41. package/es/internal/useControllableState.js +1 -1
  42. package/es/internal/useId.js +10 -1
  43. package/es/internal/useMatchMedia.js +44 -0
  44. package/lib/components/ComboBox/ComboBox.js +43 -10
  45. package/lib/components/ContentSwitcher/ContentSwitcher.js +5 -5
  46. package/lib/components/DataTable/DataTable.js +110 -130
  47. package/lib/components/DataTable/Table.js +1 -1
  48. package/lib/components/DatePicker/DatePicker.d.ts +14 -13
  49. package/lib/components/DatePicker/DatePicker.js +3 -0
  50. package/lib/components/DatePickerInput/DatePickerInput.d.ts +2 -2
  51. package/lib/components/Dropdown/Dropdown.js +30 -5
  52. package/lib/components/FileUploader/FileUploader.Skeleton.d.ts +29 -0
  53. package/lib/components/FileUploader/FileUploader.d.ts +175 -0
  54. package/lib/components/FileUploader/FileUploader.js +3 -3
  55. package/lib/components/FileUploader/FileUploaderButton.d.ts +140 -0
  56. package/lib/components/FileUploader/FileUploaderButton.js +11 -7
  57. package/lib/components/FileUploader/FileUploaderDropContainer.d.ts +139 -0
  58. package/lib/components/FileUploader/FileUploaderDropContainer.js +3 -3
  59. package/lib/components/FileUploader/FileUploaderItem.d.ts +110 -0
  60. package/lib/components/FileUploader/Filename.d.ts +71 -0
  61. package/lib/components/FileUploader/Filename.js +6 -4
  62. package/lib/components/InlineCheckbox/InlineCheckbox.js +3 -1
  63. package/lib/components/Loading/Loading.d.ts +65 -0
  64. package/lib/components/Notification/Notification.d.ts +4 -4
  65. package/lib/components/Notification/Notification.js +3 -3
  66. package/lib/components/OverflowMenu/OverflowMenu.js +36 -41
  67. package/lib/components/Slider/Slider.js +59 -68
  68. package/lib/components/Tabs/Tabs.d.ts +9 -1
  69. package/lib/components/Tabs/Tabs.js +16 -3
  70. package/lib/components/Toggle/Toggle.d.ts +129 -0
  71. package/lib/components/Toggle/Toggle.js +2 -2
  72. package/lib/components/Toggle/index.d.ts +11 -0
  73. package/lib/components/UIShell/HeaderMenu.js +29 -36
  74. package/lib/components/UIShell/HeaderName.d.ts +39 -0
  75. package/lib/components/UIShell/HeaderName.js +2 -7
  76. package/lib/components/UIShell/HeaderPanel.js +60 -4
  77. package/lib/components/UIShell/Link.js +2 -1
  78. package/lib/components/UIShell/SideNav.d.ts +1 -1
  79. package/lib/components/UIShell/Switcher.js +44 -4
  80. package/lib/components/UIShell/SwitcherItem.js +45 -6
  81. package/lib/index.js +2 -2
  82. package/lib/internal/FloatingMenu.js +47 -51
  83. package/lib/internal/useControllableState.js +1 -1
  84. package/lib/internal/useId.js +9 -0
  85. package/lib/internal/useMatchMedia.js +48 -0
  86. package/package.json +22 -19
@@ -104,6 +104,10 @@ export interface TabListProps extends DivAttributes {
104
104
  * Specify whether component is contained type
105
105
  */
106
106
  contained?: boolean;
107
+ /**
108
+ * Used for tabs within a grid, this makes it so tabs span the full container width and have the same width. Only available on contained tabs with <9 children
109
+ */
110
+ fullWidth?: boolean;
107
111
  /**
108
112
  * If using `IconTab`, specify the size of the icon being used.
109
113
  */
@@ -132,7 +136,7 @@ export interface TabListProps extends DivAttributes {
132
136
  */
133
137
  scrollIntoView?: boolean;
134
138
  }
135
- declare function TabList({ activation, 'aria-label': label, children, className: customClassName, contained, iconSize, leftOverflowButtonProps, light, rightOverflowButtonProps, scrollDebounceWait, scrollIntoView, ...rest }: TabListProps): JSX.Element;
139
+ declare function TabList({ activation, 'aria-label': label, children, className: customClassName, contained, fullWidth, iconSize, leftOverflowButtonProps, light, rightOverflowButtonProps, scrollDebounceWait, scrollIntoView, ...rest }: TabListProps): JSX.Element;
136
140
  declare namespace TabList {
137
141
  var propTypes: {
138
142
  /**
@@ -158,6 +162,10 @@ declare namespace TabList {
158
162
  * Specify whether component is contained type
159
163
  */
160
164
  contained: PropTypes.Requireable<boolean>;
165
+ /**
166
+ * Used for tabs within a grid, this makes it so tabs span the full container width and have the same width. Only available on contained tabs with <9 children
167
+ */
168
+ fullWidth: PropTypes.Requireable<boolean>;
161
169
  /**
162
170
  * If using `IconTab`, specify the size of the icon being used.
163
171
  */
@@ -7,6 +7,7 @@
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
9
  import { ChevronLeft, ChevronRight, Close } from '@carbon/icons-react';
10
+ import { breakpoints } from '@carbon/layout';
10
11
  import cx from 'classnames';
11
12
  import debounce from 'lodash.debounce';
12
13
  import PropTypes from 'prop-types';
@@ -24,6 +25,7 @@ import { usePrefix } from '../../internal/usePrefix.js';
24
25
  import { usePressable } from './usePressable.js';
25
26
  import deprecate from '../../prop-types/deprecate.js';
26
27
  import { useEvent } from '../../internal/useEvent.js';
28
+ import { useMatchMedia } from '../../internal/useMatchMedia.js';
27
29
  import { matches, match } from '../../internal/keyboard/match.js';
28
30
  import { ArrowRight, ArrowLeft, Home, End, Delete } from '../../internal/keyboard/keys.js';
29
31
 
@@ -47,6 +49,7 @@ const TabContext = /*#__PURE__*/React__default.createContext({
47
49
  index: 0,
48
50
  hasSecondaryLabel: false
49
51
  });
52
+ const lgMediaQuery = `(min-width: ${breakpoints.lg.width})`;
50
53
 
51
54
  // Used to keep track of position in a list of tab panels
52
55
  const TabPanelContext = /*#__PURE__*/React__default.createContext(0);
@@ -156,6 +159,7 @@ function TabList(_ref2) {
156
159
  children,
157
160
  className: customClassName,
158
161
  contained = false,
162
+ fullWidth = false,
159
163
  iconSize,
160
164
  leftOverflowButtonProps,
161
165
  light,
@@ -183,12 +187,15 @@ function TabList(_ref2) {
183
187
  return isElement(child) && !!child.props.secondaryLabel;
184
188
  });
185
189
  }
190
+ const isLg = useMatchMedia(lgMediaQuery);
191
+ const distributeWidth = fullWidth && contained && isLg && React__default.Children.toArray(children).length < 9;
186
192
  const className = cx(`${prefix}--tabs`, {
187
193
  [`${prefix}--tabs--contained`]: contained,
188
194
  [`${prefix}--tabs--light`]: light,
189
195
  [`${prefix}--tabs__icon--default`]: iconSize === 'default',
190
196
  [`${prefix}--tabs__icon--lg`]: iconSize === 'lg',
191
- [`${prefix}--tabs--tall`]: hasSecondaryLabelTabs
197
+ [`${prefix}--tabs--tall`]: hasSecondaryLabelTabs,
198
+ [`${prefix}--tabs--full-width`]: distributeWidth
192
199
  }, customClassName);
193
200
 
194
201
  // Previous Button
@@ -396,6 +403,10 @@ TabList.propTypes = {
396
403
  * Specify whether component is contained type
397
404
  */
398
405
  contained: PropTypes.bool,
406
+ /**
407
+ * Used for tabs within a grid, this makes it so tabs span the full container width and have the same width. Only available on contained tabs with <9 children
408
+ */
409
+ fullWidth: PropTypes.bool,
399
410
  /**
400
411
  * If using `IconTab`, specify the size of the icon being used.
401
412
  */
@@ -574,7 +585,8 @@ const Tab = /*#__PURE__*/forwardRef(function Tab(_ref5, forwardRef) {
574
585
  }, /*#__PURE__*/React__default.createElement(Icon, {
575
586
  size: 16
576
587
  })), /*#__PURE__*/React__default.createElement("span", {
577
- className: `${prefix}--tabs__nav-item-label`
588
+ className: `${prefix}--tabs__nav-item-label`,
589
+ title: children
578
590
  }, children), /*#__PURE__*/React__default.createElement("div", {
579
591
  className: cx(`${prefix}--tabs__nav-item--icon`, {
580
592
  [`${prefix}--visually-hidden`]: !hasIcon
@@ -582,7 +594,8 @@ const Tab = /*#__PURE__*/forwardRef(function Tab(_ref5, forwardRef) {
582
594
  }, DismissIcon, !dismissable && Icon && /*#__PURE__*/React__default.createElement(Icon, {
583
595
  size: 16
584
596
  }))), hasSecondaryLabel && /*#__PURE__*/React__default.createElement("div", {
585
- className: `${prefix}--tabs__nav-item-secondary-label`
597
+ className: `${prefix}--tabs__nav-item-secondary-label`,
598
+ title: secondaryLabel
586
599
  }, secondaryLabel));
587
600
  });
588
601
  Tab.propTypes = {
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Copyright IBM Corp. 2021, 2023
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
+ import React, { KeyboardEventHandler, MouseEventHandler } from 'react';
8
+ import PropTypes from 'prop-types';
9
+ type ExcludedAttributes = 'aria-labelledby' | 'aria-checked' | 'type' | 'role' | 'id' | 'size' | 'onClick';
10
+ export interface ToggleProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, ExcludedAttributes> {
11
+ /**
12
+ * Specify another element's id to be used as the label for this toggle
13
+ */
14
+ 'aria-labelledby'?: string;
15
+ /**
16
+ * Provide an id that unique represents the underlying `<button>`
17
+ */
18
+ id: string;
19
+ /**
20
+ * Specify the label for the "off" position
21
+ */
22
+ labelA?: string | undefined;
23
+ /**
24
+ * Specify the label for the "on" position
25
+ */
26
+ labelB?: string | undefined;
27
+ /**
28
+ * Provide the text that will be read by a screen reader when visiting this
29
+ * control. This should be provided unless 'aria-labelledby' is set instead
30
+ * or you use an external <label> element with its "for" attribute set to the
31
+ * toggle's id.
32
+ */
33
+ labelText?: string | undefined;
34
+ /**
35
+ * If true, the side labels (props.labelA and props.labelB) will be replaced by
36
+ * props.labelText (if passed), so that the toggle doesn't render a top label.
37
+ */
38
+ hideLabel?: boolean;
39
+ /**
40
+ * Provide an event listener that is called when the control is toggled
41
+ */
42
+ onClick: MouseEventHandler<HTMLDivElement> | KeyboardEventHandler<HTMLDivElement> | undefined;
43
+ /**
44
+ * Provide an event listener that is called when the control is toggled
45
+ */
46
+ onToggle?(checked: boolean): void;
47
+ /**
48
+ * Specify the size of the Toggle. Currently only supports 'sm' or 'md' (default)
49
+ */
50
+ size?: 'sm' | 'md' | undefined;
51
+ /**
52
+ * Whether the toggle should be read-only
53
+ */
54
+ readOnly?: boolean | undefined;
55
+ /**
56
+ * Specify whether the toggle should be on by default
57
+ */
58
+ defaultToggled?: boolean | undefined;
59
+ /**
60
+ * Specify whether the control is toggled
61
+ */
62
+ toggled?: boolean | undefined;
63
+ }
64
+ export declare function Toggle({ 'aria-labelledby': ariaLabelledby, className, defaultToggled, disabled, hideLabel, id, labelA, labelB, labelText, onClick, onToggle, readOnly, size, toggled, ...other }: ToggleProps): JSX.Element;
65
+ export declare namespace Toggle {
66
+ var propTypes: {
67
+ /**
68
+ * Specify another element's id to be used as the label for this toggle
69
+ */
70
+ 'aria-labelledby': PropTypes.Requireable<string>;
71
+ /**
72
+ * Specify a custom className to apply to the form-item node
73
+ */
74
+ className: PropTypes.Requireable<string>;
75
+ /**
76
+ * Specify whether the toggle should be on by default
77
+ */
78
+ defaultToggled: PropTypes.Requireable<boolean>;
79
+ /**
80
+ * Whether this control should be disabled
81
+ */
82
+ disabled: PropTypes.Requireable<boolean>;
83
+ /**
84
+ * If true, the side labels (props.labelA and props.labelB) will be replaced by
85
+ * props.labelText (if passed), so that the toggle doesn't render a top label.
86
+ */
87
+ hideLabel: PropTypes.Requireable<boolean>;
88
+ /**
89
+ * Provide an id that unique represents the underlying `<button>`
90
+ */
91
+ id: PropTypes.Validator<string>;
92
+ /**
93
+ * Specify the label for the "off" position
94
+ */
95
+ labelA: PropTypes.Requireable<PropTypes.ReactNodeLike>;
96
+ /**
97
+ * Specify the label for the "on" position
98
+ */
99
+ labelB: PropTypes.Requireable<PropTypes.ReactNodeLike>;
100
+ /**
101
+ * Provide the text that will be read by a screen reader when visiting this
102
+ * control. This should be provided unless 'aria-labelledby' is set instead
103
+ * or you use an external <label> element with its "for" attribute set to the
104
+ * toggle's id.
105
+ */
106
+ labelText: PropTypes.Requireable<string>;
107
+ /**
108
+ * Provide an event listener that is called when the control is clicked
109
+ */
110
+ onClick: PropTypes.Requireable<(...args: any[]) => any>;
111
+ /**
112
+ * Provide an event listener that is called when the control is toggled
113
+ */
114
+ onToggle: PropTypes.Requireable<(...args: any[]) => any>;
115
+ /**
116
+ * Whether the toggle should be read-only
117
+ */
118
+ readOnly: PropTypes.Requireable<boolean>;
119
+ /**
120
+ * Specify the size of the Toggle. Currently only supports 'sm' or 'md' (default)
121
+ */
122
+ size: PropTypes.Requireable<string>;
123
+ /**
124
+ * Specify whether the control is toggled
125
+ */
126
+ toggled: PropTypes.Requireable<boolean>;
127
+ };
128
+ }
129
+ export default Toggle;
@@ -78,7 +78,7 @@ function Toggle(_ref) {
78
78
  handleClick(e);
79
79
  buttonElement.current.focus();
80
80
  }
81
- } : null
81
+ } : undefined
82
82
  }, /*#__PURE__*/React__default.createElement("button", _extends({}, other, {
83
83
  ref: buttonElement,
84
84
  id: id,
@@ -90,7 +90,7 @@ function Toggle(_ref) {
90
90
  disabled: disabled,
91
91
  onClick: handleClick
92
92
  })), /*#__PURE__*/React__default.createElement(LabelComponent, {
93
- htmlFor: ariaLabelledby ? null : id,
93
+ htmlFor: ariaLabelledby ? undefined : id,
94
94
  className: `${prefix}--toggle__label`
95
95
  }, labelText && /*#__PURE__*/React__default.createElement("span", {
96
96
  className: labelTextClasses
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2023
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
+ import { default as Toggle, ToggleProps } from './Toggle';
8
+ export * from './Toggle.Skeleton';
9
+ export default Toggle;
10
+ export { Toggle };
11
+ export type { ToggleProps };
@@ -26,6 +26,9 @@ class HeaderMenu extends React__default.Component {
26
26
  constructor(props) {
27
27
  super(props);
28
28
  _defineProperty(this, "_subMenus", /*#__PURE__*/React__default.createRef());
29
+ /**
30
+ * Toggle the expanded state of the menu on click.
31
+ */
29
32
  _defineProperty(this, "handleOnClick", e => {
30
33
  const {
31
34
  current: subMenusNode
@@ -37,6 +40,9 @@ class HeaderMenu extends React__default.Component {
37
40
  expanded: !prevState.expanded
38
41
  }));
39
42
  });
43
+ /**
44
+ * Keyboard event handler for the entire menu.
45
+ */
40
46
  _defineProperty(this, "handleOnKeyDown", event => {
41
47
  // Handle enter or space key for toggling the expanded state of the menu.
42
48
  if (matches(event, [Enter, Space])) {
@@ -48,6 +54,11 @@ class HeaderMenu extends React__default.Component {
48
54
  return;
49
55
  }
50
56
  });
57
+ /**
58
+ * Handle our blur event from our underlying menuitems. Will mostly be used
59
+ * for toggling the expansion status of our menu in response to a user
60
+ * clicking off of the menu or menubar.
61
+ */
51
62
  _defineProperty(this, "handleOnBlur", event => {
52
63
  // Rough guess for a blur event that is triggered outside of our menu or
53
64
  // menubar context
@@ -60,12 +71,24 @@ class HeaderMenu extends React__default.Component {
60
71
  selectedIndex: null
61
72
  });
62
73
  });
74
+ /**
75
+ * ref handler for our menu button. If we are supplied a `focusRef` prop, we also
76
+ * forward along the node.
77
+ *
78
+ * This is useful when this component is a child in a
79
+ * menu or menubar as it will allow the parent to explicitly focus the menu
80
+ * button node when that child should receive focus.
81
+ */
63
82
  _defineProperty(this, "handleMenuButtonRef", node => {
64
83
  if (this.props.focusRef) {
65
84
  this.props.focusRef(node);
66
85
  }
67
86
  this.menuButtonRef = node;
68
87
  });
88
+ /**
89
+ * Handles individual menuitem refs. We assign them to a class instance
90
+ * property so that we can properly manage focus of our children.
91
+ */
69
92
  _defineProperty(this, "handleItemRef", index => node => {
70
93
  this.items[index] = node;
71
94
  });
@@ -84,6 +107,12 @@ class HeaderMenu extends React__default.Component {
84
107
  return;
85
108
  }
86
109
  });
110
+ /**
111
+ * We capture the `ref` for each child inside of `this.items` to properly
112
+ * manage focus. In addition to this focus management, all items receive a
113
+ * `tabIndex: -1` so the user won't hit a large number of items in their tab
114
+ * sequence when they might not want to go through all the items.
115
+ */
87
116
  _defineProperty(this, "_renderMenuItem", (item, index) => {
88
117
  if ( /*#__PURE__*/React__default.isValidElement(item)) {
89
118
  return /*#__PURE__*/React__default.cloneElement(item, {
@@ -100,35 +129,6 @@ class HeaderMenu extends React__default.Component {
100
129
  };
101
130
  this.items = [];
102
131
  }
103
-
104
- /**
105
- * Toggle the expanded state of the menu on click.
106
- */
107
-
108
- /**
109
- * Keyboard event handler for the entire menu.
110
- */
111
-
112
- /**
113
- * Handle our blur event from our underlying menuitems. Will mostly be used
114
- * for toggling the expansion status of our menu in response to a user
115
- * clicking off of the menu or menubar.
116
- */
117
-
118
- /**
119
- * ref handler for our menu button. If we are supplied a `focusRef` prop, we also
120
- * forward along the node.
121
- *
122
- * This is useful when this component is a child in a
123
- * menu or menubar as it will allow the parent to explicitly focus the menu
124
- * button node when that child should receive focus.
125
- */
126
-
127
- /**
128
- * Handles individual menuitem refs. We assign them to a class instance
129
- * property so that we can properly manage focus of our children.
130
- */
131
-
132
132
  render() {
133
133
  const prefix = this.context;
134
134
  const {
@@ -191,13 +191,6 @@ class HeaderMenu extends React__default.Component {
191
191
  className: `${prefix}--header__menu`
192
192
  }), React__default.Children.map(children, this._renderMenuItem)));
193
193
  }
194
-
195
- /**
196
- * We capture the `ref` for each child inside of `this.items` to properly
197
- * manage focus. In addition to this focus management, all items receive a
198
- * `tabIndex: -1` so the user won't hit a large number of items in their tab
199
- * sequence when they might not want to go through all the items.
200
- */
201
194
  }
202
195
  _defineProperty(HeaderMenu, "propTypes", {
203
196
  /**
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2023
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
+ import { type ElementType } from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import { type LinkProps } from './Link';
10
+ type HeaderNameProps<E extends ElementType> = LinkProps<E> & {
11
+ prefix?: string | undefined;
12
+ };
13
+ declare function HeaderName<E extends ElementType = 'a'>({ children, className: customClassName, prefix, ...rest }: HeaderNameProps<E>): JSX.Element;
14
+ declare namespace HeaderName {
15
+ var propTypes: {
16
+ /**
17
+ * Pass in children that are either a string or can be read as a string by
18
+ * screen readers
19
+ */
20
+ children: PropTypes.Validator<NonNullable<PropTypes.ReactNodeLike>>;
21
+ /**
22
+ * Optionally provide a custom class to apply to the underlying `<li>` node
23
+ */
24
+ className: PropTypes.Requireable<string>;
25
+ /**
26
+ * Provide an href for the name to link to
27
+ */
28
+ href: PropTypes.Requireable<string>;
29
+ /**
30
+ * Optionally specify a prefix to your header name. Useful for companies, for
31
+ * example: IBM [Product Name] versus solely [Product Name]
32
+ */
33
+ prefix: PropTypes.Requireable<string>;
34
+ as: PropTypes.Requireable<PropTypes.ReactComponentLike>;
35
+ element: (props: any, propName: any, componentName: any, ...rest: any[]) => any;
36
+ isSideNavExpanded: PropTypes.Requireable<boolean>;
37
+ };
38
+ }
39
+ export default HeaderName;
@@ -16,15 +16,13 @@ function HeaderName(_ref) {
16
16
  let {
17
17
  children,
18
18
  className: customClassName,
19
- prefix,
20
- href,
19
+ prefix = 'IBM',
21
20
  ...rest
22
21
  } = _ref;
23
22
  const selectorPrefix = usePrefix();
24
23
  const className = cx(`${selectorPrefix}--header__name`, customClassName);
25
24
  return /*#__PURE__*/React__default.createElement(Link, _extends({}, rest, {
26
- className: className,
27
- href: href
25
+ className: className
28
26
  }), prefix && /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("span", {
29
27
  className: `${selectorPrefix}--header__name--prefix`
30
28
  }, prefix), "\xA0"), children);
@@ -54,8 +52,5 @@ HeaderName.propTypes = {
54
52
  */
55
53
  prefix: PropTypes.string
56
54
  };
57
- HeaderName.defaultProps = {
58
- prefix: 'IBM'
59
- };
60
55
 
61
56
  export { HeaderName as default };
@@ -6,29 +6,75 @@
6
6
  */
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React__default from 'react';
9
+ import React__default, { useRef, useState } from 'react';
10
10
  import cx from 'classnames';
11
11
  import PropTypes from 'prop-types';
12
12
  import { usePrefix } from '../../internal/usePrefix.js';
13
+ import { useWindowEvent } from '../../internal/useEvent.js';
14
+ import { useMergedRefs } from '../../internal/useMergedRefs.js';
15
+ import { match } from '../../internal/keyboard/match.js';
16
+ import { Escape } from '../../internal/keyboard/keys.js';
13
17
 
14
18
  const HeaderPanel = /*#__PURE__*/React__default.forwardRef(function HeaderPanel(_ref, ref) {
15
19
  let {
16
20
  children,
17
21
  className: customClassName,
18
22
  expanded,
23
+ addFocusListeners = true,
24
+ onHeaderPanelFocus,
25
+ href,
19
26
  ...other
20
27
  } = _ref;
21
28
  const prefix = usePrefix();
29
+ const headerPanelReference = useRef(null);
30
+ const headerPanelRef = useMergedRefs([headerPanelReference, ref]);
31
+ const controlled = useRef(expanded !== undefined).current;
32
+ const [expandedState, setExpandedState] = useState(expanded);
33
+ const expandedProp = controlled ? expanded : expandedState;
34
+ const [lastClickedElement, setLastClickedElement] = useState(null);
22
35
  const className = cx(`${prefix}--header-panel`, {
23
- [`${prefix}--header-panel--expanded`]: expanded,
36
+ [`${prefix}--header-panel--expanded`]: expandedProp,
24
37
  [customClassName]: !!customClassName
25
38
  });
39
+ const eventHandlers = {};
40
+ if (addFocusListeners) {
41
+ eventHandlers.onBlur = event => {
42
+ if (!event.currentTarget.contains(event.relatedTarget) && !lastClickedElement.classList.contains('cds--switcher__item-link')) {
43
+ setExpandedState(false);
44
+ setLastClickedElement(null);
45
+ if (expanded) {
46
+ onHeaderPanelFocus();
47
+ }
48
+ }
49
+ };
50
+ eventHandlers.onKeyDown = event => {
51
+ if (match(event, Escape)) {
52
+ setExpandedState(false);
53
+ onHeaderPanelFocus();
54
+ if (href) {
55
+ window.location.href = href;
56
+ }
57
+ }
58
+ };
59
+ }
60
+ useWindowEvent('click', () => {
61
+ const focusedElement = document.activeElement;
62
+ setLastClickedElement(focusedElement);
63
+ if (children.type?.displayName === 'Switcher' && !focusedElement?.closest(`.${prefix}--header-panel--expanded`) && !focusedElement?.closest(`.${prefix}--header__action`) && !headerPanelRef?.current?.classList.contains(`${prefix}--switcher`) && expanded) {
64
+ setExpandedState(false);
65
+ onHeaderPanelFocus();
66
+ }
67
+ });
26
68
  return /*#__PURE__*/React__default.createElement("div", _extends({}, other, {
27
69
  className: className,
28
- ref: ref
29
- }), children);
70
+ ref: headerPanelRef
71
+ }, eventHandlers), children);
30
72
  });
31
73
  HeaderPanel.propTypes = {
74
+ /**
75
+ * Specify whether focus and blur listeners are added. They are by default.
76
+ */
77
+ addFocusListeners: PropTypes.bool,
32
78
  /**
33
79
  * The content that will render inside of the `HeaderPanel`
34
80
  */
@@ -40,7 +86,17 @@ HeaderPanel.propTypes = {
40
86
  /**
41
87
  * Specify whether the panel is expanded
42
88
  */
43
- expanded: PropTypes.bool
89
+ expanded: PropTypes.bool,
90
+ /**
91
+ * Provide the `href` to the id of the element on your package that could
92
+ * be target.
93
+ */
94
+ href: PropTypes.string,
95
+ /**
96
+ * An optional listener that is called a callback to collapse the HeaderPanel
97
+ */
98
+
99
+ onHeaderPanelFocus: PropTypes.func
44
100
  };
45
101
  HeaderPanel.displayName = 'HeaderPanel';
46
102
  var HeaderPanel$1 = HeaderPanel;
@@ -55,5 +55,6 @@ const LinkPropTypes = {
55
55
  };
56
56
  Link.displayName = 'Link';
57
57
  Link.propTypes = LinkPropTypes;
58
+ var Link$1 = Link;
58
59
 
59
- export { LinkPropTypes, Link as default };
60
+ export { LinkPropTypes, Link$1 as default };
@@ -20,5 +20,5 @@ interface SideNavProps extends ComponentProps<'nav'> {
20
20
  onSideNavBlur?: () => void | undefined;
21
21
  enterDelayMs?: number;
22
22
  }
23
- declare const SideNav: React.ForwardRefExoticComponent<Pick<SideNavProps, "children" | "slot" | "style" | "title" | "className" | "dir" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "onToggle" | "key" | "id" | "aria-controls" | "aria-expanded" | "onClick" | "onAnimationEnd" | "onKeyDown" | "contentEditable" | "contextMenu" | "draggable" | "hidden" | "lang" | "placeholder" | "spellCheck" | "tabIndex" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "href" | "expanded" | "enterDelayMs" | "defaultExpanded" | "isChildOfHeader" | "isFixedNav" | "isRail" | "isPersistent" | "addFocusListeners" | "addMouseListeners" | "onOverlayClick" | "onSideNavBlur"> & React.RefAttributes<HTMLElement>>;
23
+ declare const SideNav: React.ForwardRefExoticComponent<Pick<SideNavProps, "children" | "slot" | "style" | "title" | "className" | "dir" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "onToggle" | "key" | "id" | "aria-controls" | "aria-expanded" | "onClick" | "onAnimationEnd" | "onKeyDown" | "contentEditable" | "contextMenu" | "draggable" | "hidden" | "lang" | "placeholder" | "spellCheck" | "tabIndex" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "href" | "expanded" | "enterDelayMs" | "defaultExpanded" | "addFocusListeners" | "isChildOfHeader" | "isFixedNav" | "isRail" | "isPersistent" | "addMouseListeners" | "onOverlayClick" | "onSideNavBlur"> & React.RefAttributes<HTMLElement>>;
24
24
  export default SideNav;