@carbon/react 1.31.3 → 1.32.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 (190) hide show
  1. package/README.md +1 -1
  2. package/es/components/Accordion/Accordion.Skeleton.d.ts +64 -0
  3. package/es/components/Accordion/Accordion.Skeleton.js +3 -3
  4. package/es/components/Accordion/Accordion.d.ts +65 -0
  5. package/es/components/Accordion/Accordion.js +5 -6
  6. package/es/components/Accordion/AccordionItem.d.ts +105 -0
  7. package/es/components/Accordion/AccordionItem.js +12 -9
  8. package/es/components/Accordion/AccordionProvider.d.ts +20 -0
  9. package/es/components/Accordion/AccordionProvider.js +25 -0
  10. package/es/components/Accordion/index.d.ts +11 -0
  11. package/es/components/Button/Button.Skeleton.d.ts +28 -0
  12. package/es/components/Button/Button.Skeleton.js +5 -3
  13. package/es/components/Button/Button.d.ts +72 -0
  14. package/es/components/Button/Button.js +13 -10
  15. package/es/components/Button/index.d.ts +11 -0
  16. package/es/components/Button/index.js +2 -1
  17. package/es/components/ButtonSet/ButtonSet.d.ts +17 -0
  18. package/es/components/ButtonSet/ButtonSet.js +1 -2
  19. package/es/components/ButtonSet/index.d.ts +9 -0
  20. package/es/components/CodeSnippet/CodeSnippet.js +1 -0
  21. package/es/components/ComboButton/index.js +1 -0
  22. package/es/components/ComposedModal/ComposedModal.d.ts +70 -0
  23. package/es/components/ComposedModal/ComposedModal.js +58 -67
  24. package/es/components/ComposedModal/ModalFooter.d.ts +71 -0
  25. package/es/components/ComposedModal/ModalFooter.js +22 -19
  26. package/es/components/ComposedModal/ModalHeader.d.ts +58 -0
  27. package/es/components/ComposedModal/ModalHeader.js +8 -25
  28. package/es/components/ComposedModal/index.d.ts +9 -0
  29. package/es/components/ContainedList/ContainedList.js +12 -1
  30. package/es/components/ContentSwitcher/ContentSwitcher.d.ts +109 -0
  31. package/es/components/ContentSwitcher/ContentSwitcher.js +14 -6
  32. package/es/components/DangerButton/DangerButton.d.ts +9 -0
  33. package/es/components/DangerButton/DangerButton.js +2 -2
  34. package/es/components/DangerButton/index.d.ts +9 -0
  35. package/es/components/DataTable/TableBatchAction.js +1 -0
  36. package/es/components/DataTable/TableBatchActions.js +1 -0
  37. package/es/components/DataTable/TableBody.d.ts +29 -0
  38. package/es/components/DataTable/TableBody.js +2 -3
  39. package/es/components/DataTable/TableContainer.d.ts +51 -0
  40. package/es/components/DataTable/TableContainer.js +3 -4
  41. package/es/components/DataTable/TableExpandHeader.d.ts +86 -0
  42. package/es/components/DataTable/TableExpandHeader.js +4 -5
  43. package/es/components/DatePicker/plugins/fixEventsPlugin.js +12 -16
  44. package/es/components/Dropdown/Dropdown.js +1 -0
  45. package/es/components/FluidTextInput/FluidTextInput.js +1 -0
  46. package/es/components/FormGroup/FormGroup.d.ts +80 -0
  47. package/es/components/IconButton/index.js +3 -2
  48. package/es/components/Layout/index.d.ts +74 -0
  49. package/es/components/Layout/index.js +14 -5
  50. package/es/components/Link/Link.d.ts +2 -2
  51. package/es/components/Link/Link.js +2 -1
  52. package/es/components/MenuButton/index.js +1 -0
  53. package/es/components/Modal/Modal.js +1 -0
  54. package/es/components/ModalWrapper/ModalWrapper.js +1 -0
  55. package/es/components/Notification/Notification.d.ts +531 -0
  56. package/es/components/Notification/Notification.js +40 -6
  57. package/es/components/Notification/index.d.ts +7 -0
  58. package/es/components/PrimaryButton/PrimaryButton.js +1 -0
  59. package/es/components/SecondaryButton/SecondaryButton.js +1 -0
  60. package/es/components/Select/Select.d.ts +1 -1
  61. package/es/components/SkeletonText/SkeletonText.d.ts +61 -0
  62. package/es/components/SkeletonText/SkeletonText.js +15 -17
  63. package/es/components/SkeletonText/index.d.ts +9 -0
  64. package/es/components/Switch/Switch.d.ts +56 -0
  65. package/es/components/Switch/Switch.js +4 -4
  66. package/es/components/Tab/index.d.ts +9 -0
  67. package/es/components/TabContent/TabContent.d.ts +40 -0
  68. package/es/components/TabContent/TabContent.js +6 -12
  69. package/es/components/TabContent/index.d.ts +10 -0
  70. package/es/components/Tabs/Tabs.Skeleton.d.ts +33 -0
  71. package/es/components/Tabs/Tabs.Skeleton.js +2 -2
  72. package/es/components/Tabs/Tabs.d.ts +311 -0
  73. package/es/components/Tabs/Tabs.js +151 -97
  74. package/es/components/Tabs/index.d.ts +10 -0
  75. package/es/components/Tabs/usePressable.js +11 -0
  76. package/es/components/TextInput/ControlledPasswordInput.d.ts +90 -0
  77. package/es/components/TextInput/ControlledPasswordInput.js +5 -6
  78. package/es/components/Tile/Tile.d.ts +153 -0
  79. package/es/components/Tile/Tile.js +62 -74
  80. package/es/components/Tile/index.d.ts +7 -0
  81. package/es/components/Toggle/Toggle.Skeleton.d.ts +3 -47
  82. package/es/components/Toggle/Toggle.Skeleton.js +24 -64
  83. package/es/components/Toggle/Toggle.js +1 -1
  84. package/es/components/UIShell/HeaderGlobalAction.js +1 -0
  85. package/es/components/UIShell/HeaderPanel.js +61 -5
  86. package/es/components/UIShell/SideNav.d.ts +1 -1
  87. package/es/components/UIShell/Switcher.js +45 -5
  88. package/es/components/UIShell/SwitcherItem.js +45 -6
  89. package/es/index.js +16 -16
  90. package/es/internal/keyboard/match.js +2 -2
  91. package/es/internal/useControllableState.js +2 -2
  92. package/es/internal/useMatchMedia.js +44 -0
  93. package/es/internal/wrapFocus.js +6 -6
  94. package/es/prop-types/requiredIfGivenPropIsTruthy.js +1 -1
  95. package/es/prop-types/types.js +3 -0
  96. package/lib/components/Accordion/Accordion.Skeleton.d.ts +64 -0
  97. package/lib/components/Accordion/Accordion.Skeleton.js +3 -3
  98. package/lib/components/Accordion/Accordion.d.ts +65 -0
  99. package/lib/components/Accordion/Accordion.js +5 -6
  100. package/lib/components/Accordion/AccordionItem.d.ts +105 -0
  101. package/lib/components/Accordion/AccordionItem.js +11 -8
  102. package/lib/components/Accordion/AccordionProvider.d.ts +20 -0
  103. package/lib/components/Accordion/AccordionProvider.js +34 -0
  104. package/lib/components/Accordion/index.d.ts +11 -0
  105. package/lib/components/Button/Button.Skeleton.d.ts +28 -0
  106. package/lib/components/Button/Button.Skeleton.js +5 -3
  107. package/lib/components/Button/Button.d.ts +72 -0
  108. package/lib/components/Button/Button.js +18 -11
  109. package/lib/components/Button/index.d.ts +11 -0
  110. package/lib/components/Button/index.js +6 -0
  111. package/lib/components/ButtonSet/ButtonSet.d.ts +17 -0
  112. package/lib/components/ButtonSet/ButtonSet.js +1 -2
  113. package/lib/components/ButtonSet/index.d.ts +9 -0
  114. package/lib/components/CodeSnippet/CodeSnippet.js +1 -0
  115. package/lib/components/ComboButton/index.js +1 -0
  116. package/lib/components/ComposedModal/ComposedModal.d.ts +70 -0
  117. package/lib/components/ComposedModal/ComposedModal.js +58 -67
  118. package/lib/components/ComposedModal/ModalFooter.d.ts +71 -0
  119. package/lib/components/ComposedModal/ModalFooter.js +22 -19
  120. package/lib/components/ComposedModal/ModalHeader.d.ts +58 -0
  121. package/lib/components/ComposedModal/ModalHeader.js +8 -25
  122. package/lib/components/ComposedModal/index.d.ts +9 -0
  123. package/lib/components/ContainedList/ContainedList.js +12 -1
  124. package/lib/components/ContentSwitcher/ContentSwitcher.d.ts +109 -0
  125. package/lib/components/ContentSwitcher/ContentSwitcher.js +14 -6
  126. package/lib/components/DangerButton/DangerButton.d.ts +9 -0
  127. package/lib/components/DangerButton/DangerButton.js +2 -2
  128. package/lib/components/DangerButton/index.d.ts +9 -0
  129. package/lib/components/DataTable/TableBatchAction.js +1 -0
  130. package/lib/components/DataTable/TableBatchActions.js +1 -0
  131. package/lib/components/DataTable/TableBody.d.ts +29 -0
  132. package/lib/components/DataTable/TableBody.js +3 -4
  133. package/lib/components/DataTable/TableContainer.d.ts +51 -0
  134. package/lib/components/DataTable/TableContainer.js +3 -4
  135. package/lib/components/DataTable/TableExpandHeader.d.ts +86 -0
  136. package/lib/components/DataTable/TableExpandHeader.js +4 -5
  137. package/lib/components/DatePicker/plugins/fixEventsPlugin.js +12 -16
  138. package/lib/components/Dropdown/Dropdown.js +1 -0
  139. package/lib/components/FluidTextInput/FluidTextInput.js +1 -0
  140. package/lib/components/FormGroup/FormGroup.d.ts +80 -0
  141. package/lib/components/IconButton/index.js +3 -2
  142. package/lib/components/Layout/index.d.ts +74 -0
  143. package/lib/components/Layout/index.js +14 -5
  144. package/lib/components/Link/Link.d.ts +2 -2
  145. package/lib/components/Link/Link.js +2 -1
  146. package/lib/components/MenuButton/index.js +1 -0
  147. package/lib/components/Modal/Modal.js +1 -0
  148. package/lib/components/ModalWrapper/ModalWrapper.js +1 -0
  149. package/lib/components/Notification/Notification.d.ts +531 -0
  150. package/lib/components/Notification/Notification.js +40 -6
  151. package/lib/components/Notification/index.d.ts +7 -0
  152. package/lib/components/PrimaryButton/PrimaryButton.js +1 -0
  153. package/lib/components/SecondaryButton/SecondaryButton.js +1 -0
  154. package/lib/components/Select/Select.d.ts +1 -1
  155. package/lib/components/SkeletonText/SkeletonText.d.ts +61 -0
  156. package/lib/components/SkeletonText/SkeletonText.js +15 -17
  157. package/lib/components/SkeletonText/index.d.ts +9 -0
  158. package/lib/components/Switch/Switch.d.ts +56 -0
  159. package/lib/components/Switch/Switch.js +4 -4
  160. package/lib/components/Tab/index.d.ts +9 -0
  161. package/lib/components/TabContent/TabContent.d.ts +40 -0
  162. package/lib/components/TabContent/TabContent.js +6 -12
  163. package/lib/components/TabContent/index.d.ts +10 -0
  164. package/lib/components/Tabs/Tabs.Skeleton.d.ts +33 -0
  165. package/lib/components/Tabs/Tabs.Skeleton.js +2 -2
  166. package/lib/components/Tabs/Tabs.d.ts +311 -0
  167. package/lib/components/Tabs/Tabs.js +150 -96
  168. package/lib/components/Tabs/index.d.ts +10 -0
  169. package/lib/components/Tabs/usePressable.js +11 -0
  170. package/lib/components/TextInput/ControlledPasswordInput.d.ts +90 -0
  171. package/lib/components/TextInput/ControlledPasswordInput.js +5 -6
  172. package/lib/components/Tile/Tile.d.ts +153 -0
  173. package/lib/components/Tile/Tile.js +62 -74
  174. package/lib/components/Tile/index.d.ts +7 -0
  175. package/lib/components/Toggle/Toggle.Skeleton.d.ts +3 -47
  176. package/lib/components/Toggle/Toggle.Skeleton.js +22 -62
  177. package/lib/components/Toggle/Toggle.js +1 -1
  178. package/lib/components/UIShell/HeaderGlobalAction.js +1 -0
  179. package/lib/components/UIShell/HeaderPanel.js +60 -4
  180. package/lib/components/UIShell/SideNav.d.ts +1 -1
  181. package/lib/components/UIShell/Switcher.js +44 -4
  182. package/lib/components/UIShell/SwitcherItem.js +45 -6
  183. package/lib/index.js +51 -47
  184. package/lib/internal/keyboard/match.js +2 -2
  185. package/lib/internal/useControllableState.js +2 -2
  186. package/lib/internal/useMatchMedia.js +48 -0
  187. package/lib/internal/wrapFocus.js +6 -6
  188. package/lib/prop-types/requiredIfGivenPropIsTruthy.js +1 -1
  189. package/lib/prop-types/types.js +3 -0
  190. package/package.json +4 -3
@@ -0,0 +1,70 @@
1
+ import React, { type MouseEvent, type KeyboardEvent, type HTMLAttributes, type ReactNode } from 'react';
2
+ export interface ModalBodyProps extends HTMLAttributes<HTMLDivElement> {
3
+ /** Specify the content to be placed in the ModalBody. */
4
+ children?: ReactNode;
5
+ /**
6
+ * Provide whether the modal content has a form element.
7
+ * If `true` is used here, non-form child content should have `bx--modal-content__regular-content` class.
8
+ */
9
+ hasForm?: boolean;
10
+ /**
11
+ * Specify whether the modal contains scrolling content
12
+ */
13
+ hasScrollingContent?: boolean;
14
+ }
15
+ export declare const ModalBody: React.ForwardRefExoticComponent<ModalBodyProps & React.RefAttributes<HTMLDivElement>>;
16
+ export interface ComposedModalProps extends HTMLAttributes<HTMLDivElement> {
17
+ /**
18
+ * Specify the aria-label for bx--modal-container
19
+ */
20
+ 'aria-label'?: string;
21
+ /**
22
+ * Specify the aria-labelledby for bx--modal-container
23
+ */
24
+ 'aria-labelledby'?: string;
25
+ /**
26
+ * Specify the content to be placed in the ComposedModal
27
+ */
28
+ children?: ReactNode;
29
+ /**
30
+ * Specify an optional className to be applied to the modal root node
31
+ */
32
+ className?: string;
33
+ /**
34
+ * Specify an optional className to be applied to the modal node
35
+ */
36
+ containerClassName?: string;
37
+ /**
38
+ * Specify whether the primary button should be replaced with danger button.
39
+ * Note that this prop is not applied if you render primary/danger button by yourself
40
+ */
41
+ danger?: boolean;
42
+ /**
43
+ * Specify whether the Modal content should have any inner padding.
44
+ */
45
+ isFullWidth?: boolean;
46
+ /**
47
+ * Specify an optional handler for closing modal.
48
+ * Returning `false` here prevents closing modal.
49
+ */
50
+ onClose?(event: MouseEvent): void | boolean;
51
+ /**
52
+ * Called for all `onKeyDown` events that do not close the modal
53
+ */
54
+ onKeyDown?(evt: KeyboardEvent): void;
55
+ /**
56
+ * Specify whether the Modal is currently open
57
+ */
58
+ open?: boolean;
59
+ preventCloseOnClickOutside?: boolean;
60
+ /**
61
+ * Specify a CSS selector that matches the DOM element that should be
62
+ * focused when the Modal opens
63
+ */
64
+ selectorPrimaryFocus?: string;
65
+ /** Specify the CSS selectors that match the floating menus. */
66
+ selectorsFloatingMenus?: Array<string | null | undefined>;
67
+ size?: 'xs' | 'sm' | 'md' | 'lg';
68
+ }
69
+ declare const ComposedModal: React.ForwardRefExoticComponent<ComposedModalProps & React.RefAttributes<HTMLDivElement>>;
70
+ export default ComposedModal;
@@ -11,6 +11,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
11
11
 
12
12
  var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
13
13
  var React = require('react');
14
+ var reactIs = require('react-is');
14
15
  var PropTypes = require('prop-types');
15
16
  var ModalHeader = require('./ModalHeader.js');
16
17
  var ModalFooter = require('./ModalFooter.js');
@@ -19,6 +20,8 @@ var toggleClass = require('../../tools/toggleClass.js');
19
20
  var requiredIfGivenPropIsTruthy = require('../../prop-types/requiredIfGivenPropIsTruthy.js');
20
21
  var wrapFocus = require('../../internal/wrapFocus.js');
21
22
  var usePrefix = require('../../internal/usePrefix.js');
23
+ var match = require('../../internal/keyboard/match.js');
24
+ var keys = require('../../internal/keyboard/keys.js');
22
25
 
23
26
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
24
27
 
@@ -35,12 +38,7 @@ const ModalBody = /*#__PURE__*/React__default["default"].forwardRef(function Mod
35
38
  ...rest
36
39
  } = _ref;
37
40
  const prefix = usePrefix.usePrefix();
38
- const contentClass = cx__default["default"]({
39
- [`${prefix}--modal-content`]: true,
40
- [`${prefix}--modal-content--with-form`]: hasForm,
41
- [`${prefix}--modal-scroll-content`]: hasScrollingContent,
42
- [customClassName]: customClassName
43
- });
41
+ const contentClass = cx__default["default"](`${prefix}--modal-content`, hasForm && `${prefix}--modal-content--with-form`, hasScrollingContent && `${prefix}--modal-scroll-content`, customClassName);
44
42
  const hasScrollingContentProps = hasScrollingContent ? {
45
43
  tabIndex: 0,
46
44
  role: 'region'
@@ -57,6 +55,7 @@ ModalBody.propTypes = {
57
55
  /**
58
56
  * Required props for the accessibility label of the header
59
57
  */
58
+ // @ts-expect-error: Built-in prop-types > TS logic doesn't jive well with custom validators
60
59
  ['aria-label']: requiredIfGivenPropIsTruthy["default"]('hasScrollingContent', PropTypes__default["default"].string),
61
60
  /**
62
61
  * Specify the content to be placed in the ModalBody
@@ -95,28 +94,38 @@ const ComposedModal = /*#__PURE__*/React__default["default"].forwardRef(function
95
94
  ...rest
96
95
  } = _ref2;
97
96
  const prefix = usePrefix.usePrefix();
98
- const [isOpen, setisOpen] = React.useState(open);
99
- const [prevOpen, setPrevOpen] = React.useState(open);
100
- const innerModal = React.useRef();
101
- const button = React.useRef();
102
- const startSentinel = React.useRef();
103
- const endSentinel = React.useRef();
104
- if (open !== prevOpen) {
105
- setisOpen(open);
106
- setPrevOpen(open);
107
- }
97
+ const [isOpen, setIsOpen] = React.useState(!!open);
98
+ const [wasOpen, setWasOpen] = React.useState(!!open);
99
+ const innerModal = React.useRef(null);
100
+ const button = React.useRef(null);
101
+ const startSentinel = React.useRef(null);
102
+ const endSentinel = React.useRef(null);
103
+
104
+ // Kepp track of modal open/close state
105
+ // and propagate it to the document.body
106
+ React.useEffect(() => {
107
+ if (open !== wasOpen) {
108
+ setIsOpen(!!open);
109
+ setWasOpen(!!open);
110
+ toggleClass["default"](document.body, `${prefix}--body--with-modal-open`, !!open);
111
+ }
112
+ }, [open, wasOpen, prefix]);
113
+ // Remove the document.body className on unmount
114
+ React.useEffect(() => {
115
+ return () => {
116
+ toggleClass["default"](document.body, `${prefix}--body--with-modal-open`, false);
117
+ };
118
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
119
+
108
120
  function handleKeyDown(evt) {
109
- // Esc key
110
- if (evt.which === 27) {
121
+ if (match.match(evt, keys.Escape)) {
111
122
  closeModal(evt);
112
123
  }
113
- onKeyDown(evt);
124
+ onKeyDown?.(evt);
114
125
  }
115
126
  function handleMousedown(evt) {
116
- if (!innerModal.current.contains(evt.target) && preventCloseOnClickOutside) {
117
- return;
118
- }
119
- if (innerModal.current && !innerModal.current.contains(evt.target)) {
127
+ const isInside = innerModal.current?.contains(evt.target);
128
+ if (!isInside && !preventCloseOnClickOutside) {
120
129
  closeModal(evt);
121
130
  }
122
131
  }
@@ -125,7 +134,7 @@ const ComposedModal = /*#__PURE__*/React__default["default"].forwardRef(function
125
134
  target: oldActiveNode,
126
135
  relatedTarget: currentActiveNode
127
136
  } = _ref3;
128
- if (open && currentActiveNode && oldActiveNode) {
137
+ if (open && currentActiveNode && oldActiveNode && innerModal.current) {
129
138
  const {
130
139
  current: bodyNode
131
140
  } = innerModal;
@@ -137,62 +146,46 @@ const ComposedModal = /*#__PURE__*/React__default["default"].forwardRef(function
137
146
  } = endSentinel;
138
147
  wrapFocus["default"]({
139
148
  bodyNode,
140
- startSentinelNode,
141
- endSentinelNode,
149
+ startTrapNode: startSentinelNode,
150
+ endTrapNode: endSentinelNode,
142
151
  currentActiveNode,
143
152
  oldActiveNode,
144
- selectorsFloatingMenus
153
+ selectorsFloatingMenus: selectorsFloatingMenus?.filter(Boolean)
145
154
  });
146
155
  }
147
156
  }
148
157
  function closeModal(evt) {
149
158
  if (!onClose || onClose(evt) !== false) {
150
- setisOpen(false);
159
+ setIsOpen(false);
151
160
  }
152
161
  }
153
- const modalClass = cx__default["default"]({
154
- [`${prefix}--modal`]: true,
155
- 'is-visible': isOpen,
156
- [customClassName]: customClassName,
157
- [`${prefix}--modal--danger`]: danger
158
- });
159
- const containerClass = cx__default["default"]({
160
- [`${prefix}--modal-container`]: true,
161
- [`${prefix}--modal-container--${size}`]: size,
162
- [`${prefix}--modal-container--full-width`]: isFullWidth,
163
- [containerClassName]: containerClassName
164
- });
162
+ const modalClass = cx__default["default"](`${prefix}--modal`, isOpen && 'is-visible', danger && `${prefix}--modal--danger`, customClassName);
163
+ const containerClass = cx__default["default"](`${prefix}--modal-container`, size && `${prefix}--modal-container--${size}`, isFullWidth && `${prefix}--modal-container--full-width`, containerClassName);
165
164
 
166
165
  // Generate aria-label based on Modal Header label if one is not provided (L253)
167
166
  let generatedAriaLabel;
168
167
  const childrenWithProps = React__default["default"].Children.toArray(children).map(child => {
169
- switch (child.type) {
170
- case React__default["default"].createElement(ModalHeader.ModalHeader).type:
171
- generatedAriaLabel = child.props.label;
172
- return /*#__PURE__*/React__default["default"].cloneElement(child, {
173
- closeModal: closeModal
174
- });
175
- case React__default["default"].createElement(ModalFooter.ModalFooter).type:
176
- return /*#__PURE__*/React__default["default"].cloneElement(child, {
177
- closeModal: closeModal,
178
- inputref: button
179
- });
168
+ switch (true) {
169
+ case reactIs.isElement(child) && child.type === React__default["default"].createElement(ModalHeader.ModalHeader).type:
170
+ {
171
+ const el = child;
172
+ generatedAriaLabel = el.props.label;
173
+ return /*#__PURE__*/React__default["default"].cloneElement(el, {
174
+ closeModal
175
+ });
176
+ }
177
+ case reactIs.isElement(child) && child.type === React__default["default"].createElement(ModalFooter.ModalFooter).type:
178
+ {
179
+ const el = child;
180
+ return /*#__PURE__*/React__default["default"].cloneElement(el, {
181
+ closeModal,
182
+ inputref: button
183
+ });
184
+ }
180
185
  default:
181
186
  return child;
182
187
  }
183
188
  });
184
- React.useEffect(() => {
185
- if (prevOpen !== isOpen) {
186
- toggleClass["default"](document.body, `${prefix}--body--with-modal-open`, isOpen);
187
- }
188
- });
189
- React.useEffect(() => {
190
- return () => toggleClass["default"](document.body, `${prefix}--body--with-modal-open`, false);
191
- }, []); // eslint-disable-line react-hooks/exhaustive-deps
192
-
193
- React.useEffect(() => {
194
- toggleClass["default"](document.body, `${prefix}--body--with-modal-open`, open);
195
- }, [open, prefix]);
196
189
  React.useEffect(() => {
197
190
  const focusButton = focusContainerElement => {
198
191
  if (focusContainerElement) {
@@ -267,7 +260,7 @@ ComposedModal.propTypes = {
267
260
  */
268
261
  danger: PropTypes__default["default"].bool,
269
262
  /**
270
- * Specify whether or not the Modal content should have any inner padding.
263
+ * Specify whether the Modal content should have any inner padding.
271
264
  */
272
265
  isFullWidth: PropTypes__default["default"].bool,
273
266
  /**
@@ -300,10 +293,8 @@ ComposedModal.propTypes = {
300
293
  size: PropTypes__default["default"].oneOf(['xs', 'sm', 'md', 'lg'])
301
294
  };
302
295
  ComposedModal.defaultProps = {
303
- onKeyDown: () => {},
304
296
  selectorPrimaryFocus: '[data-modal-primary-focus]'
305
297
  };
306
- var ComposedModal$1 = ComposedModal;
307
298
 
308
299
  exports.ModalBody = ModalBody;
309
- exports["default"] = ComposedModal$1;
300
+ exports["default"] = ComposedModal;
@@ -0,0 +1,71 @@
1
+ import React, { type ReactNode, type MouseEvent, type Ref } from 'react';
2
+ interface SecondaryButtonProps {
3
+ buttonText: ReactNode;
4
+ onClick(evt: MouseEvent): void;
5
+ }
6
+ export interface SecondaryButtonSetProps {
7
+ closeModal(evt: MouseEvent): void;
8
+ onRequestClose(evt: MouseEvent): void;
9
+ secondaryButtonText?: string;
10
+ secondaryButtons?: [SecondaryButtonProps, SecondaryButtonProps];
11
+ secondaryClassName?: string;
12
+ }
13
+ export interface ModalFooterProps {
14
+ /**
15
+ * Pass in content that will be rendered in the Modal Footer
16
+ */
17
+ children: ReactNode;
18
+ /**
19
+ * Specify a custom className to be applied to the Modal Footer container
20
+ */
21
+ className?: string;
22
+ /**
23
+ * Specify an optional function that is called whenever the modal is closed
24
+ */
25
+ closeModal?(evt: MouseEvent): void;
26
+ /**
27
+ * Specify whether the primary button should be replaced with danger button.
28
+ * Note that this prop is not applied if you render primary/danger button by yourself
29
+ */
30
+ danger?: boolean;
31
+ /**
32
+ * The `ref` callback for the primary button.
33
+ */
34
+ inputref?: Ref<HTMLButtonElement>;
35
+ /**
36
+ * Specify an optional function for when the modal is requesting to be
37
+ * closed
38
+ */
39
+ onRequestClose?(): void;
40
+ /**
41
+ * Specify an optional function for when the modal is requesting to be
42
+ * submitted
43
+ */
44
+ onRequestSubmit?(): void;
45
+ /**
46
+ * Specify whether the primary button should be disabled
47
+ */
48
+ primaryButtonDisabled?: boolean;
49
+ /**
50
+ * Specify the text for the primary button
51
+ */
52
+ primaryButtonText?: string;
53
+ /**
54
+ * Specify a custom className to be applied to the primary button
55
+ */
56
+ primaryClassName?: string;
57
+ /**
58
+ * Specify the text for the secondary button
59
+ */
60
+ secondaryButtonText?: string;
61
+ /**
62
+ * Specify an array of config objects for secondary buttons
63
+ */
64
+ secondaryButtons?: [SecondaryButtonProps, SecondaryButtonProps];
65
+ /**
66
+ * Specify a custom className to be applied to the secondary button
67
+ */
68
+ secondaryClassName?: string;
69
+ }
70
+ export declare const ModalFooter: React.ForwardRefExoticComponent<ModalFooterProps & React.RefAttributes<HTMLElement>>;
71
+ export {};
@@ -13,6 +13,7 @@ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelper
13
13
  var React = require('react');
14
14
  var PropTypes = require('prop-types');
15
15
  var Button = require('../Button/Button.js');
16
+ require('../Button/Button.Skeleton.js');
16
17
  var ButtonSet = require('../ButtonSet/ButtonSet.js');
17
18
  var cx = require('classnames');
18
19
  var usePrefix = require('../../internal/usePrefix.js');
@@ -97,11 +98,7 @@ const ModalFooter = /*#__PURE__*/React__default["default"].forwardRef(function M
97
98
  ...rest
98
99
  } = _ref3;
99
100
  const prefix = usePrefix.usePrefix();
100
- const footerClass = cx__default["default"]({
101
- [`${prefix}--modal-footer`]: true,
102
- [customClassName]: customClassName,
103
- [`${prefix}--modal-footer--three-button`]: Array.isArray(secondaryButtons) && secondaryButtons.length === 2
104
- });
101
+ const footerClass = cx__default["default"](`${prefix}--modal-footer`, customClassName, Array.isArray(secondaryButtons) && secondaryButtons.length === 2 ? `${prefix}--modal-footer--three-button` : null);
105
102
  const secondaryButtonProps = {
106
103
  closeModal,
107
104
  secondaryButtons,
@@ -109,17 +106,21 @@ const ModalFooter = /*#__PURE__*/React__default["default"].forwardRef(function M
109
106
  secondaryClassName,
110
107
  onRequestClose
111
108
  };
112
- return /*#__PURE__*/React__default["default"].createElement(ButtonSet["default"], _rollupPluginBabelHelpers["extends"]({
113
- className: footerClass
114
- }, rest, {
115
- ref: ref
116
- }), /*#__PURE__*/React__default["default"].createElement(SecondaryButtonSet, secondaryButtonProps), primaryButtonText && /*#__PURE__*/React__default["default"].createElement(Button["default"], {
117
- onClick: onRequestSubmit,
118
- className: primaryClassName,
119
- disabled: primaryButtonDisabled,
120
- kind: danger ? 'danger' : 'primary',
121
- ref: inputref
122
- }, primaryButtonText), children);
109
+ return (
110
+ /*#__PURE__*/
111
+ // @ts-expect-error: Invalid derived types, will be fine once explicit types are added
112
+ React__default["default"].createElement(ButtonSet["default"], _rollupPluginBabelHelpers["extends"]({
113
+ className: footerClass
114
+ }, rest, {
115
+ ref: ref
116
+ }), /*#__PURE__*/React__default["default"].createElement(SecondaryButtonSet, secondaryButtonProps), primaryButtonText && /*#__PURE__*/React__default["default"].createElement(Button["default"], {
117
+ onClick: onRequestSubmit,
118
+ className: primaryClassName,
119
+ disabled: primaryButtonDisabled,
120
+ kind: danger ? 'danger' : 'primary',
121
+ ref: inputref
122
+ }, primaryButtonText), children)
123
+ );
123
124
  });
124
125
  ModalFooter.propTypes = {
125
126
  /**
@@ -142,6 +143,7 @@ ModalFooter.propTypes = {
142
143
  /**
143
144
  * The `ref` callback for the primary button.
144
145
  */
146
+ // @ts-expect-error: Invalid derived type
145
147
  inputref: PropTypes__default["default"].oneOfType([PropTypes__default["default"].func, PropTypes__default["default"].shape({
146
148
  current: PropTypes__default["default"].any
147
149
  })]),
@@ -198,10 +200,11 @@ ModalFooter.propTypes = {
198
200
  */
199
201
  secondaryClassName: PropTypes__default["default"].string
200
202
  };
203
+ const noop = () => {};
201
204
  ModalFooter.defaultProps = {
202
- onRequestClose: () => {},
203
- onRequestSubmit: () => {},
204
- closeModal: () => {}
205
+ onRequestClose: noop,
206
+ onRequestSubmit: noop,
207
+ closeModal: noop
205
208
  };
206
209
 
207
210
  exports.ModalFooter = ModalFooter;
@@ -0,0 +1,58 @@
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, { type ReactNode, type MouseEvent, type HTMLAttributes } from 'react';
8
+ type DivProps = Omit<HTMLAttributes<HTMLDivElement>, 'title'>;
9
+ export interface ModalHeaderProps extends DivProps {
10
+ /**
11
+ * Provide an optional function to be called when the close button is
12
+ * clicked
13
+ */
14
+ buttonOnClick?(event: MouseEvent): void;
15
+ /**
16
+ * Specify the content to be placed in the ModalHeader
17
+ */
18
+ children?: ReactNode;
19
+ /**
20
+ * Specify an optional className to be applied to the modal header
21
+ */
22
+ className?: string;
23
+ /**
24
+ * Specify an optional className to be applied to the modal close node
25
+ */
26
+ closeClassName?: string;
27
+ /**
28
+ * Specify an optional className to be applied to the modal close icon node
29
+ */
30
+ closeIconClassName?: string;
31
+ /**
32
+ * Provide an optional function to be called when the modal is closed
33
+ */
34
+ closeModal?(event: MouseEvent): void;
35
+ /**
36
+ * Specify a description for the close icon that can be read by screen
37
+ * readers
38
+ */
39
+ iconDescription?: string;
40
+ /**
41
+ * Specify an optional label to be displayed
42
+ */
43
+ label?: ReactNode;
44
+ /**
45
+ * Specify an optional className to be applied to the modal header label
46
+ */
47
+ labelClassName?: string;
48
+ /**
49
+ * Specify an optional title to be displayed
50
+ */
51
+ title?: ReactNode;
52
+ /**
53
+ * Specify an optional className to be applied to the modal heading
54
+ */
55
+ titleClassName?: string;
56
+ }
57
+ export declare const ModalHeader: React.ForwardRefExoticComponent<ModalHeaderProps & React.RefAttributes<HTMLDivElement>>;
58
+ export {};
@@ -39,29 +39,14 @@ const ModalHeader = /*#__PURE__*/React__default["default"].forwardRef(function M
39
39
  } = _ref;
40
40
  const prefix = usePrefix.usePrefix();
41
41
  function handleCloseButtonClick(evt) {
42
- closeModal(evt);
43
- buttonOnClick();
42
+ closeModal?.(evt);
43
+ buttonOnClick?.(evt);
44
44
  }
45
- const headerClass = cx__default["default"]({
46
- [`${prefix}--modal-header`]: true,
47
- [customClassName]: customClassName
48
- });
49
- const labelClass = cx__default["default"]({
50
- [`${prefix}--modal-header__label ${prefix}--type-delta`]: true,
51
- [labelClassName]: labelClassName
52
- });
53
- const titleClass = cx__default["default"]({
54
- [`${prefix}--modal-header__heading ${prefix}--type-beta`]: true,
55
- [titleClassName]: titleClassName
56
- });
57
- const closeClass = cx__default["default"]({
58
- [`${prefix}--modal-close`]: true,
59
- [closeClassName]: closeClassName
60
- });
61
- const closeIconClass = cx__default["default"]({
62
- [`${prefix}--modal-close__icon`]: true,
63
- [closeIconClassName]: closeIconClassName
64
- });
45
+ const headerClass = cx__default["default"](`${prefix}--modal-header`, customClassName);
46
+ const labelClass = cx__default["default"](`${prefix}--modal-header__label ${prefix}--type-delta`, labelClassName);
47
+ const titleClass = cx__default["default"](`${prefix}--modal-header__heading ${prefix}--type-beta`, titleClassName);
48
+ const closeClass = cx__default["default"](`${prefix}--modal-close`, closeClassName);
49
+ const closeIconClass = cx__default["default"](`${prefix}--modal-close__icon`, closeIconClassName);
65
50
  return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({
66
51
  className: headerClass
67
52
  }, rest, {
@@ -130,9 +115,7 @@ ModalHeader.propTypes = {
130
115
  titleClassName: PropTypes__default["default"].string
131
116
  };
132
117
  ModalHeader.defaultProps = {
133
- iconDescription: 'Close',
134
- buttonOnClick: () => {},
135
- closeModal: () => {}
118
+ iconDescription: 'Close'
136
119
  };
137
120
 
138
121
  exports.ModalHeader = ModalHeader;
@@ -0,0 +1,9 @@
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
+ export { default as ComposedModal, type ComposedModalProps, ModalBody, type ModalBodyProps, } from './ComposedModal';
8
+ export { ModalHeader, type ModalHeaderProps } from './ModalHeader';
9
+ export { ModalFooter, type ModalFooterProps } from './ModalFooter';
@@ -80,7 +80,18 @@ function ContainedList(_ref) {
80
80
  max: 'xl'
81
81
  },
82
82
  className: `${prefix}--contained-list__action`
83
- }, action)), children && /*#__PURE__*/React__default["default"].createElement("ul", {
83
+ }, action)), children &&
84
+ /*#__PURE__*/
85
+ /**
86
+ * Webkit removes implicit "list" semantics when "list-style-type: none" is set.
87
+ * Explicitly setting the "list" role ensures assistive technology in webkit
88
+ * browsers correctly announce the semantics.
89
+ *
90
+ * Ref https://bugs.webkit.org/show_bug.cgi?id=170179#c1
91
+ */
92
+ // eslint-disable-next-line jsx-a11y/no-redundant-roles
93
+ React__default["default"].createElement("ul", {
94
+ role: "list",
84
95
  "aria-labelledby": labelId
85
96
  }, isActionSearch ? filteredChildren : renderedChildren));
86
97
  }
@@ -0,0 +1,109 @@
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 PropTypes from 'prop-types';
8
+ import React, { HTMLAttributes, ReactElement } from 'react';
9
+ interface SwitchEventHandlersParams {
10
+ index?: number;
11
+ name?: string | number;
12
+ text?: string;
13
+ key?: string | number;
14
+ }
15
+ export interface ContentSwitcherProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {
16
+ /**
17
+ * Pass in Switch components to be rendered in the ContentSwitcher
18
+ */
19
+ children?: ReactElement[];
20
+ /**
21
+ * Specify an optional className to be added to the container node
22
+ */
23
+ className?: string;
24
+ /**
25
+ * `true` to use the light version.
26
+ *
27
+ * @deprecated The `light` prop for `ContentSwitcher` has
28
+ * been deprecated in favor of the new `Layer` component. It will be removed in the next major release.
29
+ */
30
+ light?: boolean;
31
+ /**
32
+ * Specify an `onChange` handler that is called whenever the ContentSwitcher
33
+ * changes which item is selected
34
+ */
35
+ onChange: (params: SwitchEventHandlersParams) => void;
36
+ /**
37
+ * Specify a selected index for the initially selected content
38
+ */
39
+ selectedIndex: number;
40
+ /**
41
+ * Choose whether or not to automatically change selection on focus
42
+ */
43
+ selectionMode: 'automatic' | 'manual';
44
+ /**
45
+ * Specify the size of the Content Switcher. Currently supports either `sm`, 'md' (default) or 'lg` as an option.
46
+ */
47
+ size: 'sm' | 'md' | 'lg';
48
+ }
49
+ interface ContentSwitcherState {
50
+ selectedIndex?: number;
51
+ }
52
+ export default class ContentSwitcher extends React.Component<ContentSwitcherProps, ContentSwitcherState> {
53
+ /**
54
+ * The DOM references of child `<Switch>`.
55
+ * @type {Array<Element>}
56
+ * @private
57
+ */
58
+ _switchRefs: HTMLButtonElement[];
59
+ state: {
60
+ selectedIndex: undefined;
61
+ };
62
+ static propTypes: {
63
+ /**
64
+ * Pass in Switch components to be rendered in the ContentSwitcher
65
+ */
66
+ children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
67
+ /**
68
+ * Specify an optional className to be added to the container node
69
+ */
70
+ className: PropTypes.Requireable<string>;
71
+ /**
72
+ * `true` to use the light variant.
73
+ */
74
+ light: (props: any, propName: any, componentName: any, ...rest: any[]) => any;
75
+ /**
76
+ * Specify an `onChange` handler that is called whenever the ContentSwitcher
77
+ * changes which item is selected
78
+ */
79
+ onChange: PropTypes.Validator<(...args: any[]) => any>;
80
+ /**
81
+ * Specify a selected index for the initially selected content
82
+ */
83
+ selectedIndex: PropTypes.Requireable<number>;
84
+ /**
85
+ * Choose whether or not to automatically change selection on focus
86
+ */
87
+ selectionMode: PropTypes.Requireable<string>;
88
+ /**
89
+ * Specify the size of the Content Switcher. Currently supports either `sm`, 'md' (default) or 'lg` as an option.
90
+ */
91
+ size: PropTypes.Requireable<string>;
92
+ };
93
+ static contextType: React.Context<string>;
94
+ static defaultProps: {
95
+ selectedIndex: number;
96
+ selectionMode: string;
97
+ onChange: () => void;
98
+ };
99
+ static getDerivedStateFromProps({ selectedIndex }: {
100
+ selectedIndex: any;
101
+ }, state: any): {
102
+ selectedIndex: any;
103
+ prevSelectedIndex: any;
104
+ } | null;
105
+ handleItemRef: (index: any) => (ref: any) => void;
106
+ handleChildChange: (data: any) => void;
107
+ render(): JSX.Element;
108
+ }
109
+ export {};