@monolith-forensics/monolith-ui 1.3.91 → 1.3.92

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.
@@ -7,7 +7,7 @@ interface InfoComponentProps {
7
7
  label?: string | ReactNode;
8
8
  }
9
9
  export declare const InfoComponent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<InfoComponentProps, never>> & string & Omit<({ className, children, description, label }: InfoComponentProps) => string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined, keyof import("react").Component<any, {}, any>>;
10
- interface FieldLabelProps {
10
+ export interface FieldLabelProps {
11
11
  className?: string;
12
12
  children?: ReactNode;
13
13
  error?: string;
@@ -15,6 +15,7 @@ interface FieldLabelProps {
15
15
  size?: Size;
16
16
  asterisk?: boolean;
17
17
  style?: React.CSSProperties;
18
+ actionComponent?: ReactNode;
18
19
  }
19
- declare const FieldLabel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<FieldLabelProps, never>> & string & Omit<({ className, children, error, description, size, style, }: FieldLabelProps) => import("react/jsx-runtime").JSX.Element, keyof import("react").Component<any, {}, any>>;
20
+ declare const FieldLabel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<FieldLabelProps, never>> & string & Omit<({ className, children, error, description, size, style, actionComponent, }: FieldLabelProps) => import("react/jsx-runtime").JSX.Element, keyof import("react").Component<any, {}, any>>;
20
21
  export default FieldLabel;
@@ -24,22 +24,38 @@ export const InfoComponent = styled(({ className, children, description, label }
24
24
  margin-bottom: 5px;
25
25
  }
26
26
  `;
27
- const FieldLabel = styled(({ className, children, error, description, size = "sm", style, }) => {
28
- return (_jsxs("div", { className: className + " FieldLabel", style: style, children: [_jsx(InfoComponent, { description: description, label: children, children: _jsx("div", { className: "label", children: children }) }), error && (_jsx("div", { className: "error", title: error, children: error || "Invalid Value" }))] }));
27
+ const FieldLabel = styled(({ className, children, error, description, size = "sm", style, actionComponent, }) => {
28
+ return (_jsxs("div", { className: className + " FieldLabel", style: style, children: [_jsxs("div", { className: "label-content", children: [_jsx(InfoComponent, { description: description, label: children, children: _jsx("div", { className: "label", children: children }) }), error && (_jsx("div", { className: "error", title: error, children: error || "Invalid Value" }))] }), actionComponent && (_jsx("div", { className: "action-section", children: actionComponent }))] }));
29
29
  }) `
30
30
  user-select: none;
31
- font-family: apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
32
- "Helvetica Neue", Arial, sans-serif;
31
+ font-family:
32
+ apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
33
+ Arial, sans-serif;
33
34
  user-select: none;
34
35
  display: flex;
35
36
  flex-direction: row;
36
- align-items: baseline;
37
- gap: 5px;
37
+ align-items: flex-start;
38
+ justify-content: space-between;
39
+ width: 100%;
38
40
 
39
41
  min-height: 15px;
40
42
  font-weight: 400;
41
43
  margin-bottom: 2.5px;
42
44
 
45
+ .label-content {
46
+ display: flex;
47
+ flex-direction: row;
48
+ align-items: baseline;
49
+ gap: 5px;
50
+ flex: 1;
51
+ }
52
+
53
+ .action-section {
54
+ display: flex;
55
+ align-items: center;
56
+ margin-left: 8px;
57
+ }
58
+
43
59
  font-size: ${({ size = "sm" }) => size === "xs"
44
60
  ? "10px"
45
61
  : size === "sm"
@@ -1 +1,2 @@
1
1
  export { default } from "./FieldLabel";
2
+ export type { FieldLabelProps } from "./FieldLabel";
@@ -0,0 +1,25 @@
1
+ export interface SearchableTextAreaProps {
2
+ label?: string;
3
+ data?: Array<{
4
+ label: string;
5
+ value: string;
6
+ }>;
7
+ searchable?: boolean;
8
+ allowCustomValue?: boolean;
9
+ required?: boolean;
10
+ error?: string;
11
+ description?: string;
12
+ value?: string;
13
+ onChange?: (value: string) => void;
14
+ selectProps?: Record<string, any>;
15
+ textAreaPlaceholder?: string;
16
+ textAreaMinRows?: number;
17
+ textAreaMaxRows?: number;
18
+ textAreaProps?: Record<string, any>;
19
+ initialValue?: string;
20
+ }
21
+ declare function SearchableTextArea({ label, data, searchable, allowCustomValue, required, error, description, selectProps, value, onChange, textAreaPlaceholder, textAreaMinRows, textAreaMaxRows, textAreaProps, initialValue, }: SearchableTextAreaProps): import("react/jsx-runtime").JSX.Element;
22
+ declare namespace SearchableTextArea {
23
+ var displayName: string;
24
+ }
25
+ export default SearchableTextArea;
@@ -0,0 +1,153 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useRef } from "react";
3
+ import styled from "styled-components";
4
+ import { MoreHorizontal } from "lucide-react";
5
+ import { SelectBox } from "../SelectBox";
6
+ import FieldLabel from "../FieldLabel";
7
+ import DropDownMenu from "../DropDownMenu";
8
+ // Wrapper components for layout
9
+ const CombinedInputWrapper = styled.div `
10
+ display: flex;
11
+ flex-direction: column;
12
+ width: 100%;
13
+ position: relative;
14
+ `;
15
+ const TextAreaRow = styled.div `
16
+ position: relative;
17
+ display: flex;
18
+ align-items: flex-start;
19
+ width: 100%;
20
+ `;
21
+ const SelectBoxWrapper = styled.div `
22
+ position: relative;
23
+ width: 100%;
24
+ `;
25
+ const StyledSelectBox = styled(SelectBox) `
26
+ /* Completely hide the SelectBox but keep it functional for dropdown */
27
+ position: absolute;
28
+ top: 0;
29
+ left: 0;
30
+ width: 100%;
31
+ opacity: 0;
32
+ pointer-events: auto; /* Allow interactions for dropdown */
33
+ z-index: -1;
34
+ `;
35
+ const StyledFieldLabel = styled(FieldLabel) `
36
+ .action-section {
37
+ margin-left: 2px !important; /* Reduce spacing from default 8px */
38
+ }
39
+
40
+ .label-content {
41
+ gap: 2px !important; /* Reduce gap from default 5px */
42
+ }
43
+ `;
44
+ // Styled TextArea that is now the primary input
45
+ const StyledTextArea = styled.textarea `
46
+ border: 1px solid
47
+ ${({ theme, $hasError }) => $hasError ? theme.palette.error.main : theme.palette.input.border};
48
+ border-radius: 4px;
49
+ padding: 10px;
50
+ font-family: ${({ theme }) => theme.typography.fontFamily};
51
+ font-size: 13px;
52
+ background-color: ${({ theme }) => theme.palette.input.background};
53
+ color: ${({ theme }) => theme.palette.text.primary};
54
+ resize: none;
55
+ outline: none;
56
+ transition: border-color 0.2s ease;
57
+ width: 100%;
58
+ min-height: ${({ $minRows = 3 }) => $minRows * 1.5 + 1.5}em;
59
+ ${({ $maxRows }) => $maxRows && `max-height: ${$maxRows * 1.5 + 1.5}em;`}
60
+ pointer-events: auto;
61
+ user-select: text;
62
+ z-index: 2;
63
+ position: relative;
64
+
65
+ &:focus {
66
+ border-color: ${({ theme }) => theme.palette.primary.main};
67
+ z-index: 3;
68
+ }
69
+
70
+ &::placeholder {
71
+ color: ${({ theme }) => theme.palette.text.secondary};
72
+ opacity: 0.5;
73
+ }
74
+ `;
75
+ function SearchableTextArea({ label, data, searchable, allowCustomValue, required, error, description, selectProps = {}, value, onChange, textAreaPlaceholder, textAreaMinRows = 3, textAreaMaxRows, textAreaProps = {}, initialValue = "", }) {
76
+ // Use controlled value if provided, otherwise use internal state
77
+ const [internalValue, setInternalValue] = useState(initialValue);
78
+ const [selectValue, setSelectValue] = useState(null);
79
+ const [selectKey, setSelectKey] = useState(0); // Force rerender key
80
+ // Ref to control the SelectBox dropdown
81
+ const selectBoxRef = useRef(null);
82
+ const textAreaValue = value !== undefined ? value : internalValue;
83
+ // Handle SelectBox selection - overrides textarea content then clears selectbox
84
+ const handleSelectChange = (newValue) => {
85
+ if (newValue) {
86
+ // Override textarea content with selected value
87
+ setInternalValue(newValue);
88
+ // Also call onChange if provided (for form integration)
89
+ if (onChange) {
90
+ onChange(newValue);
91
+ }
92
+ setTimeout(() => {
93
+ setSelectValue(null);
94
+ setSelectKey((prev) => prev + 1);
95
+ }, 100);
96
+ }
97
+ else {
98
+ setSelectValue(newValue);
99
+ }
100
+ };
101
+ // Handle textarea changes
102
+ const handleTextAreaChange = (event) => {
103
+ const newValue = event.target.value;
104
+ // Always update internal state for display purposes
105
+ setInternalValue(newValue);
106
+ // Also call onChange if provided (for form integration)
107
+ if (onChange) {
108
+ onChange(newValue);
109
+ }
110
+ };
111
+ // Handle keyboard shortcuts for dropdown
112
+ const handleTextAreaKeyDown = (event) => {
113
+ // Ctrl/Cmd + Space to open dropdown
114
+ if ((event.ctrlKey || event.metaKey) && event.code === "Space") {
115
+ event.preventDefault();
116
+ handleSearchClick();
117
+ }
118
+ };
119
+ const handleSearchClick = () => {
120
+ if (selectBoxRef.current) {
121
+ const selectInput = selectBoxRef.current.querySelector("input");
122
+ if (selectInput) {
123
+ selectInput.focus();
124
+ selectInput.click();
125
+ }
126
+ }
127
+ };
128
+ // Used to create red border when zod validation detects errors
129
+ const hasError = Boolean(error);
130
+ return (_jsxs(CombinedInputWrapper, { children: [label && (_jsx(StyledFieldLabel, { asterisk: required, error: error, description: description, actionComponent: _jsx(DropDownMenu, { data: [
131
+ {
132
+ value: "search",
133
+ label: "Select Recent Entry",
134
+ visible: true,
135
+ },
136
+ ], variant: "text", size: "xs", arrow: false, onItemSelect: (item) => {
137
+ if (item.value === "search") {
138
+ handleSearchClick();
139
+ }
140
+ }, buttonProps: {
141
+ style: {
142
+ minWidth: "auto",
143
+ border: "none",
144
+ background: "transparent",
145
+ padding: "0",
146
+ margin: "0",
147
+ height: "16px",
148
+ width: "16px",
149
+ },
150
+ }, children: _jsx(MoreHorizontal, { size: 16 }) }), children: label })), _jsx(TextAreaRow, { children: _jsx(StyledTextArea, Object.assign({ placeholder: textAreaPlaceholder || "Enter details about the move", "$minRows": textAreaMinRows, "$maxRows": textAreaMaxRows, "$hasError": hasError, value: textAreaValue, onChange: handleTextAreaChange, onKeyDown: handleTextAreaKeyDown }, textAreaProps)) }), _jsx(SelectBoxWrapper, { ref: selectBoxRef, children: _jsx(StyledSelectBox, Object.assign({ data: data, searchable: searchable, allowCustomValue: allowCustomValue, arrow: false, value: selectValue || undefined, onChange: handleSelectChange, hasError: hasError }, selectProps), selectKey) })] }));
151
+ }
152
+ SearchableTextArea.displayName = "SearchableTextArea";
153
+ export default SearchableTextArea;
@@ -0,0 +1,2 @@
1
+ export { default } from "./SearchableTextArea";
2
+ export type { SearchableTextAreaProps } from "./SearchableTextArea";
@@ -0,0 +1 @@
1
+ export { default } from "./SearchableTextArea";
@@ -33,7 +33,7 @@ const TableMenu = () => {
33
33
  const inputRef = useRef(null);
34
34
  if ((tableMenuOptions === null || tableMenuOptions === void 0 ? void 0 : tableMenuOptions.enabled) !== true)
35
35
  return null;
36
- const { addButtonOptions, filterOptions, tableCountOptions, exportOptions, compactOptions, columnSelectorOptions, actionOptions, searchOptions, children, } = tableMenuOptions;
36
+ const { addButtonOptions, filterOptions, tableCountOptions, exportOptions, compactOptions, columnSelectorOptions, searchOptions, children, } = tableMenuOptions;
37
37
  const queryFilter = useQueryFilter({
38
38
  defaultFilter: filterState,
39
39
  filterDefinitions: (filterOptions === null || filterOptions === void 0 ? void 0 : filterOptions.filterDefinitions) || [],
@@ -84,7 +84,7 @@ const TableMenu = () => {
84
84
  }, onItemSelect: handleSelectFilter, dropDownProps: {
85
85
  style: { width: 175, maxWidth: 400 },
86
86
  }, searchable: true, children: "Filter" })), (tableCountOptions === null || tableCountOptions === void 0 ? void 0 : tableCountOptions.recordsTotalEnabled) === true && (_jsx(InfoBadge, { total: totalRecords || data.length })), enableSelection === true &&
87
- (tableCountOptions === null || tableCountOptions === void 0 ? void 0 : tableCountOptions.selectionTotalEnabled) === true && (_jsx(InfoBadge, { total: getCalculatedSelectionTotal(), hint: "Selected Items", icon: CheckSquareIcon })), children] }), _jsxs(FlexedRow, { children: [(actionOptions === null || actionOptions === void 0 ? void 0 : actionOptions.enabled) === true && actionOptions.menu, (exportOptions === null || exportOptions === void 0 ? void 0 : exportOptions.enabled) === true && (_jsx(DropDownMenu, { variant: "outlined", size: "xs", data: [
87
+ (tableCountOptions === null || tableCountOptions === void 0 ? void 0 : tableCountOptions.selectionTotalEnabled) === true && (_jsx(InfoBadge, { total: getCalculatedSelectionTotal(), hint: "Selected Items", icon: CheckSquareIcon })), children] }), _jsxs(FlexedRow, { children: [(exportOptions === null || exportOptions === void 0 ? void 0 : exportOptions.enabled) === true && (_jsx(DropDownMenu, { variant: "outlined", size: "xs", data: [
88
88
  {
89
89
  label: "Export Visible Columns",
90
90
  value: TableExportOptions.ExportVisible,
@@ -227,10 +227,6 @@ export type TableMenuOptions = {
227
227
  recordsTotalEnabled?: boolean;
228
228
  selectionTotalEnabled?: boolean;
229
229
  };
230
- actionOptions?: {
231
- enabled?: boolean;
232
- menu?: React.ReactNode;
233
- };
234
230
  searchOptions?: {
235
231
  enabled?: boolean;
236
232
  placeholder?: string;
package/dist/index.d.ts CHANGED
@@ -14,6 +14,8 @@ export type { DropDownItem } from "./DropDownMenu";
14
14
  export { default as DateInput } from "./DateInput";
15
15
  export { default as TextArea } from "./TextArea";
16
16
  export { default as TextAreaInput } from "./TextAreaInput";
17
+ export { default as SearchableTextArea } from "./SearchableTextArea";
18
+ export type { SearchableTextAreaProps } from "./SearchableTextArea";
17
19
  export { default as TagBox } from "./TagBox";
18
20
  export type { TagBoxProps, TagboxOption } from "./TagBox";
19
21
  export { default as FieldLabel } from "./FieldLabel";
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ export { default as DropDownMenu } from "./DropDownMenu";
8
8
  export { default as DateInput } from "./DateInput";
9
9
  export { default as TextArea } from "./TextArea";
10
10
  export { default as TextAreaInput } from "./TextAreaInput";
11
+ export { default as SearchableTextArea } from "./SearchableTextArea";
11
12
  export { default as TagBox } from "./TagBox";
12
13
  export { default as FieldLabel } from "./FieldLabel";
13
14
  export { default as Modal } from "./Modal";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monolith-forensics/monolith-ui",
3
- "version": "1.3.91",
3
+ "version": "1.3.92",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "author": "Matt Danner (Monolith Forensics LLC)",