@mezzanine-ui/react 1.0.0-rc.5 → 1.0.0-rc.7
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/Accordion/Accordion.d.ts +36 -0
- package/Accordion/Accordion.js +37 -1
- package/AlertBanner/AlertBanner.d.ts +30 -1
- package/AlertBanner/AlertBanner.js +56 -12
- package/AutoComplete/AutoComplete.d.ts +75 -11
- package/AutoComplete/AutoComplete.js +145 -25
- package/AutoComplete/AutoCompleteInside.d.ts +54 -0
- package/AutoComplete/AutoCompleteInside.js +17 -0
- package/AutoComplete/useAutoCompleteKeyboard.d.ts +2 -1
- package/AutoComplete/useAutoCompleteKeyboard.js +4 -1
- package/Backdrop/Backdrop.d.ts +33 -1
- package/Backdrop/Backdrop.js +33 -1
- package/Badge/Badge.d.ts +26 -1
- package/Badge/Badge.js +26 -1
- package/Badge/typings.d.ts +15 -0
- package/Breadcrumb/BreadcrumbDropdown.d.ts +1 -1
- package/Breadcrumb/BreadcrumbOverflowMenuDropdown.d.ts +1 -1
- package/Breadcrumb/typings.d.ts +1 -1
- package/Button/Button.d.ts +26 -1
- package/Button/Button.js +33 -5
- package/COMPONENTS.md +267 -0
- package/Calendar/useCalendarControls.d.ts +18 -0
- package/Calendar/useCalendarControls.js +18 -0
- package/Card/FourThumbnailCard.js +1 -1
- package/Card/SingleThumbnailCard.js +1 -1
- package/Checkbox/Checkbox.d.ts +30 -1
- package/Checkbox/Checkbox.js +54 -4
- package/Checkbox/CheckboxGroup.d.ts +39 -1
- package/Checkbox/CheckboxGroup.js +49 -3
- package/Cropper/Cropper.d.ts +2 -2
- package/Cropper/Cropper.js +2 -3
- package/Cropper/CropperElement.js +1 -1
- package/Cropper/utils/cropper-calculations.d.ts +1 -1
- package/Cropper/utils/cropper-calculations.js +16 -14
- package/DatePicker/DatePicker.d.ts +36 -2
- package/DatePicker/DatePicker.js +36 -2
- package/DateRangePicker/useDateRangePickerValue.d.ts +24 -0
- package/DateRangePicker/useDateRangePickerValue.js +24 -0
- package/Description/Description.d.ts +1 -1
- package/Description/Description.js +1 -1
- package/Description/DescriptionTitle.d.ts +6 -1
- package/Description/DescriptionTitle.js +2 -2
- package/Drawer/Drawer.d.ts +78 -33
- package/Drawer/Drawer.js +72 -34
- package/Dropdown/Dropdown.d.ts +63 -1
- package/Dropdown/Dropdown.js +203 -9
- package/Dropdown/DropdownItem.d.ts +26 -2
- package/Dropdown/DropdownItem.js +91 -43
- package/Dropdown/DropdownItemCard.d.ts +3 -2
- package/Dropdown/DropdownItemCard.js +8 -5
- package/Dropdown/DropdownStatus.d.ts +2 -2
- package/Dropdown/DropdownStatus.js +3 -2
- package/Dropdown/dropdownKeydownHandler.d.ts +6 -0
- package/Dropdown/dropdownKeydownHandler.js +14 -7
- package/Empty/icons/EmptyMainInitialDataIcon.js +1 -1
- package/Empty/icons/EmptyMainNotificationIcon.js +1 -1
- package/Empty/icons/EmptyMainResultIcon.js +1 -1
- package/Empty/icons/EmptyMainSystemIcon.js +1 -1
- package/FilterArea/Filter.d.ts +25 -2
- package/FilterArea/Filter.js +43 -2
- package/FilterArea/FilterArea.d.ts +43 -4
- package/FilterArea/FilterArea.js +39 -4
- package/FilterArea/FilterAreaContext.d.ts +6 -0
- package/FilterArea/FilterAreaContext.js +6 -0
- package/FilterArea/FilterLine.d.ts +19 -0
- package/FilterArea/FilterLine.js +19 -0
- package/FilterArea/index.d.ts +2 -2
- package/FilterArea/index.js +1 -1
- package/Form/FormField.d.ts +43 -2
- package/Form/FormField.js +40 -3
- package/Form/typings.d.ts +2 -0
- package/Form/useAutoCompleteValueControl.d.ts +20 -0
- package/Form/useAutoCompleteValueControl.js +20 -0
- package/Form/useCheckboxControlValue.d.ts +19 -0
- package/Form/useCheckboxControlValue.js +19 -0
- package/Form/useControlValueState.d.ts +16 -0
- package/Form/useControlValueState.js +16 -0
- package/Form/useCustomControlValue.d.ts +17 -0
- package/Form/useCustomControlValue.js +17 -0
- package/Form/useInputControlValue.d.ts +19 -0
- package/Form/useInputControlValue.js +19 -0
- package/Form/useInputWithClearControlValue.d.ts +20 -0
- package/Form/useInputWithClearControlValue.js +20 -0
- package/Form/useRadioControlValue.d.ts +19 -0
- package/Form/useRadioControlValue.js +19 -0
- package/Form/useSelectValueControl.d.ts +19 -0
- package/Form/useSelectValueControl.js +19 -0
- package/Form/useSwitchControlValue.d.ts +18 -0
- package/Form/useSwitchControlValue.js +18 -0
- package/Icon/Icon.d.ts +23 -1
- package/Icon/Icon.js +23 -1
- package/Input/Input.d.ts +31 -1
- package/Input/Input.js +31 -1
- package/Input/SpinnerButton/SpinnerButton.js +1 -1
- package/Message/Message.d.ts +56 -6
- package/Message/Message.js +59 -52
- package/Modal/Modal.d.ts +76 -4
- package/Modal/Modal.js +117 -6
- package/Modal/ModalBodyForVerification.js +3 -1
- package/Modal/ModalFooter.d.ts +21 -6
- package/Modal/ModalHeader.d.ts +50 -11
- package/Modal/ModalHeader.js +1 -1
- package/Modal/index.d.ts +1 -1
- package/Navigation/Navigation.js +20 -11
- package/Navigation/NavigationHeader.js +2 -1
- package/Navigation/NavigationIconButton.d.ts +8 -0
- package/Navigation/NavigationIconButton.js +2 -2
- package/Navigation/NavigationOption.js +6 -3
- package/Navigation/NavigationOverflowMenu.js +9 -6
- package/Navigation/NavigationUserMenu.js +3 -1
- package/Navigation/context.d.ts +1 -0
- package/NotificationCenter/NotificationCenter.d.ts +59 -9
- package/NotificationCenter/NotificationCenter.js +150 -54
- package/NotificationCenter/NotificationCenterDrawer.d.ts +56 -6
- package/NotificationCenter/NotificationCenterDrawer.js +6 -8
- package/NotificationCenter/index.d.ts +1 -1
- package/OverflowTooltip/OverflowTooltip.js +46 -5
- package/PageFooter/PageFooter.d.ts +1 -1
- package/PageFooter/PageFooter.js +8 -16
- package/Pagination/Pagination.d.ts +38 -1
- package/Pagination/Pagination.js +38 -1
- package/Pagination/PaginationPageSize.js +1 -1
- package/Pagination/usePagination.d.ts +20 -0
- package/Pagination/usePagination.js +20 -0
- package/Progress/Progress.d.ts +24 -1
- package/Progress/Progress.js +24 -1
- package/README.md +82 -0
- package/Radio/Radio.d.ts +35 -1
- package/Radio/Radio.js +50 -12
- package/Radio/RadioGroup.d.ts +2 -2
- package/Radio/RadioGroupContext.d.ts +3 -2
- package/Section/SectionGroup.d.ts +20 -0
- package/Section/SectionGroup.js +16 -0
- package/Section/index.d.ts +2 -0
- package/Section/index.js +1 -0
- package/Select/Select.d.ts +55 -1
- package/Select/Select.js +37 -2
- package/Select/typings.d.ts +9 -0
- package/{Selection/Selection.d.ts → SelectionCard/SelectionCard.d.ts} +23 -11
- package/{Selection/Selection.js → SelectionCard/SelectionCard.js} +14 -14
- package/SelectionCard/SelectionCardGroup.d.ts +28 -0
- package/SelectionCard/index.d.ts +12 -0
- package/SelectionCard/index.js +5 -0
- package/Separator/Separator.d.ts +19 -1
- package/Separator/Separator.js +19 -1
- package/Slider/Slider.d.ts +11 -0
- package/Slider/useSlider.d.ts +21 -0
- package/Spin/Spin.d.ts +14 -5
- package/Spin/Spin.js +6 -8
- package/Stepper/Stepper.d.ts +34 -1
- package/Stepper/Stepper.js +34 -1
- package/Stepper/useStepper.d.ts +18 -0
- package/Stepper/useStepper.js +18 -0
- package/Tab/Tab.d.ts +33 -1
- package/Tab/Tab.js +33 -1
- package/Table/Table.d.ts +51 -3
- package/Table/Table.js +52 -4
- package/Table/hooks/useTableDataSource.d.ts +4 -4
- package/Table/hooks/useTableDataSource.js +1 -1
- package/Tag/Tag.d.ts +27 -1
- package/Tag/Tag.js +27 -1
- package/Tag/typings.d.ts +28 -0
- package/Textarea/Textarea.d.ts +28 -1
- package/Textarea/Textarea.js +25 -1
- package/TimePicker/TimePicker.js +1 -1
- package/TimeRangePicker/TimeRangePicker.js +1 -1
- package/Toggle/Toggle.d.ts +34 -1
- package/Toggle/Toggle.js +34 -1
- package/Tooltip/Tooltip.d.ts +39 -1
- package/Tooltip/Tooltip.js +39 -1
- package/Tooltip/useDelayMouseEnterLeave.d.ts +17 -0
- package/Tooltip/useDelayMouseEnterLeave.js +17 -0
- package/Typography/Typography.d.ts +23 -1
- package/Typography/Typography.js +23 -1
- package/Upload/Upload.d.ts +13 -7
- package/Upload/Upload.js +55 -20
- package/Upload/UploadItem.d.ts +3 -3
- package/Upload/UploadItem.js +11 -8
- package/Upload/UploadPictureCard.d.ts +5 -0
- package/Upload/UploadPictureCard.js +10 -6
- package/Upload/Uploader.d.ts +32 -31
- package/Upload/Uploader.js +10 -9
- package/hooks/useClickAway.d.ts +16 -0
- package/hooks/useClickAway.js +16 -0
- package/hooks/useComposeRefs.d.ts +15 -0
- package/hooks/useComposeRefs.js +15 -0
- package/hooks/useDocumentEscapeKeyDown.d.ts +15 -0
- package/hooks/useDocumentEscapeKeyDown.js +15 -0
- package/hooks/useDocumentEvents.d.ts +16 -0
- package/hooks/useDocumentEvents.js +16 -0
- package/hooks/useDocumentTabKeyDown.d.ts +15 -0
- package/hooks/useDocumentTabKeyDown.js +15 -0
- package/hooks/useIsomorphicLayoutEffect.d.ts +16 -0
- package/hooks/useIsomorphicLayoutEffect.js +16 -0
- package/hooks/useLastCallback.d.ts +15 -0
- package/hooks/useLastCallback.js +15 -0
- package/hooks/useLastValue.d.ts +18 -0
- package/hooks/useLastValue.js +18 -0
- package/hooks/usePreviousValue.d.ts +14 -0
- package/hooks/usePreviousValue.js +14 -0
- package/hooks/useScrollLock.d.ts +6 -4
- package/hooks/useScrollLock.js +6 -4
- package/hooks/useTopStack.d.ts +17 -0
- package/hooks/useTopStack.js +17 -0
- package/hooks/useWindowWidth.d.ts +14 -0
- package/hooks/useWindowWidth.js +14 -0
- package/index.d.ts +6 -4
- package/index.js +3 -2
- package/llms.txt +200 -0
- package/package.json +5 -4
- package/Selection/SelectionGroup.d.ts +0 -28
- package/Selection/index.d.ts +0 -12
- package/Selection/index.js +0 -5
package/Modal/Modal.d.ts
CHANGED
|
@@ -3,7 +3,8 @@ import { ModalContainerProps } from './useModalContainer';
|
|
|
3
3
|
import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
4
4
|
import { ModalHeaderProps } from './ModalHeader';
|
|
5
5
|
import { ModalFooterProps } from './ModalFooter';
|
|
6
|
-
|
|
6
|
+
export type ModalHeaderLayoutProps = Pick<ModalHeaderProps, 'statusTypeIconLayout' | 'titleAlign' | 'supportingTextAlign'>;
|
|
7
|
+
interface CommonModalProps extends Omit<ModalContainerProps, 'children'>, Pick<NativeElementPropsWithoutKeyAndRef<'div'>, 'children'>, Partial<Omit<ModalFooterProps, 'cancelText' | 'children' | 'className' | 'confirmText' | 'showCancelButton'>> {
|
|
7
8
|
/**
|
|
8
9
|
* The custom class name applied to the modal container.
|
|
9
10
|
*/
|
|
@@ -29,6 +30,15 @@ interface CommonModalProps extends Omit<ModalContainerProps, 'children'>, Pick<N
|
|
|
29
30
|
* @default true
|
|
30
31
|
*/
|
|
31
32
|
showDismissButton?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Whether to show status type icon.
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
showStatusTypeIcon?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Supporting text displayed below the title.
|
|
40
|
+
*/
|
|
41
|
+
supportingText?: string;
|
|
32
42
|
}
|
|
33
43
|
interface ExtendedSplitModalProps extends CommonModalProps {
|
|
34
44
|
/**
|
|
@@ -41,6 +51,13 @@ interface ExtendedSplitModalProps extends CommonModalProps {
|
|
|
41
51
|
* Required when modalType is 'extendedSplit'.
|
|
42
52
|
*/
|
|
43
53
|
extendedSplitRightSideContent: React.ReactNode;
|
|
54
|
+
/**
|
|
55
|
+
* Controls which side the sidebar panel (narrow column with footer) appears on.
|
|
56
|
+
* - `'left'`: sidebar on the left, wide content on the right
|
|
57
|
+
* - `'right'`: wide content on the left, sidebar on the right
|
|
58
|
+
* @default 'right'
|
|
59
|
+
*/
|
|
60
|
+
extendedSplitSidebarPosition?: 'left' | 'right';
|
|
44
61
|
/**
|
|
45
62
|
* Controls the type/layout of the modal.
|
|
46
63
|
* - 'extendedSplit': Modal with split layout (footer inside left content)
|
|
@@ -64,6 +81,10 @@ interface OtherModalProps extends CommonModalProps {
|
|
|
64
81
|
* Cannot be provided when modalType is not 'extendedSplit'.
|
|
65
82
|
*/
|
|
66
83
|
extendedSplitRightSideContent?: never;
|
|
84
|
+
/**
|
|
85
|
+
* 此模式下不適用。
|
|
86
|
+
*/
|
|
87
|
+
extendedSplitSidebarPosition?: never;
|
|
67
88
|
/**
|
|
68
89
|
* Controls the type/layout of the modal.
|
|
69
90
|
* - 'standard': Default modal with body container
|
|
@@ -102,6 +123,7 @@ type ModalHeaderPropsWithoutHeader = {
|
|
|
102
123
|
*/
|
|
103
124
|
title?: never;
|
|
104
125
|
};
|
|
126
|
+
export type ModalFooterCancelProps = Pick<ModalFooterProps, 'cancelText' | 'showCancelButton'>;
|
|
105
127
|
type ModalFooterPropsWithFooter = {
|
|
106
128
|
/**
|
|
107
129
|
* Whether to show modal footer.
|
|
@@ -111,7 +133,7 @@ type ModalFooterPropsWithFooter = {
|
|
|
111
133
|
* The confirm button text of the modal footer (required when showModalFooter is true).
|
|
112
134
|
*/
|
|
113
135
|
confirmText: string;
|
|
114
|
-
};
|
|
136
|
+
} & ModalFooterCancelProps;
|
|
115
137
|
type ModalFooterPropsWithoutFooter = {
|
|
116
138
|
/**
|
|
117
139
|
* Whether to show modal footer.
|
|
@@ -123,10 +145,60 @@ type ModalFooterPropsWithoutFooter = {
|
|
|
123
145
|
* Cannot be provided when showModalFooter is false.
|
|
124
146
|
*/
|
|
125
147
|
confirmText?: never;
|
|
148
|
+
/**
|
|
149
|
+
* 此模式下不適用。
|
|
150
|
+
*/
|
|
151
|
+
cancelText?: never;
|
|
152
|
+
/**
|
|
153
|
+
* 此模式下不適用。
|
|
154
|
+
*/
|
|
155
|
+
showCancelButton?: never;
|
|
126
156
|
};
|
|
127
|
-
export type ModalProps = BaseModalProps & ((ModalHeaderPropsWithHeader & ModalFooterPropsWithFooter) | (ModalHeaderPropsWithHeader & ModalFooterPropsWithoutFooter) | (ModalHeaderPropsWithoutHeader & ModalFooterPropsWithFooter) | (ModalHeaderPropsWithoutHeader & ModalFooterPropsWithoutFooter));
|
|
157
|
+
export type ModalProps = BaseModalProps & ModalHeaderLayoutProps & ((ModalHeaderPropsWithHeader & ModalFooterPropsWithFooter) | (ModalHeaderPropsWithHeader & ModalFooterPropsWithoutFooter) | (ModalHeaderPropsWithoutHeader & ModalFooterPropsWithFooter) | (ModalHeaderPropsWithoutHeader & ModalFooterPropsWithoutFooter));
|
|
128
158
|
/**
|
|
129
|
-
*
|
|
159
|
+
* 對話框元件,以 Backdrop 遮罩呈現需要使用者互動或確認的浮動視窗。
|
|
160
|
+
*
|
|
161
|
+
* 透過 `showModalHeader` 與 `showModalFooter` 分別啟用標題列與操作列,
|
|
162
|
+
* `modalStatusType` 可在標題旁顯示狀態圖示(`info`、`success`、`warning`、`error`)。
|
|
163
|
+
* `modalType` 支援 `standard`、`extended`、`mediaPreview`、`verification` 及 `extendedSplit` 佈局,
|
|
164
|
+
* 其中 `extendedSplit` 需同時傳入 `extendedSplitLeftSideContent` 與 `extendedSplitRightSideContent`。
|
|
165
|
+
* `size` 可選 `regular`、`large`、`wide` 等尺寸,`fullScreen` 則強制全螢幕顯示。
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```tsx
|
|
169
|
+
* import Modal from '@mezzanine-ui/react/Modal';
|
|
170
|
+
*
|
|
171
|
+
* // 基本對話框(含標題與操作列)
|
|
172
|
+
* <Modal
|
|
173
|
+
* open={isOpen}
|
|
174
|
+
* onClose={() => setIsOpen(false)}
|
|
175
|
+
* showModalHeader
|
|
176
|
+
* title="確認刪除"
|
|
177
|
+
* showModalFooter
|
|
178
|
+
* confirmText="確認"
|
|
179
|
+
* cancelText="取消"
|
|
180
|
+
* onConfirm={handleConfirm}
|
|
181
|
+
* onCancel={() => setIsOpen(false)}
|
|
182
|
+
* >
|
|
183
|
+
* <p>此操作無法復原,確定要刪除嗎?</p>
|
|
184
|
+
* </Modal>
|
|
185
|
+
*
|
|
186
|
+
* // 帶狀態圖示的對話框
|
|
187
|
+
* <Modal
|
|
188
|
+
* open={isOpen}
|
|
189
|
+
* onClose={() => setIsOpen(false)}
|
|
190
|
+
* showModalHeader
|
|
191
|
+
* title="操作成功"
|
|
192
|
+
* showStatusTypeIcon
|
|
193
|
+
* modalStatusType="success"
|
|
194
|
+
* showModalFooter
|
|
195
|
+
* confirmText="關閉"
|
|
196
|
+
* onConfirm={() => setIsOpen(false)}
|
|
197
|
+
* />
|
|
198
|
+
* ```
|
|
199
|
+
*
|
|
200
|
+
* @see {@link Drawer} 從側邊滑入的抽屜式對話框元件
|
|
201
|
+
* @see {@link useModalContainer} 用於自訂 Modal 掛載容器的 Hook
|
|
130
202
|
*/
|
|
131
203
|
declare const Modal: import("react").ForwardRefExoticComponent<ModalProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
132
204
|
export default Modal;
|
package/Modal/Modal.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { modalClasses } from '@mezzanine-ui/core/modal';
|
|
3
|
-
import { forwardRef, useMemo } from 'react';
|
|
3
|
+
import { forwardRef, useRef, useState, useCallback, useMemo } from 'react';
|
|
4
4
|
import { ModalControlContext } from './ModalControl.js';
|
|
5
5
|
import useModalContainer from './useModalContainer.js';
|
|
6
6
|
import ModalHeader from './ModalHeader.js';
|
|
@@ -9,23 +9,134 @@ import ClearActions from '../ClearActions/ClearActions.js';
|
|
|
9
9
|
import cx from 'clsx';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* 對話框元件,以 Backdrop 遮罩呈現需要使用者互動或確認的浮動視窗。
|
|
13
|
+
*
|
|
14
|
+
* 透過 `showModalHeader` 與 `showModalFooter` 分別啟用標題列與操作列,
|
|
15
|
+
* `modalStatusType` 可在標題旁顯示狀態圖示(`info`、`success`、`warning`、`error`)。
|
|
16
|
+
* `modalType` 支援 `standard`、`extended`、`mediaPreview`、`verification` 及 `extendedSplit` 佈局,
|
|
17
|
+
* 其中 `extendedSplit` 需同時傳入 `extendedSplitLeftSideContent` 與 `extendedSplitRightSideContent`。
|
|
18
|
+
* `size` 可選 `regular`、`large`、`wide` 等尺寸,`fullScreen` 則強制全螢幕顯示。
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* import Modal from '@mezzanine-ui/react/Modal';
|
|
23
|
+
*
|
|
24
|
+
* // 基本對話框(含標題與操作列)
|
|
25
|
+
* <Modal
|
|
26
|
+
* open={isOpen}
|
|
27
|
+
* onClose={() => setIsOpen(false)}
|
|
28
|
+
* showModalHeader
|
|
29
|
+
* title="確認刪除"
|
|
30
|
+
* showModalFooter
|
|
31
|
+
* confirmText="確認"
|
|
32
|
+
* cancelText="取消"
|
|
33
|
+
* onConfirm={handleConfirm}
|
|
34
|
+
* onCancel={() => setIsOpen(false)}
|
|
35
|
+
* >
|
|
36
|
+
* <p>此操作無法復原,確定要刪除嗎?</p>
|
|
37
|
+
* </Modal>
|
|
38
|
+
*
|
|
39
|
+
* // 帶狀態圖示的對話框
|
|
40
|
+
* <Modal
|
|
41
|
+
* open={isOpen}
|
|
42
|
+
* onClose={() => setIsOpen(false)}
|
|
43
|
+
* showModalHeader
|
|
44
|
+
* title="操作成功"
|
|
45
|
+
* showStatusTypeIcon
|
|
46
|
+
* modalStatusType="success"
|
|
47
|
+
* showModalFooter
|
|
48
|
+
* confirmText="關閉"
|
|
49
|
+
* onConfirm={() => setIsOpen(false)}
|
|
50
|
+
* />
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @see {@link Drawer} 從側邊滑入的抽屜式對話框元件
|
|
54
|
+
* @see {@link useModalContainer} 用於自訂 Modal 掛載容器的 Hook
|
|
13
55
|
*/
|
|
14
56
|
const Modal = forwardRef(function Modal(props, ref) {
|
|
15
|
-
const { actionsButtonLayout, annotation, auxiliaryContentButtonProps, auxiliaryContentButtonText, auxiliaryContentChecked, auxiliaryContentLabel, auxiliaryContentOnChange, auxiliaryContentOnClick, auxiliaryContentType, backdropClassName, cancelButtonProps, cancelText, children, className, confirmButtonProps, confirmText, container, disableCloseOnBackdropClick = false, disableCloseOnEscapeKeyDown = false, disablePortal = false, extendedSplitLeftSideContent, extendedSplitRightSideContent, fullScreen = false, loading = false, modalStatusType = 'info', modalType = 'standard', onBackdropClick, onCancel, onClose, onConfirm, open, passwordButtonProps, passwordButtonText, passwordChecked, passwordCheckedLabel, passwordCheckedOnChange, passwordOnClick, showCancelButton, showDismissButton = true, showModalFooter = false, showModalHeader, showStatusTypeIcon, size = 'regular', statusTypeIconLayout, supportingText, supportingTextAlign, title, titleAlign, ...rest } = props;
|
|
57
|
+
const { actionsButtonLayout, annotation, auxiliaryContentButtonProps, auxiliaryContentButtonText, auxiliaryContentChecked, auxiliaryContentLabel, auxiliaryContentOnChange, auxiliaryContentOnClick, auxiliaryContentType, backdropClassName, cancelButtonProps, cancelText, children, className, confirmButtonProps, confirmText, container, disableCloseOnBackdropClick = false, disableCloseOnEscapeKeyDown = false, disablePortal = false, extendedSplitLeftSideContent, extendedSplitRightSideContent, extendedSplitSidebarPosition = 'right', fullScreen = false, loading = false, modalStatusType = 'info', modalType = 'standard', onBackdropClick, onCancel, onClose, onConfirm, open, passwordButtonProps, passwordButtonText, passwordChecked, passwordCheckedLabel, passwordCheckedOnChange, passwordOnClick, showCancelButton, showDismissButton = true, showModalFooter = false, showModalHeader, showStatusTypeIcon, size = 'regular', statusTypeIconLayout, supportingText, supportingTextAlign, title, titleAlign, ...rest } = props;
|
|
58
|
+
const bodyContentRef = useRef(null);
|
|
59
|
+
const [hasTopSeparator, setHasTopSeparator] = useState(false);
|
|
60
|
+
const [hasBottomSeparator, setHasBottomSeparator] = useState(false);
|
|
61
|
+
const scrollCleanupRef = useRef(null);
|
|
62
|
+
const handleBodyContainerRef = useCallback((node) => {
|
|
63
|
+
if (scrollCleanupRef.current) {
|
|
64
|
+
scrollCleanupRef.current();
|
|
65
|
+
scrollCleanupRef.current = null;
|
|
66
|
+
}
|
|
67
|
+
if (!node) {
|
|
68
|
+
setHasTopSeparator(false);
|
|
69
|
+
setHasBottomSeparator(false);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const checkScroll = () => {
|
|
73
|
+
const { scrollTop, scrollHeight, clientHeight } = node;
|
|
74
|
+
setHasTopSeparator(scrollTop > 0);
|
|
75
|
+
setHasBottomSeparator(scrollTop + clientHeight < scrollHeight);
|
|
76
|
+
};
|
|
77
|
+
const rafId = requestAnimationFrame(checkScroll);
|
|
78
|
+
node.addEventListener('scroll', checkScroll);
|
|
79
|
+
const observer = new ResizeObserver(checkScroll);
|
|
80
|
+
observer.observe(node);
|
|
81
|
+
const content = bodyContentRef.current;
|
|
82
|
+
if (content) {
|
|
83
|
+
observer.observe(content);
|
|
84
|
+
}
|
|
85
|
+
scrollCleanupRef.current = () => {
|
|
86
|
+
cancelAnimationFrame(rafId);
|
|
87
|
+
node.removeEventListener('scroll', checkScroll);
|
|
88
|
+
observer.disconnect();
|
|
89
|
+
};
|
|
90
|
+
}, []);
|
|
16
91
|
const modalControl = useMemo(() => ({
|
|
17
92
|
loading,
|
|
18
93
|
modalStatusType: modalStatusType,
|
|
19
94
|
}), [loading, modalStatusType]);
|
|
20
95
|
const { Container: ModalContainer } = useModalContainer();
|
|
21
|
-
const renderModalFooter = () => (jsx(ModalFooter, {
|
|
96
|
+
const renderModalFooter = () => (jsx(ModalFooter, { ...{
|
|
97
|
+
actionsButtonLayout,
|
|
98
|
+
annotation,
|
|
99
|
+
auxiliaryContentButtonProps,
|
|
100
|
+
auxiliaryContentButtonText,
|
|
101
|
+
auxiliaryContentChecked,
|
|
102
|
+
auxiliaryContentLabel,
|
|
103
|
+
auxiliaryContentOnChange,
|
|
104
|
+
auxiliaryContentOnClick,
|
|
105
|
+
auxiliaryContentType,
|
|
106
|
+
cancelButtonProps,
|
|
107
|
+
cancelText,
|
|
108
|
+
confirmButtonProps,
|
|
109
|
+
confirmText: confirmText,
|
|
110
|
+
loading,
|
|
111
|
+
onCancel,
|
|
112
|
+
onConfirm,
|
|
113
|
+
passwordButtonProps,
|
|
114
|
+
passwordButtonText,
|
|
115
|
+
passwordChecked,
|
|
116
|
+
passwordCheckedLabel,
|
|
117
|
+
passwordCheckedOnChange,
|
|
118
|
+
passwordOnClick,
|
|
119
|
+
showCancelButton,
|
|
120
|
+
} }));
|
|
22
121
|
return (jsx(ModalControlContext.Provider, { value: modalControl, children: jsx(ModalContainer, { className: backdropClassName, container: container, disableCloseOnBackdropClick: disableCloseOnBackdropClick, disableCloseOnEscapeKeyDown: disableCloseOnEscapeKeyDown, disablePortal: disablePortal, onBackdropClick: onBackdropClick, onClose: onClose, open: open, ref: ref, children: jsxs("div", { ...rest, className: cx(modalClasses.host, modalClasses.modalStatusType(modalStatusType), modalClasses.size(size), {
|
|
23
122
|
[modalClasses.fullScreen]: fullScreen,
|
|
24
123
|
[modalClasses.withCloseIcon]: showDismissButton,
|
|
25
|
-
}, className), role: "dialog", children: [showModalHeader && (jsx(ModalHeader, {
|
|
124
|
+
}, className), role: "dialog", children: [showModalHeader && (jsx(ModalHeader, { ...{
|
|
125
|
+
showStatusTypeIcon,
|
|
126
|
+
statusTypeIconLayout,
|
|
127
|
+
supportingText,
|
|
128
|
+
supportingTextAlign,
|
|
129
|
+
title: title,
|
|
130
|
+
titleAlign,
|
|
131
|
+
} })), modalType === 'extendedSplit' && (jsxs("div", { className: cx(modalClasses.modalBodyContainerExtendedSplit, {
|
|
132
|
+
[modalClasses.modalBodyContainerExtendedSplitSidebarLeft]: extendedSplitSidebarPosition === 'left',
|
|
133
|
+
}), children: [jsx("div", { className: modalClasses.modalBodyContainerExtendedSplitRight, children: extendedSplitRightSideContent }), jsxs("div", { className: modalClasses.modalBodyContainerExtendedSplitLeft, children: [jsx("div", { className: modalClasses.modalBodyContainerExtendedSplitLeftSideContent, children: extendedSplitLeftSideContent }), showModalFooter && renderModalFooter()] })] })), (modalType === 'standard' ||
|
|
26
134
|
modalType === 'verification' ||
|
|
27
135
|
modalType === 'extended' ||
|
|
28
|
-
modalType === 'mediaPreview') && (jsxs(Fragment, { children: [children && (jsx("div", {
|
|
136
|
+
modalType === 'mediaPreview') && (jsxs(Fragment, { children: [children && (jsx("div", { ref: handleBodyContainerRef, className: cx(modalClasses.modalBodyContainer, {
|
|
137
|
+
[modalClasses.modalBodyContainerWithTopSeparator]: modalType === 'extended' || hasTopSeparator,
|
|
138
|
+
[modalClasses.modalBodyContainerWithBottomSeparator]: modalType === 'extended' || hasBottomSeparator,
|
|
139
|
+
}), children: jsx("div", { ref: bodyContentRef, children: children }) })), showModalFooter && renderModalFooter()] })), showDismissButton && (jsx(ClearActions, { onClick: onClose, className: modalClasses.closeIcon, variant: "base" }))] }) }) }));
|
|
29
140
|
});
|
|
30
141
|
|
|
31
142
|
export { Modal as default };
|
|
@@ -89,7 +89,9 @@ const ModalBodyForVerification = forwardRef(function ModalBodyForVerification(pr
|
|
|
89
89
|
const handleInputChange = (index, e) => {
|
|
90
90
|
handleChange(index, e.target.value);
|
|
91
91
|
};
|
|
92
|
-
return (jsxs("div", { ...rest, ref: ref, className: cx(modalClasses.modalBodyVerification, className), children: [jsx("div", { className: modalClasses.modalBodyVerificationInputs,
|
|
92
|
+
return (jsxs("div", { ...rest, ref: ref, className: cx(modalClasses.modalBodyVerification, className), children: [jsx("div", { className: cx(modalClasses.modalBodyVerificationInputs, {
|
|
93
|
+
[modalClasses.modalBodyVerificationInputsExtended]: length > 4,
|
|
94
|
+
}), children: Array.from({ length }).map((_, index) => (jsx("input", { ref: (el) => {
|
|
93
95
|
inputRefs.current[index] = el;
|
|
94
96
|
}, type: "text", inputMode: "numeric", maxLength: 1, value: codes[index] || '', onChange: (e) => handleInputChange(index, e), onKeyDown: (e) => handleKeyDown(index, e), onPaste: handlePaste, className: cx(modalClasses.modalBodyVerificationInput, {
|
|
95
97
|
[modalClasses.modalBodyVerificationInputError]: error,
|
package/Modal/ModalFooter.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
3
3
|
import { ButtonProps } from '../Button/Button';
|
|
4
|
-
|
|
4
|
+
interface ModalFooterBaseProps extends NativeElementPropsWithoutKeyAndRef<'div'> {
|
|
5
5
|
/**
|
|
6
6
|
* Layout of action buttons.
|
|
7
7
|
* - 'fixed': Buttons maintain fixed width
|
|
@@ -58,10 +58,6 @@ export interface ModalFooterProps extends NativeElementPropsWithoutKeyAndRef<'di
|
|
|
58
58
|
* Additional props for the cancel button.
|
|
59
59
|
*/
|
|
60
60
|
cancelButtonProps?: ButtonProps;
|
|
61
|
-
/**
|
|
62
|
-
* Text content of the cancel button.
|
|
63
|
-
*/
|
|
64
|
-
cancelText?: ReactNode;
|
|
65
61
|
/**
|
|
66
62
|
* Additional props for the confirm button.
|
|
67
63
|
*/
|
|
@@ -112,12 +108,31 @@ export interface ModalFooterProps extends NativeElementPropsWithoutKeyAndRef<'di
|
|
|
112
108
|
* Only used when auxiliaryContentType is 'password'.
|
|
113
109
|
*/
|
|
114
110
|
passwordOnClick?: ButtonProps['onClick'];
|
|
111
|
+
}
|
|
112
|
+
interface ModalFooterWithCancelButtonProps extends ModalFooterBaseProps {
|
|
113
|
+
/**
|
|
114
|
+
* Text content of the cancel button.
|
|
115
|
+
* Required when cancel button is shown (showCancelButton is true or not provided).
|
|
116
|
+
*/
|
|
117
|
+
cancelText: ReactNode;
|
|
115
118
|
/**
|
|
116
119
|
* Whether to show the cancel button.
|
|
117
120
|
* @default true
|
|
118
121
|
*/
|
|
119
|
-
showCancelButton?:
|
|
122
|
+
showCancelButton?: true;
|
|
123
|
+
}
|
|
124
|
+
interface ModalFooterWithoutCancelButtonProps extends ModalFooterBaseProps {
|
|
125
|
+
/**
|
|
126
|
+
* Text content of the cancel button.
|
|
127
|
+
* Cannot be provided when showCancelButton is false.
|
|
128
|
+
*/
|
|
129
|
+
cancelText?: never;
|
|
130
|
+
/**
|
|
131
|
+
* Whether to show the cancel button.
|
|
132
|
+
*/
|
|
133
|
+
showCancelButton: false;
|
|
120
134
|
}
|
|
135
|
+
export type ModalFooterProps = ModalFooterWithCancelButtonProps | ModalFooterWithoutCancelButtonProps;
|
|
121
136
|
/**
|
|
122
137
|
* The react component for `mezzanine` modal footer.
|
|
123
138
|
*/
|
package/Modal/ModalHeader.d.ts
CHANGED
|
@@ -1,36 +1,75 @@
|
|
|
1
1
|
import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
2
|
-
|
|
2
|
+
interface ModalHeaderBaseProps extends NativeElementPropsWithoutKeyAndRef<'div'> {
|
|
3
3
|
/**
|
|
4
4
|
* Whether to show status type icon.
|
|
5
5
|
* @default false
|
|
6
6
|
*/
|
|
7
7
|
showStatusTypeIcon?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Supporting text displayed below the title.
|
|
10
|
+
*/
|
|
11
|
+
supportingText?: string;
|
|
12
|
+
/**
|
|
13
|
+
* The title text of the modal header.
|
|
14
|
+
*/
|
|
15
|
+
title: string;
|
|
16
|
+
}
|
|
17
|
+
interface ModalHeaderHorizontalIconProps extends ModalHeaderBaseProps {
|
|
8
18
|
/**
|
|
9
19
|
* Layout of the status type icon relative to title.
|
|
10
|
-
* - 'vertical': Icon above title
|
|
11
20
|
* - 'horizontal': Icon to the left of title
|
|
12
|
-
* @default 'vertical'
|
|
13
21
|
*/
|
|
14
|
-
statusTypeIconLayout
|
|
22
|
+
statusTypeIconLayout: 'horizontal';
|
|
15
23
|
/**
|
|
16
|
-
*
|
|
24
|
+
* Alignment of the supporting text.
|
|
25
|
+
* Only 'left' is allowed when statusTypeIconLayout is 'horizontal'.
|
|
26
|
+
* @default 'left'
|
|
17
27
|
*/
|
|
18
|
-
|
|
28
|
+
supportingTextAlign?: 'left';
|
|
19
29
|
/**
|
|
20
|
-
* Alignment of the
|
|
30
|
+
* Alignment of the title.
|
|
31
|
+
* Only 'left' is allowed when statusTypeIconLayout is 'horizontal'.
|
|
21
32
|
* @default 'left'
|
|
22
33
|
*/
|
|
23
|
-
|
|
34
|
+
titleAlign?: 'left';
|
|
35
|
+
}
|
|
36
|
+
interface ModalHeaderVerticalLeftTitleProps extends ModalHeaderBaseProps {
|
|
24
37
|
/**
|
|
25
|
-
*
|
|
38
|
+
* Layout of the status type icon relative to title.
|
|
39
|
+
* - 'vertical': Icon above title
|
|
40
|
+
* @default 'vertical'
|
|
26
41
|
*/
|
|
27
|
-
|
|
42
|
+
statusTypeIconLayout?: 'vertical';
|
|
43
|
+
/**
|
|
44
|
+
* Alignment of the supporting text.
|
|
45
|
+
* Only 'left' is allowed when titleAlign is 'left'.
|
|
46
|
+
* @default 'left'
|
|
47
|
+
*/
|
|
48
|
+
supportingTextAlign?: 'left';
|
|
28
49
|
/**
|
|
29
50
|
* Alignment of the title.
|
|
30
51
|
* @default 'left'
|
|
31
52
|
*/
|
|
32
|
-
titleAlign?: 'left'
|
|
53
|
+
titleAlign?: 'left';
|
|
54
|
+
}
|
|
55
|
+
interface ModalHeaderVerticalCenterTitleProps extends ModalHeaderBaseProps {
|
|
56
|
+
/**
|
|
57
|
+
* Layout of the status type icon relative to title.
|
|
58
|
+
* - 'vertical': Icon above title
|
|
59
|
+
* @default 'vertical'
|
|
60
|
+
*/
|
|
61
|
+
statusTypeIconLayout?: 'vertical';
|
|
62
|
+
/**
|
|
63
|
+
* Alignment of the supporting text.
|
|
64
|
+
* @default 'left'
|
|
65
|
+
*/
|
|
66
|
+
supportingTextAlign?: 'left' | 'center';
|
|
67
|
+
/**
|
|
68
|
+
* Alignment of the title.
|
|
69
|
+
*/
|
|
70
|
+
titleAlign: 'center';
|
|
33
71
|
}
|
|
72
|
+
export type ModalHeaderProps = ModalHeaderHorizontalIconProps | ModalHeaderVerticalCenterTitleProps | ModalHeaderVerticalLeftTitleProps;
|
|
34
73
|
/**
|
|
35
74
|
* The React component for `mezzanine` modal header.
|
|
36
75
|
*/
|
package/Modal/ModalHeader.js
CHANGED
|
@@ -37,7 +37,7 @@ const ModalHeader = forwardRef(function ModalHeader(props, ref) {
|
|
|
37
37
|
[modalClasses.modalHeader + '--title-align-left']: titleAlign === 'left',
|
|
38
38
|
[modalClasses.modalHeader + '--title-align-center']: titleAlign === 'center',
|
|
39
39
|
[modalClasses.modalHeader + '--show-modal-status-type-icon']: showStatusTypeIcon,
|
|
40
|
-
}, className), children: [showStatusTypeIcon && (jsx("div", { className: cx(modalClasses.modalHeaderStatusTypeIcon), children: jsx(Icon, { icon: modalStatusTypeIcons[modalStatusType], color: iconColor(modalStatusType), size: 20 }) })), jsxs("div", { className: cx(modalClasses.modalHeaderTitleAndSupportingTextContainer), children: [jsx(Typography, { variant: "
|
|
40
|
+
}, className), children: [showStatusTypeIcon && (jsx("div", { className: cx(modalClasses.modalHeaderStatusTypeIcon), children: jsx(Icon, { icon: modalStatusTypeIcons[modalStatusType], color: iconColor(modalStatusType), size: 20 }) })), jsxs("div", { className: cx(modalClasses.modalHeaderTitleAndSupportingTextContainer), children: [jsx(Typography, { variant: "h2", color: "text-neutral-solid", className: cx(modalClasses.modalHeaderTitle), title: typeof title === 'string' ? title : undefined, children: title }), jsx(Typography, { variant: "body", color: "text-neutral-strong", className: cx(modalClasses.modalHeaderSupportingText, {
|
|
41
41
|
[modalClasses.modalHeaderSupportingText + '--align-left']: supportingTextAlign === 'left',
|
|
42
42
|
[modalClasses.modalHeaderSupportingText + '--align-center']: supportingTextAlign === 'center',
|
|
43
43
|
}), children: supportingText })] })] }));
|
package/Modal/index.d.ts
CHANGED
|
@@ -9,5 +9,5 @@ export type { MediaPreviewModalProps } from './MediaPreviewModal';
|
|
|
9
9
|
export { default as MediaPreviewModal } from './MediaPreviewModal';
|
|
10
10
|
export { default as useModalContainer } from './useModalContainer';
|
|
11
11
|
export type { ModalContainerProps } from './useModalContainer';
|
|
12
|
-
export type { ModalProps } from './Modal';
|
|
12
|
+
export type { ModalFooterCancelProps, ModalHeaderLayoutProps, ModalProps, } from './Modal';
|
|
13
13
|
export { default } from './Modal';
|
package/Navigation/Navigation.js
CHANGED
|
@@ -12,6 +12,7 @@ import { useCurrentPathname } from './useCurrentPathname.js';
|
|
|
12
12
|
import { useVisibleItems } from './useVisibleItems.js';
|
|
13
13
|
import { NavigationOverflowMenu } from './NavigationOverflowMenu.js';
|
|
14
14
|
import Input from '../Input/Input.js';
|
|
15
|
+
import Scrollbar from '../Scrollbar/Scrollbar.js';
|
|
15
16
|
import cx from 'clsx';
|
|
16
17
|
|
|
17
18
|
const Navigation = forwardRef((props, ref) => {
|
|
@@ -102,29 +103,37 @@ const Navigation = forwardRef((props, ref) => {
|
|
|
102
103
|
};
|
|
103
104
|
checkActivatedPathKey(level1Items, []);
|
|
104
105
|
hrefActivated.current = true;
|
|
105
|
-
}, [
|
|
106
|
+
}, [
|
|
107
|
+
combineSetActivatedPath,
|
|
108
|
+
currentPathname,
|
|
109
|
+
exactActivatedMatch,
|
|
110
|
+
level1Items,
|
|
111
|
+
]);
|
|
106
112
|
const { contentRef, visibleCount } = useVisibleItems(items, collapsed);
|
|
107
|
-
const
|
|
108
|
-
return
|
|
109
|
-
collapsedItems: visibleCount !== null
|
|
110
|
-
? level1Items.slice(0, visibleCount)
|
|
111
|
-
: level1Items,
|
|
112
|
-
collapsedMenuItems: visibleCount !== null ? level1Items.slice(visibleCount) : [],
|
|
113
|
-
};
|
|
113
|
+
const collapsedMenuItems = useMemo(() => {
|
|
114
|
+
return visibleCount !== null ? level1Items.slice(visibleCount) : [];
|
|
114
115
|
}, [level1Items, visibleCount]);
|
|
116
|
+
const collapsedHiddenKeys = useMemo(() => {
|
|
117
|
+
if (!collapsed || visibleCount === null)
|
|
118
|
+
return new Set();
|
|
119
|
+
return new Set(level1Items
|
|
120
|
+
.slice(visibleCount)
|
|
121
|
+
.map((item) => item.props.id || item.props.title || item.props.href || ''));
|
|
122
|
+
}, [collapsed, visibleCount, level1Items]);
|
|
115
123
|
const [filterText, setFilterText] = useState('');
|
|
116
124
|
return (jsx("nav", { ...rest, ref: ref, className: cx(navigationClasses.host, collapsed ? navigationClasses.collapsed : navigationClasses.expand, className), children: jsxs(NavigationActivatedContext.Provider, { value: {
|
|
117
125
|
activatedPath: activatedPath || innerActivatedPath,
|
|
118
126
|
activatedPathKey,
|
|
119
127
|
collapsed,
|
|
128
|
+
collapsedHiddenKeys,
|
|
120
129
|
currentPathname,
|
|
121
130
|
filterText,
|
|
122
131
|
handleCollapseChange,
|
|
123
132
|
setActivatedPath: combineSetActivatedPath,
|
|
124
133
|
optionsAnchorComponent,
|
|
125
|
-
}, children: [headerComponent, jsx(NavigationOptionLevelContext.Provider, { value: navigationOptionLevelContextDefaultValues, children: jsxs("div", { ref: contentRef, className: navigationClasses.content, children: [filter && (jsx(Input, { size: "sub", variant: "search", className: cx(navigationClasses.searchInput), value: filterText, onChange: (e) => setFilterText(e.target.value) })), jsxs("ul", {
|
|
126
|
-
|
|
127
|
-
|
|
134
|
+
}, children: [headerComponent, jsx(NavigationOptionLevelContext.Provider, { value: navigationOptionLevelContextDefaultValues, children: jsxs("div", { ref: contentRef, className: navigationClasses.content, children: [filter && (jsx(Input, { size: "sub", variant: "search", className: cx(navigationClasses.searchInput), value: filterText, onChange: (e) => setFilterText(e.target.value) })), jsx(Scrollbar, { disabled: collapsed, style: { flex: '1 1 0', minHeight: 0 }, children: jsxs("ul", { className: navigationClasses.list, children: [items, collapsed &&
|
|
135
|
+
visibleCount !== null &&
|
|
136
|
+
visibleCount < level1Items.length && (jsx(NavigationOverflowMenu, { items: collapsedMenuItems }))] }) })] }) }), footerComponent] }) }));
|
|
128
137
|
});
|
|
129
138
|
|
|
130
139
|
export { Navigation as default };
|
|
@@ -4,13 +4,14 @@ import { navigationHeaderClasses } from '@mezzanine-ui/core/navigation';
|
|
|
4
4
|
import { SiderIcon } from '@mezzanine-ui/icons';
|
|
5
5
|
import NavigationIconButton from './NavigationIconButton.js';
|
|
6
6
|
import { NavigationActivatedContext } from './context.js';
|
|
7
|
+
import Fade from '../Transition/Fade.js';
|
|
7
8
|
import cx from 'clsx';
|
|
8
9
|
|
|
9
10
|
const NavigationHeader = forwardRef((props, ref) => {
|
|
10
11
|
const { children, className, title, onBrandClick, ...rest } = props;
|
|
11
12
|
const { collapsed, handleCollapseChange } = use(NavigationActivatedContext);
|
|
12
13
|
const BrandComponent = onBrandClick ? 'button' : 'span';
|
|
13
|
-
return (jsxs("header", { ...rest, ref: ref, className: cx(navigationHeaderClasses.host, collapsed && navigationHeaderClasses.collapsed, className), children: [jsx(NavigationIconButton, { onClick: () => handleCollapseChange(!collapsed), icon: SiderIcon }), jsxs(BrandComponent, { type:
|
|
14
|
+
return (jsxs("header", { ...rest, ref: ref, className: cx(navigationHeaderClasses.host, collapsed && navigationHeaderClasses.collapsed, !!children && navigationHeaderClasses.hasChildren, className), children: [jsx(NavigationIconButton, { onClick: () => handleCollapseChange(!collapsed), icon: SiderIcon }), jsxs(BrandComponent, { type: onBrandClick ? 'button' : undefined, className: navigationHeaderClasses.content, onClick: onBrandClick, children: [!!children && (jsx("span", { className: navigationHeaderClasses.childrenWrapper, children: children })), jsx(Fade, { in: !collapsed || !children, children: jsx("span", { className: navigationHeaderClasses.title, children: collapsed ? title === null || title === void 0 ? void 0 : title[0] : title }) })] })] }));
|
|
14
15
|
});
|
|
15
16
|
|
|
16
17
|
export { NavigationHeader as default };
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { IconDefinition } from '@mezzanine-ui/icons';
|
|
2
2
|
import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
3
3
|
export type NavigationIconButtonProps = Omit<NativeElementPropsWithoutKeyAndRef<'button'>, 'children'> & {
|
|
4
|
+
/**
|
|
5
|
+
* Whether the button is in an active state.
|
|
6
|
+
*/
|
|
7
|
+
active?: boolean;
|
|
4
8
|
/**
|
|
5
9
|
* The icon to be displayed.
|
|
6
10
|
*/
|
|
7
11
|
icon: IconDefinition;
|
|
8
12
|
};
|
|
9
13
|
declare const NavigationIconButton: import("react").ForwardRefExoticComponent<Omit<NativeElementPropsWithoutKeyAndRef<"button">, "children"> & {
|
|
14
|
+
/**
|
|
15
|
+
* Whether the button is in an active state.
|
|
16
|
+
*/
|
|
17
|
+
active?: boolean;
|
|
10
18
|
/**
|
|
11
19
|
* The icon to be displayed.
|
|
12
20
|
*/
|
|
@@ -5,8 +5,8 @@ import Icon from '../Icon/Icon.js';
|
|
|
5
5
|
import cx from 'clsx';
|
|
6
6
|
|
|
7
7
|
const NavigationIconButton = forwardRef((props, ref) => {
|
|
8
|
-
const { className, icon, ...rest } = props;
|
|
9
|
-
return (jsx("button", { ...rest, ref: ref, className: cx(navigationIconButtonClasses.host, className), type: "button", children: jsx(Icon, { icon: icon, size: 16 }) }));
|
|
8
|
+
const { active, className, icon, ...rest } = props;
|
|
9
|
+
return (jsx("button", { ...rest, ref: ref, className: cx(navigationIconButtonClasses.host, active && navigationIconButtonClasses.active, className), type: "button", children: jsx(Icon, { icon: icon, size: 16 }) }));
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
export { NavigationIconButton as default };
|
|
@@ -15,7 +15,7 @@ import cx from 'clsx';
|
|
|
15
15
|
const NavigationOption = forwardRef((props, ref) => {
|
|
16
16
|
var _a;
|
|
17
17
|
const { active, children, className, anchorComponent, defaultOpen, href, icon, id, onTriggerClick, title, ...rest } = props;
|
|
18
|
-
const { activatedPathKey, activatedPath, collapsed, filterText, handleCollapseChange, setActivatedPath, optionsAnchorComponent, } = use(NavigationActivatedContext);
|
|
18
|
+
const { activatedPathKey, activatedPath, collapsed, collapsedHiddenKeys, filterText, handleCollapseChange, setActivatedPath, optionsAnchorComponent, } = use(NavigationActivatedContext);
|
|
19
19
|
const [open, setOpen] = useState(defaultOpen !== null && defaultOpen !== void 0 ? defaultOpen : false);
|
|
20
20
|
const GroupToggleIcon = open ? ChevronUpIcon : ChevronDownIcon;
|
|
21
21
|
const { level, path: parentPath } = use(NavigationOptionLevelContext);
|
|
@@ -84,7 +84,10 @@ const NavigationOption = forwardRef((props, ref) => {
|
|
|
84
84
|
};
|
|
85
85
|
}, [title]);
|
|
86
86
|
return (jsxs("li", { ...rest, ref: ref, className: cx(navigationOptionClasses.host, open && navigationOptionClasses.open, !children && navigationOptionClasses.basic, (active !== null && active !== void 0 ? active : (activatedPath === null || activatedPath === void 0 ? void 0 : activatedPath[currentLevel - 1]) === currentKey) &&
|
|
87
|
-
navigationOptionClasses.active, collapsed && navigationOptionClasses.collapsed,
|
|
87
|
+
navigationOptionClasses.active, collapsed && navigationOptionClasses.collapsed, (collapsed && collapsedHiddenKeys.has(currentKey)) ||
|
|
88
|
+
(!collapsed && !filter)
|
|
89
|
+
? navigationOptionClasses.hidden
|
|
90
|
+
: undefined, className), "data-id": currentKey, children: [jsx(Tooltip, { disablePortal: false, offsetMainAxis: 8 + 6 /* 6 is the padding of the item */, options: {
|
|
88
91
|
placement: collapsed ? 'right' : 'top',
|
|
89
92
|
}, title: collapsed || titleOverflow ? title : undefined, children: ({ onMouseEnter, onMouseLeave, ref: tooltipChildRef }) => (jsxs(Component, { className: cx(navigationOptionClasses.content, navigationOptionClasses.level(currentLevel)), href: Component === 'div' ? undefined : href, onClick: () => {
|
|
90
93
|
setOpen(!open);
|
|
@@ -101,7 +104,7 @@ const NavigationOption = forwardRef((props, ref) => {
|
|
|
101
104
|
if (!children)
|
|
102
105
|
setActivatedPath(currentPath);
|
|
103
106
|
}
|
|
104
|
-
}, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, ref: tooltipChildRef, role: "menuitem", tabIndex: 0, children: [icon && jsx(Icon, { className: navigationOptionClasses.icon, icon: icon }), jsx(Fade, { ref: titleRef, in: collapsed === false || !icon, children: jsx("span", { className: navigationOptionClasses.title, children: title }) }), badge, children && (jsx(Icon, { className: navigationOptionClasses.toggleIcon, icon: GroupToggleIcon }))] })) }), children && !collapsed && (jsx(Collapse, { lazyMount: true, className: cx(navigationOptionClasses.childrenWrapper), in: open, children: jsx(NavigationOptionLevelContext.Provider, { value: {
|
|
107
|
+
}, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, ref: tooltipChildRef, role: "menuitem", tabIndex: 0, children: [icon && jsx(Icon, { className: navigationOptionClasses.icon, icon: icon }), jsx("span", { className: navigationOptionClasses.titleWrapper, children: jsx(Fade, { ref: titleRef, in: collapsed === false || !icon, children: jsx("span", { className: navigationOptionClasses.title, children: title }) }) }), badge, children && (jsx(Icon, { className: navigationOptionClasses.toggleIcon, icon: GroupToggleIcon }))] })) }), children && !collapsed && (jsx(Collapse, { lazyMount: true, className: cx(navigationOptionClasses.childrenWrapper), in: open, children: jsx(NavigationOptionLevelContext.Provider, { value: {
|
|
105
108
|
level: currentLevel,
|
|
106
109
|
path: currentPath,
|
|
107
110
|
}, children: jsx("ul", { className: navigationOptionClasses.group, children: items }) }) }))] }));
|