@monolith-forensics/monolith-ui 1.8.1-dev.1 → 1.8.1-dev.3

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 (107) hide show
  1. package/dist/Calendar/Calendar.d.ts +4 -1
  2. package/dist/Calendar/Calendar.js +126 -50
  3. package/dist/Calendar/CalendarStyles.d.ts +3 -2
  4. package/dist/Calendar/CalendarStyles.js +67 -25
  5. package/dist/Calendar/calendarHelpers.d.ts +1 -1
  6. package/dist/CheckBox/CheckBox.js +35 -4
  7. package/dist/DateTimeRangePicker/DateTimeRangePicker.d.ts +41 -0
  8. package/dist/DateTimeRangePicker/DateTimeRangePicker.js +363 -0
  9. package/dist/DateTimeRangePicker/index.d.ts +2 -0
  10. package/dist/DateTimeRangePicker/index.js +2 -0
  11. package/dist/DropDownMenu/DropDownMenu.js +25 -15
  12. package/dist/DropDownMenu/components/MenuComponent.js +6 -1
  13. package/dist/DropDownMenu/components/MenuItem.d.ts +2 -0
  14. package/dist/DropDownMenu/components/MenuItem.js +22 -9
  15. package/dist/DropDownMenu/components/MenuItemList.d.ts +3 -0
  16. package/dist/DropDownMenu/components/MenuItemList.js +186 -63
  17. package/dist/DropDownMenu/components/StyledContent.js +1 -2
  18. package/dist/DropDownMenu/types.d.ts +3 -0
  19. package/dist/FileViewer/viewers/ImageViewer.js +75 -18
  20. package/dist/MonolithUIProvider/MonolithUIProvider.d.ts +1 -0
  21. package/dist/QueryFilter/DefaultOperators.d.ts +1 -76
  22. package/dist/QueryFilter/DefaultOperators.js +1 -21
  23. package/dist/QueryFilter/QueryFilter.constants.d.ts +134 -0
  24. package/dist/QueryFilter/QueryFilter.constants.js +39 -0
  25. package/dist/QueryFilter/QueryFilter.d.ts +1 -1
  26. package/dist/QueryFilter/QueryFilter.js +3 -303
  27. package/dist/QueryFilter/QueryFilter.lib.d.ts +14 -0
  28. package/dist/QueryFilter/QueryFilter.lib.js +84 -0
  29. package/dist/QueryFilter/QueryFilter.styled.d.ts +89 -0
  30. package/dist/QueryFilter/QueryFilter.styled.js +184 -0
  31. package/dist/QueryFilter/QueryFilter.types.d.ts +61 -0
  32. package/dist/QueryFilter/QueryFilter.types.js +1 -0
  33. package/dist/QueryFilter/components/MultiSelectEditor.d.ts +7 -0
  34. package/dist/QueryFilter/components/MultiSelectEditor.js +44 -0
  35. package/dist/QueryFilter/components/RuleChip.d.ts +8 -0
  36. package/dist/QueryFilter/components/RuleChip.js +37 -0
  37. package/dist/QueryFilter/components/Rules.d.ts +11 -0
  38. package/dist/QueryFilter/components/Rules.js +41 -0
  39. package/dist/QueryFilter/components/UnavailableRuleChip.d.ts +5 -0
  40. package/dist/QueryFilter/components/UnavailableRuleChip.js +7 -0
  41. package/dist/QueryFilter/components/ValueEditor.d.ts +7 -0
  42. package/dist/QueryFilter/components/ValueEditor.js +45 -0
  43. package/dist/QueryFilter/components/ValueSelector.d.ts +7 -0
  44. package/dist/QueryFilter/components/ValueSelector.js +34 -0
  45. package/dist/QueryFilter/components/index.d.ts +6 -0
  46. package/dist/QueryFilter/components/index.js +6 -0
  47. package/dist/QueryFilter/index.d.ts +3 -2
  48. package/dist/QueryFilter/index.js +3 -2
  49. package/dist/QueryFilter/types.d.ts +1 -52
  50. package/dist/QueryFilter/types.js +1 -1
  51. package/dist/QueryFilter/useQueryFilter.d.ts +1 -1
  52. package/dist/QueryFilter/useQueryFilter.js +23 -19
  53. package/dist/RichTextEditor/Extensions/getTiptapExtensions.js +5 -15
  54. package/dist/RichTextEditor/Plugins/ImageActionsPlugin.d.ts +3 -0
  55. package/dist/RichTextEditor/Plugins/ImageActionsPlugin.js +241 -0
  56. package/dist/RichTextEditor/Plugins/UploadImagesPlugin.d.ts +15 -0
  57. package/dist/RichTextEditor/Plugins/UploadImagesPlugin.js +115 -51
  58. package/dist/RichTextEditor/Plugins/index.d.ts +1 -0
  59. package/dist/RichTextEditor/Plugins/index.js +1 -0
  60. package/dist/RichTextEditor/RichTextEditor.d.ts +3 -2
  61. package/dist/RichTextEditor/RichTextEditor.js +302 -35
  62. package/dist/SuperDatePicker/SuperDatePicker.constants.d.ts +24 -0
  63. package/dist/SuperDatePicker/SuperDatePicker.constants.js +30 -0
  64. package/dist/SuperDatePicker/SuperDatePicker.d.ts +3 -0
  65. package/dist/SuperDatePicker/SuperDatePicker.js +31 -0
  66. package/dist/SuperDatePicker/SuperDatePicker.lib.d.ts +17 -0
  67. package/dist/SuperDatePicker/SuperDatePicker.lib.js +206 -0
  68. package/dist/SuperDatePicker/SuperDatePicker.styled.d.ts +60 -0
  69. package/dist/SuperDatePicker/SuperDatePicker.styled.js +256 -0
  70. package/dist/SuperDatePicker/SuperDatePicker.types.d.ts +48 -0
  71. package/dist/SuperDatePicker/SuperDatePicker.types.js +1 -0
  72. package/dist/SuperDatePicker/components/CommonPresetGroups.d.ts +7 -0
  73. package/dist/SuperDatePicker/components/CommonPresetGroups.js +6 -0
  74. package/dist/SuperDatePicker/components/EndpointCalendarDropdown.d.ts +10 -0
  75. package/dist/SuperDatePicker/components/EndpointCalendarDropdown.js +9 -0
  76. package/dist/SuperDatePicker/components/EndpointDateInput.d.ts +16 -0
  77. package/dist/SuperDatePicker/components/EndpointDateInput.js +26 -0
  78. package/dist/SuperDatePicker/components/EndpointPopover.d.ts +18 -0
  79. package/dist/SuperDatePicker/components/EndpointPopover.js +11 -0
  80. package/dist/SuperDatePicker/components/QuickRangeDropdown.d.ts +14 -0
  81. package/dist/SuperDatePicker/components/QuickRangeDropdown.js +19 -0
  82. package/dist/SuperDatePicker/components/QuickRangePopover.d.ts +18 -0
  83. package/dist/SuperDatePicker/components/QuickRangePopover.js +12 -0
  84. package/dist/SuperDatePicker/components/index.d.ts +6 -0
  85. package/dist/SuperDatePicker/components/index.js +6 -0
  86. package/dist/SuperDatePicker/index.d.ts +3 -0
  87. package/dist/SuperDatePicker/index.js +3 -0
  88. package/dist/SuperDatePicker/useSuperDatePicker.d.ts +32 -0
  89. package/dist/SuperDatePicker/useSuperDatePicker.js +125 -0
  90. package/dist/Table/ColumnResizer.d.ts +6 -9
  91. package/dist/Table/ColumnResizer.js +30 -10
  92. package/dist/Table/TableComponents.js +14 -10
  93. package/dist/Table/TableHeader.js +31 -16
  94. package/dist/Table/TableMenu/TableMenu.js +1 -1
  95. package/dist/Table/TableProvider.js +91 -4
  96. package/dist/Table/TableRow.js +19 -12
  97. package/dist/Table/Utils/index.d.ts +0 -1
  98. package/dist/Table/Utils/index.js +0 -1
  99. package/dist/Table/types.d.ts +6 -19
  100. package/dist/TagBox/TagBox.d.ts +1 -1
  101. package/dist/TagBox/TagBox.js +6 -6
  102. package/dist/TagBox/types.d.ts +1 -0
  103. package/dist/TextArea/TextArea.js +5 -0
  104. package/dist/index.d.ts +2 -0
  105. package/dist/index.js +1 -0
  106. package/dist/theme/variants.js +2 -0
  107. package/package.json +22 -18
@@ -0,0 +1,363 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { autoUpdate, flip, FloatingPortal, offset, shift, useDismiss, useFloating, useInteractions, } from "@floating-ui/react";
3
+ import moment from "moment";
4
+ import { CalendarDaysIcon, Clock3Icon } from "lucide-react";
5
+ import { forwardRef, useCallback, useEffect, useMemo, useRef, useState, } from "react";
6
+ import styled from "styled-components";
7
+ import { Button, Calendar, DateInput, FieldLabel, SegmentedControl } from "..";
8
+ import { ArrowButton, ClearButton, getControlSizeTokens, StyledContent, StyledFloatContainer, } from "../core";
9
+ const DEFAULT_FORMAT = "YYYY-MM-DD HH:mm:ss";
10
+ const resolveNow = (utc) => (utc ? moment.utc() : moment());
11
+ const serializeMoment = (value, utc) => {
12
+ const next = utc ? value.clone().utc() : value.clone();
13
+ return next.toISOString();
14
+ };
15
+ const getDefaultPresets = (utc) => {
16
+ const makePreset = (label, amount, unit) => ({
17
+ label,
18
+ getRange: () => {
19
+ const end = resolveNow(utc);
20
+ const start = end.clone().subtract(amount, unit);
21
+ return {
22
+ start: serializeMoment(start, utc),
23
+ end: serializeMoment(end, utc),
24
+ };
25
+ },
26
+ });
27
+ return [
28
+ makePreset("Last 15 minutes", 15, "minutes"),
29
+ makePreset("Last 30 minutes", 30, "minutes"),
30
+ makePreset("Last 1 hour", 1, "hour"),
31
+ makePreset("Last 24 hours", 24, "hours"),
32
+ makePreset("Last 7 days", 7, "days"),
33
+ makePreset("Last 30 days", 30, "days"),
34
+ ];
35
+ };
36
+ const parseRangeMoment = (value, utc) => {
37
+ if (!value)
38
+ return null;
39
+ const parsed = utc ? moment.utc(value) : moment(value);
40
+ return parsed.isValid() ? parsed : null;
41
+ };
42
+ const momentToCalendarDate = (value, utc) => {
43
+ const parsed = parseRangeMoment(value, utc);
44
+ if (!parsed)
45
+ return undefined;
46
+ if (!utc)
47
+ return parsed.toDate();
48
+ return new Date(parsed.year(), parsed.month(), parsed.date(), parsed.hour(), parsed.minute(), parsed.second(), parsed.millisecond());
49
+ };
50
+ const calendarDateToMoment = (value, utc) => {
51
+ if (!utc)
52
+ return moment(value);
53
+ return moment.utc({
54
+ year: value.getFullYear(),
55
+ month: value.getMonth(),
56
+ date: value.getDate(),
57
+ hour: value.getHours(),
58
+ minute: value.getMinutes(),
59
+ second: value.getSeconds(),
60
+ millisecond: value.getMilliseconds(),
61
+ });
62
+ };
63
+ const formatDisplay = (value, format, utc) => {
64
+ const parsed = parseRangeMoment(value, utc);
65
+ if (!parsed)
66
+ return "";
67
+ return parsed.format(format);
68
+ };
69
+ const StyledContainer = styled.div.attrs({
70
+ className: "mfui-DateTimeRangePicker",
71
+ }) `
72
+ width: ${({ $width }) => {
73
+ if ($width === undefined || $width === null)
74
+ return "100%";
75
+ return typeof $width === "number" ? `${$width}px` : $width;
76
+ }};
77
+ `;
78
+ const StyledTrigger = styled.button `
79
+ position: relative;
80
+ display: flex;
81
+ align-items: center;
82
+ gap: ${({ size }) => `${getControlSizeTokens(size).iconGap}px`};
83
+ width: 100%;
84
+ height: ${({ size }) => `${getControlSizeTokens(size).height}px`};
85
+ padding: ${({ size }) => `0 ${getControlSizeTokens(size).adornmentWidth}px 0 ${getControlSizeTokens(size).inputPaddingX}px`};
86
+ border-radius: 5px;
87
+ border: 1px solid
88
+ ${({ theme, variant }) => variant === "filled" || variant === "text"
89
+ ? "transparent"
90
+ : theme.palette.input.border};
91
+ outline: none;
92
+ background: ${({ theme, variant }) => variant === "text" ? "transparent" : theme.palette.input.background};
93
+ color: ${({ theme }) => theme.palette.text.primary};
94
+ font-family: ${({ theme }) => theme.typography.fontFamily};
95
+ font-size: ${({ size }) => `${getControlSizeTokens(size).fontSize}px`};
96
+ text-align: left;
97
+ cursor: pointer;
98
+ transition: border 0.1s ease-in-out;
99
+
100
+ &:focus-visible,
101
+ &:focus {
102
+ border-color: ${({ theme }) => theme.palette.primary.main};
103
+ }
104
+
105
+ &:disabled {
106
+ cursor: not-allowed;
107
+ opacity: 0.5;
108
+ }
109
+ `;
110
+ const TriggerIcon = styled.span `
111
+ display: inline-flex;
112
+ align-items: center;
113
+ color: ${({ theme }) => theme.palette.text.secondary};
114
+
115
+ svg {
116
+ width: ${({ size }) => `${getControlSizeTokens(size).iconSize}px`};
117
+ height: ${({ size }) => `${getControlSizeTokens(size).iconSize}px`};
118
+ }
119
+ `;
120
+ const TriggerText = styled.span `
121
+ min-width: 0;
122
+ overflow: hidden;
123
+ text-overflow: ellipsis;
124
+ white-space: nowrap;
125
+ color: ${({ theme, $empty }) => $empty ? theme.palette.input.placeholder : theme.palette.text.primary};
126
+ `;
127
+ const TriggerActions = styled.span `
128
+ position: absolute;
129
+ right: 0;
130
+ top: 0;
131
+ display: flex;
132
+ height: 100%;
133
+ `;
134
+ const PickerPanel = styled.div `
135
+ display: grid;
136
+ grid-template-columns: 172px minmax(430px, 1fr);
137
+ gap: 10px;
138
+ width: min(720px, calc(100vw - 32px));
139
+
140
+ @media (max-width: 640px) {
141
+ grid-template-columns: minmax(0, 1fr);
142
+ width: calc(100vw - 32px);
143
+ }
144
+ `;
145
+ const PresetColumn = styled.div `
146
+ display: flex;
147
+ flex-direction: column;
148
+ gap: 4px;
149
+ padding-right: 10px;
150
+ border-right: 1px solid ${({ theme }) => theme.palette.divider};
151
+
152
+ @media (max-width: 640px) {
153
+ padding-right: 0;
154
+ padding-bottom: 10px;
155
+ border-right: none;
156
+ border-bottom: 1px solid ${({ theme }) => theme.palette.divider};
157
+ }
158
+ `;
159
+ const PanelTitle = styled.div `
160
+ font-size: 11px;
161
+ font-weight: 700;
162
+ line-height: 1.2;
163
+ text-transform: uppercase;
164
+ color: ${({ theme }) => theme.palette.text.secondary};
165
+ margin-bottom: 4px;
166
+ `;
167
+ const PresetButton = styled.button `
168
+ display: flex;
169
+ align-items: center;
170
+ width: 100%;
171
+ min-height: 28px;
172
+ padding: 0 8px;
173
+ border: none;
174
+ border-radius: 4px;
175
+ background: transparent;
176
+ color: ${({ theme }) => theme.palette.text.primary};
177
+ font: inherit;
178
+ font-size: 12px;
179
+ text-align: left;
180
+ cursor: pointer;
181
+
182
+ &:hover,
183
+ &:focus-visible {
184
+ background: ${({ theme }) => theme.palette.action.hover};
185
+ outline: none;
186
+ }
187
+ `;
188
+ const CustomColumn = styled.div `
189
+ display: flex;
190
+ flex-direction: column;
191
+ gap: 10px;
192
+ min-width: 0;
193
+ `;
194
+ const InputGrid = styled.div `
195
+ display: grid;
196
+ grid-template-columns: repeat(2, minmax(0, 1fr));
197
+ gap: 8px;
198
+
199
+ @media (max-width: 640px) {
200
+ grid-template-columns: minmax(0, 1fr);
201
+ }
202
+ `;
203
+ const EndpointField = styled.div `
204
+ min-width: 0;
205
+ `;
206
+ const ActiveControlRow = styled.div `
207
+ display: flex;
208
+ align-items: center;
209
+ justify-content: space-between;
210
+ gap: 10px;
211
+ `;
212
+ const CalendarShell = styled.div `
213
+ display: flex;
214
+ justify-content: center;
215
+ padding: 8px;
216
+ overflow-x: auto;
217
+ border: 1px solid ${({ theme }) => theme.palette.divider};
218
+ border-radius: 5px;
219
+ background: ${({ theme }) => theme.palette.background.paper};
220
+ `;
221
+ const ValidationText = styled.div `
222
+ min-height: 16px;
223
+ font-size: 11px;
224
+ color: ${({ theme }) => theme.palette.error.main};
225
+ `;
226
+ const ActionRow = styled.div `
227
+ display: flex;
228
+ justify-content: flex-end;
229
+ gap: 8px;
230
+ `;
231
+ const FooterMeta = styled.div `
232
+ display: flex;
233
+ align-items: center;
234
+ gap: 5px;
235
+ margin-right: auto;
236
+ color: ${({ theme }) => theme.palette.text.secondary};
237
+ font-size: 11px;
238
+
239
+ svg {
240
+ width: 13px;
241
+ height: 13px;
242
+ }
243
+ `;
244
+ const DateTimeRangePicker = forwardRef(({ className, style, defaultValue = { start: null, end: null }, value, onChange = () => { }, label, description, placeholder = "Select date/time range", startLabel = "Start", endLabel = "End", format = DEFAULT_FORMAT, size = "sm", variant = "outlined", required = false, clearable = true, disabled = false, error, width, min, max, utc = false, presets, }, ref) => {
245
+ var _a, _b;
246
+ const isControlled = useRef(value !== undefined);
247
+ const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
248
+ const _value = isControlled.current ? value || {} : uncontrolledValue;
249
+ const [isOpen, setIsOpen] = useState(false);
250
+ const [draftValue, setDraftValue] = useState(_value);
251
+ const [activeEndpoint, setActiveEndpoint] = useState("start");
252
+ const resolvedPresets = useMemo(() => presets || getDefaultPresets(utc), [presets, utc]);
253
+ const { refs, floatingStyles, context } = useFloating({
254
+ open: isOpen,
255
+ onOpenChange: setIsOpen,
256
+ placement: "bottom-start",
257
+ strategy: "absolute",
258
+ middleware: [offset(5), flip(), shift({ padding: 8 })],
259
+ whileElementsMounted: autoUpdate,
260
+ });
261
+ const dismiss = useDismiss(context, {
262
+ outsidePress: (event) => {
263
+ var _a, _b, _c;
264
+ const target = event.target;
265
+ if (((_a = target === null || target === void 0 ? void 0 : target.closest) === null || _a === void 0 ? void 0 : _a.call(target, ".mfui-DateInput")) ||
266
+ ((_b = target === null || target === void 0 ? void 0 : target.closest) === null || _b === void 0 ? void 0 : _b.call(target, ".mfui-DropDownMenu")) ||
267
+ ((_c = target === null || target === void 0 ? void 0 : target.closest) === null || _c === void 0 ? void 0 : _c.call(target, ".Menu"))) {
268
+ return false;
269
+ }
270
+ return true;
271
+ },
272
+ });
273
+ const { getReferenceProps, getFloatingProps } = useInteractions([dismiss]);
274
+ useEffect(() => {
275
+ if (isOpen) {
276
+ setDraftValue(_value);
277
+ setActiveEndpoint(_value.start ? "end" : "start");
278
+ }
279
+ }, [isOpen, _value.start, _value.end]);
280
+ const commitValue = useCallback((nextValue, meta) => {
281
+ if (!isControlled.current) {
282
+ setUncontrolledValue(nextValue);
283
+ }
284
+ onChange(nextValue, meta);
285
+ }, [onChange]);
286
+ const displayValue = useMemo(() => {
287
+ if (!_value.start && !_value.end)
288
+ return "";
289
+ const start = formatDisplay(_value.start, format, utc) || "Start";
290
+ const end = formatDisplay(_value.end, format, utc) || "End";
291
+ return `${start} - ${end}${utc ? " UTC" : ""}`;
292
+ }, [_value.start, _value.end, format, utc]);
293
+ const validationError = useMemo(() => {
294
+ const start = parseRangeMoment(draftValue.start, utc);
295
+ const end = parseRangeMoment(draftValue.end, utc);
296
+ if (!start || !end)
297
+ return "Select both a start and end timestamp.";
298
+ if (start.isAfter(end))
299
+ return "Start timestamp must be before end.";
300
+ if (min && start.isBefore(moment(min)))
301
+ return "Start is before minimum.";
302
+ if (max && end.isAfter(moment(max)))
303
+ return "End is after maximum.";
304
+ return "";
305
+ }, [draftValue.start, draftValue.end, min, max, utc]);
306
+ const patchDraft = (patch) => {
307
+ setDraftValue((prev) => (Object.assign(Object.assign({}, prev), patch)));
308
+ };
309
+ const handleClear = (event) => {
310
+ event === null || event === void 0 ? void 0 : event.preventDefault();
311
+ event === null || event === void 0 ? void 0 : event.stopPropagation();
312
+ const emptyValue = { start: null, end: null };
313
+ setDraftValue(emptyValue);
314
+ commitValue(emptyValue, { source: "clear" });
315
+ setIsOpen(false);
316
+ };
317
+ const handleApply = () => {
318
+ if (validationError)
319
+ return;
320
+ commitValue(draftValue, { source: "apply" });
321
+ setIsOpen(false);
322
+ };
323
+ const handleCancel = () => {
324
+ setDraftValue(_value);
325
+ setIsOpen(false);
326
+ };
327
+ const handlePreset = (preset) => {
328
+ const nextValue = preset.getRange();
329
+ setDraftValue(nextValue);
330
+ commitValue(nextValue, { source: "preset", preset });
331
+ setIsOpen(false);
332
+ };
333
+ const handleCalendarChange = (date) => {
334
+ if (!date) {
335
+ patchDraft({ [activeEndpoint]: null });
336
+ return;
337
+ }
338
+ patchDraft({
339
+ [activeEndpoint]: serializeMoment(calendarDateToMoment(date, utc), utc),
340
+ });
341
+ };
342
+ const activeValue = draftValue[activeEndpoint];
343
+ const activeMin = activeEndpoint === "end"
344
+ ? ((_a = parseRangeMoment(draftValue.start, utc)) === null || _a === void 0 ? void 0 : _a.toDate()) || min
345
+ : min;
346
+ const activeMax = activeEndpoint === "start"
347
+ ? ((_b = parseRangeMoment(draftValue.end, utc)) === null || _b === void 0 ? void 0 : _b.toDate()) || max
348
+ : max;
349
+ return (_jsxs(StyledContainer, Object.assign({ ref: (node) => {
350
+ if (typeof ref === "function") {
351
+ ref(node);
352
+ }
353
+ else if (ref) {
354
+ ref.current = node;
355
+ }
356
+ refs.setReference(node);
357
+ }, className: className, "$width": width }, getReferenceProps(), { children: [label && (_jsx(FieldLabel, { error: error, asterisk: required, size: size, description: description, children: label })), _jsxs(StyledTrigger, { type: "button", size: size, variant: variant, disabled: disabled, style: style, "aria-haspopup": "dialog", "aria-expanded": isOpen, onClick: () => setIsOpen((prev) => !prev), children: [_jsx(TriggerIcon, { size: size, children: _jsx(CalendarDaysIcon, {}) }), _jsx(TriggerText, { "$empty": !displayValue, children: displayValue || placeholder }), _jsx(TriggerActions, { children: clearable && (_value.start || _value.end) ? (_jsx(ClearButton, { size: size, onClick: handleClear })) : (_jsx(ArrowButton, { size: size })) })] }), !disabled && isOpen && (_jsx(FloatingPortal, { preserveTabOrder: true, children: _jsx(StyledFloatContainer, Object.assign({ ref: refs.setFloating, style: floatingStyles }, getFloatingProps(), { children: _jsx(StyledContent, { maxDropdownHeight: "fit-content", children: _jsxs(PickerPanel, { children: [_jsxs(PresetColumn, { children: [_jsx(PanelTitle, { children: "Quick ranges" }), resolvedPresets.map((preset) => (_jsx(PresetButton, { type: "button", onClick: () => handlePreset(preset), children: preset.label }, preset.label)))] }), _jsxs(CustomColumn, { children: [_jsxs(InputGrid, { children: [_jsx(EndpointField, { onClick: () => setActiveEndpoint("start"), children: _jsx(DateInput, { label: startLabel, value: draftValue.start, onChange: (next) => patchDraft({ start: next }), format: format, size: size, variant: variant, clearable: true, utc: utc, min: min, max: activeEndpoint === "start" ? activeMax : max }) }), _jsx(EndpointField, { onClick: () => setActiveEndpoint("end"), children: _jsx(DateInput, { label: endLabel, value: draftValue.end, onChange: (next) => patchDraft({ end: next }), format: format, size: size, variant: variant, clearable: true, utc: utc, min: activeEndpoint === "end" ? activeMin : min, max: max }) })] }), _jsxs(ActiveControlRow, { children: [_jsxs(PanelTitle, { children: ["Editing ", activeEndpoint === "start" ? startLabel : endLabel] }), _jsx(SegmentedControl, { data: [
358
+ { label: startLabel, value: "start" },
359
+ { label: endLabel, value: "end" },
360
+ ], value: activeEndpoint, onChange: (next) => setActiveEndpoint(next), size: "xs" })] }), _jsx(CalendarShell, { children: _jsx(Calendar, { value: momentToCalendarDate(activeValue, utc), onChange: handleCalendarChange, includeTime: true, clearable: false, min: activeMin, max: activeMax }) }), _jsx(ValidationText, { children: validationError }), _jsxs(ActionRow, { children: [_jsxs(FooterMeta, { children: [_jsx(Clock3Icon, {}), utc ? "UTC" : "Local time"] }), clearable && (_jsx(Button, { type: "button", size: size, variant: "subtle", onClick: handleClear, children: "Clear" })), _jsx(Button, { type: "button", size: size, variant: "outlined", onClick: handleCancel, children: "Cancel" }), _jsx(Button, { type: "button", size: size, variant: "contained", onClick: handleApply, disabled: Boolean(validationError), children: "Apply" })] })] })] }) }) })) }))] })));
361
+ });
362
+ DateTimeRangePicker.displayName = "DateTimeRangePicker";
363
+ export default DateTimeRangePicker;
@@ -0,0 +1,2 @@
1
+ export { default } from "./DateTimeRangePicker";
2
+ export * from "./DateTimeRangePicker";
@@ -0,0 +1,2 @@
1
+ export { default } from "./DateTimeRangePicker";
2
+ export * from "./DateTimeRangePicker";
@@ -1,29 +1,39 @@
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, grouped, onAddNew, loading, onScroll, onScrollToTop, onScrollToBottom, onSearch, manualSearch, multiselect, renderOption, onItemSelect, onChange, buttonProps, TooltipContent, dropDownProps, query, disabled, }) => {
4
+ export const DropDownMenu = ({ data, children, defaultValue, value, variant, arrow, size, searchable, grouped, onAddNew, loading, onScroll, onScrollToTop, onScrollToBottom, onSearch, manualSearch, multiselect, enableSelectAll, renderOption, dynamicOptionHeight, 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
- const [selected, setSelected] = useState(defaultValue || []);
7
+ const [internalSelected, setInternalSelected] = useState(defaultValue || []);
8
+ const isControlled = value !== undefined;
9
+ const selected = isControlled ? value || [] : internalSelected;
10
+ const updateSelected = (newSelected, diff) => {
11
+ if (!isControlled) {
12
+ setInternalSelected(newSelected);
13
+ }
14
+ onChange === null || onChange === void 0 ? void 0 : onChange(newSelected, diff);
15
+ };
16
+ const isSameItem = (a, b) => isObjectArray ? (a === null || a === void 0 ? void 0 : a.value) === (b === null || b === void 0 ? void 0 : b.value) : a === b;
8
17
  const handleAddItem = (item) => {
9
- setSelected((prev) => {
10
- let newSelected = [...prev, item];
11
- const diff = [item];
12
- onChange === null || onChange === void 0 ? void 0 : onChange(newSelected, diff);
13
- return newSelected;
14
- });
18
+ if (!multiselect) {
19
+ updateSelected([item], [item]);
20
+ return;
21
+ }
22
+ const nextSelected = selected.some((selectedItem) => isSameItem(selectedItem, item))
23
+ ? selected
24
+ : [...selected, item];
25
+ updateSelected(nextSelected, [item]);
15
26
  };
16
27
  const handleRemoveItem = (item) => {
17
- setSelected((prev) => {
18
- let newSelected = prev.filter((i) => isObjectArray ? (i === null || i === void 0 ? void 0 : i.value) !== (item === null || item === void 0 ? void 0 : item.value) : i !== item);
19
- const diff = [item];
20
- onChange === null || onChange === void 0 ? void 0 : onChange(newSelected, diff);
21
- return newSelected;
22
- });
28
+ const newSelected = selected.filter((i) => !isSameItem(i, item));
29
+ updateSelected(newSelected, [item]);
30
+ };
31
+ const handleSetSelected = (newSelected, diff) => {
32
+ updateSelected(newSelected, diff);
23
33
  };
24
34
  const handleMenuClose = () => { };
25
35
  const handleScrollToBottom = (e) => {
26
36
  onScrollToBottom === null || onScrollToBottom === void 0 ? void 0 : onScrollToBottom(e);
27
37
  };
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 }))] }) }));
38
+ 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, dynamicOptionHeight: dynamicOptionHeight, selected: selected, TooltipContent: TooltipContent, multiselect: multiselect, enableSelectAll: enableSelectAll, size: size, handleAddItem: handleAddItem, handleRemoveItem: handleRemoveItem, handleSetSelected: handleSetSelected, onItemSelect: onItemSelect, renderOption: renderOption, onScroll: onScroll, onScrollToTop: onScrollToTop, onScrollToBottom: handleScrollToBottom, query: query }))] }) }));
29
39
  };
@@ -11,7 +11,7 @@ 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 { forwardRef, useContext, useEffect, useRef, useState } from "react";
14
- import { autoUpdate, flip, FloatingFocusManager, FloatingList, FloatingNode, FloatingPortal, offset, safePolygon, shift, useClick, useDismiss, useFloating, useFloatingNodeId, useFloatingParentNodeId, useFloatingTree, useHover, useInteractions, useListItem, useListNavigation, useMergeRefs, useRole, useTypeahead, } from "@floating-ui/react";
14
+ import { autoUpdate, flip, FloatingFocusManager, FloatingList, FloatingNode, FloatingPortal, offset, safePolygon, shift, size as floatingSize, useClick, useDismiss, useFloating, useFloatingNodeId, useFloatingParentNodeId, useFloatingTree, useHover, useInteractions, useListItem, useListNavigation, useMergeRefs, useRole, useTypeahead, } from "@floating-ui/react";
15
15
  import { ChevronDownIcon, ChevronRightIcon } from "lucide-react";
16
16
  import { getControlSizeTokens } from "../../core";
17
17
  import { MenuContext } from "./MenuContext";
@@ -43,6 +43,11 @@ export const MenuComponent = forwardRef((_a, forwardedRef) => {
43
43
  }),
44
44
  flip(),
45
45
  shift(),
46
+ floatingSize({
47
+ apply({ rects, elements }) {
48
+ elements.floating.style.setProperty("--mfui-dropdown-reference-width", `${rects.reference.width}px`);
49
+ },
50
+ }),
46
51
  ],
47
52
  whileElementsMounted: autoUpdate,
48
53
  });
@@ -19,6 +19,7 @@ export declare const MenuItem: import("styled-components/dist/types").IStyledCom
19
19
  onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
20
20
  } & {
21
21
  multiselect?: boolean;
22
+ $dynamicHeight?: boolean;
22
23
  }, "ref"> & import("react").RefAttributes<unknown>, never>> & string & Omit<import("react").ForwardRefExoticComponent<Omit<MenuProps & import("react").ButtonHTMLAttributes<HTMLButtonElement> & {
23
24
  ref?: RefObject<HTMLButtonElement>;
24
25
  children?: import("react").ReactNode | string;
@@ -38,4 +39,5 @@ export declare const MenuItem: import("styled-components/dist/types").IStyledCom
38
39
  onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
39
40
  } & {
40
41
  multiselect?: boolean;
42
+ $dynamicHeight?: boolean;
41
43
  }, "ref"> & import("react").RefAttributes<unknown>>, keyof import("react").Component<any, {}, any>>;
@@ -49,16 +49,18 @@ export const MenuItem = styled(forwardRef((_a, forwardedRef) => {
49
49
  min-height: ${({ size = "sm" }) => `${getControlSizeTokens(size).menuRowHeight}px`};
50
50
  width: 100%;
51
51
  min-width: 100%;
52
- height: ${({ size = "sm" }) => `${getControlSizeTokens(size).menuRowHeight}px`};
52
+ height: ${({ size = "sm", $dynamicHeight }) => $dynamicHeight ? "auto" : `${getControlSizeTokens(size).menuRowHeight}px`};
53
+ box-sizing: border-box;
53
54
  position: relative;
54
55
  user-select: none;
55
56
  outline: none;
56
57
 
57
58
  border: none;
59
+ text-align: left;
58
60
 
59
- white-space: nowrap;
60
- overflow: hidden;
61
- text-overflow: ellipsis;
61
+ white-space: ${({ $dynamicHeight }) => $dynamicHeight ? "normal" : "nowrap"};
62
+ overflow: ${({ $dynamicHeight }) => $dynamicHeight ? "visible" : "hidden"};
63
+ text-overflow: ${({ $dynamicHeight }) => $dynamicHeight ? "clip" : "ellipsis"};
62
64
 
63
65
  cursor: pointer;
64
66
  text-decoration: none;
@@ -66,7 +68,7 @@ export const MenuItem = styled(forwardRef((_a, forwardedRef) => {
66
68
  font-weight: normal;
67
69
  letter-spacing: normal;
68
70
 
69
- padding: ${({ size = "sm" }) => `0px ${getControlSizeTokens(size).menuItemPaddingX}px`};
71
+ padding: ${({ size = "sm", $dynamicHeight }) => `${$dynamicHeight ? 6 : 0}px ${getControlSizeTokens(size).menuItemPaddingX}px`};
70
72
 
71
73
  &[data-disabled="true"] {
72
74
  opacity: 0.5;
@@ -74,6 +76,12 @@ export const MenuItem = styled(forwardRef((_a, forwardedRef) => {
74
76
  pointer-events: "none";
75
77
  }
76
78
 
79
+ &[data-selected="true"] {
80
+ background-color: ${(props) => props.theme.palette.primary.main}20;
81
+ color: ${(props) => props.theme.palette.primary.main};
82
+ font-weight: 600;
83
+ }
84
+
77
85
  &:hover {
78
86
  background-color: ${(props) => props.theme.palette.action.hover};
79
87
  color: ${(props) => props.theme.palette.text.primary};
@@ -84,10 +92,15 @@ export const MenuItem = styled(forwardRef((_a, forwardedRef) => {
84
92
  }
85
93
 
86
94
  .button-label {
87
- display: inline-block;
88
- overflow: hidden;
89
- white-space: nowrap;
90
- text-overflow: ellipsis;
95
+ display: ${({ $dynamicHeight }) => $dynamicHeight ? "flex" : "inline-block"};
96
+ align-items: center;
97
+ justify-content: flex-start;
98
+ min-width: 0;
99
+ width: 100%;
100
+ text-align: left;
101
+ overflow: ${({ $dynamicHeight }) => $dynamicHeight ? "visible" : "hidden"};
102
+ white-space: ${({ $dynamicHeight }) => $dynamicHeight ? "normal" : "nowrap"};
103
+ text-overflow: ${({ $dynamicHeight }) => $dynamicHeight ? "clip" : "ellipsis"};
91
104
  }
92
105
  }
93
106
  `;
@@ -7,14 +7,17 @@ export declare const MenuItemList: React.FC<{
7
7
  searchValue?: string;
8
8
  onSearch?: (value: string) => void;
9
9
  manualSearch?: boolean;
10
+ dynamicOptionHeight?: boolean;
10
11
  selected?: DropDownItem[];
11
12
  TooltipContent?: ComponentType<any>;
12
13
  multiselect?: boolean;
14
+ enableSelectAll?: boolean;
13
15
  grouped?: boolean;
14
16
  onAddNew?: (value: string) => void;
15
17
  size?: Size;
16
18
  handleAddItem: (item: DropDownItem) => void;
17
19
  handleRemoveItem: (item: DropDownItem) => void;
20
+ handleSetSelected: (selected: DropDownItem[], diff: DropDownItem[]) => void;
18
21
  onItemSelect?: (item: DropDownItem) => void;
19
22
  renderOption?: (item: DropDownItem) => React.ReactNode;
20
23
  onScroll?: (e: Event) => void;