@mezzanine-ui/react 1.0.0-beta.1 → 1.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Anchor/Anchor.d.ts +51 -18
- package/Anchor/Anchor.js +15 -15
- package/Anchor/AnchorGroup.d.ts +34 -0
- package/Anchor/AnchorGroup.js +37 -0
- package/Anchor/AnchorItem.d.ts +30 -0
- package/Anchor/AnchorItem.js +65 -0
- package/Anchor/index.d.ts +2 -0
- package/Anchor/index.js +1 -0
- package/Anchor/utils.d.ts +13 -0
- package/Anchor/utils.js +95 -0
- package/AutoComplete/AutoComplete.d.ts +194 -0
- package/AutoComplete/AutoComplete.js +419 -0
- package/AutoComplete/index.d.ts +2 -0
- package/AutoComplete/index.js +1 -0
- package/AutoComplete/useAutoCompleteCreation.d.ts +33 -0
- package/AutoComplete/useAutoCompleteCreation.js +201 -0
- package/AutoComplete/useAutoCompleteKeyboard.d.ts +31 -0
- package/AutoComplete/useAutoCompleteKeyboard.js +149 -0
- package/AutoComplete/useAutoCompleteSearch.d.ts +16 -0
- package/AutoComplete/useAutoCompleteSearch.js +69 -0
- package/AutoComplete/useCreationTracker.d.ts +17 -0
- package/AutoComplete/useCreationTracker.js +47 -0
- package/Badge/Badge.js +2 -2
- package/Breadcrumb/BreadcrumbItem.d.ts +1 -1
- package/Button/Button.js +13 -11
- package/Button/index.d.ts +1 -1
- package/Button/typings.d.ts +27 -4
- package/Description/Description.d.ts +30 -0
- package/Description/Description.js +13 -0
- package/Description/DescriptionContent.d.ts +41 -0
- package/Description/DescriptionContent.js +14 -0
- package/Description/DescriptionGroup.d.ts +13 -0
- package/Description/DescriptionGroup.js +12 -0
- package/Description/DescriptionTitle.d.ts +45 -0
- package/Description/DescriptionTitle.js +17 -0
- package/Description/index.d.ts +8 -0
- package/Description/index.js +4 -0
- package/Dropdown/Dropdown.d.ts +43 -3
- package/Dropdown/Dropdown.js +154 -35
- package/Dropdown/DropdownAction.d.ts +1 -1
- package/Dropdown/DropdownAction.js +1 -4
- package/Dropdown/DropdownItem.d.ts +21 -4
- package/Dropdown/DropdownItem.js +23 -10
- package/Dropdown/DropdownItemCard.d.ts +5 -5
- package/Dropdown/DropdownItemCard.js +11 -10
- package/Dropdown/DropdownStatus.d.ts +2 -2
- package/Dropdown/DropdownStatus.js +29 -0
- package/Dropdown/dropdownKeydownHandler.d.ts +2 -1
- package/Dropdown/dropdownKeydownHandler.js +73 -0
- package/Dropdown/highlightText.js +5 -1
- package/Dropdown/shortcutTextHandler.d.ts +24 -0
- package/Dropdown/shortcutTextHandler.js +171 -0
- package/Form/FormControlContext.d.ts +2 -2
- package/Form/FormField.d.ts +56 -4
- package/Form/FormField.js +10 -6
- package/Form/FormHintText.d.ts +24 -1
- package/Form/FormHintText.js +4 -4
- package/Form/FormLabel.d.ts +6 -3
- package/Form/FormLabel.js +5 -3
- package/Input/Input.d.ts +29 -3
- package/Input/Input.js +22 -6
- package/Input/PasswordStrengthIndicator/PasswordStrengthIndicator.js +1 -1
- package/Modal/Modal.d.ts +103 -11
- package/Modal/Modal.js +14 -9
- package/Modal/ModalBodyForVerification.d.ts +59 -0
- package/Modal/ModalBodyForVerification.js +99 -0
- package/Modal/ModalControl.d.ts +2 -2
- package/Modal/ModalControl.js +1 -1
- package/Modal/ModalFooter.d.ts +119 -1
- package/Modal/ModalFooter.js +15 -3
- package/Modal/ModalHeader.d.ts +26 -7
- package/Modal/ModalHeader.js +33 -7
- package/Modal/index.d.ts +4 -5
- package/Modal/index.js +1 -2
- package/Modal/useModalContainer.d.ts +12 -3
- package/Modal/useModalContainer.js +28 -6
- package/Navigation/CollapsedMenu.d.ts +6 -0
- package/Navigation/CollapsedMenu.js +16 -0
- package/Navigation/Navigation.d.ts +17 -3
- package/Navigation/Navigation.js +48 -33
- package/Navigation/NavigationFooter.js +4 -2
- package/Navigation/NavigationHeader.d.ts +11 -1
- package/Navigation/NavigationHeader.js +6 -3
- package/Navigation/NavigationOption.d.ts +3 -2
- package/Navigation/NavigationOption.js +45 -26
- package/Navigation/NavigationOptionCategory.js +20 -2
- package/Navigation/context.d.ts +2 -0
- package/Navigation/useVisibleItems.d.ts +5 -0
- package/Navigation/useVisibleItems.js +54 -0
- package/NotificationCenter/NotificationCenter.d.ts +124 -0
- package/NotificationCenter/NotificationCenter.js +259 -0
- package/NotificationCenter/NotificationCenterDrawer.d.ts +89 -0
- package/NotificationCenter/index.d.ts +3 -0
- package/NotificationCenter/index.js +1 -0
- package/PageFooter/PageFooter.d.ts +19 -9
- package/PageFooter/PageFooter.js +10 -10
- package/PageHeader/PageHeader.js +4 -12
- package/PageToolbar/PageToolbar.d.ts +2 -6
- package/PageToolbar/utils.js +4 -12
- package/Select/index.d.ts +0 -2
- package/Select/index.js +0 -1
- package/Slider/useSlider.js +1 -1
- package/Table/Table.d.ts +53 -15
- package/Table/Table.js +178 -82
- package/Table/TableContext.d.ts +18 -42
- package/Table/components/TableActionsCell.d.ts +26 -0
- package/Table/components/TableActionsCell.js +78 -0
- package/Table/components/TableBody.d.ts +2 -5
- package/Table/components/TableBody.js +16 -19
- package/Table/components/TableBulkActions.d.ts +15 -0
- package/Table/components/TableBulkActions.js +26 -0
- package/Table/components/TableCell.d.ts +2 -0
- package/Table/components/TableCell.js +42 -10
- package/Table/components/TableColGroup.js +10 -112
- package/Table/components/TableColumnTitleMenu.d.ts +6 -0
- package/Table/components/TableColumnTitleMenu.js +20 -0
- package/Table/components/TableDragHandleCell.d.ts +2 -0
- package/Table/components/TableDragHandleCell.js +8 -1
- package/Table/components/TableExpandCell.d.ts +2 -0
- package/Table/components/TableExpandCell.js +8 -1
- package/Table/components/TableExpandedRow.js +3 -2
- package/Table/components/TableHeader.d.ts +2 -4
- package/Table/components/TableHeader.js +11 -14
- package/Table/components/TableResizeHandle.js +3 -7
- package/Table/components/TableRow.js +54 -20
- package/Table/components/TableSelectionCell.d.ts +5 -0
- package/Table/components/TableSelectionCell.js +12 -1
- package/Table/components/index.d.ts +1 -0
- package/Table/components/index.js +1 -0
- package/Table/hooks/index.d.ts +1 -1
- package/Table/hooks/index.js +1 -1
- package/Table/hooks/useTableDataSource.d.ts +2 -2
- package/Table/hooks/useTableExpansion.js +0 -6
- package/Table/hooks/useTableFixedOffsets.d.ts +1 -1
- package/Table/hooks/useTableFixedOffsets.js +24 -26
- package/Table/hooks/useTableResizedColumns.d.ts +2 -0
- package/Table/hooks/useTableResizedColumns.js +22 -0
- package/Table/hooks/useTableScroll.d.ts +3 -1
- package/Table/hooks/useTableScroll.js +25 -19
- package/Table/hooks/useTableSelection.js +32 -8
- package/Table/hooks/useTableVirtualization.d.ts +1 -1
- package/Table/index.d.ts +4 -4
- package/Table/index.js +5 -3
- package/Table/utils/calculateColumnWidths.d.ts +28 -0
- package/Table/utils/calculateColumnWidths.js +80 -0
- package/Table/utils/index.d.ts +2 -0
- package/Table/utils/index.js +1 -0
- package/Table/utils/useTableRowSelection.d.ts +5 -5
- package/Table/utils/useTableRowSelection.js +14 -6
- package/Tag/TagGroup.d.ts +3 -0
- package/Tag/index.d.ts +2 -0
- package/Tag/index.js +1 -0
- package/Upload/UploadPictureCard.js +1 -1
- package/index.d.ts +36 -20
- package/index.js +26 -7
- package/package.json +4 -4
- package/utils/format-number-with-commas.d.ts +4 -0
- package/utils/format-number-with-commas.js +27 -0
- package/utils/parse-number-with-commas.d.ts +4 -0
- package/utils/parse-number-with-commas.js +22 -0
- package/Modal/ModalActions.d.ts +0 -9
- package/Modal/ModalActions.js +0 -20
- package/Modal/ModalBody.d.ts +0 -7
- package/Modal/ModalBody.js +0 -14
- package/Notification/Notification.d.ts +0 -54
- package/Notification/Notification.js +0 -76
- package/Notification/index.d.ts +0 -3
- package/Notification/index.js +0 -1
- package/Select/AutoComplete.d.ts +0 -107
- package/Select/AutoComplete.js +0 -114
- package/Table/hooks/useTableColumns.d.ts +0 -8
- package/Table/hooks/useTableColumns.js +0 -91
|
@@ -62,9 +62,7 @@ export type PageToolbarProps = Omit<NativeElementPropsWithoutKeyAndRef<'div'>, '
|
|
|
62
62
|
* They usually appear as smaller buttons with only an icon and no text.
|
|
63
63
|
*/
|
|
64
64
|
utilities?: (ButtonProps & {
|
|
65
|
-
icon:
|
|
66
|
-
src: IconDefinition;
|
|
67
|
-
};
|
|
65
|
+
icon: IconDefinition;
|
|
68
66
|
})[];
|
|
69
67
|
};
|
|
70
68
|
/**
|
|
@@ -106,9 +104,7 @@ declare const PageToolbar: import("react").ForwardRefExoticComponent<Omit<Native
|
|
|
106
104
|
* They usually appear as smaller buttons with only an icon and no text.
|
|
107
105
|
*/
|
|
108
106
|
utilities?: (ButtonProps & {
|
|
109
|
-
icon:
|
|
110
|
-
src: IconDefinition;
|
|
111
|
-
};
|
|
107
|
+
icon: IconDefinition;
|
|
112
108
|
})[];
|
|
113
109
|
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
114
110
|
export default PageToolbar;
|
package/PageToolbar/utils.js
CHANGED
|
@@ -45,12 +45,8 @@ const renderFilterProp = (prop, size) => {
|
|
|
45
45
|
const renderIconButtonWithProps = (child, size) => {
|
|
46
46
|
const { icon } = child.props;
|
|
47
47
|
return cloneElement(child, {
|
|
48
|
-
icon: icon
|
|
49
|
-
|
|
50
|
-
...icon,
|
|
51
|
-
position: 'icon-only',
|
|
52
|
-
}
|
|
53
|
-
: undefined,
|
|
48
|
+
icon: icon,
|
|
49
|
+
iconType: icon ? 'icon-only' : undefined,
|
|
54
50
|
size,
|
|
55
51
|
variant: 'base-secondary',
|
|
56
52
|
});
|
|
@@ -58,10 +54,7 @@ const renderIconButtonWithProps = (child, size) => {
|
|
|
58
54
|
const renderIconButtonsProp = (utilities, size) => {
|
|
59
55
|
const result = [];
|
|
60
56
|
utilities === null || utilities === void 0 ? void 0 : utilities.forEach((buttonProps) => {
|
|
61
|
-
result.push(jsx(Button, { ...buttonProps, size: size, icon:
|
|
62
|
-
...buttonProps.icon,
|
|
63
|
-
position: 'icon-only',
|
|
64
|
-
}, variant: "base-secondary" }));
|
|
57
|
+
result.push(jsx(Button, { ...buttonProps, size: size, icon: buttonProps.icon, iconType: buttonProps.icon ? 'icon-only' : undefined, variant: "base-secondary" }));
|
|
65
58
|
});
|
|
66
59
|
return result;
|
|
67
60
|
};
|
|
@@ -94,7 +87,6 @@ const resolvePageToolbarChild = (children, size) => {
|
|
|
94
87
|
if (children) {
|
|
95
88
|
const flatChildren = flattenChildren(children);
|
|
96
89
|
Children.forEach(flatChildren, (child) => {
|
|
97
|
-
var _a;
|
|
98
90
|
if (!isValidElement(child)) {
|
|
99
91
|
return;
|
|
100
92
|
}
|
|
@@ -112,7 +104,7 @@ const resolvePageToolbarChild = (children, size) => {
|
|
|
112
104
|
}
|
|
113
105
|
// is utilities (icon button)
|
|
114
106
|
else if (type === Button &&
|
|
115
|
-
|
|
107
|
+
props.iconType === 'icon-only') {
|
|
116
108
|
utilities.push(renderIconButtonWithProps(child, size));
|
|
117
109
|
}
|
|
118
110
|
// is actions (normal button)
|
package/Select/index.d.ts
CHANGED
|
@@ -12,5 +12,3 @@ export { default as OptionGroup } from '../Menu/MenuItemGroup';
|
|
|
12
12
|
export type { MenuItemGroupProps as OptionGroupProps } from '../Menu/MenuItemGroup';
|
|
13
13
|
export type { TreeSelectProps } from './TreeSelect';
|
|
14
14
|
export { default as TreeSelect } from './TreeSelect';
|
|
15
|
-
export type { AutoCompleteProps } from './AutoComplete';
|
|
16
|
-
export { default as AutoComplete } from './AutoComplete';
|
package/Select/index.js
CHANGED
|
@@ -5,4 +5,3 @@ export { default } from './Select.js';
|
|
|
5
5
|
export { default as Option } from './Option.js';
|
|
6
6
|
export { default as OptionGroup } from '../Menu/MenuItemGroup.js';
|
|
7
7
|
export { default as TreeSelect } from './TreeSelect.js';
|
|
8
|
-
export { default as AutoComplete } from './AutoComplete.js';
|
package/Slider/useSlider.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isRangeSlider, fixRangeSliderValue, fixSingleSliderValue, toSliderCssVars, getPercentage,
|
|
1
|
+
import { isRangeSlider, fixRangeSliderValue, fixSingleSliderValue, toSliderCssVars, getPercentage, findClosetValueIndex, sortSliderValue, getSliderRect, getValueFromClientX, roundToStep } from '@mezzanine-ui/core/slider';
|
|
2
2
|
import { useRef, useState } from 'react';
|
|
3
3
|
import { useDocumentEvents } from '../hooks/useDocumentEvents.js';
|
|
4
4
|
|
package/Table/Table.d.ts
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
|
-
import { TableSize, type HighlightMode, type TableColumn, type TableDataSource, type TableDraggable, type TableExpandable, type TableRowSelection, type TableScroll } from '@mezzanine-ui/core/table';
|
|
1
|
+
import { TableSize, type HighlightMode, type TableActions, type TableActionsWithMinWidth, type TableColumn, type TableColumnWithMinWidth, type TableDataSource, type TableDraggable, type TableExpandable, type TableRowSelection, type TableScroll } from '@mezzanine-ui/core/table';
|
|
2
2
|
import type { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
|
|
3
|
-
import {
|
|
3
|
+
import type { TableTransitionState } from './hooks/useTableDataSource';
|
|
4
4
|
import { TablePaginationProps } from './components/TablePagination';
|
|
5
5
|
import type { EmptyProps } from '../Empty';
|
|
6
6
|
export interface TableBaseProps<T extends TableDataSource = TableDataSource> extends Omit<NativeElementPropsWithoutKeyAndRef<'table'>, 'children' | 'draggable' | 'summary' | 'onChange'> {
|
|
7
|
-
/** Column configuration */
|
|
8
|
-
columns: TableColumn<T>[];
|
|
9
7
|
/** Data source */
|
|
10
8
|
dataSource: T[];
|
|
11
9
|
/** Props for Empty component when no data */
|
|
12
|
-
emptyProps?: EmptyProps
|
|
10
|
+
emptyProps?: EmptyProps & {
|
|
11
|
+
height?: number | string;
|
|
12
|
+
};
|
|
13
13
|
/** Expandable row configuration */
|
|
14
14
|
expandable?: TableExpandable<T>;
|
|
15
|
+
/**
|
|
16
|
+
* Whether the table should stretch to fill its container width.
|
|
17
|
+
* When true, the table will always be 100% width of its container.
|
|
18
|
+
* Note: If the sum of all column widths is less than the table width,
|
|
19
|
+
* columns will be proportionally stretched to fill the remaining space.
|
|
20
|
+
* @default false
|
|
21
|
+
*/
|
|
22
|
+
fullWidth?: boolean;
|
|
15
23
|
/** Highlight mode for hover effects
|
|
16
24
|
* @default 'row'
|
|
17
25
|
*/
|
|
@@ -20,23 +28,22 @@ export interface TableBaseProps<T extends TableDataSource = TableDataSource> ext
|
|
|
20
28
|
loading?: boolean;
|
|
21
29
|
/** Number of rows to display when loading */
|
|
22
30
|
loadingRowsCount?: number;
|
|
31
|
+
/** Minimum height of the table */
|
|
32
|
+
minHeight?: number | string;
|
|
23
33
|
/**
|
|
24
34
|
* Whether the table is nested inside an expanded row content area
|
|
25
35
|
*/
|
|
26
36
|
nested?: boolean;
|
|
27
37
|
/** Pagination configuration */
|
|
28
38
|
pagination?: TablePaginationProps;
|
|
29
|
-
/**
|
|
30
|
-
* Whether columns are resizable by user interaction
|
|
31
|
-
* @default false
|
|
32
|
-
*/
|
|
33
|
-
resizable?: boolean;
|
|
34
39
|
/**
|
|
35
40
|
* Row height preset token.
|
|
36
41
|
*/
|
|
37
42
|
rowHeightPreset?: 'base' | 'condensed' | 'detailed' | 'roomy';
|
|
38
43
|
/** Row selection configuration */
|
|
39
44
|
rowSelection?: TableRowSelection<T>;
|
|
45
|
+
/** Row indexes where a separator border should be displayed */
|
|
46
|
+
separatorAtRowIndexes?: number[];
|
|
40
47
|
/** Show header row */
|
|
41
48
|
showHeader?: boolean;
|
|
42
49
|
/** Custom size variant
|
|
@@ -49,12 +56,42 @@ export interface TableBaseProps<T extends TableDataSource = TableDataSource> ext
|
|
|
49
56
|
sticky?: boolean;
|
|
50
57
|
/** Transition state for row add/remove animations (from useTableDataSource hook) */
|
|
51
58
|
transitionState?: TableTransitionState;
|
|
59
|
+
/** Enable zebra striping for alternating row backgrounds */
|
|
60
|
+
zebraStriping?: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Props when resizable is enabled.
|
|
64
|
+
* Requires minWidth on all columns.
|
|
65
|
+
*/
|
|
66
|
+
export interface TableResizableProps<T extends TableDataSource = TableDataSource> extends TableBaseProps<T> {
|
|
67
|
+
/** Actions column configuration - minWidth required when resizable */
|
|
68
|
+
actions?: TableActionsWithMinWidth<T>;
|
|
69
|
+
/** Column configuration - minWidth required for each column when resizable */
|
|
70
|
+
columns: TableColumnWithMinWidth<T>[];
|
|
71
|
+
/**
|
|
72
|
+
* Whether columns are resizable by user interaction
|
|
73
|
+
*/
|
|
74
|
+
resizable: true;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Props when resizable is disabled or not specified.
|
|
78
|
+
*/
|
|
79
|
+
export interface TableNonResizableProps<T extends TableDataSource = TableDataSource> extends TableBaseProps<T> {
|
|
80
|
+
/** Actions column configuration */
|
|
81
|
+
actions?: TableActions<T>;
|
|
82
|
+
/** Column configuration */
|
|
83
|
+
columns: TableColumn<T>[];
|
|
84
|
+
/**
|
|
85
|
+
* Whether columns are resizable by user interaction
|
|
86
|
+
* @default false
|
|
87
|
+
*/
|
|
88
|
+
resizable?: false;
|
|
52
89
|
}
|
|
53
90
|
/**
|
|
54
91
|
* Props when virtualized scrolling is enabled.
|
|
55
92
|
* Draggable is not allowed in this mode.
|
|
56
93
|
*/
|
|
57
|
-
export
|
|
94
|
+
export type TableVirtualizedProps<T extends TableDataSource = TableDataSource> = (TableResizableProps<T> | TableNonResizableProps<T>) & {
|
|
58
95
|
/** Draggable row configuration - not available when virtualized is enabled */
|
|
59
96
|
draggable?: never;
|
|
60
97
|
/** Scroll configuration with virtualized enabled */
|
|
@@ -62,22 +99,23 @@ export interface TableVirtualizedProps<T extends TableDataSource = TableDataSour
|
|
|
62
99
|
virtualized: true;
|
|
63
100
|
y: number | string;
|
|
64
101
|
};
|
|
65
|
-
}
|
|
102
|
+
};
|
|
66
103
|
/**
|
|
67
104
|
* Props when virtualized scrolling is disabled or not specified.
|
|
68
105
|
* Draggable is allowed in this mode.
|
|
69
106
|
*/
|
|
70
|
-
export
|
|
107
|
+
export type TableNonVirtualizedProps<T extends TableDataSource = TableDataSource> = (TableResizableProps<T> | TableNonResizableProps<T>) & {
|
|
71
108
|
/** Draggable row configuration */
|
|
72
109
|
draggable?: TableDraggable<T>;
|
|
73
110
|
/** Scroll configuration for scrolling (virtualized defaults to false) */
|
|
74
111
|
scroll?: TableScroll & {
|
|
75
112
|
virtualized?: false;
|
|
76
113
|
};
|
|
77
|
-
}
|
|
114
|
+
};
|
|
78
115
|
/**
|
|
79
116
|
* TableProps - discriminated union to ensure draggable and virtualized
|
|
80
|
-
* scrolling are mutually exclusive at the type level
|
|
117
|
+
* scrolling are mutually exclusive at the type level, and resizable
|
|
118
|
+
* requires minWidth on all columns.
|
|
81
119
|
*/
|
|
82
120
|
export type TableProps<T extends TableDataSource = TableDataSource> = TableVirtualizedProps<T> | TableNonVirtualizedProps<T>;
|
|
83
121
|
/**
|
package/Table/Table.js
CHANGED
|
@@ -1,36 +1,37 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
-
import { forwardRef, useRef, useMemo, useState, useCallback } from 'react';
|
|
4
|
-
import
|
|
3
|
+
import { forwardRef, useRef, useMemo, useState, useCallback, useEffect } from 'react';
|
|
4
|
+
import throttle from 'lodash/throttle';
|
|
5
|
+
import { TABLE_ACTIONS_KEY, tableClasses } from '@mezzanine-ui/core/table';
|
|
5
6
|
import { DragDropContext, Droppable } from '@hello-pangea/dnd';
|
|
6
|
-
import { TableContext, TableDataContext
|
|
7
|
+
import { TableSuperContext, TableContext, TableDataContext } from './TableContext.js';
|
|
7
8
|
import { TableBody } from './components/TableBody.js';
|
|
8
9
|
import { TableColGroup } from './components/TableColGroup.js';
|
|
9
10
|
import { TableHeader } from './components/TableHeader.js';
|
|
10
11
|
import { TablePagination } from './components/TablePagination.js';
|
|
11
|
-
import {
|
|
12
|
+
import { useTableResizedColumns } from './hooks/useTableResizedColumns.js';
|
|
12
13
|
import { useTableExpansion } from './hooks/useTableExpansion.js';
|
|
13
14
|
import { useTableFixedOffsets } from './hooks/useTableFixedOffsets.js';
|
|
14
15
|
import { useTableScroll } from './hooks/useTableScroll.js';
|
|
15
16
|
import { useTableSelection } from './hooks/useTableSelection.js';
|
|
16
17
|
import { useTableSorting } from './hooks/useTableSorting.js';
|
|
17
|
-
import { composeRefs } from '../utils/composeRefs.js';
|
|
18
18
|
import { getNumericCSSVariablePixelValue } from '../utils/get-css-variable-value.js';
|
|
19
19
|
import { spacingPrefix } from '@mezzanine-ui/system/spacing';
|
|
20
|
+
import TableBulkActions from './components/TableBulkActions.js';
|
|
21
|
+
import { useComposeRefs } from '../hooks/useComposeRefs.js';
|
|
20
22
|
import cx from 'clsx';
|
|
21
23
|
|
|
22
24
|
function TableInner(props, ref) {
|
|
23
|
-
const { className, columns, dataSource, draggable, emptyProps, expandable, highlight = 'row', loading = false, loadingRowsCount = 10, nested = false, pagination, resizable = false, rowHeightPreset = 'base', rowSelection, scroll, showHeader = true, size = 'main', sticky = true, style, transitionState, ...restProps } = props;
|
|
25
|
+
const { actions, className, columns, dataSource, draggable, emptyProps, expandable, fullWidth = false, highlight = 'row', loading = false, loadingRowsCount = 10, minHeight, nested = false, pagination, resizable = false, rowHeightPreset = 'base', rowSelection, scroll, showHeader = true, size = 'main', sticky = true, style, transitionState, zebraStriping, separatorAtRowIndexes, ...restProps } = props;
|
|
24
26
|
const hostRef = useRef(null);
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
// mock loading dataSource
|
|
27
|
+
const composedHostRef = useComposeRefs([ref, hostRef]);
|
|
28
|
+
/** Feature: Loading */
|
|
28
29
|
const dataSourceForRender = loading
|
|
29
30
|
? Array.from({ length: Math.max(loadingRowsCount, 1) }).map((_, idx) => ({
|
|
30
|
-
key: idx
|
|
31
|
+
key: `${idx}`,
|
|
31
32
|
}))
|
|
32
33
|
: dataSource;
|
|
33
|
-
|
|
34
|
+
/** Feature: Row Height Preset */
|
|
34
35
|
const rowHeight = useMemo(() => {
|
|
35
36
|
switch (rowHeightPreset) {
|
|
36
37
|
case 'condensed':
|
|
@@ -52,25 +53,55 @@ function TableInner(props, ref) {
|
|
|
52
53
|
: getNumericCSSVariablePixelValue(`--${spacingPrefix}-size-container-minimal`);
|
|
53
54
|
}
|
|
54
55
|
}, [rowHeightPreset, size]);
|
|
55
|
-
|
|
56
|
+
/** Feature: Highlight */
|
|
56
57
|
const [hoveredRowIndex, setHoveredRowIndex] = useState(null);
|
|
57
58
|
const [hoveredColumnIndex, setHoveredColumnIndex] = useState(null);
|
|
58
59
|
const setHoveredCell = useCallback((rowIndex, columnIndex) => {
|
|
59
60
|
setHoveredRowIndex(rowIndex);
|
|
60
61
|
setHoveredColumnIndex(columnIndex);
|
|
61
62
|
}, []);
|
|
62
|
-
|
|
63
|
+
const highlightValue = useMemo(() => ({
|
|
64
|
+
columnIndex: hoveredColumnIndex,
|
|
65
|
+
mode: highlight,
|
|
66
|
+
rowIndex: hoveredRowIndex,
|
|
67
|
+
setHoveredCell,
|
|
68
|
+
}), [highlight, hoveredColumnIndex, hoveredRowIndex, setHoveredCell]);
|
|
69
|
+
/** Feature: sorting */
|
|
63
70
|
const sortingState = useTableSorting({
|
|
64
71
|
columns,
|
|
65
72
|
});
|
|
73
|
+
/** Feature: Actions column */
|
|
74
|
+
const columnsWithActions = useMemo(() => {
|
|
75
|
+
var _a;
|
|
76
|
+
if (!actions)
|
|
77
|
+
return columns;
|
|
78
|
+
const actionsColumn = {
|
|
79
|
+
...actions,
|
|
80
|
+
align: (_a = actions.align) !== null && _a !== void 0 ? _a : 'end',
|
|
81
|
+
ellipsis: false,
|
|
82
|
+
key: TABLE_ACTIONS_KEY,
|
|
83
|
+
render: () => null, // Placeholder, actual rendering is handled in TableRow
|
|
84
|
+
};
|
|
85
|
+
return [...columns, actionsColumn];
|
|
86
|
+
}, [actions, columns]);
|
|
87
|
+
/** Feature: Row selection */
|
|
66
88
|
const selectionState = useTableSelection({
|
|
67
89
|
dataSource,
|
|
68
90
|
rowSelection,
|
|
69
91
|
});
|
|
92
|
+
/** Feature: Expansion */
|
|
70
93
|
const expansionState = useTableExpansion({
|
|
71
94
|
expandable,
|
|
72
95
|
hasDragHandle: !!(draggable === null || draggable === void 0 ? void 0 : draggable.enabled),
|
|
73
96
|
});
|
|
97
|
+
/** Feature: Column resized */
|
|
98
|
+
const columnState = useTableResizedColumns();
|
|
99
|
+
/** Feature: Scroll and dimensions calculation */
|
|
100
|
+
const { containerWidth, handleScroll, isScrollingHorizontally, scrollLeft, containerRef: scrollContainerRef, setContainerRef, } = useTableScroll({
|
|
101
|
+
enabled: !nested,
|
|
102
|
+
});
|
|
103
|
+
const virtualScrollEnabled = useMemo(() => !!((scroll === null || scroll === void 0 ? void 0 : scroll.virtualized) && (scroll === null || scroll === void 0 ? void 0 : scroll.y)), [scroll === null || scroll === void 0 ? void 0 : scroll.virtualized, scroll === null || scroll === void 0 ? void 0 : scroll.y]);
|
|
104
|
+
/** Feature: Column fixed */
|
|
74
105
|
const actionConfig = useMemo(() => ({
|
|
75
106
|
hasDragHandle: !!(draggable === null || draggable === void 0 ? void 0 : draggable.enabled),
|
|
76
107
|
dragHandleFixed: !!(draggable === null || draggable === void 0 ? void 0 : draggable.fixed),
|
|
@@ -79,50 +110,48 @@ function TableInner(props, ref) {
|
|
|
79
110
|
hasSelection: !!rowSelection,
|
|
80
111
|
selectionFixed: !!(rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.fixed),
|
|
81
112
|
}), [draggable === null || draggable === void 0 ? void 0 : draggable.enabled, draggable === null || draggable === void 0 ? void 0 : draggable.fixed, expandable, rowSelection]);
|
|
82
|
-
const columnState = useTableColumns({
|
|
83
|
-
actionConfig,
|
|
84
|
-
columns,
|
|
85
|
-
});
|
|
86
|
-
const scrollState = useTableScroll({
|
|
87
|
-
enabled: !nested,
|
|
88
|
-
});
|
|
89
|
-
// Fixed column offset calculations
|
|
90
113
|
const fixedOffsetsState = useTableFixedOffsets({
|
|
91
114
|
actionConfig,
|
|
92
|
-
columns:
|
|
115
|
+
columns: columnsWithActions,
|
|
93
116
|
getResizedColumnWidth: columnState.getResizedColumnWidth,
|
|
94
117
|
});
|
|
95
|
-
|
|
96
|
-
const
|
|
118
|
+
/** Feature: Drag n Drop */
|
|
119
|
+
const handleDragEnd = useCallback((result) => {
|
|
120
|
+
var _a;
|
|
121
|
+
if (!result.destination || !draggable)
|
|
122
|
+
return;
|
|
123
|
+
const sourceIndex = result.source.index;
|
|
124
|
+
const destIndex = result.destination.index;
|
|
125
|
+
if (sourceIndex === destIndex)
|
|
126
|
+
return;
|
|
127
|
+
const newData = [...dataSource];
|
|
128
|
+
const [removed] = newData.splice(sourceIndex, 1);
|
|
129
|
+
newData.splice(destIndex, 0, removed);
|
|
130
|
+
(_a = draggable.onDragEnd) === null || _a === void 0 ? void 0 : _a.call(draggable, newData, {
|
|
131
|
+
draggingId: result.draggableId,
|
|
132
|
+
fromIndex: sourceIndex,
|
|
133
|
+
toIndex: destIndex,
|
|
134
|
+
});
|
|
135
|
+
}, [dataSource, draggable]);
|
|
136
|
+
const draggableState = useMemo(() => draggable
|
|
97
137
|
? {
|
|
98
|
-
|
|
99
|
-
enabled: true,
|
|
138
|
+
enabled: draggable.enabled,
|
|
100
139
|
fixed: draggable.fixed,
|
|
101
140
|
}
|
|
102
141
|
: undefined, [draggable]);
|
|
103
|
-
|
|
104
|
-
const highlightValue = useMemo(() => ({
|
|
105
|
-
columnIndex: hoveredColumnIndex,
|
|
106
|
-
mode: highlight,
|
|
107
|
-
rowIndex: hoveredRowIndex,
|
|
108
|
-
setHoveredCell,
|
|
109
|
-
}), [highlight, hoveredColumnIndex, hoveredRowIndex, setHoveredCell]);
|
|
110
|
-
// Determine if virtual scrolling should be enabled
|
|
111
|
-
// Requires scroll.virtualized to be true AND scroll.y to be set
|
|
112
|
-
const virtualScrollEnabled = !!((scroll === null || scroll === void 0 ? void 0 : scroll.virtualized) && (scroll === null || scroll === void 0 ? void 0 : scroll.y));
|
|
113
|
-
// Context value - cast to any to avoid complex generic issues
|
|
142
|
+
/** Context values */
|
|
114
143
|
const contextValue = useMemo(() => ({
|
|
144
|
+
actions: actions,
|
|
115
145
|
columnState,
|
|
116
|
-
columns: columns,
|
|
117
146
|
dataSource: dataSourceForRender,
|
|
118
|
-
draggable:
|
|
147
|
+
draggable: draggableState,
|
|
119
148
|
emptyProps,
|
|
120
149
|
expansion: expansionState,
|
|
121
150
|
fixedOffsets: fixedOffsetsState,
|
|
122
151
|
resizable,
|
|
123
152
|
rowHeight,
|
|
124
153
|
highlight: highlightValue,
|
|
125
|
-
isScrollingHorizontally:
|
|
154
|
+
isScrollingHorizontally: isScrollingHorizontally,
|
|
126
155
|
isInsideExpandedContentArea: nested,
|
|
127
156
|
loading,
|
|
128
157
|
pagination: pagination || undefined,
|
|
@@ -130,14 +159,16 @@ function TableInner(props, ref) {
|
|
|
130
159
|
scrollContainerRef,
|
|
131
160
|
selection: selectionState,
|
|
132
161
|
size,
|
|
162
|
+
separatorAtRowIndexes,
|
|
133
163
|
sorting: sortingState,
|
|
134
164
|
transitionState,
|
|
135
165
|
virtualScrollEnabled,
|
|
166
|
+
zebraStriping,
|
|
136
167
|
}), [
|
|
168
|
+
actions,
|
|
137
169
|
columnState,
|
|
138
|
-
columns,
|
|
139
170
|
dataSourceForRender,
|
|
140
|
-
|
|
171
|
+
draggableState,
|
|
141
172
|
emptyProps,
|
|
142
173
|
expansionState,
|
|
143
174
|
fixedOffsetsState,
|
|
@@ -148,84 +179,149 @@ function TableInner(props, ref) {
|
|
|
148
179
|
pagination,
|
|
149
180
|
scroll,
|
|
150
181
|
scrollContainerRef,
|
|
151
|
-
|
|
182
|
+
isScrollingHorizontally,
|
|
152
183
|
selectionState,
|
|
153
184
|
size,
|
|
154
185
|
sortingState,
|
|
155
186
|
transitionState,
|
|
156
187
|
virtualScrollEnabled,
|
|
188
|
+
zebraStriping,
|
|
189
|
+
separatorAtRowIndexes,
|
|
157
190
|
nested,
|
|
158
191
|
]);
|
|
159
192
|
const dataContextValue = useMemo(() => ({
|
|
160
|
-
columns:
|
|
193
|
+
columns: columnsWithActions,
|
|
161
194
|
dataSource,
|
|
162
|
-
}), [
|
|
195
|
+
}), [columnsWithActions, dataSource]);
|
|
163
196
|
const superContextValue = useMemo(() => {
|
|
164
197
|
var _a;
|
|
165
198
|
return ({
|
|
166
|
-
containerWidth:
|
|
199
|
+
containerWidth: containerWidth,
|
|
167
200
|
getResizedColumnWidth: columnState.getResizedColumnWidth,
|
|
168
|
-
scrollLeft:
|
|
201
|
+
scrollLeft: scrollLeft,
|
|
169
202
|
expansionLeftPadding: (_a = expansionState === null || expansionState === void 0 ? void 0 : expansionState.expansionLeftPadding) !== null && _a !== void 0 ? _a : 0,
|
|
203
|
+
hasDragHandleFixed: !!(draggable === null || draggable === void 0 ? void 0 : draggable.enabled) && draggable.fixed,
|
|
170
204
|
});
|
|
171
205
|
}, [
|
|
172
|
-
|
|
206
|
+
scrollLeft,
|
|
173
207
|
expansionState === null || expansionState === void 0 ? void 0 : expansionState.expansionLeftPadding,
|
|
174
|
-
|
|
208
|
+
containerWidth,
|
|
175
209
|
columnState.getResizedColumnWidth,
|
|
210
|
+
draggable === null || draggable === void 0 ? void 0 : draggable.enabled,
|
|
211
|
+
draggable === null || draggable === void 0 ? void 0 : draggable.fixed,
|
|
176
212
|
]);
|
|
177
|
-
|
|
178
|
-
const handleDragEnd = useCallback((result) => {
|
|
179
|
-
var _a;
|
|
180
|
-
if (!result.destination || !draggable)
|
|
181
|
-
return;
|
|
182
|
-
const sourceIndex = result.source.index;
|
|
183
|
-
const destIndex = result.destination.index;
|
|
184
|
-
if (sourceIndex === destIndex)
|
|
185
|
-
return;
|
|
186
|
-
const newData = [...dataSource];
|
|
187
|
-
const [removed] = newData.splice(sourceIndex, 1);
|
|
188
|
-
newData.splice(destIndex, 0, removed);
|
|
189
|
-
(_a = draggable.onDragEnd) === null || _a === void 0 ? void 0 : _a.call(draggable, newData);
|
|
190
|
-
}, [dataSource, draggable]);
|
|
191
|
-
const sizeClass = size === 'sub' ? tableClasses.sub : tableClasses.main;
|
|
192
|
-
// Scroll container style
|
|
213
|
+
/** Computed styles */
|
|
193
214
|
const scrollContainerStyle = useMemo(() => {
|
|
194
215
|
const containerStyle = {};
|
|
195
216
|
if (scroll === null || scroll === void 0 ? void 0 : scroll.y) {
|
|
196
217
|
containerStyle.maxHeight = scroll.y;
|
|
197
|
-
containerStyle.overflowY = 'auto';
|
|
198
|
-
}
|
|
199
|
-
if (scroll === null || scroll === void 0 ? void 0 : scroll.x) {
|
|
200
|
-
containerStyle.overflowX = 'auto';
|
|
201
218
|
}
|
|
202
219
|
if (nested) {
|
|
203
220
|
containerStyle.position = 'unset';
|
|
204
221
|
containerStyle.overflow = 'unset';
|
|
205
222
|
}
|
|
223
|
+
if (minHeight) {
|
|
224
|
+
containerStyle.minHeight = minHeight;
|
|
225
|
+
}
|
|
206
226
|
return containerStyle;
|
|
207
|
-
}, [scroll === null || scroll === void 0 ? void 0 : scroll.
|
|
208
|
-
// Table style with min-width for horizontal scroll
|
|
227
|
+
}, [scroll === null || scroll === void 0 ? void 0 : scroll.y, nested, minHeight]);
|
|
209
228
|
const tableStyle = useMemo(() => {
|
|
210
229
|
const baseStyle = {};
|
|
211
|
-
if (
|
|
212
|
-
baseStyle.minWidth = scroll.x;
|
|
230
|
+
if (fullWidth) {
|
|
213
231
|
baseStyle.width = '100%';
|
|
214
232
|
}
|
|
215
233
|
return baseStyle;
|
|
216
|
-
}, [
|
|
217
|
-
|
|
218
|
-
const
|
|
219
|
-
|
|
234
|
+
}, [fullWidth]);
|
|
235
|
+
/** Scroll Container Ref */
|
|
236
|
+
const droppableInnerRefSetter = useRef(null);
|
|
237
|
+
const composedScrollContainerRef = useCallback((element) => {
|
|
220
238
|
setContainerRef(element);
|
|
239
|
+
if (droppableInnerRefSetter.current) {
|
|
240
|
+
droppableInnerRefSetter.current(element);
|
|
241
|
+
}
|
|
221
242
|
}, [setContainerRef]);
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
243
|
+
/** Feature: bulk actions */
|
|
244
|
+
const bulkActionsConfig = useMemo(() => {
|
|
245
|
+
if (!selectionState || selectionState.mode !== 'checkbox') {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
const checkboxConfig = selectionState.config;
|
|
249
|
+
return {
|
|
250
|
+
enabled: !!checkboxConfig.bulkActions && selectionState.selectedRowKeys.length,
|
|
251
|
+
bulkActions: checkboxConfig.bulkActions,
|
|
252
|
+
onClearSelection: () => checkboxConfig.onChange([], null, []),
|
|
253
|
+
selectedRowKeys: selectionState.selectedRowKeys,
|
|
254
|
+
};
|
|
255
|
+
}, [selectionState]);
|
|
256
|
+
const [isBulkActionsFixed, setIsBulkActionsFixed] = useState(false);
|
|
257
|
+
useEffect(() => {
|
|
258
|
+
if (!(bulkActionsConfig === null || bulkActionsConfig === void 0 ? void 0 : bulkActionsConfig.enabled)) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const calculateFixedState = () => {
|
|
262
|
+
const { current: hostEl } = hostRef;
|
|
263
|
+
if (!hostEl)
|
|
264
|
+
return;
|
|
265
|
+
const hostRect = hostEl.getBoundingClientRect();
|
|
266
|
+
const paginationHeightWithPx = hostEl.style.getPropertyValue('--mzn-table-pagination-height');
|
|
267
|
+
const paginationHeight = paginationHeightWithPx
|
|
268
|
+
? Number(paginationHeightWithPx.replace('px', ''))
|
|
269
|
+
: 0;
|
|
270
|
+
const viewportHeight = window.innerHeight;
|
|
271
|
+
const bottomSpacing = getNumericCSSVariablePixelValue(`--${spacingPrefix}-padding-vertical-relaxed`);
|
|
272
|
+
const bulkActionsFixedBottom = viewportHeight - bottomSpacing;
|
|
273
|
+
const shouldBeFixed = hostRect.bottom > viewportHeight + paginationHeight &&
|
|
274
|
+
hostRect.top < bulkActionsFixedBottom;
|
|
275
|
+
setIsBulkActionsFixed(shouldBeFixed);
|
|
276
|
+
if (shouldBeFixed) {
|
|
277
|
+
/** Table 不一定在 viewport 中間 */
|
|
278
|
+
const centerLeft = hostRect.left + hostRect.width / 2;
|
|
279
|
+
hostEl.style.setProperty('--mzn-bulk-actions-fixed-left', `${centerLeft}px`);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
/** @NOTE 如果覺得位置更新的不夠即時,再把 throttle 拔掉 (目前先以減少觸發次數做效能優化) */
|
|
283
|
+
const throttledCalculateFixedState = throttle(calculateFixedState, 50);
|
|
284
|
+
calculateFixedState();
|
|
285
|
+
window.addEventListener('scroll', throttledCalculateFixedState, false);
|
|
286
|
+
window.addEventListener('resize', throttledCalculateFixedState, false);
|
|
287
|
+
return () => {
|
|
288
|
+
throttledCalculateFixedState.cancel();
|
|
289
|
+
window.removeEventListener('scroll', throttledCalculateFixedState, false);
|
|
290
|
+
window.removeEventListener('resize', throttledCalculateFixedState, false);
|
|
291
|
+
};
|
|
292
|
+
}, [bulkActionsConfig === null || bulkActionsConfig === void 0 ? void 0 : bulkActionsConfig.enabled]);
|
|
293
|
+
/** Get Dynamic Pagination Height */
|
|
294
|
+
const paginationRef = useRef(null);
|
|
295
|
+
useEffect(() => {
|
|
296
|
+
const { current: paginationEl } = paginationRef;
|
|
297
|
+
if (paginationEl) {
|
|
298
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
299
|
+
var _a;
|
|
300
|
+
(_a = hostRef.current) === null || _a === void 0 ? void 0 : _a.style.setProperty('--mzn-table-pagination-height', `${paginationEl.offsetHeight}px`);
|
|
301
|
+
});
|
|
302
|
+
resizeObserver.observe(paginationEl);
|
|
303
|
+
return () => {
|
|
304
|
+
resizeObserver.disconnect();
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
return;
|
|
308
|
+
}, []);
|
|
309
|
+
/** Main render */
|
|
310
|
+
const renderMainTable = (droppableProvided) => {
|
|
311
|
+
if (droppableProvided) {
|
|
312
|
+
droppableInnerRefSetter.current = droppableProvided.innerRef;
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
droppableInnerRefSetter.current = null;
|
|
316
|
+
}
|
|
317
|
+
return (jsx(TableContext.Provider, { value: contextValue, children: jsx(TableDataContext.Provider, { value: dataContextValue, children: jsxs("div", { className: cx(tableClasses.host, className), ref: composedHostRef, style: style, ...restProps, children: [jsx("div", { ...droppableProvided === null || droppableProvided === void 0 ? void 0 : droppableProvided.droppableProps, className: cx(tableClasses.scrollContainer, {
|
|
318
|
+
[tableClasses.sticky]: !!sticky,
|
|
319
|
+
}), onScroll: handleScroll, ref: droppableProvided ? composedScrollContainerRef : setContainerRef, style: scrollContainerStyle, children: jsxs("table", { className: cx(tableClasses.root, size === 'sub' ? tableClasses.sub : tableClasses.main), style: tableStyle, children: [jsx(TableColGroup, {}), showHeader && jsx(TableHeader, {}), jsx(TableBody, {}), (droppableProvided === null || droppableProvided === void 0 ? void 0 : droppableProvided.placeholder) ? (jsx("tbody", { children: droppableProvided.placeholder })) : null] }) }), pagination && (jsx(TablePagination, { ...pagination, ref: paginationRef })), (bulkActionsConfig === null || bulkActionsConfig === void 0 ? void 0 : bulkActionsConfig.enabled) ? (jsx(TableBulkActions, { bulkActions: bulkActionsConfig.bulkActions, isFixed: isBulkActionsFixed, onClearSelection: bulkActionsConfig.onClearSelection, selectedRowKeys: bulkActionsConfig.selectedRowKeys })) : null] }) }) }));
|
|
320
|
+
};
|
|
225
321
|
if (nested) {
|
|
226
|
-
return
|
|
322
|
+
return renderMainTable();
|
|
227
323
|
}
|
|
228
|
-
return (jsx(DragDropContext, { onDragEnd: handleDragEnd, children: jsx(Droppable, { droppableId: "mzn-table-
|
|
324
|
+
return (jsx(DragDropContext, { onDragEnd: handleDragEnd, children: jsx(Droppable, { droppableId: "mzn-table-dnd", children: (provided) => (jsx(TableSuperContext.Provider, { value: superContextValue, children: renderMainTable(provided) })) }) }));
|
|
229
325
|
}
|
|
230
326
|
/**
|
|
231
327
|
* Table is a high-performance data table component with support for
|