@carbon/react 1.89.0-rc.1 → 1.90.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 (68) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +1152 -849
  2. package/README.md +2 -2
  3. package/es/components/ComposedModal/ComposedModal.js +16 -5
  4. package/es/components/DataTable/DataTable.d.ts +3 -8
  5. package/es/components/DataTable/DataTable.js +10 -3
  6. package/es/components/DataTable/TableExpandRow.d.ts +33 -5
  7. package/es/components/DataTable/TableExpandRow.js +4 -2
  8. package/es/components/DataTable/TableHeader.d.ts +1 -2
  9. package/es/components/DataTable/TableHeader.js +1 -2
  10. package/es/components/DataTable/TableRow.d.ts +3 -6
  11. package/es/components/DataTable/TableRow.js +35 -22
  12. package/es/components/DataTable/state/sorting.d.ts +55 -14
  13. package/es/components/DataTable/state/sorting.js +40 -50
  14. package/es/components/DataTable/tools/sorting.js +4 -0
  15. package/es/components/Dialog/Dialog.d.ts +245 -0
  16. package/es/components/Dialog/Dialog.js +593 -0
  17. package/es/components/Dialog/index.d.ts +3 -251
  18. package/es/components/Dialog/index.js +1 -609
  19. package/es/components/FeatureFlags/index.d.ts +3 -1
  20. package/es/components/FeatureFlags/index.js +5 -2
  21. package/es/components/FileUploader/FileUploader.d.ts +28 -6
  22. package/es/components/FileUploader/FileUploader.js +152 -38
  23. package/es/components/Menu/MenuItem.js +2 -1
  24. package/es/components/Modal/Modal.js +14 -8
  25. package/es/components/NumberInput/NumberInput.js +11 -6
  26. package/es/components/Popover/index.js +6 -2
  27. package/es/components/StructuredList/StructuredList.js +4 -2
  28. package/es/components/Tag/DismissibleTag.d.ts +5 -0
  29. package/es/components/Tag/DismissibleTag.js +6 -1
  30. package/es/components/Toggletip/index.js +20 -8
  31. package/es/components/TreeView/TreeNode.d.ts +28 -0
  32. package/es/components/TreeView/TreeNode.js +6 -5
  33. package/es/index.d.ts +2 -1
  34. package/es/index.js +2 -0
  35. package/lib/components/ComposedModal/ComposedModal.js +16 -5
  36. package/lib/components/DataTable/DataTable.d.ts +3 -8
  37. package/lib/components/DataTable/DataTable.js +10 -3
  38. package/lib/components/DataTable/TableExpandRow.d.ts +33 -5
  39. package/lib/components/DataTable/TableExpandRow.js +4 -2
  40. package/lib/components/DataTable/TableHeader.d.ts +1 -2
  41. package/lib/components/DataTable/TableHeader.js +1 -2
  42. package/lib/components/DataTable/TableRow.d.ts +3 -6
  43. package/lib/components/DataTable/TableRow.js +34 -21
  44. package/lib/components/DataTable/state/sorting.d.ts +55 -14
  45. package/lib/components/DataTable/state/sorting.js +39 -50
  46. package/lib/components/DataTable/tools/sorting.js +4 -0
  47. package/lib/components/Dialog/Dialog.d.ts +245 -0
  48. package/lib/components/Dialog/Dialog.js +602 -0
  49. package/lib/components/Dialog/index.d.ts +3 -251
  50. package/lib/components/Dialog/index.js +9 -614
  51. package/lib/components/FeatureFlags/index.d.ts +3 -1
  52. package/lib/components/FeatureFlags/index.js +5 -2
  53. package/lib/components/FileUploader/FileUploader.d.ts +28 -6
  54. package/lib/components/FileUploader/FileUploader.js +151 -37
  55. package/lib/components/Menu/MenuItem.js +2 -1
  56. package/lib/components/Modal/Modal.js +21 -15
  57. package/lib/components/NumberInput/NumberInput.js +10 -5
  58. package/lib/components/Popover/index.js +6 -2
  59. package/lib/components/StructuredList/StructuredList.js +4 -2
  60. package/lib/components/Tag/DismissibleTag.d.ts +5 -0
  61. package/lib/components/Tag/DismissibleTag.js +6 -1
  62. package/lib/components/Toggletip/index.js +19 -7
  63. package/lib/components/TreeView/TreeNode.d.ts +28 -0
  64. package/lib/components/TreeView/TreeNode.js +6 -5
  65. package/lib/index.d.ts +2 -1
  66. package/lib/index.js +60 -58
  67. package/package.json +15 -15
  68. package/telemetry.yml +16 -0
@@ -0,0 +1,602 @@
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
+ 'use strict';
9
+
10
+ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
11
+ var PropTypes = require('prop-types');
12
+ var React = require('react');
13
+ var useIsomorphicEffect = require('../../internal/useIsomorphicEffect.js');
14
+ var usePrefix = require('../../internal/usePrefix.js');
15
+ var cx = require('classnames');
16
+ var iconsReact = require('@carbon/icons-react');
17
+ var index = require('../IconButton/index.js');
18
+ var noopFn = require('../../internal/noopFn.js');
19
+ require('../Text/index.js');
20
+ var index$1 = require('../Layer/index.js');
21
+ var ButtonSet = require('../ButtonSet/ButtonSet.js');
22
+ var Button = require('../Button/Button.js');
23
+ require('../Button/Button.Skeleton.js');
24
+ var useId = require('../../internal/useId.js');
25
+ var InlineLoading = require('../InlineLoading/InlineLoading.js');
26
+ var debounce = require('../../node_modules/es-toolkit/dist/compat/function/debounce.js');
27
+ var Text = require('../Text/Text.js');
28
+
29
+ const DialogContext = /*#__PURE__*/React.createContext({});
30
+
31
+ /**
32
+ * ----------
33
+ * Dialog
34
+ * ----------
35
+ */
36
+
37
+ const Dialog = /*#__PURE__*/React.forwardRef(({
38
+ children,
39
+ className,
40
+ focusAfterCloseRef,
41
+ modal,
42
+ onCancel = noopFn.noopFn,
43
+ onClick = noopFn.noopFn,
44
+ onClose = noopFn.noopFn,
45
+ onRequestClose = noopFn.noopFn,
46
+ open = false,
47
+ role,
48
+ ariaLabel,
49
+ ariaLabelledBy,
50
+ ariaDescribedBy,
51
+ ...rest
52
+ }, forwardRef) => {
53
+ const prefix = usePrefix.usePrefix();
54
+ const dialogId = useId.useId();
55
+ const titleId = `${prefix}--dialog-header__heading--${dialogId}`;
56
+ const subtitleId = `${prefix}--dialog-header__label--${dialogId}`;
57
+
58
+ // This component needs access to a ref, placed on the dialog, to call the
59
+ // various imperative dialog functions (show(), close(), etc.).
60
+ // If the parent component has not passed a ref for forwardRef, forwardRef
61
+ // will be null. A "backup" ref is needed to ensure the dialog's instance
62
+ // methods can always be called within this component.
63
+ const backupRef = React.useRef(null);
64
+ const ref = forwardRef ?? backupRef;
65
+
66
+ // Clicks on the backdrop of an open modal dialog should request the consuming component to close
67
+ // the dialog. Clicks elsewhere, or on non-modal dialogs should not request
68
+ // to close the dialog.
69
+ function handleModalBackdropClick(e) {
70
+ if (open && modal && e.target === ref.current) {
71
+ onRequestClose(e);
72
+ }
73
+ }
74
+ function handleClick(e) {
75
+ handleModalBackdropClick(e);
76
+
77
+ // onClick should always be called, no matter if the target is a modal
78
+ // dialog, modal dialog backdrop, or non-modal dialog.
79
+ onClick(e);
80
+ }
81
+ React.useEffect(() => {
82
+ if (ref.current) {
83
+ if (open) {
84
+ if (modal) {
85
+ // Display the dialog as a modal, over the top of any other dialogs
86
+ // that might be present. Everything outside the dialog are inert
87
+ // with interactions outside the dialog being blocked.
88
+ ref.current.showModal();
89
+ } else {
90
+ // Display the dialog modelessly, i.e. still allowing interaction
91
+ // with content outside of the dialog.
92
+ ref.current.show();
93
+ }
94
+ } else {
95
+ ref.current.close();
96
+ }
97
+ }
98
+ }, [modal, open]);
99
+ React.useEffect(() => {
100
+ if (!open && focusAfterCloseRef) {
101
+ // use setTimeout to ensure focus is set after all other default focus behavior
102
+ const moveFocus = setTimeout(() => {
103
+ focusAfterCloseRef.current?.focus();
104
+ });
105
+
106
+ //component did unmount equivalent
107
+ return () => {
108
+ clearTimeout(moveFocus);
109
+ };
110
+ }
111
+ }, [open, focusAfterCloseRef]);
112
+ const containerClasses = cx(`${prefix}--dialog-container`);
113
+ const contextValue = {
114
+ dialogId,
115
+ titleId,
116
+ subtitleId,
117
+ isOpen: open
118
+ };
119
+ React.useEffect(() => {
120
+ if (ref.current && open && !ariaLabel && !ariaLabelledBy) {
121
+ const title = ref.current.querySelector(`.${prefix}--dialog-header__heading`);
122
+
123
+ // Set aria-labelledby to the title's ID if it exists
124
+ if (title && title.id) {
125
+ ref.current.setAttribute('aria-labelledby', title.id);
126
+ }
127
+ }
128
+ }, [open, ariaLabel, ariaLabelledBy, prefix]);
129
+ return /*#__PURE__*/React.createElement(DialogContext.Provider, {
130
+ value: contextValue
131
+ }, /*#__PURE__*/React.createElement("dialog", _rollupPluginBabelHelpers.extends({}, rest, {
132
+ className: cx(`${prefix}--dialog`, {
133
+ [`${prefix}--dialog--modal`]: modal
134
+ }, className),
135
+ ref: ref,
136
+ onCancel: onCancel,
137
+ onClick: handleClick,
138
+ onClose: onClose,
139
+ role: role,
140
+ "aria-label": ariaLabel,
141
+ "aria-labelledby": !ariaLabel ? ariaLabelledBy || titleId : undefined,
142
+ "aria-describedby": ariaDescribedBy
143
+ }), /*#__PURE__*/React.createElement("div", {
144
+ className: containerClasses
145
+ }, children)));
146
+ });
147
+ Dialog.displayName = 'Dialog';
148
+ Dialog.propTypes = {
149
+ /**
150
+ * Provide children to be rendered inside of the Dialog
151
+ */
152
+ children: PropTypes.node,
153
+ /**
154
+ * Specify an optional className to be applied to the modal root node
155
+ */
156
+ className: PropTypes.string,
157
+ /**
158
+ * Provide a ref to return focus to once the dialog is closed.
159
+ */
160
+ focusAfterCloseRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
161
+ current: PropTypes.any
162
+ })]),
163
+ /**
164
+ * Modal specifies whether the Dialog is modal or non-modal. This cannot be
165
+ * changed while open=true
166
+ */
167
+ modal: PropTypes.bool,
168
+ /**
169
+ * Specify a handler for closing Dialog.
170
+ * The handler should care of closing Dialog, e.g. changing `open` prop.
171
+ */
172
+ onRequestClose: PropTypes.func,
173
+ /**
174
+ * open initial state
175
+ */
176
+ open: PropTypes.bool,
177
+ /**
178
+ * Specify the role of the dialog for accessibility
179
+ */
180
+ role: PropTypes.oneOf(['dialog', 'alertdialog']),
181
+ /**
182
+ * Specify a label for screen readers
183
+ */
184
+ 'aria-label': PropTypes.string,
185
+ /**
186
+ * Specify the ID of an element that labels this dialog
187
+ */
188
+ 'aria-labelledby': PropTypes.string,
189
+ /**
190
+ * Specify the ID of an element that describes this dialog
191
+ */
192
+ ariaDescribedBy: PropTypes.string
193
+ };
194
+
195
+ /**
196
+ * -------------
197
+ * DialogHeader
198
+ * -------------
199
+ */
200
+
201
+ const DialogHeader = /*#__PURE__*/React.forwardRef(({
202
+ children,
203
+ ...rest
204
+ }, ref) => {
205
+ const prefix = usePrefix.usePrefix();
206
+ return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
207
+ className: `${prefix}--dialog__header`,
208
+ ref: ref
209
+ }, rest), children);
210
+ });
211
+ DialogHeader.displayName = 'DialogHeader';
212
+ DialogHeader.propTypes = {
213
+ /**
214
+ * Provide the contents to be rendered inside of this component
215
+ */
216
+ children: PropTypes.node
217
+ };
218
+
219
+ /**
220
+ * ---------------
221
+ * DialogControls
222
+ * ---------------
223
+ */
224
+
225
+ const DialogControls = /*#__PURE__*/React.forwardRef(({
226
+ children,
227
+ ...rest
228
+ }, ref) => {
229
+ const prefix = usePrefix.usePrefix();
230
+ return (
231
+ /*#__PURE__*/
232
+ // @ts-ignore
233
+ React.createElement("div", _rollupPluginBabelHelpers.extends({
234
+ className: `${prefix}--dialog__header-controls`,
235
+ ref: ref
236
+ }, rest), children)
237
+ );
238
+ });
239
+ DialogControls.displayName = 'DialogControls';
240
+ DialogControls.propTypes = {
241
+ /**
242
+ * Provide children to be rendered inside of this component
243
+ */
244
+ children: PropTypes.node
245
+ };
246
+
247
+ /**
248
+ * -------------------
249
+ * DialogCloseButton
250
+ * -------------------
251
+ */
252
+
253
+ const DialogCloseButton = /*#__PURE__*/React.forwardRef(({
254
+ onClick,
255
+ ...rest
256
+ }, ref) => {
257
+ const prefix = usePrefix.usePrefix();
258
+ return (
259
+ /*#__PURE__*/
260
+ // @ts-ignore
261
+ React.createElement(index.IconButton, _rollupPluginBabelHelpers.extends({
262
+ kind: "ghost",
263
+ className: `${prefix}--dialog__close`,
264
+ label: "Close",
265
+ title: "Close",
266
+ "aria-label": "Close",
267
+ align: "left",
268
+ onClick: onClick,
269
+ ref: ref
270
+ }, rest), /*#__PURE__*/React.createElement(iconsReact.Close, {
271
+ size: 20,
272
+ "aria-hidden": "true",
273
+ tabIndex: -1,
274
+ className: `${prefix}--icon__close`
275
+ }))
276
+ );
277
+ });
278
+ DialogCloseButton.displayName = 'DialogCloseButton';
279
+ DialogCloseButton.propTypes = {
280
+ /**
281
+ * Specify a click handler applied to the IconButton
282
+ */
283
+ onClick: PropTypes.func
284
+ };
285
+
286
+ /**
287
+ * ------------
288
+ * DialogTitle
289
+ * ------------
290
+ */
291
+
292
+ const DialogTitle = /*#__PURE__*/React.forwardRef(({
293
+ children,
294
+ className,
295
+ id,
296
+ ...rest
297
+ }, ref) => {
298
+ const prefix = usePrefix.usePrefix();
299
+ const {
300
+ titleId
301
+ } = React.useContext(DialogContext);
302
+ const headingId = id || titleId;
303
+ return /*#__PURE__*/React.createElement(Text.Text, _rollupPluginBabelHelpers.extends({
304
+ as: "h2",
305
+ id: headingId,
306
+ className: cx(`${prefix}--dialog-header__heading`, className),
307
+ ref: ref
308
+ }, rest), children);
309
+ });
310
+ DialogTitle.displayName = 'DialogTitle';
311
+ DialogTitle.propTypes = {
312
+ /**
313
+ * Provide the contents to be rendered inside of this component
314
+ */
315
+ children: PropTypes.node,
316
+ /**
317
+ * Specify an optional className to be applied to the title node
318
+ */
319
+ className: PropTypes.string,
320
+ /**
321
+ * Specify an optional id for the title element
322
+ */
323
+ id: PropTypes.string
324
+ };
325
+
326
+ /**
327
+ * ---------------
328
+ * DialogSubtitle
329
+ * ---------------
330
+ */
331
+
332
+ const DialogSubtitle = /*#__PURE__*/React.forwardRef(({
333
+ children,
334
+ className,
335
+ id,
336
+ ...rest
337
+ }, ref) => {
338
+ const prefix = usePrefix.usePrefix();
339
+ const {
340
+ subtitleId
341
+ } = React.useContext(DialogContext);
342
+ const labelId = id || subtitleId;
343
+ return /*#__PURE__*/React.createElement(Text.Text, _rollupPluginBabelHelpers.extends({
344
+ as: "h2",
345
+ id: labelId,
346
+ className: cx(`${prefix}--dialog-header__label`, className),
347
+ ref: ref
348
+ }, rest), children);
349
+ });
350
+ DialogSubtitle.displayName = 'DialogSubtitle';
351
+ DialogSubtitle.propTypes = {
352
+ /**
353
+ * Provide the contents to be rendered inside of this component
354
+ */
355
+ children: PropTypes.node,
356
+ /**
357
+ * Specify an optional className to be applied to the subtitle node
358
+ */
359
+ className: PropTypes.string,
360
+ /**
361
+ * Specify an optional id for the subtitle element
362
+ */
363
+ id: PropTypes.string
364
+ };
365
+
366
+ /**
367
+ * -----------
368
+ * DialogBody
369
+ * -----------
370
+ */
371
+
372
+ const DialogBody = /*#__PURE__*/React.forwardRef(({
373
+ children,
374
+ className,
375
+ hasScrollingContent,
376
+ ...rest
377
+ }, ref) => {
378
+ const prefix = usePrefix.usePrefix();
379
+ const contentRef = React.useRef(null);
380
+ const [isScrollable, setIsScrollable] = React.useState(false);
381
+ const dialogId = useId.useId();
382
+ const dialogBodyId = `${prefix}--dialog-body--${dialogId}`;
383
+ useIsomorphicEffect.default(() => {
384
+ if (contentRef.current) {
385
+ setIsScrollable(contentRef.current.scrollHeight > contentRef.current.clientHeight);
386
+ }
387
+ function handler() {
388
+ if (contentRef.current) {
389
+ setIsScrollable(contentRef.current.scrollHeight > contentRef.current.clientHeight);
390
+ }
391
+ }
392
+ const debouncedHandler = debounce.debounce(handler, 200);
393
+ window.addEventListener('resize', debouncedHandler);
394
+ return () => {
395
+ debouncedHandler.cancel();
396
+ window.removeEventListener('resize', debouncedHandler);
397
+ };
398
+ }, []);
399
+ const contentClasses = cx(`${prefix}--dialog-content`, {
400
+ [`${prefix}--dialog-scroll-content`]: hasScrollingContent || isScrollable
401
+ }, className);
402
+ const hasScrollingContentProps = hasScrollingContent || isScrollable ? {
403
+ tabIndex: 0,
404
+ role: 'region'
405
+ } : {};
406
+ const combinedRef = el => {
407
+ if (typeof ref === 'function') {
408
+ ref(el);
409
+ } else if (ref) {
410
+ ref.current = el;
411
+ }
412
+ contentRef.current = el;
413
+ };
414
+ return /*#__PURE__*/React.createElement(index$1.Layer, _rollupPluginBabelHelpers.extends({
415
+ ref: combinedRef,
416
+ id: dialogBodyId,
417
+ className: contentClasses
418
+ }, hasScrollingContentProps, rest), children);
419
+ });
420
+ DialogBody.displayName = 'DialogBody';
421
+ DialogBody.propTypes = {
422
+ /**
423
+ * Provide the contents to be rendered inside of this component
424
+ */
425
+ children: PropTypes.node,
426
+ /**
427
+ * Specify an optional className to be applied to the body node
428
+ */
429
+ className: PropTypes.string,
430
+ /**
431
+ * Specify whether the content has overflow that should be scrollable
432
+ */
433
+ hasScrollingContent: PropTypes.bool
434
+ };
435
+
436
+ /**
437
+ * -------------
438
+ * DialogFooter
439
+ * -------------
440
+ */
441
+
442
+ const DialogFooter = /*#__PURE__*/React.forwardRef(({
443
+ children,
444
+ className,
445
+ onRequestClose = noopFn.noopFn,
446
+ onSecondarySubmit,
447
+ onRequestSubmit = noopFn.noopFn,
448
+ primaryButtonText = 'Save',
449
+ primaryButtonDisabled = false,
450
+ secondaryButtonText = 'Cancel',
451
+ secondaryButtons,
452
+ loadingStatus = 'inactive',
453
+ loadingDescription,
454
+ loadingIconDescription,
455
+ onLoadingSuccess = noopFn.noopFn,
456
+ danger = false,
457
+ ...rest
458
+ }, ref) => {
459
+ const prefix = usePrefix.usePrefix();
460
+ const button = React.useRef(null);
461
+ const {
462
+ isOpen
463
+ } = React.useContext(DialogContext);
464
+ const [secondaryButtonRef, setSecondaryButtonRef] = React.useState(null);
465
+ React.useEffect(() => {
466
+ if (danger && secondaryButtonRef) {
467
+ const focusFrame = requestAnimationFrame(() => {
468
+ secondaryButtonRef.focus();
469
+ });
470
+ return () => cancelAnimationFrame(focusFrame);
471
+ }
472
+ }, [danger, secondaryButtonRef, isOpen]);
473
+ const classes = cx(`${prefix}--dialog-footer`, className, {
474
+ [`${prefix}--dialog-footer--three-button`]: Array.isArray(secondaryButtons) && secondaryButtons.length === 2
475
+ });
476
+ const loadingActive = loadingStatus !== 'inactive';
477
+ const primaryButtonClass = cx({
478
+ [`${prefix}--btn--loading`]: loadingStatus !== 'inactive'
479
+ });
480
+ const onSecondaryButtonClick = onSecondarySubmit ? onSecondarySubmit : onRequestClose;
481
+ if (children) {
482
+ return /*#__PURE__*/React.createElement(ButtonSet.default, _rollupPluginBabelHelpers.extends({
483
+ className: classes,
484
+ ref: ref
485
+ }, rest), children);
486
+ }
487
+ return /*#__PURE__*/React.createElement(ButtonSet.default, _rollupPluginBabelHelpers.extends({
488
+ className: classes,
489
+ "aria-busy": loadingActive,
490
+ ref: ref
491
+ }, rest), Array.isArray(secondaryButtons) && secondaryButtons.length <= 2 ? secondaryButtons.map(({
492
+ buttonText,
493
+ onClick: onButtonClick
494
+ }, i) => /*#__PURE__*/React.createElement(Button.default, {
495
+ key: `${buttonText}-${i}`,
496
+ autoFocus: danger,
497
+ kind: "secondary",
498
+ ref: i === 0 && danger ? setSecondaryButtonRef : undefined,
499
+ onClick: onButtonClick
500
+ }, buttonText)) : secondaryButtonText && /*#__PURE__*/React.createElement(Button.default, {
501
+ ref: danger ? setSecondaryButtonRef : undefined,
502
+ disabled: loadingActive,
503
+ kind: "secondary",
504
+ autoFocus: danger,
505
+ onClick: onSecondaryButtonClick
506
+ }, secondaryButtonText), /*#__PURE__*/React.createElement(Button.default, {
507
+ className: primaryButtonClass,
508
+ kind: danger ? 'danger' : 'primary',
509
+ disabled: loadingActive || primaryButtonDisabled,
510
+ onClick: onRequestSubmit,
511
+ ref: button
512
+ }, loadingStatus === 'inactive' ? primaryButtonText : /*#__PURE__*/React.createElement(InlineLoading.default, {
513
+ status: loadingStatus,
514
+ description: loadingDescription,
515
+ iconDescription: loadingIconDescription,
516
+ className: `${prefix}--inline-loading--btn`,
517
+ onSuccess: onLoadingSuccess
518
+ })));
519
+ });
520
+ DialogFooter.displayName = 'DialogFooter';
521
+ DialogFooter.propTypes = {
522
+ /**
523
+ * Provide the contents to be rendered inside of this component
524
+ */
525
+ children: PropTypes.node,
526
+ /**
527
+ * Specify an optional className to be applied to the footer node
528
+ */
529
+ className: PropTypes.string,
530
+ /**
531
+ * Specify a handler for closing dialog.
532
+ */
533
+ onRequestClose: PropTypes.func,
534
+ /**
535
+ * Specify a handler for the secondary button.
536
+ */
537
+ onSecondarySubmit: PropTypes.func,
538
+ /**
539
+ * Specify a handler for submitting dialog.
540
+ */
541
+ onRequestSubmit: PropTypes.func,
542
+ /**
543
+ * Specify the text for the primary button
544
+ */
545
+ primaryButtonText: PropTypes.node,
546
+ /**
547
+ * Specify whether the Button should be disabled, or not
548
+ */
549
+ primaryButtonDisabled: PropTypes.bool,
550
+ /**
551
+ * Specify the text for the secondary button
552
+ */
553
+ secondaryButtonText: PropTypes.node,
554
+ /**
555
+ * Specify an array of config objects for secondary buttons
556
+ */
557
+ secondaryButtons: (props, propName, componentName) => {
558
+ if (props.secondaryButtons) {
559
+ if (!Array.isArray(props.secondaryButtons) || props.secondaryButtons.length !== 2) {
560
+ return new Error(`${propName} needs to be an array of two button config objects`);
561
+ }
562
+ const shape = {
563
+ buttonText: PropTypes.node,
564
+ onClick: PropTypes.func
565
+ };
566
+ props[propName].forEach(secondaryButton => {
567
+ PropTypes.checkPropTypes(shape, secondaryButton, propName, componentName);
568
+ });
569
+ }
570
+ return null;
571
+ },
572
+ /**
573
+ * Specify whether the Dialog is for dangerous actions
574
+ */
575
+ danger: PropTypes.bool,
576
+ /**
577
+ * Specify loading status
578
+ */
579
+ loadingStatus: PropTypes.oneOf(['inactive', 'active', 'finished', 'error']),
580
+ /**
581
+ * Specify the description for the loading text
582
+ */
583
+ loadingDescription: PropTypes.string,
584
+ /**
585
+ * Specify the description for the loading icon
586
+ */
587
+ loadingIconDescription: PropTypes.string,
588
+ /**
589
+ * Provide an optional handler to be invoked when loading is
590
+ * successful
591
+ */
592
+ onLoadingSuccess: PropTypes.func
593
+ };
594
+
595
+ exports.Dialog = Dialog;
596
+ exports.DialogBody = DialogBody;
597
+ exports.DialogCloseButton = DialogCloseButton;
598
+ exports.DialogControls = DialogControls;
599
+ exports.DialogFooter = DialogFooter;
600
+ exports.DialogHeader = DialogHeader;
601
+ exports.DialogSubtitle = DialogSubtitle;
602
+ exports.DialogTitle = DialogTitle;