@monolith-forensics/monolith-ui 1.1.57 → 1.1.58
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.
|
@@ -441,8 +441,48 @@ const DateInput = styled(({ className, defaultValue, format = "YYYY-MM-DD HH:mm:
|
|
|
441
441
|
const handlePaste = (e) => __awaiter(void 0, void 0, void 0, function* () {
|
|
442
442
|
const pastedText = yield window.navigator.clipboard.readText();
|
|
443
443
|
if (!pastedText)
|
|
444
|
+
return; // do nothing if clipboard is empty
|
|
445
|
+
// check for unix timestamp in seconds
|
|
446
|
+
if (pastedText.match(/^\d{10}$/)) {
|
|
447
|
+
const parsedTimestamp = moment
|
|
448
|
+
.unix(parseInt(pastedText, 10))
|
|
449
|
+
.toISOString();
|
|
450
|
+
setValue(parsedTimestamp);
|
|
444
451
|
return;
|
|
445
|
-
|
|
452
|
+
}
|
|
453
|
+
// check for unix timestamp in seconds with fractional seconds
|
|
454
|
+
if (pastedText.match(/^\d{10}\.\d{1,6}$/)) {
|
|
455
|
+
const parsedTimestamp = moment
|
|
456
|
+
.unix(parseFloat(pastedText))
|
|
457
|
+
.toISOString();
|
|
458
|
+
setValue(parsedTimestamp);
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
// check for unix timestamp in milliseconds
|
|
462
|
+
if (pastedText.match(/^\d{13}$/)) {
|
|
463
|
+
const parsedTimestamp = moment
|
|
464
|
+
.unix(parseInt(pastedText, 10) / 1000)
|
|
465
|
+
.toISOString();
|
|
466
|
+
setValue(parsedTimestamp);
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
// check for windows ldap or filetime timestamp
|
|
470
|
+
if (pastedText.match(/^\d{18}$/)) {
|
|
471
|
+
const parsedTimestamp = moment
|
|
472
|
+
.unix((parseInt(pastedText, 10) - 116444736000000000) / 10000000)
|
|
473
|
+
.toISOString();
|
|
474
|
+
setValue(parsedTimestamp);
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
// check for YMD ldap timestamp in format YYYYMMDDHHMMSSZ
|
|
478
|
+
if (pastedText.match(/^\d{14}Z$/)) {
|
|
479
|
+
const parsedTimestamp = moment
|
|
480
|
+
.utc(pastedText, "YYYYMMDDHHmmssZ")
|
|
481
|
+
.toISOString();
|
|
482
|
+
setValue(parsedTimestamp);
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
// check if pasted text is any other valid timestamp
|
|
446
486
|
if (!moment(pastedText).isValid())
|
|
447
487
|
return;
|
|
448
488
|
const parsedTimestamp = moment.utc(pastedText).toISOString();
|
|
@@ -3,6 +3,7 @@ import { Size, Variant } from "../core";
|
|
|
3
3
|
interface SelectBoxProps {
|
|
4
4
|
className?: string;
|
|
5
5
|
defaultValue?: Option | string;
|
|
6
|
+
value?: Option | string;
|
|
6
7
|
data?: Option[] | string[];
|
|
7
8
|
placeholder?: string;
|
|
8
9
|
arrow?: boolean;
|
|
@@ -41,5 +42,5 @@ type Option = {
|
|
|
41
42
|
export declare const StyledInputContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
42
43
|
width?: string | number | null;
|
|
43
44
|
}>> & string;
|
|
44
|
-
declare const SelectBox: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<SelectBoxProps, never>> & string & Omit<({ className, data, placeholder, arrow, onChange, onSearch, searchFn, onScroll, loading, defaultValue, onItemAdded, size, variant, width, allowCustomValue, searchable, clearable, label, description, required, error, openOnFocus, renderOption, actionComponent, focused, grouped, TooltipContent, DropDownProps, }: SelectBoxProps) => import("react/jsx-runtime").JSX.Element, keyof import("react").Component<any, {}, any>>;
|
|
45
|
+
declare const SelectBox: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<SelectBoxProps, never>> & string & Omit<({ className, data, placeholder, arrow, onChange, onSearch, searchFn, onScroll, loading, defaultValue, value, onItemAdded, size, variant, width, allowCustomValue, searchable, clearable, label, description, required, error, openOnFocus, renderOption, actionComponent, focused, grouped, TooltipContent, DropDownProps, }: SelectBoxProps) => import("react/jsx-runtime").JSX.Element, keyof import("react").Component<any, {}, any>>;
|
|
45
46
|
export default SelectBox;
|
|
@@ -15,6 +15,7 @@ import { useFloating, flip, offset, FloatingPortal, autoUpdate, } from "@floatin
|
|
|
15
15
|
import { useCallback, useEffect, useRef, useState, } from "react";
|
|
16
16
|
import { Input, FieldLabel, Tooltip } from "..";
|
|
17
17
|
import { useDebouncedCallback } from "use-debounce";
|
|
18
|
+
import { useUncontrolled } from "@mantine/hooks";
|
|
18
19
|
import { StyledContent, StyledFloatContainer, ArrowButton, ClearButton, } from "../core";
|
|
19
20
|
export const StyledInputContainer = styled.div `
|
|
20
21
|
font-family: ${({ theme }) => theme.typography.fontFamily};
|
|
@@ -150,11 +151,15 @@ const StyledItem = styled.div `
|
|
|
150
151
|
color: ${(props) => props.theme.palette.text.primary};
|
|
151
152
|
}
|
|
152
153
|
`;
|
|
153
|
-
const SelectBox = styled(({ className, data = [], placeholder = "Select...", arrow = true, onChange, onSearch, searchFn, onScroll, loading, defaultValue, onItemAdded, size = "sm", variant = "outlined", width = "100%", allowCustomValue = false, searchable = false, clearable = false, label, description, required = false, error, openOnFocus = true, renderOption, actionComponent, focused, grouped, TooltipContent, DropDownProps = {}, }) => {
|
|
154
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
154
|
+
const SelectBox = styled(({ className, data = [], placeholder = "Select...", arrow = true, onChange, onSearch, searchFn, onScroll, loading, defaultValue, value, onItemAdded, size = "sm", variant = "outlined", width = "100%", allowCustomValue = false, searchable = false, clearable = false, label, description, required = false, error, openOnFocus = true, renderOption, actionComponent, focused, grouped, TooltipContent, DropDownProps = {}, }) => {
|
|
155
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
155
156
|
const isObjectArray = (_a = Object.keys((data === null || data === void 0 ? void 0 : data[0]) || {})) === null || _a === void 0 ? void 0 : _a.includes("label");
|
|
157
|
+
const [_value, handleChange] = useUncontrolled({
|
|
158
|
+
value,
|
|
159
|
+
defaultValue,
|
|
160
|
+
onChange,
|
|
161
|
+
});
|
|
156
162
|
const [isOpen, setIsOpen] = useState(false);
|
|
157
|
-
const [selected, setSelected] = useState(null);
|
|
158
163
|
const [searchValue, setSearchValue] = useState("");
|
|
159
164
|
const [customItems, setCustomItems] = useState([]);
|
|
160
165
|
const [placement, setPlacement] = useState("bottom-start");
|
|
@@ -162,9 +167,9 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
|
|
|
162
167
|
const inputRef = useRef(null);
|
|
163
168
|
const containerRef = useRef(null);
|
|
164
169
|
const scrollContainerRef = useRef(null);
|
|
165
|
-
const uniqueItems = Array.from(new Map([...data, ...customItems].map(item => [
|
|
170
|
+
const uniqueItems = Array.from(new Map([...data, ...customItems].map((item) => [
|
|
166
171
|
isObjectArray ? item.value : item,
|
|
167
|
-
item
|
|
172
|
+
item,
|
|
168
173
|
])).values());
|
|
169
174
|
const filteredItems = uniqueItems
|
|
170
175
|
.filter((item) => {
|
|
@@ -225,11 +230,9 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
|
|
|
225
230
|
};
|
|
226
231
|
const handleClear = (e) => {
|
|
227
232
|
e.preventDefault();
|
|
228
|
-
|
|
229
|
-
inputRef.current.value = "";
|
|
233
|
+
e.stopPropagation();
|
|
230
234
|
setIsOpen(false);
|
|
231
|
-
|
|
232
|
-
setSelected(null);
|
|
235
|
+
handleChange(undefined);
|
|
233
236
|
setSearchValue("");
|
|
234
237
|
searchFn === null || searchFn === void 0 ? void 0 : searchFn("");
|
|
235
238
|
update();
|
|
@@ -237,13 +240,9 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
|
|
|
237
240
|
const handleItemClick = (event, item) => {
|
|
238
241
|
event.preventDefault();
|
|
239
242
|
event.stopPropagation();
|
|
240
|
-
|
|
243
|
+
handleChange(item);
|
|
241
244
|
setIsOpen(false);
|
|
242
245
|
};
|
|
243
|
-
const handleChangeSelection = useCallback((option) => {
|
|
244
|
-
setSelected(option);
|
|
245
|
-
onChange === null || onChange === void 0 ? void 0 : onChange((option === null || option === void 0 ? void 0 : option.value) || option, option);
|
|
246
|
-
}, [onChange]);
|
|
247
246
|
const handleAddItem = useCallback((newItem) => {
|
|
248
247
|
const isNewItem = data.every((item) => item.label.toLowerCase() !==
|
|
249
248
|
newItem.toLowerCase());
|
|
@@ -255,7 +254,7 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
|
|
|
255
254
|
prev.push(newValue);
|
|
256
255
|
return prev;
|
|
257
256
|
});
|
|
258
|
-
|
|
257
|
+
handleChange(newValue);
|
|
259
258
|
onItemAdded === null || onItemAdded === void 0 ? void 0 : onItemAdded(newValue);
|
|
260
259
|
}
|
|
261
260
|
else {
|
|
@@ -264,9 +263,9 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
|
|
|
264
263
|
? item.label.toLowerCase() === newItem.toLowerCase()
|
|
265
264
|
: item.toLowerCase() === newItem.toLowerCase();
|
|
266
265
|
});
|
|
267
|
-
|
|
266
|
+
handleChange(item);
|
|
268
267
|
}
|
|
269
|
-
}, [onItemAdded, isObjectArray, data,
|
|
268
|
+
}, [onItemAdded, isObjectArray, data, handleChange]);
|
|
270
269
|
const handleKeyDown = (e) => {
|
|
271
270
|
var _a, _b;
|
|
272
271
|
const currentInputValue = (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.value;
|
|
@@ -293,32 +292,26 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
|
|
|
293
292
|
// Arrow down
|
|
294
293
|
if (e.key === "ArrowDown") {
|
|
295
294
|
e.preventDefault();
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
onChange === null || onChange === void 0 ? void 0 : onChange((newItem === null || newItem === void 0 ? void 0 : newItem.value) || newItem, newItem);
|
|
305
|
-
return newItem;
|
|
306
|
-
});
|
|
295
|
+
let newItem = filteredItems[0]; // Loop back to the first item
|
|
296
|
+
const index = filteredItems.findIndex((item) => isObjectArray
|
|
297
|
+
? item.value === (_value === null || _value === void 0 ? void 0 : _value.value)
|
|
298
|
+
: item === _value);
|
|
299
|
+
if (index < filteredItems.length - 1) {
|
|
300
|
+
newItem = filteredItems[index + 1];
|
|
301
|
+
}
|
|
302
|
+
handleChange === null || handleChange === void 0 ? void 0 : handleChange(newItem, newItem);
|
|
307
303
|
}
|
|
308
304
|
// Arrow up
|
|
309
305
|
if (e.key === "ArrowUp") {
|
|
310
306
|
e.preventDefault();
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
onChange === null || onChange === void 0 ? void 0 : onChange((newItem === null || newItem === void 0 ? void 0 : newItem.value) || newItem, newItem);
|
|
320
|
-
return newItem;
|
|
321
|
-
});
|
|
307
|
+
let newItem = filteredItems[filteredItems.length - 1]; // Loop back to the last item
|
|
308
|
+
const index = filteredItems.findIndex((item) => isObjectArray
|
|
309
|
+
? item.value === (_value === null || _value === void 0 ? void 0 : _value.value)
|
|
310
|
+
: item === _value);
|
|
311
|
+
if (index > 0) {
|
|
312
|
+
newItem = filteredItems[index - 1];
|
|
313
|
+
}
|
|
314
|
+
handleChange === null || handleChange === void 0 ? void 0 : handleChange(newItem, newItem);
|
|
322
315
|
}
|
|
323
316
|
// Tab key
|
|
324
317
|
if (e.key === "Tab") {
|
|
@@ -326,7 +319,7 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
|
|
|
326
319
|
handleAddItem(currentInputValue);
|
|
327
320
|
setSearchValue("");
|
|
328
321
|
}
|
|
329
|
-
else if (!
|
|
322
|
+
else if (!_value) {
|
|
330
323
|
// clear input
|
|
331
324
|
if (inputRef.current) {
|
|
332
325
|
inputRef.current.value = "";
|
|
@@ -381,31 +374,6 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
|
|
|
381
374
|
document.addEventListener("click", close);
|
|
382
375
|
return () => document.removeEventListener("click", close);
|
|
383
376
|
}, [refs.floating, refs.reference]);
|
|
384
|
-
// Handle default value
|
|
385
|
-
useEffect(() => {
|
|
386
|
-
if (defaultValue) {
|
|
387
|
-
const isOption = defaultValue.value !== undefined;
|
|
388
|
-
const searchPattern = isOption
|
|
389
|
-
? defaultValue.value
|
|
390
|
-
: defaultValue;
|
|
391
|
-
setSelected(data.find((item) => isObjectArray
|
|
392
|
-
? item.value === searchPattern
|
|
393
|
-
: item === searchPattern) || null);
|
|
394
|
-
}
|
|
395
|
-
}, [data, defaultValue, isObjectArray]);
|
|
396
|
-
// handle input value change
|
|
397
|
-
useEffect(() => {
|
|
398
|
-
if (inputRef.current) {
|
|
399
|
-
if (!selected) {
|
|
400
|
-
inputRef.current.value = "";
|
|
401
|
-
}
|
|
402
|
-
else {
|
|
403
|
-
inputRef.current.value = isObjectArray
|
|
404
|
-
? selected.label
|
|
405
|
-
: selected;
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
}, [selected]);
|
|
409
377
|
// handle scroll item into view
|
|
410
378
|
useEffect(() => {
|
|
411
379
|
var _a, _b;
|
|
@@ -413,7 +381,7 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
|
|
|
413
381
|
if (item) {
|
|
414
382
|
item.scrollIntoView({ block: "nearest" });
|
|
415
383
|
}
|
|
416
|
-
}, [
|
|
384
|
+
}, [_value]);
|
|
417
385
|
// make calls to onSearch callback
|
|
418
386
|
useEffect(() => {
|
|
419
387
|
if (searchable) {
|
|
@@ -446,7 +414,7 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
|
|
|
446
414
|
setDropDownHeight(bottomHeight);
|
|
447
415
|
};
|
|
448
416
|
}, [topHeight, bottomHeight, isOpen]);
|
|
449
|
-
return (_jsxs("div", { className: className, children: [label && (_jsx(FieldLabel, { error: error, asterisk: required, size: size, description: description, children: label })), _jsxs(StyledInputContainer, { ref: refs.setReference, onMouseDown: () => setIsOpen(true), width: width, onKeyDown: handleKeyDown, "data-open": isOpen, children: [_jsx(Input, { ref: inputRef, onChange: debouncedHandleOnChange, onFocus: handleFocus, autoFocus: focused, placeholder: placeholder, size: size, readOnly: !searchable, "data-button-right": arrow || clearable }), clearable &&
|
|
417
|
+
return (_jsxs("div", { className: className, children: [label && (_jsx(FieldLabel, { error: error, asterisk: required, size: size, description: description, children: label })), _jsxs(StyledInputContainer, { ref: refs.setReference, onMouseDown: () => setIsOpen(true), width: width, onKeyDown: handleKeyDown, "data-open": isOpen, children: [_jsx(Input, { ref: inputRef, value: isObjectArray ? (_value === null || _value === void 0 ? void 0 : _value.label) || "" : _value || "", onChange: debouncedHandleOnChange, onFocus: handleFocus, autoFocus: focused, placeholder: placeholder, size: size, readOnly: !searchable, "data-button-right": arrow || clearable }), clearable && _value ? (_jsx(ClearButton, { className: "input-btn", onClick: handleClear, onMouseDown: (e) => {
|
|
450
418
|
e.preventDefault();
|
|
451
419
|
e.stopPropagation();
|
|
452
420
|
} })) : arrow ? (_jsx(ArrowButton, { onClick: (e) => {
|
|
@@ -468,15 +436,14 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
|
|
|
468
436
|
}, variant: variant, "data-empty": filteredItems.length === 0 }, DropDownProps, { children: [actionComponent && _jsx(ActionMenu, { children: actionComponent }), _jsxs(StyledInnerItemContainer, { ref: scrollContainerRef, "data-scroll-active": scrollActive, onScroll: onScroll, children: [loading && _jsx("div", { children: "Loading..." }), !loading && grouped
|
|
469
437
|
? groups.map((group, index) => (_jsxs("div", { children: [_jsx(GroupTitle, { size: size, children: group.label }), group.items.map((item, index) => {
|
|
470
438
|
return (_jsx(Tooltip, { content: TooltipContent ? (_jsx(TooltipContent, { data: item.data })) : null, side: "left", children: _jsx(StyledItem, { className: "mfFloatingItem", onClick: (e) => handleItemClick(e, item), "data-selected": isObjectArray
|
|
471
|
-
? (
|
|
472
|
-
|
|
473
|
-
: selected === item, size: size, children: (renderOption === null || renderOption === void 0 ? void 0 : renderOption(item)) || (_jsx(_Fragment, { children: (item === null || item === void 0 ? void 0 : item.label) || item })) }, index) }, index));
|
|
439
|
+
? (_value === null || _value === void 0 ? void 0 : _value.value) === item.value
|
|
440
|
+
: _value === item, size: size, children: (renderOption === null || renderOption === void 0 ? void 0 : renderOption(item)) || (_jsx(_Fragment, { children: (item === null || item === void 0 ? void 0 : item.label) || item })) }, index) }, index));
|
|
474
441
|
})] }, group.label)))
|
|
475
442
|
: filteredItems.map((item, index) => {
|
|
476
443
|
return (_jsx(Tooltip, { content: TooltipContent ? (_jsx(TooltipContent, { data: item.data })) : null, side: "left", children: _jsx(StyledItem, { className: "mfFloatingItem", onClick: (e) => handleItemClick(e, item), "data-selected": isObjectArray
|
|
477
|
-
? (
|
|
444
|
+
? (_value === null || _value === void 0 ? void 0 : _value.value) ===
|
|
478
445
|
(item === null || item === void 0 ? void 0 : item.value)
|
|
479
|
-
:
|
|
446
|
+
: _value === item, size: size, children: (renderOption === null || renderOption === void 0 ? void 0 : renderOption(item)) || (_jsx(_Fragment, { children: (item === null || item === void 0 ? void 0 : item.label) || item })) }, index) }, index));
|
|
480
447
|
})] })] })) }) }))] }));
|
|
481
448
|
}) `
|
|
482
449
|
position: relative;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monolith-forensics/monolith-ui",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.58",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"author": "Matt Danner (Monolith Forensics LLC)",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@floating-ui/react": "^0.26.16",
|
|
25
|
+
"@mantine/hooks": "^7.13.0",
|
|
25
26
|
"@radix-ui/react-switch": "^1.0.7",
|
|
26
27
|
"@radix-ui/react-tooltip": "^1.0.7",
|
|
27
28
|
"@tabler/icons-react": "^3.11.0",
|