@mezzanine-ui/react 1.0.0-alpha.0 → 1.0.0-beta.1
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/Breadcrumb/Breadcrumb.js +40 -12
- package/Breadcrumb/typings.d.ts +8 -3
- package/Drawer/Drawer.d.ts +47 -6
- package/Drawer/Drawer.js +36 -11
- package/Dropdown/Dropdown.d.ts +116 -15
- package/Dropdown/Dropdown.js +235 -32
- package/Dropdown/DropdownAction.d.ts +50 -0
- package/Dropdown/DropdownAction.js +26 -0
- package/Dropdown/DropdownItem.d.ts +60 -0
- package/Dropdown/DropdownItem.js +318 -0
- package/Dropdown/DropdownItemCard.d.ts +96 -0
- package/Dropdown/DropdownItemCard.js +115 -0
- package/Dropdown/DropdownStatus.d.ts +22 -0
- package/Dropdown/dropdownKeydownHandler.d.ts +15 -0
- package/Dropdown/highlightText.d.ts +9 -0
- package/Dropdown/highlightText.js +32 -0
- package/Dropdown/index.d.ts +1 -1
- package/Empty/Empty.js +26 -3
- package/Empty/typings.d.ts +16 -7
- package/Navigation/Navigation.d.ts +11 -17
- package/Navigation/Navigation.js +58 -41
- package/Navigation/NavigationFooter.d.ts +10 -0
- package/Navigation/NavigationFooter.js +26 -0
- package/Navigation/NavigationHeader.d.ts +8 -0
- package/Navigation/NavigationHeader.js +13 -0
- package/Navigation/NavigationIconButton.d.ts +15 -0
- package/Navigation/NavigationIconButton.js +12 -0
- package/Navigation/NavigationOption.d.ts +35 -0
- package/Navigation/NavigationOption.js +60 -0
- package/Navigation/NavigationOptionCategory.d.ts +6 -0
- package/Navigation/NavigationOptionCategory.js +12 -0
- package/Navigation/NavigationUserMenu.d.ts +8 -0
- package/Navigation/NavigationUserMenu.js +18 -0
- package/Navigation/context.d.ts +13 -0
- package/Navigation/context.js +7 -0
- package/Navigation/index.d.ts +12 -6
- package/Navigation/index.js +6 -3
- package/Navigation/useCurrentPathname.d.ts +1 -0
- package/Navigation/useCurrentPathname.js +14 -0
- package/PageHeader/PageHeader.d.ts +5 -1
- package/PageHeader/PageHeader.js +8 -3
- package/PageToolbar/PageToolbar.d.ts +73 -26
- package/PageToolbar/PageToolbar.js +10 -101
- package/PageToolbar/utils.d.ts +23 -0
- package/PageToolbar/utils.js +165 -0
- package/Pagination/PaginationItem.js +1 -3
- package/Pagination/usePagination.js +0 -18
- package/Radio/Radio.d.ts +36 -3
- package/Radio/Radio.js +21 -11
- package/Radio/RadioGroup.d.ts +36 -7
- package/Radio/RadioGroup.js +5 -4
- package/Radio/RadioGroupContext.d.ts +2 -1
- package/Radio/index.d.ts +3 -3
- package/Slider/useSlider.js +1 -1
- package/Tab/Tab.d.ts +32 -0
- package/Tab/Tab.js +57 -0
- package/Tab/TabItem.d.ts +27 -0
- package/Tab/TabItem.js +18 -0
- package/Tab/index.d.ts +4 -0
- package/Tab/index.js +2 -0
- package/Table/Table.d.ts +75 -94
- package/Table/Table.js +216 -161
- package/Table/TableContext.d.ts +114 -51
- package/Table/TableContext.js +21 -3
- package/Table/components/TableBody.d.ts +5 -0
- package/Table/components/TableBody.js +102 -0
- package/Table/components/TableCell.d.ts +17 -0
- package/Table/components/TableCell.js +74 -0
- package/Table/components/TableColGroup.d.ts +4 -0
- package/Table/components/TableColGroup.js +206 -0
- package/Table/components/TableDragHandleCell.d.ts +9 -0
- package/Table/components/TableDragHandleCell.js +37 -0
- package/Table/components/TableExpandCell.d.ts +11 -0
- package/Table/components/TableExpandCell.js +44 -0
- package/Table/components/TableExpandedRow.d.ts +9 -0
- package/Table/components/TableExpandedRow.js +46 -0
- package/Table/components/TableHeader.d.ts +4 -0
- package/Table/components/TableHeader.js +125 -0
- package/Table/components/TablePagination.d.ts +3 -0
- package/Table/components/TablePagination.js +11 -0
- package/Table/components/TableResizeHandle.d.ts +13 -0
- package/Table/components/TableResizeHandle.js +115 -0
- package/Table/components/TableRow.d.ts +12 -0
- package/Table/components/TableRow.js +126 -0
- package/Table/components/TableSelectionCell.d.ts +13 -0
- package/Table/components/TableSelectionCell.js +35 -0
- package/Table/components/index.d.ts +10 -0
- package/Table/components/index.js +10 -0
- package/Table/hooks/index.d.ts +9 -0
- package/Table/hooks/index.js +8 -0
- package/Table/hooks/typings.d.ts +14 -0
- package/Table/hooks/useTableColumns.d.ts +8 -0
- package/Table/hooks/useTableColumns.js +91 -0
- package/Table/hooks/useTableDataSource.d.ts +57 -0
- package/Table/hooks/useTableDataSource.js +183 -0
- package/Table/hooks/useTableExpansion.d.ts +7 -0
- package/Table/hooks/useTableExpansion.js +52 -0
- package/Table/hooks/useTableFixedOffsets.d.ts +29 -0
- package/Table/hooks/useTableFixedOffsets.js +241 -0
- package/Table/hooks/useTableScroll.d.ts +12 -0
- package/Table/hooks/useTableScroll.js +58 -0
- package/Table/hooks/useTableSelection.d.ts +7 -0
- package/Table/hooks/useTableSelection.js +94 -0
- package/Table/hooks/useTableSorting.d.ts +6 -0
- package/Table/hooks/useTableSorting.js +32 -0
- package/Table/hooks/useTableVirtualization.d.ts +22 -0
- package/Table/hooks/useTableVirtualization.js +115 -0
- package/Table/index.d.ts +7 -10
- package/Table/index.js +22 -6
- package/Table/utils/index.d.ts +2 -0
- package/Table/utils/index.js +1 -0
- package/Table/utils/useTableRowSelection.d.ts +18 -0
- package/Table/utils/useTableRowSelection.js +63 -0
- package/_internal/InputCheck/InputCheck.d.ts +15 -1
- package/_internal/InputCheck/InputCheck.js +6 -2
- package/_internal/InputCheck/InputCheckGroup.d.ts +11 -1
- package/_internal/InputCheck/InputCheckGroup.js +4 -2
- package/_internal/SlideFadeOverlay/SlideFadeOverlay.d.ts +1 -1
- package/_internal/SlideFadeOverlay/SlideFadeOverlay.js +1 -1
- package/hooks/useElementHeight.d.ts +8 -0
- package/hooks/useElementHeight.js +41 -0
- package/index.d.ts +9 -7
- package/index.js +6 -11
- package/package.json +6 -4
- package/utils/flatten-children.d.ts +12 -0
- package/utils/flatten-children.js +37 -0
- package/utils/get-css-variable-value.d.ts +1 -0
- package/utils/get-css-variable-value.js +4 -1
- package/Navigation/NavigationContext.d.ts +0 -5
- package/Navigation/NavigationContext.js +0 -8
- package/Navigation/NavigationItem.d.ts +0 -31
- package/Navigation/NavigationItem.js +0 -23
- package/Navigation/NavigationSubMenu.d.ts +0 -22
- package/Navigation/NavigationSubMenu.js +0 -50
- package/Table/TableBody.d.ts +0 -10
- package/Table/TableBody.js +0 -31
- package/Table/TableBodyRow.d.ts +0 -11
- package/Table/TableBodyRow.js +0 -65
- package/Table/TableCell.d.ts +0 -19
- package/Table/TableCell.js +0 -24
- package/Table/TableExpandedTable.d.ts +0 -11
- package/Table/TableExpandedTable.js +0 -29
- package/Table/TableHeader.d.ts +0 -3
- package/Table/TableHeader.js +0 -36
- package/Table/draggable/useTableDraggable.d.ts +0 -14
- package/Table/draggable/useTableDraggable.js +0 -64
- package/Table/editable/TableEditRenderWrapper.d.ts +0 -7
- package/Table/editable/TableEditRenderWrapper.js +0 -16
- package/Table/expandable/TableExpandable.d.ts +0 -27
- package/Table/expandable/TableExpandable.js +0 -24
- package/Table/pagination/TablePagination.d.ts +0 -10
- package/Table/pagination/TablePagination.js +0 -26
- package/Table/pagination/useTablePagination.d.ts +0 -8
- package/Table/pagination/useTablePagination.js +0 -30
- package/Table/refresh/TableRefresh.d.ts +0 -10
- package/Table/refresh/TableRefresh.js +0 -22
- package/Table/rowSelection/TableRowSelection.d.ts +0 -18
- package/Table/rowSelection/TableRowSelection.js +0 -93
- package/Table/rowSelection/useTableRowSelection.d.ts +0 -6
- package/Table/rowSelection/useTableRowSelection.js +0 -53
- package/Table/sorting/TableSortingIcon.d.ts +0 -10
- package/Table/sorting/TableSortingIcon.js +0 -33
- package/Table/sorting/useTableSorting.d.ts +0 -11
- package/Table/sorting/useTableSorting.js +0 -121
- package/Table/useTableFetchMore.d.ts +0 -10
- package/Table/useTableFetchMore.js +0 -50
- package/Table/useTableLoading.d.ts +0 -5
- package/Table/useTableLoading.js +0 -19
- package/Table/useTableScroll.d.ts +0 -592
- package/Table/useTableScroll.js +0 -296
- package/Tabs/Tab.d.ts +0 -18
- package/Tabs/Tab.js +0 -16
- package/Tabs/TabPane.d.ts +0 -14
- package/Tabs/TabPane.js +0 -19
- package/Tabs/Tabs.d.ts +0 -39
- package/Tabs/Tabs.js +0 -52
- package/Tabs/index.d.ts +0 -6
- package/Tabs/index.js +0 -3
- package/Tabs/useTabsOverflow.d.ts +0 -8
- package/Tabs/useTabsOverflow.js +0 -62
package/Breadcrumb/Breadcrumb.js
CHANGED
|
@@ -1,25 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { forwardRef } from 'react';
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { forwardRef, isValidElement, cloneElement } from 'react';
|
|
3
3
|
import { SlashIcon } from '@mezzanine-ui/icons';
|
|
4
4
|
import { breadcrumbClasses } from '@mezzanine-ui/core/breadcrumb';
|
|
5
5
|
import BreadcrumbItem from './BreadcrumbItem.js';
|
|
6
|
+
import { flattenChildren } from '../utils/flatten-children.js';
|
|
6
7
|
import Icon from '../Icon/Icon.js';
|
|
7
8
|
import cx from 'clsx';
|
|
8
9
|
|
|
10
|
+
const renderItemWithProps = (item, appendProps) => {
|
|
11
|
+
if (isValidElement(item)) {
|
|
12
|
+
return cloneElement(item, appendProps);
|
|
13
|
+
}
|
|
14
|
+
return jsx(BreadcrumbItem, { ...item, ...appendProps });
|
|
15
|
+
};
|
|
16
|
+
const renderItems = (items, condensed) => {
|
|
17
|
+
if (!items) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const lastIndex = items.length - 1;
|
|
21
|
+
return (jsxs(Fragment, { children: [!condensed &&
|
|
22
|
+
lastIndex >= 0 &&
|
|
23
|
+
renderItemWithProps(items[0], { current: lastIndex === 0 }), !condensed && lastIndex >= 1 && (jsxs(Fragment, { children: [jsx(Icon, { icon: SlashIcon, size: 14 }), renderItemWithProps(items[1], { current: lastIndex === 1 })] })), !condensed && items.length <= 4 && (jsxs(Fragment, { children: [lastIndex >= 2 && (jsxs(Fragment, { children: [jsx(Icon, { icon: SlashIcon, size: 14 }), renderItemWithProps(items[2], { current: lastIndex === 2 })] })), lastIndex === 3 && (jsxs(Fragment, { children: [jsx(Icon, { icon: SlashIcon, size: 14 }), renderItemWithProps(items[3], { current: true })] }))] })), (items.length > 4 || condensed) && (jsxs(Fragment, { children: [!condensed && jsx(Icon, { icon: SlashIcon, size: 14 }), (!condensed || items.length > 2) && (jsxs(Fragment, { children: [jsx(BreadcrumbItem, { options: (condensed
|
|
24
|
+
? items.slice(0, lastIndex - 1)
|
|
25
|
+
: items.slice(2, lastIndex - 1)).map((item) => {
|
|
26
|
+
if (isValidElement(item)) {
|
|
27
|
+
const { props } = item;
|
|
28
|
+
return {
|
|
29
|
+
label: props.label,
|
|
30
|
+
href: props.href,
|
|
31
|
+
target: props.target,
|
|
32
|
+
id: props.id,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
label: item.label,
|
|
37
|
+
href: item.href,
|
|
38
|
+
target: item.target,
|
|
39
|
+
id: item.id,
|
|
40
|
+
};
|
|
41
|
+
}) }), jsx(Icon, { icon: SlashIcon, size: 14 })] })), lastIndex - 1 >= 0 && (jsxs(Fragment, { children: [renderItemWithProps(items[lastIndex - 1]), jsx(Icon, { icon: SlashIcon, size: 14 })] })), renderItemWithProps(items[lastIndex], { current: true })] }))] }));
|
|
42
|
+
};
|
|
9
43
|
/**
|
|
10
44
|
* The react component for `mezzanine` breadcrumb.
|
|
11
45
|
*/
|
|
12
46
|
const Breadcrumb = forwardRef(function Breadcrumb(props, ref) {
|
|
13
|
-
const { className, condensed, items, ...rest } = props;
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
: items.slice(2, lastIndex - 1)).map((item) => ({
|
|
18
|
-
label: item.label,
|
|
19
|
-
href: item.href,
|
|
20
|
-
target: item.target,
|
|
21
|
-
id: item.id,
|
|
22
|
-
})) }), jsx(Icon, { icon: SlashIcon, size: 14 })] })), lastIndex - 1 >= 0 && (jsxs(Fragment, { children: [jsx(BreadcrumbItem, { ...items[lastIndex - 1] }), jsx(Icon, { icon: SlashIcon, size: 14 })] })), jsx(BreadcrumbItem, { ...items[lastIndex], current: true })] }))] }));
|
|
47
|
+
const { children, className, condensed, items, ...rest } = props;
|
|
48
|
+
const flatChildren = flattenChildren(children);
|
|
49
|
+
const itemFragment = renderItems(items || flatChildren, condensed);
|
|
50
|
+
return (jsx("nav", { ...rest, "aria-label": "Breadcrumb", className: cx(breadcrumbClasses.host, className), ref: ref, children: itemFragment }));
|
|
23
51
|
});
|
|
24
52
|
|
|
25
53
|
export { Breadcrumb as default };
|
package/Breadcrumb/typings.d.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import type { JSXElementConstructor } from 'react';
|
|
1
|
+
import type { JSXElementConstructor, ReactElement } from 'react';
|
|
2
2
|
import type { ComponentOverridableForwardRefComponentPropsFactory, NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
3
|
-
export
|
|
3
|
+
export type BreadcrumbProps = Omit<NativeElementPropsWithoutKeyAndRef<'nav'>, 'children'> & ({
|
|
4
4
|
/**
|
|
5
5
|
* Display only the last two items with an ellipsis dropdown for all previous items
|
|
6
6
|
*/
|
|
7
7
|
condensed?: boolean;
|
|
8
8
|
items: Array<BreadcrumbItemProps>;
|
|
9
|
-
|
|
9
|
+
children?: never;
|
|
10
|
+
} | {
|
|
11
|
+
condensed?: boolean;
|
|
12
|
+
items?: never;
|
|
13
|
+
children: ReactElement<BreadcrumbItemProps> | ReactElement<BreadcrumbItemProps>[];
|
|
14
|
+
});
|
|
10
15
|
export type BreadcrumbItemComponent = 'a' | 'button' | JSXElementConstructor<any>;
|
|
11
16
|
export type BreadcrumbItemProps<C extends BreadcrumbItemComponent = 'button'> = ComponentOverridableForwardRefComponentPropsFactory<BreadcrumbItemComponent, C, BreadcrumbDropdownItemProps | BreadcrumbItemTextProps | BreadcrumbLinkItemProps>;
|
|
12
17
|
export type BreadcrumbDropdownItemProps = Omit<NativeElementPropsWithoutKeyAndRef<'button'>, 'children'> & {
|
package/Drawer/Drawer.d.ts
CHANGED
|
@@ -1,12 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { SlideFadeOverlayProps } from '../_internal/SlideFadeOverlay';
|
|
1
|
+
import { DrawerSize } from '@mezzanine-ui/core/drawer';
|
|
3
2
|
import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
4
|
-
|
|
3
|
+
import { BackdropProps } from '../Backdrop';
|
|
4
|
+
export interface DrawerProps extends NativeElementPropsWithoutKeyAndRef<'div'>, Pick<BackdropProps, 'container' | 'disableCloseOnBackdropClick' | 'disablePortal' | 'onBackdropClick' | 'onClose' | 'open'> {
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
* @default 'left'
|
|
6
|
+
* Text for the ghost action button in the bottom action area.
|
|
8
7
|
*/
|
|
9
|
-
|
|
8
|
+
bottomGhostActionText?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Click handler for the ghost action button in the bottom action area.
|
|
11
|
+
*/
|
|
12
|
+
bottomOnGhostActionClick?: VoidFunction;
|
|
13
|
+
/**
|
|
14
|
+
* Click handler for the primary action button in the bottom action area.
|
|
15
|
+
*/
|
|
16
|
+
bottomOnPrimaryActionClick?: VoidFunction;
|
|
17
|
+
/**
|
|
18
|
+
* Click handler for the secondary action button in the bottom action area.
|
|
19
|
+
*/
|
|
20
|
+
bottomOnSecondaryActionClick?: VoidFunction;
|
|
21
|
+
/**
|
|
22
|
+
* Text for the primary action button in the bottom action area.
|
|
23
|
+
*/
|
|
24
|
+
bottomPrimaryActionText?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Text for the secondary action button in the bottom action area.
|
|
27
|
+
*/
|
|
28
|
+
bottomSecondaryActionText?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Controls whether to disable closing drawer while escape key down.
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
33
|
+
disableCloseOnEscapeKeyDown?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Title text displayed in the drawer header.
|
|
36
|
+
*/
|
|
37
|
+
headerTitle?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Controls whether to display the bottom action area.
|
|
40
|
+
*/
|
|
41
|
+
isBottomDisplay?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Controls whether to display the header area.
|
|
44
|
+
*/
|
|
45
|
+
isHeaderDisplay?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Controls the width of the drawer.
|
|
48
|
+
* @default 'medium'
|
|
49
|
+
*/
|
|
50
|
+
size?: DrawerSize;
|
|
10
51
|
}
|
|
11
52
|
declare const Drawer: import("react").ForwardRefExoticComponent<DrawerProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
12
53
|
export default Drawer;
|
package/Drawer/Drawer.js
CHANGED
|
@@ -1,18 +1,43 @@
|
|
|
1
|
-
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { forwardRef,
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { forwardRef, useState } from 'react';
|
|
3
3
|
import { drawerClasses } from '@mezzanine-ui/core/drawer';
|
|
4
|
-
import
|
|
4
|
+
import { useDocumentEscapeKeyDown } from '../hooks/useDocumentEscapeKeyDown.js';
|
|
5
|
+
import useTopStack from '../_internal/SlideFadeOverlay/useTopStack.js';
|
|
6
|
+
import ClearActions from '../ClearActions/ClearActions.js';
|
|
7
|
+
import Button from '../Button/Button.js';
|
|
8
|
+
import { MOTION_EASING, MOTION_DURATION } from '@mezzanine-ui/system/motion';
|
|
9
|
+
import Backdrop from '../Backdrop/Backdrop.js';
|
|
10
|
+
import Slide from '../Transition/Slide.js';
|
|
5
11
|
import cx from 'clsx';
|
|
6
12
|
|
|
7
13
|
const Drawer = forwardRef((props, ref) => {
|
|
8
|
-
const {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const { bottomGhostActionText, bottomOnGhostActionClick, bottomOnPrimaryActionClick, bottomOnSecondaryActionClick, bottomPrimaryActionText, bottomSecondaryActionText, children, className, container, disableCloseOnBackdropClick = false, disableCloseOnEscapeKeyDown = false, disablePortal, headerTitle, isBottomDisplay, isHeaderDisplay, onBackdropClick, onClose, open, size = 'medium', ...rest } = props;
|
|
15
|
+
const [exited, setExited] = useState(true);
|
|
16
|
+
/**
|
|
17
|
+
* Escape keydown close: escape will only close the top drawer
|
|
18
|
+
*/
|
|
19
|
+
const checkIsOnTheTop = useTopStack(open);
|
|
20
|
+
useDocumentEscapeKeyDown(() => {
|
|
21
|
+
if (!open || disableCloseOnEscapeKeyDown || !onClose) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
return (event) => {
|
|
25
|
+
if (checkIsOnTheTop()) {
|
|
26
|
+
event.stopPropagation();
|
|
27
|
+
onClose();
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}, [disableCloseOnEscapeKeyDown, checkIsOnTheTop, open, onClose]);
|
|
31
|
+
if (!open && exited) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return (jsx(Backdrop, { className: drawerClasses.overlay, container: container, disableCloseOnBackdropClick: disableCloseOnBackdropClick, disablePortal: disablePortal, onBackdropClick: onBackdropClick, onClose: onClose, open: open, role: "presentation", children: jsx(Slide, { duration: {
|
|
35
|
+
enter: MOTION_DURATION.moderate,
|
|
36
|
+
exit: MOTION_DURATION.moderate,
|
|
37
|
+
}, easing: {
|
|
38
|
+
enter: MOTION_EASING.entrance,
|
|
39
|
+
exit: MOTION_EASING.exit,
|
|
40
|
+
}, in: open, onEntered: () => setExited(false), onExited: () => setExited(true), ref: ref, children: jsxs("div", { ...rest, className: cx(drawerClasses.host, drawerClasses.right, drawerClasses.size(size), className), children: [isHeaderDisplay && (jsxs("div", { className: drawerClasses.header, children: [headerTitle, jsx(ClearActions, { onClick: onClose })] })), jsx("div", { className: drawerClasses.content, children: children }), isBottomDisplay && (jsxs("div", { className: drawerClasses.bottom, children: [jsx("div", { children: bottomGhostActionText && bottomOnGhostActionClick && (jsx(Button, { onClick: bottomOnGhostActionClick, type: "button", variant: "base-ghost", children: bottomGhostActionText })) }), jsxs("div", { className: drawerClasses['bottom__actions'], children: [bottomSecondaryActionText && bottomOnSecondaryActionClick && (jsx(Button, { onClick: bottomOnSecondaryActionClick, type: "button", variant: "base-secondary", children: bottomSecondaryActionText })), bottomPrimaryActionText && bottomOnPrimaryActionClick && (jsx(Button, { onClick: bottomOnPrimaryActionClick, type: "button", variant: "base-primary", children: bottomPrimaryActionText }))] })] }))] }) }) }));
|
|
16
41
|
});
|
|
17
42
|
|
|
18
43
|
export { Drawer as default };
|
package/Dropdown/Dropdown.d.ts
CHANGED
|
@@ -1,25 +1,126 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { dropdownInputPosition, DropdownItemSharedProps, DropdownOption, dropdownType } from '@mezzanine-ui/core/dropdown/dropdown';
|
|
3
|
+
import { ButtonProps } from '../Button';
|
|
4
|
+
import { InputProps } from '../Input';
|
|
5
|
+
import { PopperPlacement } from '../Popper';
|
|
6
|
+
export interface DropdownProps extends DropdownItemSharedProps {
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
+
* The text of the cancel button.
|
|
9
|
+
*/
|
|
10
|
+
actionCancelText?: string;
|
|
11
|
+
/**
|
|
12
|
+
* The text of the clear button.
|
|
13
|
+
*/
|
|
14
|
+
actionClearText?: string;
|
|
15
|
+
/**
|
|
16
|
+
* The text of the confirm button.
|
|
17
|
+
*/
|
|
18
|
+
actionConfirmText?: string;
|
|
19
|
+
/**
|
|
20
|
+
* The custom action button props of the dropdown.
|
|
21
|
+
*/
|
|
22
|
+
actionCustomButtonProps?: ButtonProps;
|
|
23
|
+
/**
|
|
24
|
+
* The text of the custom action button.
|
|
25
|
+
*/
|
|
26
|
+
actionText?: string;
|
|
27
|
+
/**
|
|
28
|
+
* The active option index for hover/focus state.
|
|
29
|
+
*/
|
|
30
|
+
activeIndex?: number | null;
|
|
31
|
+
/**
|
|
32
|
+
* The children of the dropdown.
|
|
33
|
+
* This can be a button or an input.
|
|
34
|
+
*/
|
|
35
|
+
children: ReactElement<ButtonProps> | ReactElement<InputProps>;
|
|
36
|
+
/**
|
|
37
|
+
* Whether the dropdown is disabled.
|
|
38
|
+
*/
|
|
39
|
+
disabled?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* The id of the dropdown.
|
|
42
|
+
*/
|
|
43
|
+
id?: string;
|
|
44
|
+
/**
|
|
45
|
+
* The position of the input.
|
|
46
|
+
* @default 'outside'
|
|
47
|
+
*/
|
|
48
|
+
inputPosition?: dropdownInputPosition;
|
|
49
|
+
/**
|
|
50
|
+
* Whether to match the input value.
|
|
51
|
+
* @default false
|
|
52
|
+
*/
|
|
53
|
+
isMatchInputValue?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* The listbox id of the dropdown.
|
|
56
|
+
*/
|
|
57
|
+
listboxId?: string;
|
|
58
|
+
/**
|
|
59
|
+
* The aria-label for the listbox.
|
|
60
|
+
* If not provided, a default label will be used when there are no options.
|
|
61
|
+
*/
|
|
62
|
+
listboxLabel?: string;
|
|
63
|
+
/**
|
|
64
|
+
* The max height of the dropdown list.
|
|
65
|
+
*/
|
|
66
|
+
maxHeight?: number | string;
|
|
67
|
+
/**
|
|
68
|
+
* Callback fired when the action cancel is clicked.
|
|
69
|
+
*/
|
|
70
|
+
onActionCancel?: () => void;
|
|
71
|
+
/**
|
|
72
|
+
* Callback fired when the action clear is clicked.
|
|
73
|
+
*/
|
|
74
|
+
onActionClear?: () => void;
|
|
75
|
+
/**
|
|
76
|
+
* Callback fired when the action confirm is clicked.
|
|
77
|
+
*/
|
|
78
|
+
onActionConfirm?: () => void;
|
|
79
|
+
/**
|
|
80
|
+
* Callback fired when the action custom is clicked.
|
|
81
|
+
*/
|
|
82
|
+
onActionCustom?: () => void;
|
|
83
|
+
/**
|
|
84
|
+
* Callback fired when the dropdown is closed.
|
|
85
|
+
*/
|
|
86
|
+
onClose?: () => void;
|
|
87
|
+
/**
|
|
88
|
+
* Callback fired when the item is hovered.
|
|
89
|
+
*/
|
|
90
|
+
onItemHover?: (index: number) => void;
|
|
91
|
+
/**
|
|
92
|
+
* Callback fired when the dropdown is opened.
|
|
93
|
+
*/
|
|
94
|
+
onOpen?: () => void;
|
|
95
|
+
/**
|
|
96
|
+
* Callback fired when the item is selected.
|
|
97
|
+
*/
|
|
98
|
+
onSelect?: (option: DropdownOption) => void;
|
|
99
|
+
/**
|
|
100
|
+
* The options of the dropdown.
|
|
101
|
+
*/
|
|
102
|
+
options: DropdownOption[];
|
|
103
|
+
/**
|
|
104
|
+
* The placement of the dropdown.
|
|
105
|
+
*/
|
|
106
|
+
placement?: PopperPlacement;
|
|
107
|
+
/**
|
|
108
|
+
* Whether to set the same width as its anchor element.
|
|
8
109
|
* @default false
|
|
9
110
|
*/
|
|
10
|
-
|
|
111
|
+
sameWidth?: boolean;
|
|
11
112
|
/**
|
|
12
|
-
*
|
|
113
|
+
* If true, display a bar at the top of the dropdown action area.
|
|
114
|
+
* @default false
|
|
13
115
|
*/
|
|
14
|
-
|
|
116
|
+
showActionShowTopBar?: boolean;
|
|
15
117
|
/**
|
|
16
|
-
*
|
|
118
|
+
* Whether to show the actions.
|
|
17
119
|
*/
|
|
18
|
-
|
|
120
|
+
showDropdownActions?: boolean;
|
|
19
121
|
/**
|
|
20
|
-
*
|
|
122
|
+
* The type of the dropdown.
|
|
21
123
|
*/
|
|
22
|
-
|
|
124
|
+
type?: dropdownType;
|
|
23
125
|
}
|
|
24
|
-
|
|
25
|
-
export default Dropdown;
|
|
126
|
+
export default function Dropdown(props: DropdownProps): import("react/jsx-runtime").JSX.Element;
|
package/Dropdown/Dropdown.js
CHANGED
|
@@ -1,42 +1,245 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useId, useMemo, useState, useRef, useEffect, useCallback, cloneElement, createElement } from 'react';
|
|
4
|
+
import cx from 'clsx';
|
|
5
|
+
import { dropdownClasses } from '@mezzanine-ui/core/dropdown/dropdown';
|
|
6
|
+
import { size, offset } from '@floating-ui/react-dom';
|
|
7
|
+
import { MOTION_EASING, MOTION_DURATION } from '@mezzanine-ui/system/motion';
|
|
8
|
+
import { TransitionGroup } from 'react-transition-group';
|
|
9
|
+
import Button from '../Button/Button.js';
|
|
10
|
+
import { useDocumentEvents } from '../hooks/useDocumentEvents.js';
|
|
11
|
+
import Translate from '../Transition/Translate.js';
|
|
12
|
+
import { composeRefs } from '../utils/composeRefs.js';
|
|
13
|
+
import DropdownItem from './DropdownItem.js';
|
|
6
14
|
import Popper from '../Popper/Popper.js';
|
|
7
15
|
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
function Dropdown(props) {
|
|
17
|
+
const { activeIndex: activeIndexProp, id, children, options = [], type = 'default', maxHeight, disabled = false, showDropdownActions = false, actionCancelText, actionConfirmText, actionText, actionClearText, actionCustomButtonProps, showActionShowTopBar, isMatchInputValue = false, inputPosition = 'outside', placement = 'bottom', sameWidth = false, listboxId: listboxIdProp, listboxLabel, onClose, onOpen, onSelect, onActionConfirm, onActionCancel, onActionCustom, onActionClear, onItemHover, } = props;
|
|
18
|
+
const isInline = inputPosition === 'inside';
|
|
19
|
+
const inputId = useId();
|
|
20
|
+
const defaultListboxId = `${inputId}-listbox`;
|
|
21
|
+
const listboxId = listboxIdProp !== null && listboxIdProp !== void 0 ? listboxIdProp : defaultListboxId;
|
|
22
|
+
const actionConfig = useMemo(() => {
|
|
23
|
+
return {
|
|
24
|
+
showActions: showDropdownActions,
|
|
25
|
+
cancelText: actionCancelText,
|
|
26
|
+
confirmText: actionConfirmText,
|
|
27
|
+
clearText: actionClearText,
|
|
28
|
+
actionText,
|
|
29
|
+
customActionButtonProps: actionCustomButtonProps,
|
|
30
|
+
showTopBar: showActionShowTopBar,
|
|
31
|
+
onConfirm: onActionConfirm,
|
|
32
|
+
onCancel: onActionCancel,
|
|
33
|
+
onClick: onActionCustom,
|
|
34
|
+
onClear: onActionClear,
|
|
35
|
+
};
|
|
36
|
+
}, [showDropdownActions, actionCancelText, actionConfirmText, actionClearText, actionText, actionCustomButtonProps, showActionShowTopBar, onActionConfirm, onActionCancel, onActionCustom, onActionClear]);
|
|
37
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
38
|
+
const [uncontrolledActiveIndex, setUncontrolledActiveIndex] = useState(activeIndexProp !== null && activeIndexProp !== void 0 ? activeIndexProp : null);
|
|
39
|
+
const isActiveIndexControlled = activeIndexProp !== undefined;
|
|
40
|
+
const mergedActiveIndex = isActiveIndexControlled ? activeIndexProp : uncontrolledActiveIndex;
|
|
41
|
+
const containerRef = useRef(null);
|
|
42
|
+
const ariaActivedescendant = useMemo(() => {
|
|
43
|
+
if (mergedActiveIndex !== null && mergedActiveIndex >= 0) {
|
|
44
|
+
return `${listboxId}-option-${mergedActiveIndex}`;
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
}, [mergedActiveIndex, listboxId]);
|
|
48
|
+
const translateProps = useMemo(() => ({
|
|
49
|
+
duration: {
|
|
50
|
+
enter: MOTION_DURATION.moderate,
|
|
51
|
+
exit: MOTION_DURATION.moderate,
|
|
52
|
+
},
|
|
53
|
+
easing: {
|
|
54
|
+
enter: MOTION_EASING.standard,
|
|
55
|
+
exit: MOTION_EASING.standard,
|
|
56
|
+
},
|
|
57
|
+
}), []);
|
|
58
|
+
const followText = useMemo(() => {
|
|
59
|
+
var _a, _b, _c, _d;
|
|
60
|
+
if (children.type === Button) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
if (!isMatchInputValue) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
// Try to get value from Input component props
|
|
67
|
+
const inputValue = (_d = (_b = (_a = children.props) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : (_c = children.props) === null || _c === void 0 ? void 0 : _c.defaultValue) !== null && _d !== void 0 ? _d : '';
|
|
68
|
+
return inputValue;
|
|
69
|
+
}, [children, isMatchInputValue]);
|
|
70
|
+
const popoverPlacement = useMemo(() => {
|
|
71
|
+
if (inputPosition === 'outside') {
|
|
72
|
+
return placement;
|
|
73
|
+
}
|
|
74
|
+
return 'bottom';
|
|
75
|
+
}, [inputPosition, placement]);
|
|
76
|
+
const sameWidthMiddleware = useMemo(() => {
|
|
77
|
+
if (!sameWidth) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
return size({
|
|
81
|
+
apply({ rects, elements }) {
|
|
82
|
+
Object.assign(elements.floating.style, {
|
|
83
|
+
width: `${rects.reference.width}px`,
|
|
84
|
+
});
|
|
85
|
+
},
|
|
14
86
|
});
|
|
15
|
-
},
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
const
|
|
87
|
+
}, [sameWidth]);
|
|
88
|
+
const offsetMiddleware = useMemo(() => {
|
|
89
|
+
return offset({ mainAxis: 4 });
|
|
90
|
+
}, []);
|
|
91
|
+
const prevIsOpenRef = useRef(isOpen);
|
|
92
|
+
const translateFrom = useMemo(() => {
|
|
93
|
+
if (isInline) {
|
|
94
|
+
return 'bottom';
|
|
95
|
+
}
|
|
96
|
+
const placementBase = popoverPlacement.split('-')[0];
|
|
97
|
+
return placementBase === 'top' ? 'top' : 'bottom';
|
|
98
|
+
}, [isInline, popoverPlacement]);
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (prevIsOpenRef.current === isOpen)
|
|
101
|
+
return;
|
|
102
|
+
if (isOpen) {
|
|
103
|
+
onOpen === null || onOpen === void 0 ? void 0 : onOpen();
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
107
|
+
}
|
|
108
|
+
prevIsOpenRef.current = isOpen;
|
|
109
|
+
}, [isOpen, onClose, onOpen]);
|
|
110
|
+
const anchorRef = useRef(null);
|
|
21
111
|
const popperRef = useRef(null);
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (!
|
|
112
|
+
// Extract combobox props logic to avoid duplication
|
|
113
|
+
const getComboboxProps = useMemo(() => {
|
|
114
|
+
const childWithRef = children;
|
|
115
|
+
const isInput = childWithRef.type !== Button;
|
|
116
|
+
if (!isInput)
|
|
117
|
+
return {};
|
|
118
|
+
return {
|
|
119
|
+
role: 'combobox',
|
|
120
|
+
'aria-controls': listboxId,
|
|
121
|
+
'aria-expanded': isOpen,
|
|
122
|
+
'aria-haspopup': 'listbox',
|
|
123
|
+
'aria-autocomplete': isMatchInputValue ? 'list' : undefined,
|
|
124
|
+
'aria-activedescendant': ariaActivedescendant,
|
|
125
|
+
};
|
|
126
|
+
}, [children, listboxId, isOpen, isMatchInputValue, ariaActivedescendant]);
|
|
127
|
+
const handleItemHover = useCallback((index) => {
|
|
128
|
+
if (!isActiveIndexControlled) {
|
|
129
|
+
setUncontrolledActiveIndex(index);
|
|
130
|
+
}
|
|
131
|
+
onItemHover === null || onItemHover === void 0 ? void 0 : onItemHover(index);
|
|
132
|
+
}, [isActiveIndexControlled, onItemHover]);
|
|
133
|
+
// Extract shared DropdownItem props to avoid duplication
|
|
134
|
+
const baseDropdownItemProps = useMemo(() => ({
|
|
135
|
+
actionConfig,
|
|
136
|
+
activeIndex: mergedActiveIndex,
|
|
137
|
+
disabled,
|
|
138
|
+
followText,
|
|
139
|
+
listboxId,
|
|
140
|
+
listboxLabel,
|
|
141
|
+
maxHeight,
|
|
142
|
+
sameWidth,
|
|
143
|
+
onHover: handleItemHover,
|
|
144
|
+
onSelect,
|
|
145
|
+
options,
|
|
146
|
+
type,
|
|
147
|
+
}), [actionConfig, mergedActiveIndex, disabled, followText, listboxId, listboxLabel, maxHeight, sameWidth, handleItemHover, onSelect, options, type]);
|
|
148
|
+
const triggerElement = useMemo(() => {
|
|
149
|
+
const childWithRef = children;
|
|
150
|
+
const composedRef = composeRefs([
|
|
151
|
+
anchorRef,
|
|
152
|
+
childWithRef.ref,
|
|
153
|
+
]);
|
|
154
|
+
return cloneElement(childWithRef, {
|
|
155
|
+
ref: composedRef,
|
|
156
|
+
...getComboboxProps,
|
|
157
|
+
onClick: (event) => {
|
|
158
|
+
var _a, _b;
|
|
159
|
+
(_b = (_a = childWithRef.props) === null || _a === void 0 ? void 0 : _a.onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event);
|
|
160
|
+
if (event === null || event === void 0 ? void 0 : event.defaultPrevented)
|
|
161
|
+
return;
|
|
162
|
+
if (!isInline) {
|
|
163
|
+
setIsOpen((prev) => !prev);
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
}, [children, isInline, getComboboxProps]);
|
|
168
|
+
const inlineTriggerElement = useMemo(() => {
|
|
169
|
+
if (!isInline) {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
const childWithRef = children;
|
|
173
|
+
const composedRef = composeRefs([
|
|
174
|
+
childWithRef.ref,
|
|
175
|
+
]);
|
|
176
|
+
return cloneElement(childWithRef, {
|
|
177
|
+
ref: composedRef,
|
|
178
|
+
...getComboboxProps,
|
|
179
|
+
onBlur: (event) => {
|
|
180
|
+
var _a, _b;
|
|
181
|
+
(_b = (_a = childWithRef.props) === null || _a === void 0 ? void 0 : _a.onBlur) === null || _b === void 0 ? void 0 : _b.call(_a, event);
|
|
182
|
+
if (event === null || event === void 0 ? void 0 : event.defaultPrevented)
|
|
183
|
+
return;
|
|
184
|
+
const nextFocusTarget = event === null || event === void 0 ? void 0 : event.relatedTarget;
|
|
185
|
+
const container = containerRef.current;
|
|
186
|
+
if (container && nextFocusTarget && container.contains(nextFocusTarget)) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
setIsOpen(false);
|
|
190
|
+
},
|
|
191
|
+
onClick: (event) => {
|
|
192
|
+
var _a, _b;
|
|
193
|
+
(_b = (_a = childWithRef.props) === null || _a === void 0 ? void 0 : _a.onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event);
|
|
194
|
+
if (event === null || event === void 0 ? void 0 : event.defaultPrevented)
|
|
195
|
+
return;
|
|
196
|
+
setIsOpen(true);
|
|
197
|
+
},
|
|
198
|
+
onFocus: (event) => {
|
|
199
|
+
var _a, _b;
|
|
200
|
+
(_b = (_a = childWithRef.props) === null || _a === void 0 ? void 0 : _a.onFocus) === null || _b === void 0 ? void 0 : _b.call(_a, event);
|
|
201
|
+
if (event === null || event === void 0 ? void 0 : event.defaultPrevented)
|
|
202
|
+
return;
|
|
203
|
+
setIsOpen(true);
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
}, [children, isInline, isOpen, getComboboxProps]);
|
|
207
|
+
useDocumentEvents(() => {
|
|
208
|
+
if (!isOpen) {
|
|
27
209
|
return;
|
|
28
210
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
211
|
+
const handleClickAway = (event) => {
|
|
212
|
+
const target = event.target;
|
|
213
|
+
const anchor = anchorRef.current;
|
|
214
|
+
const popper = popperRef.current;
|
|
215
|
+
const container = containerRef.current;
|
|
216
|
+
if (!target)
|
|
217
|
+
return;
|
|
218
|
+
if (isInline) {
|
|
219
|
+
if (container && !container.contains(target)) {
|
|
220
|
+
setIsOpen(false);
|
|
221
|
+
}
|
|
222
|
+
return;
|
|
32
223
|
}
|
|
224
|
+
if (anchor && popper && !anchor.contains(target) && !popper.contains(target)) {
|
|
225
|
+
setIsOpen(false);
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
return {
|
|
229
|
+
click: handleClickAway,
|
|
230
|
+
touchend: handleClickAway,
|
|
33
231
|
};
|
|
34
|
-
},
|
|
35
|
-
return (jsxs(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
232
|
+
}, [isInline, isOpen]);
|
|
233
|
+
return (jsxs("div", { id: id, ref: containerRef, className: cx(dropdownClasses.root, dropdownClasses.inputPosition(inputPosition)), children: [isInline && (jsxs(TransitionGroup, { component: null, children: [!isOpen && inlineTriggerElement && (createElement(Translate, { ...translateProps, from: translateFrom, key: "inline-trigger", in: true },
|
|
234
|
+
jsx("div", { children: inlineTriggerElement }))), isOpen && (createElement(Translate, { ...translateProps, from: translateFrom, key: "inline-list", in: true },
|
|
235
|
+
jsx("div", { children: jsx(DropdownItem, { ...baseDropdownItemProps, headerContent: inlineTriggerElement }) })))] })), !isInline && (jsx(Popper, { ref: popperRef, anchor: anchorRef, open: isOpen, disablePortal: true, options: {
|
|
236
|
+
placement: popoverPlacement,
|
|
237
|
+
middleware: [
|
|
238
|
+
offsetMiddleware,
|
|
239
|
+
...(sameWidthMiddleware ? [sameWidthMiddleware] : []),
|
|
240
|
+
],
|
|
241
|
+
}, children: jsx(TransitionGroup, { component: null, children: isOpen && (createElement(Translate, { ...translateProps, from: translateFrom, key: "popper-list", in: true },
|
|
242
|
+
jsx("div", { children: jsx(DropdownItem, { ...baseDropdownItemProps }) }))) }) })), !isInline && triggerElement] }));
|
|
243
|
+
}
|
|
41
244
|
|
|
42
245
|
export { Dropdown as default };
|