@monolith-forensics/monolith-ui 1.4.0 → 1.4.2

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.
@@ -3,6 +3,9 @@ export type AlertProps = {
3
3
  children: React.ReactNode;
4
4
  variant?: AlertVariant;
5
5
  title?: string;
6
+ open?: boolean;
7
+ defaultOpen?: boolean;
8
+ showCloseButton?: boolean;
6
9
  onClose?: () => void;
7
10
  };
8
11
  export declare const Alert: React.FC<AlertProps>;
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { AlertCircleIcon, AlertTriangleIcon, CheckIcon, InfoIcon, } from "lucide-react";
2
+ import { AlertCircleIcon, AlertTriangleIcon, CheckIcon, InfoIcon, XIcon, } from "lucide-react";
3
3
  import styled from "styled-components";
4
+ import { useControlled } from "../Utilities";
4
5
  const Icons = {
5
6
  info: _jsx(InfoIcon, { size: 20 }),
6
7
  success: _jsx(CheckIcon, { size: 20 }),
@@ -9,14 +10,15 @@ const Icons = {
9
10
  default: _jsx(InfoIcon, { size: 20 }),
10
11
  };
11
12
  const StyledContainer = styled.div `
13
+ position: relative;
12
14
  display: flex;
13
15
  gap: 10px;
14
- padding: 15px;
16
+ padding: 15px 40px 15px 15px;
15
17
  border-radius: 4px;
16
18
 
17
- border: 1px solid ${({ theme, variant }) => theme.alert[variant].border};
18
- background-color: ${({ theme, variant }) => theme.alert[variant].background};
19
- color: ${({ theme, variant }) => theme.alert[variant].color};
19
+ border: 1px solid ${({ theme, $variant }) => theme.alert[$variant].border};
20
+ background-color: ${({ theme, $variant }) => theme.alert[$variant].background};
21
+ color: ${({ theme, $variant }) => theme.alert[$variant].color};
20
22
  `;
21
23
  const StyledTitle = styled.div `
22
24
  height: 25px;
@@ -26,7 +28,7 @@ const StyledTitle = styled.div `
26
28
  font-weight: bold;
27
29
  margin: 0px;
28
30
 
29
- color: ${({ theme, variant }) => { var _a; return (_a = theme.alert[variant]) === null || _a === void 0 ? void 0 : _a.color; }};
31
+ color: ${({ theme, $variant }) => { var _a; return (_a = theme.alert[$variant]) === null || _a === void 0 ? void 0 : _a.color; }};
30
32
  `;
31
33
  const StyledContent = styled.div `
32
34
  display: flex;
@@ -34,10 +36,11 @@ const StyledContent = styled.div `
34
36
  font-weight: 400;
35
37
  margin: 0px;
36
38
 
37
- color: ${({ theme, variant }) => theme.palette.text.primary};
39
+ color: ${({ theme }) => theme.palette.text.primary};
38
40
  `;
39
41
  const StyledContentContainer = styled.div `
40
42
  display: flex;
43
+ flex: 1;
41
44
  flex-direction: column;
42
45
  gap: 5px;
43
46
  `;
@@ -47,6 +50,44 @@ const StyledHeader = styled.div `
47
50
  height: 28px;
48
51
  align-items: center;
49
52
  `;
50
- export const Alert = ({ children, variant = "info", title, onClose, }) => {
51
- return (_jsxs(StyledContainer, { variant: variant, children: [_jsx(StyledHeader, { children: Icons[variant] }), _jsxs(StyledContentContainer, { children: [title && _jsx(StyledTitle, { variant: variant, children: title }), _jsx(StyledContent, { variant: variant, children: children })] })] }));
53
+ const StyledCloseButton = styled.button `
54
+ position: absolute;
55
+ top: 10px;
56
+ right: 10px;
57
+ border: none;
58
+ background: transparent;
59
+ display: inline-flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+ padding: 0;
63
+ cursor: pointer;
64
+ color: ${({ theme, $variant }) => theme.alert[$variant].color};
65
+ `;
66
+ const StyledCloseIconWrapper = styled.div `
67
+ display: inline-flex;
68
+ align-items: center;
69
+ justify-content: center;
70
+ padding: 4px;
71
+ border-radius: 8px;
72
+ background-color: transparent;
73
+ transition:
74
+ background-color 0.15s ease,
75
+ opacity 0.15s ease;
76
+
77
+ ${StyledCloseButton}:hover & {
78
+ ${({ $variant, theme }) => $variant === "default"
79
+ ? `background-color: ${theme.palette.action.hover};`
80
+ : `background-color: ${theme.alert[$variant].background};`}
81
+ }
82
+ `;
83
+ export const Alert = ({ children, variant = "info", title, open, defaultOpen = true, showCloseButton = false, onClose, }) => {
84
+ const [isVisible, setIsVisible] = useControlled(open, defaultOpen);
85
+ if (!isVisible) {
86
+ return null;
87
+ }
88
+ const handleClose = () => {
89
+ setIsVisible(false);
90
+ onClose === null || onClose === void 0 ? void 0 : onClose();
91
+ };
92
+ return (_jsxs(StyledContainer, { "$variant": variant, children: [_jsx(StyledHeader, { children: Icons[variant] }), _jsxs(StyledContentContainer, { children: [title && _jsx(StyledTitle, { "$variant": variant, children: title }), _jsx(StyledContent, { "$variant": variant, children: children })] }), showCloseButton && (_jsx(StyledCloseButton, { type: "button", "$variant": variant, "aria-label": "Close alert", onClick: handleClose, children: _jsx(StyledCloseIconWrapper, { "$variant": variant, children: _jsx(XIcon, { size: 16 }) }) }))] }));
52
93
  };
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from "react";
3
3
  import { Menu, MenuItemList, StyledInnerItemContainer } from "./components";
4
- export const DropDownMenu = ({ data, children, defaultValue, variant, arrow, size, searchable, loading, onScroll, onScrollToTop, onScrollToBottom, onSearch, manualSearch, multiselect, renderOption, onItemSelect, onChange, buttonProps, TooltipContent, dropDownProps, query, disabled, }) => {
4
+ export const DropDownMenu = ({ data, children, defaultValue, variant, arrow, size, searchable, grouped, onAddNew, loading, onScroll, onScrollToTop, onScrollToBottom, onSearch, manualSearch, multiselect, renderOption, onItemSelect, onChange, buttonProps, TooltipContent, dropDownProps, query, disabled, }) => {
5
5
  var _a;
6
6
  const isObjectArray = (_a = Object.keys((data === null || data === void 0 ? void 0 : data[0]) || {})) === null || _a === void 0 ? void 0 : _a.includes("label");
7
7
  const [selected, setSelected] = useState(defaultValue || []);
@@ -25,5 +25,5 @@ export const DropDownMenu = ({ data, children, defaultValue, variant, arrow, siz
25
25
  const handleScrollToBottom = (e) => {
26
26
  onScrollToBottom === null || onScrollToBottom === void 0 ? void 0 : onScrollToBottom(e);
27
27
  };
28
- return (_jsx(Menu, { label: children, disabled: disabled, arrow: arrow, buttonSize: size, variant: variant, multiselect: multiselect, buttonProps: buttonProps, onMenuClose: handleMenuClose, dropDownProps: dropDownProps, children: _jsxs(StyledInnerItemContainer, { children: [loading && _jsx("div", { children: "Loading..." }), !loading && (_jsx(MenuItemList, { menuItems: data, searchable: searchable, onSearch: onSearch, manualSearch: manualSearch, selected: selected, TooltipContent: TooltipContent, multiselect: multiselect, size: size, handleAddItem: handleAddItem, handleRemoveItem: handleRemoveItem, onItemSelect: onItemSelect, renderOption: renderOption, onScroll: onScroll, onScrollToTop: onScrollToTop, onScrollToBottom: handleScrollToBottom, query: query }))] }) }));
28
+ return (_jsx(Menu, { label: children, disabled: disabled, arrow: arrow, buttonSize: size, variant: variant, multiselect: multiselect, buttonProps: buttonProps, onMenuClose: handleMenuClose, dropDownProps: dropDownProps, children: _jsxs(StyledInnerItemContainer, { children: [loading && _jsx("div", { children: "Loading..." }), !loading && (_jsx(MenuItemList, { menuItems: data, searchable: searchable, grouped: grouped, onAddNew: onAddNew, onSearch: onSearch, manualSearch: manualSearch, selected: selected, TooltipContent: TooltipContent, multiselect: multiselect, size: size, handleAddItem: handleAddItem, handleRemoveItem: handleRemoveItem, onItemSelect: onItemSelect, renderOption: renderOption, onScroll: onScroll, onScrollToTop: onScrollToTop, onScrollToBottom: handleScrollToBottom, query: query }))] }) }));
29
29
  };
@@ -10,6 +10,8 @@ export declare const MenuItemList: React.FC<{
10
10
  selected?: DropDownItem[];
11
11
  TooltipContent?: ComponentType<any>;
12
12
  multiselect?: boolean;
13
+ grouped?: boolean;
14
+ onAddNew?: (value: string) => void;
13
15
  size?: Size;
14
16
  handleAddItem: (item: DropDownItem) => void;
15
17
  handleRemoveItem: (item: DropDownItem) => void;
@@ -13,6 +13,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
13
13
  import { useLayoutEffect, useRef, useState } from "react";
14
14
  import styled from "styled-components";
15
15
  import { FixedSizeList } from "react-window";
16
+ import { Plus } from "lucide-react";
16
17
  import CheckBox from "../../CheckBox";
17
18
  import { DropDownMenu } from "../DropDownMenu";
18
19
  import { MenuItem } from "./MenuItem";
@@ -30,11 +31,71 @@ const filterMenuItems = (menuItems, searchValue) => {
30
31
  return (_c = item.toLowerCase) === null || _c === void 0 ? void 0 : _c.call(item).includes(searchValue.toLowerCase());
31
32
  });
32
33
  };
34
+ const buildGroupedDisplayList = (items) => {
35
+ const groups = {};
36
+ for (const item of items) {
37
+ const key = item.group || "Other";
38
+ if (!groups[key])
39
+ groups[key] = [];
40
+ groups[key].push(item);
41
+ }
42
+ const sortedKeys = Object.keys(groups).sort((a, b) => a.localeCompare(b));
43
+ const result = [];
44
+ for (const key of sortedKeys) {
45
+ result.push({
46
+ _isGroupHeader: true,
47
+ label: key,
48
+ value: `__group__${key}`,
49
+ });
50
+ result.push(...groups[key]);
51
+ }
52
+ return result;
53
+ };
33
54
  const ListViewPort = styled.div.attrs({ className: "ListViewPort" }) `
34
55
  display: flex;
35
56
  flex-direction: column;
36
57
  `;
37
- export const MenuItemList = ({ menuItems, searchable, onSearch, manualSearch, selected, TooltipContent, multiselect, size, handleAddItem, handleRemoveItem, onItemSelect, renderOption, onScroll, onScrollToTop, onScrollToBottom, query, }) => {
58
+ const GroupHeader = styled.div `
59
+ display: flex;
60
+ align-items: center;
61
+ gap: 8px;
62
+ color: ${(props) => props.theme.palette.text.secondary};
63
+ font-weight: 500;
64
+ user-select: none;
65
+ padding: ${({ $size }) => $size === "xs"
66
+ ? "2px 8px"
67
+ : $size === "sm"
68
+ ? "4px 10px"
69
+ : $size === "md"
70
+ ? "4px 12px"
71
+ : $size === "lg"
72
+ ? "5px 14px"
73
+ : $size === "xl"
74
+ ? "6px 16px"
75
+ : "2px 8px"};
76
+ font-size: ${({ $size }) => $size === "xs"
77
+ ? "10px"
78
+ : $size === "sm"
79
+ ? "11px"
80
+ : $size === "md"
81
+ ? "13px"
82
+ : $size === "lg"
83
+ ? "15px"
84
+ : $size === "xl"
85
+ ? "17px"
86
+ : "10px"};
87
+
88
+ .group-line {
89
+ border-top: 1px solid ${(props) => props.theme.palette.divider};
90
+ flex: 1;
91
+ }
92
+
93
+ .group-label {
94
+ white-space: nowrap;
95
+ min-width: fit-content;
96
+ }
97
+ `;
98
+ export const MenuItemList = ({ menuItems, searchable, onSearch, manualSearch, selected, TooltipContent, multiselect, grouped, onAddNew, size, handleAddItem, handleRemoveItem, onItemSelect, renderOption, onScroll, onScrollToTop, onScrollToBottom, query, }) => {
38
99
  var _a;
39
100
  const [searchValue, setSearchValue] = useState("");
40
101
  const _b = query !== null && query !== void 0 ? query : {}, { queryKey, queryFn, getNextPageParam, initialPageParam } = _b, rest = __rest(_b, ["queryKey", "queryFn", "getNextPageParam", "initialPageParam"]);
@@ -69,6 +130,29 @@ export const MenuItemList = ({ menuItems, searchable, onSearch, manualSearch, se
69
130
  const filteredItems = searchable
70
131
  ? filterMenuItems(visibleItems, searchValue)
71
132
  : visibleItems;
133
+ const hasExactMatch = searchValue.trim() !== "" &&
134
+ filteredItems.some((item) => {
135
+ var _a, _b;
136
+ return ((_a = item === null || item === void 0 ? void 0 : item.label) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === searchValue.trim().toLowerCase() ||
137
+ ((_b = item === null || item === void 0 ? void 0 : item.value) === null || _b === void 0 ? void 0 : _b.toString().toLowerCase()) ===
138
+ searchValue.trim().toLowerCase();
139
+ });
140
+ const displayItems = (() => {
141
+ let items = grouped
142
+ ? buildGroupedDisplayList(filteredItems)
143
+ : filteredItems;
144
+ if (onAddNew && searchValue.trim() && !hasExactMatch) {
145
+ items = [
146
+ ...items,
147
+ {
148
+ _isAddNew: true,
149
+ label: `Add "${searchValue.trim()}"`,
150
+ value: searchValue.trim(),
151
+ },
152
+ ];
153
+ }
154
+ return items;
155
+ })();
72
156
  const isObjectArray = (_a = Object.keys((visibleItems === null || visibleItems === void 0 ? void 0 : visibleItems[0]) || {})) === null || _a === void 0 ? void 0 : _a.includes("label");
73
157
  const isLoading = isLoadingInfiniteQuery;
74
158
  const handleOnScroll = (event) => {
@@ -114,7 +198,7 @@ export const MenuItemList = ({ menuItems, searchable, onSearch, manualSearch, se
114
198
  }, [targetElm.current, isLoading]);
115
199
  const overscanCount = 10;
116
200
  const itemHeight = 25;
117
- const itemCount = (filteredItems === null || filteredItems === void 0 ? void 0 : filteredItems.length) || 0;
201
+ const itemCount = (displayItems === null || displayItems === void 0 ? void 0 : displayItems.length) || 0;
118
202
  const height = viewPortDimensions.height
119
203
  ? viewPortDimensions.height
120
204
  : itemCount * itemHeight < 200
@@ -134,8 +218,20 @@ export const MenuItemList = ({ menuItems, searchable, onSearch, manualSearch, se
134
218
  alignItems: "center",
135
219
  height: "100%",
136
220
  padding: "10px 0",
137
- }, children: [_jsx("div", { style: { fontSize: "12px" }, children: "Loading..." }), _jsx(Loader, {})] })), !isLoading && (_jsx(ListViewPort, { ref: targetElm, children: _jsx(FixedSizeList, { itemData: filteredItems, overscanCount: overscanCount, height: height, width: width, itemCount: itemCount, itemSize: itemHeight, outerRef: listElm, children: ({ data, index, style }) => {
138
- const item = (data === null || data === void 0 ? void 0 : data[index]) || {};
221
+ }, children: [_jsx("div", { style: { fontSize: "12px" }, children: "Loading..." }), _jsx(Loader, {})] })), !isLoading && (_jsx(ListViewPort, { ref: targetElm, children: _jsx(FixedSizeList, { itemData: displayItems, overscanCount: overscanCount, height: height, width: width, itemCount: itemCount, itemSize: itemHeight, outerRef: listElm, children: ({ data, index, style }) => {
222
+ const item = data === null || data === void 0 ? void 0 : data[index];
223
+ if (!item)
224
+ return null;
225
+ if (item._isGroupHeader) {
226
+ return (_jsxs(GroupHeader, { "$size": size, style: style, children: [_jsx("span", { className: "group-line" }), _jsx("span", { className: "group-label", children: item.label }), _jsx("span", { className: "group-line" })] }, item.value));
227
+ }
228
+ if (item._isAddNew) {
229
+ return (_jsx(MenuItem, { className: "MenuItem", size: size, leftSection: _jsx(Plus, { size: 14 }), onClick: (e) => {
230
+ e.preventDefault();
231
+ e.stopPropagation();
232
+ onAddNew === null || onAddNew === void 0 ? void 0 : onAddNew(item.value);
233
+ }, style: style, children: item.label }, "__add_new__"));
234
+ }
139
235
  const isSelected = !!(selected === null || selected === void 0 ? void 0 : selected.find((s) => {
140
236
  return isObjectArray ? (s === null || s === void 0 ? void 0 : s.value) === (item === null || item === void 0 ? void 0 : item.value) : s === item;
141
237
  }));
@@ -15,6 +15,7 @@ export type DropDownItem = {
15
15
  rightSection?: React.ReactNode;
16
16
  disabled?: boolean;
17
17
  visible?: boolean;
18
+ group?: string;
18
19
  };
19
20
  export type SearchInputProps = React.ComponentPropsWithoutRef<typeof Input>;
20
21
  export type StyledContentProps = {
@@ -42,6 +43,8 @@ export type DropDownMenuProps = {
42
43
  onSearch?: (value: string) => void;
43
44
  searchable?: boolean;
44
45
  manualSearch?: boolean;
46
+ grouped?: boolean;
47
+ onAddNew?: (value: string) => void;
45
48
  loading?: boolean;
46
49
  arrow?: boolean;
47
50
  dropDownProps?: ComponentPropsWithoutRef<typeof StyledContent>;
@@ -58,6 +58,7 @@ const StyledContent = styled.div `
58
58
  const StyledInnerContent = styled.div `
59
59
  display: flex;
60
60
  flex-direction: column;
61
+ flex: 1 1 auto;
61
62
 
62
63
  overflow-y: auto;
63
64
  padding: 25px;
@@ -20,13 +20,13 @@ export type Operator = {
20
20
  label: string;
21
21
  value: string;
22
22
  };
23
- export type EditorType = "text" | "select" | "checkbox" | "radio" | "multiselect" | "date" | "time" | null;
23
+ export type InputType = "text" | "number" | "date" | "datetime" | "multiselect";
24
24
  export interface FilterDefinition {
25
25
  dataField: string;
26
26
  label: string;
27
27
  pluralLabel?: string;
28
28
  operators?: Operator[];
29
- inputType?: HTMLInputElement["type"];
29
+ inputType?: InputType;
30
30
  resolution?: "day" | "second" | "millisecond";
31
31
  isoString?: boolean;
32
32
  placeholder?: string;
@@ -34,7 +34,6 @@ export interface FilterDefinition {
34
34
  dropDownOptions?: {
35
35
  style?: React.CSSProperties;
36
36
  };
37
- editorType?: EditorType;
38
37
  query?: DropDownMenuProps["query"];
39
38
  }
40
39
  export interface Rule {
@@ -5,6 +5,6 @@ import useTable from "./useTable";
5
5
  const StaticRows = ({ targetElm, listElm }) => {
6
6
  var _a;
7
7
  const { data, loadingRowIds, keyField } = useTable();
8
- return (_jsx(TBody, { className: "mfui-tbody", children: _jsx(TableViewPort, { className: "mfui-tbody-viewport", ref: targetElm, children: _jsx(TableListElement, { className: "mfui-tbody-list", ref: listElm, children: (_a = data === null || data === void 0 ? void 0 : data.map) === null || _a === void 0 ? void 0 : _a.call(data, (row, index) => (_jsx(TableRow, { rowData: row, loading: !!keyField ? loadingRowIds === null || loadingRowIds === void 0 ? void 0 : loadingRowIds.includes(row[keyField]) : false }, index))) }) }) }));
8
+ return (_jsx(TBody, { className: "mfui-tbody", children: _jsx(TableViewPort, { className: "mfui-tbody-viewport", ref: targetElm, children: _jsx(TableListElement, { className: "mfui-tbody-list", ref: listElm, children: (_a = data === null || data === void 0 ? void 0 : data.map) === null || _a === void 0 ? void 0 : _a.call(data, (row) => (_jsx(TableRow, { rowData: row, loading: !!keyField ? loadingRowIds === null || loadingRowIds === void 0 ? void 0 : loadingRowIds.includes(row[keyField]) : false }, keyField ? row[keyField] : row.__key))) }) }) }));
9
9
  };
10
10
  export default StaticRows;
@@ -9,14 +9,14 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
12
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
14
14
  import { useOverlayScrollbars } from "overlayscrollbars-react";
15
15
  import { StyledTable } from "./TableComponents";
16
16
  import TableHeader from "./TableHeader";
17
17
  import TableProvider from "./TableProvider";
18
18
  import shortUUID from "short-uuid";
19
- import VirtualizedRows from "./VirtualIzedRows";
19
+ import VirtualizedRows from "./VirtualizedRows";
20
20
  import StaticRows from "./StaticRows";
21
21
  import TableMenu from "./TableMenu";
22
22
  import useTable from "./useTable";
@@ -37,7 +37,7 @@ const TableContent = ({ children, }) => {
37
37
  height: tableHeight || "100%",
38
38
  maxHeight: tableMaxHeight,
39
39
  minHeight: tableMinHeight,
40
- }, ref: tableElement, "data-compact": compactState, children: [_jsx(LoadingIndicator, { visible: loading }), _jsx(TableHeader, { headerRowElm: headerRowElm }), visibleColumnCount === 0 && _jsx(_Fragment, {}), virtualized === true ? (_jsx(VirtualizedRows, { tableDimensions: tableDimensions, targetElm: targetElm, listElm: listElm, rowHeight: rowHeight, headerRowHeight: headerRowHeight })) : (_jsx(StaticRows, { targetElm: targetElm, listElm: listElm }))] })] }));
40
+ }, ref: tableElement, "data-compact": compactState, children: [_jsx(LoadingIndicator, { visible: loading }), _jsx(TableHeader, { headerRowElm: headerRowElm }), visibleColumnCount === 0 && _jsx("div", { children: "No columns visible" }), virtualized === true ? (_jsx(VirtualizedRows, { tableDimensions: tableDimensions, targetElm: targetElm, listElm: listElm, rowHeight: rowHeight, headerRowHeight: headerRowHeight })) : (_jsx(StaticRows, { targetElm: targetElm, listElm: listElm }))] })] }));
41
41
  };
42
42
  export const Table = (_a) => {
43
43
  var { data, columnProps, children } = _a, props = __rest(_a, ["data", "columnProps", "children"]) // pass through props straight to table context
@@ -109,6 +109,22 @@ export const Table = (_a) => {
109
109
  resizeObserver.unobserve(element);
110
110
  };
111
111
  }, []);
112
- const __data = useMemo(() => data === null || data === void 0 ? void 0 : data.map((d, i) => (Object.assign(Object.assign({}, d), { __key: shortUUID.generate(), __index: i }))), [data]);
112
+ // Persistent cache mapping each row object to a stable UUID.
113
+ // Uses a WeakMap so entries are automatically garbage collected
114
+ // when their corresponding row objects are no longer referenced.
115
+ const uuidCache = useRef(new WeakMap());
116
+ // Augment each row with a stable __key (UUID) and __index.
117
+ // The WeakMap ensures that the same row object always receives
118
+ // the same UUID across re-renders, preventing unnecessary DOM
119
+ // reconciliation. useMemo preserves referential stability of
120
+ // the output array when the data reference hasn't changed.
121
+ const __data = useMemo(() => data === null || data === void 0 ? void 0 : data.map((d, i) => {
122
+ let key = uuidCache.current.get(d);
123
+ if (!key) {
124
+ key = shortUUID.uuid();
125
+ uuidCache.current.set(d, key);
126
+ }
127
+ return Object.assign(Object.assign({}, d), { __key: key, __index: i });
128
+ }), [data]);
113
129
  return (_jsx(TableProvider, Object.assign({ columns: columnProps, data: __data, tableElement: tableElement, headerRowElm: headerRowElm, tableDimensions: tableDimensions, targetElm: targetElm, listElm: listElm }, props, { children: _jsx(TableContent, { children: children }) })));
114
130
  };
@@ -29,7 +29,7 @@ const FlexedRow = styled.div `
29
29
  }
30
30
  `;
31
31
  const TableMenu = () => {
32
- var _a, _b, _c, _d;
32
+ var _a, _b, _c, _d, _e;
33
33
  const { data, columnState, searchState, toggleColumnVisibility, tableMenuOptions, runSearch, enableSelection, compactState, toggleCompact, totalRecords, getCalculatedSelectionTotal, filterState, handleFilterChange, clearSearch, } = useTable();
34
34
  const inputRef = useRef(null);
35
35
  if ((tableMenuOptions === null || tableMenuOptions === void 0 ? void 0 : tableMenuOptions.enabled) !== true)
@@ -38,7 +38,7 @@ const TableMenu = () => {
38
38
  const queryFilter = useQueryFilter({
39
39
  defaultFilter: filterState,
40
40
  filterDefinitions: (filterOptions === null || filterOptions === void 0 ? void 0 : filterOptions.filterDefinitions) || [],
41
- showCombinator: true,
41
+ showCombinator: (_a = filterOptions === null || filterOptions === void 0 ? void 0 : filterOptions.showCombinator) !== null && _a !== void 0 ? _a : true,
42
42
  onFilterChange: (q) => {
43
43
  var _a;
44
44
  handleFilterChange(q);
@@ -81,13 +81,13 @@ const TableMenu = () => {
81
81
  inputRef.current.value = "";
82
82
  }
83
83
  }, [searchState]);
84
- return (_jsxs(StyledContainer, { children: [_jsxs(FlexedRow, { className: "justify-sb", children: [_jsxs(FlexedRow, { children: [(addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.enabled) === true &&
84
+ return (_jsxs(StyledContainer, { className: "mfui-table-menu", children: [_jsxs(FlexedRow, { className: "justify-sb", children: [_jsxs(FlexedRow, { children: [(addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.enabled) === true &&
85
85
  ((addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.type) === "button" ||
86
- (addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.type) === undefined) && (_jsx(Button, Object.assign({ color: "primary", variant: "contained", size: "xxs", onClick: () => { var _a; return (_a = addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.onClick) === null || _a === void 0 ? void 0 : _a.call(addButtonOptions); } }, addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.buttonOptions, { children: ((_a = tableMenuOptions === null || tableMenuOptions === void 0 ? void 0 : tableMenuOptions.addButtonOptions) === null || _a === void 0 ? void 0 : _a.label) || "+ Add Record" }))), (addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.enabled) === true &&
86
+ (addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.type) === undefined) && (_jsx(Button, Object.assign({ color: "primary", variant: "contained", size: "xxs", onClick: () => { var _a; return (_a = addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.onClick) === null || _a === void 0 ? void 0 : _a.call(addButtonOptions); } }, addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.buttonOptions, { children: ((_b = tableMenuOptions === null || tableMenuOptions === void 0 ? void 0 : tableMenuOptions.addButtonOptions) === null || _b === void 0 ? void 0 : _b.label) || "+ Add Record" }))), (addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.enabled) === true &&
87
87
  (addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.type) === "menu" && (_jsx(DropDownMenu, Object.assign({ data: [], variant: "contained", arrow: true, size: "xxs", buttonProps: {
88
88
  color: "primary",
89
89
  size: "xxs",
90
- } }, addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.menuOptions, { children: ((_b = tableMenuOptions === null || tableMenuOptions === void 0 ? void 0 : tableMenuOptions.addButtonOptions) === null || _b === void 0 ? void 0 : _b.label) || "Options" }))), (filterOptions === null || filterOptions === void 0 ? void 0 : filterOptions.enabled) === true && (_jsx(DropDownMenu, { variant: "outlined", size: "xs", data: ((_c = filterOptions === null || filterOptions === void 0 ? void 0 : filterOptions.filterDefinitions) === null || _c === void 0 ? void 0 : _c.map((filter) => ({
90
+ } }, addButtonOptions === null || addButtonOptions === void 0 ? void 0 : addButtonOptions.menuOptions, { children: ((_c = tableMenuOptions === null || tableMenuOptions === void 0 ? void 0 : tableMenuOptions.addButtonOptions) === null || _c === void 0 ? void 0 : _c.label) || "Options" }))), (filterOptions === null || filterOptions === void 0 ? void 0 : filterOptions.enabled) === true && (_jsx(DropDownMenu, { variant: "outlined", size: "xs", data: ((_d = filterOptions === null || filterOptions === void 0 ? void 0 : filterOptions.filterDefinitions) === null || _d === void 0 ? void 0 : _d.map((filter) => ({
91
91
  label: filter.label,
92
92
  value: filter.dataField,
93
93
  data: filter,
@@ -131,6 +131,6 @@ const TableMenu = () => {
131
131
  style: { padding: "0px 4px", height: 24 },
132
132
  }, dropDownProps: {
133
133
  style: { width: 175, maxWidth: 400 },
134
- }, children: _jsx(Columns3Icon, { size: 14 }) })), (searchOptions === null || searchOptions === void 0 ? void 0 : searchOptions.enabled) === true && (_jsx(TextInput, { ref: inputRef, size: "xs", placeholder: ((_d = tableMenuOptions === null || tableMenuOptions === void 0 ? void 0 : tableMenuOptions.searchOptions) === null || _d === void 0 ? void 0 : _d.placeholder) || "Search", defaultValue: searchState, onChange: handleSearch }))] })] }), _jsx(QueryFilter, { queryFilter: queryFilter })] }));
134
+ }, children: _jsx(Columns3Icon, { size: 14 }) })), (searchOptions === null || searchOptions === void 0 ? void 0 : searchOptions.enabled) === true && (_jsx(TextInput, { ref: inputRef, size: "xs", placeholder: ((_e = tableMenuOptions === null || tableMenuOptions === void 0 ? void 0 : tableMenuOptions.searchOptions) === null || _e === void 0 ? void 0 : _e.placeholder) || "Search", defaultValue: searchState, onChange: handleSearch }))] })] }), _jsx(QueryFilter, { queryFilter: queryFilter })] }));
135
135
  };
136
136
  export default TableMenu;