@carbon/react 1.42.1 → 1.44.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 (97) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +2843 -1416
  2. package/es/components/Breadcrumb/BreadcrumbItem.js +1 -2
  3. package/es/components/ComboBox/ComboBox.d.ts +5 -0
  4. package/es/components/ComboBox/ComboBox.js +28 -2
  5. package/es/components/ComboButton/index.js +2 -1
  6. package/es/components/ComposedModal/ComposedModal.d.ts +3 -3
  7. package/es/components/ComposedModal/ComposedModal.js +3 -3
  8. package/es/components/ComposedModal/ModalFooter.d.ts +18 -0
  9. package/es/components/ComposedModal/ModalFooter.js +48 -16
  10. package/es/components/ContextMenu/useContextMenu.js +2 -1
  11. package/es/components/DataTableSkeleton/DataTableSkeleton.js +1 -1
  12. package/es/components/DatePickerInput/DatePickerInput.d.ts +4 -0
  13. package/es/components/DatePickerInput/DatePickerInput.js +16 -2
  14. package/es/components/Dropdown/Dropdown.d.ts +5 -0
  15. package/es/components/Dropdown/Dropdown.js +20 -3
  16. package/es/components/InlineLoading/index.js +9 -0
  17. package/es/components/Link/Link.d.ts +5 -0
  18. package/es/components/Link/Link.js +9 -2
  19. package/es/components/Menu/Menu.js +14 -0
  20. package/es/components/Menu/MenuContext.js +1 -0
  21. package/es/components/Menu/MenuItem.js +19 -4
  22. package/es/components/MenuButton/index.js +3 -1
  23. package/es/components/Modal/Modal.d.ts +17 -0
  24. package/es/components/Modal/Modal.js +38 -3
  25. package/es/components/MultiSelect/FilterableMultiSelect.js +17 -3
  26. package/es/components/MultiSelect/MultiSelect.d.ts +5 -0
  27. package/es/components/MultiSelect/MultiSelect.js +17 -3
  28. package/es/components/NumberInput/NumberInput.d.ts +5 -0
  29. package/es/components/NumberInput/NumberInput.js +29 -4
  30. package/es/components/Select/Select.d.ts +6 -1
  31. package/es/components/Select/Select.js +16 -2
  32. package/es/components/Slug/index.js +187 -0
  33. package/es/components/TextArea/TextArea.d.ts +4 -0
  34. package/es/components/TextArea/TextArea.js +47 -31
  35. package/es/components/TextInput/TextInput.d.ts +5 -0
  36. package/es/components/TextInput/TextInput.js +16 -2
  37. package/es/components/UIShell/SideNav.js +1 -1
  38. package/es/components/UIShell/SideNavHeader.d.ts +29 -0
  39. package/es/components/UIShell/SideNavHeader.js +3 -3
  40. package/es/components/UIShell/Switcher.d.ts +38 -0
  41. package/es/components/UIShell/Switcher.js +14 -13
  42. package/es/components/UIShell/SwitcherDivider.d.ts +9 -0
  43. package/es/components/UIShell/SwitcherDivider.js +4 -5
  44. package/es/components/UIShell/SwitcherItem.d.ts +49 -0
  45. package/es/components/UIShell/SwitcherItem.js +13 -17
  46. package/es/index.d.ts +1 -0
  47. package/es/index.js +1 -0
  48. package/es/prop-types/tools/getDisplayName.js +34 -0
  49. package/lib/components/Breadcrumb/BreadcrumbItem.js +1 -2
  50. package/lib/components/ComboBox/ComboBox.d.ts +5 -0
  51. package/lib/components/ComboBox/ComboBox.js +28 -2
  52. package/lib/components/ComboButton/index.js +2 -1
  53. package/lib/components/ComposedModal/ComposedModal.d.ts +3 -3
  54. package/lib/components/ComposedModal/ComposedModal.js +3 -3
  55. package/lib/components/ComposedModal/ModalFooter.d.ts +18 -0
  56. package/lib/components/ComposedModal/ModalFooter.js +48 -16
  57. package/lib/components/ContextMenu/useContextMenu.js +2 -1
  58. package/lib/components/DataTableSkeleton/DataTableSkeleton.js +1 -1
  59. package/lib/components/DatePickerInput/DatePickerInput.d.ts +4 -0
  60. package/lib/components/DatePickerInput/DatePickerInput.js +16 -2
  61. package/lib/components/Dropdown/Dropdown.d.ts +5 -0
  62. package/lib/components/Dropdown/Dropdown.js +20 -3
  63. package/lib/components/InlineLoading/index.js +17 -0
  64. package/lib/components/Link/Link.d.ts +5 -0
  65. package/lib/components/Link/Link.js +9 -2
  66. package/lib/components/Menu/Menu.js +14 -0
  67. package/lib/components/Menu/MenuContext.js +1 -0
  68. package/lib/components/Menu/MenuItem.js +19 -4
  69. package/lib/components/MenuButton/index.js +3 -1
  70. package/lib/components/Modal/Modal.d.ts +17 -0
  71. package/lib/components/Modal/Modal.js +38 -3
  72. package/lib/components/MultiSelect/FilterableMultiSelect.js +17 -3
  73. package/lib/components/MultiSelect/MultiSelect.d.ts +5 -0
  74. package/lib/components/MultiSelect/MultiSelect.js +17 -3
  75. package/lib/components/NumberInput/NumberInput.d.ts +5 -0
  76. package/lib/components/NumberInput/NumberInput.js +28 -3
  77. package/lib/components/Select/Select.d.ts +6 -1
  78. package/lib/components/Select/Select.js +16 -2
  79. package/lib/components/Slug/index.js +199 -0
  80. package/lib/components/TextArea/TextArea.d.ts +4 -0
  81. package/lib/components/TextArea/TextArea.js +47 -31
  82. package/lib/components/TextInput/TextInput.d.ts +5 -0
  83. package/lib/components/TextInput/TextInput.js +16 -2
  84. package/lib/components/UIShell/SideNav.js +1 -1
  85. package/lib/components/UIShell/SideNavHeader.d.ts +29 -0
  86. package/lib/components/UIShell/SideNavHeader.js +3 -3
  87. package/lib/components/UIShell/Switcher.d.ts +38 -0
  88. package/lib/components/UIShell/Switcher.js +13 -12
  89. package/lib/components/UIShell/SwitcherDivider.d.ts +9 -0
  90. package/lib/components/UIShell/SwitcherDivider.js +4 -5
  91. package/lib/components/UIShell/SwitcherItem.d.ts +49 -0
  92. package/lib/components/UIShell/SwitcherItem.js +12 -16
  93. package/lib/index.d.ts +1 -0
  94. package/lib/index.js +45 -41
  95. package/lib/prop-types/tools/getDisplayName.js +38 -0
  96. package/package.json +6 -6
  97. package/scss/utilities/_ai-gradient.scss +9 -0
@@ -0,0 +1,187 @@
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
+
8
+ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
+ import cx from 'classnames';
10
+ import PropTypes from 'prop-types';
11
+ import React__default from 'react';
12
+ import { usePrefix } from '../../internal/usePrefix.js';
13
+ import { ToggletipContent, ToggletipActions, Toggletip, ToggletipButton } from '../Toggletip/index.js';
14
+ import { IconButton } from '../IconButton/index.js';
15
+ import { Undo } from '@carbon/icons-react';
16
+ import { useId } from '../../internal/useId.js';
17
+
18
+ var _Undo;
19
+ const SlugContent = /*#__PURE__*/React__default.forwardRef(function SlugContent(_ref, ref) {
20
+ let {
21
+ children,
22
+ className
23
+ } = _ref;
24
+ const prefix = usePrefix();
25
+ const slugContentClasses = cx(className, {
26
+ [`${prefix}--slug-content`]: true
27
+ });
28
+ return /*#__PURE__*/React__default.createElement(ToggletipContent, {
29
+ className: slugContentClasses,
30
+ ref: ref
31
+ }, children);
32
+ });
33
+ SlugContent.propTypes = {
34
+ /**
35
+ * Specify the content you want rendered inside the slug ToggleTip
36
+ */
37
+ children: PropTypes.node,
38
+ /**
39
+ * Specify an optional className to be added to the AI slug callout
40
+ */
41
+ className: PropTypes.string
42
+ };
43
+ const SlugActions = /*#__PURE__*/React__default.forwardRef(function SlugActions(_ref2, ref) {
44
+ let {
45
+ children,
46
+ className
47
+ } = _ref2;
48
+ const prefix = usePrefix();
49
+ const slugActionBarClasses = cx(className, {
50
+ [`${prefix}--slug-actions`]: true
51
+ });
52
+ return /*#__PURE__*/React__default.createElement(ToggletipActions, {
53
+ className: slugActionBarClasses,
54
+ ref: ref
55
+ }, children);
56
+ });
57
+ SlugActions.propTypes = {
58
+ /**
59
+ * Specify the content you want rendered inside the slug callout toolbar
60
+ */
61
+ children: PropTypes.node,
62
+ /**
63
+ * Specify an optional className to be added to the AI slug toolbar
64
+ */
65
+ className: PropTypes.string
66
+ };
67
+ const Slug = /*#__PURE__*/React__default.forwardRef(function Slug(_ref3, ref) {
68
+ let {
69
+ aiText = 'AI',
70
+ aiTextLabel,
71
+ align,
72
+ autoAlign = true,
73
+ children,
74
+ className,
75
+ dotType,
76
+ kind,
77
+ onRevertClick,
78
+ revertActive,
79
+ revertLabel = 'Revert to AI input',
80
+ slugLabel = 'Show information',
81
+ size = 'xs',
82
+ ...rest
83
+ } = _ref3;
84
+ const prefix = usePrefix();
85
+ const id = useId('slug');
86
+ const slugClasses = cx(className, {
87
+ [`${prefix}--slug`]: true,
88
+ [`${prefix}--slug--hollow`]: kind === 'hollow' || dotType === 'hollow',
89
+ // Need to come up with a better name; explainable?
90
+ // Need to be able to target the non-hollow variant another way
91
+ // other than using `:not` all over the styles
92
+ [`${prefix}--slug--enabled`]: kind !== 'hollow' && dotType !== 'hollow',
93
+ [`${prefix}--slug--revert`]: revertActive
94
+ });
95
+ const slugButtonClasses = cx({
96
+ [`${prefix}--slug__button`]: true,
97
+ [`${prefix}--slug__button--${size}`]: size,
98
+ [`${prefix}--slug__button--${kind}`]: kind,
99
+ [`${prefix}--slug__button--inline-with-content`]: kind === 'inline' && aiTextLabel
100
+ });
101
+ const handleOnRevertClick = evt => {
102
+ if (onRevertClick) {
103
+ onRevertClick(evt);
104
+ }
105
+ };
106
+ const ariaLabel = !aiTextLabel ? `${aiText} - ${slugLabel}` : `${aiText} - ${aiTextLabel}`;
107
+ return /*#__PURE__*/React__default.createElement("div", {
108
+ className: slugClasses,
109
+ ref: ref,
110
+ id: id
111
+ }, revertActive ? /*#__PURE__*/React__default.createElement(IconButton, _extends({
112
+ onClick: handleOnRevertClick,
113
+ kind: "ghost",
114
+ size: "sm",
115
+ label: revertLabel
116
+ }, rest), _Undo || (_Undo = /*#__PURE__*/React__default.createElement(Undo, null))) : /*#__PURE__*/React__default.createElement(Toggletip, _extends({
117
+ align: align,
118
+ autoAlign: autoAlign
119
+ }, rest), /*#__PURE__*/React__default.createElement(ToggletipButton, {
120
+ className: slugButtonClasses,
121
+ label: ariaLabel
122
+ }, /*#__PURE__*/React__default.createElement("span", {
123
+ className: `${prefix}--slug__text`
124
+ }, aiText), aiTextLabel && /*#__PURE__*/React__default.createElement("span", {
125
+ className: `${prefix}--slug__additional-text`
126
+ }, aiTextLabel)), children));
127
+ });
128
+ Slug.propTypes = {
129
+ /**
130
+ * Specify the correct translation of the AI text
131
+ */
132
+ aiText: PropTypes.string,
133
+ /**
134
+ * Specify additional text to be rendered next to the AI label in the inline variant
135
+ */
136
+ aiTextLabel: PropTypes.string,
137
+ /**
138
+ * Specify how the popover should align with the button
139
+ */
140
+ align: PropTypes.oneOf(['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'left-bottom', 'left-top', 'right', 'right-bottom', 'right-top']),
141
+ /**
142
+ * Will auto-align the popover on first render if it is not visible. This prop is currently experimental and is subject to future changes.
143
+ */
144
+ autoAlign: PropTypes.bool,
145
+ /**
146
+ * Specify the content you want rendered inside the slug ToggleTip
147
+ */
148
+ children: PropTypes.node,
149
+ /**
150
+ * Specify an optional className to be added to the AI slug
151
+ */
152
+ className: PropTypes.string,
153
+ /**
154
+ * Specify the type of dot that should be rendered in front of the inline variant
155
+ */
156
+ dotType: PropTypes.oneOf(['default', 'hollow']),
157
+ /**
158
+ * Specify the type of Slug, from the following list of types:
159
+ */
160
+ kind: PropTypes.oneOf(['default', 'hollow', 'inline']),
161
+ /**
162
+ * Callback function that fires when the revert button is clicked
163
+ */
164
+ onRevertClick: PropTypes.func,
165
+ /**
166
+ * Specify whether the revert button should be visible
167
+ */
168
+ revertActive: PropTypes.bool,
169
+ /**
170
+ * Specify the text that should be shown when the revert button is hovered
171
+ */
172
+ revertLabel: PropTypes.string,
173
+ /**
174
+ * Specify the size of the button, from the following list of sizes:
175
+ */
176
+ size: PropTypes.oneOf(['mini', '2xs', 'xs', 'sm', 'md', 'lg', 'xl']),
177
+ /**
178
+ * Specify the content you want rendered inside the slug ToggleTip
179
+ */
180
+ slugContent: PropTypes.node,
181
+ /**
182
+ * Specify the text that will be provided to the aria-label of the `Slug` button
183
+ */
184
+ slugLabel: PropTypes.string
185
+ };
186
+
187
+ export { Slug, SlugActions, SlugContent };
@@ -85,6 +85,10 @@ export interface TextAreaProps extends React.InputHTMLAttributes<HTMLTextAreaEle
85
85
  * Specify the rows attribute for the `<textarea>`
86
86
  */
87
87
  rows?: number;
88
+ /**
89
+ * Provide a `Slug` component to be rendered inside the `TextArea` component
90
+ */
91
+ slug?: ReactNodeLike;
88
92
  /**
89
93
  * Provide the current value of the `<textarea>`
90
94
  */
@@ -42,6 +42,7 @@ const TextArea = /*#__PURE__*/React__default.forwardRef((props, forwardRef) => {
42
42
  warn = false,
43
43
  warnText = '',
44
44
  rows = 4,
45
+ slug,
45
46
  ...other
46
47
  } = props;
47
48
  const prefix = usePrefix();
@@ -56,9 +57,19 @@ const TextArea = /*#__PURE__*/React__default.forwardRef((props, forwardRef) => {
56
57
  const {
57
58
  current: textAreaInstanceId
58
59
  } = useRef(getInstanceId());
60
+ const textareaRef = useRef(null);
61
+ const ref = useMergedRefs([forwardRef, textareaRef]);
59
62
  useEffect(() => {
60
63
  setTextCount(defaultValue?.toString()?.length || value?.toString()?.length || 0);
61
64
  }, [value, defaultValue]);
65
+ useIsomorphicEffect(() => {
66
+ if (other.cols && textareaRef.current) {
67
+ textareaRef.current.style.width = '';
68
+ textareaRef.current.style.resize = 'none';
69
+ } else if (textareaRef.current) {
70
+ textareaRef.current.style.width = `100%`;
71
+ }
72
+ }, [other.cols]);
62
73
  const textareaProps = {
63
74
  id,
64
75
  onChange: evt => {
@@ -77,29 +88,36 @@ const TextArea = /*#__PURE__*/React__default.forwardRef((props, forwardRef) => {
77
88
  }
78
89
  }
79
90
  };
80
- if (enableCounter) {
81
- textareaProps.maxLength = maxCount;
82
- }
83
- const ariaAnnouncement = useAnnouncer(textCount, maxCount);
91
+ const formItemClasses = cx(`${prefix}--form-item`, className);
92
+ const textAreaWrapperClasses = cx(`${prefix}--text-area__wrapper`, {
93
+ [`${prefix}--text-area__wrapper--readonly`]: other.readOnly,
94
+ [`${prefix}--text-area__wrapper--warn`]: warn,
95
+ [`${prefix}--text-area__wrapper--slug`]: slug
96
+ });
84
97
  const labelClasses = cx(`${prefix}--label`, {
85
98
  [`${prefix}--visually-hidden`]: hideLabel && !isFluid,
86
99
  [`${prefix}--label--disabled`]: disabled
87
100
  });
101
+ const textareaClasses = cx(`${prefix}--text-area`, {
102
+ [`${prefix}--text-area--light`]: light,
103
+ [`${prefix}--text-area--invalid`]: invalid,
104
+ [`${prefix}--text-area--warn`]: warn
105
+ });
106
+ const counterClasses = cx(`${prefix}--label`, {
107
+ [`${prefix}--label--disabled`]: disabled
108
+ });
109
+ const helperTextClasses = cx(`${prefix}--form__helper-text`, {
110
+ [`${prefix}--form__helper-text--disabled`]: disabled
111
+ });
88
112
  const label = labelText ? /*#__PURE__*/React__default.createElement(Text, {
89
113
  as: "label",
90
114
  htmlFor: id,
91
115
  className: labelClasses
92
116
  }, labelText) : null;
93
- const counterClasses = cx(`${prefix}--label`, {
94
- [`${prefix}--label--disabled`]: disabled
95
- });
96
117
  const counter = enableCounter && maxCount ? /*#__PURE__*/React__default.createElement(Text, {
97
118
  as: "div",
98
119
  className: counterClasses
99
120
  }, `${textCount}/${maxCount}`) : null;
100
- const helperTextClasses = cx(`${prefix}--form__helper-text`, {
101
- [`${prefix}--form__helper-text--disabled`]: disabled
102
- });
103
121
  const helperId = !helperText ? undefined : `text-area-helper-text-${textAreaInstanceId}`;
104
122
  const helper = helperText ? /*#__PURE__*/React__default.createElement(Text, {
105
123
  as: "div",
@@ -122,27 +140,16 @@ const TextArea = /*#__PURE__*/React__default.forwardRef((props, forwardRef) => {
122
140
  }, warnText, isFluid && /*#__PURE__*/React__default.createElement(WarningAltFilled, {
123
141
  className: `${prefix}--text-area__invalid-icon ${prefix}--text-area__invalid-icon--warning`
124
142
  })) : null;
125
- const textareaClasses = cx(`${prefix}--text-area`, {
126
- [`${prefix}--text-area--light`]: light,
127
- [`${prefix}--text-area--invalid`]: invalid,
128
- [`${prefix}--text-area--warn`]: warn
129
- });
130
- const textareaRef = useRef(null);
131
- const ref = useMergedRefs([forwardRef, textareaRef]);
132
- useIsomorphicEffect(() => {
133
- if (other.cols && textareaRef.current) {
134
- textareaRef.current.style.width = '';
135
- textareaRef.current.style.resize = 'none';
136
- } else if (textareaRef.current) {
137
- textareaRef.current.style.width = `100%`;
138
- }
139
- }, [other.cols]);
140
143
  let ariaDescribedBy;
141
144
  if (invalid) {
142
145
  ariaDescribedBy = errorId;
143
146
  } else if (!invalid && !warn && !isFluid && helperText) {
144
147
  ariaDescribedBy = helperId;
145
148
  }
149
+ if (enableCounter) {
150
+ textareaProps.maxLength = maxCount;
151
+ }
152
+ const ariaAnnouncement = useAnnouncer(textCount, maxCount);
146
153
  const input = /*#__PURE__*/React__default.createElement("textarea", _extends({}, other, textareaProps, {
147
154
  placeholder: placeholder,
148
155
  className: textareaClasses,
@@ -153,21 +160,26 @@ const TextArea = /*#__PURE__*/React__default.forwardRef((props, forwardRef) => {
153
160
  readOnly: other.readOnly,
154
161
  ref: ref
155
162
  }));
163
+
164
+ // Slug is always size `mini`
165
+ let normalizedSlug;
166
+ if (slug) {
167
+ normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
168
+ size: 'mini'
169
+ });
170
+ }
156
171
  return /*#__PURE__*/React__default.createElement("div", {
157
- className: cx(`${prefix}--form-item`, className)
172
+ className: formItemClasses
158
173
  }, /*#__PURE__*/React__default.createElement("div", {
159
174
  className: `${prefix}--text-area__label-wrapper`
160
175
  }, label, counter), /*#__PURE__*/React__default.createElement("div", {
161
- className: cx(`${prefix}--text-area__wrapper`, {
162
- [`${prefix}--text-area__wrapper--readonly`]: other.readOnly,
163
- [`${prefix}--text-area__wrapper--warn`]: warn
164
- }),
176
+ className: textAreaWrapperClasses,
165
177
  "data-invalid": invalid || null
166
178
  }, invalid && !isFluid && /*#__PURE__*/React__default.createElement(WarningFilled, {
167
179
  className: `${prefix}--text-area__invalid-icon`
168
180
  }), warn && !invalid && !isFluid && /*#__PURE__*/React__default.createElement(WarningAltFilled, {
169
181
  className: `${prefix}--text-area__invalid-icon ${prefix}--text-area__invalid-icon--warning`
170
- }), input, /*#__PURE__*/React__default.createElement("span", {
182
+ }), input, normalizedSlug, /*#__PURE__*/React__default.createElement("span", {
171
183
  className: `${prefix}--text-area__counter-alert`,
172
184
  role: "alert"
173
185
  }, ariaAnnouncement), isFluid && /*#__PURE__*/React__default.createElement("hr", {
@@ -253,6 +265,10 @@ TextArea.propTypes = {
253
265
  * Specify the rows attribute for the `<textarea>`
254
266
  */
255
267
  rows: PropTypes.number,
268
+ /**
269
+ * Provide a `Slug` component to be rendered inside the `TextArea` component
270
+ */
271
+ slug: PropTypes.node,
256
272
  /**
257
273
  * Provide the current value of the `<textarea>`
258
274
  */
@@ -4,6 +4,7 @@
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
+ import { ReactNodeLike } from 'prop-types';
7
8
  import React, { ReactNode } from 'react';
8
9
  type ExcludedAttributes = 'defaultValue' | 'id' | 'size' | 'value';
9
10
  export interface TextInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, ExcludedAttributes> {
@@ -85,6 +86,10 @@ export interface TextInputProps extends Omit<React.InputHTMLAttributes<HTMLInput
85
86
  * Specify the size of the Text Input. Currently supports the following:
86
87
  */
87
88
  size?: 'sm' | 'md' | 'lg' | 'xl';
89
+ /**
90
+ * Provide a `Slug` component to be rendered inside the `TextInput` component
91
+ */
92
+ slug?: ReactNodeLike;
88
93
  /**
89
94
  * Specify the type of the `<input>`
90
95
  */
@@ -42,6 +42,7 @@ const TextInput = /*#__PURE__*/React__default.forwardRef(function TextInput(_ref
42
42
  warnText,
43
43
  enableCounter = false,
44
44
  maxCount,
45
+ slug,
45
46
  ...rest
46
47
  } = _ref;
47
48
  const prefix = usePrefix();
@@ -113,7 +114,8 @@ const TextInput = /*#__PURE__*/React__default.forwardRef(function TextInput(_ref
113
114
  [`${prefix}--text-input__field-outer-wrapper--inline`]: inline
114
115
  });
115
116
  const fieldWrapperClasses = cx(`${prefix}--text-input__field-wrapper`, {
116
- [`${prefix}--text-input__field-wrapper--warning`]: normalizedProps.warn
117
+ [`${prefix}--text-input__field-wrapper--warning`]: normalizedProps.warn,
118
+ [`${prefix}--text-input__field-wrapper--slug`]: slug
117
119
  });
118
120
  const iconClasses = cx({
119
121
  [`${prefix}--text-input__invalid-icon`]: normalizedProps.invalid || normalizedProps.warn,
@@ -152,6 +154,14 @@ const TextInput = /*#__PURE__*/React__default.forwardRef(function TextInput(_ref
152
154
  } = useContext(FormContext);
153
155
  const ariaAnnouncement = useAnnouncer(textCount, maxCount);
154
156
  const Icon = normalizedProps.icon;
157
+
158
+ // Slug is always size `mini`
159
+ let normalizedSlug;
160
+ if (slug) {
161
+ normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
162
+ size: 'mini'
163
+ });
164
+ }
155
165
  return /*#__PURE__*/React__default.createElement("div", {
156
166
  className: inputWrapperClasses
157
167
  }, !inline ? labelWrapper : /*#__PURE__*/React__default.createElement("div", {
@@ -163,7 +173,7 @@ const TextInput = /*#__PURE__*/React__default.forwardRef(function TextInput(_ref
163
173
  "data-invalid": normalizedProps.invalid || null
164
174
  }, Icon && /*#__PURE__*/React__default.createElement(Icon, {
165
175
  className: iconClasses
166
- }), input, /*#__PURE__*/React__default.createElement("span", {
176
+ }), input, normalizedSlug, /*#__PURE__*/React__default.createElement("span", {
167
177
  className: `${prefix}--text-input__counter-alert`,
168
178
  role: "alert"
169
179
  }, ariaAnnouncement), isFluid && /*#__PURE__*/React__default.createElement("hr", {
@@ -250,6 +260,10 @@ TextInput.propTypes = {
250
260
  * Specify the size of the Text Input. Currently supports the following:
251
261
  */
252
262
  size: PropTypes.oneOf(['sm', 'md', 'lg']),
263
+ /**
264
+ * Provide a `Slug` component to be rendered inside the `TextInput` component
265
+ */
266
+ slug: PropTypes.node,
253
267
  /**
254
268
  * Specify the type of the `<input>`
255
269
  */
@@ -170,7 +170,7 @@ function SideNavRenderFunction(_ref, ref) {
170
170
  tabIndex: -1,
171
171
  ref: navRef,
172
172
  className: `${prefix}--side-nav__navigation ${className}`,
173
- inert: !isRail && (expanded || isLg ? undefined : -1)
173
+ inert: !isRail ? expanded || isLg ? undefined : -1 : undefined
174
174
  }, accessibilityLabel, eventHandlers, other), childrenToRender));
175
175
  }
176
176
  const SideNav = /*#__PURE__*/React__default.forwardRef(SideNavRenderFunction);
@@ -0,0 +1,29 @@
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 React from 'react';
8
+ interface SideNavHeaderProps {
9
+ /**
10
+ * The child nodes to be rendered
11
+ */
12
+ children?: React.ReactNode;
13
+ /**
14
+ * Provide an optional class to be applied to the containing node
15
+ */
16
+ className?: string;
17
+ /**
18
+ * Property to indicate if the side nav container is open (or not). Use to
19
+ * keep local state and styling in step with the SideNav expansion state.
20
+ */
21
+ isSideNavExpanded?: boolean;
22
+ /**
23
+ * Provide an icon to render in the header of the side navigation. Should be
24
+ * a React class.
25
+ */
26
+ renderIcon: React.ComponentType;
27
+ }
28
+ declare const SideNavHeader: React.FC<SideNavHeaderProps>;
29
+ export default SideNavHeader;
@@ -13,8 +13,8 @@ import { usePrefix } from '../../internal/usePrefix.js';
13
13
 
14
14
  const SideNavHeader = _ref => {
15
15
  let {
16
- className: customClassName,
17
16
  children,
17
+ className: customClassName,
18
18
  renderIcon: IconElement
19
19
  } = _ref;
20
20
  const prefix = usePrefix();
@@ -42,8 +42,8 @@ SideNavHeader.propTypes = {
42
42
  * Provide an icon to render in the header of the side navigation. Should be
43
43
  * a React class.
44
44
  */
45
+ // @ts-expect-error - PropTypes are unable to cover this case.
45
46
  renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired
46
47
  };
47
- var SideNavHeader$1 = SideNavHeader;
48
48
 
49
- export { SideNavHeader$1 as default };
49
+ export { SideNavHeader as default };
@@ -0,0 +1,38 @@
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
+ /**
8
+ * Copyright IBM Corp. 2016, 2023
9
+ *
10
+ * This source code is licensed under the Apache-2.0 license found in the
11
+ * LICENSE file in the root directory of this source tree.
12
+ */
13
+ import React, { ReactNode } from 'react';
14
+ interface BaseSwitcherProps {
15
+ /**
16
+ * expects to receive <SwitcherItem />
17
+ */
18
+ children: ReactNode;
19
+ /**
20
+ * Optionally provide a custom class to apply to the underlying `<ul>` node
21
+ */
22
+ className?: string;
23
+ /**
24
+ * Specify whether the panel is expanded
25
+ */
26
+ expanded?: boolean;
27
+ }
28
+ interface SwitcherWithAriaLabel extends BaseSwitcherProps {
29
+ 'aria-label': string;
30
+ 'aria-labelledby'?: never;
31
+ }
32
+ interface SwitcherWithAriaLabelledBy extends BaseSwitcherProps {
33
+ 'aria-label'?: never;
34
+ 'aria-labelledby': string;
35
+ }
36
+ type SwitcherProps = SwitcherWithAriaLabel | SwitcherWithAriaLabelledBy;
37
+ declare const Switcher: React.ForwardRefExoticComponent<SwitcherProps & React.RefAttributes<HTMLUListElement>>;
38
+ export default Switcher;
@@ -6,14 +6,15 @@
6
6
  */
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React__default, { useRef } from 'react';
9
+ import React__default, { forwardRef, useRef } from 'react';
10
10
  import cx from 'classnames';
11
- import PropTypes from 'prop-types';
12
- import { AriaLabelPropType } from '../../prop-types/AriaPropTypes.js';
13
11
  import { usePrefix } from '../../internal/usePrefix.js';
14
12
  import { useMergedRefs } from '../../internal/useMergedRefs.js';
13
+ import PropTypes from 'prop-types';
14
+ import { AriaLabelPropType } from '../../prop-types/AriaPropTypes.js';
15
+ import getDisplayName from '../../prop-types/tools/getDisplayName.js';
15
16
 
16
- const Switcher = /*#__PURE__*/React__default.forwardRef(function Switcher(props, forwardRef) {
17
+ const Switcher = /*#__PURE__*/forwardRef(function Switcher(props, forwardRef) {
17
18
  const switcherRef = useRef(null);
18
19
  const ref = useMergedRefs([switcherRef, forwardRef]);
19
20
  const prefix = usePrefix();
@@ -29,7 +30,7 @@ const Switcher = /*#__PURE__*/React__default.forwardRef(function Switcher(props,
29
30
  'aria-labelledby': ariaLabelledBy
30
31
  };
31
32
  const className = cx(`${prefix}--switcher`, {
32
- [customClassName]: !!customClassName
33
+ [customClassName || '']: !!customClassName
33
34
  });
34
35
  const handleSwitcherItemFocus = _ref => {
35
36
  let {
@@ -54,13 +55,14 @@ const Switcher = /*#__PURE__*/React__default.forwardRef(function Switcher(props,
54
55
  return enabledIndices[nextIndex];
55
56
  }
56
57
  })();
57
- const switcherItem = switcherRef.current.children[nextValidIndex].children[0];
58
- switcherItem?.focus();
58
+ const switcherItem = switcherRef.current?.children[nextValidIndex]?.children[0];
59
+ if (switcherItem) {
60
+ switcherItem.focus();
61
+ }
59
62
  };
60
- const childrenWithProps = React__default.Children.toArray(children).map((child, index) => {
61
- // handleSwitcherItemFocus should only be passed down if the child is a SwitcherItem
62
- // SwitcherDivider, for example, does not accept a handleSwitcherItemFocus prop
63
- if (child.type?.displayName === 'SwitcherItem') {
63
+ const childrenWithProps = React__default.Children.map(children, (child, index) => {
64
+ // only setup click handlers if onChange event is passed
65
+ if ( /*#__PURE__*/React__default.isValidElement(child) && child.type && getDisplayName(child.type) === 'Switcher') {
64
66
  return /*#__PURE__*/React__default.cloneElement(child, {
65
67
  handleSwitcherItemFocus,
66
68
  index,
@@ -98,6 +100,5 @@ Switcher.propTypes = {
98
100
  */
99
101
  expanded: PropTypes.bool
100
102
  };
101
- var Switcher$1 = Switcher;
102
103
 
103
- export { Switcher$1 as default };
104
+ export { Switcher as default };
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ interface SwitcherDividerProps {
3
+ /**
4
+ * Optionally provide a custom class to apply to the underlying `<li>` node
5
+ */
6
+ className?: string;
7
+ }
8
+ declare const SwitcherDivider: React.FC<SwitcherDividerProps>;
9
+ export default SwitcherDivider;
@@ -17,11 +17,11 @@ const SwitcherDivider = _ref => {
17
17
  ...other
18
18
  } = _ref;
19
19
  const prefix = usePrefix();
20
- const className = cx(`${prefix}--switcher__item--divider`, {
21
- [customClassName]: !!customClassName
20
+ const classNames = cx(`${prefix}--switcher__item--divider`, {
21
+ [customClassName || '']: !!customClassName
22
22
  });
23
23
  return /*#__PURE__*/React__default.createElement("hr", _extends({}, other, {
24
- className: className
24
+ className: classNames
25
25
  }));
26
26
  };
27
27
  SwitcherDivider.propTypes = {
@@ -30,6 +30,5 @@ SwitcherDivider.propTypes = {
30
30
  */
31
31
  className: PropTypes.string
32
32
  };
33
- var SwitcherDivider$1 = SwitcherDivider;
34
33
 
35
- export { SwitcherDivider$1 as default };
34
+ export { SwitcherDivider as default };
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ interface BaseSwitcherItemProps {
3
+ /**
4
+ * Specify the text content for the link
5
+ */
6
+ children: React.ReactNode;
7
+ /**
8
+ * Optionally provide a custom class to apply to the underlying `<li>` node
9
+ */
10
+ className?: string;
11
+ /**
12
+ * event handlers
13
+ */
14
+ handleSwitcherItemFocus?: (event: {
15
+ currentIndex: number;
16
+ direction: number;
17
+ }) => void;
18
+ /**
19
+ * Specify the index of the SwitcherItem
20
+ */
21
+ index?: number;
22
+ /**
23
+ * event handlers
24
+ */
25
+ onKeyDown?: (event: KeyboardEvent) => void;
26
+ /**
27
+ * Specify the tab index of the Link
28
+ */
29
+ tabIndex?: number;
30
+ /**
31
+ * Specify whether the panel is expanded
32
+ */
33
+ expanded?: boolean;
34
+ /**
35
+ * Specify whether the panel is selected
36
+ */
37
+ isSelected?: boolean;
38
+ }
39
+ interface SwitcherItemWithAriaLabel extends BaseSwitcherItemProps {
40
+ 'aria-label': string;
41
+ 'aria-labelledby'?: never;
42
+ }
43
+ interface SwitcherItemWithAriaLabelledBy extends BaseSwitcherItemProps {
44
+ 'aria-label'?: never;
45
+ 'aria-labelledby': string;
46
+ }
47
+ type SwitcherItemProps = SwitcherItemWithAriaLabel | SwitcherItemWithAriaLabelledBy;
48
+ declare const SwitcherItem: React.ForwardRefExoticComponent<SwitcherItemProps & React.RefAttributes<React.ElementType<any>>>;
49
+ export default SwitcherItem;