@monolith-forensics/monolith-ui 1.1.29 → 1.1.31

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.
Files changed (67) hide show
  1. package/dist/Button/Button.js +327 -0
  2. package/dist/Button/index.js +1 -0
  3. package/dist/Calendar/Calendar.js +204 -0
  4. package/dist/Calendar/CalendarStyles.js +164 -0
  5. package/dist/Calendar/calendarHelpers.js +169 -0
  6. package/dist/Calendar/index.js +1 -0
  7. package/dist/CheckBox/CheckBox.js +41 -0
  8. package/dist/CheckBox/index.js +1 -0
  9. package/dist/DateInput/DateInput.js +504 -0
  10. package/dist/DateInput/index.js +1 -0
  11. package/dist/DropDownMenu/DropDownMenu.js +208 -0
  12. package/dist/DropDownMenu/index.js +1 -0
  13. package/dist/Error/Error.js +33 -0
  14. package/dist/Error/index.js +1 -0
  15. package/dist/FieldLabel/FieldLabel.js +90 -0
  16. package/dist/FieldLabel/index.js +1 -0
  17. package/dist/FileInputField/FileInputField.js +112 -0
  18. package/dist/FileInputField/index.js +1 -0
  19. package/dist/Flyout/Flyout.js +106 -0
  20. package/dist/Flyout/FlyoutHeader.js +7 -0
  21. package/dist/Flyout/FlyoutTitle.js +8 -0
  22. package/dist/Flyout/index.js +3 -0
  23. package/dist/FormSection/FormSection.js +46 -0
  24. package/dist/FormSection/index.js +1 -0
  25. package/dist/Grid/Grid.js +13 -0
  26. package/dist/Grid/index.js +1 -0
  27. package/dist/IconButton/IconButton.js +25 -0
  28. package/dist/IconButton/index.js +1 -0
  29. package/dist/Input/Input.js +144 -0
  30. package/dist/Input/index.js +1 -0
  31. package/dist/Modal/Modal.js +105 -0
  32. package/dist/Modal/index.js +1 -0
  33. package/dist/MonolithUIProvider/GlobalStyle.js +51 -0
  34. package/dist/MonolithUIProvider/MonolithUIProvider.js +23 -0
  35. package/dist/MonolithUIProvider/index.js +3 -0
  36. package/dist/MonolithUIProvider/useMonolithUITheme.js +10 -0
  37. package/dist/Pill/Pill.js +147 -0
  38. package/dist/Pill/index.js +1 -0
  39. package/dist/SelectBox/SelectBox.js +471 -0
  40. package/dist/SelectBox/index.js +1 -0
  41. package/dist/Switch/Switch.js +129 -0
  42. package/dist/Switch/index.js +1 -0
  43. package/dist/Table/Table.js +707 -0
  44. package/dist/Table/index.js +2 -0
  45. package/dist/TagBox/TagBox.js +585 -0
  46. package/dist/TagBox/TagBoxStyles.js +107 -0
  47. package/dist/TagBox/index.js +1 -0
  48. package/dist/TextArea/TextArea.js +76 -0
  49. package/dist/TextArea/index.js +1 -0
  50. package/dist/TextAreaInput/TextAreaInput.js +9 -0
  51. package/dist/TextAreaInput/index.js +1 -0
  52. package/dist/TextInput/TextInput.js +26 -0
  53. package/dist/TextInput/index.js +1 -0
  54. package/dist/Tooltip/Tooltip.js +25 -0
  55. package/dist/Tooltip/index.js +1 -0
  56. package/dist/core/ArrowButton.js +43 -0
  57. package/dist/core/ClearButton.js +43 -0
  58. package/dist/core/StyledContent.js +42 -0
  59. package/dist/core/StyledFloatContainer.js +5 -0
  60. package/dist/core/Types/Size.js +1 -0
  61. package/dist/core/Types/Variant.js +1 -0
  62. package/dist/core/index.js +4 -0
  63. package/dist/index.js +26 -0
  64. package/dist/theme/index.js +9 -0
  65. package/dist/theme/typography.js +57 -0
  66. package/dist/theme/variants.js +270 -0
  67. package/package.json +1 -1
@@ -0,0 +1,504 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import moment from "moment";
3
+ import { useFloating, flip, offset, FloatingPortal } from "@floating-ui/react";
4
+ import { useEffect, useMemo, useRef, useState, } from "react";
5
+ import styled from "styled-components";
6
+ import { FieldLabel, Calendar } from "..";
7
+ import { StyledContent, StyledFloatContainer, ArrowButton, ClearButton, } from "../core";
8
+ const StyledInputContainer = styled.div `
9
+ position: relative;
10
+
11
+ caret-color: transparent;
12
+ user-select: none;
13
+
14
+ display: flex;
15
+ flex-direction: row;
16
+ align-items: center;
17
+ user-select: none;
18
+
19
+ pointer-events: all;
20
+ outline: none;
21
+
22
+ border-radius: 5px;
23
+ transition: border 0.1s ease-in-out;
24
+ border: 1px solid
25
+ ${({ theme, variant }) => {
26
+ switch (variant) {
27
+ case "filled":
28
+ return "transparent";
29
+ case "outlined":
30
+ return theme.palette.input.border;
31
+ case "text":
32
+ return "transparent";
33
+ default:
34
+ return theme.palette.input.border;
35
+ }
36
+ }};
37
+
38
+ font-family: ${({ theme }) => theme.typography.fontFamily};
39
+
40
+ color: ${(props) => props.theme.palette.text.primary};
41
+ font-size: ${({ size }) => size === "xs"
42
+ ? "11px"
43
+ : size === "sm"
44
+ ? "13px"
45
+ : size === "md"
46
+ ? "15px"
47
+ : size === "lg"
48
+ ? "17px"
49
+ : size === "xl"
50
+ ? "19px"
51
+ : "11px"};
52
+
53
+ width: 100%;
54
+ height: ${({ size }) => size === "xs"
55
+ ? "26px"
56
+ : size === "sm"
57
+ ? "30px"
58
+ : size === "md"
59
+ ? "36px"
60
+ : size === "lg"
61
+ ? "42px"
62
+ : size === "xl"
63
+ ? "50px"
64
+ : "26px"};
65
+
66
+ padding: ${({ size }) => size === "xs"
67
+ ? "0px 8px"
68
+ : size === "sm"
69
+ ? "0px 10px"
70
+ : size === "md"
71
+ ? "0px 12px"
72
+ : size === "lg"
73
+ ? "0px 14px"
74
+ : size === "xl"
75
+ ? "0px 16px"
76
+ : "0px 8px"};
77
+
78
+ &[data-button-right="true"] {
79
+ padding-right: 36px;
80
+ }
81
+
82
+ background-color: ${({ theme, variant }) => {
83
+ switch (variant) {
84
+ case "filled":
85
+ return theme.palette.input.background;
86
+ case "outlined":
87
+ return theme.palette.input.background;
88
+ case "text":
89
+ return "transparent";
90
+ default:
91
+ return theme.palette.input.background;
92
+ }
93
+ }};
94
+
95
+ &[readOnly] {
96
+ cursor: pointer;
97
+ }
98
+
99
+ & [data-has-space="true"] {
100
+ padding-left: 4px;
101
+ }
102
+
103
+ & [data-selected="true"] {
104
+ background-color: ${(props) => props.theme.palette.primary.main}50;
105
+ }
106
+
107
+ &[data-empty="true"] {
108
+ color: ${(props) => props.theme.palette.input.placeholder};
109
+ div {
110
+ color: ${(props) => props.theme.palette.input.placeholder};
111
+ }
112
+ }
113
+
114
+ & [data-default-btn="true"] {
115
+ color: ${(props) => props.theme.palette.text.secondary};
116
+ div {
117
+ color: ${(props) => props.theme.palette.text.secondary};
118
+ }
119
+ }
120
+
121
+ &:focus {
122
+ border: 1px solid ${(props) => props.theme.palette.primary.main};
123
+ }
124
+ `;
125
+ const InputSegment = styled.div `
126
+ user-select: none;
127
+ display: flex;
128
+ flex-direction: row;
129
+ align-items: center;
130
+ pointer-events: all;
131
+ outline: none;
132
+ border: none;
133
+ padding: 0;
134
+
135
+ height: ${({ size }) => size === "xs"
136
+ ? "22px"
137
+ : size === "sm"
138
+ ? "26px"
139
+ : size === "md"
140
+ ? "32px"
141
+ : size === "lg"
142
+ ? "38px"
143
+ : size === "xl"
144
+ ? "46px"
145
+ : "22px"};
146
+
147
+ height: 100%;
148
+
149
+ background-color: transparent;
150
+ color: ${(props) => props.theme.palette.text.primary};
151
+
152
+ ::placeholder {
153
+ font-size: ${({ size }) => size === "xs"
154
+ ? "10px"
155
+ : size === "sm"
156
+ ? "12px"
157
+ : size === "md"
158
+ ? "14px"
159
+ : size === "lg"
160
+ ? "16px"
161
+ : size === "xl"
162
+ ? "18px"
163
+ : "10px"};
164
+ }
165
+ `;
166
+ function parseTimestamp(timestamp, format, utc = false) {
167
+ // Define patterns to identify datetime components and their placeholders
168
+ const patterns = [
169
+ { pattern: "YYYY", placeholder: "YYYY", type: "year", momentType: "year" },
170
+ { pattern: "MM", placeholder: "MM", type: "month", momentType: "month" },
171
+ { pattern: "DD", placeholder: "DD", type: "day", momentType: "date" },
172
+ { pattern: "HH", placeholder: "HH", type: "hour", momentType: "hour" },
173
+ { pattern: "h", placeholder: "h", type: "hour", momentType: "hour" },
174
+ { pattern: "mm", placeholder: "mm", type: "minute", momentType: "minute" },
175
+ { pattern: "ss", placeholder: "ss", type: "second", momentType: "second" },
176
+ {
177
+ pattern: "SSS",
178
+ placeholder: "SSS",
179
+ type: "millisecond",
180
+ momentType: "millisecond",
181
+ },
182
+ {
183
+ pattern: "A",
184
+ placeholder: "AM/PM",
185
+ type: "meridiem",
186
+ momentType: "meridiem",
187
+ },
188
+ {
189
+ pattern: "Z",
190
+ placeholder: "Z",
191
+ type: "timezone",
192
+ momentType: "timezone",
193
+ },
194
+ ];
195
+ // Helper function to split format into datetime components and separators
196
+ function splitFormat(format) {
197
+ return format.split(/(YYYY|MM|DD|HH|h|mm|ss|SSS|Z)/).filter((s) => s);
198
+ }
199
+ // Helper function to match segments to their placeholders and types
200
+ function matchSegment(segment) {
201
+ const pattern = patterns.find((p) => p.pattern === segment);
202
+ return pattern
203
+ ? pattern
204
+ : {
205
+ pattern: segment,
206
+ placeholder: segment,
207
+ type: "separator",
208
+ value: "",
209
+ text: "",
210
+ index: -1,
211
+ };
212
+ }
213
+ const segments = splitFormat(format).map((segment, i) => {
214
+ const { pattern, placeholder, type, momentType } = matchSegment(segment);
215
+ const value = timestamp
216
+ ? utc === true
217
+ ? moment.utc(timestamp).format(pattern)
218
+ : moment(timestamp).format(pattern)
219
+ : placeholder;
220
+ return {
221
+ value,
222
+ text: value,
223
+ placeholder,
224
+ type,
225
+ momentType,
226
+ index: i,
227
+ };
228
+ });
229
+ return segments;
230
+ }
231
+ const DateInput = styled(({ className, defaultValue, format = "YYYY-MM-DD HH:mm:ss", label, description, arrow = true, size = "sm", variant = "outlined", clearable = false, required = false, onChange = () => { }, min, max, error, enableCalendar = false, utc = false, closeOnSelect = true, }) => {
232
+ const [value, setValue] = useState(defaultValue);
233
+ const [selectedSegment, setSelectedSegment] = useState();
234
+ const [isOpen, setIsOpen] = useState(false);
235
+ // Check if format is date only and does not include time
236
+ const isDateOnly = format.match(/(HH|h|mm|ss|SSS|A|Z)/) === null;
237
+ const mainRef = useRef(null);
238
+ const typedKeys = useRef("");
239
+ const { refs, floatingStyles } = useFloating({
240
+ open: isOpen,
241
+ onOpenChange: setIsOpen,
242
+ placement: "bottom-start",
243
+ strategy: "absolute",
244
+ // Handle collisions with the viewport
245
+ middleware: [flip(), offset(5)],
246
+ });
247
+ const segments = useMemo(() => parseTimestamp(moment(value).toISOString(), format, utc), [value, format, utc]);
248
+ const checkValidRange = (value) => {
249
+ if (min && moment(value).isBefore(min))
250
+ return false;
251
+ if (max && moment(value).isAfter(max))
252
+ return false;
253
+ return true;
254
+ };
255
+ const toggleOpen = () => {
256
+ setIsOpen((prev) => {
257
+ return !prev;
258
+ });
259
+ };
260
+ const handleClear = (e) => {
261
+ e.preventDefault();
262
+ e.stopPropagation();
263
+ setValue(null);
264
+ onChange === null || onChange === void 0 ? void 0 : onChange(null);
265
+ setIsOpen(false);
266
+ };
267
+ const handleSegmentClick = (e, segment) => {
268
+ e.stopPropagation();
269
+ e.preventDefault();
270
+ if (segment.type === "separator")
271
+ return;
272
+ if (mainRef === null || mainRef === void 0 ? void 0 : mainRef.current) {
273
+ const input = mainRef.current.querySelector("div[data-type='input']");
274
+ if (input) {
275
+ input.focus();
276
+ }
277
+ }
278
+ setSelectedSegment(segment);
279
+ };
280
+ const handleContainerClick = (e) => {
281
+ e.stopPropagation();
282
+ e.preventDefault();
283
+ if (mainRef === null || mainRef === void 0 ? void 0 : mainRef.current) {
284
+ const input = mainRef.current.querySelector("div[data-type='input']");
285
+ if (input) {
286
+ input.focus();
287
+ }
288
+ }
289
+ toggleOpen();
290
+ setIsOpen(true);
291
+ setSelectedSegment(segments[0]);
292
+ };
293
+ const nextSegment = () => {
294
+ setSelectedSegment((prev) => {
295
+ if (!prev)
296
+ return segments[0];
297
+ const next = segments[prev.index + 2];
298
+ return next || prev;
299
+ });
300
+ };
301
+ // prevent click and drag selection
302
+ const handleMouseDown = (e) => {
303
+ e.preventDefault();
304
+ };
305
+ const handleKeyDown = (e) => {
306
+ if (!selectedSegment)
307
+ return;
308
+ // tab
309
+ if (e.key === "Tab") {
310
+ setSelectedSegment(null);
311
+ setIsOpen(false);
312
+ return;
313
+ }
314
+ // Right Arrow
315
+ if (e.key === "ArrowRight") {
316
+ e.preventDefault();
317
+ setSelectedSegment((prev) => {
318
+ if (!prev)
319
+ return segments[0];
320
+ const next = segments[prev.index + 2];
321
+ return next || prev;
322
+ });
323
+ }
324
+ // Left Arrow
325
+ if (e.key === "ArrowLeft") {
326
+ e.preventDefault();
327
+ setSelectedSegment((prev) => {
328
+ if (!prev)
329
+ return segments[0];
330
+ const next = segments[prev.index - 2];
331
+ return next || prev;
332
+ });
333
+ }
334
+ // Up Arrow
335
+ if (e.key === "ArrowUp") {
336
+ e.preventDefault();
337
+ setValue((prev) => {
338
+ if (selectedSegment.type === "separator")
339
+ return prev;
340
+ let newValue = prev
341
+ ? moment(prev).add(1, selectedSegment.type).toISOString()
342
+ : moment().toISOString();
343
+ if (!checkValidRange(newValue))
344
+ return prev;
345
+ if (isDateOnly) {
346
+ newValue = moment(newValue).format("YYYY-MM-DD");
347
+ }
348
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
349
+ return newValue;
350
+ });
351
+ }
352
+ // Down Arrow
353
+ if (e.key === "ArrowDown") {
354
+ e.preventDefault();
355
+ setValue((prev) => {
356
+ if (selectedSegment.type === "separator")
357
+ return prev;
358
+ let newValue = prev
359
+ ? moment(prev).subtract(1, selectedSegment.type).toISOString()
360
+ : moment().toISOString();
361
+ if (!checkValidRange(newValue))
362
+ return prev;
363
+ if (isDateOnly) {
364
+ newValue = moment(newValue).format("YYYY-MM-DD");
365
+ }
366
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
367
+ return newValue;
368
+ });
369
+ }
370
+ // handle paste
371
+ if (e.key === "v" && (e.metaKey || e.ctrlKey)) {
372
+ return;
373
+ }
374
+ // only allow numbers
375
+ if (e.key.match(/[0-9]/)) {
376
+ e.preventDefault();
377
+ const segmentLength = selectedSegment.text.length;
378
+ typedKeys.current += e.key;
379
+ let tempValue = typedKeys.current;
380
+ if (["month", "day"].includes(selectedSegment.type) &&
381
+ Array.from(tempValue).every((c) => c === "0")) {
382
+ tempValue = "01";
383
+ }
384
+ setValue((prev) => {
385
+ if (!(selectedSegment === null || selectedSegment === void 0 ? void 0 : selectedSegment.momentType))
386
+ return prev;
387
+ const newValue = moment(prev)
388
+ .set(selectedSegment.momentType, parseInt(tempValue, 10) -
389
+ (selectedSegment.type === "month" ? 1 : 0))
390
+ .toISOString();
391
+ if (!checkValidRange(newValue))
392
+ return prev;
393
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
394
+ return newValue;
395
+ });
396
+ if (typedKeys.current.length === segmentLength) {
397
+ nextSegment();
398
+ typedKeys.current = "";
399
+ }
400
+ }
401
+ e.preventDefault();
402
+ };
403
+ const handleWheelEvent = (e) => {
404
+ if (!selectedSegment)
405
+ return;
406
+ if (e.deltaY > 0) {
407
+ setValue((prev) => {
408
+ if (selectedSegment.type === "separator")
409
+ return prev;
410
+ const newValue = prev
411
+ ? moment(prev).subtract(1, selectedSegment.type).toISOString()
412
+ : moment().toISOString();
413
+ if (!checkValidRange(newValue))
414
+ return prev;
415
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
416
+ return newValue;
417
+ });
418
+ }
419
+ else {
420
+ setValue((prev) => {
421
+ if (selectedSegment.type === "separator")
422
+ return prev;
423
+ const newValue = prev
424
+ ? moment(prev).add(1, selectedSegment.type).toISOString()
425
+ : moment().toISOString();
426
+ if (!checkValidRange(newValue))
427
+ return prev;
428
+ onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
429
+ return newValue;
430
+ });
431
+ }
432
+ };
433
+ const handlePaste = (e) => {
434
+ var _a, _b;
435
+ e.preventDefault();
436
+ 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");
437
+ if (!pastedText)
438
+ return;
439
+ // check if pasted text is a valid timestamp
440
+ if (!moment(pastedText).isValid())
441
+ return;
442
+ const parsedTimestamp = moment.utc(pastedText).toISOString();
443
+ setValue(parsedTimestamp);
444
+ };
445
+ // Close on outside click
446
+ useEffect(() => {
447
+ const close = (e) => {
448
+ var _a, _b;
449
+ const target = e.target;
450
+ const referenceElement = (_a = refs === null || refs === void 0 ? void 0 : refs.reference) === null || _a === void 0 ? void 0 : _a.current;
451
+ const floatingElement = (_b = refs === null || refs === void 0 ? void 0 : refs.floating) === null || _b === void 0 ? void 0 : _b.current;
452
+ if (floatingElement && // Check if the floating element exists
453
+ e.target !== referenceElement && // Check if the target is not the reference (input)
454
+ !referenceElement.contains(target) && // Check if the target is not inside the reference (input)
455
+ !floatingElement.contains(target) // Check if the target is not inside the floating element (content)
456
+ ) {
457
+ setIsOpen(false);
458
+ }
459
+ setSelectedSegment(null); // clear selected segment when clicked outside component
460
+ };
461
+ document.addEventListener("click", close);
462
+ return () => document.removeEventListener("click", close);
463
+ }, [refs.floating]);
464
+ // Global Wheel Event when segement selected
465
+ useEffect(() => {
466
+ if (selectedSegment) {
467
+ document.addEventListener("wheel", handleWheelEvent);
468
+ }
469
+ return () => {
470
+ document.removeEventListener("wheel", handleWheelEvent);
471
+ };
472
+ }, [selectedSegment]);
473
+ return (_jsxs("div", { className: className, children: [label && (_jsx(FieldLabel, { error: error, asterisk: required, size: size, description: description, children: label })), _jsxs(StyledInputContainer, { ref: (ref) => {
474
+ mainRef.current = ref;
475
+ refs.setReference(ref);
476
+ }, onClick: handleContainerClick, onMouseDown: handleMouseDown, onKeyDown: handleKeyDown, onPaste: handlePaste, onFocus: (e) => {
477
+ e.preventDefault();
478
+ setSelectedSegment(segments[0]);
479
+ }, "data-empty": !value, role: "textbox", size: size, variant: variant, "data-button-right": arrow || clearable, children: [segments.map((segment, i) => {
480
+ if (segment.type === "separator") {
481
+ return (_jsx("div", { className: "separator", tabIndex: -1, onClick: (e) => {
482
+ e.preventDefault();
483
+ e.stopPropagation();
484
+ }, 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));
485
+ }
486
+ return (_jsx(InputSegment, { className: "input", contentEditable: true, suppressContentEditableWarning: true, 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));
487
+ }), 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, { ref: refs.setFloating, style: floatingStyles, 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) => {
488
+ setValue((prev) => {
489
+ // make copy of prev variable
490
+ const oldValue = moment(prev).toISOString();
491
+ const result = `${moment(date).format("YYYY-MM-DD")}T${moment(prev || undefined).format("HH:mm:ss")}`;
492
+ let isoResult = moment(result).toISOString();
493
+ if (!checkValidRange(result))
494
+ return oldValue;
495
+ if (isDateOnly) {
496
+ isoResult = moment(result).format("YYYY-MM-DD");
497
+ }
498
+ onChange === null || onChange === void 0 ? void 0 : onChange(isoResult);
499
+ setIsOpen(closeOnSelect ? false : true);
500
+ return isoResult;
501
+ });
502
+ }, includeTime: false }, 1) }) }) }) }))] }));
503
+ }) ``;
504
+ export default DateInput;
@@ -0,0 +1 @@
1
+ export { default } from "./DateInput";