@mtes-mct/monitor-ui 1.1.1

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 (120) hide show
  1. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/_lib/buildFormatLongFn/index.js +12 -0
  2. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/_lib/buildFormatLongFn/index.js.map +1 -0
  3. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/_lib/buildLocalizeFn/index.js +25 -0
  4. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/_lib/buildLocalizeFn/index.js.map +1 -0
  5. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/_lib/buildMatchFn/index.js +51 -0
  6. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/_lib/buildMatchFn/index.js.map +1 -0
  7. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/_lib/buildMatchPatternFn/index.js +20 -0
  8. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/_lib/buildMatchPatternFn/index.js.map +1 -0
  9. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/fr/_lib/formatDistance/index.js +89 -0
  10. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/fr/_lib/formatDistance/index.js.map +1 -0
  11. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/fr/_lib/formatLong/index.js +37 -0
  12. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/fr/_lib/formatLong/index.js.map +1 -0
  13. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/fr/_lib/formatRelative/index.js +15 -0
  14. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/fr/_lib/formatRelative/index.js.map +1 -0
  15. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/fr/_lib/localize/index.js +101 -0
  16. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/fr/_lib/localize/index.js.map +1 -0
  17. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/fr/_lib/match/index.js +101 -0
  18. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/fr/_lib/match/index.js.map +1 -0
  19. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/fr/index.js +34 -0
  20. package/.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/fr/index.js.map +1 -0
  21. package/.yarn/cache/dayjs-npm-1.11.5-a825142dc5-e3bbaa7b48.zip/node_modules/dayjs/locale/fr.js +8 -0
  22. package/.yarn/cache/dayjs-npm-1.11.5-a825142dc5-e3bbaa7b48.zip/node_modules/dayjs/locale/fr.js.map +1 -0
  23. package/.yarn/cache/dayjs-npm-1.11.5-a825142dc5-e3bbaa7b48.zip/node_modules/dayjs/plugin/timezone.js +11 -0
  24. package/.yarn/cache/dayjs-npm-1.11.5-a825142dc5-e3bbaa7b48.zip/node_modules/dayjs/plugin/timezone.js.map +1 -0
  25. package/.yarn/cache/dayjs-npm-1.11.5-a825142dc5-e3bbaa7b48.zip/node_modules/dayjs/plugin/utc.js +11 -0
  26. package/.yarn/cache/dayjs-npm-1.11.5-a825142dc5-e3bbaa7b48.zip/node_modules/dayjs/plugin/utc.js.map +1 -0
  27. package/.yarn/cache/lodash.throttle-npm-4.1.1-856641af92-129c0a28ce.zip/node_modules/lodash.throttle/index.js +444 -0
  28. package/.yarn/cache/lodash.throttle-npm-4.1.1-856641af92-129c0a28ce.zip/node_modules/lodash.throttle/index.js.map +1 -0
  29. package/CHANGELOG.md +15 -0
  30. package/LICENSE +661 -0
  31. package/README.md +25 -0
  32. package/ThemeProvider.d.ts +7 -0
  33. package/_virtual/_commonjsHelpers.js +4 -0
  34. package/_virtual/_commonjsHelpers.js.map +1 -0
  35. package/_virtual/fr.js +4 -0
  36. package/_virtual/fr.js.map +1 -0
  37. package/_virtual/timezone.js +4 -0
  38. package/_virtual/timezone.js.map +1 -0
  39. package/_virtual/utc.js +4 -0
  40. package/_virtual/utc.js.map +1 -0
  41. package/constants.d.ts +1 -0
  42. package/fields/DatePicker/CalendarPicker.d.ts +9 -0
  43. package/fields/DatePicker/index.d.ts +23 -0
  44. package/fields/DateRangePicker/DateInput.d.ts +22 -0
  45. package/fields/DateRangePicker/NumberInput.d.ts +32 -0
  46. package/fields/DateRangePicker/RangeCalendarPicker.d.ts +10 -0
  47. package/fields/DateRangePicker/RangedTimePicker.d.ts +9 -0
  48. package/fields/DateRangePicker/TimeInput.d.ts +24 -0
  49. package/fields/DateRangePicker/constants.d.ts +11 -0
  50. package/fields/DateRangePicker/index.d.ts +24 -0
  51. package/fields/DateRangePicker/types.d.ts +18 -0
  52. package/fields/DateRangePicker/utils.d.ts +24 -0
  53. package/fields/Select.d.ts +11 -0
  54. package/formiks/FormikEffect.d.ts +5 -0
  55. package/formiks/FormikSelect.d.ts +5 -0
  56. package/hooks/useForceUpdate.d.ts +10 -0
  57. package/index.d.ts +14 -0
  58. package/package.json +53 -0
  59. package/src/ThemeProvider.js +13 -0
  60. package/src/ThemeProvider.js.map +1 -0
  61. package/src/constants.js +2 -0
  62. package/src/constants.js.map +1 -0
  63. package/src/fields/DatePicker/CalendarPicker.js +137 -0
  64. package/src/fields/DatePicker/CalendarPicker.js.map +1 -0
  65. package/src/fields/DatePicker/index.js +136 -0
  66. package/src/fields/DatePicker/index.js.map +1 -0
  67. package/src/fields/DateRangePicker/DateInput.js +84 -0
  68. package/src/fields/DateRangePicker/DateInput.js.map +1 -0
  69. package/src/fields/DateRangePicker/NumberInput.js +82 -0
  70. package/src/fields/DateRangePicker/NumberInput.js.map +1 -0
  71. package/src/fields/DateRangePicker/RangeCalendarPicker.js +147 -0
  72. package/src/fields/DateRangePicker/RangeCalendarPicker.js.map +1 -0
  73. package/src/fields/DateRangePicker/RangedTimePicker.js +90 -0
  74. package/src/fields/DateRangePicker/RangedTimePicker.js.map +1 -0
  75. package/src/fields/DateRangePicker/TimeInput.js +116 -0
  76. package/src/fields/DateRangePicker/TimeInput.js.map +1 -0
  77. package/src/fields/DateRangePicker/constants.js +34 -0
  78. package/src/fields/DateRangePicker/constants.js.map +1 -0
  79. package/src/fields/DateRangePicker/index.js +197 -0
  80. package/src/fields/DateRangePicker/index.js.map +1 -0
  81. package/src/fields/DateRangePicker/types.js +8 -0
  82. package/src/fields/DateRangePicker/types.js.map +1 -0
  83. package/src/fields/DateRangePicker/utils.js +73 -0
  84. package/src/fields/DateRangePicker/utils.js.map +1 -0
  85. package/src/fields/Select.js +38 -0
  86. package/src/fields/Select.js.map +1 -0
  87. package/src/formiks/FormikEffect.js +14 -0
  88. package/src/formiks/FormikEffect.js.map +1 -0
  89. package/src/formiks/FormikSelect.js +21 -0
  90. package/src/formiks/FormikSelect.js.map +1 -0
  91. package/src/hooks/useForceUpdate.js +17 -0
  92. package/src/hooks/useForceUpdate.js.map +1 -0
  93. package/src/index.js +10 -0
  94. package/src/index.js.map +1 -0
  95. package/src/theme.js +68 -0
  96. package/src/theme.js.map +1 -0
  97. package/src/utils/capitalizeFirstLetter.js +9 -0
  98. package/src/utils/capitalizeFirstLetter.js.map +1 -0
  99. package/src/utils/dayjs.js +11 -0
  100. package/src/utils/dayjs.js.map +1 -0
  101. package/src/utils/getLocalizedDayjs.js +19 -0
  102. package/src/utils/getLocalizedDayjs.js.map +1 -0
  103. package/src/utils/getUtcDayjs.js +9 -0
  104. package/src/utils/getUtcDayjs.js.map +1 -0
  105. package/src/utils/getUtcizedDayjs.js +20 -0
  106. package/src/utils/getUtcizedDayjs.js.map +1 -0
  107. package/src/utils/sortDates.js +12 -0
  108. package/src/utils/sortDates.js.map +1 -0
  109. package/src/utils/stopMouseEventPropagation.js +6 -0
  110. package/src/utils/stopMouseEventPropagation.js.map +1 -0
  111. package/theme.d.ts +54 -0
  112. package/types/index.d.ts +8 -0
  113. package/utils/capitalizeFirstLetter.d.ts +4 -0
  114. package/utils/cleanInputString.d.ts +4 -0
  115. package/utils/dayjs.d.ts +3 -0
  116. package/utils/getLocalizedDayjs.d.ts +8 -0
  117. package/utils/getUtcDayjs.d.ts +2 -0
  118. package/utils/getUtcizedDayjs.d.ts +8 -0
  119. package/utils/sortDates.d.ts +1 -0
  120. package/utils/stopMouseEventPropagation.d.ts +2 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RangedTimePicker.js","sources":["../../../../src/fields/DateRangePicker/RangedTimePicker.tsx"],"sourcesContent":["import { Fragment, useCallback, useEffect, useMemo, useState } from 'react'\nimport styled from 'styled-components'\n\nimport { stopMouseEventPropagation } from '../../utils/stopMouseEventPropagation'\nimport { getRangedTimeOptions } from './utils'\n\nimport type { TimeTuple } from './types'\nimport type { Promisable } from 'type-fest'\n\ntype RangedTimePickerProps = {\n filter: RegExp\n minutesRange: number\n onChange: (nextTimeTuple: TimeTuple) => Promisable<void>\n}\nexport function RangedTimePicker({ filter, minutesRange, onChange }: RangedTimePickerProps) {\n const rangedTimeOptions = useMemo(() => getRangedTimeOptions(minutesRange), [minutesRange])\n const filteredRangedTimeOptions = useMemo(\n () => rangedTimeOptions.filter(({ label }) => filter.test(label)),\n [filter, rangedTimeOptions]\n )\n\n const [selectedOptionIndex, setSelectedOptionIndex] = useState(0)\n\n const handleBoxKeyDown = useCallback(\n (event: globalThis.KeyboardEvent) => {\n if (event.key === 'ArrowDown') {\n event.preventDefault()\n\n const nextSelectedOptionIndex =\n selectedOptionIndex < filteredRangedTimeOptions.length - 1 ? selectedOptionIndex + 1 : 0\n\n setSelectedOptionIndex(nextSelectedOptionIndex)\n\n window.document.querySelectorAll('.js-ranged-time-picker-option')[nextSelectedOptionIndex]?.scrollIntoView()\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault()\n\n const nextSelectedOptionIndex =\n selectedOptionIndex > 0 ? selectedOptionIndex - 1 : filteredRangedTimeOptions.length - 1\n\n setSelectedOptionIndex(nextSelectedOptionIndex)\n\n window.document.querySelectorAll('.js-ranged-time-picker-option')[nextSelectedOptionIndex]?.scrollIntoView()\n }\n\n if (['Enter', 'Space', 'Tab'].includes(event.key)) {\n const selectedRangedTimeOption = filteredRangedTimeOptions[selectedOptionIndex]\n if (!selectedRangedTimeOption) {\n return\n }\n\n onChange(selectedRangedTimeOption.value)\n }\n },\n [filteredRangedTimeOptions, selectedOptionIndex, onChange]\n )\n\n useEffect(() => {\n window.addEventListener('keydown', handleBoxKeyDown, {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n once: true\n })\n\n return () => {\n window.removeEventListener('keydown', handleBoxKeyDown)\n }\n }, [handleBoxKeyDown])\n\n useEffect(() => {\n setSelectedOptionIndex(0)\n }, [filteredRangedTimeOptions])\n\n if (!filteredRangedTimeOptions.length) {\n return <></>\n }\n\n return (\n <Box onClick={stopMouseEventPropagation} role=\"listbox\">\n {filteredRangedTimeOptions.map(({ label, value }, index) => (\n <Option\n key={label}\n aria-selected={false}\n className=\"js-ranged-time-picker-option\"\n isSelected={index === selectedOptionIndex}\n onClick={() => onChange(value)}\n role=\"option\"\n tabIndex={-1}\n >\n {label}\n </Option>\n ))}\n </Box>\n )\n}\n\nconst Box = styled.div`\n background-color: ${p => p.theme.color.gainsboro};\n display: flex;\n flex-direction: column;\n left: -1px;\n max-height: 10rem;\n overflow: auto;\n position: absolute;\n /* Non-WebKit Firefox Compatibility */\n scrollbar-color: ${p => p.theme.color.lightGray};\n scrollbar-width: thin;\n top: 2.25rem;\n z-index: 9999;\n\n ::-webkit-scrollbar {\n -webkit-appearance: none;\n }\n ::-webkit-scrollbar:vertical {\n width: 0.33rem;\n }\n ::-webkit-scrollbar-thumb {\n border: 0;\n background-color: ${p => p.theme.color.lightGray};\n }\n ::-webkit-scrollbar-track {\n background-color: ${p => p.theme.color.gainsboro};\n }\n`\n\nconst Option = styled.div<{\n isSelected: boolean\n}>`\n background-color: ${p => (p.isSelected ? p.theme.color.blueGray[100] : 'transparent')};\n cursor: pointer;\n line-height: 1;\n padding: 5px 9px 7px 8px;\n text-align: center;\n\n :hover {\n background-color: ${p => (p.isSelected ? p.theme.color.blueGray[100] : p.theme.color.blueYonder[25])};\n }\n`\n"],"names":["_jsx"],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import { forwardRef, useRef, useState, useImperativeHandle, useCallback, useEffect } from 'react';
3
+ import styled from 'styled-components';
4
+ import { useForceUpdate } from '../../hooks/useForceUpdate.js';
5
+ import { NumberInput } from './NumberInput.js';
6
+ import { RangedTimePicker } from './RangedTimePicker.js';
7
+
8
+ function TimeInputWithRef({ defaultValue, isStartDate = false, minutesRange = 15, onBack, onChange, onFocus, onNext, onPrevious }, ref) {
9
+ const boxSpanRef = useRef();
10
+ const hourInputRef = useRef();
11
+ const minuteInputRef = useRef();
12
+ const [controlledDefaultValue, setControlledDefaultValue] = useState(defaultValue);
13
+ const [hasFormatError, setHasFormatError] = useState(false);
14
+ const [hasValidationError, setHasValidationError] = useState(false);
15
+ const [isFocused, setIsFocused] = useState(false);
16
+ useImperativeHandle(ref, () => ({
17
+ boxSpan: boxSpanRef.current,
18
+ focus: (isInLastInputOfTheGroup = false) => {
19
+ if (isInLastInputOfTheGroup) {
20
+ minuteInputRef.current.focus();
21
+ }
22
+ else {
23
+ hourInputRef.current.focus();
24
+ }
25
+ }
26
+ }));
27
+ const isRangedTimePickerOpenRef = useRef(false);
28
+ const [rangedTimePickerFilter, setRangedTimePickerFilter] = useState(/.*/);
29
+ const { forceUpdate } = useForceUpdate();
30
+ const closeRangedTimePicker = useCallback(() => {
31
+ isRangedTimePickerOpenRef.current = false;
32
+ forceUpdate();
33
+ }, [forceUpdate]);
34
+ const handleBack = useCallback(() => {
35
+ if (!onBack) {
36
+ return;
37
+ }
38
+ closeRangedTimePicker();
39
+ onBack();
40
+ }, [closeRangedTimePicker, onBack]);
41
+ const handleBlur = useCallback(() => {
42
+ setIsFocused(false);
43
+ }, []);
44
+ const handleClickOutside = useCallback((event) => {
45
+ const target = event.target;
46
+ if (hourInputRef.current.contains(target) || minuteInputRef.current.contains(target)) {
47
+ return;
48
+ }
49
+ closeRangedTimePicker();
50
+ }, [closeRangedTimePicker]);
51
+ const handleFocus = useCallback(() => {
52
+ setIsFocused(true);
53
+ if (onFocus) {
54
+ onFocus();
55
+ }
56
+ }, [onFocus]);
57
+ const handleFormatError = useCallback((hasNextFormatError) => {
58
+ setHasFormatError(hasNextFormatError);
59
+ }, []);
60
+ const handleRangedTimePickedChange = useCallback((nextTimeTuple) => {
61
+ closeRangedTimePicker();
62
+ setControlledDefaultValue(nextTimeTuple);
63
+ onChange(nextTimeTuple);
64
+ }, [closeRangedTimePicker, onChange]);
65
+ const handleHourInput = useCallback((nextValue) => {
66
+ // eslint-disable-next-line no-nested-ternary
67
+ const nextRangedTimePickerFilter = nextValue.length ? new RegExp(`^${nextValue}`) : /.*/;
68
+ setRangedTimePickerFilter(nextRangedTimePickerFilter);
69
+ }, []);
70
+ const openRangedTimePicker = useCallback(() => {
71
+ isRangedTimePickerOpenRef.current = true;
72
+ forceUpdate();
73
+ }, [forceUpdate]);
74
+ useEffect(() => {
75
+ window.document.addEventListener('click', handleClickOutside);
76
+ return () => {
77
+ window.document.removeEventListener('click', handleClickOutside);
78
+ };
79
+ }, [handleClickOutside]);
80
+ const submit = useCallback(() => {
81
+ setHasValidationError(false);
82
+ if (window.document.activeElement === hourInputRef.current) {
83
+ minuteInputRef.current.focus();
84
+ }
85
+ if (!hourInputRef.current.value.length || !minuteInputRef.current.value.length) {
86
+ if (minuteInputRef.current.value.length && !hourInputRef.current.value.length) {
87
+ setHasValidationError(true);
88
+ }
89
+ return;
90
+ }
91
+ closeRangedTimePicker();
92
+ const nextTimeTuple = [hourInputRef.current.value, minuteInputRef.current.value];
93
+ onChange(nextTimeTuple);
94
+ }, [closeRangedTimePicker, onChange]);
95
+ return (jsxs(Box, { ref: boxSpanRef, hasError: hasFormatError || hasValidationError, isFocused: isFocused, children: [jsxs(Fragment, { children: [jsx(NumberInput, { ref: hourInputRef, "data-cy": `date-range-picker-${isStartDate ? 'start' : 'end'}-hour`, defaultValue: controlledDefaultValue && controlledDefaultValue[0], max: 23, min: 0, onBack: handleBack, onBlur: handleBlur, onClick: openRangedTimePicker, onFilled: submit, onFocus: handleFocus, onFormatError: handleFormatError, onInput: handleHourInput, onNext: () => minuteInputRef.current.focus(), onPrevious: onPrevious, size: 2 }), ":", jsx(NumberInput, { ref: minuteInputRef, "data-cy": `date-range-picker-${isStartDate ? 'start' : 'end'}-minute`, defaultValue: controlledDefaultValue && controlledDefaultValue[1], max: 59, min: 0, onBack: () => hourInputRef.current.focus(), onBlur: handleBlur, onClick: openRangedTimePicker, onFilled: submit, onFocus: handleFocus, onFormatError: handleFormatError, onNext: onNext, onPrevious: () => hourInputRef.current.focus(), size: 2 })] }), isRangedTimePickerOpenRef.current && (jsx(RangedTimePicker, { filter: rangedTimePickerFilter, minutesRange: minutesRange, onChange: handleRangedTimePickedChange }))] }));
96
+ }
97
+ const TimeInput = forwardRef(TimeInputWithRef);
98
+ const Box = styled.span `
99
+ background-color: ${p => p.theme.color.gainsboro};
100
+ box-shadow: ${p => p.hasError || p.isFocused
101
+ ? `inset 0px 0px 0px 1px ${p.hasError ? p.theme.color.maximumRed : p.theme.color.blueGray[100]}`
102
+ : 'none'};
103
+ color: ${p => p.theme.color.slateGray};
104
+ display: inline-block;
105
+ font-size: inherit;
106
+ padding: 0.3125rem 0.5rem 0.4375rem;
107
+ position: relative;
108
+ user-select: none;
109
+
110
+ :hover {
111
+ box-shadow: ${p => `inset 0px 0px 0px 1px ${p.theme.color.blueYonder[100]}`};
112
+ }
113
+ `;
114
+
115
+ export { TimeInput };
116
+ //# sourceMappingURL=TimeInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeInput.js","sources":["../../../../src/fields/DateRangePicker/TimeInput.tsx"],"sourcesContent":["import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'\nimport styled from 'styled-components'\n\nimport { useForceUpdate } from '../../hooks/useForceUpdate'\nimport { NumberInput } from './NumberInput'\nimport { RangedTimePicker } from './RangedTimePicker'\n\nimport type { NumberInputProps } from './NumberInput'\nimport type { DateOrTimeInputRef, TimeTuple } from './types'\nimport type { ForwardedRef, MutableRefObject } from 'react'\nimport type { Promisable } from 'type-fest'\n\nexport type TimeInputProps = Pick<NumberInputProps, 'onBack' | 'onPrevious' | 'onNext'> & {\n defaultValue?: TimeTuple\n isStartDate?: boolean\n minutesRange?: number\n /** Called each time the time input is changed to a new valid value. */\n onChange: (nextTimeTuple: TimeTuple) => Promisable<void>\n onFocus?: () => Promisable<void>\n onNext?: () => Promisable<void>\n onPrevious?: () => Promisable<void>\n}\nfunction TimeInputWithRef(\n {\n defaultValue,\n isStartDate = false,\n minutesRange = 15,\n onBack,\n onChange,\n onFocus,\n onNext,\n onPrevious\n }: TimeInputProps,\n ref: ForwardedRef<DateOrTimeInputRef>\n) {\n const boxSpanRef = useRef() as MutableRefObject<HTMLSpanElement>\n const hourInputRef = useRef() as MutableRefObject<HTMLInputElement>\n const minuteInputRef = useRef() as MutableRefObject<HTMLInputElement>\n\n const [controlledDefaultValue, setControlledDefaultValue] = useState(defaultValue)\n const [hasFormatError, setHasFormatError] = useState(false)\n const [hasValidationError, setHasValidationError] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n\n useImperativeHandle<DateOrTimeInputRef, DateOrTimeInputRef>(ref, () => ({\n boxSpan: boxSpanRef.current,\n focus: (isInLastInputOfTheGroup = false) => {\n if (isInLastInputOfTheGroup) {\n minuteInputRef.current.focus()\n } else {\n hourInputRef.current.focus()\n }\n }\n }))\n\n const isRangedTimePickerOpenRef = useRef(false)\n\n const [rangedTimePickerFilter, setRangedTimePickerFilter] = useState<RegExp>(/.*/)\n\n const { forceUpdate } = useForceUpdate()\n\n const closeRangedTimePicker = useCallback(() => {\n isRangedTimePickerOpenRef.current = false\n\n forceUpdate()\n }, [forceUpdate])\n\n const handleBack = useCallback(() => {\n if (!onBack) {\n return\n }\n\n closeRangedTimePicker()\n\n onBack()\n }, [closeRangedTimePicker, onBack])\n\n const handleBlur = useCallback(() => {\n setIsFocused(false)\n }, [])\n\n const handleClickOutside = useCallback(\n (event: globalThis.MouseEvent) => {\n const target = event.target as Node | null\n\n if (hourInputRef.current.contains(target) || minuteInputRef.current.contains(target)) {\n return\n }\n\n closeRangedTimePicker()\n },\n [closeRangedTimePicker]\n )\n\n const handleFocus = useCallback(() => {\n setIsFocused(true)\n\n if (onFocus) {\n onFocus()\n }\n }, [onFocus])\n\n const handleFormatError = useCallback((hasNextFormatError: boolean) => {\n setHasFormatError(hasNextFormatError)\n }, [])\n\n const handleRangedTimePickedChange = useCallback(\n (nextTimeTuple: TimeTuple) => {\n closeRangedTimePicker()\n\n setControlledDefaultValue(nextTimeTuple)\n\n onChange(nextTimeTuple)\n },\n [closeRangedTimePicker, onChange]\n )\n\n const handleHourInput = useCallback((nextValue: string) => {\n // eslint-disable-next-line no-nested-ternary\n const nextRangedTimePickerFilter = nextValue.length ? new RegExp(`^${nextValue}`) : /.*/\n\n setRangedTimePickerFilter(nextRangedTimePickerFilter)\n }, [])\n\n const openRangedTimePicker = useCallback(() => {\n isRangedTimePickerOpenRef.current = true\n\n forceUpdate()\n }, [forceUpdate])\n\n useEffect(() => {\n window.document.addEventListener('click', handleClickOutside)\n\n return () => {\n window.document.removeEventListener('click', handleClickOutside)\n }\n }, [handleClickOutside])\n\n const submit = useCallback(() => {\n setHasValidationError(false)\n\n if (window.document.activeElement === hourInputRef.current) {\n minuteInputRef.current.focus()\n }\n\n if (!hourInputRef.current.value.length || !minuteInputRef.current.value.length) {\n if (minuteInputRef.current.value.length && !hourInputRef.current.value.length) {\n setHasValidationError(true)\n }\n\n return\n }\n\n closeRangedTimePicker()\n\n const nextTimeTuple: TimeTuple = [hourInputRef.current.value, minuteInputRef.current.value]\n onChange(nextTimeTuple)\n }, [closeRangedTimePicker, onChange])\n\n return (\n <Box ref={boxSpanRef} hasError={hasFormatError || hasValidationError} isFocused={isFocused}>\n <>\n <NumberInput\n ref={hourInputRef}\n data-cy={`date-range-picker-${isStartDate ? 'start' : 'end'}-hour`}\n defaultValue={controlledDefaultValue && controlledDefaultValue[0]}\n max={23}\n min={0}\n onBack={handleBack}\n onBlur={handleBlur}\n onClick={openRangedTimePicker}\n onFilled={submit}\n onFocus={handleFocus}\n onFormatError={handleFormatError}\n onInput={handleHourInput}\n onNext={() => minuteInputRef.current.focus()}\n onPrevious={onPrevious}\n size={2}\n />\n :\n <NumberInput\n ref={minuteInputRef}\n data-cy={`date-range-picker-${isStartDate ? 'start' : 'end'}-minute`}\n defaultValue={controlledDefaultValue && controlledDefaultValue[1]}\n max={59}\n min={0}\n onBack={() => hourInputRef.current.focus()}\n onBlur={handleBlur}\n onClick={openRangedTimePicker}\n onFilled={submit}\n onFocus={handleFocus}\n onFormatError={handleFormatError}\n onNext={onNext}\n onPrevious={() => hourInputRef.current.focus()}\n size={2}\n />\n </>\n\n {isRangedTimePickerOpenRef.current && (\n <RangedTimePicker\n filter={rangedTimePickerFilter}\n minutesRange={minutesRange}\n onChange={handleRangedTimePickedChange}\n />\n )}\n </Box>\n )\n}\n\nexport const TimeInput = forwardRef(TimeInputWithRef)\n\nconst Box = styled.span<{\n hasError: boolean\n isFocused: boolean\n}>`\n background-color: ${p => p.theme.color.gainsboro};\n box-shadow: ${p =>\n p.hasError || p.isFocused\n ? `inset 0px 0px 0px 1px ${p.hasError ? p.theme.color.maximumRed : p.theme.color.blueGray[100]}`\n : 'none'};\n color: ${p => p.theme.color.slateGray};\n display: inline-block;\n font-size: inherit;\n padding: 0.3125rem 0.5rem 0.4375rem;\n position: relative;\n user-select: none;\n\n :hover {\n box-shadow: ${p => `inset 0px 0px 0px 1px ${p.theme.color.blueYonder[100]}`};\n }\n`\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import fr from '../../../.yarn/cache/date-fns-npm-2.29.3-fef7e3c72c-e01cf5b62a.zip/node_modules/date-fns/esm/locale/fr/index.js';
2
+
3
+ new Array(24).fill(undefined).map((_, index) => ({
4
+ label: String(index).padStart(2, '0'),
5
+ value: index
6
+ }));
7
+ const RSUITE_CALENDAR_LOCALE = {
8
+ // TODO Why this doesn't work?
9
+ dateLocale: fr,
10
+ formattedDayPattern: 'dd/MM/yyyy',
11
+ formattedMonthPattern: 'MM/yyyy',
12
+ friday: 'V',
13
+ hours: 'Heures',
14
+ minutes: 'Minutes',
15
+ monday: 'L',
16
+ ok: 'Valider',
17
+ saturday: 'S',
18
+ seconds: 'Secondes',
19
+ sunday: 'D',
20
+ thursday: 'J',
21
+ today: 'Aujourd’hui',
22
+ tuesday: 'M',
23
+ wednesday: 'M',
24
+ yesterday: 'Hier'
25
+ };
26
+ var STATUS;
27
+ (function (STATUS) {
28
+ STATUS["END_DATE"] = "END_DATE";
29
+ STATUS["NO_DATE"] = "NO_DATE";
30
+ STATUS["START_DATE"] = "START_DATE";
31
+ })(STATUS || (STATUS = {}));
32
+
33
+ export { RSUITE_CALENDAR_LOCALE, STATUS };
34
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sources":["../../../../src/fields/DateRangePicker/constants.ts"],"sourcesContent":["import fr from 'date-fns/locale/fr'\n\nimport type { DateRangePickerLocale } from 'rsuite'\n\nexport const HOURS_AS_OPTIONS = new Array(24).fill(undefined).map((_, index) => ({\n label: String(index).padStart(2, '0'),\n value: index\n}))\n\nexport const RSUITE_CALENDAR_LOCALE: DateRangePickerLocale = {\n // TODO Why this doesn't work?\n dateLocale: fr,\n formattedDayPattern: 'dd/MM/yyyy',\n formattedMonthPattern: 'MM/yyyy',\n friday: 'V',\n hours: 'Heures',\n minutes: 'Minutes',\n monday: 'L',\n ok: 'Valider',\n saturday: 'S',\n seconds: 'Secondes',\n sunday: 'D',\n thursday: 'J',\n today: 'Aujourd’hui',\n tuesday: 'M',\n wednesday: 'M',\n yesterday: 'Hier'\n}\n\nexport enum STATUS {\n 'END_DATE' = 'END_DATE',\n 'NO_DATE' = 'NO_DATE',\n 'START_DATE' = 'START_DATE'\n}\n"],"names":[],"mappings":";;AAIgC,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM;IAC/E,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AACrC,IAAA,KAAK,EAAE,KAAK;AACb,CAAA,CAAC,EAAC;AAEU,MAAA,sBAAsB,GAA0B;;AAE3D,IAAA,UAAU,EAAE,EAAE;AACd,IAAA,mBAAmB,EAAE,YAAY;AACjC,IAAA,qBAAqB,EAAE,SAAS;AAChC,IAAA,MAAM,EAAE,GAAG;AACX,IAAA,KAAK,EAAE,QAAQ;AACf,IAAA,OAAO,EAAE,SAAS;AAClB,IAAA,MAAM,EAAE,GAAG;AACX,IAAA,EAAE,EAAE,SAAS;AACb,IAAA,QAAQ,EAAE,GAAG;AACb,IAAA,OAAO,EAAE,UAAU;AACnB,IAAA,MAAM,EAAE,GAAG;AACX,IAAA,QAAQ,EAAE,GAAG;AACb,IAAA,KAAK,EAAE,aAAa;AACpB,IAAA,OAAO,EAAE,GAAG;AACZ,IAAA,SAAS,EAAE,GAAG;AACd,IAAA,SAAS,EAAE,MAAM;EAClB;IAEW,OAIX;AAJD,CAAA,UAAY,MAAM,EAAA;AAChB,IAAA,MAAA,CAAA,UAAA,CAAA,GAAA,UAAuB,CAAA;AACvB,IAAA,MAAA,CAAA,SAAA,CAAA,GAAA,SAAqB,CAAA;AACrB,IAAA,MAAA,CAAA,YAAA,CAAA,GAAA,YAA2B,CAAA;AAC7B,CAAC,EAJW,MAAM,KAAN,MAAM,GAIjB,EAAA,CAAA,CAAA;;;;"}
@@ -0,0 +1,197 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useRef, useMemo, useCallback, useEffect } from 'react';
3
+ import styled from 'styled-components';
4
+ import { useForceUpdate } from '../../hooks/useForceUpdate.js';
5
+ import { getLocalizedDayjs } from '../../utils/getLocalizedDayjs.js';
6
+ import { getUtcizedDayjs } from '../../utils/getUtcizedDayjs.js';
7
+ import { DateInput } from './DateInput.js';
8
+ import { RangeCalendarPicker } from './RangeCalendarPicker.js';
9
+ import { TimeInput } from './TimeInput.js';
10
+ import { DateRangePosition } from './types.js';
11
+ import { getDateTupleFromDate, getTimeTupleFromDate, getDateFromDateAndTimeTuple } from './utils.js';
12
+
13
+ function DateRangePicker({ defaultValue, isHistorical = false, isLabelHidden = false, label, minutesRange = 15, onChange, withTime = false }) {
14
+ const startDateInputRef = useRef();
15
+ const startTimeInputRef = useRef();
16
+ const endDateInputRef = useRef();
17
+ const endTimeInputRef = useRef();
18
+ const isRangeCalendarPickerOpenRef = useRef(false);
19
+ const selectedStartDateRef = useRef(defaultValue ? getLocalizedDayjs(defaultValue[0]).toDate() : undefined);
20
+ const selectedEndDateRef = useRef(defaultValue ? getLocalizedDayjs(defaultValue[1]).toDate() : undefined);
21
+ const selectedStartDateTupleRef = useRef(getDateTupleFromDate(selectedStartDateRef.current));
22
+ const selectedEndDateTupleRef = useRef(getDateTupleFromDate(selectedEndDateRef.current));
23
+ const selectedStartTimeTupleRef = useRef(getTimeTupleFromDate(selectedStartDateRef.current));
24
+ const selectedEndTimeTupleRef = useRef(getTimeTupleFromDate(selectedEndDateRef.current));
25
+ const { forceUpdate } = useForceUpdate();
26
+ const rangeCalendarPickerDefaultValue = useMemo(() => selectedStartDateTupleRef.current && selectedEndDateTupleRef.current
27
+ ? [
28
+ getDateFromDateAndTimeTuple(selectedStartDateTupleRef.current, ['00', '00']),
29
+ getDateFromDateAndTimeTuple(selectedEndDateTupleRef.current, ['00', '00'], true)
30
+ ]
31
+ : undefined,
32
+ // eslint-disable-next-line react-hooks/exhaustive-deps
33
+ [selectedEndDateTupleRef.current, selectedStartDateTupleRef.current]);
34
+ const submit = useCallback(() => {
35
+ if (!selectedStartDateRef.current || !selectedEndDateRef.current) {
36
+ return;
37
+ }
38
+ const utcizedStartDate = getUtcizedDayjs(selectedStartDateRef.current).toDate();
39
+ const utcizedEndDate = getUtcizedDayjs(selectedEndDateRef.current).toDate();
40
+ const nextDateRange = [utcizedStartDate, utcizedEndDate];
41
+ onChange(nextDateRange);
42
+ }, [onChange]);
43
+ const closeRangeCalendarPicker = useCallback(() => {
44
+ isRangeCalendarPickerOpenRef.current = false;
45
+ forceUpdate();
46
+ }, [forceUpdate]);
47
+ const handleClickOutside = useCallback((event) => {
48
+ const target = event.target;
49
+ if (startDateInputRef.current.boxSpan.contains(target) || endDateInputRef.current.boxSpan.contains(target)) {
50
+ return;
51
+ }
52
+ closeRangeCalendarPicker();
53
+ }, [closeRangeCalendarPicker]);
54
+ const handleEndDateInputNext = useCallback(() => {
55
+ if (!withTime) {
56
+ return;
57
+ }
58
+ endTimeInputRef.current.focus();
59
+ }, [withTime]);
60
+ const handleEndDateInputPrevious = useCallback(() => {
61
+ if (withTime) {
62
+ startTimeInputRef.current.focus(true);
63
+ return;
64
+ }
65
+ startDateInputRef.current.focus(true);
66
+ }, [withTime]);
67
+ const handleStartDateInputNext = useCallback(() => {
68
+ if (withTime) {
69
+ startTimeInputRef.current.focus();
70
+ return;
71
+ }
72
+ endDateInputRef.current.focus();
73
+ }, [withTime]);
74
+ const handleDateInputFilled = useCallback((position, nextDateTuple) => {
75
+ if (position === DateRangePosition.START) {
76
+ selectedStartDateTupleRef.current = nextDateTuple;
77
+ // If there is no time input or a start time has already been selected,
78
+ if (!withTime || selectedStartTimeTupleRef.current) {
79
+ // we must update the selected start date and call onChange()
80
+ const startTimeTuple = (withTime ? selectedStartTimeTupleRef.current : ['00', '00']);
81
+ const nextStartDate = getDateFromDateAndTimeTuple(nextDateTuple, startTimeTuple);
82
+ selectedStartDateRef.current = nextStartDate;
83
+ submit();
84
+ }
85
+ handleStartDateInputNext();
86
+ }
87
+ else {
88
+ selectedEndDateTupleRef.current = nextDateTuple;
89
+ // If there is no time input or an end time has already been selected,
90
+ if (!withTime || selectedEndTimeTupleRef.current) {
91
+ // we must update the selected end date and call onChange()
92
+ const endTimeTuple = (withTime ? selectedEndTimeTupleRef.current : ['23', '59']);
93
+ const nextEndDate = getDateFromDateAndTimeTuple(nextDateTuple, endTimeTuple, true);
94
+ selectedEndDateRef.current = nextEndDate;
95
+ submit();
96
+ }
97
+ handleEndDateInputNext();
98
+ }
99
+ }, [handleEndDateInputNext, handleStartDateInputNext, submit, withTime]);
100
+ const handleRangeCalendarPickerChange = useCallback((nextDateTupleRange) => {
101
+ const [nextStartDateTuple, nextEndDateTuple] = nextDateTupleRange;
102
+ // If this is a date picker without a time input,
103
+ if (!withTime) {
104
+ // we have to fix the start date at the beginning of the day
105
+ const nextStartDate = getDateFromDateAndTimeTuple(nextStartDateTuple, ['00', '00']);
106
+ // and the end date at the end of the day
107
+ const nextEndDate = getDateFromDateAndTimeTuple(nextEndDateTuple, ['23', '59'], true);
108
+ selectedStartDateRef.current = nextStartDate;
109
+ selectedEndDateRef.current = nextEndDate;
110
+ }
111
+ // If this is a date picker with a time input,
112
+ else {
113
+ // we include the selected start time if it exists, set it at the beginning of the day if not
114
+ const nextStartDate = getDateFromDateAndTimeTuple(nextStartDateTuple, selectedStartTimeTupleRef.current || ['00', '00']);
115
+ selectedStartDateRef.current = nextStartDate;
116
+ // we include the selected end time if it exists, set it at the end of the day if not
117
+ const nextEndDate = getDateFromDateAndTimeTuple(nextEndDateTuple, selectedEndTimeTupleRef.current || ['23', '59'], true);
118
+ selectedEndDateRef.current = nextEndDate;
119
+ }
120
+ selectedStartDateTupleRef.current = nextStartDateTuple;
121
+ selectedStartTimeTupleRef.current = getTimeTupleFromDate(selectedStartDateRef.current);
122
+ selectedEndDateTupleRef.current = nextEndDateTuple;
123
+ selectedEndTimeTupleRef.current = getTimeTupleFromDate(selectedEndDateRef.current);
124
+ closeRangeCalendarPicker();
125
+ forceUpdate();
126
+ submit();
127
+ }, [closeRangeCalendarPicker, forceUpdate, submit, withTime]);
128
+ const handleTimeInputFilled = useCallback((position, nextTimeTuple) => {
129
+ if (position === DateRangePosition.START) {
130
+ // If a start date has already been selected
131
+ if (selectedStartDateTupleRef.current) {
132
+ // we must update the selected start date accordingly and submit it
133
+ const nextStartDate = getDateFromDateAndTimeTuple(selectedStartDateTupleRef.current, nextTimeTuple);
134
+ selectedStartDateRef.current = nextStartDate;
135
+ submit();
136
+ }
137
+ selectedStartTimeTupleRef.current = nextTimeTuple;
138
+ endDateInputRef.current.focus();
139
+ }
140
+ else {
141
+ // If an end date has already been selected
142
+ if (selectedEndDateTupleRef.current) {
143
+ // we must update the selected end date accordingly and submit it
144
+ const nextEndDate = getDateFromDateAndTimeTuple(selectedEndDateTupleRef.current, nextTimeTuple, true);
145
+ selectedEndDateRef.current = nextEndDate;
146
+ submit();
147
+ }
148
+ selectedEndTimeTupleRef.current = nextTimeTuple;
149
+ }
150
+ submit();
151
+ }, [submit]);
152
+ const openRangeCalendarPicker = useCallback(() => {
153
+ isRangeCalendarPickerOpenRef.current = true;
154
+ forceUpdate();
155
+ }, [forceUpdate]);
156
+ useEffect(() => {
157
+ window.document.addEventListener('click', handleClickOutside);
158
+ return () => {
159
+ window.document.removeEventListener('click', handleClickOutside);
160
+ };
161
+ }, [handleClickOutside]);
162
+ return (jsxs(Fieldset, { className: "DateRangePicker", children: [jsx(Legend, { isHidden: isLabelHidden, children: label }), jsxs(Box, { children: [jsx(Field, { children: jsx(DateInput, { ref: startDateInputRef, defaultValue: selectedStartDateTupleRef.current, isForcedFocused: isRangeCalendarPickerOpenRef.current, isStartDate: true, onChange: nextDateTuple => handleDateInputFilled(DateRangePosition.START, nextDateTuple), onClick: openRangeCalendarPicker, onNext: handleStartDateInputNext }) }), withTime && (jsx(Field, { isTimeField: true, children: jsx(TimeInput, { ref: startTimeInputRef, defaultValue: selectedStartTimeTupleRef.current, isStartDate: true, minutesRange: minutesRange, onBack: () => startDateInputRef.current.focus(true), onChange: nextTimeTuple => handleTimeInputFilled(DateRangePosition.START, nextTimeTuple), onFocus: closeRangeCalendarPicker, onNext: () => endDateInputRef.current.focus(), onPrevious: () => startDateInputRef.current.focus(true) }) })), jsx(Field, { isEndDateField: true, children: jsx(DateInput, { ref: endDateInputRef, defaultValue: selectedEndDateTupleRef.current, isEndDate: true, isForcedFocused: isRangeCalendarPickerOpenRef.current, onBack: handleEndDateInputPrevious, onChange: nextDateTuple => handleDateInputFilled(DateRangePosition.END, nextDateTuple), onClick: openRangeCalendarPicker, onNext: handleEndDateInputNext, onPrevious: handleEndDateInputPrevious }) }), withTime && (jsx(Field, { isTimeField: true, children: jsx(TimeInput, { ref: endTimeInputRef, defaultValue: selectedEndTimeTupleRef.current, minutesRange: minutesRange, onBack: () => endDateInputRef.current.focus(true), onChange: nextTimeTuple => handleTimeInputFilled(DateRangePosition.END, nextTimeTuple), onFocus: closeRangeCalendarPicker, onPrevious: () => endDateInputRef.current.focus(true) }) }))] }), isRangeCalendarPickerOpenRef.current && (jsx(RangeCalendarPicker, { defaultValue: rangeCalendarPickerDefaultValue, isHistorical: isHistorical, onChange: handleRangeCalendarPickerChange }))] }));
163
+ }
164
+ const Fieldset = styled.fieldset `
165
+ border: 0;
166
+ margin: 0;
167
+ padding: 0;
168
+ `;
169
+ const Box = styled.div `
170
+ * {
171
+ font-weight: 500;
172
+ line-height: 1;
173
+ }
174
+
175
+ color: ${p => p.theme.color.gunMetal};
176
+ font-size: 13px;
177
+ position: relative;
178
+ `;
179
+ const Legend = styled.legend `
180
+ color: ${p => p.theme.color.slateGray};
181
+ display: ${p => (p.isHidden ? 'none' : 'table')};
182
+ font-weight: inherit;
183
+ margin-bottom: 0.5rem;
184
+ padding: 0;
185
+ `;
186
+ const Field = styled.span `
187
+ font-size: inherit;
188
+ margin-left: ${p => {
189
+ if (p.isEndDateField) {
190
+ return '0.625rem';
191
+ }
192
+ return p.isTimeField ? '0.125rem' : 0;
193
+ }};
194
+ `;
195
+
196
+ export { DateRangePicker };
197
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../../src/fields/DateRangePicker/index.tsx"],"sourcesContent":["// TODO We should make this component both form- & a11y-compliant with a `name` and proper (aria-)labels.\n\nimport { useCallback, useEffect, useMemo, useRef } from 'react'\nimport styled from 'styled-components'\n\nimport { useForceUpdate } from '../../hooks/useForceUpdate'\nimport { getLocalizedDayjs } from '../../utils/getLocalizedDayjs'\nimport { getUtcizedDayjs } from '../../utils/getUtcizedDayjs'\nimport { DateInput } from './DateInput'\nimport { RangeCalendarPicker } from './RangeCalendarPicker'\nimport { TimeInput } from './TimeInput'\nimport { DateOrTimeInputRef, DateRangePosition, DateTuple, DateTupleRange, TimeTuple } from './types'\nimport { getDateFromDateAndTimeTuple, getDateTupleFromDate, getTimeTupleFromDate } from './utils'\n\nimport type { DateRange } from '../../types'\nimport type { MutableRefObject } from 'react'\nimport type { Promisable } from 'type-fest'\n\nexport type DateRangePickerProps = {\n defaultValue?: DateRange\n /** Only allow past dates until today. */\n isHistorical?: boolean\n isLabelHidden?: boolean\n label: string\n /**\n * Range of minutes used to generate the time picker list.\n *\n * @example\n * `15` would produce a list with `..., 10:45, 11:00, 11:15, ...`.\n */\n minutesRange?: number\n /**\n * Called each time the date range picker is changed to a new valid value.\n *\n * @param nextUtcDateRange - A utcized date to be used as is to interact with the API.\n */\n onChange: (nextUtcDateRange: DateRange) => Promisable<void>\n withTime?: boolean\n}\nexport function DateRangePicker({\n defaultValue,\n isHistorical = false,\n isLabelHidden = false,\n label,\n minutesRange = 15,\n onChange,\n withTime = false\n}: DateRangePickerProps) {\n const startDateInputRef = useRef() as MutableRefObject<DateOrTimeInputRef>\n const startTimeInputRef = useRef() as MutableRefObject<DateOrTimeInputRef>\n const endDateInputRef = useRef() as MutableRefObject<DateOrTimeInputRef>\n const endTimeInputRef = useRef() as MutableRefObject<DateOrTimeInputRef>\n\n const isRangeCalendarPickerOpenRef = useRef(false)\n\n const selectedStartDateRef = useRef<Date | undefined>(\n defaultValue ? getLocalizedDayjs(defaultValue[0]).toDate() : undefined\n )\n const selectedEndDateRef = useRef<Date | undefined>(\n defaultValue ? getLocalizedDayjs(defaultValue[1]).toDate() : undefined\n )\n const selectedStartDateTupleRef = useRef<DateTuple | undefined>(getDateTupleFromDate(selectedStartDateRef.current))\n const selectedEndDateTupleRef = useRef<DateTuple | undefined>(getDateTupleFromDate(selectedEndDateRef.current))\n const selectedStartTimeTupleRef = useRef<TimeTuple | undefined>(getTimeTupleFromDate(selectedStartDateRef.current))\n const selectedEndTimeTupleRef = useRef<TimeTuple | undefined>(getTimeTupleFromDate(selectedEndDateRef.current))\n\n const { forceUpdate } = useForceUpdate()\n\n const rangeCalendarPickerDefaultValue = useMemo(\n () =>\n selectedStartDateTupleRef.current && selectedEndDateTupleRef.current\n ? ([\n getDateFromDateAndTimeTuple(selectedStartDateTupleRef.current, ['00', '00']),\n getDateFromDateAndTimeTuple(selectedEndDateTupleRef.current, ['00', '00'], true)\n ] as DateRange)\n : undefined,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [selectedEndDateTupleRef.current, selectedStartDateTupleRef.current]\n )\n\n const submit = useCallback(() => {\n if (!selectedStartDateRef.current || !selectedEndDateRef.current) {\n return\n }\n\n const utcizedStartDate = getUtcizedDayjs(selectedStartDateRef.current).toDate()\n const utcizedEndDate = getUtcizedDayjs(selectedEndDateRef.current).toDate()\n\n const nextDateRange: DateRange = [utcizedStartDate, utcizedEndDate]\n onChange(nextDateRange)\n }, [onChange])\n\n const closeRangeCalendarPicker = useCallback(() => {\n isRangeCalendarPickerOpenRef.current = false\n\n forceUpdate()\n }, [forceUpdate])\n\n const handleClickOutside = useCallback(\n (event: globalThis.MouseEvent) => {\n const target = event.target as Node | null\n\n if (startDateInputRef.current.boxSpan.contains(target) || endDateInputRef.current.boxSpan.contains(target)) {\n return\n }\n\n closeRangeCalendarPicker()\n },\n [closeRangeCalendarPicker]\n )\n\n const handleEndDateInputNext = useCallback(() => {\n if (!withTime) {\n return\n }\n\n endTimeInputRef.current.focus()\n }, [withTime])\n\n const handleEndDateInputPrevious = useCallback(() => {\n if (withTime) {\n startTimeInputRef.current.focus(true)\n\n return\n }\n\n startDateInputRef.current.focus(true)\n }, [withTime])\n\n const handleStartDateInputNext = useCallback(() => {\n if (withTime) {\n startTimeInputRef.current.focus()\n\n return\n }\n\n endDateInputRef.current.focus()\n }, [withTime])\n\n const handleDateInputFilled = useCallback(\n (position: DateRangePosition, nextDateTuple: DateTuple) => {\n if (position === DateRangePosition.START) {\n selectedStartDateTupleRef.current = nextDateTuple\n\n // If there is no time input or a start time has already been selected,\n if (!withTime || selectedStartTimeTupleRef.current) {\n // we must update the selected start date and call onChange()\n const startTimeTuple = (withTime ? selectedStartTimeTupleRef.current : ['00', '00']) as TimeTuple\n const nextStartDate = getDateFromDateAndTimeTuple(nextDateTuple, startTimeTuple)\n\n selectedStartDateRef.current = nextStartDate\n\n submit()\n }\n\n handleStartDateInputNext()\n } else {\n selectedEndDateTupleRef.current = nextDateTuple\n\n // If there is no time input or an end time has already been selected,\n if (!withTime || selectedEndTimeTupleRef.current) {\n // we must update the selected end date and call onChange()\n const endTimeTuple = (withTime ? selectedEndTimeTupleRef.current : ['23', '59']) as TimeTuple\n const nextEndDate = getDateFromDateAndTimeTuple(nextDateTuple, endTimeTuple, true)\n\n selectedEndDateRef.current = nextEndDate\n\n submit()\n }\n\n handleEndDateInputNext()\n }\n },\n [handleEndDateInputNext, handleStartDateInputNext, submit, withTime]\n )\n\n const handleRangeCalendarPickerChange = useCallback(\n (nextDateTupleRange: DateTupleRange) => {\n const [nextStartDateTuple, nextEndDateTuple] = nextDateTupleRange\n\n // If this is a date picker without a time input,\n if (!withTime) {\n // we have to fix the start date at the beginning of the day\n const nextStartDate = getDateFromDateAndTimeTuple(nextStartDateTuple, ['00', '00'])\n // and the end date at the end of the day\n const nextEndDate = getDateFromDateAndTimeTuple(nextEndDateTuple, ['23', '59'], true)\n\n selectedStartDateRef.current = nextStartDate\n selectedEndDateRef.current = nextEndDate\n }\n\n // If this is a date picker with a time input,\n else {\n // we include the selected start time if it exists, set it at the beginning of the day if not\n const nextStartDate = getDateFromDateAndTimeTuple(\n nextStartDateTuple,\n selectedStartTimeTupleRef.current || ['00', '00']\n )\n selectedStartDateRef.current = nextStartDate\n\n // we include the selected end time if it exists, set it at the end of the day if not\n const nextEndDate = getDateFromDateAndTimeTuple(\n nextEndDateTuple,\n selectedEndTimeTupleRef.current || ['23', '59'],\n true\n )\n\n selectedEndDateRef.current = nextEndDate\n }\n\n selectedStartDateTupleRef.current = nextStartDateTuple\n selectedStartTimeTupleRef.current = getTimeTupleFromDate(selectedStartDateRef.current)\n selectedEndDateTupleRef.current = nextEndDateTuple\n selectedEndTimeTupleRef.current = getTimeTupleFromDate(selectedEndDateRef.current)\n\n closeRangeCalendarPicker()\n forceUpdate()\n\n submit()\n },\n [closeRangeCalendarPicker, forceUpdate, submit, withTime]\n )\n\n const handleTimeInputFilled = useCallback(\n (position: DateRangePosition, nextTimeTuple: TimeTuple) => {\n if (position === DateRangePosition.START) {\n // If a start date has already been selected\n if (selectedStartDateTupleRef.current) {\n // we must update the selected start date accordingly and submit it\n const nextStartDate = getDateFromDateAndTimeTuple(selectedStartDateTupleRef.current, nextTimeTuple)\n\n selectedStartDateRef.current = nextStartDate\n\n submit()\n }\n\n selectedStartTimeTupleRef.current = nextTimeTuple\n\n endDateInputRef.current.focus()\n } else {\n // If an end date has already been selected\n if (selectedEndDateTupleRef.current) {\n // we must update the selected end date accordingly and submit it\n const nextEndDate = getDateFromDateAndTimeTuple(selectedEndDateTupleRef.current, nextTimeTuple, true)\n\n selectedEndDateRef.current = nextEndDate\n\n submit()\n }\n\n selectedEndTimeTupleRef.current = nextTimeTuple\n }\n\n submit()\n },\n [submit]\n )\n\n const openRangeCalendarPicker = useCallback(() => {\n isRangeCalendarPickerOpenRef.current = true\n\n forceUpdate()\n }, [forceUpdate])\n\n useEffect(() => {\n window.document.addEventListener('click', handleClickOutside)\n\n return () => {\n window.document.removeEventListener('click', handleClickOutside)\n }\n }, [handleClickOutside])\n\n return (\n <Fieldset className=\"DateRangePicker\">\n <Legend isHidden={isLabelHidden}>{label}</Legend>\n\n <Box>\n <Field>\n <DateInput\n ref={startDateInputRef}\n defaultValue={selectedStartDateTupleRef.current}\n isForcedFocused={isRangeCalendarPickerOpenRef.current}\n isStartDate\n onChange={nextDateTuple => handleDateInputFilled(DateRangePosition.START, nextDateTuple)}\n onClick={openRangeCalendarPicker}\n onNext={handleStartDateInputNext}\n />\n </Field>\n\n {withTime && (\n <Field isTimeField>\n <TimeInput\n ref={startTimeInputRef}\n defaultValue={selectedStartTimeTupleRef.current}\n isStartDate\n minutesRange={minutesRange}\n onBack={() => startDateInputRef.current.focus(true)}\n onChange={nextTimeTuple => handleTimeInputFilled(DateRangePosition.START, nextTimeTuple)}\n onFocus={closeRangeCalendarPicker}\n onNext={() => endDateInputRef.current.focus()}\n onPrevious={() => startDateInputRef.current.focus(true)}\n />\n </Field>\n )}\n\n <Field isEndDateField>\n <DateInput\n ref={endDateInputRef}\n defaultValue={selectedEndDateTupleRef.current}\n isEndDate\n isForcedFocused={isRangeCalendarPickerOpenRef.current}\n onBack={handleEndDateInputPrevious}\n onChange={nextDateTuple => handleDateInputFilled(DateRangePosition.END, nextDateTuple)}\n onClick={openRangeCalendarPicker}\n onNext={handleEndDateInputNext}\n onPrevious={handleEndDateInputPrevious}\n />\n </Field>\n\n {withTime && (\n <Field isTimeField>\n <TimeInput\n ref={endTimeInputRef}\n defaultValue={selectedEndTimeTupleRef.current}\n minutesRange={minutesRange}\n onBack={() => endDateInputRef.current.focus(true)}\n onChange={nextTimeTuple => handleTimeInputFilled(DateRangePosition.END, nextTimeTuple)}\n onFocus={closeRangeCalendarPicker}\n onPrevious={() => endDateInputRef.current.focus(true)}\n />\n </Field>\n )}\n </Box>\n\n {isRangeCalendarPickerOpenRef.current && (\n <RangeCalendarPicker\n defaultValue={rangeCalendarPickerDefaultValue}\n isHistorical={isHistorical}\n onChange={handleRangeCalendarPickerChange}\n />\n )}\n </Fieldset>\n )\n}\n\nconst Fieldset = styled.fieldset`\n border: 0;\n margin: 0;\n padding: 0;\n`\n\nconst Box = styled.div`\n * {\n font-weight: 500;\n line-height: 1;\n }\n\n color: ${p => p.theme.color.gunMetal};\n font-size: 13px;\n position: relative;\n`\n\nconst Legend = styled.legend<{\n isHidden: boolean\n}>`\n color: ${p => p.theme.color.slateGray};\n display: ${p => (p.isHidden ? 'none' : 'table')};\n font-weight: inherit;\n margin-bottom: 0.5rem;\n padding: 0;\n`\n\nconst Field = styled.span<{\n isEndDateField?: boolean\n isTimeField?: boolean\n}>`\n font-size: inherit;\n margin-left: ${p => {\n if (p.isEndDateField) {\n return '0.625rem'\n }\n\n return p.isTimeField ? '0.125rem' : 0\n }};\n`\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ var DateRangePosition;
2
+ (function (DateRangePosition) {
3
+ DateRangePosition["END"] = "END";
4
+ DateRangePosition["START"] = "START";
5
+ })(DateRangePosition || (DateRangePosition = {}));
6
+
7
+ export { DateRangePosition };
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sources":["../../../../src/fields/DateRangePicker/types.ts"],"sourcesContent":["export type DateOrTimeInputRef = {\n boxSpan: HTMLSpanElement\n /**\n * Focus the first input in the group.\n *\n * @param inLastInputOfTheGroup - If `true`, focus the last input in the group instead of the first one\n */\n focus: (inLastInputOfTheGroup?: boolean) => void\n}\n\nexport enum DateRangePosition {\n END = 'END',\n START = 'START'\n}\n\n/** In the shape of [\"YYYY\", \"MM\", \"DD\"]. */\nexport type DateTuple = [string, string, string]\n\nexport type DateTupleRange = [DateTuple, DateTuple]\n\n/** In the shape of [\"hh\", \"mm\"]. */\nexport type TimeTuple = [string, string]\n"],"names":[],"mappings":"IAUY,kBAGX;AAHD,CAAA,UAAY,iBAAiB,EAAA;AAC3B,IAAA,iBAAA,CAAA,KAAA,CAAA,GAAA,KAAW,CAAA;AACX,IAAA,iBAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACjB,CAAC,EAHW,iBAAiB,KAAjB,iBAAiB,GAG5B,EAAA,CAAA,CAAA;;;;"}
@@ -0,0 +1,73 @@
1
+ import '../../utils/dayjs.js';
2
+ import dayjs from 'dayjs';
3
+
4
+ // TODO Use `date-fns` instead of `dayjs`.
5
+ function formatNumberAsDoubleDigit(numberLike) {
6
+ return String(numberLike).padStart(2, '0');
7
+ }
8
+ function getDateFromDateAndTimeTuple(dateTuple, timeTuple, isEnd = false) {
9
+ const [year, month, day] = dateTuple;
10
+ const [hour, minute] = timeTuple;
11
+ const rawDateAsDayjs = dayjs()
12
+ .year(Number(year))
13
+ .month(Number(month) - 1)
14
+ .date(Number(day))
15
+ .hour(Number(hour))
16
+ .minute(Number(minute));
17
+ return isEnd
18
+ ? rawDateAsDayjs
19
+ .endOf('minute')
20
+ // TODO For some reason the API can't handle miliseconds in dates.
21
+ // That's why we set it to 0 (instead of 999)
22
+ .millisecond(0)
23
+ .toDate()
24
+ : rawDateAsDayjs.startOf('minute').toDate();
25
+ }
26
+ function getDateTupleFromDate(date) {
27
+ if (!date) {
28
+ return undefined;
29
+ }
30
+ return [
31
+ String(date.getFullYear()),
32
+ formatNumberAsDoubleDigit(date.getMonth() + 1),
33
+ formatNumberAsDoubleDigit(date.getDate())
34
+ ];
35
+ }
36
+ /**
37
+ * Generate a list of ranged time options.
38
+ *
39
+ * @example
40
+ * ```
41
+ * (minutesRange = 30) => ([
42
+ * { label: '00:00', value: ['00', '00'] },
43
+ * { label: '00:30', value: ['00', '30'] },
44
+ * { label: '01:00', value: ['01', '00'] },
45
+ * { label: '01:30', value: ['01', '30'] },
46
+ * { label: '02:00', value: ['02', '00'] },
47
+ * ...
48
+ * ])
49
+ * ```
50
+ */
51
+ const getRangedTimeOptions = (minutesRange) => {
52
+ const perHourOptionsLength = 60 / minutesRange;
53
+ const totalOptionsLength = 24 * perHourOptionsLength;
54
+ return new Array(totalOptionsLength).fill(undefined).map((_, index) => {
55
+ const hour = Math.floor(index / perHourOptionsLength);
56
+ const minute = minutesRange * (index % perHourOptionsLength);
57
+ const label = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`;
58
+ const value = [formatNumberAsDoubleDigit(hour), formatNumberAsDoubleDigit(minute)];
59
+ return {
60
+ label,
61
+ value
62
+ };
63
+ });
64
+ };
65
+ function getTimeTupleFromDate(date) {
66
+ if (!date) {
67
+ return undefined;
68
+ }
69
+ return [formatNumberAsDoubleDigit(date.getHours()), formatNumberAsDoubleDigit(date.getMinutes())];
70
+ }
71
+
72
+ export { formatNumberAsDoubleDigit, getDateFromDateAndTimeTuple, getDateTupleFromDate, getRangedTimeOptions, getTimeTupleFromDate };
73
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sources":["../../../../src/fields/DateRangePicker/utils.ts"],"sourcesContent":["// TODO Use `date-fns` instead of `dayjs`.\n\nimport { dayjs } from '../../utils/dayjs'\n\nimport type { Option } from '../../types'\nimport type { DateTuple, TimeTuple } from './types'\n\nexport function formatNumberAsDoubleDigit(numberLike: number | string): string {\n return String(numberLike).padStart(2, '0')\n}\n\nexport function getDateFromDateAndTimeTuple(dateTuple: DateTuple, timeTuple: TimeTuple, isEnd: boolean = false): Date {\n const [year, month, day] = dateTuple\n const [hour, minute] = timeTuple\n\n const rawDateAsDayjs = dayjs()\n .year(Number(year))\n .month(Number(month) - 1)\n .date(Number(day))\n .hour(Number(hour))\n .minute(Number(minute))\n\n return isEnd\n ? rawDateAsDayjs\n .endOf('minute')\n // TODO For some reason the API can't handle miliseconds in dates.\n // That's why we set it to 0 (instead of 999)\n .millisecond(0)\n .toDate()\n : rawDateAsDayjs.startOf('minute').toDate()\n}\n\nexport function getDateTupleFromDate(date: undefined): undefined\nexport function getDateTupleFromDate(date: Date): DateTuple\nexport function getDateTupleFromDate(date?: Date): DateTuple | undefined\nexport function getDateTupleFromDate(date?: Date): DateTuple | undefined {\n if (!date) {\n return undefined\n }\n\n return [\n String(date.getFullYear()),\n formatNumberAsDoubleDigit(date.getMonth() + 1),\n formatNumberAsDoubleDigit(date.getDate())\n ]\n}\n\n/**\n * Generate a list of ranged time options.\n *\n * @example\n * ```\n * (minutesRange = 30) => ([\n * { label: '00:00', value: ['00', '00'] },\n * { label: '00:30', value: ['00', '30'] },\n * { label: '01:00', value: ['01', '00'] },\n * { label: '01:30', value: ['01', '30'] },\n * { label: '02:00', value: ['02', '00'] },\n * ...\n * ])\n * ```\n */\nexport const getRangedTimeOptions = (minutesRange: number): Option<TimeTuple>[] => {\n const perHourOptionsLength = 60 / minutesRange\n const totalOptionsLength = 24 * perHourOptionsLength\n\n return new Array(totalOptionsLength).fill(undefined).map((_, index) => {\n const hour = Math.floor(index / perHourOptionsLength)\n const minute = minutesRange * (index % perHourOptionsLength)\n const label = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`\n const value: TimeTuple = [formatNumberAsDoubleDigit(hour), formatNumberAsDoubleDigit(minute)]\n\n return {\n label,\n value\n }\n })\n}\n\nexport function getTimeTupleFromDate(date?: Date): TimeTuple | undefined {\n if (!date) {\n return undefined\n }\n\n return [formatNumberAsDoubleDigit(date.getHours()), formatNumberAsDoubleDigit(date.getMinutes())]\n}\n"],"names":[],"mappings":";;;AAAA;AAOM,SAAU,yBAAyB,CAAC,UAA2B,EAAA;IACnE,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;AAC5C,CAAC;AAEK,SAAU,2BAA2B,CAAC,SAAoB,EAAE,SAAoB,EAAE,QAAiB,KAAK,EAAA;IAC5G,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,SAAS,CAAA;AACpC,IAAA,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;IAEhC,MAAM,cAAc,GAAG,KAAK,EAAE;AAC3B,SAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAClB,SAAA,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACxB,SAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACjB,SAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAClB,SAAA,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;AAEzB,IAAA,OAAO,KAAK;AACV,UAAE,cAAc;aACX,KAAK,CAAC,QAAQ,CAAC;;;aAGf,WAAW,CAAC,CAAC,CAAC;AACd,aAAA,MAAM,EAAE;UACX,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAA;AAC/C,CAAC;AAKK,SAAU,oBAAoB,CAAC,IAAW,EAAA;IAC9C,IAAI,CAAC,IAAI,EAAE;AACT,QAAA,OAAO,SAAS,CAAA;AACjB,KAAA;IAED,OAAO;AACL,QAAA,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;AAC1B,QAAA,yBAAyB,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AAC9C,QAAA,yBAAyB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;KAC1C,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;AAcG;AACU,MAAA,oBAAoB,GAAG,CAAC,YAAoB,KAAyB;AAChF,IAAA,MAAM,oBAAoB,GAAG,EAAE,GAAG,YAAY,CAAA;AAC9C,IAAA,MAAM,kBAAkB,GAAG,EAAE,GAAG,oBAAoB,CAAA;AAEpD,IAAA,OAAO,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAI;QACpE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,oBAAoB,CAAC,CAAA;QACrD,MAAM,MAAM,GAAG,YAAY,IAAI,KAAK,GAAG,oBAAoB,CAAC,CAAA;QAC5D,MAAM,KAAK,GAAG,CAAA,EAAG,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA,CAAA,EAAI,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA,CAAE,CAAA;AACnF,QAAA,MAAM,KAAK,GAAc,CAAC,yBAAyB,CAAC,IAAI,CAAC,EAAE,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAA;QAE7F,OAAO;YACL,KAAK;YACL,KAAK;SACN,CAAA;AACH,KAAC,CAAC,CAAA;AACJ,EAAC;AAEK,SAAU,oBAAoB,CAAC,IAAW,EAAA;IAC9C,IAAI,CAAC,IAAI,EAAE;AACT,QAAA,OAAO,SAAS,CAAA;AACjB,KAAA;AAED,IAAA,OAAO,CAAC,yBAAyB,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,yBAAyB,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;AACnG;;;;"}
@@ -0,0 +1,38 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useCallback } from 'react';
3
+ import { SelectPicker, TagPicker } from 'rsuite';
4
+ import styled from 'styled-components';
5
+
6
+ function Select({ isMulti = false, label, name, onChange, options,
7
+ // eslint-disable-next-line @typescript-eslint/naming-convention
8
+ searchable = false, ...originalProps }) {
9
+ const handleChange = useCallback((valueOrValues) => {
10
+ if (!onChange) {
11
+ return;
12
+ }
13
+ const normalizedValueOrValues = !valueOrValues || (Array.isArray(valueOrValues) && !valueOrValues.length) ? undefined : valueOrValues;
14
+ onChange(normalizedValueOrValues);
15
+ }, [onChange]);
16
+ if (isMulti) {
17
+ return (jsx(StyledTagPicker, { data: options, onChange: handleChange, placeholder: label, searchable: searchable, ...originalProps }));
18
+ }
19
+ return (jsx(StyledSelectPicker, { data: options,
20
+ // The `unknown` type from Rsuite library is wrong. It should be inferred from `data` prop type.
21
+ // `onChange: ((value: unknown, event: React.SyntheticEvent<Element, Event>) => void) | undefined`
22
+ onChange: handleChange, placeholder: label, searchable: searchable, ...originalProps }));
23
+ }
24
+ const StyledSelectPicker = styled(SelectPicker) `
25
+ display: inline-flex;
26
+ width: 9.25rem;
27
+ `;
28
+ const StyledTagPicker = styled(TagPicker) `
29
+ cursor: pointer;
30
+ width: 9.25rem;
31
+
32
+ > .rs-picker-toggle {
33
+ cursor: inherit;
34
+ }
35
+ `;
36
+
37
+ export { Select };
38
+ //# sourceMappingURL=Select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.js","sources":["../../../src/fields/Select.tsx"],"sourcesContent":["import { useCallback } from 'react'\nimport { SelectPicker, TagPicker } from 'rsuite'\nimport styled from 'styled-components'\n\nimport type { Option } from '../types'\nimport type { TagPickerProps } from 'rsuite'\nimport type { Promisable } from 'type-fest'\n\nexport type SelectProps = Omit<TagPickerProps, 'as' | 'data' | 'onChange' | 'placeholder'> & {\n isMulti?: boolean\n label: string\n name: string\n onChange: (valueOrValues: string | string[] | undefined) => Promisable<void>\n options: Option[]\n}\nexport function Select({\n isMulti = false,\n label,\n name,\n onChange,\n options,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n searchable = false,\n ...originalProps\n}: SelectProps) {\n const handleChange = useCallback(\n (valueOrValues: string | string[] | null) => {\n if (!onChange) {\n return\n }\n\n const normalizedValueOrValues =\n !valueOrValues || (Array.isArray(valueOrValues) && !valueOrValues.length) ? undefined : valueOrValues\n\n onChange(normalizedValueOrValues)\n },\n [onChange]\n )\n\n if (isMulti) {\n return (\n <StyledTagPicker\n data={options}\n onChange={handleChange}\n placeholder={label}\n searchable={searchable}\n {...originalProps}\n />\n )\n }\n\n return (\n <StyledSelectPicker\n data={options}\n // The `unknown` type from Rsuite library is wrong. It should be inferred from `data` prop type.\n // `onChange: ((value: unknown, event: React.SyntheticEvent<Element, Event>) => void) | undefined`\n onChange={handleChange as any}\n placeholder={label}\n searchable={searchable}\n {...originalProps}\n />\n )\n}\n\nconst StyledSelectPicker = styled(SelectPicker)`\n display: inline-flex;\n width: 9.25rem;\n`\n\nconst StyledTagPicker = styled(TagPicker)`\n cursor: pointer;\n width: 9.25rem;\n\n > .rs-picker-toggle {\n cursor: inherit;\n }\n`\n"],"names":["_jsx"],"mappings":";;;;;AAegB,SAAA,MAAM,CAAC,EACrB,OAAO,GAAG,KAAK,EACf,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,OAAO;AACP;AACA,UAAU,GAAG,KAAK,EAClB,GAAG,aAAa,EACJ,EAAA;AACZ,IAAA,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,aAAuC,KAAI;QAC1C,IAAI,CAAC,QAAQ,EAAE;YACb,OAAM;AACP,SAAA;QAED,MAAM,uBAAuB,GAC3B,CAAC,aAAa,KAAK,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,GAAG,aAAa,CAAA;QAEvG,QAAQ,CAAC,uBAAuB,CAAC,CAAA;AACnC,KAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAA;AAED,IAAA,IAAI,OAAO,EAAE;QACX,QACEA,IAAC,eAAe,EAAA,EACd,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,YAAY,EACtB,WAAW,EAAE,KAAK,EAClB,UAAU,EAAE,UAAU,EAClB,GAAA,aAAa,EACjB,CAAA,EACH;AACF,KAAA;AAED,IAAA,QACEA,GAAC,CAAA,kBAAkB,EACjB,EAAA,IAAI,EAAE,OAAO;;;AAGb,QAAA,QAAQ,EAAE,YAAmB,EAC7B,WAAW,EAAE,KAAK,EAClB,UAAU,EAAE,UAAU,EAAA,GAClB,aAAa,EAAA,CACjB,EACH;AACH,CAAC;AAED,MAAM,kBAAkB,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA,CAAA;;;CAG9C,CAAA;AAED,MAAM,eAAe,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA,CAAA;;;;;;;CAOxC;;;;"}
@@ -0,0 +1,14 @@
1
+ import { jsx, Fragment } from 'react/jsx-runtime';
2
+ import { useFormikContext } from 'formik';
3
+ import { useEffect } from 'react';
4
+
5
+ function FormikEffect({ onChange }) {
6
+ const { values } = useFormikContext();
7
+ useEffect(() => {
8
+ onChange(values);
9
+ }, [onChange, values]);
10
+ return jsx(Fragment, {});
11
+ }
12
+
13
+ export { FormikEffect };
14
+ //# sourceMappingURL=FormikEffect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormikEffect.js","sources":["../../../src/formiks/FormikEffect.tsx"],"sourcesContent":["import { useFormikContext } from 'formik'\nimport { useEffect } from 'react'\n\nimport type { Promisable } from 'type-fest'\n\nexport type FormikEffectProps = {\n onChange: (nextValues: Record<string, any>) => Promisable<void>\n}\nexport function FormikEffect({ onChange }: FormikEffectProps) {\n const { values } = useFormikContext<Record<string, any>>()\n\n useEffect(() => {\n onChange(values)\n }, [onChange, values])\n\n return <></>\n}\n"],"names":["_jsx"],"mappings":";;;;AAQgB,SAAA,YAAY,CAAC,EAAE,QAAQ,EAAqB,EAAA;AAC1D,IAAA,MAAM,EAAE,MAAM,EAAE,GAAG,gBAAgB,EAAuB,CAAA;IAE1D,SAAS,CAAC,MAAK;QACb,QAAQ,CAAC,MAAM,CAAC,CAAA;AAClB,KAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;AAEtB,IAAA,OAAOA,iBAAK,CAAA;AACd;;;;"}