@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
@@ -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;
@@ -88,7 +88,7 @@ function Toggle(_ref) {
88
88
  handleClick(e);
89
89
  buttonElement.current.focus();
90
90
  }
91
- } : null
91
+ } : undefined
92
92
  }, /*#__PURE__*/React__default["default"].createElement("button", _rollupPluginBabelHelpers["extends"]({}, other, {
93
93
  ref: buttonElement,
94
94
  id: id,
@@ -100,7 +100,7 @@ function Toggle(_ref) {
100
100
  disabled: disabled,
101
101
  onClick: handleClick
102
102
  })), /*#__PURE__*/React__default["default"].createElement(LabelComponent, {
103
- htmlFor: ariaLabelledby ? null : id,
103
+ htmlFor: ariaLabelledby ? undefined : id,
104
104
  className: `${prefix}--toggle__label`
105
105
  }, labelText && /*#__PURE__*/React__default["default"].createElement("span", {
106
106
  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 };
@@ -36,6 +36,9 @@ class HeaderMenu extends React__default["default"].Component {
36
36
  constructor(props) {
37
37
  super(props);
38
38
  _rollupPluginBabelHelpers.defineProperty(this, "_subMenus", /*#__PURE__*/React__default["default"].createRef());
39
+ /**
40
+ * Toggle the expanded state of the menu on click.
41
+ */
39
42
  _rollupPluginBabelHelpers.defineProperty(this, "handleOnClick", e => {
40
43
  const {
41
44
  current: subMenusNode
@@ -47,6 +50,9 @@ class HeaderMenu extends React__default["default"].Component {
47
50
  expanded: !prevState.expanded
48
51
  }));
49
52
  });
53
+ /**
54
+ * Keyboard event handler for the entire menu.
55
+ */
50
56
  _rollupPluginBabelHelpers.defineProperty(this, "handleOnKeyDown", event => {
51
57
  // Handle enter or space key for toggling the expanded state of the menu.
52
58
  if (match.matches(event, [keys.Enter, keys.Space])) {
@@ -58,6 +64,11 @@ class HeaderMenu extends React__default["default"].Component {
58
64
  return;
59
65
  }
60
66
  });
67
+ /**
68
+ * Handle our blur event from our underlying menuitems. Will mostly be used
69
+ * for toggling the expansion status of our menu in response to a user
70
+ * clicking off of the menu or menubar.
71
+ */
61
72
  _rollupPluginBabelHelpers.defineProperty(this, "handleOnBlur", event => {
62
73
  // Rough guess for a blur event that is triggered outside of our menu or
63
74
  // menubar context
@@ -70,12 +81,24 @@ class HeaderMenu extends React__default["default"].Component {
70
81
  selectedIndex: null
71
82
  });
72
83
  });
84
+ /**
85
+ * ref handler for our menu button. If we are supplied a `focusRef` prop, we also
86
+ * forward along the node.
87
+ *
88
+ * This is useful when this component is a child in a
89
+ * menu or menubar as it will allow the parent to explicitly focus the menu
90
+ * button node when that child should receive focus.
91
+ */
73
92
  _rollupPluginBabelHelpers.defineProperty(this, "handleMenuButtonRef", node => {
74
93
  if (this.props.focusRef) {
75
94
  this.props.focusRef(node);
76
95
  }
77
96
  this.menuButtonRef = node;
78
97
  });
98
+ /**
99
+ * Handles individual menuitem refs. We assign them to a class instance
100
+ * property so that we can properly manage focus of our children.
101
+ */
79
102
  _rollupPluginBabelHelpers.defineProperty(this, "handleItemRef", index => node => {
80
103
  this.items[index] = node;
81
104
  });
@@ -94,6 +117,12 @@ class HeaderMenu extends React__default["default"].Component {
94
117
  return;
95
118
  }
96
119
  });
120
+ /**
121
+ * We capture the `ref` for each child inside of `this.items` to properly
122
+ * manage focus. In addition to this focus management, all items receive a
123
+ * `tabIndex: -1` so the user won't hit a large number of items in their tab
124
+ * sequence when they might not want to go through all the items.
125
+ */
97
126
  _rollupPluginBabelHelpers.defineProperty(this, "_renderMenuItem", (item, index) => {
98
127
  if ( /*#__PURE__*/React__default["default"].isValidElement(item)) {
99
128
  return /*#__PURE__*/React__default["default"].cloneElement(item, {
@@ -110,35 +139,6 @@ class HeaderMenu extends React__default["default"].Component {
110
139
  };
111
140
  this.items = [];
112
141
  }
113
-
114
- /**
115
- * Toggle the expanded state of the menu on click.
116
- */
117
-
118
- /**
119
- * Keyboard event handler for the entire menu.
120
- */
121
-
122
- /**
123
- * Handle our blur event from our underlying menuitems. Will mostly be used
124
- * for toggling the expansion status of our menu in response to a user
125
- * clicking off of the menu or menubar.
126
- */
127
-
128
- /**
129
- * ref handler for our menu button. If we are supplied a `focusRef` prop, we also
130
- * forward along the node.
131
- *
132
- * This is useful when this component is a child in a
133
- * menu or menubar as it will allow the parent to explicitly focus the menu
134
- * button node when that child should receive focus.
135
- */
136
-
137
- /**
138
- * Handles individual menuitem refs. We assign them to a class instance
139
- * property so that we can properly manage focus of our children.
140
- */
141
-
142
142
  render() {
143
143
  const prefix = this.context;
144
144
  const {
@@ -201,13 +201,6 @@ class HeaderMenu extends React__default["default"].Component {
201
201
  className: `${prefix}--header__menu`
202
202
  }), React__default["default"].Children.map(children, this._renderMenuItem)));
203
203
  }
204
-
205
- /**
206
- * We capture the `ref` for each child inside of `this.items` to properly
207
- * manage focus. In addition to this focus management, all items receive a
208
- * `tabIndex: -1` so the user won't hit a large number of items in their tab
209
- * sequence when they might not want to go through all the items.
210
- */
211
204
  }
212
205
  _rollupPluginBabelHelpers.defineProperty(HeaderMenu, "propTypes", {
213
206
  /**
@@ -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;
@@ -26,15 +26,13 @@ function HeaderName(_ref) {
26
26
  let {
27
27
  children,
28
28
  className: customClassName,
29
- prefix,
30
- href,
29
+ prefix = 'IBM',
31
30
  ...rest
32
31
  } = _ref;
33
32
  const selectorPrefix = usePrefix.usePrefix();
34
33
  const className = cx__default["default"](`${selectorPrefix}--header__name`, customClassName);
35
34
  return /*#__PURE__*/React__default["default"].createElement(Link["default"], _rollupPluginBabelHelpers["extends"]({}, rest, {
36
- className: className,
37
- href: href
35
+ className: className
38
36
  }), prefix && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement("span", {
39
37
  className: `${selectorPrefix}--header__name--prefix`
40
38
  }, prefix), "\xA0"), children);
@@ -64,8 +62,5 @@ HeaderName.propTypes = {
64
62
  */
65
63
  prefix: PropTypes__default["default"].string
66
64
  };
67
- HeaderName.defaultProps = {
68
- prefix: 'IBM'
69
- };
70
65
 
71
66
  exports["default"] = HeaderName;
@@ -14,6 +14,10 @@ var React = require('react');
14
14
  var cx = require('classnames');
15
15
  var PropTypes = require('prop-types');
16
16
  var usePrefix = require('../../internal/usePrefix.js');
17
+ var useEvent = require('../../internal/useEvent.js');
18
+ var useMergedRefs = require('../../internal/useMergedRefs.js');
19
+ var match = require('../../internal/keyboard/match.js');
20
+ var keys = require('../../internal/keyboard/keys.js');
17
21
 
18
22
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
19
23
 
@@ -26,19 +30,61 @@ const HeaderPanel = /*#__PURE__*/React__default["default"].forwardRef(function H
26
30
  children,
27
31
  className: customClassName,
28
32
  expanded,
33
+ addFocusListeners = true,
34
+ onHeaderPanelFocus,
35
+ href,
29
36
  ...other
30
37
  } = _ref;
31
38
  const prefix = usePrefix.usePrefix();
39
+ const headerPanelReference = React.useRef(null);
40
+ const headerPanelRef = useMergedRefs.useMergedRefs([headerPanelReference, ref]);
41
+ const controlled = React.useRef(expanded !== undefined).current;
42
+ const [expandedState, setExpandedState] = React.useState(expanded);
43
+ const expandedProp = controlled ? expanded : expandedState;
44
+ const [lastClickedElement, setLastClickedElement] = React.useState(null);
32
45
  const className = cx__default["default"](`${prefix}--header-panel`, {
33
- [`${prefix}--header-panel--expanded`]: expanded,
46
+ [`${prefix}--header-panel--expanded`]: expandedProp,
34
47
  [customClassName]: !!customClassName
35
48
  });
49
+ const eventHandlers = {};
50
+ if (addFocusListeners) {
51
+ eventHandlers.onBlur = event => {
52
+ if (!event.currentTarget.contains(event.relatedTarget) && !lastClickedElement.classList.contains('cds--switcher__item-link')) {
53
+ setExpandedState(false);
54
+ setLastClickedElement(null);
55
+ if (expanded) {
56
+ onHeaderPanelFocus();
57
+ }
58
+ }
59
+ };
60
+ eventHandlers.onKeyDown = event => {
61
+ if (match.match(event, keys.Escape)) {
62
+ setExpandedState(false);
63
+ onHeaderPanelFocus();
64
+ if (href) {
65
+ window.location.href = href;
66
+ }
67
+ }
68
+ };
69
+ }
70
+ useEvent.useWindowEvent('click', () => {
71
+ const focusedElement = document.activeElement;
72
+ setLastClickedElement(focusedElement);
73
+ if (children.type?.displayName === 'Switcher' && !focusedElement?.closest(`.${prefix}--header-panel--expanded`) && !focusedElement?.closest(`.${prefix}--header__action`) && !headerPanelRef?.current?.classList.contains(`${prefix}--switcher`) && expanded) {
74
+ setExpandedState(false);
75
+ onHeaderPanelFocus();
76
+ }
77
+ });
36
78
  return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({}, other, {
37
79
  className: className,
38
- ref: ref
39
- }), children);
80
+ ref: headerPanelRef
81
+ }, eventHandlers), children);
40
82
  });
41
83
  HeaderPanel.propTypes = {
84
+ /**
85
+ * Specify whether focus and blur listeners are added. They are by default.
86
+ */
87
+ addFocusListeners: PropTypes__default["default"].bool,
42
88
  /**
43
89
  * The content that will render inside of the `HeaderPanel`
44
90
  */
@@ -50,7 +96,17 @@ HeaderPanel.propTypes = {
50
96
  /**
51
97
  * Specify whether the panel is expanded
52
98
  */
53
- expanded: PropTypes__default["default"].bool
99
+ expanded: PropTypes__default["default"].bool,
100
+ /**
101
+ * Provide the `href` to the id of the element on your package that could
102
+ * be target.
103
+ */
104
+ href: PropTypes__default["default"].string,
105
+ /**
106
+ * An optional listener that is called a callback to collapse the HeaderPanel
107
+ */
108
+
109
+ onHeaderPanelFocus: PropTypes__default["default"].func
54
110
  };
55
111
  HeaderPanel.displayName = 'HeaderPanel';
56
112
  var HeaderPanel$1 = HeaderPanel;
@@ -64,6 +64,7 @@ const LinkPropTypes = {
64
64
  };
65
65
  Link.displayName = 'Link';
66
66
  Link.propTypes = LinkPropTypes;
67
+ var Link$1 = Link;
67
68
 
68
69
  exports.LinkPropTypes = LinkPropTypes;
69
- exports["default"] = Link;
70
+ exports["default"] = Link$1;
@@ -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;
@@ -15,6 +15,7 @@ var cx = require('classnames');
15
15
  var PropTypes = require('prop-types');
16
16
  var AriaPropTypes = require('../../prop-types/AriaPropTypes.js');
17
17
  var usePrefix = require('../../internal/usePrefix.js');
18
+ var useMergedRefs = require('../../internal/useMergedRefs.js');
18
19
 
19
20
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
20
21
 
@@ -22,13 +23,16 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
22
23
  var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
23
24
  var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
24
25
 
25
- const Switcher = /*#__PURE__*/React__default["default"].forwardRef(function Switcher(props, ref) {
26
+ const Switcher = /*#__PURE__*/React__default["default"].forwardRef(function Switcher(props, forwardRef) {
27
+ const switcherRef = React.useRef(null);
28
+ const ref = useMergedRefs.useMergedRefs([switcherRef, forwardRef]);
26
29
  const prefix = usePrefix.usePrefix();
27
30
  const {
28
31
  'aria-label': ariaLabel,
29
32
  'aria-labelledby': ariaLabelledBy,
30
33
  className: customClassName,
31
- children
34
+ children,
35
+ expanded
32
36
  } = props;
33
37
  const accessibilityLabel = {
34
38
  'aria-label': ariaLabel,
@@ -37,10 +41,42 @@ const Switcher = /*#__PURE__*/React__default["default"].forwardRef(function Swit
37
41
  const className = cx__default["default"](`${prefix}--switcher`, {
38
42
  [customClassName]: !!customClassName
39
43
  });
44
+ const handleSwitcherItemFocus = _ref => {
45
+ let {
46
+ currentIndex,
47
+ direction
48
+ } = _ref;
49
+ const enabledIndices = React__default["default"].Children.toArray(children).reduce((acc, curr, i) => {
50
+ if (Object.keys(curr.props).length !== 0) {
51
+ acc.push(i);
52
+ }
53
+ return acc;
54
+ }, []);
55
+ const nextValidIndex = (() => {
56
+ const nextIndex = enabledIndices.indexOf(currentIndex) + direction;
57
+ switch (enabledIndices[nextIndex]) {
58
+ case undefined:
59
+ if (direction === -1) {
60
+ return enabledIndices[enabledIndices.length - 1];
61
+ }
62
+ return 0;
63
+ default:
64
+ return enabledIndices[nextIndex];
65
+ }
66
+ })();
67
+ const switcherItem = switcherRef.current.children[nextValidIndex].children[0];
68
+ switcherItem?.focus();
69
+ };
70
+ const childrenWithProps = React__default["default"].Children.toArray(children).map((child, index) => /*#__PURE__*/React__default["default"].cloneElement(child, {
71
+ handleSwitcherItemFocus,
72
+ index,
73
+ key: index,
74
+ expanded
75
+ }));
40
76
  return /*#__PURE__*/React__default["default"].createElement("ul", _rollupPluginBabelHelpers["extends"]({
41
77
  ref: ref,
42
78
  className: className
43
- }, accessibilityLabel), children);
79
+ }, accessibilityLabel), childrenWithProps);
44
80
  });
45
81
  Switcher.displayName = 'Switcher';
46
82
  Switcher.propTypes = {
@@ -55,7 +91,11 @@ Switcher.propTypes = {
55
91
  /**
56
92
  * Optionally provide a custom class to apply to the underlying `<ul>` node
57
93
  */
58
- className: PropTypes__default["default"].string
94
+ className: PropTypes__default["default"].string,
95
+ /**
96
+ * Specify whether the panel is expanded
97
+ */
98
+ expanded: PropTypes__default["default"].bool
59
99
  };
60
100
  var Switcher$1 = Switcher;
61
101
 
@@ -16,6 +16,8 @@ var PropTypes = require('prop-types');
16
16
  var AriaPropTypes = require('../../prop-types/AriaPropTypes.js');
17
17
  var Link = require('./Link.js');
18
18
  var usePrefix = require('../../internal/usePrefix.js');
19
+ var match = require('../../internal/keyboard/match.js');
20
+ var keys = require('../../internal/keyboard/keys.js');
19
21
 
20
22
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
21
23
 
@@ -23,17 +25,21 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
23
25
  var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
24
26
  var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
25
27
 
26
- const SwitcherItem = /*#__PURE__*/React__default["default"].forwardRef(function SwitcherItem(props, ref) {
27
- const prefix = usePrefix.usePrefix();
28
- const {
28
+ const SwitcherItem = /*#__PURE__*/React__default["default"].forwardRef(function SwitcherItem(_ref, ref) {
29
+ let {
29
30
  'aria-label': ariaLabel,
30
31
  'aria-labelledby': ariaLabelledBy,
31
32
  className: customClassName,
32
33
  children,
33
34
  isSelected,
34
- tabIndex = 0,
35
+ expanded,
36
+ tabIndex = expanded ? 0 : -1,
37
+ index,
38
+ handleSwitcherItemFocus,
39
+ onKeyDown = () => {},
35
40
  ...rest
36
- } = props;
41
+ } = _ref;
42
+ const prefix = usePrefix.usePrefix();
37
43
  const className = cx__default["default"](`${prefix}--switcher__item`, {
38
44
  [customClassName]: !!customClassName
39
45
  });
@@ -44,9 +50,30 @@ const SwitcherItem = /*#__PURE__*/React__default["default"].forwardRef(function
44
50
  const linkClassName = cx__default["default"](`${prefix}--switcher__item-link`, {
45
51
  [`${prefix}--switcher__item-link--selected`]: isSelected
46
52
  });
53
+ function setTabFocus(evt) {
54
+ if (match.match(evt, keys.ArrowDown)) {
55
+ evt.preventDefault();
56
+ handleSwitcherItemFocus?.({
57
+ currentIndex: index,
58
+ direction: 1
59
+ });
60
+ }
61
+ if (match.match(evt, keys.ArrowUp)) {
62
+ evt.preventDefault();
63
+ handleSwitcherItemFocus?.({
64
+ currentIndex: index,
65
+ direction: -1
66
+ });
67
+ }
68
+ }
47
69
  return /*#__PURE__*/React__default["default"].createElement("li", {
48
70
  className: className
49
- }, /*#__PURE__*/React__default["default"].createElement(Link["default"], _rollupPluginBabelHelpers["extends"]({}, rest, {
71
+ }, /*#__PURE__*/React__default["default"].createElement(Link["default"], _rollupPluginBabelHelpers["extends"]({
72
+ onKeyDown: evt => {
73
+ setTabFocus(evt);
74
+ onKeyDown(evt);
75
+ }
76
+ }, rest, {
50
77
  ref: ref,
51
78
  className: linkClassName,
52
79
  tabIndex: tabIndex
@@ -66,6 +93,18 @@ SwitcherItem.propTypes = {
66
93
  * Optionally provide a custom class to apply to the underlying `<li>` node
67
94
  */
68
95
  className: PropTypes__default["default"].string,
96
+ /**
97
+ * event handlers
98
+ */
99
+ handleSwitcherItemFocus: PropTypes__default["default"].func,
100
+ /**
101
+ * Specify the index of the SwitcherItem
102
+ */
103
+ index: PropTypes__default["default"].number,
104
+ /**
105
+ * event handlers
106
+ */
107
+ onKeyDown: PropTypes__default["default"].func,
69
108
  /**
70
109
  * Specify the tab index of the Link
71
110
  */