@monolith-forensics/monolith-ui 1.1.56 → 1.1.57

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.
@@ -1,6 +1,15 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
11
  import moment from "moment";
3
- import { useFloating, flip, offset, FloatingPortal, useDismiss, useInteractions, autoUpdate } from "@floating-ui/react";
12
+ import { useFloating, flip, offset, FloatingPortal, useDismiss, useInteractions, autoUpdate, } from "@floating-ui/react";
4
13
  import { useEffect, useMemo, useRef, useState, } from "react";
5
14
  import styled from "styled-components";
6
15
  import { FieldLabel, Calendar } from "..";
@@ -246,9 +255,7 @@ const DateInput = styled(({ className, defaultValue, format = "YYYY-MM-DD HH:mm:
246
255
  whileElementsMounted: autoUpdate,
247
256
  });
248
257
  const dismiss = useDismiss(context);
249
- const { getReferenceProps } = useInteractions([
250
- dismiss,
251
- ]);
258
+ const { getReferenceProps } = useInteractions([dismiss]);
252
259
  const segments = useMemo(() => parseTimestamp(moment(value).toISOString(), format, utc), [value, format, utc]);
253
260
  const checkValidRange = (value) => {
254
261
  if (min && moment(value).isBefore(min))
@@ -319,6 +326,7 @@ const DateInput = styled(({ className, defaultValue, format = "YYYY-MM-DD HH:mm:
319
326
  const next = segments[prev.index + 2];
320
327
  return next || prev;
321
328
  });
329
+ typedKeys.current = ""; // clear typed keys when moving to next segment
322
330
  }
323
331
  // Left Arrow
324
332
  if (e.key === "ArrowLeft") {
@@ -329,6 +337,7 @@ const DateInput = styled(({ className, defaultValue, format = "YYYY-MM-DD HH:mm:
329
337
  const next = segments[prev.index - 2];
330
338
  return next || prev;
331
339
  });
340
+ typedKeys.current = ""; // clear typed keys when moving to next segment
332
341
  }
333
342
  // Up Arrow
334
343
  if (e.key === "ArrowUp") {
@@ -368,7 +377,7 @@ const DateInput = styled(({ className, defaultValue, format = "YYYY-MM-DD HH:mm:
368
377
  }
369
378
  // handle paste
370
379
  if (e.key === "v" && (e.metaKey || e.ctrlKey)) {
371
- return;
380
+ handlePaste();
372
381
  }
373
382
  // only allow numbers
374
383
  if (e.key.match(/[0-9]/)) {
@@ -383,7 +392,8 @@ const DateInput = styled(({ className, defaultValue, format = "YYYY-MM-DD HH:mm:
383
392
  setValue((prev) => {
384
393
  if (!(selectedSegment === null || selectedSegment === void 0 ? void 0 : selectedSegment.momentType))
385
394
  return prev;
386
- const newValue = moment(prev)
395
+ const momentValue = utc ? moment.utc(prev) : moment(prev);
396
+ const newValue = moment(momentValue)
387
397
  .set(selectedSegment.momentType, parseInt(tempValue, 10) -
388
398
  (selectedSegment.type === "month" ? 1 : 0))
389
399
  .toISOString();
@@ -397,28 +407,39 @@ const DateInput = styled(({ className, defaultValue, format = "YYYY-MM-DD HH:mm:
397
407
  typedKeys.current = "";
398
408
  }
399
409
  }
400
- e.preventDefault();
401
410
  };
402
411
  const handleWheelEvent = (e) => {
403
412
  if (!selectedSegment)
404
413
  return;
405
- setValue((prev) => {
406
- if (selectedSegment.type === "separator")
407
- return prev;
408
- if (!prev)
409
- return isDateOnly ? moment().format(format) : moment().toISOString();
410
- let newValue = e.deltaY > 0 ? moment(prev).subtract(1, selectedSegment.type).toISOString() : moment(prev).add(1, selectedSegment.type).toISOString();
411
- if (!checkValidRange(newValue))
412
- return prev;
413
- newValue = isDateOnly ? moment(newValue).format(format) : newValue;
414
- onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
415
- return newValue;
416
- });
414
+ if (e.deltaY > 0) {
415
+ setValue((prev) => {
416
+ if (selectedSegment.type === "separator")
417
+ return prev;
418
+ const newValue = prev
419
+ ? moment(prev).subtract(1, selectedSegment.type).toISOString()
420
+ : moment().toISOString();
421
+ if (!checkValidRange(newValue))
422
+ return prev;
423
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
424
+ return newValue;
425
+ });
426
+ }
427
+ else {
428
+ setValue((prev) => {
429
+ if (selectedSegment.type === "separator")
430
+ return prev;
431
+ const newValue = prev
432
+ ? moment(prev).add(1, selectedSegment.type).toISOString()
433
+ : moment().toISOString();
434
+ if (!checkValidRange(newValue))
435
+ return prev;
436
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
437
+ return newValue;
438
+ });
439
+ }
417
440
  };
418
- const handlePaste = (e) => {
419
- var _a, _b;
420
- e.preventDefault();
421
- const pastedText = (_b = (_a = e === null || e === void 0 ? void 0 : e.clipboardData) === null || _a === void 0 ? void 0 : _a.getData) === null || _b === void 0 ? void 0 : _b.call(_a, "text");
441
+ const handlePaste = (e) => __awaiter(void 0, void 0, void 0, function* () {
442
+ const pastedText = yield window.navigator.clipboard.readText();
422
443
  if (!pastedText)
423
444
  return;
424
445
  // check if pasted text is a valid timestamp
@@ -426,7 +447,7 @@ const DateInput = styled(({ className, defaultValue, format = "YYYY-MM-DD HH:mm:
426
447
  return;
427
448
  const parsedTimestamp = moment.utc(pastedText).toISOString();
428
449
  setValue(parsedTimestamp);
429
- };
450
+ });
430
451
  // Close on outside click
431
452
  useEffect(() => {
432
453
  const close = (e) => {
@@ -458,7 +479,7 @@ const DateInput = styled(({ className, defaultValue, format = "YYYY-MM-DD HH:mm:
458
479
  return (_jsxs("div", { className: className, children: [label && (_jsx(FieldLabel, { error: error, asterisk: required, size: size, description: description, children: label })), _jsxs(StyledInputContainer, { ref: (ref) => {
459
480
  mainRef.current = ref;
460
481
  refs.setReference(ref);
461
- }, onClick: handleContainerClick, onMouseDown: handleMouseDown, onKeyDown: handleKeyDown, onPaste: handlePaste, onFocus: (e) => {
482
+ }, onClick: handleContainerClick, onMouseDown: handleMouseDown, onKeyDown: handleKeyDown, onFocus: (e) => {
462
483
  e.preventDefault();
463
484
  setSelectedSegment(segments[0]);
464
485
  }, onBlur: () => {
@@ -471,7 +492,7 @@ const DateInput = styled(({ className, defaultValue, format = "YYYY-MM-DD HH:mm:
471
492
  }, onFocus: (e) => e.preventDefault(), onPointerDown: (e) => e.preventDefault(), "data-type": "separator", "data-identifier": segment.type, "data-has-space": segment.text.includes(" "), "data-placeholder": segment.placeholder, "data-value": segment.value, children: segment.text }, i));
472
493
  }
473
494
  return (_jsx(InputSegment, { className: "input", tabIndex: i === 0 ? 0 : -1, onClick: (e) => handleSegmentClick(e, segment), "data-type": "input", size: size, "data-identifier": segment.type, "data-has-space": segment.text.includes(" "), "data-placeholder": segment.placeholder, "data-value": segment.value, "data-selected": (selectedSegment === null || selectedSegment === void 0 ? void 0 : selectedSegment.index) === segment.index, children: value ? segment.text : segment.placeholder }, i));
474
- }), utc && _jsx("div", { style: { marginLeft: 5 }, children: "UTC" }), clearable && value ? (_jsx(ClearButton, { onClick: handleClear })) : arrow ? (_jsx(ArrowButton, {})) : null] }), enableCalendar && isOpen && (_jsx(FloatingPortal, { preserveTabOrder: true, children: _jsx(StyledFloatContainer, Object.assign({ ref: refs.setFloating, style: floatingStyles }, getReferenceProps(), { children: _jsx(StyledContent, { maxDropdownHeight: "fit-content", children: _jsx("div", { children: _jsx(Calendar, { defaultValue: value ? moment(value).toDate() : undefined, clearable: false, min: min, max: max, onChange: (date) => {
495
+ }), utc && _jsx("div", { style: { marginLeft: 5 }, children: "UTC" }), clearable && value ? (_jsx(ClearButton, { onClick: handleClear })) : arrow ? (_jsx(ArrowButton, {})) : null] }), enableCalendar && isOpen && (_jsx(FloatingPortal, { preserveTabOrder: true, children: _jsx(StyledFloatContainer, Object.assign({ ref: refs.setFloating, style: floatingStyles }, getReferenceProps(), { children: _jsx(StyledContent, { maxDropdownHeight: "fit-content", children: _jsx("div", { children: _jsx(Calendar, { value: value ? moment(value).toDate() : undefined, clearable: false, min: min, max: max, onChange: (date) => {
475
496
  setValue((prev) => {
476
497
  // make copy of prev variable
477
498
  const oldValue = moment(prev).toISOString();
@@ -1,14 +1,5 @@
1
1
  import { ReactNode } from "react";
2
2
  import { Size, Variant } from "../core";
3
- 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>, {
4
- width?: string | number | null;
5
- }>> & string;
6
- type Option = {
7
- label: string;
8
- value: any;
9
- group?: string;
10
- data?: any;
11
- };
12
3
  interface SelectBoxProps {
13
4
  className?: string;
14
5
  defaultValue?: Option | string;
@@ -41,5 +32,14 @@ interface SelectBoxProps {
41
32
  }>;
42
33
  DropDownProps?: any;
43
34
  }
35
+ type Option = {
36
+ label: string;
37
+ value: any;
38
+ group?: string;
39
+ data?: any;
40
+ };
41
+ 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
+ width?: string | number | null;
43
+ }>> & string;
44
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
45
  export default SelectBox;
@@ -162,8 +162,11 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
162
162
  const inputRef = useRef(null);
163
163
  const containerRef = useRef(null);
164
164
  const scrollContainerRef = useRef(null);
165
- const filteredItems = data
166
- .concat(customItems) // Add custom items to the list
165
+ const uniqueItems = Array.from(new Map([...data, ...customItems].map(item => [
166
+ isObjectArray ? item.value : item,
167
+ item
168
+ ])).values());
169
+ const filteredItems = uniqueItems
167
170
  .filter((item) => {
168
171
  const itemValue = (isObjectArray ? item.label : item);
169
172
  return itemValue === null || itemValue === void 0 ? void 0 : itemValue.toLowerCase().includes(searchValue.toLowerCase());
@@ -174,8 +177,10 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
174
177
  const bValue = b.group;
175
178
  return aValue.localeCompare(bValue);
176
179
  }
177
- // return current sort order
178
- return 0;
180
+ // Secondary sort by label/value to ensure consistent ordering
181
+ const aLabel = isObjectArray ? a.label : a;
182
+ const bLabel = isObjectArray ? b.label : b;
183
+ return aLabel.localeCompare(bLabel);
179
184
  });
180
185
  const groupedItems = grouped
181
186
  ? filteredItems.reduce((acc, item) => {
@@ -284,7 +289,6 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
284
289
  // TODO: decide what to do when user presses enter after typing a search value
285
290
  }
286
291
  toggleOpen();
287
- // setIsOpen(false);
288
292
  }
289
293
  // Arrow down
290
294
  if (e.key === "ArrowDown") {
@@ -352,6 +356,13 @@ const SelectBox = styled(({ className, data = [], placeholder = "Select...", arr
352
356
  setIsOpen(true);
353
357
  }
354
358
  };
359
+ const handleBlur = () => {
360
+ var _a;
361
+ if (allowCustomValue && ((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.value)) {
362
+ handleAddItem(inputRef.current.value);
363
+ setSearchValue("");
364
+ }
365
+ };
355
366
  // Close on outside click
356
367
  useEffect(() => {
357
368
  const close = (e) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monolith-forensics/monolith-ui",
3
- "version": "1.1.56",
3
+ "version": "1.1.57",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "author": "Matt Danner (Monolith Forensics LLC)",