@mezzanine-ui/react 1.0.0-beta.1 → 1.0.0-beta.3
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.
- package/Anchor/Anchor.d.ts +51 -18
- package/Anchor/Anchor.js +15 -15
- package/Anchor/AnchorGroup.d.ts +34 -0
- package/Anchor/AnchorGroup.js +37 -0
- package/Anchor/AnchorItem.d.ts +30 -0
- package/Anchor/AnchorItem.js +65 -0
- package/Anchor/index.d.ts +2 -0
- package/Anchor/index.js +1 -0
- package/Anchor/utils.d.ts +13 -0
- package/Anchor/utils.js +95 -0
- package/AutoComplete/AutoComplete.d.ts +194 -0
- package/AutoComplete/AutoComplete.js +419 -0
- package/AutoComplete/index.d.ts +2 -0
- package/AutoComplete/index.js +1 -0
- package/AutoComplete/useAutoCompleteCreation.d.ts +33 -0
- package/AutoComplete/useAutoCompleteCreation.js +201 -0
- package/AutoComplete/useAutoCompleteKeyboard.d.ts +31 -0
- package/AutoComplete/useAutoCompleteKeyboard.js +149 -0
- package/AutoComplete/useAutoCompleteSearch.d.ts +16 -0
- package/AutoComplete/useAutoCompleteSearch.js +69 -0
- package/AutoComplete/useCreationTracker.d.ts +17 -0
- package/AutoComplete/useCreationTracker.js +47 -0
- package/Badge/Badge.js +2 -2
- package/Breadcrumb/BreadcrumbItem.d.ts +1 -1
- package/Button/Button.js +13 -11
- package/Button/index.d.ts +1 -1
- package/Button/typings.d.ts +27 -4
- package/Description/Description.d.ts +30 -0
- package/Description/Description.js +13 -0
- package/Description/DescriptionContent.d.ts +41 -0
- package/Description/DescriptionContent.js +14 -0
- package/Description/DescriptionGroup.d.ts +13 -0
- package/Description/DescriptionGroup.js +12 -0
- package/Description/DescriptionTitle.d.ts +45 -0
- package/Description/DescriptionTitle.js +17 -0
- package/Description/index.d.ts +8 -0
- package/Description/index.js +4 -0
- package/Dropdown/Dropdown.d.ts +43 -3
- package/Dropdown/Dropdown.js +154 -35
- package/Dropdown/DropdownAction.d.ts +1 -1
- package/Dropdown/DropdownAction.js +1 -4
- package/Dropdown/DropdownItem.d.ts +21 -4
- package/Dropdown/DropdownItem.js +23 -10
- package/Dropdown/DropdownItemCard.d.ts +5 -5
- package/Dropdown/DropdownItemCard.js +11 -10
- package/Dropdown/DropdownStatus.d.ts +2 -2
- package/Dropdown/DropdownStatus.js +29 -0
- package/Dropdown/dropdownKeydownHandler.d.ts +2 -1
- package/Dropdown/dropdownKeydownHandler.js +73 -0
- package/Dropdown/highlightText.js +5 -1
- package/Dropdown/shortcutTextHandler.d.ts +24 -0
- package/Dropdown/shortcutTextHandler.js +171 -0
- package/Form/FormControlContext.d.ts +2 -2
- package/Form/FormField.d.ts +56 -4
- package/Form/FormField.js +10 -6
- package/Form/FormHintText.d.ts +24 -1
- package/Form/FormHintText.js +4 -4
- package/Form/FormLabel.d.ts +6 -3
- package/Form/FormLabel.js +5 -3
- package/Input/Input.d.ts +29 -3
- package/Input/Input.js +22 -6
- package/Input/PasswordStrengthIndicator/PasswordStrengthIndicator.js +1 -1
- package/Modal/Modal.d.ts +103 -11
- package/Modal/Modal.js +14 -9
- package/Modal/ModalBodyForVerification.d.ts +59 -0
- package/Modal/ModalBodyForVerification.js +99 -0
- package/Modal/ModalControl.d.ts +2 -2
- package/Modal/ModalControl.js +1 -1
- package/Modal/ModalFooter.d.ts +119 -1
- package/Modal/ModalFooter.js +15 -3
- package/Modal/ModalHeader.d.ts +26 -7
- package/Modal/ModalHeader.js +33 -7
- package/Modal/index.d.ts +4 -5
- package/Modal/index.js +1 -2
- package/Modal/useModalContainer.d.ts +12 -3
- package/Modal/useModalContainer.js +28 -6
- package/Navigation/CollapsedMenu.d.ts +6 -0
- package/Navigation/CollapsedMenu.js +16 -0
- package/Navigation/Navigation.d.ts +17 -3
- package/Navigation/Navigation.js +48 -33
- package/Navigation/NavigationFooter.js +4 -2
- package/Navigation/NavigationHeader.d.ts +11 -1
- package/Navigation/NavigationHeader.js +6 -3
- package/Navigation/NavigationOption.d.ts +3 -2
- package/Navigation/NavigationOption.js +45 -26
- package/Navigation/NavigationOptionCategory.js +20 -2
- package/Navigation/context.d.ts +2 -0
- package/Navigation/useVisibleItems.d.ts +5 -0
- package/Navigation/useVisibleItems.js +54 -0
- package/NotificationCenter/NotificationCenter.d.ts +124 -0
- package/NotificationCenter/NotificationCenter.js +259 -0
- package/NotificationCenter/NotificationCenterDrawer.d.ts +89 -0
- package/NotificationCenter/index.d.ts +3 -0
- package/NotificationCenter/index.js +1 -0
- package/PageFooter/PageFooter.d.ts +19 -9
- package/PageFooter/PageFooter.js +10 -10
- package/PageHeader/PageHeader.js +4 -12
- package/PageToolbar/PageToolbar.d.ts +2 -6
- package/PageToolbar/utils.js +4 -12
- package/Select/index.d.ts +0 -2
- package/Select/index.js +0 -1
- package/Slider/useSlider.js +1 -1
- package/Table/Table.d.ts +53 -15
- package/Table/Table.js +178 -82
- package/Table/TableContext.d.ts +18 -42
- package/Table/components/TableActionsCell.d.ts +26 -0
- package/Table/components/TableActionsCell.js +78 -0
- package/Table/components/TableBody.d.ts +2 -5
- package/Table/components/TableBody.js +16 -19
- package/Table/components/TableBulkActions.d.ts +15 -0
- package/Table/components/TableBulkActions.js +26 -0
- package/Table/components/TableCell.d.ts +2 -0
- package/Table/components/TableCell.js +42 -10
- package/Table/components/TableColGroup.js +10 -112
- package/Table/components/TableColumnTitleMenu.d.ts +6 -0
- package/Table/components/TableColumnTitleMenu.js +20 -0
- package/Table/components/TableDragHandleCell.d.ts +2 -0
- package/Table/components/TableDragHandleCell.js +8 -1
- package/Table/components/TableExpandCell.d.ts +2 -0
- package/Table/components/TableExpandCell.js +8 -1
- package/Table/components/TableExpandedRow.js +3 -2
- package/Table/components/TableHeader.d.ts +2 -4
- package/Table/components/TableHeader.js +11 -14
- package/Table/components/TableResizeHandle.js +3 -7
- package/Table/components/TableRow.js +54 -20
- package/Table/components/TableSelectionCell.d.ts +5 -0
- package/Table/components/TableSelectionCell.js +12 -1
- package/Table/components/index.d.ts +1 -0
- package/Table/components/index.js +1 -0
- package/Table/hooks/index.d.ts +1 -1
- package/Table/hooks/index.js +1 -1
- package/Table/hooks/useTableDataSource.d.ts +2 -2
- package/Table/hooks/useTableExpansion.js +0 -6
- package/Table/hooks/useTableFixedOffsets.d.ts +1 -1
- package/Table/hooks/useTableFixedOffsets.js +24 -26
- package/Table/hooks/useTableResizedColumns.d.ts +2 -0
- package/Table/hooks/useTableResizedColumns.js +22 -0
- package/Table/hooks/useTableScroll.d.ts +3 -1
- package/Table/hooks/useTableScroll.js +25 -19
- package/Table/hooks/useTableSelection.js +32 -8
- package/Table/hooks/useTableVirtualization.d.ts +1 -1
- package/Table/index.d.ts +4 -4
- package/Table/index.js +5 -3
- package/Table/utils/calculateColumnWidths.d.ts +28 -0
- package/Table/utils/calculateColumnWidths.js +80 -0
- package/Table/utils/index.d.ts +2 -0
- package/Table/utils/index.js +1 -0
- package/Table/utils/useTableRowSelection.d.ts +5 -5
- package/Table/utils/useTableRowSelection.js +14 -6
- package/Tag/TagGroup.d.ts +3 -0
- package/Tag/index.d.ts +2 -0
- package/Tag/index.js +1 -0
- package/Upload/UploadPictureCard.js +1 -1
- package/index.d.ts +36 -20
- package/index.js +26 -7
- package/package.json +4 -4
- package/utils/format-number-with-commas.d.ts +4 -0
- package/utils/format-number-with-commas.js +27 -0
- package/utils/parse-number-with-commas.d.ts +4 -0
- package/utils/parse-number-with-commas.js +22 -0
- package/Modal/ModalActions.d.ts +0 -9
- package/Modal/ModalActions.js +0 -20
- package/Modal/ModalBody.d.ts +0 -7
- package/Modal/ModalBody.js +0 -14
- package/Notification/Notification.d.ts +0 -54
- package/Notification/Notification.js +0 -76
- package/Notification/index.d.ts +0 -3
- package/Notification/index.js +0 -1
- package/Select/AutoComplete.d.ts +0 -107
- package/Select/AutoComplete.js +0 -114
- package/Table/hooks/useTableColumns.d.ts +0 -8
- package/Table/hooks/useTableColumns.js +0 -91
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useRef, useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
function useVisibleItems(items, collapsed) {
|
|
4
|
+
const contentRef = useRef(null);
|
|
5
|
+
const [visibleCount, setVisibleCount] = useState(null);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const contentEl = contentRef.current;
|
|
8
|
+
if (!contentEl)
|
|
9
|
+
return;
|
|
10
|
+
let timeoutId = null;
|
|
11
|
+
const calculateVisibleItems = () => {
|
|
12
|
+
if (!collapsed) {
|
|
13
|
+
setVisibleCount(null);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const contentHeight = contentEl.clientHeight;
|
|
17
|
+
const ul = contentEl.querySelector('ul');
|
|
18
|
+
const option = contentEl.querySelector('.mzn-navigation-option--level-1');
|
|
19
|
+
const optionHeight = (option === null || option === void 0 ? void 0 : option.clientHeight) || 0;
|
|
20
|
+
const optionsGapTightFixed = 4;
|
|
21
|
+
if (optionHeight === 0) {
|
|
22
|
+
setVisibleCount(0);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (!ul)
|
|
26
|
+
return;
|
|
27
|
+
const count = Math.floor((contentHeight + optionsGapTightFixed) /
|
|
28
|
+
(optionHeight + optionsGapTightFixed)) - 1;
|
|
29
|
+
setVisibleCount(count);
|
|
30
|
+
};
|
|
31
|
+
const debouncedCalculate = () => {
|
|
32
|
+
if (timeoutId) {
|
|
33
|
+
clearTimeout(timeoutId);
|
|
34
|
+
}
|
|
35
|
+
timeoutId = setTimeout(() => {
|
|
36
|
+
calculateVisibleItems();
|
|
37
|
+
}, 100);
|
|
38
|
+
};
|
|
39
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
40
|
+
debouncedCalculate();
|
|
41
|
+
});
|
|
42
|
+
resizeObserver.observe(contentEl);
|
|
43
|
+
calculateVisibleItems();
|
|
44
|
+
return () => {
|
|
45
|
+
if (timeoutId) {
|
|
46
|
+
clearTimeout(timeoutId);
|
|
47
|
+
}
|
|
48
|
+
resizeObserver.disconnect();
|
|
49
|
+
};
|
|
50
|
+
}, [collapsed, items]);
|
|
51
|
+
return { contentRef, visibleCount };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { useVisibleItems };
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { FC, Key } from 'react';
|
|
2
|
+
import { DropdownOption } from '@mezzanine-ui/core/dropdown/dropdown';
|
|
3
|
+
import { NotificationSeverity, NotificationType } from '@mezzanine-ui/core/notification-center';
|
|
4
|
+
import { ButtonProps } from '../Button';
|
|
5
|
+
import { Notifier, NotifierConfig, NotifierData } from '../Notifier';
|
|
6
|
+
import { SlideProps } from '../Transition';
|
|
7
|
+
export interface NotificationConfigProps extends Pick<NotifierConfig, 'duration'>, Pick<SlideProps, 'onEnter' | 'onEntered' | 'onExit' | 'onExited' | 'easing'> {
|
|
8
|
+
/**
|
|
9
|
+
* Callback function when "View All" button is clicked.
|
|
10
|
+
* This will be called after closing all notifications.
|
|
11
|
+
*/
|
|
12
|
+
onViewAll?: VoidFunction;
|
|
13
|
+
/**
|
|
14
|
+
* The text of the "View All" button.
|
|
15
|
+
* @default '查看更多'
|
|
16
|
+
*/
|
|
17
|
+
viewAllButtonText?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface NotificationData extends NotifierData, NotificationConfigProps {
|
|
20
|
+
/**
|
|
21
|
+
* The tips to be appended to the notification.
|
|
22
|
+
* Only displayed when the type is 'drawer'.
|
|
23
|
+
*/
|
|
24
|
+
appendTips?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Other props of cancel button.
|
|
27
|
+
*/
|
|
28
|
+
cancelButtonProps?: ButtonProps;
|
|
29
|
+
/**
|
|
30
|
+
* Cancel button text.
|
|
31
|
+
*/
|
|
32
|
+
cancelButtonText?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Other props of confirm button.
|
|
35
|
+
*/
|
|
36
|
+
confirmButtonProps?: ButtonProps;
|
|
37
|
+
/**
|
|
38
|
+
* Confirm button text.
|
|
39
|
+
*/
|
|
40
|
+
confirmButtonText?: string;
|
|
41
|
+
/**
|
|
42
|
+
* The description of notification.
|
|
43
|
+
*/
|
|
44
|
+
description?: string;
|
|
45
|
+
/**
|
|
46
|
+
* The maximum number of notifications to be displayed.
|
|
47
|
+
* Only displayed when the type is 'notification'.
|
|
48
|
+
* @default 3
|
|
49
|
+
*/
|
|
50
|
+
maxVisibleNotifications?: number;
|
|
51
|
+
/**
|
|
52
|
+
* The callback function when the badge is clicked.
|
|
53
|
+
* Only displayed when the type is 'drawer'.
|
|
54
|
+
*/
|
|
55
|
+
onBadgeClick?: VoidFunction;
|
|
56
|
+
/**
|
|
57
|
+
* The callback function when the badge is selected.
|
|
58
|
+
* Only displayed when the type is 'drawer'.
|
|
59
|
+
*/
|
|
60
|
+
onBadgeSelect?: (option: DropdownOption) => void;
|
|
61
|
+
/**
|
|
62
|
+
* Cancel button click event handler. <br />
|
|
63
|
+
* If not provided, the event handler will fallback to a close function using `NotificationCenter.remove`.
|
|
64
|
+
*/
|
|
65
|
+
onCancel?: VoidFunction;
|
|
66
|
+
/**
|
|
67
|
+
* Confirm button click event handler. <br />
|
|
68
|
+
* If given, will render action button group.
|
|
69
|
+
*/
|
|
70
|
+
onConfirm?: VoidFunction;
|
|
71
|
+
/**
|
|
72
|
+
* The options of the badge.
|
|
73
|
+
* Only displayed when the type is 'drawer'.
|
|
74
|
+
*/
|
|
75
|
+
options?: DropdownOption[];
|
|
76
|
+
/**
|
|
77
|
+
* The tips to be prepended to the notification.
|
|
78
|
+
* Only displayed when the type is 'drawer'.
|
|
79
|
+
*/
|
|
80
|
+
prependTips?: string;
|
|
81
|
+
/**
|
|
82
|
+
* The identifier of the notification.
|
|
83
|
+
*/
|
|
84
|
+
reference?: Key;
|
|
85
|
+
/**
|
|
86
|
+
* The severity of the message.
|
|
87
|
+
* @default info
|
|
88
|
+
*/
|
|
89
|
+
severity?: NotificationSeverity;
|
|
90
|
+
/**
|
|
91
|
+
* The props of the badge.
|
|
92
|
+
* Only displayed when the type is 'drawer'.
|
|
93
|
+
*/
|
|
94
|
+
showBadge?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* The time stamp of notification on the drawer list.
|
|
97
|
+
* @default new Date().toLocaleTimeString()
|
|
98
|
+
*/
|
|
99
|
+
timeStamp?: string;
|
|
100
|
+
/**
|
|
101
|
+
* The locale of the time stamp.
|
|
102
|
+
* @default 'zh-TW'
|
|
103
|
+
*/
|
|
104
|
+
timeStampLocale?: string;
|
|
105
|
+
/**
|
|
106
|
+
* The title of notification.
|
|
107
|
+
*/
|
|
108
|
+
title?: string;
|
|
109
|
+
/**
|
|
110
|
+
* The type of notification.
|
|
111
|
+
* @default 'notification'
|
|
112
|
+
*/
|
|
113
|
+
type?: NotificationType;
|
|
114
|
+
}
|
|
115
|
+
export interface NotificationCenter extends FC<NotificationData>, Notifier<NotificationData, NotificationConfigProps>, Record<NotificationSeverity, (props?: Omit<NotificationData, 'severity'>) => Key> {
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The react component for `mezzanine` notification center.
|
|
119
|
+
*
|
|
120
|
+
* Use the API from the NotificationCenter instance such as `NotificationCenter.success` and `NotificationCenter.error`
|
|
121
|
+
* to display a notification globally.
|
|
122
|
+
*/
|
|
123
|
+
declare const NotificationCenter: NotificationCenter;
|
|
124
|
+
export default NotificationCenter;
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { useState, useRef, useMemo, useEffect, useCallback, Children, isValidElement, Fragment as Fragment$1 } from 'react';
|
|
4
|
+
import { offset, flip } from '@floating-ui/react-dom';
|
|
5
|
+
import { notificationIcons, notificationClasses } from '@mezzanine-ui/core/notification-center';
|
|
6
|
+
import { DotVerticalIcon, CloseIcon } from '@mezzanine-ui/icons';
|
|
7
|
+
import Button from '../Button/Button.js';
|
|
8
|
+
import ButtonGroup from '../Button/ButtonGroup.js';
|
|
9
|
+
import Typography from '../Typography/Typography.js';
|
|
10
|
+
import Icon from '../Icon/Icon.js';
|
|
11
|
+
import Popper from '../Popper/Popper.js';
|
|
12
|
+
import Dropdown from '../Dropdown/Dropdown.js';
|
|
13
|
+
import Badge from '../Badge/Badge.js';
|
|
14
|
+
import Slide from '../Transition/Slide.js';
|
|
15
|
+
import cx from 'clsx';
|
|
16
|
+
import { createNotifier } from '../Notifier/createNotifier.js';
|
|
17
|
+
|
|
18
|
+
const DEFAULT_MAX_VISIBLE_NOTIFICATIONS = 3;
|
|
19
|
+
const NotificationCenterContainer = ({ children }) => {
|
|
20
|
+
const notificationItems = useMemo(() => Children.toArray(children), [children]);
|
|
21
|
+
// Helper function to extract NotificationCenter component from Fragment or direct element
|
|
22
|
+
const extractNotificationCenter = (child) => {
|
|
23
|
+
if (!isValidElement(child)) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
// If it's a Fragment, check its children
|
|
27
|
+
if (child.type === Fragment$1) {
|
|
28
|
+
const fragmentProps = child.props;
|
|
29
|
+
const fragmentChildren = Children.toArray(fragmentProps.children);
|
|
30
|
+
const notificationCenter = fragmentChildren.find((fragmentChild) => isValidElement(fragmentChild));
|
|
31
|
+
return notificationCenter !== null && notificationCenter !== void 0 ? notificationCenter : null;
|
|
32
|
+
}
|
|
33
|
+
// If it's directly a NotificationCenter component
|
|
34
|
+
if (isValidElement(child)) {
|
|
35
|
+
return child;
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
};
|
|
39
|
+
const maxVisibleNotifications = useMemo(() => {
|
|
40
|
+
var _a;
|
|
41
|
+
const firstNotification = notificationItems
|
|
42
|
+
.map(extractNotificationCenter)
|
|
43
|
+
.find((notification) => notification !== null);
|
|
44
|
+
if (firstNotification) {
|
|
45
|
+
return (_a = firstNotification.props.maxVisibleNotifications) !== null && _a !== void 0 ? _a : DEFAULT_MAX_VISIBLE_NOTIFICATIONS;
|
|
46
|
+
}
|
|
47
|
+
return DEFAULT_MAX_VISIBLE_NOTIFICATIONS;
|
|
48
|
+
}, [notificationItems]);
|
|
49
|
+
const onViewAll = useMemo(() => {
|
|
50
|
+
const firstNotification = notificationItems
|
|
51
|
+
.map(extractNotificationCenter)
|
|
52
|
+
.find((notification) => notification !== null);
|
|
53
|
+
return firstNotification === null || firstNotification === void 0 ? void 0 : firstNotification.props.onViewAll;
|
|
54
|
+
}, [notificationItems]);
|
|
55
|
+
const viewAllButtonText = useMemo(() => {
|
|
56
|
+
var _a;
|
|
57
|
+
const firstNotification = notificationItems
|
|
58
|
+
.map(extractNotificationCenter)
|
|
59
|
+
.find((notification) => notification !== null);
|
|
60
|
+
return (_a = firstNotification === null || firstNotification === void 0 ? void 0 : firstNotification.props.viewAllButtonText) !== null && _a !== void 0 ? _a : '查看更多';
|
|
61
|
+
}, [notificationItems]);
|
|
62
|
+
const hasOverflow = notificationItems.length > maxVisibleNotifications;
|
|
63
|
+
const visibleItems = useMemo(() => notificationItems.slice(0, maxVisibleNotifications), [notificationItems, maxVisibleNotifications]);
|
|
64
|
+
const handleViewAll = () => {
|
|
65
|
+
NotificationCenter.destroy();
|
|
66
|
+
if (onViewAll) {
|
|
67
|
+
onViewAll();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
if (!notificationItems.length) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
return (jsxs(Fragment, { children: [visibleItems, hasOverflow
|
|
74
|
+
? (jsx("div", { className: notificationClasses.viewAllButton, children: jsx(Button, { onClick: handleViewAll, size: "main", variant: "base-secondary", className: notificationClasses.viewAllButtonText, children: viewAllButtonText }) }))
|
|
75
|
+
: null] }));
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* The react component for `mezzanine` notification center.
|
|
79
|
+
*
|
|
80
|
+
* Use the API from the NotificationCenter instance such as `NotificationCenter.success` and `NotificationCenter.error`
|
|
81
|
+
* to display a notification globally.
|
|
82
|
+
*/
|
|
83
|
+
const NotificationCenter = ((props) => {
|
|
84
|
+
const { type = 'notification', cancelButtonProps = {}, cancelButtonText = 'Cancel', confirmButtonProps = {}, confirmButtonText = 'Confirm', description, duration, onCancel: onCancelProp, onClose: onCloseProp, onConfirm: onConfirmProp, onExited: onExitedProp, reference, severity = 'info', title, timeStamp = new Date().toLocaleTimeString(), timeStampLocale = 'zh-TW', showBadge, onBadgeClick: onBadgeClickProp, options, onBadgeSelect: onBadgeSelectProp, prependTips, appendTips, ...restTransitionProps } = props;
|
|
85
|
+
const targetIcon = notificationIcons[severity];
|
|
86
|
+
const [openDropdown, setOpenDropdown] = useState(false);
|
|
87
|
+
const [open, setOpen] = useState(true);
|
|
88
|
+
const [timeStampAnchor, setTimeStampAnchor] = useState(null);
|
|
89
|
+
const timeStampRef = useRef(null);
|
|
90
|
+
const formattedTimeStamp = useMemo(() => {
|
|
91
|
+
try {
|
|
92
|
+
const timestampDate = new Date(timeStamp);
|
|
93
|
+
// Check if the time stamp is a valid date
|
|
94
|
+
if (isNaN(timestampDate.getTime())) {
|
|
95
|
+
return timeStamp;
|
|
96
|
+
}
|
|
97
|
+
const now = Date.now();
|
|
98
|
+
const diffInMs = timestampDate.getTime() - now;
|
|
99
|
+
const diffInSeconds = Math.round(diffInMs / 1000);
|
|
100
|
+
const diffInDays = Math.round(diffInSeconds / 86400);
|
|
101
|
+
if (Math.abs(diffInDays) <= 7) {
|
|
102
|
+
const rtf = new Intl.RelativeTimeFormat(timeStampLocale, { numeric: 'always' });
|
|
103
|
+
const units = [
|
|
104
|
+
{ unit: 'day', seconds: 86400 },
|
|
105
|
+
{ unit: 'hour', seconds: 3600 },
|
|
106
|
+
{ unit: 'minute', seconds: 60 },
|
|
107
|
+
];
|
|
108
|
+
for (const { unit, seconds } of units) {
|
|
109
|
+
const value = Math.round(diffInSeconds / seconds);
|
|
110
|
+
if (Math.abs(value) >= 1) {
|
|
111
|
+
return rtf.format(value, unit);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return 'now';
|
|
115
|
+
}
|
|
116
|
+
const hasTimeComponent = /:\d{2}/.test(timeStamp) || timeStamp.includes('T');
|
|
117
|
+
if (hasTimeComponent) {
|
|
118
|
+
const dateFormatter = new Intl.DateTimeFormat(timeStampLocale, {
|
|
119
|
+
year: 'numeric',
|
|
120
|
+
month: '2-digit',
|
|
121
|
+
day: '2-digit',
|
|
122
|
+
hour: '2-digit',
|
|
123
|
+
minute: '2-digit',
|
|
124
|
+
hour12: false,
|
|
125
|
+
});
|
|
126
|
+
return dateFormatter.format(timestampDate).replace(/\//g, '-');
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const dateFormatter = new Intl.DateTimeFormat(timeStampLocale, {
|
|
130
|
+
year: 'numeric',
|
|
131
|
+
month: '2-digit',
|
|
132
|
+
day: '2-digit',
|
|
133
|
+
});
|
|
134
|
+
return dateFormatter.format(timestampDate).replace(/\//g, '-');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (_a) {
|
|
138
|
+
return timeStamp;
|
|
139
|
+
}
|
|
140
|
+
}, [timeStamp, timeStampLocale]);
|
|
141
|
+
useEffect(() => {
|
|
142
|
+
if (open && duration) {
|
|
143
|
+
const timer = window.setTimeout(() => {
|
|
144
|
+
setOpen(false);
|
|
145
|
+
}, duration);
|
|
146
|
+
return () => {
|
|
147
|
+
window.clearTimeout(timer);
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}, [open, duration]);
|
|
151
|
+
const onBadgeClick = useCallback(() => {
|
|
152
|
+
if (onBadgeClickProp) {
|
|
153
|
+
onBadgeClickProp();
|
|
154
|
+
}
|
|
155
|
+
if (options && options.length > 0) {
|
|
156
|
+
setOpenDropdown(true);
|
|
157
|
+
}
|
|
158
|
+
}, [onBadgeClickProp, setOpenDropdown, options]);
|
|
159
|
+
const onClose = () => {
|
|
160
|
+
setOpen(false);
|
|
161
|
+
if (onCloseProp) {
|
|
162
|
+
onCloseProp(reference);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
const onConfirm = onConfirmProp
|
|
166
|
+
? () => {
|
|
167
|
+
setOpen(false);
|
|
168
|
+
onConfirmProp();
|
|
169
|
+
}
|
|
170
|
+
: undefined;
|
|
171
|
+
const onCancel = onCancelProp
|
|
172
|
+
? () => {
|
|
173
|
+
setOpen(false);
|
|
174
|
+
onCancelProp();
|
|
175
|
+
}
|
|
176
|
+
: undefined;
|
|
177
|
+
const onExited = (node) => {
|
|
178
|
+
if (onExitedProp) {
|
|
179
|
+
onExitedProp(node);
|
|
180
|
+
}
|
|
181
|
+
NotificationCenter.remove(reference);
|
|
182
|
+
};
|
|
183
|
+
const onSelect = useCallback((option) => {
|
|
184
|
+
if (onBadgeSelectProp) {
|
|
185
|
+
onBadgeSelectProp(option);
|
|
186
|
+
}
|
|
187
|
+
}, [onBadgeSelectProp]);
|
|
188
|
+
const handleNotificationMouseEnter = () => {
|
|
189
|
+
if (type === 'drawer') {
|
|
190
|
+
setTimeout(() => {
|
|
191
|
+
if (timeStampRef.current) {
|
|
192
|
+
setTimeStampAnchor(timeStampRef.current);
|
|
193
|
+
}
|
|
194
|
+
}, 0);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
const handleNotificationMouseLeave = () => {
|
|
198
|
+
if (type === 'drawer') {
|
|
199
|
+
setTimeStampAnchor(null);
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
const showConfirmButton = Boolean(confirmButtonText && onConfirmProp);
|
|
203
|
+
const showCancelButton = Boolean(cancelButtonText && (onCancelProp || onCloseProp));
|
|
204
|
+
const hideButtons = !(type === 'notification' && (showConfirmButton || showCancelButton));
|
|
205
|
+
const notificationContent = (jsxs("div", { className: cx(notificationClasses.host, notificationClasses.severity(severity), notificationClasses.type(type)), onMouseEnter: handleNotificationMouseEnter, onMouseLeave: handleNotificationMouseLeave, children: [targetIcon
|
|
206
|
+
? (jsx("div", { className: notificationClasses.iconContainer, children: jsx(Icon, { icon: targetIcon, className: notificationClasses.severityIcon }) }))
|
|
207
|
+
: null, jsxs("div", { className: notificationClasses.body, children: [jsxs("div", { className: notificationClasses.bodyContent, children: [jsx("h4", { className: notificationClasses.title, children: title }), jsx(Typography, { className: notificationClasses.content, children: description })] }), !hideButtons && (jsxs(ButtonGroup, { className: notificationClasses.action, children: [showConfirmButton
|
|
208
|
+
? (jsx(Button, { onClick: onConfirm, size: "minor", ...confirmButtonProps, children: confirmButtonText }))
|
|
209
|
+
: jsx(Fragment, {}), showCancelButton
|
|
210
|
+
? (jsx(Button, { onClick: onCancel || onClose, size: "minor", variant: "base-secondary", ...cancelButtonProps, children: cancelButtonText }))
|
|
211
|
+
: jsx(Fragment, {})] })), type === 'drawer' && (jsxs(Fragment, { children: [jsx(Popper, { anchor: timeStampAnchor, open: Boolean(timeStampAnchor), arrow: {
|
|
212
|
+
className: notificationClasses.timeStampPopperArrow,
|
|
213
|
+
enabled: true,
|
|
214
|
+
padding: 0,
|
|
215
|
+
}, style: {
|
|
216
|
+
zIndex: 'var(--mzn-z-index-popover)',
|
|
217
|
+
}, options: {
|
|
218
|
+
placement: 'bottom',
|
|
219
|
+
middleware: [
|
|
220
|
+
offset({ mainAxis: 8 }),
|
|
221
|
+
flip(),
|
|
222
|
+
],
|
|
223
|
+
}, children: jsx("div", { className: notificationClasses.timeStampPopper, children: jsx(Typography, { className: notificationClasses.timeStampText, children: timeStamp }) }) }), jsx(Typography, { ref: timeStampRef, className: notificationClasses.timeStamp, children: formattedTimeStamp })] }))] }), type === 'drawer'
|
|
224
|
+
? (jsx(Dropdown, { open: openDropdown, onClose: () => setOpenDropdown(false), onVisibilityChange: (open) => setOpenDropdown(open), options: options !== null && options !== void 0 ? options : [], onSelect: onSelect, placement: "bottom-end", zIndex: 'var(--mzn-z-index-popover)', children: jsxs(Button, { variant: "base-ghost", size: "minor", onClick: onClose, children: [showBadge && jsx(Badge, { variant: "dot-error" }), jsx(Icon, { icon: DotVerticalIcon, className: notificationClasses.closeIcon, size: 16, onClick: onBadgeClick })] }) }))
|
|
225
|
+
: (jsx(Icon, { icon: CloseIcon, className: notificationClasses.closeIcon, size: 16, onClick: onClose }))] }));
|
|
226
|
+
if (type === 'notification') {
|
|
227
|
+
return (jsxs(Fragment, { children: [prependTips && jsx(Typography, { className: notificationClasses.prependTips, children: prependTips }), jsx(Slide, { in: open, appear: true, onExited: onExited, ...restTransitionProps, children: notificationContent }), appendTips && jsx(Typography, { className: notificationClasses.appendTips, children: appendTips })] }));
|
|
228
|
+
}
|
|
229
|
+
return (jsxs(Fragment, { children: [prependTips && jsx(Typography, { className: notificationClasses.prependTips, children: prependTips }), notificationContent, appendTips && jsx(Typography, { className: notificationClasses.appendTips, children: appendTips })] }));
|
|
230
|
+
});
|
|
231
|
+
const { add: addNotifier, config, destroy, remove } = createNotifier({
|
|
232
|
+
duration: false,
|
|
233
|
+
render: (notif) => {
|
|
234
|
+
const { key, ...restNotif } = notif;
|
|
235
|
+
return (jsx(NotificationCenter, { ...restNotif, reference: key }, key));
|
|
236
|
+
},
|
|
237
|
+
renderContainer: (children) => (jsx(NotificationCenterContainer, { children: children })),
|
|
238
|
+
setRoot: (root) => {
|
|
239
|
+
root === null || root === void 0 ? void 0 : root.setAttribute('class', notificationClasses.root);
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
NotificationCenter.add = (notif) => {
|
|
243
|
+
if (notif.type === 'drawer') {
|
|
244
|
+
return 'NOT_SET';
|
|
245
|
+
}
|
|
246
|
+
return addNotifier(notif);
|
|
247
|
+
};
|
|
248
|
+
NotificationCenter.config = config;
|
|
249
|
+
NotificationCenter.destroy = destroy;
|
|
250
|
+
NotificationCenter.remove = remove;
|
|
251
|
+
['success', 'warning', 'error', 'info'].forEach((severity) => {
|
|
252
|
+
NotificationCenter[severity] = (props) => NotificationCenter.add({
|
|
253
|
+
...props,
|
|
254
|
+
severity: severity || 'info',
|
|
255
|
+
type: 'notification',
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
export { NotificationCenter as default };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { type ChangeEventHandler, type ComponentProps, type Key, type ReactElement } from 'react';
|
|
2
|
+
import { DrawerSize } from '@mezzanine-ui/core/drawer';
|
|
3
|
+
import { type IconDefinition } from '@mezzanine-ui/icons';
|
|
4
|
+
import { type DrawerProps } from '../Drawer';
|
|
5
|
+
import NotificationCenter, { type NotificationData } from './NotificationCenter';
|
|
6
|
+
type NotificationDataForDrawer = NotificationData & {
|
|
7
|
+
key: Key;
|
|
8
|
+
type: 'drawer';
|
|
9
|
+
};
|
|
10
|
+
type NotificationCenterDrawerPropsBase = Pick<DrawerProps, 'open' | 'onClose'> & {
|
|
11
|
+
/**
|
|
12
|
+
* The label of the all radio.
|
|
13
|
+
*/
|
|
14
|
+
allRadioLabel?: string;
|
|
15
|
+
/**
|
|
16
|
+
* The label of the custom radio.
|
|
17
|
+
*/
|
|
18
|
+
customRadioLabel?: string;
|
|
19
|
+
/**
|
|
20
|
+
* The default value of the radio group.
|
|
21
|
+
*/
|
|
22
|
+
defaultValue?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The size of the drawer.
|
|
25
|
+
* @default 'narrow'
|
|
26
|
+
*/
|
|
27
|
+
drawerSize?: DrawerSize;
|
|
28
|
+
/**
|
|
29
|
+
* The icon of the empty notification.
|
|
30
|
+
*/
|
|
31
|
+
emptyNotificationIcon?: IconDefinition;
|
|
32
|
+
/**
|
|
33
|
+
* The title of the empty notification.
|
|
34
|
+
*/
|
|
35
|
+
emptyNotificationTitle?: string;
|
|
36
|
+
/**
|
|
37
|
+
* The callback function when the custom button is clicked.
|
|
38
|
+
*/
|
|
39
|
+
onCustomButtonClick?: VoidFunction;
|
|
40
|
+
/**
|
|
41
|
+
* The callback function when the radio group value changes.
|
|
42
|
+
*/
|
|
43
|
+
onRadioChange?: ChangeEventHandler<HTMLInputElement>;
|
|
44
|
+
/**
|
|
45
|
+
* The label of the read radio.
|
|
46
|
+
*/
|
|
47
|
+
readRadioLabel?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Controls whether to display the toolbar.
|
|
50
|
+
* @default true
|
|
51
|
+
*/
|
|
52
|
+
showToolbar?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Controls whether to display the unread button.
|
|
55
|
+
* @default false
|
|
56
|
+
*/
|
|
57
|
+
showUnreadButton?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* The title of the drawer.
|
|
60
|
+
*/
|
|
61
|
+
title?: string;
|
|
62
|
+
/**
|
|
63
|
+
* The label of the unread radio.
|
|
64
|
+
*/
|
|
65
|
+
unreadRadioLabel?: string;
|
|
66
|
+
/**
|
|
67
|
+
* The value of the radio group.
|
|
68
|
+
*/
|
|
69
|
+
value?: string;
|
|
70
|
+
};
|
|
71
|
+
export type NotificationCenterDrawerProps = (NotificationCenterDrawerPropsBase & {
|
|
72
|
+
/**
|
|
73
|
+
* The children of the drawer.
|
|
74
|
+
* Use this when you want to manually render NotificationCenter components.
|
|
75
|
+
* Can be a single NotificationCenter element or an array of them.
|
|
76
|
+
*/
|
|
77
|
+
children: ReactElement<ComponentProps<typeof NotificationCenter>> | ReactElement<ComponentProps<typeof NotificationCenter>>[];
|
|
78
|
+
notificationList?: never;
|
|
79
|
+
}) | (NotificationCenterDrawerPropsBase & {
|
|
80
|
+
/**
|
|
81
|
+
* The list of notifications to render.
|
|
82
|
+
* Use this when you want to pass notification data and let the component render them.
|
|
83
|
+
* Each notification must have `key` and `type: 'drawer'`.
|
|
84
|
+
*/
|
|
85
|
+
notificationList: NotificationDataForDrawer[];
|
|
86
|
+
children?: never;
|
|
87
|
+
});
|
|
88
|
+
declare const NotificationCenterDrawer: (props: NotificationCenterDrawerProps) => import("react/jsx-runtime").JSX.Element;
|
|
89
|
+
export default NotificationCenterDrawer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './NotificationCenter.js';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
2
2
|
import type { ButtonProps } from '../Button';
|
|
3
|
+
import { DropdownProps } from '../Dropdown';
|
|
3
4
|
/**
|
|
4
5
|
* Single button configuration - only primary button is allowed
|
|
5
6
|
*/
|
|
@@ -41,14 +42,23 @@ type PageFooterStandardProps = PageFooterBaseProps & {
|
|
|
41
42
|
*/
|
|
42
43
|
type?: 'standard';
|
|
43
44
|
/**
|
|
44
|
-
*
|
|
45
|
-
* Children of the button.
|
|
45
|
+
* The text/label (children) for the supporting action button in the PageFooter annotation.
|
|
46
46
|
*/
|
|
47
|
-
|
|
47
|
+
supportingActionName?: ButtonProps['children'];
|
|
48
|
+
/**
|
|
49
|
+
* The HTML button type for the supporting action (e.g., 'button', 'submit', 'reset').
|
|
50
|
+
*/
|
|
51
|
+
supportingActionType?: ButtonProps['type'];
|
|
52
|
+
/**
|
|
53
|
+
* Click handler for the supporting action button in the PageFooter annotation.
|
|
54
|
+
*/
|
|
55
|
+
supportingActionOnClick?: ButtonProps['onClick'];
|
|
48
56
|
/**
|
|
49
|
-
*
|
|
57
|
+
* Visual style variant of the supporting action button in the PageFooter
|
|
58
|
+
* (for example, 'base-ghost', 'base-secondary').
|
|
59
|
+
* @default 'base-ghost'
|
|
50
60
|
*/
|
|
51
|
-
|
|
61
|
+
supportingActionVariant?: ButtonProps['variant'];
|
|
52
62
|
};
|
|
53
63
|
type PageFooterOverflowProps = PageFooterBaseProps & {
|
|
54
64
|
/**
|
|
@@ -57,13 +67,13 @@ type PageFooterOverflowProps = PageFooterBaseProps & {
|
|
|
57
67
|
type: 'overflow';
|
|
58
68
|
/**
|
|
59
69
|
* Overflow type: Icon for the icon-only button.
|
|
60
|
-
* @
|
|
70
|
+
* @default DotVerticalIcon
|
|
61
71
|
*/
|
|
62
|
-
|
|
72
|
+
supportingActionIcon?: ButtonProps['icon'];
|
|
63
73
|
/**
|
|
64
|
-
*
|
|
74
|
+
* Dropdown props for the supporting action button.
|
|
65
75
|
*/
|
|
66
|
-
|
|
76
|
+
dropdownProps: Partial<DropdownProps>;
|
|
67
77
|
};
|
|
68
78
|
type PageFooterInformationProps = PageFooterBaseProps & {
|
|
69
79
|
/**
|
package/PageFooter/PageFooter.js
CHANGED
|
@@ -4,11 +4,13 @@ import { pageFooterClasses } from '@mezzanine-ui/core/page-footer';
|
|
|
4
4
|
import Button from '../Button/Button.js';
|
|
5
5
|
import ButtonGroup from '../Button/ButtonGroup.js';
|
|
6
6
|
import Typography from '../Typography/Typography.js';
|
|
7
|
+
import { DotVerticalIcon } from '@mezzanine-ui/icons';
|
|
8
|
+
import Dropdown from '../Dropdown/Dropdown.js';
|
|
7
9
|
import cx from 'clsx';
|
|
8
10
|
|
|
9
11
|
const PageFooter = forwardRef(function PageFooter(props, ref) {
|
|
10
12
|
var _a;
|
|
11
|
-
const { actions,
|
|
13
|
+
const { actions, annotationClassName, className, type = 'standard', warningMessage, ...rest } = props;
|
|
12
14
|
// Filter out onAnnotationClick from rest props to avoid React warnings
|
|
13
15
|
if ('onAnnotationClick' in rest) {
|
|
14
16
|
delete rest.onAnnotationClick;
|
|
@@ -16,21 +18,19 @@ const PageFooter = forwardRef(function PageFooter(props, ref) {
|
|
|
16
18
|
const { children: primaryButtonText, ...restPrimaryButtonProps } = (_a = actions === null || actions === void 0 ? void 0 : actions.primaryButton) !== null && _a !== void 0 ? _a : {};
|
|
17
19
|
// Render annotation based on type
|
|
18
20
|
const renderAnnotation = () => {
|
|
19
|
-
if (!annotation)
|
|
20
|
-
return null;
|
|
21
21
|
switch (type) {
|
|
22
22
|
case 'standard': {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
: undefined, size: "main", variant: "base-ghost", children: annotation }));
|
|
23
|
+
const { supportingActionName, supportingActionType, supportingActionOnClick, supportingActionVariant = 'base-ghost', } = props;
|
|
24
|
+
return (jsx(Button, { size: "main", type: supportingActionType, onClick: supportingActionOnClick, variant: supportingActionVariant, children: supportingActionName }));
|
|
26
25
|
}
|
|
27
26
|
case 'overflow': {
|
|
28
|
-
|
|
29
|
-
return (jsx(
|
|
30
|
-
? props.onAnnotationClick
|
|
31
|
-
: undefined, size: "main", variant: "base-ghost" }));
|
|
27
|
+
const { supportingActionIcon, dropdownProps } = props;
|
|
28
|
+
return (jsx(Dropdown, { ...dropdownProps, options: dropdownProps.options || [], placement: dropdownProps.placement || 'top', children: jsx(Button, { type: "button", iconType: "icon-only", icon: supportingActionIcon || DotVerticalIcon, size: "main", variant: "base-ghost" }) }));
|
|
32
29
|
}
|
|
33
30
|
case 'information': {
|
|
31
|
+
const { annotation } = props;
|
|
32
|
+
if (!annotation)
|
|
33
|
+
return null;
|
|
34
34
|
return (jsx(Typography, { color: "text-neutral", variant: "caption", children: annotation }));
|
|
35
35
|
}
|
|
36
36
|
default:
|
package/PageHeader/PageHeader.js
CHANGED
|
@@ -27,20 +27,15 @@ const getBreadcrumbAndToolbar = (children) => {
|
|
|
27
27
|
}
|
|
28
28
|
else if (child.type === Button) {
|
|
29
29
|
backButtonOrLink = cloneElement(child, {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
src: ChevronLeftIcon,
|
|
33
|
-
},
|
|
30
|
+
iconType: 'icon-only',
|
|
31
|
+
icon: ChevronLeftIcon,
|
|
34
32
|
size: 'sub',
|
|
35
33
|
variant: 'base-tertiary',
|
|
36
34
|
});
|
|
37
35
|
}
|
|
38
36
|
else if (child.type === 'a') {
|
|
39
37
|
backButtonOrLink = cloneElement(child, {
|
|
40
|
-
children: (jsx(Button, { component: 'div', icon:
|
|
41
|
-
position: 'icon-only',
|
|
42
|
-
src: ChevronLeftIcon,
|
|
43
|
-
}, size: "sub", variant: "base-tertiary" })),
|
|
38
|
+
children: (jsx(Button, { component: 'div', iconType: "icon-only", icon: ChevronLeftIcon, size: "sub", variant: "base-tertiary" })),
|
|
44
39
|
});
|
|
45
40
|
}
|
|
46
41
|
else {
|
|
@@ -60,10 +55,7 @@ const PageHeader = forwardRef(function PageHeader(props, ref) {
|
|
|
60
55
|
const { children, className, description, onBackClick, title, titleComponent = 'h2', ...rest } = props;
|
|
61
56
|
const { backButtonOrLink, breadcrumb, pageToolbar } = getBreadcrumbAndToolbar(children);
|
|
62
57
|
// prop onBack takes precedence over backButtonOrLink
|
|
63
|
-
const backButton = onBackClick ? (jsx(Button, { icon:
|
|
64
|
-
position: 'icon-only',
|
|
65
|
-
src: ChevronLeftIcon,
|
|
66
|
-
}, onClick: onBackClick, size: "sub", variant: "base-tertiary" })) : (backButtonOrLink);
|
|
58
|
+
const backButton = onBackClick ? (jsx(Button, { iconType: "icon-only", icon: ChevronLeftIcon, onClick: onBackClick, size: "sub", variant: "base-tertiary" })) : (backButtonOrLink);
|
|
67
59
|
return (jsxs("header", { ...rest, className: cx(pageHeaderClasses.host, className), ref: ref, children: [breadcrumb, jsxs("span", { className: pageHeaderClasses.headerContent, children: [jsxs("span", { className: pageHeaderClasses.pageTitleWithIcon, children: [backButton && jsx("div", { children: backButton }), jsxs("div", { className: pageHeaderClasses.pageTitleText, children: [jsx(Typography, { align: "left", color: "text-neutral-solid", component: titleComponent, variant: "h2", children: title }), description && (jsx(Typography, { align: "left", color: "text-neutral", component: "p", variant: "caption", children: description }))] })] }), pageToolbar] })] }));
|
|
68
60
|
});
|
|
69
61
|
|