@mezzanine-ui/react 1.0.0-beta.3 → 1.0.0-beta.5
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/AutoComplete/AutoComplete.d.ts +23 -0
- package/AutoComplete/AutoComplete.js +39 -9
- package/Breadcrumb/Breadcrumb.js +16 -21
- package/Breadcrumb/BreadcrumbDropdown.d.ts +11 -0
- package/Breadcrumb/BreadcrumbDropdown.js +22 -0
- package/Breadcrumb/BreadcrumbItem.d.ts +2 -3
- package/Breadcrumb/BreadcrumbItem.js +13 -31
- package/Breadcrumb/BreadcrumbOverflowMenu.d.ts +7 -0
- package/Breadcrumb/BreadcrumbOverflowMenu.js +77 -0
- package/Breadcrumb/BreadcrumbOverflowMenuDropdown.d.ts +11 -0
- package/Breadcrumb/BreadcrumbOverflowMenuDropdown.js +21 -0
- package/Breadcrumb/BreadcrumbOverflowMenuItem.d.ts +3 -0
- package/Breadcrumb/BreadcrumbOverflowMenuItem.js +27 -0
- package/Breadcrumb/typings.d.ts +21 -39
- package/Calendar/Calendar.js +2 -6
- package/Calendar/CalendarCell.d.ts +22 -0
- package/Calendar/CalendarCell.js +6 -2
- package/Calendar/CalendarControls.js +1 -1
- package/Calendar/CalendarDayOfWeek.js +3 -2
- package/Calendar/CalendarDays.js +5 -1
- package/Calendar/CalendarHalfYears.js +13 -7
- package/Calendar/CalendarMonths.js +13 -6
- package/Calendar/CalendarQuarters.js +13 -7
- package/Calendar/CalendarWeeks.js +87 -34
- package/Calendar/CalendarYears.js +13 -12
- package/Calendar/useCalendarControlModifiers.d.ts +1 -1
- package/Calendar/useCalendarControlModifiers.js +12 -12
- package/Calendar/useCalendarControls.d.ts +4 -4
- package/Calendar/useCalendarControls.js +33 -19
- package/Calendar/useRangeCalendarControls.d.ts +8 -8
- package/Calendar/useRangeCalendarControls.js +42 -31
- package/Checkbox/index.d.ts +4 -5
- package/Checkbox/index.js +1 -5
- package/ContentHeader/ContentHeader.d.ts +160 -0
- package/ContentHeader/ContentHeader.js +54 -0
- package/ContentHeader/index.d.ts +2 -0
- package/ContentHeader/index.js +1 -0
- package/ContentHeader/utils.d.ts +23 -0
- package/ContentHeader/utils.js +215 -0
- package/DateRangePicker/useDateRangeCalendarControls.js +8 -2
- package/Dropdown/Dropdown.d.ts +48 -0
- package/Dropdown/Dropdown.js +16 -2
- package/Dropdown/DropdownItem.d.ts +42 -0
- package/Dropdown/DropdownItem.js +144 -13
- package/Dropdown/DropdownItemCard.d.ts +7 -2
- package/Dropdown/DropdownItemCard.js +12 -9
- package/Empty/Empty.js +2 -1
- package/Empty/icons/EmptyMainNotificationIcon.d.ts +4 -0
- package/Empty/icons/EmptyMainNotificationIcon.js +9 -0
- package/Empty/typings.d.ts +2 -2
- package/FilterArea/Filter.d.ts +32 -0
- package/FilterArea/Filter.js +23 -0
- package/FilterArea/FilterArea.d.ts +58 -0
- package/FilterArea/FilterArea.js +31 -0
- package/FilterArea/FilterLine.d.ts +11 -0
- package/FilterArea/FilterLine.js +13 -0
- package/FilterArea/index.d.ts +6 -0
- package/FilterArea/index.js +3 -0
- package/Form/useSelectValueControl.d.ts +3 -4
- package/Form/useSelectValueControl.js +51 -39
- package/Input/Input.d.ts +6 -4
- package/Input/Input.js +28 -10
- package/Input/index.d.ts +1 -1
- package/Modal/MediaPreviewModal.d.ts +54 -0
- package/Modal/MediaPreviewModal.js +158 -0
- package/Modal/Modal.js +1 -1
- package/Modal/index.d.ts +2 -0
- package/Modal/index.js +1 -0
- package/Navigation/Navigation.js +6 -5
- package/Navigation/NavigationOption.d.ts +6 -2
- package/Navigation/NavigationOption.js +19 -9
- package/Navigation/NavigationOverflowMenu.d.ts +6 -0
- package/Navigation/NavigationOverflowMenu.js +90 -0
- package/Navigation/NavigationOverflowMenuOption.d.ts +7 -0
- package/Navigation/NavigationOverflowMenuOption.js +68 -0
- package/Navigation/NavigationUserMenu.d.ts +4 -2
- package/Navigation/NavigationUserMenu.js +13 -5
- package/Navigation/context.d.ts +3 -2
- package/NotificationCenter/NotificationCenter.d.ts +1 -1
- package/NotificationCenter/NotificationCenter.js +34 -14
- package/NotificationCenter/NotificationCenterDrawer.d.ts +20 -0
- package/PageHeader/PageHeader.d.ts +32 -25
- package/PageHeader/PageHeader.js +49 -35
- package/Popper/Popper.js +2 -1
- package/ResultState/ResultState.d.ts +9 -0
- package/ResultState/ResultState.js +36 -4
- package/Scrollbar/Scrollbar.d.ts +9 -0
- package/Scrollbar/Scrollbar.js +79 -0
- package/Scrollbar/index.d.ts +2 -0
- package/Scrollbar/index.js +1 -0
- package/Scrollbar/typings.d.ts +47 -0
- package/Select/Select.d.ts +37 -18
- package/Select/Select.js +165 -51
- package/Select/SelectTrigger.js +5 -4
- package/Select/index.d.ts +8 -9
- package/Select/index.js +3 -3
- package/Select/typings.d.ts +6 -1
- package/Selection/Selection.js +1 -1
- package/Selection/SelectionGroup.d.ts +28 -0
- package/Table/Table.d.ts +2 -120
- package/Table/Table.js +148 -53
- package/Table/TableContext.d.ts +11 -12
- package/Table/components/TableActionsCell.js +12 -4
- package/Table/components/TableBody.js +2 -1
- package/Table/components/TableColGroup.d.ts +1 -4
- package/Table/components/TableColGroup.js +15 -16
- package/Table/components/TableCollectableCell.d.ts +17 -0
- package/Table/components/TableCollectableCell.js +54 -0
- package/Table/components/TableDragOrPinHandleCell.d.ts +20 -0
- package/Table/components/TableDragOrPinHandleCell.js +58 -0
- package/Table/components/TableExpandedRow.js +11 -2
- package/Table/components/TableHeader.js +12 -10
- package/Table/components/TableRow.js +38 -13
- package/Table/components/TableSelectionCell.js +1 -1
- package/Table/components/TableToggleableCell.d.ts +16 -0
- package/Table/components/TableToggleableCell.js +51 -0
- package/Table/components/index.d.ts +4 -1
- package/Table/components/index.js +3 -0
- package/Table/hooks/typings.d.ts +18 -4
- package/Table/hooks/useTableExpansion.d.ts +2 -2
- package/Table/hooks/useTableExpansion.js +5 -5
- package/Table/hooks/useTableFixedOffsets.d.ts +6 -2
- package/Table/hooks/useTableFixedOffsets.js +58 -24
- package/Table/hooks/useTableScroll.d.ts +9 -3
- package/Table/hooks/useTableScroll.js +34 -7
- package/Table/hooks/useTableVirtualization.d.ts +2 -1
- package/Table/hooks/useTableVirtualization.js +2 -8
- package/Table/index.d.ts +4 -3
- package/Table/index.js +3 -0
- package/Table/typings.d.ts +172 -0
- package/Transition/Slide.d.ts +9 -2
- package/Transition/Slide.js +7 -4
- package/Tree/TreeNode.js +1 -1
- package/index.d.ts +4 -2
- package/index.js +6 -3
- package/package.json +6 -4
- package/Navigation/CollapsedMenu.d.ts +0 -6
- package/Navigation/CollapsedMenu.js +0 -16
- package/PageToolbar/PageToolbar.d.ts +0 -110
- package/PageToolbar/PageToolbar.js +0 -23
- package/PageToolbar/index.d.ts +0 -2
- package/PageToolbar/index.js +0 -1
- package/PageToolbar/utils.d.ts +0 -23
- package/PageToolbar/utils.js +0 -157
- package/Table/components/TableDragHandleCell.d.ts +0 -11
- package/Table/components/TableDragHandleCell.js +0 -44
|
@@ -2,14 +2,14 @@ import { DateType, CalendarMode } from '@mezzanine-ui/core/calendar';
|
|
|
2
2
|
export declare function useRangeCalendarControls(referenceDateProp: DateType, mode?: CalendarMode): {
|
|
3
3
|
currentMode: CalendarMode;
|
|
4
4
|
onMonthControlClick: () => void;
|
|
5
|
-
onFirstNext: () => void;
|
|
6
|
-
onFirstPrev: () => void;
|
|
7
|
-
onFirstDoubleNext: () => void;
|
|
8
|
-
onFirstDoublePrev: () => void;
|
|
9
|
-
onSecondNext: () => void;
|
|
10
|
-
onSecondPrev: () => void;
|
|
11
|
-
onSecondDoubleNext: () => void;
|
|
12
|
-
onSecondDoublePrev: () => void;
|
|
5
|
+
onFirstNext: (() => void) | undefined;
|
|
6
|
+
onFirstPrev: (() => void) | undefined;
|
|
7
|
+
onFirstDoubleNext: (() => void) | undefined;
|
|
8
|
+
onFirstDoublePrev: (() => void) | undefined;
|
|
9
|
+
onSecondNext: (() => void) | undefined;
|
|
10
|
+
onSecondPrev: (() => void) | undefined;
|
|
11
|
+
onSecondDoubleNext: (() => void) | undefined;
|
|
12
|
+
onSecondDoublePrev: (() => void) | undefined;
|
|
13
13
|
onYearControlClick: () => void;
|
|
14
14
|
popModeStack: () => void;
|
|
15
15
|
referenceDates: [string, string];
|
|
@@ -37,54 +37,65 @@ function useRangeCalendarControls(referenceDateProp, mode) {
|
|
|
37
37
|
const { currentMode, pushModeStack, popModeStack } = useCalendarModeStack(mode || 'day');
|
|
38
38
|
const modifierGroup = useCalendarControlModifiers();
|
|
39
39
|
// First calendar controls
|
|
40
|
-
const onFirstPrev = () => {
|
|
40
|
+
const onFirstPrev = useMemo(() => {
|
|
41
41
|
const modifiers = modifierGroup[currentMode].single;
|
|
42
42
|
if (!modifiers)
|
|
43
43
|
return;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
return () => {
|
|
45
|
+
const [handleMinus] = modifiers;
|
|
46
|
+
const newFirst = handleMinus(firstReferenceDate);
|
|
47
|
+
setFirstReferenceDate(newFirst);
|
|
48
|
+
setSecondReferenceDate(getSecondCalendarDate(newFirst));
|
|
49
|
+
};
|
|
50
|
+
}, [currentMode, modifierGroup, firstReferenceDate, getSecondCalendarDate]);
|
|
51
|
+
const onFirstNext = useMemo(() => {
|
|
50
52
|
const modifiers = modifierGroup[currentMode].single;
|
|
51
53
|
if (!modifiers)
|
|
52
54
|
return;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
55
|
+
return () => {
|
|
56
|
+
const [, handleAdd] = modifiers;
|
|
57
|
+
const newFirst = handleAdd(firstReferenceDate);
|
|
58
|
+
setFirstReferenceDate(newFirst);
|
|
59
|
+
setSecondReferenceDate(getSecondCalendarDate(newFirst));
|
|
60
|
+
};
|
|
61
|
+
}, [currentMode, modifierGroup, firstReferenceDate, getSecondCalendarDate]);
|
|
62
|
+
const onFirstDoublePrev = useMemo(() => {
|
|
63
|
+
const modifiers = modifierGroup[currentMode].double;
|
|
64
|
+
if (!modifiers)
|
|
65
|
+
return;
|
|
66
|
+
return () => {
|
|
67
|
+
const [handleMinus] = modifiers;
|
|
68
|
+
const newFirst = handleMinus(firstReferenceDate);
|
|
69
|
+
setFirstReferenceDate(newFirst);
|
|
70
|
+
setSecondReferenceDate(getSecondCalendarDate(newFirst));
|
|
71
|
+
};
|
|
72
|
+
}, [currentMode, modifierGroup, firstReferenceDate, getSecondCalendarDate]);
|
|
73
|
+
const onFirstDoubleNext = useMemo(() => {
|
|
74
|
+
const modifiers = modifierGroup[currentMode].double;
|
|
75
|
+
if (!modifiers)
|
|
76
|
+
return;
|
|
77
|
+
return () => {
|
|
78
|
+
const [, handleAdd] = modifiers;
|
|
79
|
+
const newFirst = handleAdd(firstReferenceDate);
|
|
80
|
+
setFirstReferenceDate(newFirst);
|
|
81
|
+
setSecondReferenceDate(getSecondCalendarDate(newFirst));
|
|
82
|
+
};
|
|
83
|
+
}, [currentMode, modifierGroup, firstReferenceDate, getSecondCalendarDate]);
|
|
70
84
|
// Second calendar controls (same behavior as first)
|
|
71
85
|
const onSecondPrev = onFirstPrev;
|
|
72
86
|
const onSecondNext = onFirstNext;
|
|
73
87
|
const onSecondDoublePrev = onFirstDoublePrev;
|
|
74
88
|
const onSecondDoubleNext = onFirstDoubleNext;
|
|
75
|
-
const onMonthControlClick = () => {
|
|
89
|
+
const onMonthControlClick = useCallback(() => {
|
|
76
90
|
setFirstReferenceDate(firstReferenceDate);
|
|
77
91
|
setSecondReferenceDate(addYear(firstReferenceDate, 1));
|
|
78
92
|
pushModeStack('month');
|
|
79
|
-
};
|
|
80
|
-
const onYearControlClick = () => {
|
|
93
|
+
}, [firstReferenceDate, pushModeStack, addYear]);
|
|
94
|
+
const onYearControlClick = useCallback(() => {
|
|
81
95
|
setFirstReferenceDate(firstReferenceDate);
|
|
82
96
|
setSecondReferenceDate(addYear(firstReferenceDate, calendarYearModuler));
|
|
83
97
|
pushModeStack('year');
|
|
84
|
-
};
|
|
85
|
-
// Wrapper functions for updating reference dates
|
|
86
|
-
// These should be used when switching modes (e.g., from month picker back to day mode)
|
|
87
|
-
// They update the target calendar and maintain the offset between calendars
|
|
98
|
+
}, [firstReferenceDate, pushModeStack, addYear]);
|
|
88
99
|
const updateFirstReferenceDate = useCallback((date) => {
|
|
89
100
|
setFirstReferenceDate(date);
|
|
90
101
|
setSecondReferenceDate(getSecondCalendarDate(date));
|
package/Checkbox/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PropsWithoutRef, ReactElement, RefAttributes } from 'react';
|
|
2
|
-
import { CheckboxProps } from './Checkbox';
|
|
1
|
+
import type { PropsWithoutRef, ReactElement, RefAttributes } from 'react';
|
|
2
|
+
import type { CheckboxProps } from './Checkbox';
|
|
3
3
|
export type { CheckboxGroupLayout, CheckboxGroupOption, } from '@mezzanine-ui/core/checkbox';
|
|
4
4
|
export { default as CheckAll } from './CheckAll';
|
|
5
5
|
export type { CheckAllProps } from './CheckAll';
|
|
@@ -11,6 +11,5 @@ export type { CheckboxComponent, CheckboxPropsBase } from './typings';
|
|
|
11
11
|
* @remark
|
|
12
12
|
* Add type alias here for parsable to react docgen typescript.
|
|
13
13
|
*/
|
|
14
|
-
type GenericCheckbox = (props: PropsWithoutRef<CheckboxProps> & RefAttributes<HTMLLabelElement>) => ReactElement<any>;
|
|
15
|
-
|
|
16
|
-
export default _default;
|
|
14
|
+
export type GenericCheckbox = (props: PropsWithoutRef<CheckboxProps> & RefAttributes<HTMLLabelElement>) => ReactElement<any>;
|
|
15
|
+
export { default } from './Checkbox';
|
package/Checkbox/index.js
CHANGED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { ButtonProps } from '../Button';
|
|
3
|
+
import { SearchInputProps } from '../Input';
|
|
4
|
+
import { SelectProps } from '../Select';
|
|
5
|
+
import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
6
|
+
import { IconDefinition } from '@mezzanine-ui/icons';
|
|
7
|
+
import { DropdownProps } from '../Dropdown';
|
|
8
|
+
type SegmentedControlProps = {
|
|
9
|
+
mock: 'SegmentedControlProps';
|
|
10
|
+
};
|
|
11
|
+
type ContentHeaderChild = ReactElement<SearchInputProps> | ReactElement<SelectProps> | ReactElement<SegmentedControlProps> | ReactElement<ButtonProps> | ReactElement<DropdownProps> | ReactElement<{
|
|
12
|
+
href: string;
|
|
13
|
+
}> | null | false | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Props for the ContentHeader component.
|
|
16
|
+
*
|
|
17
|
+
* Defines a flexible header with title, description, filter, action buttons, and utility icons.
|
|
18
|
+
* Commonly used in page headers for primary user actions.
|
|
19
|
+
*/
|
|
20
|
+
export type ContentHeaderProps = Omit<NativeElementPropsWithoutKeyAndRef<'header'>, 'children'> & {
|
|
21
|
+
/**
|
|
22
|
+
* Button configuration for actions. <br />
|
|
23
|
+
* Automatically applies proper styling and order. <br />
|
|
24
|
+
* When conflicting with other props, props take priority over children. <br />
|
|
25
|
+
* Buttons with variants other than primary, secondary, and destructive will not be rendered. <br />
|
|
26
|
+
*/
|
|
27
|
+
actions?: ButtonProps[];
|
|
28
|
+
/**
|
|
29
|
+
* Children elements: <br />
|
|
30
|
+
* - Back button which Component with href prop.
|
|
31
|
+
* - example 1: `<a href="..." />` <br />
|
|
32
|
+
* - example 2: `<Link href="..." />` <br />
|
|
33
|
+
* - conflicting prop: `onBackClick` <br />
|
|
34
|
+
* - Filter component (SearchInput, Select, or SegmentedControl) <br />
|
|
35
|
+
* - Action buttons `<Button />` <br />
|
|
36
|
+
* - Icon-only utility buttons `<Button icon="..." />` <br />
|
|
37
|
+
* - Overflow icon utility dropdown `<Dropdown> <Button icon="..." /> </Dropdown>` <br />
|
|
38
|
+
* <br />
|
|
39
|
+
* Can mix and match the above children. <br />
|
|
40
|
+
* The order of children does not matter as they will be arranged properly. <br />
|
|
41
|
+
* When conflicting with other props, props take priority over children. <br />
|
|
42
|
+
*/
|
|
43
|
+
children?: ContentHeaderChild[] | ContentHeaderChild;
|
|
44
|
+
/** Optional description text displayed below the title */
|
|
45
|
+
description?: string;
|
|
46
|
+
/** Filter component (SearchInput, Select, or SegmentedControl) */
|
|
47
|
+
filter?: {
|
|
48
|
+
variant: 'search' | 'select' | 'segmentedControl';
|
|
49
|
+
} & (SearchInputProps | SelectProps | SegmentedControlProps);
|
|
50
|
+
/**
|
|
51
|
+
* Optional back button properties. <br />
|
|
52
|
+
* When provided, a back button will be rendered on the left side of the title. <br />
|
|
53
|
+
* href prop from children will be ignored if onBackClick is provided. <br />
|
|
54
|
+
* */
|
|
55
|
+
onBackClick?: () => void;
|
|
56
|
+
/**
|
|
57
|
+
* Size variant of the toolbar. <br />
|
|
58
|
+
* Affects the size of buttons and filter component. <br />
|
|
59
|
+
*/
|
|
60
|
+
size?: 'main' | 'sub';
|
|
61
|
+
/** Main title text for the content header */
|
|
62
|
+
title: string;
|
|
63
|
+
/**
|
|
64
|
+
* HTML element type for the title (defaults to 'h1' for main size and 'h2' for sub size)
|
|
65
|
+
*/
|
|
66
|
+
titleComponent?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p';
|
|
67
|
+
/**
|
|
68
|
+
* Icon-only utility buttons `<Button icon="..." />`. <br />
|
|
69
|
+
* They usually appear as smaller buttons with only an icon and no text.
|
|
70
|
+
*/
|
|
71
|
+
utilities?: ((ButtonProps & {
|
|
72
|
+
icon: IconDefinition;
|
|
73
|
+
}) | DropdownProps)[];
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* ContentHeader component. <br />
|
|
77
|
+
* A flexible header with title, description, filter, action buttons, and utility icons. <br />
|
|
78
|
+
* Commonly used in page headers for primary user actions. <br />
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```tsx
|
|
82
|
+
* <ContentHeader
|
|
83
|
+
* size="main"
|
|
84
|
+
* title={'ContentHeader Title'}
|
|
85
|
+
* description="description."
|
|
86
|
+
* >
|
|
87
|
+
* <a href="" title="back" /> <-- Back button
|
|
88
|
+
*
|
|
89
|
+
* <Input variant="search" placeholder="Search..." /> <-- Filter component
|
|
90
|
+
* <Button variant="base-secondary">Secondary</Button> <-- Action buttons
|
|
91
|
+
* <Button>Primary</Button>
|
|
92
|
+
*
|
|
93
|
+
* <Button icon={PlusIcon} /> <-- Utility icon button
|
|
94
|
+
* <Dropdown
|
|
95
|
+
* options={[
|
|
96
|
+
* { id: '1', name: 'Option 1' },
|
|
97
|
+
* { id: '2', name: 'Option 2' },
|
|
98
|
+
* ]}
|
|
99
|
+
* >
|
|
100
|
+
* <Button icon={DotHorizontalIcon} />
|
|
101
|
+
* </Dropdown> <-- Utility dropdown
|
|
102
|
+
* </ContentHeader>
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
declare const ContentHeader: import("react").ForwardRefExoticComponent<Omit<NativeElementPropsWithoutKeyAndRef<"header">, "children"> & {
|
|
106
|
+
/**
|
|
107
|
+
* Button configuration for actions. <br />
|
|
108
|
+
* Automatically applies proper styling and order. <br />
|
|
109
|
+
* When conflicting with other props, props take priority over children. <br />
|
|
110
|
+
* Buttons with variants other than primary, secondary, and destructive will not be rendered. <br />
|
|
111
|
+
*/
|
|
112
|
+
actions?: ButtonProps[];
|
|
113
|
+
/**
|
|
114
|
+
* Children elements: <br />
|
|
115
|
+
* - Back button which Component with href prop.
|
|
116
|
+
* - example 1: `<a href="..." />` <br />
|
|
117
|
+
* - example 2: `<Link href="..." />` <br />
|
|
118
|
+
* - conflicting prop: `onBackClick` <br />
|
|
119
|
+
* - Filter component (SearchInput, Select, or SegmentedControl) <br />
|
|
120
|
+
* - Action buttons `<Button />` <br />
|
|
121
|
+
* - Icon-only utility buttons `<Button icon="..." />` <br />
|
|
122
|
+
* - Overflow icon utility dropdown `<Dropdown> <Button icon="..." /> </Dropdown>` <br />
|
|
123
|
+
* <br />
|
|
124
|
+
* Can mix and match the above children. <br />
|
|
125
|
+
* The order of children does not matter as they will be arranged properly. <br />
|
|
126
|
+
* When conflicting with other props, props take priority over children. <br />
|
|
127
|
+
*/
|
|
128
|
+
children?: ContentHeaderChild[] | ContentHeaderChild;
|
|
129
|
+
/** Optional description text displayed below the title */
|
|
130
|
+
description?: string;
|
|
131
|
+
/** Filter component (SearchInput, Select, or SegmentedControl) */
|
|
132
|
+
filter?: {
|
|
133
|
+
variant: "search" | "select" | "segmentedControl";
|
|
134
|
+
} & (SearchInputProps | SelectProps | SegmentedControlProps);
|
|
135
|
+
/**
|
|
136
|
+
* Optional back button properties. <br />
|
|
137
|
+
* When provided, a back button will be rendered on the left side of the title. <br />
|
|
138
|
+
* href prop from children will be ignored if onBackClick is provided. <br />
|
|
139
|
+
* */
|
|
140
|
+
onBackClick?: () => void;
|
|
141
|
+
/**
|
|
142
|
+
* Size variant of the toolbar. <br />
|
|
143
|
+
* Affects the size of buttons and filter component. <br />
|
|
144
|
+
*/
|
|
145
|
+
size?: "main" | "sub";
|
|
146
|
+
/** Main title text for the content header */
|
|
147
|
+
title: string;
|
|
148
|
+
/**
|
|
149
|
+
* HTML element type for the title (defaults to 'h1' for main size and 'h2' for sub size)
|
|
150
|
+
*/
|
|
151
|
+
titleComponent?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p";
|
|
152
|
+
/**
|
|
153
|
+
* Icon-only utility buttons `<Button icon="..." />`. <br />
|
|
154
|
+
* They usually appear as smaller buttons with only an icon and no text.
|
|
155
|
+
*/
|
|
156
|
+
utilities?: ((ButtonProps & {
|
|
157
|
+
icon: IconDefinition;
|
|
158
|
+
}) | DropdownProps)[];
|
|
159
|
+
} & import("react").RefAttributes<HTMLElement>>;
|
|
160
|
+
export default ContentHeader;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import { contentHeaderClasses } from '@mezzanine-ui/core/content-header';
|
|
4
|
+
import Button from '../Button/Button.js';
|
|
5
|
+
import ButtonGroup from '../Button/ButtonGroup.js';
|
|
6
|
+
import { ChevronLeftIcon } from '@mezzanine-ui/icons';
|
|
7
|
+
import { renderFilterProp, renderActionsProp, renderIconButtonsProp, resolveContentHeaderChild } from './utils.js';
|
|
8
|
+
import Typography from '../Typography/Typography.js';
|
|
9
|
+
import cx from 'clsx';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* ContentHeader component. <br />
|
|
13
|
+
* A flexible header with title, description, filter, action buttons, and utility icons. <br />
|
|
14
|
+
* Commonly used in page headers for primary user actions. <br />
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* <ContentHeader
|
|
19
|
+
* size="main"
|
|
20
|
+
* title={'ContentHeader Title'}
|
|
21
|
+
* description="description."
|
|
22
|
+
* >
|
|
23
|
+
* <a href="" title="back" /> <-- Back button
|
|
24
|
+
*
|
|
25
|
+
* <Input variant="search" placeholder="Search..." /> <-- Filter component
|
|
26
|
+
* <Button variant="base-secondary">Secondary</Button> <-- Action buttons
|
|
27
|
+
* <Button>Primary</Button>
|
|
28
|
+
*
|
|
29
|
+
* <Button icon={PlusIcon} /> <-- Utility icon button
|
|
30
|
+
* <Dropdown
|
|
31
|
+
* options={[
|
|
32
|
+
* { id: '1', name: 'Option 1' },
|
|
33
|
+
* { id: '2', name: 'Option 2' },
|
|
34
|
+
* ]}
|
|
35
|
+
* >
|
|
36
|
+
* <Button icon={DotHorizontalIcon} />
|
|
37
|
+
* </Dropdown> <-- Utility dropdown
|
|
38
|
+
* </ContentHeader>
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
const ContentHeader = forwardRef(function ContentHeader(props, ref) {
|
|
42
|
+
const { actions, children, className, description, filter, onBackClick, size = 'main', title, titleComponent = size === 'main' ? 'h1' : 'h2', utilities, ...rest } = props;
|
|
43
|
+
const renderFilter = renderFilterProp(filter, size);
|
|
44
|
+
const renderActions = actions ? renderActionsProp(actions, size) : null;
|
|
45
|
+
const renderUtilities = utilities
|
|
46
|
+
? renderIconButtonsProp(utilities, size)
|
|
47
|
+
: null;
|
|
48
|
+
const { backButton, filter: filterFromChildren, actions: actionsFromChildren, utilities: utilitiesFromChildren, } = resolveContentHeaderChild(children, size);
|
|
49
|
+
// prop onBack takes precedence over backButtonOrLink
|
|
50
|
+
const renderBackButton = onBackClick ? (jsx(Button, { iconType: "icon-only", icon: ChevronLeftIcon, onClick: onBackClick, "aria-label": "Back", type: "button", size: "sub", variant: "base-tertiary" })) : (backButton);
|
|
51
|
+
return (jsxs("header", { ...rest, className: cx(contentHeaderClasses.host, contentHeaderClasses.size(size), className), ref: ref, children: [jsxs("span", { className: contentHeaderClasses.titleArea, children: [renderBackButton && (jsx("span", { className: contentHeaderClasses.backButton, children: renderBackButton })), jsxs("span", { className: contentHeaderClasses.textGroup, children: [jsx(Typography, { component: titleComponent, align: "left", color: "text-neutral-solid", variant: size === 'main' ? 'h2' : 'h3', children: title }), description && (jsx(Typography, { align: "left", color: "text-neutral", variant: "caption", children: description }))] })] }), jsxs("span", { className: contentHeaderClasses.actionArea, children: [renderFilter || filterFromChildren, (renderActions || actionsFromChildren.length > 0) && (jsx(ButtonGroup, { children: renderActions || actionsFromChildren })), (renderUtilities || utilitiesFromChildren.length > 0) && (jsx("span", { className: contentHeaderClasses.utilities, children: renderUtilities || utilitiesFromChildren }))] })] }));
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export { ContentHeader as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './ContentHeader.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { ButtonProps, ButtonGroupChild } from '../Button';
|
|
3
|
+
import { ContentHeaderProps } from './ContentHeader';
|
|
4
|
+
import { DropdownProps } from '../Dropdown';
|
|
5
|
+
/**
|
|
6
|
+
* Renders a button from either ButtonProps or a React element.
|
|
7
|
+
* Applies the specified size and variant to the button.
|
|
8
|
+
*/
|
|
9
|
+
export declare const renderButton: (button: ButtonProps | ButtonGroupChild | undefined, size: ButtonProps["size"]) => ReactElement<ButtonProps> | null;
|
|
10
|
+
export declare const renderFilterProp: (prop: ContentHeaderProps["filter"], size: "main" | "sub") => import("react/jsx-runtime").JSX.Element | null;
|
|
11
|
+
export declare const renderIconButtonWithProps: (child: ReactElement<ButtonProps>, size: ButtonProps["size"]) => ReactElement<ButtonProps>;
|
|
12
|
+
export declare const renderIconButtonsProp: (utilities: ContentHeaderProps["utilities"], size: ButtonProps["size"]) => ButtonGroupChild | ButtonGroupChild[];
|
|
13
|
+
/**
|
|
14
|
+
* Renders action buttons based on the actions configuration.
|
|
15
|
+
* Supports both structured actions object and single button element/props.
|
|
16
|
+
*/
|
|
17
|
+
export declare const renderActionsProp: (actions: ContentHeaderProps["actions"], size: ButtonProps["size"]) => ButtonGroupChild | ButtonGroupChild[];
|
|
18
|
+
export declare const resolveContentHeaderChild: (children: ContentHeaderProps["children"], size: "main" | "sub") => {
|
|
19
|
+
filter: null;
|
|
20
|
+
actions: ReactElement<ButtonProps, string | import("react").JSXElementConstructor<any>>[];
|
|
21
|
+
utilities: (ButtonGroupChild | ReactElement<DropdownProps, string | import("react").JSXElementConstructor<any>>)[];
|
|
22
|
+
backButton: null;
|
|
23
|
+
};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { isValidElement, cloneElement, Children } from 'react';
|
|
3
|
+
import Button from '../Button/Button.js';
|
|
4
|
+
import { flattenChildren } from '../utils/flatten-children.js';
|
|
5
|
+
import { ChevronLeftIcon } from '@mezzanine-ui/icons';
|
|
6
|
+
import Input from '../Input/Input.js';
|
|
7
|
+
import Select from '../Select/Select.js';
|
|
8
|
+
import Dropdown from '../Dropdown/Dropdown.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Renders a button from either ButtonProps or a React element.
|
|
12
|
+
* Applies the specified size and variant to the button.
|
|
13
|
+
*/
|
|
14
|
+
const renderButton = (button, size) => {
|
|
15
|
+
if (!button) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
if (isValidElement(button)) {
|
|
19
|
+
return cloneElement(button, {
|
|
20
|
+
size,
|
|
21
|
+
type: 'button',
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return jsx(Button, { ...button, size: size, type: "button" });
|
|
25
|
+
};
|
|
26
|
+
const withSize = (target, size) => {
|
|
27
|
+
return cloneElement(target, { size });
|
|
28
|
+
};
|
|
29
|
+
const renderFilterProp = (prop, size) => {
|
|
30
|
+
if (!prop) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const { variant } = prop;
|
|
34
|
+
if (variant === 'search') {
|
|
35
|
+
return (jsx(Input, { ...prop, size: size, variant: "search" }));
|
|
36
|
+
}
|
|
37
|
+
if (variant === 'select') {
|
|
38
|
+
return jsx(Select, { ...prop, size: size });
|
|
39
|
+
}
|
|
40
|
+
if (variant === 'segmentedControl') {
|
|
41
|
+
console.warn('SegmentedControl component is not implemented yet.');
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
};
|
|
46
|
+
const renderIconButtonWithProps = (child, size) => {
|
|
47
|
+
const { icon } = child.props;
|
|
48
|
+
return cloneElement(child, {
|
|
49
|
+
icon,
|
|
50
|
+
iconType: 'icon-only',
|
|
51
|
+
size,
|
|
52
|
+
variant: 'base-secondary',
|
|
53
|
+
type: 'button',
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
const renderIconButtonsProp = (utilities, size) => {
|
|
57
|
+
const result = [];
|
|
58
|
+
utilities === null || utilities === void 0 ? void 0 : utilities.forEach((props) => {
|
|
59
|
+
if (props instanceof Object && 'icon' in props) {
|
|
60
|
+
result.push(jsx(Button, { ...props, type: "button", size: size, iconType: "icon-only", variant: "base-secondary" }));
|
|
61
|
+
}
|
|
62
|
+
if (props instanceof Object && 'options' in props) {
|
|
63
|
+
if (!isValidElement(props.children) ||
|
|
64
|
+
!(props.children.type === Button)) {
|
|
65
|
+
console.warn('[Mezzanine][ContentHeader]: Dropdown in utilities should have Button with icon as its children.');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
result.push(jsx(Dropdown, { ...props, children: cloneElement(props.children, {
|
|
69
|
+
type: 'button',
|
|
70
|
+
size: size,
|
|
71
|
+
iconType: 'icon-only',
|
|
72
|
+
variant: 'base-secondary',
|
|
73
|
+
}) }));
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return result;
|
|
77
|
+
};
|
|
78
|
+
const variantOrder = {
|
|
79
|
+
'destructive-secondary': 0,
|
|
80
|
+
'base-secondary': 1,
|
|
81
|
+
'base-primary': 2,
|
|
82
|
+
// undefined: 2,
|
|
83
|
+
'base-tertiary': 0,
|
|
84
|
+
'base-ghost': 0,
|
|
85
|
+
'base-dashed': 0,
|
|
86
|
+
'base-text-link': 0,
|
|
87
|
+
'destructive-primary': 0,
|
|
88
|
+
'destructive-ghost': 0,
|
|
89
|
+
'destructive-text-link': 0,
|
|
90
|
+
inverse: 0,
|
|
91
|
+
'inverse-ghost': 0,
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Renders action buttons based on the actions configuration.
|
|
95
|
+
* Supports both structured actions object and single button element/props.
|
|
96
|
+
*/
|
|
97
|
+
const renderActionsProp = (actions, size) => {
|
|
98
|
+
if (actions) {
|
|
99
|
+
return actions
|
|
100
|
+
.filter((v) => {
|
|
101
|
+
if (v.variant === 'destructive-secondary' ||
|
|
102
|
+
v.variant === 'base-secondary' ||
|
|
103
|
+
v.variant === 'base-primary' ||
|
|
104
|
+
v.variant === undefined) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
console.warn(`[Mezzanine][ContentHeader]: Button with variant "${v.variant}" will not be rendered in ContentHeader actions.`);
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
})
|
|
112
|
+
.sort((a, b) => variantOrder[a.variant || 'base-primary'] -
|
|
113
|
+
variantOrder[b.variant || 'base-primary'])
|
|
114
|
+
.map((v) => renderButton(v, size));
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
};
|
|
118
|
+
const resolveContentHeaderChild = (children, size) => {
|
|
119
|
+
let filter = null;
|
|
120
|
+
// [destructive-secondary[], base-secondary[], base-primary[]]
|
|
121
|
+
const actionsWithOrder = [[], [], []];
|
|
122
|
+
const utilities = [];
|
|
123
|
+
let backButton = null;
|
|
124
|
+
if (children) {
|
|
125
|
+
const flatChildren = flattenChildren(children);
|
|
126
|
+
Children.forEach(flatChildren, (child) => {
|
|
127
|
+
if (!isValidElement(child)) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const { type, props } = child;
|
|
131
|
+
if (type === 'a' || props.href) {
|
|
132
|
+
backButton = cloneElement(child, {
|
|
133
|
+
children: (jsx(Button, { component: 'span', iconType: "icon-only", icon: ChevronLeftIcon, "aria-label": "Back", type: "button", size: "sub", variant: "base-tertiary" })),
|
|
134
|
+
});
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const sizeProp = props.size;
|
|
138
|
+
if (sizeProp !== undefined && sizeProp !== size) {
|
|
139
|
+
console.warn('[Mezzanine][ContentHeader]: Input, Button, Select size in ContentHeader utilities is forced to match ContentHeader size.');
|
|
140
|
+
}
|
|
141
|
+
// is filter
|
|
142
|
+
if ((type === Input && props.variant === 'search') ||
|
|
143
|
+
type === Select) {
|
|
144
|
+
if (filter) {
|
|
145
|
+
console.warn('[Mezzanine][ContentHeader]: ContentHeader only accepts one filter component.');
|
|
146
|
+
}
|
|
147
|
+
filter = withSize(child, size);
|
|
148
|
+
}
|
|
149
|
+
else if (type.toString() === 'SegmentedControl') {
|
|
150
|
+
console.warn('SegmentedControl component is not implemented yet.');
|
|
151
|
+
}
|
|
152
|
+
// is utilities (icon button)
|
|
153
|
+
else if ((type === Button && props.iconType === 'icon-only') ||
|
|
154
|
+
(type === Button &&
|
|
155
|
+
props.icon &&
|
|
156
|
+
!props.children)) {
|
|
157
|
+
utilities.push(renderIconButtonWithProps(child, size));
|
|
158
|
+
}
|
|
159
|
+
else if (type === Dropdown) {
|
|
160
|
+
const childProps = child.props
|
|
161
|
+
.children;
|
|
162
|
+
if (!isValidElement(childProps) || childProps.type !== Button) {
|
|
163
|
+
console.warn('[Mezzanine][ContentHeader]: Dropdown in utilities should have Button with icon as its children.');
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
utilities.push(cloneElement(child, {
|
|
167
|
+
children: renderIconButtonWithProps(child.props
|
|
168
|
+
.children, size),
|
|
169
|
+
}));
|
|
170
|
+
}
|
|
171
|
+
// is actions (normal button)
|
|
172
|
+
else if (type === Button) {
|
|
173
|
+
const variant = props.variant;
|
|
174
|
+
if (variant !== 'base-primary' &&
|
|
175
|
+
variant !== 'base-secondary' &&
|
|
176
|
+
variant !== 'destructive-secondary' &&
|
|
177
|
+
variant !== undefined) {
|
|
178
|
+
console.warn(`[Mezzanine][ContentHeader]: Button with variant "${variant}" will not be rendered in ContentHeader actions.`);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const buttonElement = renderButton(child, size);
|
|
182
|
+
if (!buttonElement) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (variant === 'destructive-secondary') {
|
|
186
|
+
actionsWithOrder[0].push(buttonElement);
|
|
187
|
+
}
|
|
188
|
+
else if (variant === 'base-secondary') {
|
|
189
|
+
actionsWithOrder[1].push(buttonElement);
|
|
190
|
+
}
|
|
191
|
+
else if (variant === 'base-primary') {
|
|
192
|
+
actionsWithOrder[2].push(buttonElement);
|
|
193
|
+
}
|
|
194
|
+
else if (variant === undefined) {
|
|
195
|
+
actionsWithOrder[2].push(buttonElement);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
console.warn('[Mezzanine][ContentHeader]: ContentHeader only accepts Input (search variant), Select, SegmentedControl, Dropdown with Icon Button, or Button as children.');
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
filter,
|
|
205
|
+
actions: [
|
|
206
|
+
...actionsWithOrder[0],
|
|
207
|
+
...actionsWithOrder[1],
|
|
208
|
+
...actionsWithOrder[2],
|
|
209
|
+
],
|
|
210
|
+
utilities,
|
|
211
|
+
backButton,
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
export { renderActionsProp, renderButton, renderFilterProp, renderIconButtonWithProps, renderIconButtonsProp, resolveContentHeaderChild };
|
|
@@ -39,7 +39,10 @@ function useDateRangeCalendarControls(referenceDate, mode) {
|
|
|
39
39
|
const onPrevFactory = (target) => () => {
|
|
40
40
|
var _a;
|
|
41
41
|
const modifiers = modifierGroup[currentMode];
|
|
42
|
-
const
|
|
42
|
+
const activeModifiers = (_a = modifiers.single) !== null && _a !== void 0 ? _a : modifiers.double;
|
|
43
|
+
if (!activeModifiers)
|
|
44
|
+
return;
|
|
45
|
+
const [handleMinus] = activeModifiers;
|
|
43
46
|
const newAnchor = handleMinus(referenceDates[target]);
|
|
44
47
|
const newDates = [...referenceDates];
|
|
45
48
|
newDates[target] = newAnchor;
|
|
@@ -54,7 +57,10 @@ function useDateRangeCalendarControls(referenceDate, mode) {
|
|
|
54
57
|
const onNextFactory = (target) => () => {
|
|
55
58
|
var _a;
|
|
56
59
|
const modifiers = modifierGroup[currentMode];
|
|
57
|
-
const
|
|
60
|
+
const activeModifiers = (_a = modifiers.single) !== null && _a !== void 0 ? _a : modifiers.double;
|
|
61
|
+
if (!activeModifiers)
|
|
62
|
+
return;
|
|
63
|
+
const [, handleAdd] = activeModifiers;
|
|
58
64
|
const newAnchor = handleAdd(referenceDates[target]);
|
|
59
65
|
const newDates = [...referenceDates];
|
|
60
66
|
newDates[target] = newAnchor;
|