@rio-cloud/rio-uikit 2.5.0-beta.1 → 2.5.0

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 (119) hide show
  1. package/CountedInput.d.ts +2 -0
  2. package/CountedInput.js +5 -0
  3. package/CountedInput.js.map +1 -0
  4. package/TabbedPanel.d.ts +2 -0
  5. package/TabbedPanel.js +5 -0
  6. package/TabbedPanel.js.map +1 -0
  7. package/components/applicationHeader/NavItems.js +58 -46
  8. package/components/applicationHeader/NavItems.js.map +1 -1
  9. package/components/applicationLayout/ApplicationLayoutBody.d.ts +1 -1
  10. package/components/applicationLayout/ApplicationLayoutBody.js +29 -29
  11. package/components/applicationLayout/ApplicationLayoutBody.js.map +1 -1
  12. package/components/applicationLayout/ApplicationLayoutHeader.js +22 -7
  13. package/components/applicationLayout/ApplicationLayoutHeader.js.map +1 -1
  14. package/components/assetTree/useTreeHeight.js.map +1 -1
  15. package/components/button/Button.d.ts +11 -3
  16. package/components/button/Button.js.map +1 -1
  17. package/components/clearableInput/ClearableInput.d.ts +4 -0
  18. package/components/clearableInput/ClearableInput.js.map +1 -1
  19. package/components/countedInput/CountedInput.d.ts +91 -0
  20. package/components/countedInput/CountedInput.js +65 -0
  21. package/components/countedInput/CountedInput.js.map +1 -0
  22. package/components/datepicker/DatePicker.d.ts +1 -1
  23. package/components/datepicker/DatePicker.js +1 -1
  24. package/components/datepicker/DatePicker.js.map +1 -1
  25. package/components/datepicker/DayPicker.js +3 -2
  26. package/components/datepicker/DayPicker.js.map +1 -1
  27. package/components/datepicker/DayPickerInput.d.ts +1 -1
  28. package/components/datepicker/DayPickerInput.js.map +1 -1
  29. package/components/datepicker/dayPickerTypes.d.ts +3 -2
  30. package/components/datepicker/dayPickerTypes.js.map +1 -1
  31. package/components/datepicker/dayPickerUtils.d.ts +1 -1
  32. package/components/datepicker/dayPickerUtils.js +45 -22
  33. package/components/datepicker/dayPickerUtils.js.map +1 -1
  34. package/components/datepicker/useDayPickerInputState.d.ts +1 -1
  35. package/components/dialog/ConfirmationDialog.d.ts +17 -0
  36. package/components/dialog/ConfirmationDialog.js +43 -19
  37. package/components/dialog/ConfirmationDialog.js.map +1 -1
  38. package/components/dialog/DialogHeader.js +20 -19
  39. package/components/dialog/DialogHeader.js.map +1 -1
  40. package/components/dropdown/ButtonDropdown.d.ts +5 -0
  41. package/components/dropdown/ButtonDropdown.js +63 -61
  42. package/components/dropdown/ButtonDropdown.js.map +1 -1
  43. package/components/dropdown/DropdownToggleButton.d.ts +2 -0
  44. package/components/dropdown/DropdownToggleButton.js +39 -35
  45. package/components/dropdown/DropdownToggleButton.js.map +1 -1
  46. package/components/map/components/features/settings/builtinSettings/MapTypeSettings.js +103 -105
  47. package/components/map/components/features/settings/builtinSettings/MapTypeSettings.js.map +1 -1
  48. package/components/map/utils/eventHandling.js.map +1 -1
  49. package/components/map/utils/mapTypes.d.ts +7 -0
  50. package/components/map/utils/mapTypes.js.map +1 -1
  51. package/components/map/utils/rendering.js +5 -5
  52. package/components/numberControl/NumberControl.js.map +1 -1
  53. package/components/page/Page.d.ts +2 -0
  54. package/components/page/Page.js.map +1 -1
  55. package/components/rioglyph/Rioglyph.d.ts +8 -2
  56. package/components/rioglyph/Rioglyph.js.map +1 -1
  57. package/components/rioglyph/RioglyphIconType.d.ts +1 -1
  58. package/components/selects/BaseSelectDropdown.d.ts +8 -0
  59. package/components/selects/BaseSelectDropdown.js +76 -60
  60. package/components/selects/BaseSelectDropdown.js.map +1 -1
  61. package/components/selects/Multiselect.d.ts +5 -0
  62. package/components/selects/Multiselect.js +60 -58
  63. package/components/selects/Multiselect.js.map +1 -1
  64. package/components/selects/Select.d.ts +5 -0
  65. package/components/selects/Select.js +60 -58
  66. package/components/selects/Select.js.map +1 -1
  67. package/components/sidebars/Sidebar.js +40 -40
  68. package/components/sidebars/Sidebar.js.map +1 -1
  69. package/components/sidebars/SidebarCloseButton.d.ts +3 -1
  70. package/components/sidebars/SidebarCloseButton.js +19 -5
  71. package/components/sidebars/SidebarCloseButton.js.map +1 -1
  72. package/components/states/CustomState.d.ts +7 -1
  73. package/components/states/CustomState.js.map +1 -1
  74. package/components/states/StateButton.d.ts +11 -1
  75. package/components/states/StateButton.js +46 -10
  76. package/components/states/StateButton.js.map +1 -1
  77. package/components/statsWidget/StatsWidgetNumber.d.ts +16 -1
  78. package/components/statsWidget/StatsWidgetNumber.js +29 -12
  79. package/components/statsWidget/StatsWidgetNumber.js.map +1 -1
  80. package/components/tabbedPanel/TabbedPanel.d.ts +99 -0
  81. package/components/tabbedPanel/TabbedPanel.js +119 -0
  82. package/components/tabbedPanel/TabbedPanel.js.map +1 -0
  83. package/components/table/Table.types.d.ts +9 -1
  84. package/components/table/TableColumn.js +20 -19
  85. package/components/table/TableColumn.js.map +1 -1
  86. package/components/table/TableHeaderColumn.d.ts +4 -0
  87. package/components/table/TableHeaderColumn.js +50 -53
  88. package/components/table/TableHeaderColumn.js.map +1 -1
  89. package/components/table/TableToolbar.d.ts +4 -0
  90. package/components/table/TableToolbar.js.map +1 -1
  91. package/components/table/TableToolbarColumn.d.ts +3 -0
  92. package/components/table/TableToolbarColumn.js.map +1 -1
  93. package/components/table/render/header/resolveHeaderCellStyle.d.ts +87 -55
  94. package/components/timepicker/TimePicker.d.ts +6 -0
  95. package/components/timepicker/TimePicker.js +57 -56
  96. package/components/timepicker/TimePicker.js.map +1 -1
  97. package/hooks/useClickOutside.js +3 -3
  98. package/hooks/useClipboard.js.map +1 -1
  99. package/hooks/useScrollPosition.js.map +1 -1
  100. package/package.json +2 -4
  101. package/themes/Volkswagen/components/applicationHeader/VolkswagenApplicationHeader.js +23 -22
  102. package/themes/Volkswagen/components/applicationHeader/VolkswagenApplicationHeader.js.map +1 -1
  103. package/utils/analytics/getTrackingLabelFromNode.d.ts +2 -0
  104. package/utils/analytics/getTrackingLabelFromNode.js +24 -0
  105. package/utils/analytics/getTrackingLabelFromNode.js.map +1 -0
  106. package/utils/analytics/googleAnalyticsUtils.js +21 -28
  107. package/utils/analytics/googleAnalyticsUtils.js.map +1 -1
  108. package/utils/getNodeTextContent.d.ts +2 -0
  109. package/utils/getNodeTextContent.js +22 -0
  110. package/utils/getNodeTextContent.js.map +1 -0
  111. package/utils/init/initCSS.js +5 -5
  112. package/utils/init/initCSS.js.map +1 -1
  113. package/utils/init/initConfig.js +4 -7
  114. package/utils/init/initConfig.js.map +1 -1
  115. package/utils/init/initDocumentBootstrapping.js +14 -14
  116. package/utils/init/initDocumentBootstrapping.js.map +1 -1
  117. package/version.d.ts +1 -1
  118. package/version.js +2 -2
  119. package/version.js.map +1 -1
@@ -1,126 +1,127 @@
1
- import { jsxs as d, jsx as n, Fragment as ee } from "react/jsx-runtime";
1
+ import { jsxs as d, jsx as n, Fragment as se } from "react/jsx-runtime";
2
2
  import { useState as V, useRef as y, useEffect as P } from "react";
3
- import { IMaskInput as se, IMask as I } from "react-imask";
4
- import { noop as te } from "es-toolkit/compat";
5
- import { isNil as ne } from "es-toolkit/predicate";
6
- import O from "moment";
7
- import oe from "tiny-invariant";
8
- import re from "../selects/BaseSelectDropdown.js";
9
- import ae from "../../hooks/useClickOutside.js";
10
- import ie from "../../hooks/useMergeRefs.js";
3
+ import { IMaskInput as te, IMask as O } from "react-imask";
4
+ import { noop as ne } from "es-toolkit/compat";
5
+ import { isNil as oe } from "es-toolkit/predicate";
6
+ import I from "moment";
7
+ import re from "tiny-invariant";
8
+ import ae from "../selects/BaseSelectDropdown.js";
9
+ import ie from "../../hooks/useClickOutside.js";
10
+ import ce from "../../hooks/useMergeRefs.js";
11
11
  import T from "../../utils/classNames.js";
12
- const b = 15, ce = /^(?:\d|[01]\d|2[0-3]):[0-5]\d$/, C = (e) => e >= 10 ? `${e}` : `0${e}`, p = (e, t) => `${C(e)}:${C(t)}`, D = (e, t = b) => Math.floor(e.minutes() / t) * t, le = (e) => Number.isInteger(e) && e > 0 && e <= 60, me = (e) => le(e) ? e : b, de = (e) => {
12
+ const b = 15, le = /^(?:\d|[01]\d|2[0-3]):[0-5]\d$/, C = (e) => e >= 10 ? `${e}` : `0${e}`, p = (e, t) => `${C(e)}:${C(t)}`, D = (e, t = b) => Math.floor(e.minutes() / t) * t, me = (e) => Number.isInteger(e) && e > 0 && e <= 60, de = (e) => me(e) ? e : b, ue = (e) => {
13
13
  const t = [];
14
14
  for (let a = 0; a < 1440; a += e) {
15
15
  const f = Math.floor(a / 60), i = a % 60;
16
16
  t.push(p(f, i));
17
17
  }
18
18
  return t;
19
- }, ue = () => {
19
+ }, pe = () => {
20
20
  const e = /* @__PURE__ */ new Date(), t = e.getHours(), r = e.getMinutes();
21
21
  return p(t, r);
22
- }, S = (e) => ce.test(e), R = (e) => {
23
- if (!!ne(e))
22
+ }, S = (e) => le.test(e), R = (e) => {
23
+ if (!!oe(e))
24
24
  return !1;
25
25
  const r = e === "" || S(e);
26
- return r || oe(!1, 'Wrong time format. Please pass in value with the following format: "hh:mm".'), r;
27
- }, be = (e) => {
26
+ return r || re(!1, 'Wrong time format. Please pass in value with the following format: "hh:mm".'), r;
27
+ }, xe = (e) => {
28
28
  const {
29
29
  value: t,
30
- onChange: r = te,
30
+ onChange: r = ne,
31
31
  alwaysShowMask: a = !0,
32
32
  showIcon: f = !1,
33
33
  dropdown: i = !1,
34
- minuteOffset: $ = b,
35
- disabled: F = !1,
34
+ maskOverwrite: $ = "shift",
35
+ minuteOffset: F = b,
36
+ disabled: E = !1,
36
37
  errorMessage: h,
37
38
  warningMessage: g,
38
- messageWhiteSpace: E = "normal",
39
- className: H = "",
39
+ messageWhiteSpace: H = "normal",
40
+ className: A = "",
40
41
  inputProps: k = {},
41
- ...A
42
- } = e, W = R(t) ? t : ue(), [c, l] = V(W), [x, N] = V(!1), m = me($), u = F || !!k.disabled, j = y(null), w = y(!1), M = y(!1), B = ae(() => {
43
- i && N(!1);
44
- }), L = ie(j, B);
42
+ ...W
43
+ } = e, j = R(t) ? t : pe(), [c, l] = V(j), [x, w] = V(!1), m = de(F), u = E || !!k.disabled, B = y(null), N = y(!1), M = y(!1), L = ie(() => {
44
+ i && w(!1);
45
+ }), U = ce(B, L);
45
46
  P(() => {
46
47
  R(t) && l(t);
47
- }, [t]), P(() => (w.current = !0, () => {
48
- w.current = !1;
48
+ }, [t]), P(() => (N.current = !0, () => {
49
+ N.current = !1;
49
50
  }), []);
50
- const U = (s) => {
51
+ const z = (s) => {
51
52
  const o = s.target;
52
53
  (!o.value || o.value.startsWith("-")) && setTimeout(() => {
53
54
  o.setSelectionRange(0, 0);
54
- }, 0), k.onFocus?.(s), i && !u && N(!0);
55
- }, z = (s, o) => {
55
+ }, 0), k.onFocus?.(s), i && !u && w(!0);
56
+ }, _ = (s, o) => {
56
57
  if (M.current) {
57
58
  M.current = !1;
58
59
  return;
59
60
  }
60
- if (l(s), !!w.current) {
61
+ if (l(s), !!N.current) {
61
62
  if (o.masked.isComplete) {
62
63
  r(s);
63
64
  return;
64
65
  }
65
66
  o.unmaskedValue === "" && r("");
66
67
  }
67
- }, _ = S(c), q = () => {
68
- const s = O(`2020-01-01 ${c}`), o = D(s, m);
68
+ }, q = S(c), G = () => {
69
+ const s = I(`2020-01-01 ${c}`), o = D(s, m);
69
70
  s.minute(o).second(0), s.add(m, "minutes");
70
71
  const v = p(s.hours(), s.minutes());
71
72
  l(v);
72
- }, G = () => {
73
- const s = O(`2020-01-01 ${c}`), o = D(s, m);
73
+ }, J = () => {
74
+ const s = I(`2020-01-01 ${c}`), o = D(s, m);
74
75
  s.minute(o).second(0), s.subtract(m, "minutes");
75
76
  const v = p(s.hours(), s.minutes());
76
77
  l(v);
77
- }, { className: J, ...K } = k, Q = de(m).map((s) => ({
78
+ }, { className: K, ...Q } = k, X = ue(m).map((s) => ({
78
79
  id: s,
79
80
  label: s,
80
81
  selected: s === c
81
- })), X = (s) => {
82
- !s || u || (M.current = !0, l(s.id), r(s.id), N(!1));
83
- }, Y = h || g, Z = T("TimePicker", i && "dropdown", x && "open", H);
84
- return /* @__PURE__ */ d("div", { ...A, className: Z, ref: L, children: [
82
+ })), Y = (s) => {
83
+ !s || u || (M.current = !0, l(s.id), r(s.id), w(!1));
84
+ }, Z = h || g, ee = T("TimePicker", i && "dropdown", x && "open", A);
85
+ return /* @__PURE__ */ d("div", { ...W, className: ee, ref: U, children: [
85
86
  /* @__PURE__ */ d("div", { className: "input-group", children: [
86
87
  f && /* @__PURE__ */ n("span", { className: "input-group-addon", children: /* @__PURE__ */ n("span", { className: "rioglyph rioglyph-time-alt" }) }),
87
88
  /* @__PURE__ */ d("div", { className: "form-control-feedback-wrapper", children: [
88
89
  /* @__PURE__ */ n(
89
- se,
90
+ te,
90
91
  {
91
- ...K,
92
- className: T("TimePickerInput", "form-control", J),
92
+ ...Q,
93
+ className: T("TimePickerInput", "form-control", K),
93
94
  disabled: u,
94
95
  mask: "HH:MM",
95
96
  blocks: {
96
97
  HH: {
97
- mask: I.MaskedRange,
98
+ mask: O.MaskedRange,
98
99
  from: 0,
99
100
  to: 23,
100
101
  maxLength: 2
101
102
  },
102
103
  MM: {
103
- mask: I.MaskedRange,
104
+ mask: O.MaskedRange,
104
105
  from: 0,
105
106
  to: 59,
106
107
  maxLength: 2
107
108
  }
108
109
  },
109
110
  value: c,
110
- onAccept: z,
111
- onFocus: U,
111
+ onAccept: _,
112
+ onFocus: z,
112
113
  lazy: !a,
113
114
  placeholderChar: "-",
114
- overwrite: !0
115
+ overwrite: $
115
116
  }
116
117
  ),
117
- Y && /* @__PURE__ */ d(ee, { children: [
118
+ Z && /* @__PURE__ */ d(se, { children: [
118
119
  h && /* @__PURE__ */ n("span", { className: "form-control-feedback rioglyph rioglyph-error-sign" }),
119
120
  g && /* @__PURE__ */ n("span", { className: "form-control-feedback rioglyph rioglyph-warning-sign" }),
120
- /* @__PURE__ */ n("span", { className: `help-block white-space-${E}`, children: /* @__PURE__ */ n("span", { children: h || g }) })
121
+ /* @__PURE__ */ n("span", { className: `help-block white-space-${H}`, children: /* @__PURE__ */ n("span", { children: h || g }) })
121
122
  ] })
122
123
  ] }),
123
- _ && /* @__PURE__ */ d(
124
+ q && /* @__PURE__ */ d(
124
125
  "div",
125
126
  {
126
127
  className: T(
@@ -132,7 +133,7 @@ const b = 15, ce = /^(?:\d|[01]\d|2[0-3]):[0-5]\d$/, C = (e) => e >= 10 ? `${e}`
132
133
  "div",
133
134
  {
134
135
  className: "text-color-gray hover-text-color-dark display-grid place-items-center cursor-pointer",
135
- onClick: G,
136
+ onClick: J,
136
137
  children: /* @__PURE__ */ n("div", { className: "rioglyph rioglyph-chevron-left scale-90" })
137
138
  }
138
139
  ),
@@ -140,7 +141,7 @@ const b = 15, ce = /^(?:\d|[01]\d|2[0-3]):[0-5]\d$/, C = (e) => e >= 10 ? `${e}`
140
141
  "div",
141
142
  {
142
143
  className: "text-color-gray hover-text-color-dark margin-left-5 display-grid place-items-center cursor-pointer",
143
- onClick: q,
144
+ onClick: G,
144
145
  children: /* @__PURE__ */ n("div", { className: "rioglyph rioglyph-chevron-right scale-90" })
145
146
  }
146
147
  )
@@ -149,17 +150,17 @@ const b = 15, ce = /^(?:\d|[01]\d|2[0-3]):[0-5]\d$/, C = (e) => e >= 10 ? `${e}`
149
150
  )
150
151
  ] }),
151
152
  i && /* @__PURE__ */ n(
152
- re,
153
+ ae,
153
154
  {
154
155
  isOpen: x,
155
- options: Q,
156
- onSelect: X,
156
+ options: X,
157
+ onSelect: Y,
157
158
  dropdownClassName: "max-height-200 overflow-auto width-100pct"
158
159
  }
159
160
  )
160
161
  ] });
161
162
  };
162
163
  export {
163
- be as default
164
+ xe as default
164
165
  };
165
166
  //# sourceMappingURL=TimePicker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TimePicker.js","sources":["../../../src/components/timepicker/TimePicker.tsx"],"sourcesContent":["import type React from 'react';\nimport { useEffect, useRef, useState } from 'react';\nimport { IMask, IMaskInput } from 'react-imask';\nimport type { InputMask } from 'imask';\nimport { noop } from 'es-toolkit/compat';\nimport { isNil } from 'es-toolkit/predicate';\nimport moment, { type Moment } from 'moment';\nimport invariant from 'tiny-invariant';\n\nimport BaseSelectDropdown, { type SelectOption } from '../selects/BaseSelectDropdown';\nimport useClickOutside from '../../useClickOutside';\nimport useMergeRefs from '../../hooks/useMergeRefs';\nimport classNames from '../../utils/classNames';\n\nconst MINUTES_OFFSET = 15;\n\nconst mask = '00:00';\nconst fullRegexp = /^(?:\\d|[01]\\d|2[0-3]):[0-5]\\d$/;\n\nconst getPadded = (value: number) => (value >= 10 ? `${value}` : `0${value}`);\nconst formatTimeString = (hours: number, minutes: number) => `${getPadded(hours)}:${getPadded(minutes)}`;\n\nconst roundedUp = (time: Moment, offset = MINUTES_OFFSET) => Math.floor(time.minutes() / offset) * offset;\nconst isValidMinuteOffset = (offset: number) => Number.isInteger(offset) && offset > 0 && offset <= 60;\nconst getEffectiveMinuteOffset = (offset: number) => (isValidMinuteOffset(offset) ? offset : MINUTES_OFFSET);\nconst getDropdownTimeValues = (offset: number) => {\n const values: string[] = [];\n const minutesPerDay = 24 * 60;\n for (let totalMinutes = 0; totalMinutes < minutesPerDay; totalMinutes += offset) {\n const hours = Math.floor(totalMinutes / 60);\n const minutes = totalMinutes % 60;\n values.push(formatTimeString(hours, minutes));\n }\n return values;\n};\n\nconst getInitialTime = () => {\n const date = new Date();\n const hours = date.getHours();\n const minutes = date.getMinutes();\n return formatTimeString(hours, minutes);\n};\n\nconst isTimeValid = (value: string) => fullRegexp.test(value);\n\nconst isControlledAndValid = (value: string | undefined): value is string => {\n const hasExternalValue = !isNil(value);\n if (!hasExternalValue) {\n return false;\n }\n\n const isValid = value === '' || isTimeValid(value);\n if (!isValid) {\n invariant(false, 'Wrong time format. Please pass in value with the following format: \"hh:mm\".');\n }\n return isValid;\n};\n\nexport type TimePickerProps = {\n /**\n * Value of the time as string. Note, when value is given the component is treated as controlled.\n */\n value?: string;\n\n /**\n * Callback function when the value changes and is a valid time format.\n * It also emits an empty string when the input is cleared.\n *\n * If not it handles the state internally until the time is valid and filled.\n */\n onChange?: (value: string) => void;\n\n /**\n * Defines whether to always show the input mask placeholder.\n *\n * @default true\n */\n alwaysShowMask?: boolean;\n\n /**\n * Defines whether to show the input icon.\n *\n * @default false\n */\n showIcon?: boolean;\n\n /**\n * Defines whether to show a dropdown with pre-defined time values.\n *\n * @default false\n */\n dropdown?: boolean;\n\n /**\n * Defines the minute interval for time controls and dropdown values.\n * Invalid values fallback to 15.\n *\n * @default 15\n */\n minuteOffset?: number;\n\n /**\n * Defines whether the component is disabled.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Input error message.\n */\n errorMessage?: string | React.ReactNode;\n\n /**\n * Input warning message.\n */\n warningMessage?: string | React.ReactNode;\n\n /**\n * Feedback message width.\n *\n * @default 'normal'\n */\n messageWhiteSpace?: 'normal' | 'nowrap' | 'pre-line';\n\n /**\n * Additional properties to be set on the input element.\n */\n inputProps?: Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'>;\n\n /**\n * Additional classes to be set on the wrapper element.\n */\n className?: string;\n};\n\nconst TimePicker = (props: TimePickerProps) => {\n const {\n value,\n onChange = noop,\n alwaysShowMask = true,\n showIcon = false,\n dropdown = false,\n minuteOffset = MINUTES_OFFSET,\n disabled = false,\n errorMessage,\n warningMessage,\n messageWhiteSpace = 'normal',\n className = '',\n inputProps = {},\n ...remainingProps\n } = props;\n\n const initialTime = isControlledAndValid(value) ? value : getInitialTime();\n\n const [timeValue, setTimeValue] = useState(initialTime);\n\n const [isDropdownOpen, setIsDropdownOpen] = useState(false);\n\n const effectiveMinuteOffset = getEffectiveMinuteOffset(minuteOffset);\n\n const isInputDisabled = disabled || !!inputProps.disabled;\n const timePickerRef = useRef<HTMLDivElement>(null);\n const hasMountedRef = useRef(false);\n const suppressNextAcceptRef = useRef(false);\n\n const clickOutsideRef = useClickOutside(() => {\n if (dropdown) {\n setIsDropdownOpen(false);\n }\n });\n\n const mergedTimePickerRefs = useMergeRefs(timePickerRef, clickOutsideRef);\n\n // Update internal time value from outside when used as a controlled component\n useEffect(() => {\n if (isControlledAndValid(value)) {\n setTimeValue(value);\n }\n }, [value]);\n\n useEffect(() => {\n hasMountedRef.current = true;\n\n return () => {\n hasMountedRef.current = false;\n };\n }, []);\n\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n const input = event.target;\n // Check if value is empty or partially filled\n if (!input.value || input.value.startsWith('-')) {\n // Move cursor to the first empty position (usually 0)\n // Timeout needed to wait for IMask internal focus handling\n setTimeout(() => {\n input.setSelectionRange(0, 0);\n }, 0);\n }\n\n // If you want to preserve custom onFocus from props\n inputProps.onFocus?.(event);\n\n if (dropdown && !isInputDisabled) {\n setIsDropdownOpen(true);\n }\n };\n\n const handleAcceptTime = (val: string, maskRef: InputMask<{ [x: string]: unknown }>) => {\n if (suppressNextAcceptRef.current) {\n suppressNextAcceptRef.current = false;\n return;\n }\n\n setTimeValue(val);\n\n if (!hasMountedRef.current) {\n return;\n }\n\n if (maskRef.masked.isComplete) {\n onChange(val);\n return;\n }\n\n if (maskRef.unmaskedValue === '') {\n onChange('');\n }\n };\n\n const isValid = isTimeValid(timeValue);\n\n const handleIncrease = () => {\n const time = moment(`2020-01-01 ${timeValue}`);\n const rounded = roundedUp(time, effectiveMinuteOffset);\n time.minute(rounded).second(0);\n time.add(effectiveMinuteOffset, 'minutes');\n const updatedTimeValue = formatTimeString(time.hours(), time.minutes());\n\n setTimeValue(updatedTimeValue);\n };\n\n const handleDecrease = () => {\n const time = moment(`2020-01-01 ${timeValue}`);\n const rounded = roundedUp(time, effectiveMinuteOffset);\n time.minute(rounded).second(0);\n time.subtract(effectiveMinuteOffset, 'minutes');\n const updatedTimeValue = formatTimeString(time.hours(), time.minutes());\n\n setTimeValue(updatedTimeValue);\n };\n\n const { className: inputClassName, ...otherInputProps } = inputProps;\n\n const dropdownOptions: SelectOption[] = getDropdownTimeValues(effectiveMinuteOffset).map(option => ({\n id: option,\n label: option,\n selected: option === timeValue,\n }));\n\n const handleSelectDropdownValue = (selectedItem: SelectOption | undefined) => {\n if (!selectedItem || isInputDisabled) {\n return;\n }\n\n suppressNextAcceptRef.current = true;\n setTimeValue(selectedItem.id);\n onChange(selectedItem.id);\n setIsDropdownOpen(false);\n };\n\n const hasFeedback = errorMessage || warningMessage;\n\n const wrapperClassName = classNames('TimePicker', dropdown && 'dropdown', isDropdownOpen && 'open', className);\n\n return (\n <div {...remainingProps} className={wrapperClassName} ref={mergedTimePickerRefs}>\n <div className='input-group'>\n {showIcon && (\n <span className='input-group-addon'>\n <span className='rioglyph rioglyph-time-alt' />\n </span>\n )}\n <div className='form-control-feedback-wrapper'>\n <IMaskInput\n {...otherInputProps}\n className={classNames('TimePickerInput', 'form-control', inputClassName)}\n disabled={isInputDisabled}\n mask='HH:MM'\n blocks={{\n HH: {\n mask: IMask.MaskedRange,\n from: 0,\n to: 23,\n maxLength: 2,\n },\n MM: {\n mask: IMask.MaskedRange,\n from: 0,\n to: 59,\n maxLength: 2,\n },\n }}\n value={timeValue}\n onAccept={handleAcceptTime}\n onFocus={handleFocus}\n lazy={!alwaysShowMask}\n placeholderChar='-'\n overwrite\n />\n {hasFeedback && (\n <>\n {errorMessage && <span className='form-control-feedback rioglyph rioglyph-error-sign' />}\n {warningMessage && (\n <span className='form-control-feedback rioglyph rioglyph-warning-sign' />\n )}\n <span className={`help-block white-space-${messageWhiteSpace}`}>\n <span>{errorMessage || warningMessage}</span>\n </span>\n </>\n )}\n </div>\n {isValid && (\n <div\n className={classNames(\n 'TimePickerIncreaseButton input-group-addon',\n isInputDisabled && 'pointer-events-none bg-lightest'\n )}\n >\n <div\n className='text-color-gray hover-text-color-dark display-grid place-items-center cursor-pointer'\n onClick={handleDecrease}\n >\n <div className='rioglyph rioglyph-chevron-left scale-90' />\n </div>\n <div\n className='text-color-gray hover-text-color-dark margin-left-5 display-grid place-items-center cursor-pointer'\n onClick={handleIncrease}\n >\n <div className='rioglyph rioglyph-chevron-right scale-90' />\n </div>\n </div>\n )}\n </div>\n {dropdown && (\n <BaseSelectDropdown\n isOpen={isDropdownOpen}\n options={dropdownOptions}\n onSelect={handleSelectDropdownValue}\n dropdownClassName='max-height-200 overflow-auto width-100pct'\n />\n )}\n </div>\n );\n};\n\nexport default TimePicker;\n"],"names":["MINUTES_OFFSET","fullRegexp","getPadded","value","formatTimeString","hours","minutes","roundedUp","time","offset","isValidMinuteOffset","getEffectiveMinuteOffset","getDropdownTimeValues","values","totalMinutes","getInitialTime","date","isTimeValid","isControlledAndValid","isNil","isValid","invariant","TimePicker","props","onChange","noop","alwaysShowMask","showIcon","dropdown","minuteOffset","disabled","errorMessage","warningMessage","messageWhiteSpace","className","inputProps","remainingProps","initialTime","timeValue","setTimeValue","useState","isDropdownOpen","setIsDropdownOpen","effectiveMinuteOffset","isInputDisabled","timePickerRef","useRef","hasMountedRef","suppressNextAcceptRef","clickOutsideRef","useClickOutside","mergedTimePickerRefs","useMergeRefs","useEffect","handleFocus","event","input","handleAcceptTime","val","maskRef","handleIncrease","moment","rounded","updatedTimeValue","handleDecrease","inputClassName","otherInputProps","dropdownOptions","option","handleSelectDropdownValue","selectedItem","hasFeedback","wrapperClassName","classNames","jsxs","jsx","IMaskInput","IMask","Fragment","BaseSelectDropdown"],"mappings":"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"}
1
+ {"version":3,"file":"TimePicker.js","sources":["../../../src/components/timepicker/TimePicker.tsx"],"sourcesContent":["import type React from 'react';\nimport { useEffect, useRef, useState } from 'react';\nimport { IMask, IMaskInput } from 'react-imask';\nimport type { InputMask } from 'imask';\nimport { noop } from 'es-toolkit/compat';\nimport { isNil } from 'es-toolkit/predicate';\nimport moment, { type Moment } from 'moment';\nimport invariant from 'tiny-invariant';\n\nimport BaseSelectDropdown, { type SelectOption } from '../selects/BaseSelectDropdown';\nimport useClickOutside from '../../useClickOutside';\nimport useMergeRefs from '../../hooks/useMergeRefs';\nimport classNames from '../../utils/classNames';\n\nconst MINUTES_OFFSET = 15;\n\nconst mask = '00:00';\nconst fullRegexp = /^(?:\\d|[01]\\d|2[0-3]):[0-5]\\d$/;\n\nconst getPadded = (value: number) => (value >= 10 ? `${value}` : `0${value}`);\nconst formatTimeString = (hours: number, minutes: number) => `${getPadded(hours)}:${getPadded(minutes)}`;\n\nconst roundedUp = (time: Moment, offset = MINUTES_OFFSET) => Math.floor(time.minutes() / offset) * offset;\nconst isValidMinuteOffset = (offset: number) => Number.isInteger(offset) && offset > 0 && offset <= 60;\nconst getEffectiveMinuteOffset = (offset: number) => (isValidMinuteOffset(offset) ? offset : MINUTES_OFFSET);\nconst getDropdownTimeValues = (offset: number) => {\n const values: string[] = [];\n const minutesPerDay = 24 * 60;\n for (let totalMinutes = 0; totalMinutes < minutesPerDay; totalMinutes += offset) {\n const hours = Math.floor(totalMinutes / 60);\n const minutes = totalMinutes % 60;\n values.push(formatTimeString(hours, minutes));\n }\n return values;\n};\n\nconst getInitialTime = () => {\n const date = new Date();\n const hours = date.getHours();\n const minutes = date.getMinutes();\n return formatTimeString(hours, minutes);\n};\n\nconst isTimeValid = (value: string) => fullRegexp.test(value);\n\nconst isControlledAndValid = (value: string | undefined): value is string => {\n const hasExternalValue = !isNil(value);\n if (!hasExternalValue) {\n return false;\n }\n\n const isValid = value === '' || isTimeValid(value);\n if (!isValid) {\n invariant(false, 'Wrong time format. Please pass in value with the following format: \"hh:mm\".');\n }\n return isValid;\n};\n\nexport type TimePickerProps = {\n /**\n * Value of the time as string. Note, when value is given the component is treated as controlled.\n */\n value?: string;\n\n /**\n * Callback function when the value changes and is a valid time format.\n * It also emits an empty string when the input is cleared.\n *\n * If not it handles the state internally until the time is valid and filled.\n */\n onChange?: (value: string) => void;\n\n /**\n * Defines whether to always show the input mask placeholder.\n *\n * @default true\n */\n alwaysShowMask?: boolean;\n\n /**\n * Defines whether to show the input icon.\n *\n * @default false\n */\n showIcon?: boolean;\n\n /**\n * Defines whether to show a dropdown with pre-defined time values.\n *\n * @default false\n */\n dropdown?: boolean;\n\n /**\n * Configures IMask overwrite behavior for manual input editing.\n *\n * @default 'shift'\n */\n maskOverwrite?: boolean | 'shift';\n\n /**\n * Defines the minute interval for time controls and dropdown values.\n * Invalid values fallback to 15.\n *\n * @default 15\n */\n minuteOffset?: number;\n\n /**\n * Defines whether the component is disabled.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Input error message.\n */\n errorMessage?: string | React.ReactNode;\n\n /**\n * Input warning message.\n */\n warningMessage?: string | React.ReactNode;\n\n /**\n * Feedback message width.\n *\n * @default 'normal'\n */\n messageWhiteSpace?: 'normal' | 'nowrap' | 'pre-line';\n\n /**\n * Additional properties to be set on the input element.\n */\n inputProps?: Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'>;\n\n /**\n * Additional classes to be set on the wrapper element.\n */\n className?: string;\n};\n\nconst TimePicker = (props: TimePickerProps) => {\n const {\n value,\n onChange = noop,\n alwaysShowMask = true,\n showIcon = false,\n dropdown = false,\n maskOverwrite = 'shift',\n minuteOffset = MINUTES_OFFSET,\n disabled = false,\n errorMessage,\n warningMessage,\n messageWhiteSpace = 'normal',\n className = '',\n inputProps = {},\n ...remainingProps\n } = props;\n\n const initialTime = isControlledAndValid(value) ? value : getInitialTime();\n\n const [timeValue, setTimeValue] = useState(initialTime);\n\n const [isDropdownOpen, setIsDropdownOpen] = useState(false);\n\n const effectiveMinuteOffset = getEffectiveMinuteOffset(minuteOffset);\n\n const isInputDisabled = disabled || !!inputProps.disabled;\n const timePickerRef = useRef<HTMLDivElement>(null);\n const hasMountedRef = useRef(false);\n const suppressNextAcceptRef = useRef(false);\n\n const clickOutsideRef = useClickOutside(() => {\n if (dropdown) {\n setIsDropdownOpen(false);\n }\n });\n\n const mergedTimePickerRefs = useMergeRefs(timePickerRef, clickOutsideRef);\n\n // Update internal time value from outside when used as a controlled component\n useEffect(() => {\n if (isControlledAndValid(value)) {\n setTimeValue(value);\n }\n }, [value]);\n\n useEffect(() => {\n hasMountedRef.current = true;\n\n return () => {\n hasMountedRef.current = false;\n };\n }, []);\n\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n const input = event.target;\n // Check if value is empty or partially filled\n if (!input.value || input.value.startsWith('-')) {\n // Move cursor to the first empty position (usually 0)\n // Timeout needed to wait for IMask internal focus handling\n setTimeout(() => {\n input.setSelectionRange(0, 0);\n }, 0);\n }\n\n // If you want to preserve custom onFocus from props\n inputProps.onFocus?.(event);\n\n if (dropdown && !isInputDisabled) {\n setIsDropdownOpen(true);\n }\n };\n\n const handleAcceptTime = (val: string, maskRef: InputMask<{ [x: string]: unknown }>) => {\n if (suppressNextAcceptRef.current) {\n suppressNextAcceptRef.current = false;\n return;\n }\n\n setTimeValue(val);\n\n if (!hasMountedRef.current) {\n return;\n }\n\n if (maskRef.masked.isComplete) {\n onChange(val);\n return;\n }\n\n if (maskRef.unmaskedValue === '') {\n onChange('');\n }\n };\n\n const isValid = isTimeValid(timeValue);\n\n const handleIncrease = () => {\n const time = moment(`2020-01-01 ${timeValue}`);\n const rounded = roundedUp(time, effectiveMinuteOffset);\n time.minute(rounded).second(0);\n time.add(effectiveMinuteOffset, 'minutes');\n const updatedTimeValue = formatTimeString(time.hours(), time.minutes());\n\n setTimeValue(updatedTimeValue);\n };\n\n const handleDecrease = () => {\n const time = moment(`2020-01-01 ${timeValue}`);\n const rounded = roundedUp(time, effectiveMinuteOffset);\n time.minute(rounded).second(0);\n time.subtract(effectiveMinuteOffset, 'minutes');\n const updatedTimeValue = formatTimeString(time.hours(), time.minutes());\n\n setTimeValue(updatedTimeValue);\n };\n\n const { className: inputClassName, ...otherInputProps } = inputProps;\n\n const dropdownOptions: SelectOption[] = getDropdownTimeValues(effectiveMinuteOffset).map(option => ({\n id: option,\n label: option,\n selected: option === timeValue,\n }));\n\n const handleSelectDropdownValue = (selectedItem: SelectOption | undefined) => {\n if (!selectedItem || isInputDisabled) {\n return;\n }\n\n suppressNextAcceptRef.current = true;\n setTimeValue(selectedItem.id);\n onChange(selectedItem.id);\n setIsDropdownOpen(false);\n };\n\n const hasFeedback = errorMessage || warningMessage;\n\n const wrapperClassName = classNames('TimePicker', dropdown && 'dropdown', isDropdownOpen && 'open', className);\n\n return (\n <div {...remainingProps} className={wrapperClassName} ref={mergedTimePickerRefs}>\n <div className='input-group'>\n {showIcon && (\n <span className='input-group-addon'>\n <span className='rioglyph rioglyph-time-alt' />\n </span>\n )}\n <div className='form-control-feedback-wrapper'>\n <IMaskInput\n {...otherInputProps}\n className={classNames('TimePickerInput', 'form-control', inputClassName)}\n disabled={isInputDisabled}\n mask='HH:MM'\n blocks={{\n HH: {\n mask: IMask.MaskedRange,\n from: 0,\n to: 23,\n maxLength: 2,\n },\n MM: {\n mask: IMask.MaskedRange,\n from: 0,\n to: 59,\n maxLength: 2,\n },\n }}\n value={timeValue}\n onAccept={handleAcceptTime}\n onFocus={handleFocus}\n lazy={!alwaysShowMask}\n placeholderChar='-'\n overwrite={maskOverwrite}\n />\n {hasFeedback && (\n <>\n {errorMessage && <span className='form-control-feedback rioglyph rioglyph-error-sign' />}\n {warningMessage && (\n <span className='form-control-feedback rioglyph rioglyph-warning-sign' />\n )}\n <span className={`help-block white-space-${messageWhiteSpace}`}>\n <span>{errorMessage || warningMessage}</span>\n </span>\n </>\n )}\n </div>\n {isValid && (\n <div\n className={classNames(\n 'TimePickerIncreaseButton input-group-addon',\n isInputDisabled && 'pointer-events-none bg-lightest'\n )}\n >\n <div\n className='text-color-gray hover-text-color-dark display-grid place-items-center cursor-pointer'\n onClick={handleDecrease}\n >\n <div className='rioglyph rioglyph-chevron-left scale-90' />\n </div>\n <div\n className='text-color-gray hover-text-color-dark margin-left-5 display-grid place-items-center cursor-pointer'\n onClick={handleIncrease}\n >\n <div className='rioglyph rioglyph-chevron-right scale-90' />\n </div>\n </div>\n )}\n </div>\n {dropdown && (\n <BaseSelectDropdown\n isOpen={isDropdownOpen}\n options={dropdownOptions}\n onSelect={handleSelectDropdownValue}\n dropdownClassName='max-height-200 overflow-auto width-100pct'\n />\n )}\n </div>\n );\n};\n\nexport default TimePicker;\n"],"names":["MINUTES_OFFSET","fullRegexp","getPadded","value","formatTimeString","hours","minutes","roundedUp","time","offset","isValidMinuteOffset","getEffectiveMinuteOffset","getDropdownTimeValues","values","totalMinutes","getInitialTime","date","isTimeValid","isControlledAndValid","isNil","isValid","invariant","TimePicker","props","onChange","noop","alwaysShowMask","showIcon","dropdown","maskOverwrite","minuteOffset","disabled","errorMessage","warningMessage","messageWhiteSpace","className","inputProps","remainingProps","initialTime","timeValue","setTimeValue","useState","isDropdownOpen","setIsDropdownOpen","effectiveMinuteOffset","isInputDisabled","timePickerRef","useRef","hasMountedRef","suppressNextAcceptRef","clickOutsideRef","useClickOutside","mergedTimePickerRefs","useMergeRefs","useEffect","handleFocus","event","input","handleAcceptTime","val","maskRef","handleIncrease","moment","rounded","updatedTimeValue","handleDecrease","inputClassName","otherInputProps","dropdownOptions","option","handleSelectDropdownValue","selectedItem","hasFeedback","wrapperClassName","classNames","jsxs","jsx","IMaskInput","IMask","Fragment","BaseSelectDropdown"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- import { useRef as i, useEffect as E } from "react";
1
+ import { useEffect as i, useRef as E } from "react";
2
2
  const c = ["mousedown", "touchstart"], f = (t, u = c, n = !0) => {
3
- const r = i(null);
3
+ const r = E(null);
4
4
  return d(r, t, u, n), r;
5
5
  }, d = (t, u, n = c, r = !0) => {
6
- E(() => {
6
+ i(() => {
7
7
  if (!r)
8
8
  return;
9
9
  const o = t && "current" in t ? t.current : t, s = (e) => {
@@ -1 +1 @@
1
- {"version":3,"file":"useClipboard.js","sources":["../../src/hooks/useClipboard.ts"],"sourcesContent":["// Inspired from https://github.com/mantinedev/mantine/blob/master/src/mantine-hooks/src/use-clipboard/use-clipboard.ts\n\nimport { useState } from 'react';\nimport { isNil } from 'es-toolkit/compat';\n\n/**\n * Custom hook to interact with the clipboard.\n *\n * @param options - Options object for configuring the hook behavior.\n * @returns An object containing functions and state related to clipboard operations.\n */\nconst useClipboard = (options?: { timeout: number }) => {\n const { timeout = 2000 } = options ?? {};\n\n const [error, setError] = useState<Error | null>(null);\n const [copied, setCopied] = useState(false);\n const [copyTimeout, setCopyTimeout] = useState<NodeJS.Timeout | null>(null);\n\n // Function to handle copy result and set copied status\n const handleCopyResult = (value: boolean) => {\n if (copyTimeout) {\n clearTimeout(copyTimeout);\n }\n setCopyTimeout(setTimeout(() => setCopied(false), timeout));\n setCopied(value);\n };\n\n // Function to copy text to clipboard\n const copy = (valueToCopy: string) => {\n if (!isNil(navigator.clipboard)) {\n navigator.clipboard\n .writeText(valueToCopy)\n .then(() => handleCopyResult(true))\n .catch(writeError => setError(writeError));\n } else {\n setError(new Error('useClipboard: navigator.clipboard is not supported'));\n }\n };\n\n // Function to reset copied status and clear errors\n const reset = () => {\n setCopied(false);\n setError(null);\n if (copyTimeout) {\n clearTimeout(copyTimeout);\n }\n };\n\n return { copy, reset, error, copied };\n};\n\nexport default useClipboard;\n"],"names":["useClipboard","options","timeout","error","setError","useState","copied","setCopied","copyTimeout","setCopyTimeout","handleCopyResult","value","valueToCopy","isNil","writeError"],"mappings":";;AAWA,MAAMA,IAAe,CAACC,MAAkC;AACpD,QAAM,EAAE,SAAAC,IAAU,IAAA,IAASD,KAAW,CAAA,GAEhC,CAACE,GAAOC,CAAQ,IAAIC,EAAuB,IAAI,GAC/C,CAACC,GAAQC,CAAS,IAAIF,EAAS,EAAK,GACpC,CAACG,GAAaC,CAAc,IAAIJ,EAAgC,IAAI,GAGpEK,IAAmB,CAACC,MAAmB;AACzC,IAAIH,KACA,aAAaA,CAAW,GAE5BC,EAAe,WAAW,MAAMF,EAAU,EAAK,GAAGL,CAAO,CAAC,GAC1DK,EAAUI,CAAK;AAAA,EACnB;AAuBA,SAAO,EAAE,MApBI,CAACC,MAAwB;AAClC,IAAKC,EAAM,UAAU,SAAS,IAM1BT,EAAS,IAAI,MAAM,oDAAoD,CAAC,IALxE,UAAU,UACL,UAAUQ,CAAW,EACrB,KAAK,MAAMF,EAAiB,EAAI,CAAC,EACjC,MAAM,CAAAI,MAAcV,EAASU,CAAU,CAAC;AAAA,EAIrD,GAWe,OARD,MAAM;AAChB,IAAAP,EAAU,EAAK,GACfH,EAAS,IAAI,GACTI,KACA,aAAaA,CAAW;AAAA,EAEhC,GAEsB,OAAAL,GAAO,QAAAG,EAAA;AACjC;"}
1
+ {"version":3,"file":"useClipboard.js","sources":["../../src/hooks/useClipboard.ts"],"sourcesContent":["// Inspired from https://github.com/mantinedev/mantine/blob/master/src/mantine-hooks/src/use-clipboard/use-clipboard.ts\n\nimport { useState } from 'react';\nimport { isNil } from 'es-toolkit/compat';\n\n/**\n * Custom hook to interact with the clipboard.\n *\n * @param options - Options object for configuring the hook behavior.\n * @returns An object containing functions and state related to clipboard operations.\n */\nconst useClipboard = (options?: { timeout: number }) => {\n const { timeout = 2000 } = options ?? {};\n\n const [error, setError] = useState<Error | null>(null);\n const [copied, setCopied] = useState(false);\n const [copyTimeout, setCopyTimeout] = useState<number | null>(null);\n\n // Function to handle copy result and set copied status\n const handleCopyResult = (value: boolean) => {\n if (copyTimeout) {\n clearTimeout(copyTimeout);\n }\n setCopyTimeout(setTimeout(() => setCopied(false), timeout));\n setCopied(value);\n };\n\n // Function to copy text to clipboard\n const copy = (valueToCopy: string) => {\n if (!isNil(navigator.clipboard)) {\n navigator.clipboard\n .writeText(valueToCopy)\n .then(() => handleCopyResult(true))\n .catch(writeError => setError(writeError));\n } else {\n setError(new Error('useClipboard: navigator.clipboard is not supported'));\n }\n };\n\n // Function to reset copied status and clear errors\n const reset = () => {\n setCopied(false);\n setError(null);\n if (copyTimeout) {\n clearTimeout(copyTimeout);\n }\n };\n\n return { copy, reset, error, copied };\n};\n\nexport default useClipboard;\n"],"names":["useClipboard","options","timeout","error","setError","useState","copied","setCopied","copyTimeout","setCopyTimeout","handleCopyResult","value","valueToCopy","isNil","writeError"],"mappings":";;AAWA,MAAMA,IAAe,CAACC,MAAkC;AACpD,QAAM,EAAE,SAAAC,IAAU,IAAA,IAASD,KAAW,CAAA,GAEhC,CAACE,GAAOC,CAAQ,IAAIC,EAAuB,IAAI,GAC/C,CAACC,GAAQC,CAAS,IAAIF,EAAS,EAAK,GACpC,CAACG,GAAaC,CAAc,IAAIJ,EAAwB,IAAI,GAG5DK,IAAmB,CAACC,MAAmB;AACzC,IAAIH,KACA,aAAaA,CAAW,GAE5BC,EAAe,WAAW,MAAMF,EAAU,EAAK,GAAGL,CAAO,CAAC,GAC1DK,EAAUI,CAAK;AAAA,EACnB;AAuBA,SAAO,EAAE,MApBI,CAACC,MAAwB;AAClC,IAAKC,EAAM,UAAU,SAAS,IAM1BT,EAAS,IAAI,MAAM,oDAAoD,CAAC,IALxE,UAAU,UACL,UAAUQ,CAAW,EACrB,KAAK,MAAMF,EAAiB,EAAI,CAAC,EACjC,MAAM,CAAAI,MAAcV,EAASU,CAAU,CAAC;AAAA,EAIrD,GAWe,OARD,MAAM;AAChB,IAAAP,EAAU,EAAK,GACfH,EAAS,IAAI,GACTI,KACA,aAAaA,CAAW;AAAA,EAEhC,GAEsB,OAAAL,GAAO,QAAAG,EAAA;AACjC;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useScrollPosition.js","sources":["../../src/hooks/useScrollPosition.ts"],"sourcesContent":["import { useState, useEffect, type RefObject } from 'react';\n\nexport type TargetType =\n | Window\n | Document\n | HTMLBodyElement\n | HTMLElement\n | Element\n | React.ReactElement\n | RefObject<HTMLElement>;\n\nconst getModuleContent = () => document.querySelector('.module-content > .scrollbar-view');\n\n// \"target\" can be \"window\", \"document.body\", a \"ref\" or undefined\n// where in later case the module-content is taken as default\n\n/**\n * A custom hook that tracks the scroll position of a target element.\n *\n * @param target The target element for scroll position tracking.\n * @returns The current scroll position of the target element.\n */\nconst useScrollPosition = (target?: TargetType): number => {\n const [targetElement, setTargetElement] = useState<TargetType | null>(null);\n const [scrollPosition, setScrollPosition] = useState(0);\n\n useEffect(() => {\n let checkForModuleContent: NodeJS.Timeout | null = null;\n\n // In case the target is undefined it might be that the module-content is\n // not rendered yet, hence check periodically for the existence in the DOM\n if (!target) {\n checkForModuleContent = setInterval(() => {\n const element = getModuleContent();\n if (element) {\n setTargetElement(element);\n }\n }, 300);\n } else if (target && checkForModuleContent) {\n clearInterval(checkForModuleContent);\n }\n\n // In case the target is a \"ref\" - set the targetElement when current is defined\n else if (target instanceof Object && 'current' in target && target.current) {\n setTargetElement(target.current);\n }\n\n // In case it's \"window\" or \"document.body\"\n else {\n setTargetElement(target);\n }\n\n return () => {\n if (checkForModuleContent) {\n clearInterval(checkForModuleContent);\n }\n };\n }, [target]);\n\n const handleScroll = () => {\n requestAnimationFrame(() => {\n if (targetElement === window) {\n setScrollPosition(window.scrollY);\n } else {\n setScrollPosition((targetElement as HTMLElement).scrollTop);\n }\n });\n };\n\n useEffect(() => {\n if (targetElement instanceof EventTarget) {\n targetElement.addEventListener('scroll', handleScroll);\n }\n\n return () => {\n if (targetElement instanceof EventTarget) {\n targetElement.removeEventListener('scroll', handleScroll);\n }\n };\n }, [targetElement]);\n\n return scrollPosition;\n};\n\nexport default useScrollPosition;\n"],"names":["getModuleContent","useScrollPosition","target","targetElement","setTargetElement","useState","scrollPosition","setScrollPosition","useEffect","checkForModuleContent","element","handleScroll"],"mappings":";AAWA,MAAMA,IAAmB,MAAM,SAAS,cAAc,mCAAmC,GAWnFC,IAAoB,CAACC,MAAgC;AACvD,QAAM,CAACC,GAAeC,CAAgB,IAAIC,EAA4B,IAAI,GACpE,CAACC,GAAgBC,CAAiB,IAAIF,EAAS,CAAC;AAEtD,EAAAG,EAAU,MAAM;AACZ,QAAIC,IAA+C;AAInD,WAAKP,IAOMA,KAAUO,IACjB,cAAcA,CAAqB,IAI9BP,aAAkB,UAAU,aAAaA,KAAUA,EAAO,UAC/DE,EAAiBF,EAAO,OAAO,IAK/BE,EAAiBF,CAAM,IAjBvBO,IAAwB,YAAY,MAAM;AACtC,YAAMC,IAAUV,EAAA;AAChB,MAAIU,KACAN,EAAiBM,CAAO;AAAA,IAEhC,GAAG,GAAG,GAeH,MAAM;AACT,MAAID,KACA,cAAcA,CAAqB;AAAA,IAE3C;AAAA,EACJ,GAAG,CAACP,CAAM,CAAC;AAEX,QAAMS,IAAe,MAAM;AACvB,0BAAsB,MAAM;AACxB,MACIJ,EADAJ,MAAkB,SACA,OAAO,UAENA,EAA8B,SAFjB;AAAA,IAIxC,CAAC;AAAA,EACL;AAEA,SAAAK,EAAU,OACFL,aAAyB,eACzBA,EAAc,iBAAiB,UAAUQ,CAAY,GAGlD,MAAM;AACT,IAAIR,aAAyB,eACzBA,EAAc,oBAAoB,UAAUQ,CAAY;AAAA,EAEhE,IACD,CAACR,CAAa,CAAC,GAEXG;AACX;"}
1
+ {"version":3,"file":"useScrollPosition.js","sources":["../../src/hooks/useScrollPosition.ts"],"sourcesContent":["import { useState, useEffect, type RefObject } from 'react';\n\nexport type TargetType =\n | Window\n | Document\n | HTMLBodyElement\n | HTMLElement\n | Element\n | React.ReactElement\n | RefObject<HTMLElement>;\n\nconst getModuleContent = () => document.querySelector('.module-content > .scrollbar-view');\n\n// \"target\" can be \"window\", \"document.body\", a \"ref\" or undefined\n// where in later case the module-content is taken as default\n\n/**\n * A custom hook that tracks the scroll position of a target element.\n *\n * @param target The target element for scroll position tracking.\n * @returns The current scroll position of the target element.\n */\nconst useScrollPosition = (target?: TargetType): number => {\n const [targetElement, setTargetElement] = useState<TargetType | null>(null);\n const [scrollPosition, setScrollPosition] = useState(0);\n\n useEffect(() => {\n let checkForModuleContent: number | null = null;\n\n // In case the target is undefined it might be that the module-content is\n // not rendered yet, hence check periodically for the existence in the DOM\n if (!target) {\n checkForModuleContent = setInterval(() => {\n const element = getModuleContent();\n if (element) {\n setTargetElement(element);\n }\n }, 300);\n } else if (target && checkForModuleContent) {\n clearInterval(checkForModuleContent);\n }\n\n // In case the target is a \"ref\" - set the targetElement when current is defined\n else if (target instanceof Object && 'current' in target && target.current) {\n setTargetElement(target.current);\n }\n\n // In case it's \"window\" or \"document.body\"\n else {\n setTargetElement(target);\n }\n\n return () => {\n if (checkForModuleContent) {\n clearInterval(checkForModuleContent);\n }\n };\n }, [target]);\n\n const handleScroll = () => {\n requestAnimationFrame(() => {\n if (targetElement === window) {\n setScrollPosition(window.scrollY);\n } else {\n setScrollPosition((targetElement as HTMLElement).scrollTop);\n }\n });\n };\n\n useEffect(() => {\n if (targetElement instanceof EventTarget) {\n targetElement.addEventListener('scroll', handleScroll);\n }\n\n return () => {\n if (targetElement instanceof EventTarget) {\n targetElement.removeEventListener('scroll', handleScroll);\n }\n };\n }, [targetElement]);\n\n return scrollPosition;\n};\n\nexport default useScrollPosition;\n"],"names":["getModuleContent","useScrollPosition","target","targetElement","setTargetElement","useState","scrollPosition","setScrollPosition","useEffect","checkForModuleContent","element","handleScroll"],"mappings":";AAWA,MAAMA,IAAmB,MAAM,SAAS,cAAc,mCAAmC,GAWnFC,IAAoB,CAACC,MAAgC;AACvD,QAAM,CAACC,GAAeC,CAAgB,IAAIC,EAA4B,IAAI,GACpE,CAACC,GAAgBC,CAAiB,IAAIF,EAAS,CAAC;AAEtD,EAAAG,EAAU,MAAM;AACZ,QAAIC,IAAuC;AAI3C,WAAKP,IAOMA,KAAUO,IACjB,cAAcA,CAAqB,IAI9BP,aAAkB,UAAU,aAAaA,KAAUA,EAAO,UAC/DE,EAAiBF,EAAO,OAAO,IAK/BE,EAAiBF,CAAM,IAjBvBO,IAAwB,YAAY,MAAM;AACtC,YAAMC,IAAUV,EAAA;AAChB,MAAIU,KACAN,EAAiBM,CAAO;AAAA,IAEhC,GAAG,GAAG,GAeH,MAAM;AACT,MAAID,KACA,cAAcA,CAAqB;AAAA,IAE3C;AAAA,EACJ,GAAG,CAACP,CAAM,CAAC;AAEX,QAAMS,IAAe,MAAM;AACvB,0BAAsB,MAAM;AACxB,MACIJ,EADAJ,MAAkB,SACA,OAAO,UAENA,EAA8B,SAFjB;AAAA,IAIxC,CAAC;AAAA,EACL;AAEA,SAAAK,EAAU,OACFL,aAAyB,eACzBA,EAAc,iBAAiB,UAAUQ,CAAY,GAGlD,MAAM;AACT,IAAIR,aAAyB,eACzBA,EAAc,oBAAoB,UAAUQ,CAAY;AAAA,EAEhE,IACD,CAACR,CAAa,CAAC,GAEXG;AACX;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rio-cloud/rio-uikit",
3
- "version": "2.5.0-beta.1",
3
+ "version": "2.5.0",
4
4
  "description": "The RIO UIKIT component library",
5
5
  "repository": {
6
6
  "type": "git",
@@ -99,21 +99,19 @@
99
99
  "@dnd-kit/utilities": "3.2.2",
100
100
  "@formkit/auto-animate": "0.9.0",
101
101
  "@popperjs/core": "2.11.8",
102
+ "@rio-cloud/react-datetime": "^3.1.1",
102
103
  "@tanstack/react-virtual": "3.13.24",
103
104
  "date-fns": "4.1.0",
104
105
  "driver.js": "1.4.0",
105
106
  "es-toolkit": "1.45.1",
106
- "events": "3.3.0",
107
107
  "iframe-resizer-react": "1.1.0",
108
108
  "moment": "2.30.1",
109
109
  "motion": "12.38.0",
110
110
  "natural-orderby": "5.0.0",
111
- "process": "0.11.10",
112
111
  "prop-types": "15.8.1",
113
112
  "react-bootstrap": "1.6.4",
114
113
  "react-content-loader": "7.1.2",
115
114
  "react-custom-scrollbars-4": "4.5.1",
116
- "react-datetime": "github:rio-cloud/react-datetime#v3.1.1-1-merged",
117
115
  "react-day-picker": "9.14.0",
118
116
  "react-dropzone": "14.3.8",
119
117
  "react-imask": "7.6.1",
@@ -1,33 +1,34 @@
1
- import { jsx as a, jsxs as p } from "react/jsx-runtime";
2
- import { forwardRef as d } from "react";
3
- import { isEmpty as i } from "es-toolkit/compat";
4
- import u from "../../../../utils/classNames.js";
5
- import N from "../../../../components/applicationHeader/ApplicationActionBar.js";
6
- const H = d(
7
- (r, n) => {
1
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
2
+ import { forwardRef as c } from "react";
3
+ import { isEmpty as d } from "es-toolkit/compat";
4
+ import N from "../../../../utils/classNames.js";
5
+ import h from "../../../../components/applicationHeader/ApplicationActionBar.js";
6
+ const H = c(
7
+ (t, r) => {
8
8
  const {
9
- homeRoute: t = "",
10
- appNavigator: v,
11
- appNavigatorClassName: f,
9
+ homeRoute: n = "",
10
+ appNavigator: u,
11
+ appNavigatorClassName: v,
12
12
  appMenuItems: g,
13
- navItems: e = [],
13
+ navItems: i = [],
14
14
  actionBarItems: l = [],
15
- onMount: h = () => {
15
+ onMount: f = () => {
16
16
  },
17
- onUnmount: k = () => {
17
+ onUnmount: y = () => {
18
18
  },
19
- className: o = "",
20
- ...m
21
- } = r, c = u(
19
+ className: s = "",
20
+ ...p
21
+ } = t, m = N(
22
22
  "ApplicationHeader VolkswagenApplicationHeader",
23
23
  "user-select-none",
24
- o && o
24
+ s && s
25
25
  );
26
- return /* @__PURE__ */ a("nav", { ...m, className: c, ref: n, children: /* @__PURE__ */ p("div", { className: "width-100pct", children: [
27
- /* @__PURE__ */ a("div", { className: "brand", children: /* @__PURE__ */ a("div", { className: "logo", children: t }) }),
28
- i(e) && /* @__PURE__ */ a("ul", { className: "SubmoduleNavigation nav" }),
29
- !i(e) && /* @__PURE__ */ a("ul", { className: "SubmoduleNavigation nav", children: e.map((s) => /* @__PURE__ */ a("li", { className: "submodule", "data-nav-item-key": s.key, children: s.route }, s.key)) }),
30
- /* @__PURE__ */ a(N, { items: l })
26
+ return /* @__PURE__ */ a("nav", { ...p, className: m, ref: r, children: /* @__PURE__ */ o("div", { className: "width-100pct", children: [
27
+ /* @__PURE__ */ o("div", { className: "position-relative padding-y-25", children: [
28
+ /* @__PURE__ */ a("div", { className: "brand", children: /* @__PURE__ */ a("div", { className: "logo", style: { height: "40px", width: "400px" }, children: n }) }),
29
+ /* @__PURE__ */ a("div", { className: "position-absolute top-50pct right-10 z-index-1 translate-y-50pct", children: /* @__PURE__ */ a(h, { items: l }) })
30
+ ] }),
31
+ /* @__PURE__ */ a("ul", { className: "SubmoduleNavigation nav", children: !d(i) && i.map((e) => /* @__PURE__ */ a("li", { className: "submodule", "data-nav-item-key": e.key, children: e.route }, e.key)) })
31
32
  ] }) });
32
33
  }
33
34
  );
@@ -1 +1 @@
1
- {"version":3,"file":"VolkswagenApplicationHeader.js","sources":["../../../../../src/themes/Volkswagen/components/applicationHeader/VolkswagenApplicationHeader.tsx"],"sourcesContent":["import React, { forwardRef, type ForwardedRef } from 'react';\nimport { isEmpty } from 'es-toolkit/compat';\n\nimport classNames from '../../../../utils/classNames';\nimport ApplicationActionBar from '../../../../components/applicationHeader/ApplicationActionBar';\nimport type { ApplicationHeaderProps } from '../../../../ApplicationHeader';\n\nexport type ModuleProps = {\n key: string;\n route: React.ReactNode;\n};\n\nexport type VolkswagenApplicationHeaderProps = ApplicationHeaderProps & {\n homeRoute?: React.ReactNode;\n appMenuItems?: ModuleProps[];\n appNavigator?: React.ReactNode;\n appNavigatorClassName?: string;\n navItems?: ModuleProps[];\n actionBarItems?: React.ReactNode[];\n onMount?: VoidFunction;\n onUnmount?: VoidFunction;\n className?: string;\n};\n\nexport const VolkswagenApplicationHeader = forwardRef(\n (props: VolkswagenApplicationHeaderProps, ref: ForwardedRef<HTMLElement>) => {\n const {\n homeRoute = '',\n appNavigator,\n appNavigatorClassName,\n appMenuItems,\n navItems = [],\n actionBarItems = [],\n onMount = () => {},\n onUnmount = () => {},\n className = '',\n ...remainingProps\n } = props;\n\n const wrapperClassNames = classNames(\n 'ApplicationHeader VolkswagenApplicationHeader',\n 'user-select-none',\n className && className\n );\n\n return (\n <nav {...remainingProps} className={wrapperClassNames} ref={ref}>\n <div className='width-100pct'>\n <div className='brand'>\n <div className='logo'>{homeRoute}</div>\n </div>\n {isEmpty(navItems) && <ul className='SubmoduleNavigation nav' />}\n {!isEmpty(navItems) && (\n <ul className='SubmoduleNavigation nav'>\n {navItems.map(navItem => (\n <li key={navItem.key} className='submodule' data-nav-item-key={navItem.key}>\n {navItem.route}\n </li>\n ))}\n </ul>\n )}\n <ApplicationActionBar items={actionBarItems} />\n </div>\n </nav>\n );\n }\n);\n\nexport default VolkswagenApplicationHeader;\n"],"names":["VolkswagenApplicationHeader","forwardRef","props","ref","homeRoute","appNavigator","appNavigatorClassName","appMenuItems","navItems","actionBarItems","onMount","onUnmount","className","remainingProps","wrapperClassNames","classNames","jsx","jsxs","isEmpty","navItem","ApplicationActionBar"],"mappings":";;;;;AAwBO,MAAMA,IAA8BC;AAAA,EACvC,CAACC,GAAyCC,MAAmC;AACzE,UAAM;AAAA,MACF,WAAAC,IAAY;AAAA,MACZ,cAAAC;AAAA,MACA,uBAAAC;AAAA,MACA,cAAAC;AAAA,MACA,UAAAC,IAAW,CAAA;AAAA,MACX,gBAAAC,IAAiB,CAAA;AAAA,MACjB,SAAAC,IAAU,MAAM;AAAA,MAAC;AAAA,MACjB,WAAAC,IAAY,MAAM;AAAA,MAAC;AAAA,MACnB,WAAAC,IAAY;AAAA,MACZ,GAAGC;AAAA,IAAA,IACHX,GAEEY,IAAoBC;AAAA,MACtB;AAAA,MACA;AAAA,MACAH,KAAaA;AAAA,IAAA;AAGjB,WACI,gBAAAI,EAAC,OAAA,EAAK,GAAGH,GAAgB,WAAWC,GAAmB,KAAAX,GACnD,UAAA,gBAAAc,EAAC,OAAA,EAAI,WAAU,gBACX,UAAA;AAAA,MAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,SACX,UAAA,gBAAAA,EAAC,SAAI,WAAU,QAAQ,aAAU,EAAA,CACrC;AAAA,MACCE,EAAQV,CAAQ,KAAK,gBAAAQ,EAAC,MAAA,EAAG,WAAU,2BAA0B;AAAA,MAC7D,CAACE,EAAQV,CAAQ,uBACb,MAAA,EAAG,WAAU,2BACT,UAAAA,EAAS,IAAI,CAAAW,wBACT,MAAA,EAAqB,WAAU,aAAY,qBAAmBA,EAAQ,KAClE,YAAQ,MAAA,GADJA,EAAQ,GAEjB,CACH,EAAA,CACL;AAAA,MAEJ,gBAAAH,EAACI,GAAA,EAAqB,OAAOX,EAAA,CAAgB;AAAA,IAAA,EAAA,CACjD,EAAA,CACJ;AAAA,EAER;AACJ;"}
1
+ {"version":3,"file":"VolkswagenApplicationHeader.js","sources":["../../../../../src/themes/Volkswagen/components/applicationHeader/VolkswagenApplicationHeader.tsx"],"sourcesContent":["import React, { forwardRef, type ForwardedRef } from 'react';\nimport { isEmpty } from 'es-toolkit/compat';\n\nimport classNames from '../../../../utils/classNames';\nimport type { ApplicationHeaderProps } from '../../../../ApplicationHeader';\nimport ApplicationActionBar from '../../../../components/applicationHeader/ApplicationActionBar';\n\nexport type ModuleProps = {\n key: string;\n route: React.ReactNode;\n};\n\nexport type VolkswagenApplicationHeaderProps = ApplicationHeaderProps & {\n homeRoute?: React.ReactNode;\n appMenuItems?: ModuleProps[];\n appNavigator?: React.ReactNode;\n appNavigatorClassName?: string;\n navItems?: ModuleProps[];\n actionBarItems?: React.ReactNode[];\n onMount?: VoidFunction;\n onUnmount?: VoidFunction;\n className?: string;\n};\n\nexport const VolkswagenApplicationHeader = forwardRef(\n (props: VolkswagenApplicationHeaderProps, ref: ForwardedRef<HTMLElement>) => {\n const {\n homeRoute = '',\n appNavigator,\n appNavigatorClassName,\n appMenuItems,\n navItems = [],\n actionBarItems = [],\n onMount = () => {},\n onUnmount = () => {},\n className = '',\n ...remainingProps\n } = props;\n\n const wrapperClassNames = classNames(\n 'ApplicationHeader VolkswagenApplicationHeader',\n 'user-select-none',\n className && className\n );\n\n return (\n <nav {...remainingProps} className={wrapperClassNames} ref={ref}>\n <div className='width-100pct'>\n <div className='position-relative padding-y-25'>\n <div className='brand'>\n <div className='logo' style={{ height: '40px', width: '400px' }}>\n {homeRoute}\n </div>\n </div>\n\n <div className='position-absolute top-50pct right-10 z-index-1 translate-y-50pct'>\n <ApplicationActionBar items={actionBarItems} />\n </div>\n </div>\n\n <ul className='SubmoduleNavigation nav'>\n {!isEmpty(navItems) &&\n navItems.map(navItem => (\n <li key={navItem.key} className='submodule' data-nav-item-key={navItem.key}>\n {navItem.route}\n </li>\n ))}\n </ul>\n </div>\n </nav>\n );\n }\n);\n\nexport default VolkswagenApplicationHeader;\n"],"names":["VolkswagenApplicationHeader","forwardRef","props","ref","homeRoute","appNavigator","appNavigatorClassName","appMenuItems","navItems","actionBarItems","onMount","onUnmount","className","remainingProps","wrapperClassNames","classNames","jsx","jsxs","ApplicationActionBar","isEmpty","navItem"],"mappings":";;;;;AAwBO,MAAMA,IAA8BC;AAAA,EACvC,CAACC,GAAyCC,MAAmC;AACzE,UAAM;AAAA,MACF,WAAAC,IAAY;AAAA,MACZ,cAAAC;AAAA,MACA,uBAAAC;AAAA,MACA,cAAAC;AAAA,MACA,UAAAC,IAAW,CAAA;AAAA,MACX,gBAAAC,IAAiB,CAAA;AAAA,MACjB,SAAAC,IAAU,MAAM;AAAA,MAAC;AAAA,MACjB,WAAAC,IAAY,MAAM;AAAA,MAAC;AAAA,MACnB,WAAAC,IAAY;AAAA,MACZ,GAAGC;AAAA,IAAA,IACHX,GAEEY,IAAoBC;AAAA,MACtB;AAAA,MACA;AAAA,MACAH,KAAaA;AAAA,IAAA;AAGjB,WACI,gBAAAI,EAAC,OAAA,EAAK,GAAGH,GAAgB,WAAWC,GAAmB,KAAAX,GACnD,UAAA,gBAAAc,EAAC,OAAA,EAAI,WAAU,gBACX,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,kCACX,UAAA;AAAA,QAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,SACX,UAAA,gBAAAA,EAAC,SAAI,WAAU,QAAO,OAAO,EAAE,QAAQ,QAAQ,OAAO,QAAA,GACjD,aACL,GACJ;AAAA,QAEA,gBAAAA,EAAC,SAAI,WAAU,oEACX,4BAACE,GAAA,EAAqB,OAAOT,GAAgB,EAAA,CACjD;AAAA,MAAA,GACJ;AAAA,MAEA,gBAAAO,EAAC,QAAG,WAAU,2BACT,WAACG,EAAQX,CAAQ,KACdA,EAAS,IAAI,CAAAY,wBACR,MAAA,EAAqB,WAAU,aAAY,qBAAmBA,EAAQ,KAClE,YAAQ,MAAA,GADJA,EAAQ,GAEjB,CACH,EAAA,CACT;AAAA,IAAA,EAAA,CACJ,EAAA,CACJ;AAAA,EAER;AACJ;"}
@@ -0,0 +1,2 @@
1
+ import { ReactNode } from 'react';
2
+ export declare const getTrackingLabelFromNode: (value: ReactNode) => string | undefined;
@@ -0,0 +1,24 @@
1
+ import { isValidElement as o } from "react";
2
+ const n = (r) => {
3
+ if (!(r == null || typeof r == "boolean")) {
4
+ if (typeof r == "string" || typeof r == "number" || typeof r == "bigint")
5
+ return String(r);
6
+ if (Array.isArray(r)) {
7
+ const t = r.map(n).filter(
8
+ (i) => typeof i == "string" && i.length > 0
9
+ );
10
+ return t.length > 0 ? t.join(" ") : void 0;
11
+ }
12
+ if (o(r)) {
13
+ const t = n(r.props.children);
14
+ if (t)
15
+ return t;
16
+ if (typeof r.props.id == "string" && r.props.id.length > 0)
17
+ return r.props.id;
18
+ }
19
+ }
20
+ };
21
+ export {
22
+ n as getTrackingLabelFromNode
23
+ };
24
+ //# sourceMappingURL=getTrackingLabelFromNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getTrackingLabelFromNode.js","sources":["../../../src/utils/analytics/getTrackingLabelFromNode.ts"],"sourcesContent":["import { isValidElement, type ReactNode } from 'react';\n\nexport const getTrackingLabelFromNode = (value: ReactNode): string | undefined => {\n if (value == null || typeof value === 'boolean') {\n return;\n }\n\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'bigint') {\n return String(value);\n }\n\n if (Array.isArray(value)) {\n const trackingValues = value\n .map(getTrackingLabelFromNode)\n .filter(\n (trackingValue): trackingValue is string =>\n typeof trackingValue === 'string' && trackingValue.length > 0\n );\n\n return trackingValues.length > 0 ? trackingValues.join(' ') : undefined;\n }\n\n if (isValidElement<{ id?: unknown; children?: ReactNode }>(value)) {\n const childrenTrackingValue = getTrackingLabelFromNode(value.props.children);\n\n if (childrenTrackingValue) {\n return childrenTrackingValue;\n }\n\n if (typeof value.props.id === 'string' && value.props.id.length > 0) {\n return value.props.id;\n }\n }\n};\n"],"names":["getTrackingLabelFromNode","value","trackingValues","trackingValue","isValidElement","childrenTrackingValue"],"mappings":";AAEO,MAAMA,IAA2B,CAACC,MAAyC;AAC9E,MAAI,EAAAA,KAAS,QAAQ,OAAOA,KAAU,YAItC;AAAA,QAAI,OAAOA,KAAU,YAAY,OAAOA,KAAU,YAAY,OAAOA,KAAU;AAC3E,aAAO,OAAOA,CAAK;AAGvB,QAAI,MAAM,QAAQA,CAAK,GAAG;AACtB,YAAMC,IAAiBD,EAClB,IAAID,CAAwB,EAC5B;AAAA,QACG,CAACG,MACG,OAAOA,KAAkB,YAAYA,EAAc,SAAS;AAAA,MAAA;AAGxE,aAAOD,EAAe,SAAS,IAAIA,EAAe,KAAK,GAAG,IAAI;AAAA,IAClE;AAEA,QAAIE,EAAuDH,CAAK,GAAG;AAC/D,YAAMI,IAAwBL,EAAyBC,EAAM,MAAM,QAAQ;AAE3E,UAAII;AACA,eAAOA;AAGX,UAAI,OAAOJ,EAAM,MAAM,MAAO,YAAYA,EAAM,MAAM,GAAG,SAAS;AAC9D,eAAOA,EAAM,MAAM;AAAA,IAE3B;AAAA;AACJ;"}
@@ -1,37 +1,30 @@
1
- import { LOOKUP_MAX_LENGTH as c } from "./analyticsAnalysisUtils.js";
2
- const l = /* @__PURE__ */ new Set(), d = (e, a) => {
3
- if (process.env.NODE_ENV === "production" || a.length <= c)
1
+ import "../init/initConfig.js";
2
+ const s = () => typeof window < "u" && Array.isArray(window.dataLayer), l = (t) => {
3
+ if (!s())
4
4
  return;
5
- const t = `${e}::${a}`;
6
- l.has(t) || (l.add(t), console.warn(
7
- `[Analytics] data-track-ga-event-label exceeds ${c} chars for action "${e}". Overlay mapping uses only the first ${c} chars.`
8
- ));
9
- }, u = () => typeof window < "u" && Array.isArray(window.dataLayer), g = (e) => {
10
- if (!u())
11
- return;
12
- const a = {
5
+ const e = {
13
6
  event: "ga_event",
14
- eventCategory: e.category,
15
- eventAction: e.action,
16
- eventLabel: e.label
7
+ eventCategory: t.category,
8
+ eventAction: t.action,
9
+ eventLabel: t.label
17
10
  };
18
- e.value !== void 0 && e.value !== "" && (a.eventValue = e.value), window.dataLayer?.push(a);
19
- }, y = (e, a) => (...t) => {
20
- const n = e(...t);
21
- return g(a), n;
22
- }, A = {}, w = {}, L = (e) => {
23
- const { trigger: a, category: t, action: n, label: r, value: s } = e, i = n || `action_${a}`, o = {
24
- "data-track-ga-event-trigger": a,
25
- "data-track-ga-event-category": t,
11
+ t.value !== void 0 && t.value !== "" && (e.eventValue = t.value), window.dataLayer?.push(e);
12
+ }, u = (t, e) => (...a) => {
13
+ const r = t(...a);
14
+ return l(e), r;
15
+ }, v = {}, g = {}, y = (t) => {
16
+ const { trigger: e, category: a, action: r, label: o, value: c } = t, i = r || `action_${e}`, n = {
17
+ "data-track-ga-event-trigger": e,
18
+ "data-track-ga-event-category": a,
26
19
  "data-track-ga-event-action": i
27
20
  };
28
- return r && (o["data-track-ga-event-label"] = r, d(i, r)), s && (o["data-track-ga-event-value"] = s), o;
21
+ return o && (n["data-track-ga-event-label"] = o), c && (n["data-track-ga-event-value"] = c), n;
29
22
  };
30
23
  export {
31
- A as TRACKING_ACTIONS,
32
- w as TRACKING_LABELS,
33
- y as executeAndTrack,
34
- g as gaPush,
35
- L as getTrackingAttributes
24
+ v as TRACKING_ACTIONS,
25
+ g as TRACKING_LABELS,
26
+ u as executeAndTrack,
27
+ l as gaPush,
28
+ y as getTrackingAttributes
36
29
  };
37
30
  //# sourceMappingURL=googleAnalyticsUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"googleAnalyticsUtils.js","sources":["../../../src/utils/analytics/googleAnalyticsUtils.ts"],"sourcesContent":["import { LOOKUP_MAX_LENGTH } from './analyticsAnalysisUtils';\n\ndeclare global {\n interface Window {\n dataLayer?: unknown[];\n }\n}\n\nexport type GAEvent = {\n category: string;\n action: string;\n label: string;\n value?: string | number;\n};\n\ntype GADataLayerEvent = {\n event: 'ga_event';\n eventCategory: string;\n eventAction: string;\n eventLabel: string;\n eventValue?: string | number;\n};\n\nconst warnedLongTrackingLabels = new Set<string>();\n\nconst warnAboutLongTrackingLabel = (action: string, label: string) => {\n if (process.env.NODE_ENV === 'production' || label.length <= LOOKUP_MAX_LENGTH) {\n return;\n }\n\n const warningKey = `${action}::${label}`;\n if (warnedLongTrackingLabels.has(warningKey)) {\n return;\n }\n\n warnedLongTrackingLabels.add(warningKey);\n console.warn(\n `[Analytics] data-track-ga-event-label exceeds ${LOOKUP_MAX_LENGTH} chars for action \"${action}\". ` +\n `Overlay mapping uses only the first ${LOOKUP_MAX_LENGTH} chars.`\n );\n};\n\n/**\n * Approach 1: DataLayer push\n *\n * Use this to send events to Google Analytics imperatively, for example from UI callbacks.\n * This is also the only supported path for tracking hover interactions, since the\n * attribute-based tracking flow only supports click and visibility triggers.\n */\n\nconst isBrowserDataLayerAvailable = () => typeof window !== 'undefined' && Array.isArray(window.dataLayer);\n\nexport const gaPush = (gaEvent: GAEvent) => {\n if (!isBrowserDataLayerAvailable()) {\n return;\n }\n\n const payload: GADataLayerEvent = {\n event: 'ga_event',\n eventCategory: gaEvent.category,\n eventAction: gaEvent.action,\n eventLabel: gaEvent.label,\n };\n\n if (gaEvent.value !== undefined && gaEvent.value !== '') {\n payload.eventValue = gaEvent.value;\n }\n\n window.dataLayer?.push(payload);\n};\n\nexport const executeAndTrack =\n <Args extends unknown[], Result>(func: (...args: Args) => Result, value: GAEvent) =>\n (...args: Args): Result => {\n const result = func(...args);\n gaPush(value);\n return result;\n };\n\n/**\n * Approach 2: Tracking attributes (preferred)\n *\n * Use this to add DOM attributes to an element. These attributes can be utilized later\n * by the AnalyticsAnalysisOverlay component.\n */\n\nexport type TRACKING_TRIGGER = 'click' | 'visibility';\n\nexport type TrackingValues = {\n trigger: TRACKING_TRIGGER;\n category: string;\n action?: string;\n label?: string;\n value?: string;\n};\n\nexport type TrackingAttributes = {\n 'data-track-ga-event-trigger': TRACKING_TRIGGER;\n 'data-track-ga-event-category': string;\n 'data-track-ga-event-action': string;\n 'data-track-ga-event-label'?: string;\n 'data-track-ga-event-value'?: string;\n};\n\n// Application-specific maps to be filled by consuming apps.\nexport const TRACKING_ACTIONS: Record<string, string> = {};\n\n// Application-specific maps to be filled by consuming apps.\nexport const TRACKING_LABELS: Record<string, string> = {};\n\nexport const getTrackingAttributes = (param: TrackingValues): TrackingAttributes => {\n const { trigger, category, action, label, value } = param;\n const resolvedAction = action || `action_${trigger}`;\n\n const attributes: TrackingAttributes = {\n 'data-track-ga-event-trigger': trigger,\n 'data-track-ga-event-category': category,\n 'data-track-ga-event-action': resolvedAction,\n };\n\n if (label) {\n attributes['data-track-ga-event-label'] = label;\n warnAboutLongTrackingLabel(resolvedAction, label);\n }\n\n if (value) {\n attributes['data-track-ga-event-value'] = value;\n }\n\n return attributes;\n};\n"],"names":["warnedLongTrackingLabels","warnAboutLongTrackingLabel","action","label","LOOKUP_MAX_LENGTH","warningKey","isBrowserDataLayerAvailable","gaPush","gaEvent","payload","executeAndTrack","func","value","args","result","TRACKING_ACTIONS","TRACKING_LABELS","getTrackingAttributes","param","trigger","category","resolvedAction","attributes"],"mappings":";AAuBA,MAAMA,wBAA+B,IAAA,GAE/BC,IAA6B,CAACC,GAAgBC,MAAkB;AAClE,MAAI,QAAQ,IAAI,aAAa,gBAAgBA,EAAM,UAAUC;AACzD;AAGJ,QAAMC,IAAa,GAAGH,CAAM,KAAKC,CAAK;AACtC,EAAIH,EAAyB,IAAIK,CAAU,MAI3CL,EAAyB,IAAIK,CAAU,GACvC,QAAQ;AAAA,IACJ,iDAAiDD,CAAiB,sBAAsBF,CAAM,0CACnDE,CAAiB;AAAA,EAAA;AAEpE,GAUME,IAA8B,MAAM,OAAO,SAAW,OAAe,MAAM,QAAQ,OAAO,SAAS,GAE5FC,IAAS,CAACC,MAAqB;AACxC,MAAI,CAACF;AACD;AAGJ,QAAMG,IAA4B;AAAA,IAC9B,OAAO;AAAA,IACP,eAAeD,EAAQ;AAAA,IACvB,aAAaA,EAAQ;AAAA,IACrB,YAAYA,EAAQ;AAAA,EAAA;AAGxB,EAAIA,EAAQ,UAAU,UAAaA,EAAQ,UAAU,OACjDC,EAAQ,aAAaD,EAAQ,QAGjC,OAAO,WAAW,KAAKC,CAAO;AAClC,GAEaC,IACT,CAAiCC,GAAiCC,MAClE,IAAIC,MAAuB;AACvB,QAAMC,IAASH,EAAK,GAAGE,CAAI;AAC3B,SAAAN,EAAOK,CAAK,GACLE;AACX,GA4BSC,IAA2C,CAAA,GAG3CC,IAA0C,CAAA,GAE1CC,IAAwB,CAACC,MAA8C;AAChF,QAAM,EAAE,SAAAC,GAAS,UAAAC,GAAU,QAAAlB,GAAQ,OAAAC,GAAO,OAAAS,MAAUM,GAC9CG,IAAiBnB,KAAU,UAAUiB,CAAO,IAE5CG,IAAiC;AAAA,IACnC,+BAA+BH;AAAA,IAC/B,gCAAgCC;AAAA,IAChC,8BAA8BC;AAAA,EAAA;AAGlC,SAAIlB,MACAmB,EAAW,2BAA2B,IAAInB,GAC1CF,EAA2BoB,GAAgBlB,CAAK,IAGhDS,MACAU,EAAW,2BAA2B,IAAIV,IAGvCU;AACX;"}
1
+ {"version":3,"file":"googleAnalyticsUtils.js","sources":["../../../src/utils/analytics/googleAnalyticsUtils.ts"],"sourcesContent":["import { LOOKUP_MAX_LENGTH } from './analyticsAnalysisUtils';\nimport { isProd } from '../init/initConfig';\n\ndeclare global {\n interface Window {\n dataLayer?: unknown[];\n }\n}\n\nexport type GAEvent = {\n category: string;\n action: string;\n label: string;\n value?: string | number;\n};\n\ntype GADataLayerEvent = {\n event: 'ga_event';\n eventCategory: string;\n eventAction: string;\n eventLabel: string;\n eventValue?: string | number;\n};\n\nconst warnedLongTrackingLabels = new Set<string>();\n\nconst warnAboutLongTrackingLabel = (action: string, label: string) => {\n if (isProd || label.length <= LOOKUP_MAX_LENGTH) {\n return;\n }\n\n const warningKey = `${action}::${label}`;\n if (warnedLongTrackingLabels.has(warningKey)) {\n return;\n }\n\n warnedLongTrackingLabels.add(warningKey);\n console.warn(\n `[Analytics] data-track-ga-event-label exceeds ${LOOKUP_MAX_LENGTH} chars for action \"${action}\". ` +\n `Overlay mapping uses only the first ${LOOKUP_MAX_LENGTH} chars.`\n );\n};\n\n/**\n * Approach 1: DataLayer push\n *\n * Use this to send events to Google Analytics imperatively, for example from UI callbacks.\n * This is also the only supported path for tracking hover interactions, since the\n * attribute-based tracking flow only supports click and visibility triggers.\n */\n\nconst isBrowserDataLayerAvailable = () => typeof window !== 'undefined' && Array.isArray(window.dataLayer);\n\nexport const gaPush = (gaEvent: GAEvent) => {\n if (!isBrowserDataLayerAvailable()) {\n return;\n }\n\n const payload: GADataLayerEvent = {\n event: 'ga_event',\n eventCategory: gaEvent.category,\n eventAction: gaEvent.action,\n eventLabel: gaEvent.label,\n };\n\n if (gaEvent.value !== undefined && gaEvent.value !== '') {\n payload.eventValue = gaEvent.value;\n }\n\n window.dataLayer?.push(payload);\n};\n\nexport const executeAndTrack =\n <Args extends unknown[], Result>(func: (...args: Args) => Result, value: GAEvent) =>\n (...args: Args): Result => {\n const result = func(...args);\n gaPush(value);\n return result;\n };\n\n/**\n * Approach 2: Tracking attributes (preferred)\n *\n * Use this to add DOM attributes to an element. These attributes can be utilized later\n * by the AnalyticsAnalysisOverlay component.\n */\n\nexport type TRACKING_TRIGGER = 'click' | 'visibility';\n\nexport type TrackingValues = {\n trigger: TRACKING_TRIGGER;\n category: string;\n action?: string;\n label?: string;\n value?: string;\n};\n\nexport type TrackingAttributes = {\n 'data-track-ga-event-trigger': TRACKING_TRIGGER;\n 'data-track-ga-event-category': string;\n 'data-track-ga-event-action': string;\n 'data-track-ga-event-label'?: string;\n 'data-track-ga-event-value'?: string;\n};\n\n// Application-specific maps to be filled by consuming apps.\nexport const TRACKING_ACTIONS: Record<string, string> = {};\n\n// Application-specific maps to be filled by consuming apps.\nexport const TRACKING_LABELS: Record<string, string> = {};\n\nexport const getTrackingAttributes = (param: TrackingValues): TrackingAttributes => {\n const { trigger, category, action, label, value } = param;\n const resolvedAction = action || `action_${trigger}`;\n\n const attributes: TrackingAttributes = {\n 'data-track-ga-event-trigger': trigger,\n 'data-track-ga-event-category': category,\n 'data-track-ga-event-action': resolvedAction,\n };\n\n if (label) {\n attributes['data-track-ga-event-label'] = label;\n warnAboutLongTrackingLabel(resolvedAction, label);\n }\n\n if (value) {\n attributes['data-track-ga-event-value'] = value;\n }\n\n return attributes;\n};\n"],"names":["isBrowserDataLayerAvailable","gaPush","gaEvent","payload","executeAndTrack","func","value","args","result","TRACKING_ACTIONS","TRACKING_LABELS","getTrackingAttributes","param","trigger","category","action","label","resolvedAction","attributes"],"mappings":";AAmDA,MAAMA,IAA8B,MAAM,OAAO,SAAW,OAAe,MAAM,QAAQ,OAAO,SAAS,GAE5FC,IAAS,CAACC,MAAqB;AACxC,MAAI,CAACF;AACD;AAGJ,QAAMG,IAA4B;AAAA,IAC9B,OAAO;AAAA,IACP,eAAeD,EAAQ;AAAA,IACvB,aAAaA,EAAQ;AAAA,IACrB,YAAYA,EAAQ;AAAA,EAAA;AAGxB,EAAIA,EAAQ,UAAU,UAAaA,EAAQ,UAAU,OACjDC,EAAQ,aAAaD,EAAQ,QAGjC,OAAO,WAAW,KAAKC,CAAO;AAClC,GAEaC,IACT,CAAiCC,GAAiCC,MAClE,IAAIC,MAAuB;AACvB,QAAMC,IAASH,EAAK,GAAGE,CAAI;AAC3B,SAAAN,EAAOK,CAAK,GACLE;AACX,GA4BSC,IAA2C,CAAA,GAG3CC,IAA0C,CAAA,GAE1CC,IAAwB,CAACC,MAA8C;AAChF,QAAM,EAAE,SAAAC,GAAS,UAAAC,GAAU,QAAAC,GAAQ,OAAAC,GAAO,OAAAV,MAAUM,GAC9CK,IAAiBF,KAAU,UAAUF,CAAO,IAE5CK,IAAiC;AAAA,IACnC,+BAA+BL;AAAA,IAC/B,gCAAgCC;AAAA,IAChC,8BAA8BG;AAAA,EAAA;AAGlC,SAAID,MACAE,EAAW,2BAA2B,IAAIF,IAI1CV,MACAY,EAAW,2BAA2B,IAAIZ,IAGvCY;AACX;"}
@@ -0,0 +1,2 @@
1
+ import { ReactNode } from 'react';
2
+ export declare const getNodeTextContent: (value: ReactNode) => string | undefined;