@mezzanine-ui/react 0.12.8 → 0.13.0

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/Table/Table.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { TableColumn, TableComponents, TableDataSource, TableRowSelection, TableExpandable, TableFetchMore, TablePagination as TablePaginationType, TableRefresh as TableRefreshType, ExpandRowBySources } from '@mezzanine-ui/core/table';
2
+ import { TableColumn, TableComponents, TableDataSource, TableRowSelection, TableExpandable, TableFetchMore, TablePagination as TablePaginationType, TableRefresh as TableRefreshType, ExpandRowBySources, TableScrolling } from '@mezzanine-ui/core/table';
3
3
  import { EmptyProps } from '../Empty';
4
4
  import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
5
5
  export interface TableBaseProps<T> extends Omit<NativeElementPropsWithoutKeyAndRef<'div'>, 'role'> {
@@ -47,6 +47,11 @@ export interface TableBaseProps<T> extends Omit<NativeElementPropsWithoutKeyAndR
47
47
  * Whether table is loading or not
48
48
  */
49
49
  loading?: boolean;
50
+ /**
51
+ * When loading is true, show specific loadingTip
52
+ * @default '資料載入中...'
53
+ */
54
+ loadingTip?: string;
50
55
  /**
51
56
  * `refresh.show` is true, refresh button will display at the top-start of table. <br />
52
57
  * `refresh.onClick` is the callback of the refresh button.
@@ -59,6 +64,17 @@ export interface TableBaseProps<T> extends Omit<NativeElementPropsWithoutKeyAndR
59
64
  * `rowSelection.actions` are the actions that you want to do for selected data.
60
65
  */
61
66
  rowSelection?: TableRowSelection;
67
+ /**
68
+ * Enable table scroll feature <br />
69
+ * `scroll.x` set horizontal scrolling, can also be used to specify the width of the scroll area <br />
70
+ * `scroll.y` Set vertical scrolling, can also be used to specify the height of the scroll area <br />
71
+ * `scroll.fixedFirstColumn` set first column fixed when horizontal scrolling.
72
+ */
73
+ scroll?: TableScrolling;
74
+ /**
75
+ * customize scroll container className
76
+ */
77
+ scrollContainerClassName?: string;
62
78
  }
63
79
  export interface TableWithFetchMore<T> extends TableBaseProps<T> {
64
80
  /**
@@ -84,5 +100,5 @@ export interface TableWithPagination<T> extends TableBaseProps<T> {
84
100
  fetchMore?: undefined;
85
101
  }
86
102
  export type TableProps<T> = TableWithFetchMore<T> | TableWithPagination<T>;
87
- declare const Table: import("react").ForwardRefExoticComponent<TableProps<Record<string, unknown>> & import("react").RefAttributes<HTMLDivElement>>;
103
+ declare const Table: import("react").ForwardRefExoticComponent<TableProps<Record<string, unknown>> & import("react").RefAttributes<HTMLTableElement>>;
88
104
  export default Table;
package/Table/Table.js CHANGED
@@ -10,12 +10,14 @@ import { useTableRowSelection } from './rowSelection/useTableRowSelection.js';
10
10
  import { useTableSorting } from './sorting/useTableSorting.js';
11
11
  import { useTableLoading } from './useTableLoading.js';
12
12
  import { useTableFetchMore } from './useTableFetchMore.js';
13
+ import useTableScroll from './useTableScroll.js';
14
+ import { useComposeRefs } from '../hooks/useComposeRefs.js';
13
15
  import Loading from '../Loading/Loading.js';
14
16
  import cx from 'clsx';
15
17
 
16
18
  const Table = forwardRef(function Table(props, ref) {
17
19
  var _a;
18
- const { bodyClassName, bodyRowClassName, className, columns, components, dataSource: dataSourceProp, emptyProps, expandable: expandableProp, fetchMore: fetchMoreProp, headerClassName, loading: loadingProp, pagination: paginationProp, refresh: refreshProp, rowSelection: rowSelectionProp, ...rest } = props;
20
+ const { bodyClassName, bodyRowClassName, className, columns, components, dataSource: dataSourceProp, emptyProps, expandable: expandableProp, fetchMore: fetchMoreProp, headerClassName, loading: loadingProp, loadingTip = '資料載入中...', pagination: paginationProp, refresh: refreshProp, rowSelection: rowSelectionProp, scroll: scrollProp, scrollContainerClassName, ...rest } = props;
19
21
  const bodyRef = useRef(null);
20
22
  /** Feature rowSelection */
21
23
  const [selectedRowKeys, setSelectedRowKey] = useTableRowSelection({
@@ -56,13 +58,19 @@ const Table = forwardRef(function Table(props, ref) {
56
58
  /** @default false */
57
59
  (_a = refreshProp === null || refreshProp === void 0 ? void 0 : refreshProp.show) !== null && _a !== void 0 ? _a : false);
58
60
  }, [refreshProp === null || refreshProp === void 0 ? void 0 : refreshProp.show]);
61
+ /** Feature Scrolling */
62
+ const [scrollBody, scrollElement, isHorizontalScrolling] = useTableScroll({
63
+ onFetchMore,
64
+ loading,
65
+ scrollBarSize: 4,
66
+ });
59
67
  /** context */
60
68
  const tableContextValue = useMemo(() => {
61
69
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
62
70
  return ({
63
- scrollBarSize: 4,
64
71
  emptyProps,
65
72
  rowSelection,
73
+ isHorizontalScrolling,
66
74
  sorting: {
67
75
  onSort,
68
76
  onResetAll,
@@ -89,6 +97,7 @@ const Table = forwardRef(function Table(props, ref) {
89
97
  siblingCount: (_j = (_h = paginationProp.options) === null || _h === void 0 ? void 0 : _h.siblingCount) !== null && _j !== void 0 ? _j : 1,
90
98
  },
91
99
  } : undefined,
100
+ scroll: scrollProp,
92
101
  });
93
102
  }, [
94
103
  dataSource,
@@ -105,6 +114,8 @@ const Table = forwardRef(function Table(props, ref) {
105
114
  isFetching,
106
115
  isReachEnd,
107
116
  paginationProp,
117
+ isHorizontalScrolling,
118
+ scrollProp,
108
119
  ]);
109
120
  const tableDataContextValue = useMemo(() => ({
110
121
  columns,
@@ -116,7 +127,27 @@ const Table = forwardRef(function Table(props, ref) {
116
127
  bodyCell: (_a = components === null || components === void 0 ? void 0 : components.body) === null || _a === void 0 ? void 0 : _a.cell,
117
128
  });
118
129
  }, [(_a = components === null || components === void 0 ? void 0 : components.body) === null || _a === void 0 ? void 0 : _a.cell]);
119
- return (jsx(Loading, { loading: loading, stretch: true, tip: "\u8CC7\u6599\u8F09\u5165\u4E2D...", children: jsx("div", { ref: ref, ...rest, className: cx(tableClasses.host, className), role: "grid", children: jsx(TableContext.Provider, { value: tableContextValue, children: jsx(TableDataContext.Provider, { value: tableDataContextValue, children: jsxs(TableComponentContext.Provider, { value: tableComponentContextValue, children: [isRefreshShow ? (jsx(TableRefresh, { onClick: refreshProp.onClick })) : null, jsx(TableHeader, { className: headerClassName }), jsx(TableBody, { ref: bodyRef, className: bodyClassName, rowClassName: bodyRowClassName }), paginationProp ? (jsx(TablePagination, { bodyRef: bodyRef })) : null] }) }) }) }) }));
130
+ const tableRefs = useComposeRefs([ref, scrollBody.target]);
131
+ return (jsx(TableContext.Provider, { value: tableContextValue, children: jsx(TableDataContext.Provider, { value: tableDataContextValue, children: jsx(TableComponentContext.Provider, { value: tableComponentContextValue, children: jsxs(Loading, { loading: loading, stretch: true, tip: loadingTip, overlayProps: {
132
+ className: tableClasses.loading,
133
+ }, children: [jsx("div", { ref: scrollBody.ref, className: cx(tableClasses.scrollContainer, scrollContainerClassName), onScroll: scrollBody.onScroll, style: tableContextValue.scroll ? {
134
+ '--table-scroll-x': tableContextValue.scroll.x
135
+ ? `${tableContextValue.scroll.x}px`
136
+ : '100%',
137
+ '--table-scroll-y': tableContextValue.scroll.y
138
+ ? `${tableContextValue.scroll.y}px`
139
+ : 'unset',
140
+ } : undefined, children: jsxs("table", { ref: tableRefs, ...rest, className: cx(tableClasses.host, className), children: [isRefreshShow ? (jsx("tbody", { children: jsx("tr", { children: jsx("td", { children: jsx(TableRefresh, { onClick: refreshProp.onClick }) }) }) })) : null, jsx(TableHeader, { className: headerClassName }), jsx(TableBody, { ref: bodyRef, className: bodyClassName, rowClassName: bodyRowClassName })] }) }), paginationProp ? (jsx(TablePagination, { bodyRef: bodyRef })) : null, jsx("div", { ref: scrollElement.trackRef, style: scrollElement.trackStyle, onMouseDown: scrollElement.onMouseDown, onMouseUp: scrollElement.onMouseUp, role: "button", tabIndex: -1, className: "mzn-table-scroll-bar-track", children: jsx("div", { style: {
141
+ width: '100%',
142
+ height: '100%',
143
+ position: 'relative',
144
+ }, children: jsx("div", { ref: scrollElement.ref, onMouseDown: scrollElement.onMouseDown, onMouseUp: scrollElement.onMouseUp, onMouseEnter: scrollElement.onMouseEnter, onMouseLeave: scrollElement.onMouseLeave, role: "button", style: scrollElement.style, tabIndex: -1, className: "mzn-table-scroll-bar", children: jsx("div", { style: {
145
+ width: `${scrollElement.scrollBarSize}px`,
146
+ height: '100%',
147
+ borderRadius: '10px',
148
+ backgroundColor: '#7d7d7d',
149
+ transition: '0.1s',
150
+ } }) }) }) })] }) }) }) }));
120
151
  });
121
152
  var Table$1 = Table;
122
153
 
@@ -6,5 +6,5 @@ export interface TableBodyProps extends NativeElementPropsWithoutKeyAndRef<'div'
6
6
  */
7
7
  rowClassName?: string;
8
8
  }
9
- declare const TableBody: import("react").ForwardRefExoticComponent<TableBodyProps & import("react").RefAttributes<HTMLDivElement>>;
9
+ declare const TableBody: import("react").ForwardRefExoticComponent<TableBodyProps & import("react").RefAttributes<HTMLTableSectionElement>>;
10
10
  export default TableBody;
@@ -1,8 +1,6 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { forwardRef, useContext } from 'react';
3
3
  import { tableClasses } from '@mezzanine-ui/core/table';
4
- import { useComposeRefs } from '../hooks/useComposeRefs.js';
5
- import useTableScroll from './useTableScroll.js';
6
4
  import { TableDataContext, TableContext } from './TableContext.js';
7
5
  import TableBodyRow from './TableBodyRow.js';
8
6
  import Loading from '../Loading/Loading.js';
@@ -12,9 +10,7 @@ import cx from 'clsx';
12
10
  const TableBody = forwardRef(function TableBody(props, ref) {
13
11
  const { className, rowClassName, ...rest } = props;
14
12
  const { dataSource = [], } = useContext(TableDataContext) || {};
15
- const { emptyProps, fetchMore, scrollBarSize, pagination, } = useContext(TableContext) || {};
16
- const [tableBody, scrollElement] = useTableScroll();
17
- const composedRefs = useComposeRefs([ref, tableBody.ref]);
13
+ const { emptyProps, fetchMore, pagination, } = useContext(TableContext) || {};
18
14
  /** customizing empty */
19
15
  const { className: emptyComponentClassName = '', children: emptyComponentChildren = '查無資料', fullHeight: emptyComponentFullHeight = true, ...restEmptyProps } = emptyProps || {};
20
16
  /** pagination feature */
@@ -22,13 +18,7 @@ const TableBody = forwardRef(function TableBody(props, ref) {
22
18
  const currentStartCount = (paginationOptions === null || paginationOptions === void 0 ? void 0 : paginationOptions.pageSize) && currentPage ? ((paginationOptions.pageSize) * (currentPage - 1)) : 0;
23
19
  const currentEndCount = (paginationOptions === null || paginationOptions === void 0 ? void 0 : paginationOptions.pageSize) && currentPage && total ? (Math.min(((paginationOptions.pageSize) * currentPage), total)) : 0;
24
20
  const currentDataSource = pagination && !disableAutoSlicing ? (dataSource.slice(currentStartCount, currentEndCount)) : dataSource;
25
- return (jsxs("div", { ...rest, ref: composedRefs, className: cx(tableClasses.body, className), onScroll: tableBody.onScroll, role: "rowgroup", children: [currentDataSource.length ? currentDataSource.map((rowData, index) => (jsx(TableBodyRow, { className: rowClassName, rowData: rowData, rowIndex: index }, (rowData.key || rowData.id)))) : (jsx(Empty, { ...restEmptyProps, className: cx(tableClasses.bodyEmpty, emptyComponentClassName), fullHeight: emptyComponentFullHeight, children: emptyComponentChildren })), (fetchMore === null || fetchMore === void 0 ? void 0 : fetchMore.isFetching) ? (jsx("div", { className: tableClasses.bodyFetchMore, children: jsx(Loading, { loading: true }) })) : null, jsx("div", { ref: scrollElement.ref, onMouseDown: scrollElement.onMouseDown, onMouseUp: scrollElement.onMouseUp, onMouseEnter: scrollElement.onMouseEnter, onMouseLeave: scrollElement.onMouseLeave, role: "button", style: scrollElement.style, tabIndex: -1, children: jsx("div", { style: {
26
- width: `${scrollBarSize}px`,
27
- height: '100%',
28
- borderRadius: '10px',
29
- backgroundColor: '#7d7d7d',
30
- transition: '0.1s',
31
- } }) })] }));
21
+ return (jsxs("tbody", { ...rest, ref: ref, className: cx(tableClasses.body, className), children: [currentDataSource.length ? currentDataSource.map((rowData, index) => (jsx(TableBodyRow, { className: rowClassName, rowData: rowData, rowIndex: index }, (rowData.key || rowData.id)))) : (jsx("tr", { children: jsx("td", { children: jsx(Empty, { ...restEmptyProps, className: cx(tableClasses.bodyEmpty, emptyComponentClassName), fullHeight: emptyComponentFullHeight, children: emptyComponentChildren }) }) })), (fetchMore === null || fetchMore === void 0 ? void 0 : fetchMore.isFetching) ? (jsx("tr", { className: tableClasses.bodyFetchMore, children: jsx("td", { children: jsx(Loading, { loading: true }) }) })) : null] }));
32
22
  });
33
23
  var TableBody$1 = TableBody;
34
24
 
@@ -8,5 +8,5 @@ export interface TableBodyRowProps extends NativeElementPropsWithoutKeyAndRef<'d
8
8
  rowData: TableDataSource;
9
9
  rowIndex: number;
10
10
  }
11
- declare const TableBodyRow: import("react").ForwardRefExoticComponent<TableBodyRowProps & import("react").RefAttributes<HTMLDivElement>>;
11
+ declare const TableBodyRow: import("react").ForwardRefExoticComponent<TableBodyRowProps & import("react").RefAttributes<HTMLTableRowElement>>;
12
12
  export default TableBodyRow;
@@ -13,7 +13,7 @@ import cx from 'clsx';
13
13
 
14
14
  const TableBodyRow = forwardRef(function TableBodyRow(props, ref) {
15
15
  const { className, rowData, rowIndex, ...rest } = props;
16
- const { rowSelection, expanding, } = useContext(TableContext) || {};
16
+ const { rowSelection, expanding, isHorizontalScrolling, scroll, } = useContext(TableContext) || {};
17
17
  const { columns, } = useContext(TableDataContext) || {};
18
18
  /** Feature rowSelection */
19
19
  const [selected, setSelected] = useState(false);
@@ -27,14 +27,32 @@ const TableBodyRow = forwardRef(function TableBodyRow(props, ref) {
27
27
  var _a, _b;
28
28
  return ((_b = (_a = expanding === null || expanding === void 0 ? void 0 : expanding.expandedRowRender) === null || _a === void 0 ? void 0 : _a.call(expanding, rowData)) !== null && _b !== void 0 ? _b : null);
29
29
  }, [expanding, rowData]);
30
- return (jsxs(Fragment, { children: [jsxs("div", { ...rest, ref: ref, className: cx(tableClasses.bodyRow, {
30
+ /** Feature scrolling */
31
+ const isFirstColumnShouldSticky = useMemo(() => {
32
+ var _a;
33
+ /** 前面有 action 時不可 sticky */
34
+ if (rowSelection || expanding)
35
+ return false;
36
+ return ((_a = scroll === null || scroll === void 0 ? void 0 : scroll.fixedFirstColumn) !== null && _a !== void 0 ? _a : false);
37
+ }, [
38
+ rowSelection,
39
+ expanding,
40
+ scroll === null || scroll === void 0 ? void 0 : scroll.fixedFirstColumn,
41
+ ]);
42
+ return (jsxs(Fragment, { children: [jsxs("tr", { ...rest, ref: ref, className: cx(tableClasses.bodyRow, {
31
43
  [tableClasses.bodyRowHighlight]: selected || expanded,
32
- }, className), role: "row", children: [rowSelection ? (jsx(TableRowSelection, { role: "gridcell", rowKey: (rowData.key || rowData.id), setChecked: (status) => setSelected(status), showDropdownIcon: false })) : null, expanding ? (jsx(TableExpandable, { expandable: isExpandable, expanded: expanded, role: "gridcell", setExpanded: setExpanded, onExpand: (status) => { var _a; return (_a = expanding.onExpand) === null || _a === void 0 ? void 0 : _a.call(expanding, rowData, status); } })) : null, (columns !== null && columns !== void 0 ? columns : []).map((column) => {
44
+ }, className), children: [rowSelection ? (jsx("td", { className: tableClasses.bodyRowCellWrapper, style: {
45
+ flex: 'unset',
46
+ minWidth: 'unset',
47
+ }, children: jsx(TableRowSelection, { rowKey: (rowData.key || rowData.id), setChecked: (status) => setSelected(status), showDropdownIcon: false }) })) : null, expanding ? (jsx("td", { className: tableClasses.bodyRowCellWrapper, style: {
48
+ flex: 'unset',
49
+ minWidth: 'unset',
50
+ }, children: jsx(TableExpandable, { expandable: isExpandable, expanded: expanded, setExpanded: setExpanded, onExpand: (status) => { var _a; return (_a = expanding.onExpand) === null || _a === void 0 ? void 0 : _a.call(expanding, rowData, status); } }) })) : null, (columns !== null && columns !== void 0 ? columns : []).map((column, idx) => {
33
51
  var _a, _b, _c, _d;
34
52
  const ellipsis = !!(get(rowData, column.dataIndex)) && ((_a = column.ellipsis) !== null && _a !== void 0 ? _a : true);
35
53
  const tooltipTitle = ((_c = (_b = column.renderTooltipTitle) === null || _b === void 0 ? void 0 : _b.call(column, rowData)) !== null && _c !== void 0 ? _c : get(rowData, column.dataIndex));
36
- return (jsx("div", { className: cx(tableClasses.bodyRowCellWrapper, column.bodyClassName), style: getColumnStyle(column), children: jsx(TableEditRenderWrapper, { ...column, rowData: rowData, children: jsx(TableCell, { ellipsis: ellipsis, forceShownTooltipWhenHovered: column.forceShownTooltipWhenHovered, style: getCellStyle(column), tooltipTitle: tooltipTitle, children: ((_d = column.render) === null || _d === void 0 ? void 0 : _d.call(column, rowData, rowIndex, column)) || get(rowData, column.dataIndex) }) }) }, `${column.dataIndex}-${column.title}`));
37
- })] }), renderedExpandedContent ? (jsx(AccordionDetails, { className: cx(expanding.className, tableClasses.bodyRowExpandedTableWrapper), expanded: expanded, children: (renderedExpandedContent === null || renderedExpandedContent === void 0 ? void 0 : renderedExpandedContent.dataSource) ? (jsx(TableExpandedTable, { renderedExpandedContent: renderedExpandedContent })) : renderedExpandedContent })) : null] }));
54
+ return (jsx("td", { className: cx(tableClasses.bodyRowCellWrapper, isFirstColumnShouldSticky && idx === 0 && tableClasses.bodyRowCellWrapperFixed, isFirstColumnShouldSticky && idx === 0 && isHorizontalScrolling && tableClasses.bodyRowCellWrapperFixedStuck, column.bodyClassName), style: getColumnStyle(column), children: jsx(TableEditRenderWrapper, { ...column, rowData: rowData, children: jsx(TableCell, { ellipsis: ellipsis, forceShownTooltipWhenHovered: column.forceShownTooltipWhenHovered, style: getCellStyle(column), tooltipTitle: tooltipTitle, children: ((_d = column.render) === null || _d === void 0 ? void 0 : _d.call(column, rowData, rowIndex, column)) || get(rowData, column.dataIndex) }) }) }, `${column.dataIndex}-${column.title}`));
55
+ })] }), renderedExpandedContent ? (jsx("tr", { children: jsx("td", { style: { padding: 0 }, children: jsx(AccordionDetails, { className: cx(expanding.className, tableClasses.bodyRowExpandedTableWrapper), expanded: expanded, children: (renderedExpandedContent === null || renderedExpandedContent === void 0 ? void 0 : renderedExpandedContent.dataSource) ? (jsx(TableExpandedTable, { renderedExpandedContent: renderedExpandedContent })) : renderedExpandedContent }) }) })) : null] }));
38
56
  });
39
57
  var TableBodyRow$1 = TableBodyRow;
40
58
 
@@ -5,9 +5,9 @@ import Tooltip from '../Tooltip/Tooltip.js';
5
5
  import cx from 'clsx';
6
6
 
7
7
  const TableCell = forwardRef(function TableCell(props, ref) {
8
- const { children, className, ellipsis = true, forceShownTooltipWhenHovered = false, role = 'gridcell', tooltipTitle, ...rest } = props;
8
+ const { children, className, ellipsis = true, forceShownTooltipWhenHovered = false, tooltipTitle, ...rest } = props;
9
9
  const ellipsisRef = useRef(null);
10
- return (jsx("div", { ref: ref, ...rest, className: cx(tableClasses.cell, className), role: role, children: ellipsis || forceShownTooltipWhenHovered ? (jsx(Tooltip, { title: `${tooltipTitle}`, options: {
10
+ return (jsx("div", { ref: ref, ...rest, className: cx(tableClasses.cell, className), children: ellipsis || forceShownTooltipWhenHovered ? (jsx(Tooltip, { title: `${tooltipTitle}`, options: {
11
11
  placement: 'top-start',
12
12
  }, children: ({ onMouseEnter, onMouseLeave }) => (jsx("div", { ref: ellipsisRef, className: ellipsis ? tableClasses.cellEllipsis : '', onMouseEnter: (e) => {
13
13
  if (ellipsisRef.current) {
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { TableRowSelection, TableColumn, TableExpandable, TablePagination, TableDataSource, TableRecord, ExpandRowBySources } from '@mezzanine-ui/core/table';
2
+ import { TableRowSelection, TableColumn, TableExpandable, TablePagination, TableDataSource, TableRecord, ExpandRowBySources, TableScrolling } from '@mezzanine-ui/core/table';
3
3
  import { EmptyProps } from '../Empty';
4
4
  /** typeof rowSelection */
5
5
  export interface RowSelectionContext extends Pick<TableRowSelection, 'actions'> {
@@ -24,7 +24,7 @@ export interface FetchMoreContext {
24
24
  isReachEnd: boolean;
25
25
  }
26
26
  export interface TableContextProps {
27
- scrollBarSize?: number;
27
+ isHorizontalScrolling?: boolean;
28
28
  emptyProps?: EmptyProps;
29
29
  rowSelection?: RowSelectionContext;
30
30
  sorting?: SortingContext;
@@ -35,6 +35,7 @@ export interface TableContextProps {
35
35
  };
36
36
  fetchMore?: FetchMoreContext;
37
37
  pagination?: TablePagination;
38
+ scroll?: TableScrolling;
38
39
  }
39
40
  export declare const TableContext: import("react").Context<TableContextProps | null>;
40
41
  export interface TableDataContextProps {
@@ -1,4 +1,4 @@
1
1
  /// <reference types="react" />
2
2
  import { NativeElementPropsWithoutKeyAndRef } from '../utils/jsx-types';
3
- declare const TableHeader: import("react").ForwardRefExoticComponent<NativeElementPropsWithoutKeyAndRef<"div"> & import("react").RefAttributes<HTMLDivElement>>;
3
+ declare const TableHeader: import("react").ForwardRefExoticComponent<NativeElementPropsWithoutKeyAndRef<"div"> & import("react").RefAttributes<HTMLTableRowElement>>;
4
4
  export default TableHeader;
@@ -1,5 +1,5 @@
1
- import { jsxs, jsx } from 'react/jsx-runtime';
2
- import { forwardRef, useContext } from 'react';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { forwardRef, useContext, useMemo } from 'react';
3
3
  import { tableClasses, getColumnStyle, getCellStyle } from '@mezzanine-ui/core/table';
4
4
  import { TableContext, TableDataContext } from './TableContext.js';
5
5
  import { SELECTED_ALL_KEY } from './rowSelection/useTableRowSelection.js';
@@ -11,12 +11,23 @@ import cx from 'clsx';
11
11
 
12
12
  const TableHeader = forwardRef(function TableHeader(props, ref) {
13
13
  const { className, ...rest } = props;
14
- const { rowSelection, expanding, } = useContext(TableContext) || {};
14
+ const { rowSelection, isHorizontalScrolling, scroll, expanding, } = useContext(TableContext) || {};
15
15
  const { columns, } = useContext(TableDataContext) || {};
16
- return (jsxs("div", { ref: ref, ...rest, className: cx(tableClasses.header, className), role: "rowgroup", children: [rowSelection ? (jsx(TableRowSelection, { rowKey: SELECTED_ALL_KEY, showDropdownIcon: true })) : null, expanding && !rowSelection ? (jsx(TableExpandable, { showIcon: false })) : null, (columns !== null && columns !== void 0 ? columns : []).map((column) => {
17
- var _a;
18
- return (jsx("div", { className: cx(tableClasses.headerCellWrapper, column.headerClassName), style: getColumnStyle(column), children: jsxs(TableCell, { ellipsis: false, role: "columnheader", style: getCellStyle(column), children: [((_a = column.renderTitle) === null || _a === void 0 ? void 0 : _a.call(column, tableClasses)) || column.title, typeof column.sorter === 'function' || typeof column.onSorted === 'function' ? (jsx(TableSortingIcon, { column: column })) : null] }) }, `${column.dataIndex}-${column.title}`));
19
- })] }));
16
+ const isFirstColumnShouldSticky = useMemo(() => {
17
+ var _a;
18
+ /** 前面有 action 時不可 sticky */
19
+ if (rowSelection || expanding)
20
+ return false;
21
+ return ((_a = scroll === null || scroll === void 0 ? void 0 : scroll.fixedFirstColumn) !== null && _a !== void 0 ? _a : false);
22
+ }, [
23
+ rowSelection,
24
+ expanding,
25
+ scroll === null || scroll === void 0 ? void 0 : scroll.fixedFirstColumn,
26
+ ]);
27
+ return (jsx("thead", { className: tableClasses.headerFixed, children: jsxs("tr", { ref: ref, ...rest, className: cx(tableClasses.header, className), children: [rowSelection ? (jsx("th", { style: { display: 'flex' }, children: jsx(TableRowSelection, { rowKey: SELECTED_ALL_KEY, showDropdownIcon: true }) })) : null, expanding && !rowSelection ? (jsx("th", { style: { display: 'flex' }, children: jsx(TableExpandable, { showIcon: false }) })) : null, (columns !== null && columns !== void 0 ? columns : []).map((column, idx) => {
28
+ var _a;
29
+ return (jsx("th", { className: cx(tableClasses.headerCellWrapper, isFirstColumnShouldSticky && idx === 0 && tableClasses.headerCellWrapperFixed, isFirstColumnShouldSticky && idx === 0 && isHorizontalScrolling && tableClasses.headerCellWrapperFixedStuck, column.headerClassName), style: getColumnStyle(column), children: jsxs(TableCell, { ellipsis: false, style: getCellStyle(column), children: [((_a = column.renderTitle) === null || _a === void 0 ? void 0 : _a.call(column, tableClasses)) || column.title, typeof column.sorter === 'function' || typeof column.onSorted === 'function' ? (jsx(TableSortingIcon, { column: column })) : null] }) }, `${column.dataIndex}-${column.title}`));
30
+ })] }) }));
20
31
  });
21
32
  var TableHeader$1 = TableHeader;
22
33
 
@@ -1,10 +1,20 @@
1
- import { MouseEvent } from 'react';
2
- export default function useTableScroll(): readonly [{
1
+ import { UIEventHandler } from 'react';
2
+ interface TableScrollProps {
3
+ onFetchMore?: VoidFunction;
4
+ loading?: boolean;
5
+ scrollBarSize?: number;
6
+ }
7
+ export default function useTableScroll(props: TableScrollProps): readonly [{
3
8
  ref: import("react").RefObject<HTMLDivElement>;
4
- onScroll: () => void;
9
+ target: import("react").RefObject<HTMLTableElement>;
10
+ onScroll: UIEventHandler<HTMLDivElement>;
5
11
  }, {
6
12
  ref: import("react").RefObject<HTMLDivElement>;
7
- onMouseDown: ({ target, clientY }: MouseEvent<HTMLDivElement>) => void;
13
+ trackRef: import("react").RefObject<HTMLDivElement>;
14
+ scrollBarSize: number;
15
+ onMouseDown: ({ clientY }: {
16
+ clientY: number;
17
+ }) => void;
8
18
  onMouseUp: () => void;
9
19
  onMouseEnter: () => void;
10
20
  onMouseLeave: () => void;
@@ -64,14 +74,18 @@ export default function useTableScroll(): readonly [{
64
74
  'aria-activedescendant'?: string | undefined;
65
75
  'aria-atomic'?: (boolean | "true" | "false") | undefined;
66
76
  'aria-autocomplete'?: "none" | "list" | "inline" | "both" | undefined;
77
+ 'aria-braillelabel'?: string | undefined;
78
+ 'aria-brailleroledescription'?: string | undefined;
67
79
  'aria-busy'?: (boolean | "true" | "false") | undefined;
68
80
  'aria-checked'?: boolean | "true" | "false" | "mixed" | undefined;
69
81
  'aria-colcount'?: number | undefined;
70
82
  'aria-colindex'?: number | undefined;
83
+ 'aria-colindextext'?: string | undefined;
71
84
  'aria-colspan'?: number | undefined;
72
85
  'aria-controls'?: string | undefined;
73
86
  'aria-current'?: boolean | "true" | "false" | "page" | "step" | "location" | "date" | "time" | undefined;
74
87
  'aria-describedby'?: string | undefined;
88
+ 'aria-description'?: string | undefined;
75
89
  'aria-details'?: string | undefined;
76
90
  'aria-disabled'?: (boolean | "true" | "false") | undefined;
77
91
  'aria-dropeffect'?: "none" | "link" | "copy" | "execute" | "move" | "popup" | undefined;
@@ -101,6 +115,7 @@ export default function useTableScroll(): readonly [{
101
115
  'aria-roledescription'?: string | undefined;
102
116
  'aria-rowcount'?: number | undefined;
103
117
  'aria-rowindex'?: number | undefined;
118
+ 'aria-rowindextext'?: string | undefined;
104
119
  'aria-rowspan'?: number | undefined;
105
120
  'aria-selected'?: (boolean | "true" | "false") | undefined;
106
121
  'aria-setsize'?: number | undefined;
@@ -263,8 +278,8 @@ export default function useTableScroll(): readonly [{
263
278
  onGotPointerCaptureCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
264
279
  onLostPointerCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
265
280
  onLostPointerCaptureCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
266
- onScroll?: import("react").UIEventHandler<HTMLDivElement> | undefined;
267
- onScrollCapture?: import("react").UIEventHandler<HTMLDivElement> | undefined;
281
+ onScroll?: UIEventHandler<HTMLDivElement> | undefined;
282
+ onScrollCapture?: UIEventHandler<HTMLDivElement> | undefined;
268
283
  onWheel?: import("react").WheelEventHandler<HTMLDivElement> | undefined;
269
284
  onWheelCapture?: import("react").WheelEventHandler<HTMLDivElement> | undefined;
270
285
  onAnimationStart?: import("react").AnimationEventHandler<HTMLDivElement> | undefined;
@@ -276,4 +291,278 @@ export default function useTableScroll(): readonly [{
276
291
  onTransitionEnd?: import("react").TransitionEventHandler<HTMLDivElement> | undefined;
277
292
  onTransitionEndCapture?: import("react").TransitionEventHandler<HTMLDivElement> | undefined;
278
293
  };
279
- }];
294
+ trackStyle: {
295
+ height: string;
296
+ ref?: import("react").LegacyRef<HTMLDivElement> | undefined;
297
+ key?: import("react").Key | null | undefined;
298
+ defaultChecked?: boolean | undefined;
299
+ defaultValue?: string | number | readonly string[] | undefined;
300
+ suppressContentEditableWarning?: boolean | undefined;
301
+ suppressHydrationWarning?: boolean | undefined;
302
+ accessKey?: string | undefined;
303
+ autoFocus?: boolean | undefined;
304
+ className?: string | undefined;
305
+ contentEditable?: (boolean | "true" | "false") | "inherit" | undefined;
306
+ contextMenu?: string | undefined;
307
+ dir?: string | undefined;
308
+ draggable?: (boolean | "true" | "false") | undefined;
309
+ hidden?: boolean | undefined;
310
+ id?: string | undefined;
311
+ lang?: string | undefined;
312
+ nonce?: string | undefined;
313
+ placeholder?: string | undefined;
314
+ slot?: string | undefined;
315
+ spellCheck?: (boolean | "true" | "false") | undefined;
316
+ style?: import("react").CSSProperties | undefined;
317
+ tabIndex?: number | undefined;
318
+ title?: string | undefined;
319
+ translate?: "yes" | "no" | undefined;
320
+ radioGroup?: string | undefined;
321
+ role?: import("react").AriaRole | undefined;
322
+ about?: string | undefined;
323
+ content?: string | undefined;
324
+ datatype?: string | undefined;
325
+ inlist?: any;
326
+ prefix?: string | undefined;
327
+ property?: string | undefined;
328
+ rel?: string | undefined;
329
+ resource?: string | undefined;
330
+ rev?: string | undefined;
331
+ typeof?: string | undefined;
332
+ vocab?: string | undefined;
333
+ autoCapitalize?: string | undefined;
334
+ autoCorrect?: string | undefined;
335
+ autoSave?: string | undefined;
336
+ color?: string | undefined;
337
+ itemProp?: string | undefined;
338
+ itemScope?: boolean | undefined;
339
+ itemType?: string | undefined;
340
+ itemID?: string | undefined;
341
+ itemRef?: string | undefined;
342
+ results?: number | undefined;
343
+ security?: string | undefined;
344
+ unselectable?: "on" | "off" | undefined;
345
+ inputMode?: "none" | "search" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | undefined;
346
+ is?: string | undefined;
347
+ 'aria-activedescendant'?: string | undefined;
348
+ 'aria-atomic'?: (boolean | "true" | "false") | undefined;
349
+ 'aria-autocomplete'?: "none" | "list" | "inline" | "both" | undefined;
350
+ 'aria-braillelabel'?: string | undefined;
351
+ 'aria-brailleroledescription'?: string | undefined;
352
+ 'aria-busy'?: (boolean | "true" | "false") | undefined;
353
+ 'aria-checked'?: boolean | "true" | "false" | "mixed" | undefined;
354
+ 'aria-colcount'?: number | undefined;
355
+ 'aria-colindex'?: number | undefined;
356
+ 'aria-colindextext'?: string | undefined;
357
+ 'aria-colspan'?: number | undefined;
358
+ 'aria-controls'?: string | undefined;
359
+ 'aria-current'?: boolean | "true" | "false" | "page" | "step" | "location" | "date" | "time" | undefined;
360
+ 'aria-describedby'?: string | undefined;
361
+ 'aria-description'?: string | undefined;
362
+ 'aria-details'?: string | undefined;
363
+ 'aria-disabled'?: (boolean | "true" | "false") | undefined;
364
+ 'aria-dropeffect'?: "none" | "link" | "copy" | "execute" | "move" | "popup" | undefined;
365
+ 'aria-errormessage'?: string | undefined;
366
+ 'aria-expanded'?: (boolean | "true" | "false") | undefined;
367
+ 'aria-flowto'?: string | undefined;
368
+ 'aria-grabbed'?: (boolean | "true" | "false") | undefined;
369
+ 'aria-haspopup'?: boolean | "true" | "false" | "dialog" | "grid" | "listbox" | "menu" | "tree" | undefined;
370
+ 'aria-hidden'?: (boolean | "true" | "false") | undefined;
371
+ 'aria-invalid'?: boolean | "true" | "false" | "grammar" | "spelling" | undefined;
372
+ 'aria-keyshortcuts'?: string | undefined;
373
+ 'aria-label'?: string | undefined;
374
+ 'aria-labelledby'?: string | undefined;
375
+ 'aria-level'?: number | undefined;
376
+ 'aria-live'?: "off" | "assertive" | "polite" | undefined;
377
+ 'aria-modal'?: (boolean | "true" | "false") | undefined;
378
+ 'aria-multiline'?: (boolean | "true" | "false") | undefined;
379
+ 'aria-multiselectable'?: (boolean | "true" | "false") | undefined;
380
+ 'aria-orientation'?: "horizontal" | "vertical" | undefined;
381
+ 'aria-owns'?: string | undefined;
382
+ 'aria-placeholder'?: string | undefined;
383
+ 'aria-posinset'?: number | undefined;
384
+ 'aria-pressed'?: boolean | "true" | "false" | "mixed" | undefined;
385
+ 'aria-readonly'?: (boolean | "true" | "false") | undefined;
386
+ 'aria-relevant'?: "text" | "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text additions" | "text removals" | undefined;
387
+ 'aria-required'?: (boolean | "true" | "false") | undefined;
388
+ 'aria-roledescription'?: string | undefined;
389
+ 'aria-rowcount'?: number | undefined;
390
+ 'aria-rowindex'?: number | undefined;
391
+ 'aria-rowindextext'?: string | undefined;
392
+ 'aria-rowspan'?: number | undefined;
393
+ 'aria-selected'?: (boolean | "true" | "false") | undefined;
394
+ 'aria-setsize'?: number | undefined;
395
+ 'aria-sort'?: "none" | "ascending" | "descending" | "other" | undefined;
396
+ 'aria-valuemax'?: number | undefined;
397
+ 'aria-valuemin'?: number | undefined;
398
+ 'aria-valuenow'?: number | undefined;
399
+ 'aria-valuetext'?: string | undefined;
400
+ children?: import("react").ReactNode;
401
+ dangerouslySetInnerHTML?: {
402
+ __html: string | TrustedHTML;
403
+ } | undefined;
404
+ onCopy?: import("react").ClipboardEventHandler<HTMLDivElement> | undefined;
405
+ onCopyCapture?: import("react").ClipboardEventHandler<HTMLDivElement> | undefined;
406
+ onCut?: import("react").ClipboardEventHandler<HTMLDivElement> | undefined;
407
+ onCutCapture?: import("react").ClipboardEventHandler<HTMLDivElement> | undefined;
408
+ onPaste?: import("react").ClipboardEventHandler<HTMLDivElement> | undefined;
409
+ onPasteCapture?: import("react").ClipboardEventHandler<HTMLDivElement> | undefined;
410
+ onCompositionEnd?: import("react").CompositionEventHandler<HTMLDivElement> | undefined;
411
+ onCompositionEndCapture?: import("react").CompositionEventHandler<HTMLDivElement> | undefined;
412
+ onCompositionStart?: import("react").CompositionEventHandler<HTMLDivElement> | undefined;
413
+ onCompositionStartCapture?: import("react").CompositionEventHandler<HTMLDivElement> | undefined;
414
+ onCompositionUpdate?: import("react").CompositionEventHandler<HTMLDivElement> | undefined;
415
+ onCompositionUpdateCapture?: import("react").CompositionEventHandler<HTMLDivElement> | undefined;
416
+ onFocus?: import("react").FocusEventHandler<HTMLDivElement> | undefined;
417
+ onFocusCapture?: import("react").FocusEventHandler<HTMLDivElement> | undefined;
418
+ onBlur?: import("react").FocusEventHandler<HTMLDivElement> | undefined;
419
+ onBlurCapture?: import("react").FocusEventHandler<HTMLDivElement> | undefined;
420
+ onChange?: import("react").FormEventHandler<HTMLDivElement> | undefined;
421
+ onChangeCapture?: import("react").FormEventHandler<HTMLDivElement> | undefined;
422
+ onBeforeInput?: import("react").FormEventHandler<HTMLDivElement> | undefined;
423
+ onBeforeInputCapture?: import("react").FormEventHandler<HTMLDivElement> | undefined;
424
+ onInput?: import("react").FormEventHandler<HTMLDivElement> | undefined;
425
+ onInputCapture?: import("react").FormEventHandler<HTMLDivElement> | undefined;
426
+ onReset?: import("react").FormEventHandler<HTMLDivElement> | undefined;
427
+ onResetCapture?: import("react").FormEventHandler<HTMLDivElement> | undefined;
428
+ onSubmit?: import("react").FormEventHandler<HTMLDivElement> | undefined;
429
+ onSubmitCapture?: import("react").FormEventHandler<HTMLDivElement> | undefined;
430
+ onInvalid?: import("react").FormEventHandler<HTMLDivElement> | undefined;
431
+ onInvalidCapture?: import("react").FormEventHandler<HTMLDivElement> | undefined;
432
+ onLoad?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
433
+ onLoadCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
434
+ onError?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
435
+ onErrorCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
436
+ onKeyDown?: import("react").KeyboardEventHandler<HTMLDivElement> | undefined;
437
+ onKeyDownCapture?: import("react").KeyboardEventHandler<HTMLDivElement> | undefined;
438
+ onKeyPress?: import("react").KeyboardEventHandler<HTMLDivElement> | undefined;
439
+ onKeyPressCapture?: import("react").KeyboardEventHandler<HTMLDivElement> | undefined;
440
+ onKeyUp?: import("react").KeyboardEventHandler<HTMLDivElement> | undefined;
441
+ onKeyUpCapture?: import("react").KeyboardEventHandler<HTMLDivElement> | undefined;
442
+ onAbort?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
443
+ onAbortCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
444
+ onCanPlay?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
445
+ onCanPlayCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
446
+ onCanPlayThrough?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
447
+ onCanPlayThroughCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
448
+ onDurationChange?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
449
+ onDurationChangeCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
450
+ onEmptied?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
451
+ onEmptiedCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
452
+ onEncrypted?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
453
+ onEncryptedCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
454
+ onEnded?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
455
+ onEndedCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
456
+ onLoadedData?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
457
+ onLoadedDataCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
458
+ onLoadedMetadata?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
459
+ onLoadedMetadataCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
460
+ onLoadStart?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
461
+ onLoadStartCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
462
+ onPause?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
463
+ onPauseCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
464
+ onPlay?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
465
+ onPlayCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
466
+ onPlaying?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
467
+ onPlayingCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
468
+ onProgress?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
469
+ onProgressCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
470
+ onRateChange?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
471
+ onRateChangeCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
472
+ onResize?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
473
+ onResizeCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
474
+ onSeeked?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
475
+ onSeekedCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
476
+ onSeeking?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
477
+ onSeekingCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
478
+ onStalled?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
479
+ onStalledCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
480
+ onSuspend?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
481
+ onSuspendCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
482
+ onTimeUpdate?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
483
+ onTimeUpdateCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
484
+ onVolumeChange?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
485
+ onVolumeChangeCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
486
+ onWaiting?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
487
+ onWaitingCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
488
+ onAuxClick?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
489
+ onAuxClickCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
490
+ onClick?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
491
+ onClickCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
492
+ onContextMenu?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
493
+ onContextMenuCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
494
+ onDoubleClick?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
495
+ onDoubleClickCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
496
+ onDrag?: import("react").DragEventHandler<HTMLDivElement> | undefined;
497
+ onDragCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
498
+ onDragEnd?: import("react").DragEventHandler<HTMLDivElement> | undefined;
499
+ onDragEndCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
500
+ onDragEnter?: import("react").DragEventHandler<HTMLDivElement> | undefined;
501
+ onDragEnterCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
502
+ onDragExit?: import("react").DragEventHandler<HTMLDivElement> | undefined;
503
+ onDragExitCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
504
+ onDragLeave?: import("react").DragEventHandler<HTMLDivElement> | undefined;
505
+ onDragLeaveCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
506
+ onDragOver?: import("react").DragEventHandler<HTMLDivElement> | undefined;
507
+ onDragOverCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
508
+ onDragStart?: import("react").DragEventHandler<HTMLDivElement> | undefined;
509
+ onDragStartCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
510
+ onDrop?: import("react").DragEventHandler<HTMLDivElement> | undefined;
511
+ onDropCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
512
+ onMouseDown?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
513
+ onMouseDownCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
514
+ onMouseEnter?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
515
+ onMouseLeave?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
516
+ onMouseMove?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
517
+ onMouseMoveCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
518
+ onMouseOut?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
519
+ onMouseOutCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
520
+ onMouseOver?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
521
+ onMouseOverCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
522
+ onMouseUp?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
523
+ onMouseUpCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
524
+ onSelect?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
525
+ onSelectCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
526
+ onTouchCancel?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
527
+ onTouchCancelCapture?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
528
+ onTouchEnd?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
529
+ onTouchEndCapture?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
530
+ onTouchMove?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
531
+ onTouchMoveCapture?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
532
+ onTouchStart?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
533
+ onTouchStartCapture?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
534
+ onPointerDown?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
535
+ onPointerDownCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
536
+ onPointerMove?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
537
+ onPointerMoveCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
538
+ onPointerUp?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
539
+ onPointerUpCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
540
+ onPointerCancel?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
541
+ onPointerCancelCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
542
+ onPointerEnter?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
543
+ onPointerEnterCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
544
+ onPointerLeave?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
545
+ onPointerLeaveCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
546
+ onPointerOver?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
547
+ onPointerOverCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
548
+ onPointerOut?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
549
+ onPointerOutCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
550
+ onGotPointerCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
551
+ onGotPointerCaptureCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
552
+ onLostPointerCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
553
+ onLostPointerCaptureCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
554
+ onScroll?: UIEventHandler<HTMLDivElement> | undefined;
555
+ onScrollCapture?: UIEventHandler<HTMLDivElement> | undefined;
556
+ onWheel?: import("react").WheelEventHandler<HTMLDivElement> | undefined;
557
+ onWheelCapture?: import("react").WheelEventHandler<HTMLDivElement> | undefined;
558
+ onAnimationStart?: import("react").AnimationEventHandler<HTMLDivElement> | undefined;
559
+ onAnimationStartCapture?: import("react").AnimationEventHandler<HTMLDivElement> | undefined;
560
+ onAnimationEnd?: import("react").AnimationEventHandler<HTMLDivElement> | undefined;
561
+ onAnimationEndCapture?: import("react").AnimationEventHandler<HTMLDivElement> | undefined;
562
+ onAnimationIteration?: import("react").AnimationEventHandler<HTMLDivElement> | undefined;
563
+ onAnimationIterationCapture?: import("react").AnimationEventHandler<HTMLDivElement> | undefined;
564
+ onTransitionEnd?: import("react").TransitionEventHandler<HTMLDivElement> | undefined;
565
+ onTransitionEndCapture?: import("react").TransitionEventHandler<HTMLDivElement> | undefined;
566
+ };
567
+ }, boolean];
568
+ export {};
@@ -1,141 +1,239 @@
1
- import { useRef, useContext, useState, useCallback, useMemo, useEffect } from 'react';
2
- import { TableContext, TableDataContext } from './TableContext.js';
3
- import { usePreviousValue } from '../hooks/usePreviousValue.js';
1
+ import { useRef, useState, useCallback, useEffect, useMemo } from 'react';
4
2
 
3
+ const HEADER_DEFAULT_HEIGHT = 40; // px
4
+ const SCROLL_BAR_MIN_START_AT = 4; // px
5
+ const SCROLL_BAR_MAX_END_SPACING = 16; // px
6
+ const FETCH_MORE_TRIGGER_AT_BOTTOM = 46; // px
7
+ const SCROLL_BAR_DISPLAY_TIMES = 1500; // ms
8
+ const defaultScrollBarTrackStyle = {
9
+ position: 'absolute',
10
+ right: 0,
11
+ top: `${HEADER_DEFAULT_HEIGHT}px`,
12
+ width: 12,
13
+ height: 0,
14
+ opacity: '0',
15
+ transition: '0.1s opacity ease-in',
16
+ backgroundColor: '#F2F2F2',
17
+ };
5
18
  const defaultScrollBarStyle = {
6
19
  display: 'flex',
7
20
  justifyContent: 'center',
8
21
  alignItems: 'flex-start',
9
22
  position: 'absolute',
10
23
  right: 0,
11
- top: 0,
24
+ top: `${SCROLL_BAR_MIN_START_AT}px`,
12
25
  width: 10,
13
26
  height: 0,
14
27
  borderRadius: 10,
28
+ transform: 'translate3d(0, 0, 0)',
15
29
  outline: 'none',
16
30
  opacity: '0',
17
31
  transition: '0.1s opacity ease-in',
18
32
  backgroundColor: 'transparent',
19
33
  };
20
- const SCROLL_BAR_MIN_START_AT = 4; // px
21
- const SCROLL_BAR_MAX_END_SPACING = 16; // px
22
- const FETCH_MORE_TRIGGER_AT_BOTTOM = 46; // px
23
- const SCROLL_BAR_DISPLAY_TIMES = 1000; // ms
24
- function useTableScroll() {
25
- const bodyRef = useRef(null);
34
+ function useTableScroll(props) {
35
+ const { onFetchMore, loading, scrollBarSize = 4, } = props;
36
+ const scrollRef = useRef(null);
37
+ const tableRef = useRef(null);
38
+ const scrollBarTrackRef = useRef(null);
26
39
  const scrollBarRef = useRef(null);
27
40
  const scrollBarDisplayTimer = useRef();
28
- const { fetchMore, loading, scrollBarSize = 4, } = useContext(TableContext) || {};
29
- const { dataSource = [], } = useContext(TableDataContext) || {};
30
41
  const [scrollBarHeight, setScrollBarHeight] = useState(0);
31
42
  const [pointerOffset, setPointerOffset] = useState(0);
43
+ const [isHorizontalScrolling, toggleIsHorizontalScrolling] = useState(false);
32
44
  /** set scroll bar callback */
33
45
  const onSetScrollBarHeight = useCallback(() => {
34
- if (!bodyRef.current)
46
+ /** @NOTE Scroll bar 高度為可視區域的百分比 */
47
+ if (!scrollRef.current)
35
48
  return;
36
- const { scrollHeight, clientHeight: tableHeight, } = bodyRef.current;
37
- const nextHeight = Math.max((tableHeight - SCROLL_BAR_MAX_END_SPACING) * (tableHeight / scrollHeight), tableHeight / 10);
49
+ const { scrollHeight, clientHeight: tableHeight, } = scrollRef.current;
50
+ const bodyHeight = scrollHeight - HEADER_DEFAULT_HEIGHT;
51
+ const viewAreaHeight = tableHeight - HEADER_DEFAULT_HEIGHT;
52
+ const nextHeight = Math.max((viewAreaHeight - (SCROLL_BAR_MAX_END_SPACING * 2)) * (viewAreaHeight / bodyHeight), tableHeight / 10);
38
53
  setScrollBarHeight(nextHeight);
39
54
  }, []);
40
55
  /** display/hide scroll bar */
41
56
  const onHideScrollBar = useCallback(() => {
42
57
  if (!scrollBarRef.current)
43
58
  return;
44
- scrollBarRef.current.style.opacity = '0';
45
- scrollBarRef.current.style.pointerEvents = 'none';
59
+ if (scrollBarDisplayTimer.current) {
60
+ window.clearTimeout(scrollBarDisplayTimer.current);
61
+ }
62
+ scrollBarDisplayTimer.current = window.setTimeout(() => {
63
+ if (scrollBarRef.current) {
64
+ scrollBarRef.current.style.opacity = '0';
65
+ scrollBarRef.current.style.pointerEvents = 'none';
66
+ }
67
+ if (scrollBarTrackRef.current) {
68
+ scrollBarTrackRef.current.style.opacity = '0';
69
+ scrollBarTrackRef.current.style.pointerEvents = 'none';
70
+ }
71
+ }, SCROLL_BAR_DISPLAY_TIMES);
46
72
  }, []);
47
73
  const onDisplayScrollBar = useCallback(() => {
48
- if (!scrollBarRef.current || !bodyRef.current)
74
+ if (!scrollBarRef.current || !scrollRef.current || !scrollBarTrackRef.current)
75
+ return;
76
+ /** 觸控螢幕不需要 scroll bar */
77
+ const isTouchEnabled = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0);
78
+ /** firefox 的滾軸只能同時顯示 or 取消,所以乾脆就用原生的(除非能單獨關掉直向的滾軸,只顯示橫向的才行) */
79
+ const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
80
+ if (isTouchEnabled || isFirefox)
49
81
  return;
82
+ scrollBarRef.current.style.opacity = '1';
83
+ scrollBarRef.current.style.pointerEvents = 'auto';
84
+ scrollBarTrackRef.current.style.opacity = '1';
85
+ scrollBarTrackRef.current.style.pointerEvents = 'auto';
50
86
  if (scrollBarDisplayTimer.current) {
51
87
  window.clearTimeout(scrollBarDisplayTimer.current);
52
88
  }
53
- scrollBarRef.current.style.opacity = '1';
54
- scrollBarRef.current.style.pointerEvents = 'auto';
55
- scrollBarDisplayTimer.current = window.setTimeout(() => onHideScrollBar(), SCROLL_BAR_DISPLAY_TIMES);
56
89
  }, []);
57
- /** reset scroll bar height when sources changed */
58
- const prevSourceLength = usePreviousValue(dataSource.length);
59
- const currentSourceLength = useMemo(() => dataSource.length, [dataSource.length]);
60
- useEffect(() => {
61
- // first initial render
62
- onSetScrollBarHeight();
90
+ const resetPointerOffset = useCallback(() => setPointerOffset(0), []);
91
+ /** scroll bar style reset when mouse leave */
92
+ const onScrollBarLeave = useCallback(() => {
93
+ if (scrollBarRef.current) {
94
+ scrollBarRef.current.childNodes[0].style.width = `${scrollBarSize}px`;
95
+ }
96
+ resetPointerOffset();
97
+ }, []);
98
+ /** when use mouse to drag scroll bar, get cursor position */
99
+ const onScrollBarMouseDown = useCallback(({ clientY }) => {
100
+ const { current: scrollBar } = scrollBarRef;
101
+ if (!scrollBar)
102
+ return;
103
+ const { top: initScrollBarTop } = scrollBar.getBoundingClientRect();
104
+ setPointerOffset(clientY - initScrollBarTop);
63
105
  }, []);
106
+ const onScrollBarMouseUp = useCallback(() => resetPointerOffset(), []);
107
+ /** 偵測 table 高度是否發生變化,有的話就要重新計算 scroll bar 長度 */
64
108
  useEffect(() => {
65
- if (prevSourceLength !== currentSourceLength) {
66
- onSetScrollBarHeight();
109
+ const { current: table } = tableRef;
110
+ function resizing() {
111
+ window.requestAnimationFrame(onSetScrollBarHeight);
67
112
  }
68
- }, [prevSourceLength, currentSourceLength]);
69
- /** set the scroll bar default position */
70
- useEffect(() => {
71
- if (!scrollBarRef.current || !bodyRef.current)
72
- return;
73
- scrollBarRef.current.style.top = `${SCROLL_BAR_MIN_START_AT}px`;
113
+ if (table) {
114
+ const observer = new ResizeObserver(resizing);
115
+ observer.observe(table);
116
+ return () => {
117
+ observer.disconnect();
118
+ };
119
+ }
120
+ return () => { };
74
121
  }, []);
75
122
  useEffect(() => {
76
- const { current: body } = bodyRef;
123
+ const { current: body } = scrollRef;
77
124
  const { current: scrollBar } = scrollBarRef;
78
- if (!body || !scrollBar)
125
+ const { current: scrollBarTrack } = scrollBarTrackRef;
126
+ if (!body || !scrollBar || !scrollBarTrack)
79
127
  return;
128
+ /** 游標在滾軸上長按並移動 */
80
129
  function onMouseMove({ clientY }) {
81
- const { scrollTop, scrollHeight, clientHeight: tableHeight, } = body;
130
+ const { scrollHeight, clientHeight: tableHeight, } = body;
82
131
  if (!pointerOffset)
83
132
  return;
84
133
  // keep scroll bar display when moving
85
134
  window.requestAnimationFrame(onDisplayScrollBar);
86
135
  const { top: tableTop, } = body.getBoundingClientRect();
87
- const nextScrollBarTop = (clientY - tableTop - pointerOffset) + scrollTop;
88
- const maxScrollBarTop = scrollHeight - scrollBarHeight - SCROLL_BAR_MAX_END_SPACING;
89
- const clampScrollBarTop = Math.min(Math.max(nextScrollBarTop, SCROLL_BAR_MIN_START_AT), // min boundary
90
- maxScrollBarTop);
91
- scrollBar.style.setProperty('top', `${clampScrollBarTop}px`);
92
- body.scrollTop = (((scrollHeight - tableHeight) * (clampScrollBarTop)) /
93
- (scrollHeight - scrollBarHeight));
136
+ /** Table 最大滾動距離 */
137
+ const maxScrollDistance = scrollHeight - tableHeight;
138
+ /** 游標在 scroll bar 上的位置 */
139
+ const scrollBarCurrentPosition = clientY - (tableTop + HEADER_DEFAULT_HEIGHT) - pointerOffset;
140
+ /** 可視區域高度 */
141
+ const viewAreaHeight = tableHeight - HEADER_DEFAULT_HEIGHT;
142
+ /** 最大滑動距離 */
143
+ const maxScrollBarDistance = viewAreaHeight - scrollBarHeight - SCROLL_BAR_MAX_END_SPACING;
144
+ /** 計算出來的距離 */
145
+ const clampScrollBarTop = Math.min(Math.max(scrollBarCurrentPosition, 0), // min boundary
146
+ maxScrollBarDistance);
147
+ scrollBar.style.setProperty('transform', `translate3d(0, ${clampScrollBarTop}px, 0)`);
148
+ body.scrollTop = ((clampScrollBarTop * maxScrollDistance) / maxScrollBarDistance);
149
+ }
150
+ /** 在滾軸滑軌上點擊,直接滾動到指定位置上 */
151
+ function onMouseClick({ clientY }) {
152
+ if (!scrollBar)
153
+ return;
154
+ const { scrollHeight, clientHeight: tableHeight, } = body;
155
+ // keep scroll bar display when moving
156
+ window.requestAnimationFrame(onDisplayScrollBar);
157
+ const { top: tableTop, } = body.getBoundingClientRect();
158
+ /** Table 最大滾動距離 */
159
+ const maxScrollDistance = scrollHeight - tableHeight;
160
+ /** 游標在 Track 上的位置 */
161
+ const scrollBarCurrentPosition = clientY - (tableTop + HEADER_DEFAULT_HEIGHT) - (scrollBarHeight / 2);
162
+ /** 可視區域高度 */
163
+ const viewAreaHeight = tableHeight - HEADER_DEFAULT_HEIGHT;
164
+ /** 最大滑動距離 */
165
+ const maxScrollBarDistance = viewAreaHeight - scrollBarHeight - SCROLL_BAR_MAX_END_SPACING;
166
+ /** 計算出來的距離 */
167
+ const clampScrollBarTop = Math.min(Math.max(scrollBarCurrentPosition, 0), // min boundary
168
+ maxScrollBarDistance);
169
+ scrollBar.style.setProperty('transform', `translate3d(0, ${clampScrollBarTop}px, 0)`);
170
+ body.scrollTop = ((clampScrollBarTop * maxScrollDistance) / maxScrollBarDistance);
171
+ }
172
+ /** 游標移動到滾軸/滑軌上方時 */
173
+ function onMouseOver() {
174
+ scrollBar.style.setProperty('transition', '0s');
175
+ onDisplayScrollBar();
176
+ }
177
+ /** 游標移開滾軸/滑軌上方時 */
178
+ function onMouseLeave() {
179
+ scrollBar.style.setProperty('transition', '0.1s');
180
+ onHideScrollBar();
94
181
  }
95
182
  scrollBar.addEventListener('mousemove', onMouseMove, false);
183
+ scrollBar.addEventListener('mouseover', onMouseOver, false);
184
+ scrollBar.addEventListener('mouseleave', onMouseLeave, false);
185
+ scrollBarTrack.addEventListener('mousemove', onMouseMove, false);
186
+ scrollBarTrack.addEventListener('mouseover', onMouseOver, false);
187
+ scrollBarTrack.addEventListener('mouseleave', onMouseLeave, false);
188
+ scrollBarTrack.addEventListener('click', onMouseClick, false);
96
189
  return () => {
97
190
  scrollBar.removeEventListener('mousemove', onMouseMove, false);
191
+ scrollBar.removeEventListener('mouseover', onMouseOver, false);
192
+ scrollBar.removeEventListener('mouseleave', onMouseLeave, false);
193
+ scrollBarTrack.removeEventListener('mousemove', onMouseMove, false);
194
+ scrollBarTrack.removeEventListener('mouseover', onMouseOver, false);
195
+ scrollBarTrack.removeEventListener('mouseleave', onMouseLeave, false);
196
+ scrollBarTrack.removeEventListener('click', onMouseClick, false);
98
197
  };
99
- }, [scrollBarHeight, pointerOffset, onDisplayScrollBar]);
100
- const resetPointerOffset = useCallback(() => setPointerOffset(0), []);
198
+ }, [scrollBarHeight, pointerOffset, onDisplayScrollBar, onHideScrollBar]);
101
199
  /** scroll bar fatter when mouse enter */
102
200
  const onScrollBarEnter = useCallback(() => {
103
201
  if (scrollBarRef.current) {
104
202
  scrollBarRef.current.childNodes[0].style.width = `${scrollBarSize + 6}px`;
105
203
  }
106
204
  }, []);
107
- /** scroll bar style reset when mouse leave */
108
- const onScrollBarLeave = useCallback(() => {
109
- if (scrollBarRef.current) {
110
- scrollBarRef.current.childNodes[0].style.width = `${scrollBarSize}px`;
111
- }
112
- resetPointerOffset();
113
- }, []);
114
- /** when use mouse to drag scroll bar, get cursor position */
115
- const onScrollBarMouseDown = useCallback(({ target, clientY }) => {
116
- if (!target)
117
- return;
118
- const { top: initScrollBarTop } = target.getBoundingClientRect();
119
- setPointerOffset(clientY - initScrollBarTop);
120
- }, []);
121
- const onScrollBarMouseUp = useCallback(() => resetPointerOffset(), []);
122
205
  /** scroll table directly */
123
206
  const setScrollBarTop = useCallback(() => {
124
- if (bodyRef.current) {
125
- const { clientHeight: tableHeight, scrollTop, scrollHeight, } = bodyRef.current;
207
+ if (scrollRef.current) {
208
+ const { clientHeight: tableHeight, scrollTop, scrollHeight, } = scrollRef.current;
126
209
  /** @NOTE don't apply scroll change when use pointer dragging */
127
210
  if (scrollBarRef.current && !pointerOffset) {
128
- scrollBarRef.current.style.top = `${(scrollTop * (tableHeight - scrollBarHeight - SCROLL_BAR_MAX_END_SPACING)) /
129
- (scrollHeight - tableHeight) + scrollTop + SCROLL_BAR_MIN_START_AT}px`;
211
+ const bodyHeight = scrollHeight - HEADER_DEFAULT_HEIGHT;
212
+ const viewAreaHeight = tableHeight - HEADER_DEFAULT_HEIGHT;
213
+ const distance = Math.max((viewAreaHeight * Math.max((scrollTop / bodyHeight), 0)), 0);
214
+ scrollBarRef.current.style.transform = `translate3d(0, ${distance}px, 0)`;
215
+ }
216
+ if (scrollBarTrackRef.current) {
217
+ scrollBarTrackRef.current.style.height = `${tableHeight - HEADER_DEFAULT_HEIGHT}px`;
130
218
  }
131
219
  }
132
220
  }, [scrollBarHeight, pointerOffset]);
133
- const onScroll = useCallback(() => {
134
- window.requestAnimationFrame(onDisplayScrollBar);
221
+ const onScroll = useCallback((scrollTarget) => {
222
+ /** 使用者開始橫向滾動 */
223
+ if (scrollTarget.target.scrollLeft) {
224
+ toggleIsHorizontalScrolling(true);
225
+ }
226
+ else {
227
+ toggleIsHorizontalScrolling(false);
228
+ }
135
229
  if (loading)
136
230
  return;
137
- if (bodyRef.current) {
138
- const { clientHeight, scrollTop, scrollHeight, } = bodyRef.current;
231
+ if (scrollRef.current) {
232
+ const { clientHeight, scrollTop, scrollHeight, } = scrollRef.current;
233
+ /** 如果不需要滾動,則不需要觸發 */
234
+ if (clientHeight >= scrollHeight)
235
+ return;
236
+ window.requestAnimationFrame(onDisplayScrollBar);
139
237
  /** @Note safari specific bug fix for scroll bouncing */
140
238
  const belowBottom = scrollTop > (scrollHeight - clientHeight);
141
239
  if (belowBottom)
@@ -143,28 +241,40 @@ function useTableScroll() {
143
241
  window.requestAnimationFrame(setScrollBarTop);
144
242
  /** trigger fetchMore when scrolling */
145
243
  if ((scrollHeight - (scrollTop + clientHeight)) < FETCH_MORE_TRIGGER_AT_BOTTOM) {
146
- fetchMore === null || fetchMore === void 0 ? void 0 : fetchMore.onFetchMore();
244
+ onFetchMore === null || onFetchMore === void 0 ? void 0 : onFetchMore();
147
245
  }
148
246
  }
149
- }, [loading, setScrollBarTop, onDisplayScrollBar, fetchMore]);
247
+ window.requestAnimationFrame(onHideScrollBar);
248
+ }, [loading, setScrollBarTop, onDisplayScrollBar, onFetchMore, onHideScrollBar]);
150
249
  const scrollBarStyle = useMemo(() => ({
151
250
  ...defaultScrollBarStyle,
152
251
  height: `${scrollBarHeight}px`,
153
252
  }), [scrollBarHeight]);
253
+ const scrollBarTrackStyle = useMemo(() => {
254
+ var _a, _b;
255
+ return ({
256
+ ...defaultScrollBarTrackStyle,
257
+ height: `${(_b = (_a = scrollRef.current) === null || _a === void 0 ? void 0 : _a.scrollHeight) !== null && _b !== void 0 ? _b : 0}px`,
258
+ });
259
+ }, [scrollBarHeight]);
154
260
  /** composing result */
155
- const tableBody = {
156
- ref: bodyRef,
261
+ const tableScrollContainer = {
262
+ ref: scrollRef,
263
+ target: tableRef,
157
264
  onScroll,
158
265
  };
159
266
  const scrollElement = {
160
267
  ref: scrollBarRef,
268
+ trackRef: scrollBarTrackRef,
269
+ scrollBarSize,
161
270
  onMouseDown: onScrollBarMouseDown,
162
271
  onMouseUp: onScrollBarMouseUp,
163
272
  onMouseEnter: onScrollBarEnter,
164
273
  onMouseLeave: onScrollBarLeave,
165
274
  style: scrollBarStyle,
275
+ trackStyle: scrollBarTrackStyle,
166
276
  };
167
- return [tableBody, scrollElement];
277
+ return [tableScrollContainer, scrollElement, isHorizontalScrolling];
168
278
  }
169
279
 
170
280
  export { useTableScroll as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mezzanine-ui/react",
3
- "version": "0.12.8",
3
+ "version": "0.13.0",
4
4
  "description": "React components for mezzanine-ui",
5
5
  "author": "Mezzanine",
6
6
  "repository": {
@@ -31,9 +31,9 @@
31
31
  "react-dom": "^18.2.0"
32
32
  },
33
33
  "dependencies": {
34
- "@mezzanine-ui/core": "^0.12.8",
35
- "@mezzanine-ui/icons": "^0.12.8",
36
- "@mezzanine-ui/system": "^0.12.8",
34
+ "@mezzanine-ui/core": "^0.13.0",
35
+ "@mezzanine-ui/icons": "^0.13.0",
36
+ "@mezzanine-ui/system": "^0.13.0",
37
37
  "@popperjs/core": "^2.11.6",
38
38
  "@types/react-transition-group": "^4.4.5",
39
39
  "clsx": "^1.2.1",