@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
package/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # Monitor UI
2
+
3
+ [![License][img-license]][lnk-license]
4
+ [![CI Status][img-github]][lnk-github]
5
+ <!-- [![NPM Version][img-npm]][lnk-npm] -->
6
+
7
+ > Common React UI components and styles for Monitorfish and Monitorenv..
8
+
9
+ ## Documentation
10
+
11
+ Here is [the Storybook][lnk-storybook].
12
+
13
+ ## Contributing
14
+
15
+ Please read the [contributing document](CONTRIBUTING.md) for setup and contributing instructions.
16
+
17
+ ---
18
+
19
+ [img-github]: https://img.shields.io/github/workflow/status/MTES-MCT/monitor-ui/Check/main?style=flat-square
20
+ [img-license]: https://img.shields.io/github/license/MTES-MCT/monitor-ui?style=flat-square
21
+ [img-npm]: https://img.shields.io/npm/v/@MTES-MCT/monitor-ui?style=flat-square
22
+ [lnk-github]: https://github.com/MTES-MCT/monitor-ui/actions?query=branch%3Amain++
23
+ [lnk-license]: https://github.com/MTES-MCT/monitor-ui/blob/main/LICENSE
24
+ [lnk-npm]: https://www.npmjs.com/package/@MTES-MCT/monitor-ui
25
+ [lnk-storybook]: https://mtes-mct.github.io/monitor-ui/
@@ -0,0 +1,7 @@
1
+ import { Theme } from './theme';
2
+ import type { DeepPartial } from './types';
3
+ export declare type ThemeProviderProps = {
4
+ children: any;
5
+ theme?: DeepPartial<Theme>;
6
+ };
7
+ export declare function ThemeProvider({ children, theme }: ThemeProviderProps): JSX.Element;
@@ -0,0 +1,4 @@
1
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
2
+
3
+ export { commonjsGlobal };
4
+ //# sourceMappingURL=_commonjsHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_commonjsHelpers.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
package/_virtual/fr.js ADDED
@@ -0,0 +1,4 @@
1
+ var fr = {exports: {}};
2
+
3
+ export { fr as f };
4
+ //# sourceMappingURL=fr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fr.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,4 @@
1
+ var timezone = {exports: {}};
2
+
3
+ export { timezone as t };
4
+ //# sourceMappingURL=timezone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timezone.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,4 @@
1
+ var utc = {exports: {}};
2
+
3
+ export { utc as u };
4
+ //# sourceMappingURL=utc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utc.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
package/constants.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { DateTuple } from '../DateRangePicker/types';
2
+ import type { Promisable } from 'type-fest';
3
+ declare type CalendarPickerProps = {
4
+ defaultValue?: Date;
5
+ isHistorical?: boolean;
6
+ onChange: (nextDateTuple: DateTuple) => Promisable<void>;
7
+ };
8
+ export declare function CalendarPicker({ defaultValue, isHistorical, onChange }: CalendarPickerProps): JSX.Element;
9
+ export {};
@@ -0,0 +1,23 @@
1
+ import type { Promisable } from 'type-fest';
2
+ export declare type DatePickerProps = {
3
+ defaultValue?: Date;
4
+ /** Only allow past dates until today. */
5
+ isHistorical?: boolean;
6
+ isLabelHidden?: boolean;
7
+ label: string;
8
+ /**
9
+ * Range of minutes used to generate the time picker list.
10
+ *
11
+ * @example
12
+ * `15` would produce a list with `..., 10:45, 11:00, 11:15, ...`.
13
+ */
14
+ minutesRange?: number;
15
+ /**
16
+ * Called each time the date range picker is changed to a new valid value.
17
+ *
18
+ * @param nextUtcDateRange - A utcized date to be used as is to interact with the API.
19
+ */
20
+ onChange: (nextUtcDate: Date) => Promisable<void>;
21
+ withTime?: boolean;
22
+ };
23
+ export declare function DatePicker({ defaultValue, isHistorical, isLabelHidden, label, minutesRange, onChange, withTime }: DatePickerProps): JSX.Element;
@@ -0,0 +1,22 @@
1
+ /// <reference types="react" />
2
+ import type { NumberInputProps } from './NumberInput';
3
+ import type { DateTuple, DateOrTimeInputRef } from './types';
4
+ import type { Promisable } from 'type-fest';
5
+ export declare type DateInputProps = Pick<NumberInputProps, 'onBack' | 'onPrevious' | 'onNext'> & {
6
+ defaultValue?: DateTuple;
7
+ isEndDate?: boolean;
8
+ isForcedFocused: boolean;
9
+ isStartDate?: boolean;
10
+ /** Called each time the date input is changed to a new valid value. */
11
+ onChange: (nextDateTuple: DateTuple) => Promisable<void>;
12
+ onClick: () => Promisable<void>;
13
+ };
14
+ export declare const DateInput: import("react").ForwardRefExoticComponent<Pick<NumberInputProps, "onBack" | "onNext" | "onPrevious"> & {
15
+ defaultValue?: DateTuple | undefined;
16
+ isEndDate?: boolean | undefined;
17
+ isForcedFocused: boolean;
18
+ isStartDate?: boolean | undefined;
19
+ /** Called each time the date input is changed to a new valid value. */
20
+ onChange: (nextDateTuple: DateTuple) => Promisable<void>;
21
+ onClick: () => Promisable<void>;
22
+ } & import("react").RefAttributes<DateOrTimeInputRef>>;
@@ -0,0 +1,32 @@
1
+ import type { InputHTMLAttributes } from 'react';
2
+ import type { Promisable } from 'type-fest';
3
+ export declare type NumberInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'maxLength' | 'onInput' | 'pattern' | 'type'> & {
4
+ max: number;
5
+ min: number;
6
+ /** Called when the use press backspace key while the input is empty. */
7
+ onBack?: () => Promisable<void>;
8
+ /** Called when the input value reaches the size property. */
9
+ onFilled?: () => Promisable<void>;
10
+ onFormatError: (hasNextFormatError: boolean) => Promisable<void>;
11
+ onInput?: (nextValue: string) => Promisable<void>;
12
+ /** Called when the right arrow is pressed while the cursor is positionned at the input end. */
13
+ onNext?: () => Promisable<void>;
14
+ /** Called when the left arrow is pressed while the cursor is positionned at the input start. */
15
+ onPrevious?: () => Promisable<void>;
16
+ size: number;
17
+ };
18
+ export declare const NumberInput: import("react").ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "maxLength" | "onInput" | "pattern" | "type"> & {
19
+ max: number;
20
+ min: number;
21
+ /** Called when the use press backspace key while the input is empty. */
22
+ onBack?: (() => Promisable<void>) | undefined;
23
+ /** Called when the input value reaches the size property. */
24
+ onFilled?: (() => Promisable<void>) | undefined;
25
+ onFormatError: (hasNextFormatError: boolean) => Promisable<void>;
26
+ onInput?: ((nextValue: string) => Promisable<void>) | undefined;
27
+ /** Called when the right arrow is pressed while the cursor is positionned at the input end. */
28
+ onNext?: (() => Promisable<void>) | undefined;
29
+ /** Called when the left arrow is pressed while the cursor is positionned at the input start. */
30
+ onPrevious?: (() => Promisable<void>) | undefined;
31
+ size: number;
32
+ } & import("react").RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,10 @@
1
+ import type { DateRange } from '../../types';
2
+ import type { DateTupleRange } from './types';
3
+ import type { Promisable } from 'type-fest';
4
+ declare type RangeCalendarPickerProps = {
5
+ defaultValue?: DateRange;
6
+ isHistorical?: boolean;
7
+ onChange: (nextDateTupleRange: DateTupleRange) => Promisable<void>;
8
+ };
9
+ export declare function RangeCalendarPicker({ defaultValue, isHistorical, onChange }: RangeCalendarPickerProps): JSX.Element;
10
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { TimeTuple } from './types';
2
+ import type { Promisable } from 'type-fest';
3
+ declare type RangedTimePickerProps = {
4
+ filter: RegExp;
5
+ minutesRange: number;
6
+ onChange: (nextTimeTuple: TimeTuple) => Promisable<void>;
7
+ };
8
+ export declare function RangedTimePicker({ filter, minutesRange, onChange }: RangedTimePickerProps): JSX.Element;
9
+ export {};
@@ -0,0 +1,24 @@
1
+ /// <reference types="react" />
2
+ import type { NumberInputProps } from './NumberInput';
3
+ import type { DateOrTimeInputRef, TimeTuple } from './types';
4
+ import type { Promisable } from 'type-fest';
5
+ export declare type TimeInputProps = Pick<NumberInputProps, 'onBack' | 'onPrevious' | 'onNext'> & {
6
+ defaultValue?: TimeTuple;
7
+ isStartDate?: boolean;
8
+ minutesRange?: number;
9
+ /** Called each time the time input is changed to a new valid value. */
10
+ onChange: (nextTimeTuple: TimeTuple) => Promisable<void>;
11
+ onFocus?: () => Promisable<void>;
12
+ onNext?: () => Promisable<void>;
13
+ onPrevious?: () => Promisable<void>;
14
+ };
15
+ export declare const TimeInput: import("react").ForwardRefExoticComponent<Pick<NumberInputProps, "onBack" | "onNext" | "onPrevious"> & {
16
+ defaultValue?: TimeTuple | undefined;
17
+ isStartDate?: boolean | undefined;
18
+ minutesRange?: number | undefined;
19
+ /** Called each time the time input is changed to a new valid value. */
20
+ onChange: (nextTimeTuple: TimeTuple) => Promisable<void>;
21
+ onFocus?: (() => Promisable<void>) | undefined;
22
+ onNext?: (() => Promisable<void>) | undefined;
23
+ onPrevious?: (() => Promisable<void>) | undefined;
24
+ } & import("react").RefAttributes<DateOrTimeInputRef>>;
@@ -0,0 +1,11 @@
1
+ import type { DateRangePickerLocale } from 'rsuite';
2
+ export declare const HOURS_AS_OPTIONS: {
3
+ label: string;
4
+ value: number;
5
+ }[];
6
+ export declare const RSUITE_CALENDAR_LOCALE: DateRangePickerLocale;
7
+ export declare enum STATUS {
8
+ 'END_DATE' = "END_DATE",
9
+ 'NO_DATE' = "NO_DATE",
10
+ 'START_DATE' = "START_DATE"
11
+ }
@@ -0,0 +1,24 @@
1
+ import type { DateRange } from '../../types';
2
+ import type { Promisable } from 'type-fest';
3
+ export declare type DateRangePickerProps = {
4
+ defaultValue?: DateRange;
5
+ /** Only allow past dates until today. */
6
+ isHistorical?: boolean;
7
+ isLabelHidden?: boolean;
8
+ label: string;
9
+ /**
10
+ * Range of minutes used to generate the time picker list.
11
+ *
12
+ * @example
13
+ * `15` would produce a list with `..., 10:45, 11:00, 11:15, ...`.
14
+ */
15
+ minutesRange?: number;
16
+ /**
17
+ * Called each time the date range picker is changed to a new valid value.
18
+ *
19
+ * @param nextUtcDateRange - A utcized date to be used as is to interact with the API.
20
+ */
21
+ onChange: (nextUtcDateRange: DateRange) => Promisable<void>;
22
+ withTime?: boolean;
23
+ };
24
+ export declare function DateRangePicker({ defaultValue, isHistorical, isLabelHidden, label, minutesRange, onChange, withTime }: DateRangePickerProps): JSX.Element;
@@ -0,0 +1,18 @@
1
+ export declare type DateOrTimeInputRef = {
2
+ boxSpan: HTMLSpanElement;
3
+ /**
4
+ * Focus the first input in the group.
5
+ *
6
+ * @param inLastInputOfTheGroup - If `true`, focus the last input in the group instead of the first one
7
+ */
8
+ focus: (inLastInputOfTheGroup?: boolean) => void;
9
+ };
10
+ export declare enum DateRangePosition {
11
+ END = "END",
12
+ START = "START"
13
+ }
14
+ /** In the shape of ["YYYY", "MM", "DD"]. */
15
+ export declare type DateTuple = [string, string, string];
16
+ export declare type DateTupleRange = [DateTuple, DateTuple];
17
+ /** In the shape of ["hh", "mm"]. */
18
+ export declare type TimeTuple = [string, string];
@@ -0,0 +1,24 @@
1
+ import type { Option } from '../../types';
2
+ import type { DateTuple, TimeTuple } from './types';
3
+ export declare function formatNumberAsDoubleDigit(numberLike: number | string): string;
4
+ export declare function getDateFromDateAndTimeTuple(dateTuple: DateTuple, timeTuple: TimeTuple, isEnd?: boolean): Date;
5
+ export declare function getDateTupleFromDate(date: undefined): undefined;
6
+ export declare function getDateTupleFromDate(date: Date): DateTuple;
7
+ export declare function getDateTupleFromDate(date?: Date): DateTuple | undefined;
8
+ /**
9
+ * Generate a list of ranged time options.
10
+ *
11
+ * @example
12
+ * ```
13
+ * (minutesRange = 30) => ([
14
+ * { label: '00:00', value: ['00', '00'] },
15
+ * { label: '00:30', value: ['00', '30'] },
16
+ * { label: '01:00', value: ['01', '00'] },
17
+ * { label: '01:30', value: ['01', '30'] },
18
+ * { label: '02:00', value: ['02', '00'] },
19
+ * ...
20
+ * ])
21
+ * ```
22
+ */
23
+ export declare const getRangedTimeOptions: (minutesRange: number) => Option<TimeTuple>[];
24
+ export declare function getTimeTupleFromDate(date?: Date): TimeTuple | undefined;
@@ -0,0 +1,11 @@
1
+ import type { Option } from '../types';
2
+ import type { TagPickerProps } from 'rsuite';
3
+ import type { Promisable } from 'type-fest';
4
+ export declare type SelectProps = Omit<TagPickerProps, 'as' | 'data' | 'onChange' | 'placeholder'> & {
5
+ isMulti?: boolean;
6
+ label: string;
7
+ name: string;
8
+ onChange: (valueOrValues: string | string[] | undefined) => Promisable<void>;
9
+ options: Option[];
10
+ };
11
+ export declare function Select({ isMulti, label, name, onChange, options, searchable, ...originalProps }: SelectProps): JSX.Element;
@@ -0,0 +1,5 @@
1
+ import type { Promisable } from 'type-fest';
2
+ export declare type FormikEffectProps = {
3
+ onChange: (nextValues: Record<string, any>) => Promisable<void>;
4
+ };
5
+ export declare function FormikEffect({ onChange }: FormikEffectProps): JSX.Element;
@@ -0,0 +1,5 @@
1
+ import type { SelectProps } from '../fields/Select';
2
+ export declare type FormikSelectProps = Omit<SelectProps, 'name' | 'onChange'> & {
3
+ name: string;
4
+ };
5
+ export declare function FormikSelect({ name, ...originalProps }: FormikSelectProps): JSX.Element;
@@ -0,0 +1,10 @@
1
+ /// <reference types="react" />
2
+ /**
3
+ * Force component re-rendering
4
+ *
5
+ * @see https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate
6
+ */
7
+ export declare function useForceUpdate(): {
8
+ forceDebouncedUpdate: import("lodash").DebouncedFunc<import("react").DispatchWithoutAction>;
9
+ forceUpdate: import("react").DispatchWithoutAction;
10
+ };
package/index.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ export * as MUI from './constants';
2
+ export { THEME } from './theme';
3
+ export { DateRangePicker } from './fields/DateRangePicker';
4
+ export { DatePicker } from './fields/DatePicker';
5
+ export { Select } from './fields/Select';
6
+ export { FormikEffect } from './formiks/FormikEffect';
7
+ export { FormikSelect } from './formiks/FormikSelect';
8
+ export { ThemeProvider } from './ThemeProvider';
9
+ export type { PartialTheme, Theme } from './theme';
10
+ export type { DateRangePickerProps } from './fields/DateRangePicker';
11
+ export type { DatePickerProps } from './fields/DatePicker';
12
+ export type { SelectProps } from './fields/Select';
13
+ export type { FormikEffectProps } from './formiks/FormikEffect';
14
+ export type { FormikSelectProps } from './formiks/FormikSelect';
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@mtes-mct/monitor-ui",
3
+ "description": "Common React UI components and styles for Monitorfish and Monitorenv.",
4
+ "version": "1.1.1",
5
+ "license": "AGPL-3.0",
6
+ "engines": {
7
+ "node": "18",
8
+ "npm": "8"
9
+ },
10
+ "browser": "./src/index.ts",
11
+ "dependencies": {
12
+ "@babel/runtime": "7.19.4",
13
+ "date-fns": "2.29.3",
14
+ "dayjs": "1.11.5",
15
+ "lodash.throttle": "4.1.1",
16
+ "prop-types": "15.8.1",
17
+ "ramda": "0.28.0",
18
+ "rsuite": "5.19.1",
19
+ "tslib": "2.4.0",
20
+ "type-fest": "3.1.0"
21
+ },
22
+ "peerDependencies": {
23
+ "formik": "^2.0.0",
24
+ "react": "^18.0.0",
25
+ "react-dom": "^18.0.0",
26
+ "styled-components": "^5.0.0"
27
+ },
28
+ "//": "https://github.com/okonet/lint-staged/issues/825#issuecomment-674575655",
29
+ "lint-staged": {
30
+ "*.{json,md,yaml,yml}": "prettier --write",
31
+ "*.{ts,tsx}": [
32
+ "eslint",
33
+ "bash -c 'npm run test:type:partial'"
34
+ ]
35
+ },
36
+ "packageManager": "yarn@3.2.4",
37
+ "bugs": {
38
+ "url": "https://github.com/MTES-MCT/monitor-ui/issues"
39
+ },
40
+ "exports": "./index.js",
41
+ "homepage": "https://mtes-mct.github.io/monitor-ui/",
42
+ "publishConfig": {
43
+ "access": "public",
44
+ "tag": "latest"
45
+ },
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git+https://github.com/MTES-MCT/monitor-ui.git"
49
+ },
50
+ "sideEffects": false,
51
+ "type": "module",
52
+ "types": "./index.d.ts"
53
+ }
@@ -0,0 +1,13 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { mergeDeepRight } from 'ramda';
3
+ import { ThemeProvider as ThemeProvider$1 } from 'styled-components';
4
+ import { THEME } from './theme.js';
5
+
6
+ const UntypedStyledComponentsThemeProvider = ThemeProvider$1;
7
+ function ThemeProvider({ children, theme = {} }) {
8
+ const finalTheme = mergeDeepRight(THEME, theme);
9
+ return jsx(UntypedStyledComponentsThemeProvider, { theme: finalTheme, children: children });
10
+ }
11
+
12
+ export { ThemeProvider };
13
+ //# sourceMappingURL=ThemeProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThemeProvider.js","sources":["../../src/ThemeProvider.tsx"],"sourcesContent":["import { mergeDeepRight } from 'ramda'\nimport { ThemeProvider as StyledComponentsThemeProvider } from 'styled-components'\n\nimport { THEME, Theme } from './theme'\n\nimport type { DeepPartial } from './types'\n\nconst UntypedStyledComponentsThemeProvider: any = StyledComponentsThemeProvider\n\nexport type ThemeProviderProps = {\n children: any\n theme?: DeepPartial<Theme>\n}\nexport function ThemeProvider({ children, theme = {} }: ThemeProviderProps) {\n const finalTheme = mergeDeepRight(THEME, theme)\n\n return <UntypedStyledComponentsThemeProvider theme={finalTheme}>{children}</UntypedStyledComponentsThemeProvider>\n}\n"],"names":["StyledComponentsThemeProvider","_jsx"],"mappings":";;;;;AAOA,MAAM,oCAAoC,GAAQA,eAA6B,CAAA;AAMzE,SAAU,aAAa,CAAC,EAAE,QAAQ,EAAE,KAAK,GAAG,EAAE,EAAsB,EAAA;IACxE,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAE/C,OAAOC,GAAA,CAAC,oCAAoC,EAAC,EAAA,KAAK,EAAE,UAAU,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAwC,CAAA;AACnH;;;;"}
@@ -0,0 +1,2 @@
1
+ /* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/string-enum */
2
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sources":["../../src/constants.ts"],"sourcesContent":["/* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/string-enum */\n\nexport {}\n"],"names":[],"mappings":"AAAA"}
@@ -0,0 +1,137 @@
1
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import { useRef, useState, useMemo, useCallback, useEffect } from 'react';
3
+ import { DatePicker } from 'rsuite';
4
+ import styled, { createGlobalStyle } from 'styled-components';
5
+ import { getUtcDayjs } from '../../utils/getUtcDayjs.js';
6
+ import { getUtcizedDayjs } from '../../utils/getUtcizedDayjs.js';
7
+ import { stopMouseEventPropagation } from '../../utils/stopMouseEventPropagation.js';
8
+ import { RSUITE_CALENDAR_LOCALE } from '../DateRangePicker/constants.js';
9
+ import { getDateTupleFromDate } from '../DateRangePicker/utils.js';
10
+
11
+ function CalendarPicker({ defaultValue, isHistorical, onChange }) {
12
+ const boxRef = useRef();
13
+ const calendarRef = useRef();
14
+ const [isFirstLoad, setIsFirstLoad] = useState(true);
15
+ const utcTodayAsDayjs = useMemo(() => getUtcDayjs().endOf('day'), []);
16
+ const disabledDate = useMemo(() => (date) => date && isHistorical ? getUtcizedDayjs(date).isAfter(utcTodayAsDayjs) : false, [isHistorical, utcTodayAsDayjs]);
17
+ const handleSelect = useCallback((nextDate) => {
18
+ const nextDateTuple = getDateTupleFromDate(nextDate);
19
+ onChange(nextDateTuple);
20
+ }, [onChange]);
21
+ useEffect(() => {
22
+ // We wait for the <Box /> to render so that `boxRef` is defined
23
+ // and can be used as a container for <RsuiteDateRangePicker />
24
+ setIsFirstLoad(false);
25
+ }, []);
26
+ return (jsxs(Fragment, { children: [jsx(GlobalStyleToHideBodyDialog, {}), jsx(Box, { ref: boxRef, onClick: stopMouseEventPropagation, children: !isFirstLoad && (jsx(DatePicker, { ref: calendarRef, container: boxRef.current, disabledDate: disabledDate, format: "yyyy-MM-dd", locale: RSUITE_CALENDAR_LOCALE, oneTap: true, onSelect: handleSelect, open: true, ranges: [],
27
+ // `defaultValue` seems to be immediatly cancelled so we come down to using a controlled `value`
28
+ value: defaultValue })) })] }));
29
+ }
30
+ const GlobalStyleToHideBodyDialog = createGlobalStyle `
31
+ body > div[role="dialog"].rs-picker-date-menu {
32
+ display: none;
33
+ }
34
+ `;
35
+ const Box = styled.div `
36
+ height: 0;
37
+ position: relative;
38
+ user-select: none;
39
+
40
+ .rs-picker-toggle {
41
+ display: none;
42
+ }
43
+
44
+ .rs-picker-date-panel {
45
+ height: 290px;
46
+ }
47
+
48
+ .rs-picker-date-menu {
49
+ border: solid 1px ${p => p.theme.color.lightGray};
50
+ border-radius: 0;
51
+ margin-top: 0.25rem;
52
+
53
+ .rs-picker-date-header,
54
+ .rs-calendar-header-time-toolbar,
55
+ .rs-picker-toolbar {
56
+ display: none;
57
+ }
58
+
59
+ .rs-calendar {
60
+ height: auto !important;
61
+ padding: 0;
62
+
63
+ :first-child {
64
+ border-right: solid 1px ${p => p.theme.color.lightGray};
65
+ }
66
+
67
+ .rs-calendar-header {
68
+ border-bottom: solid 1px ${p => p.theme.color.lightGray};
69
+ padding: 0.5rem;
70
+
71
+ .rs-calendar-header-month-toolbar {
72
+ align-items: center;
73
+ color: ${p => p.theme.color.slateGray};
74
+ display: flex;
75
+ justify-content: space-between;
76
+
77
+ .rs-calendar-header-title {
78
+ font-size: inherit;
79
+ text-transform: uppercase;
80
+
81
+ &.rs-calendar-header-error {
82
+ color: ${p => p.theme.color.slateGray};
83
+
84
+ :hover {
85
+ color: ${p => p.theme.color.slateGray};
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+
92
+ .rs-calendar-view {
93
+ padding: 0.75rem 0.5rem 0;
94
+
95
+ .rs-calendar-table-cell {
96
+ padding: 0 0 0.25rem 0;
97
+ width: 33px;
98
+
99
+ &.rs-calendar-table-cell-in-range:before {
100
+ background-color: ${p => p.theme.color.blueGray[25]};
101
+ height: 33px;
102
+ margin-top: 0;
103
+ }
104
+
105
+ > .rs-calendar-table-cell-content {
106
+ align-items: center;
107
+ border-radius: 0 !important;
108
+ display: inline-flex;
109
+ height: 33px;
110
+ justify-content: center;
111
+ padding-bottom: 3px;
112
+ width: 33px;
113
+ }
114
+ :hover .rs-calendar-table-cell-content {
115
+ background-color: ${p => p.theme.color.blueYonder[25]};
116
+ color: ${p => p.theme.color.blueYonder[100]};
117
+ }
118
+ &[role='columnheader'] .rs-calendar-table-cell-content,
119
+ &[role='columnheader']:hover .rs-calendar-table-cell-content {
120
+ background-color: transparent;
121
+ color: ${p => p.theme.color.slateGray};
122
+ }
123
+ &.rs-calendar-table-cell-disabled .rs-calendar-table-cell-content {
124
+ background-color: transparent;
125
+ color: ${p => p.theme.color.lightGray};
126
+ }
127
+ &.rs-calendar-table-cell-selected > .rs-calendar-table-cell-content {
128
+ background-color: ${p => p.theme.color.blueGray[100]};
129
+ }
130
+ }
131
+ }
132
+ }
133
+ }
134
+ `;
135
+
136
+ export { CalendarPicker };
137
+ //# sourceMappingURL=CalendarPicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CalendarPicker.js","sources":["../../../../src/fields/DatePicker/CalendarPicker.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { DatePicker as RsuiteDatePicker } from 'rsuite'\nimport styled, { createGlobalStyle } from 'styled-components'\n\nimport { getUtcDayjs } from '../../utils/getUtcDayjs'\nimport { getUtcizedDayjs } from '../../utils/getUtcizedDayjs'\nimport { stopMouseEventPropagation } from '../../utils/stopMouseEventPropagation'\nimport { RSUITE_CALENDAR_LOCALE } from '../DateRangePicker/constants'\nimport { getDateTupleFromDate } from '../DateRangePicker/utils'\n\nimport type { DateTuple } from '../DateRangePicker/types'\nimport type { MutableRefObject } from 'react'\nimport type { Promisable } from 'type-fest'\n\ntype CalendarPickerProps = {\n defaultValue?: Date\n isHistorical?: boolean\n onChange: (nextDateTuple: DateTuple) => Promisable<void>\n}\nexport function CalendarPicker({ defaultValue, isHistorical, onChange }: CalendarPickerProps) {\n const boxRef = useRef() as MutableRefObject<HTMLDivElement>\n const calendarRef = useRef<any>()\n\n const [isFirstLoad, setIsFirstLoad] = useState(true)\n\n const utcTodayAsDayjs = useMemo(() => getUtcDayjs().endOf('day'), [])\n const disabledDate = useMemo(\n () => (date?: Date) => date && isHistorical ? getUtcizedDayjs(date).isAfter(utcTodayAsDayjs) : false,\n [isHistorical, utcTodayAsDayjs]\n )\n\n const handleSelect = useCallback(\n (nextDate: Date) => {\n const nextDateTuple = getDateTupleFromDate(nextDate)\n\n onChange(nextDateTuple)\n },\n [onChange]\n )\n\n useEffect(() => {\n // We wait for the <Box /> to render so that `boxRef` is defined\n // and can be used as a container for <RsuiteDateRangePicker />\n setIsFirstLoad(false)\n }, [])\n\n return (\n <>\n <GlobalStyleToHideBodyDialog />\n\n <Box ref={boxRef} onClick={stopMouseEventPropagation}>\n {!isFirstLoad && (\n <RsuiteDatePicker\n ref={calendarRef}\n container={boxRef.current}\n disabledDate={disabledDate}\n format=\"yyyy-MM-dd\"\n locale={RSUITE_CALENDAR_LOCALE}\n oneTap\n onSelect={handleSelect}\n open\n ranges={[]}\n // `defaultValue` seems to be immediatly cancelled so we come down to using a controlled `value`\n value={defaultValue}\n />\n )}\n </Box>\n </>\n )\n}\n\nconst GlobalStyleToHideBodyDialog: any = createGlobalStyle`\n body > div[role=\"dialog\"].rs-picker-date-menu {\n display: none;\n }\n`\n\nconst Box = styled.div`\n height: 0;\n position: relative;\n user-select: none;\n\n .rs-picker-toggle {\n display: none;\n }\n\n .rs-picker-date-panel {\n height: 290px;\n }\n\n .rs-picker-date-menu {\n border: solid 1px ${p => p.theme.color.lightGray};\n border-radius: 0;\n margin-top: 0.25rem;\n\n .rs-picker-date-header,\n .rs-calendar-header-time-toolbar,\n .rs-picker-toolbar {\n display: none;\n }\n\n .rs-calendar {\n height: auto !important;\n padding: 0;\n\n :first-child {\n border-right: solid 1px ${p => p.theme.color.lightGray};\n }\n\n .rs-calendar-header {\n border-bottom: solid 1px ${p => p.theme.color.lightGray};\n padding: 0.5rem;\n\n .rs-calendar-header-month-toolbar {\n align-items: center;\n color: ${p => p.theme.color.slateGray};\n display: flex;\n justify-content: space-between;\n\n .rs-calendar-header-title {\n font-size: inherit;\n text-transform: uppercase;\n\n &.rs-calendar-header-error {\n color: ${p => p.theme.color.slateGray};\n\n :hover {\n color: ${p => p.theme.color.slateGray};\n }\n }\n }\n }\n }\n\n .rs-calendar-view {\n padding: 0.75rem 0.5rem 0;\n\n .rs-calendar-table-cell {\n padding: 0 0 0.25rem 0;\n width: 33px;\n\n &.rs-calendar-table-cell-in-range:before {\n background-color: ${p => p.theme.color.blueGray[25]};\n height: 33px;\n margin-top: 0;\n }\n\n > .rs-calendar-table-cell-content {\n align-items: center;\n border-radius: 0 !important;\n display: inline-flex;\n height: 33px;\n justify-content: center;\n padding-bottom: 3px;\n width: 33px;\n }\n :hover .rs-calendar-table-cell-content {\n background-color: ${p => p.theme.color.blueYonder[25]};\n color: ${p => p.theme.color.blueYonder[100]};\n }\n &[role='columnheader'] .rs-calendar-table-cell-content,\n &[role='columnheader']:hover .rs-calendar-table-cell-content {\n background-color: transparent;\n color: ${p => p.theme.color.slateGray};\n }\n &.rs-calendar-table-cell-disabled .rs-calendar-table-cell-content {\n background-color: transparent;\n color: ${p => p.theme.color.lightGray};\n }\n &.rs-calendar-table-cell-selected > .rs-calendar-table-cell-content {\n background-color: ${p => p.theme.color.blueGray[100]};\n }\n }\n }\n }\n }\n`\n"],"names":["_jsxs","_Fragment","_jsx","RsuiteDatePicker"],"mappings":"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"}