@monolith-forensics/monolith-ui 1.4.1 → 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.
- package/dist/DropDownMenu/DropDownMenu.js +2 -2
- package/dist/DropDownMenu/components/MenuItemList.d.ts +2 -0
- package/dist/DropDownMenu/components/MenuItemList.js +100 -4
- package/dist/DropDownMenu/types.d.ts +3 -0
- package/dist/TextAreaInput/TextAreaInput.d.ts +15 -7
- package/dist/TextAreaInput/TextAreaInput.js +45 -105
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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 = (
|
|
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:
|
|
138
|
-
const item =
|
|
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>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Size } from "../core";
|
|
3
|
-
import {
|
|
3
|
+
import { DropDownMenuProps } from "../DropDownMenu/types";
|
|
4
4
|
export type InsertableItem = {
|
|
5
5
|
label: string;
|
|
6
6
|
value: string;
|
|
7
|
+
group?: string;
|
|
7
8
|
};
|
|
8
9
|
export interface TextAreaInputProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
9
10
|
variant?: "contained" | "filled" | "outlined" | "text";
|
|
@@ -19,14 +20,21 @@ export interface TextAreaInputProps extends React.TextareaHTMLAttributes<HTMLTex
|
|
|
19
20
|
onHeightChange?: (height: number, meta: {
|
|
20
21
|
rowHeight: number;
|
|
21
22
|
}) => void;
|
|
22
|
-
showActionMenu?: boolean;
|
|
23
|
-
actionMenuOptions?: Array<{
|
|
24
|
-
value: string;
|
|
25
|
-
label: string;
|
|
26
|
-
}>;
|
|
27
|
-
onActionMenuSelect?: (item: DropDownItem) => void;
|
|
28
23
|
insertableItems?: InsertableItem[];
|
|
29
24
|
onInsertItem?: (item: InsertableItem) => void;
|
|
25
|
+
groupInsertableItems?: boolean;
|
|
26
|
+
/** Callback when the user creates a new item by typing a value in the search box that doesn't match any existing option. */
|
|
27
|
+
onAddNewItem?: (value: string) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Visual style of the insert menu trigger.
|
|
30
|
+
* - `"ellipsis"` renders a minimal `...` icon button.
|
|
31
|
+
* - `"dropdown"` renders an outlined button with a label and arrow (default).
|
|
32
|
+
*/
|
|
33
|
+
insertMenuVariant?: "ellipsis" | "dropdown";
|
|
34
|
+
/** Label for the insert dropdown trigger button. Only used when `insertMenuVariant` is `"dropdown"`. Defaults to "Insert". */
|
|
35
|
+
insertMenuLabel?: string;
|
|
36
|
+
/** Additional props forwarded to the DropDownMenu component. */
|
|
37
|
+
insertMenuProps?: Partial<DropDownMenuProps>;
|
|
30
38
|
}
|
|
31
39
|
declare const TextAreaInput: React.ForwardRefExoticComponent<TextAreaInputProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
32
40
|
export default TextAreaInput;
|
|
@@ -11,34 +11,9 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
13
|
import styled from "styled-components";
|
|
14
|
-
import { forwardRef,
|
|
15
|
-
import { TextArea, FieldLabel, DropDownMenu
|
|
14
|
+
import { forwardRef, useRef, useMemo } from "react";
|
|
15
|
+
import { TextArea, FieldLabel, DropDownMenu } from "..";
|
|
16
16
|
import { MoreHorizontal } from "lucide-react";
|
|
17
|
-
const DEFAULT_ACTIONS = [
|
|
18
|
-
{ value: "clear", label: "Clear Text" },
|
|
19
|
-
{ value: "insert", label: "Insert Item" },
|
|
20
|
-
];
|
|
21
|
-
const TextAreaWrapper = styled.div `
|
|
22
|
-
position: relative;
|
|
23
|
-
`;
|
|
24
|
-
const InsertMenuOverlay = styled.div `
|
|
25
|
-
position: absolute;
|
|
26
|
-
top: 0;
|
|
27
|
-
left: 0;
|
|
28
|
-
right: 0;
|
|
29
|
-
z-index: 10;
|
|
30
|
-
opacity: ${({ $visible }) => ($visible ? 1 : 0)};
|
|
31
|
-
pointer-events: ${({ $visible }) => ($visible ? "auto" : "none")};
|
|
32
|
-
transform: ${({ $visible }) => $visible ? "translateY(0)" : "translateY(-4px)"};
|
|
33
|
-
transition:
|
|
34
|
-
opacity 0.2s ease,
|
|
35
|
-
transform 0.2s ease;
|
|
36
|
-
`;
|
|
37
|
-
const StyledInsertSelectBox = styled(SelectBox) `
|
|
38
|
-
width: 100%;
|
|
39
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
40
|
-
border: 1px solid ${({ theme }) => theme.palette.primary.main};
|
|
41
|
-
`;
|
|
42
17
|
const StyledMoreHorizontal = styled(MoreHorizontal) `
|
|
43
18
|
color: ${({ theme }) => theme.palette.text.secondary};
|
|
44
19
|
&:hover {
|
|
@@ -46,21 +21,8 @@ const StyledMoreHorizontal = styled(MoreHorizontal) `
|
|
|
46
21
|
}
|
|
47
22
|
`;
|
|
48
23
|
const TextAreaInput = forwardRef((props, ref) => {
|
|
49
|
-
const {
|
|
50
|
-
// UI
|
|
51
|
-
label, error, required, colSpan = 1, size = "sm", description, maxRows = 6, minRows = 3, onHeightChange, cacheMeasurements,
|
|
52
|
-
// Action menu
|
|
53
|
-
showActionMenu = false, actionMenuOptions = DEFAULT_ACTIONS, onActionMenuSelect,
|
|
54
|
-
// Insertable items
|
|
55
|
-
insertableItems, onInsertItem } = props,
|
|
56
|
-
// Rest of props for TextArea
|
|
57
|
-
rest = __rest(props, ["label", "error", "required", "colSpan", "size", "description", "maxRows", "minRows", "onHeightChange", "cacheMeasurements", "showActionMenu", "actionMenuOptions", "onActionMenuSelect", "insertableItems", "onInsertItem"]);
|
|
58
|
-
// State for insert menu visibility
|
|
59
|
-
const [showInsertMenu, setShowInsertMenu] = useState(false);
|
|
60
|
-
const [triggerSelectBoxOpen, setTriggerSelectBoxOpen] = useState(false);
|
|
24
|
+
const { label, error, required, colSpan = 1, size = "sm", description, maxRows = 6, minRows = 3, onHeightChange, cacheMeasurements, insertableItems, onInsertItem, groupInsertableItems, onAddNewItem, insertMenuVariant = "dropdown", insertMenuLabel = "Insert", insertMenuProps } = props, rest = __rest(props, ["label", "error", "required", "colSpan", "size", "description", "maxRows", "minRows", "onHeightChange", "cacheMeasurements", "insertableItems", "onInsertItem", "groupInsertableItems", "onAddNewItem", "insertMenuVariant", "insertMenuLabel", "insertMenuProps"]);
|
|
61
25
|
const textareaRef = useRef(null);
|
|
62
|
-
const insertMenuRef = useRef(null);
|
|
63
|
-
// Merge refs
|
|
64
26
|
const mergedRef = (node) => {
|
|
65
27
|
textareaRef.current = node;
|
|
66
28
|
if (typeof ref === "function") {
|
|
@@ -70,79 +32,50 @@ const TextAreaInput = forwardRef((props, ref) => {
|
|
|
70
32
|
ref.current = node;
|
|
71
33
|
}
|
|
72
34
|
};
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
35
|
+
const dropdownData = useMemo(() => (insertableItems || []).map((item) => ({
|
|
36
|
+
label: item.label,
|
|
37
|
+
value: item.value,
|
|
38
|
+
group: item.group,
|
|
39
|
+
})), [insertableItems]);
|
|
40
|
+
const insertAtCursor = (text) => {
|
|
41
|
+
var _a;
|
|
42
|
+
const textarea = textareaRef.current;
|
|
43
|
+
if (!textarea)
|
|
76
44
|
return;
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
45
|
+
const start = textarea.selectionStart;
|
|
46
|
+
const end = textarea.selectionEnd;
|
|
47
|
+
const currentValue = textarea.value;
|
|
48
|
+
const newValue = currentValue.slice(0, start) + text + currentValue.slice(end);
|
|
49
|
+
const nativeSet = (_a = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, "value")) === null || _a === void 0 ? void 0 : _a.set;
|
|
50
|
+
nativeSet === null || nativeSet === void 0 ? void 0 : nativeSet.call(textarea, newValue);
|
|
51
|
+
textarea.dispatchEvent(new Event("input", { bubbles: true }));
|
|
52
|
+
textarea.focus();
|
|
53
|
+
textarea.setSelectionRange(start + text.length, start + text.length);
|
|
54
|
+
};
|
|
55
|
+
const handleItemSelect = (item) => {
|
|
56
|
+
const insertable = {
|
|
57
|
+
label: item.label,
|
|
58
|
+
value: String(item.value),
|
|
59
|
+
group: item.group,
|
|
86
60
|
};
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (item.value === "insert" && (insertableItems === null || insertableItems === void 0 ? void 0 : insertableItems.length)) {
|
|
90
|
-
setShowInsertMenu(true);
|
|
91
|
-
// Trigger SelectBox to open using the new enhanced props
|
|
92
|
-
setTriggerSelectBoxOpen(true);
|
|
93
|
-
}
|
|
94
|
-
else if (item.value === "clear") {
|
|
95
|
-
// Built-in clear functionality
|
|
96
|
-
const textarea = textareaRef.current;
|
|
97
|
-
if (textarea) {
|
|
98
|
-
textarea.value = "";
|
|
99
|
-
textarea.focus();
|
|
100
|
-
// Trigger change event so controlled components update
|
|
101
|
-
const event = new Event("input", { bubbles: true });
|
|
102
|
-
textarea.dispatchEvent(event);
|
|
103
|
-
}
|
|
104
|
-
onActionMenuSelect === null || onActionMenuSelect === void 0 ? void 0 : onActionMenuSelect(item);
|
|
61
|
+
if (onInsertItem) {
|
|
62
|
+
onInsertItem(insertable);
|
|
105
63
|
}
|
|
106
64
|
else {
|
|
107
|
-
|
|
65
|
+
insertAtCursor(insertable.value);
|
|
108
66
|
}
|
|
109
67
|
};
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
};
|
|
114
|
-
const handleInsertSelect = (value, option) => {
|
|
115
|
-
console.log("Selected value:", value, "Selected option:", option); // Debug log
|
|
116
|
-
// SelectBox passes (value, option) - we want the full option object
|
|
117
|
-
const item = option;
|
|
118
|
-
if (!item || !item.value) {
|
|
119
|
-
console.warn("Invalid item selected:", item);
|
|
120
|
-
setShowInsertMenu(false);
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
if (onInsertItem) {
|
|
124
|
-
onInsertItem(item);
|
|
68
|
+
const handleAddNew = (value) => {
|
|
69
|
+
if (onAddNewItem) {
|
|
70
|
+
onAddNewItem(value);
|
|
125
71
|
}
|
|
126
72
|
else {
|
|
127
|
-
|
|
128
|
-
const textarea = textareaRef.current;
|
|
129
|
-
if (textarea) {
|
|
130
|
-
const start = textarea.selectionStart;
|
|
131
|
-
const end = textarea.selectionEnd;
|
|
132
|
-
const currentValue = textarea.value;
|
|
133
|
-
const newValue = currentValue.slice(0, start) + item.value + currentValue.slice(end);
|
|
134
|
-
textarea.value = newValue;
|
|
135
|
-
textarea.focus();
|
|
136
|
-
textarea.setSelectionRange(start + item.value.length, start + item.value.length);
|
|
137
|
-
// Trigger change event
|
|
138
|
-
const event = new Event("input", { bubbles: true });
|
|
139
|
-
textarea.dispatchEvent(event);
|
|
140
|
-
}
|
|
73
|
+
insertAtCursor(value);
|
|
141
74
|
}
|
|
142
|
-
setShowInsertMenu(false);
|
|
143
75
|
};
|
|
144
|
-
|
|
145
|
-
|
|
76
|
+
const hasInsertableItems = !!dropdownData.length;
|
|
77
|
+
return (_jsxs("div", { style: { gridColumn: `span ${colSpan}`, height: "fit-content" }, children: [label && (_jsx(FieldLabel, { asterisk: required, error: error, description: description, size: size, actionComponent: hasInsertableItems ? (insertMenuVariant === "ellipsis" ? (_jsx(DropDownMenu, Object.assign({ data: dropdownData, variant: "text", size: "xs", arrow: false, searchable: true, grouped: groupInsertableItems, onAddNew: handleAddNew, onItemSelect: handleItemSelect, buttonProps: {
|
|
78
|
+
"aria-label": "Insert item",
|
|
146
79
|
style: {
|
|
147
80
|
minWidth: "auto",
|
|
148
81
|
border: "none",
|
|
@@ -152,7 +85,14 @@ const TextAreaInput = forwardRef((props, ref) => {
|
|
|
152
85
|
height: 16,
|
|
153
86
|
width: 16,
|
|
154
87
|
},
|
|
155
|
-
},
|
|
88
|
+
}, dropDownProps: {
|
|
89
|
+
style: { width: 200, maxWidth: 400 },
|
|
90
|
+
} }, insertMenuProps, { children: _jsx(StyledMoreHorizontal, { size: 16 }) }))) : (_jsx(DropDownMenu, Object.assign({ data: dropdownData, variant: "outlined", size: "xs", arrow: true, searchable: true, grouped: groupInsertableItems, onAddNew: handleAddNew, onItemSelect: handleItemSelect, buttonProps: {
|
|
91
|
+
title: insertMenuLabel,
|
|
92
|
+
size: "xxs",
|
|
93
|
+
}, dropDownProps: {
|
|
94
|
+
style: { width: 200, maxWidth: 400 },
|
|
95
|
+
} }, insertMenuProps, { children: insertMenuLabel })))) : null, children: label })), _jsx(TextArea, Object.assign({ ref: mergedRef, size: size, maxRows: maxRows, minRows: minRows, onHeightChange: onHeightChange, cacheMeasurements: cacheMeasurements }, rest))] }));
|
|
156
96
|
});
|
|
157
97
|
TextAreaInput.displayName = "TextAreaInput";
|
|
158
98
|
export default TextAreaInput;
|