@hortiview/shared-components 2.22.0 → 2.23.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ## [2.23.1](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/compare/v2.23.0...v2.23.1) (2026-04-14)
2
+
3
+ ### Bug Fixes
4
+
5
+ * update BaseView to conditionally apply fullHeight class ([7862e04](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/7862e04236b407afe357cc2eee66f03a1ff38592))
6
+
7
+ ### Code Refactoring
8
+
9
+ * improve Modal component layout and error banner display ([5586676](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/55866762e965d66ce1d3540957c7e6fe469e9e4d))
10
+ * update Modal component layout and enhance error banner functionality ([8a10088](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/8a10088582d759454c893a63cde767880e4fc88d))
11
+
12
+ ## [2.23.0](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/compare/v2.22.0...v2.23.0) (2026-04-13)
13
+
14
+ ### Features
15
+
16
+ * improve FormDatePicker UTC handling and date conversion logic ([d2e6000](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/d2e6000f5e6e60acdd4c424297b76ea5d1d2f88a))
17
+
18
+ ### Code Refactoring
19
+
20
+ * extract FormDatePicker utility functions into a separate service file; linting ([7908c2c](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/7908c2c5233c841965a515f7144656fdd0d12285))
21
+ * rename and update date handling functions for improved clarity and functionality ([1f6713b](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/1f6713bbe19e84f01f57890f7c77559ce281e9d5))
22
+
1
23
  ## [2.22.0](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/compare/v2.21.0...v2.22.0) (2026-04-13)
2
24
 
3
25
  ### Features
@@ -1 +1 @@
1
- ._fullHeight_71rfc_1{height:100%}._fullWidth_71rfc_5{width:100%}._maxWidth_71rfc_9{background-color:var(--lmnt-theme-background)}._list_71rfc_13{box-shadow:0 8px 24px #959da533;background-color:var(--lmnt-theme-background);border-radius:.5rem;overflow-y:auto;width:100%;height:100%}._desktopList_71rfc_22{width:30%;align-self:stretch}._noRoundedCorners_71rfc_27 [class*="lmnt mdc-list-item"]{border-radius:0rem!important}._detail_71rfc_31{height:100%;box-shadow:0 8px 24px #959da533;border-radius:.5rem;background-color:var(--lmnt-theme-background);width:100%}._desktopDetail_71rfc_39{width:70%;overflow-y:auto;scrollbar-width:thin}
1
+ ._fullHeight_1yui7_1{height:100%}._fullWidth_1yui7_5{width:100%}._heading_1yui7_9{background-color:var(--lmnt-theme-background)}._list_1yui7_18{box-shadow:0 8px 24px #959da533;background-color:var(--lmnt-theme-background);border-radius:.5rem;overflow-y:auto;width:100%;height:100%}._desktopList_1yui7_27{width:30%;align-self:stretch}._noRoundedCorners_1yui7_32 [class*="lmnt mdc-list-item"]{border-radius:0rem!important}._detail_1yui7_36{height:100%;box-shadow:0 8px 24px #959da533;border-radius:.5rem;background-color:var(--lmnt-theme-background);width:100%}._desktopDetail_1yui7_44{width:70%;overflow-y:auto;scrollbar-width:thin}
@@ -1 +1 @@
1
- ._modal_1yn30_1 div[class*=lmnt-modal__surface]{max-height:100svh!important;max-width:100svw!important}._modal_1yn30_1 div:not([class*=mdc-dialog--fullscreen]) div[class*=lmnt-modal__surface]{border-radius:1rem!important}._modal_1yn30_1 footer{margin-bottom:0!important}._gap_1yn30_14{gap:4px!important}._title_1yn30_18{header{display:flex;justify-content:start;padding-left:.5rem!important;>div{width:100%;margin-left:0!important}}}._titleWithoutCloseIcon_1yn30_31{margin-left:1rem!important}._closeButton_1yn30_35{color:var(--lmnt-theme-on-surface-inactive)}._closeButton_1yn30_35:before{display:none!important}._closeButton_1yn30_35:hover{background-color:var(--lmnt-theme-surface-variant)!important}._errorBanner_1yn30_47{margin:-20px -24px 20px}
1
+ ._modal_lk11w_1 div[class*=lmnt-modal__surface]{max-height:100svh!important;max-width:100svw!important}._modal_lk11w_1 div:not([class*=mdc-dialog--fullscreen]) div[class*=lmnt-modal__surface]{border-radius:1rem!important}._modal_lk11w_1 footer{margin-bottom:0!important}._gap_lk11w_14{gap:4px!important;padding-left:.5rem!important}._title_lk11w_19{header{display:flex;justify-content:start;padding-inline:0!important;>div{width:100%;margin-left:0!important}}}._titleWithoutCloseIcon_lk11w_32{margin-left:1rem!important}._closeButton_lk11w_36{color:var(--lmnt-theme-on-surface-inactive)}._closeButton_lk11w_36:before{display:none!important}._closeButton_lk11w_36:hover{background-color:var(--lmnt-theme-surface-variant)!important}._errorBanner_lk11w_48{width:100%}._headerActions_lk11w_52{margin-left:.5rem}
@@ -5,43 +5,43 @@ import { P as $ } from "../../index.es-DgncYOqO.js";
5
5
  import { c as g } from "../../index-Df2FYN-K.js";
6
6
  import { useMemo as n } from "react";
7
7
  import { BasicHeading as w } from "../BasicHeading/BasicHeading.js";
8
- import { EmptyView as y } from "../EmptyView/EmptyView.js";
9
- import { ListArea as F } from "../ListArea/ListArea.js";
10
- import { useBreakpoints as M } from "../../hooks/useBreakpoints.js";
11
- import { OfflineView as P } from "../OfflineView/OfflineView.js";
12
- import { useScrollableInfo as T } from "./BaseView.service.js";
13
- import '../../assets/BaseView.css';const q = "_fullHeight_71rfc_1", z = "_fullWidth_71rfc_5", J = "_maxWidth_71rfc_9", K = "_list_71rfc_13", O = "_desktopList_71rfc_22", Q = "_noRoundedCorners_71rfc_27", U = "_detail_71rfc_31", X = "_desktopDetail_71rfc_39", i = {
14
- fullHeight: q,
15
- fullWidth: z,
16
- maxWidth: J,
17
- list: K,
18
- desktopList: O,
19
- noRoundedCorners: Q,
20
- detail: U,
21
- desktopDetail: X
22
- }, ct = ({
8
+ import { EmptyView as F } from "../EmptyView/EmptyView.js";
9
+ import { ListArea as M } from "../ListArea/ListArea.js";
10
+ import { useBreakpoints as P } from "../../hooks/useBreakpoints.js";
11
+ import { OfflineView as T } from "../OfflineView/OfflineView.js";
12
+ import { useScrollableInfo as q } from "./BaseView.service.js";
13
+ import '../../assets/BaseView.css';const z = "_fullHeight_1yui7_1", J = "_fullWidth_1yui7_5", K = "_heading_1yui7_9", O = "_list_1yui7_18", Q = "_desktopList_1yui7_27", U = "_noRoundedCorners_1yui7_32", X = "_detail_1yui7_36", Y = "_desktopDetail_1yui7_44", i = {
14
+ fullHeight: z,
15
+ fullWidth: J,
16
+ heading: K,
17
+ list: O,
18
+ desktopList: Q,
19
+ noRoundedCorners: U,
20
+ detail: X,
21
+ desktopDetail: Y
22
+ }, ut = ({
23
23
  heading: u,
24
24
  action: f = /* @__PURE__ */ e(d, {}),
25
25
  hint: v = /* @__PURE__ */ e(d, {}),
26
26
  elements: r,
27
27
  emptyText: m,
28
28
  hasSearch: D = !0,
29
- isSorted: W = !0,
30
- className: k,
31
- withAvatar: x = !1,
32
- listMaxHeight: L = "calc(100vh - 220px)",
33
- titleLevel: b = 5,
34
- detailTitleLevel: H,
29
+ isSorted: k = !0,
30
+ className: y,
31
+ withAvatar: L = !1,
32
+ listMaxHeight: b = "calc(100vh - 220px)",
33
+ titleLevel: H = 5,
34
+ detailTitleLevel: N,
35
35
  pathname: s,
36
- basicHeadingIcon: N,
36
+ basicHeadingIcon: W,
37
37
  isOnline: h = !0,
38
38
  offlineViewProps: p,
39
39
  noRoundedListItemEdges: _ = !0,
40
40
  routerLinkElement: B,
41
- searchPlaceholder: R,
42
- isGrouped: A = !1
41
+ searchPlaceholder: x,
42
+ isGrouped: R = !1
43
43
  }) => {
44
- const { isDesktopNavbar: o } = M(), t = n(() => r.find((a) => a.route === s), [s, r]), C = n(() => r.filter((a) => a.isAllowed !== !1), [r]), I = n(() => h ? t?.component ? t.component : o ? /* @__PURE__ */ e($, { className: i.fullWidth, children: /* @__PURE__ */ e(y, { title: m }) }) : /* @__PURE__ */ e(d, {}) : /* @__PURE__ */ e(P, { ...p, fullWidth: !0 }), [t?.component, m, o, h, p]), { showList: S, showDetail: E } = n(() => o ? { showList: !0, showDetail: !0 } : { showList: !t, showDetail: !!t }, [t, o]), { ref: j, hasScrolled: G } = T([
44
+ const { isDesktopNavbar: o, isDesktop: A } = P(), t = n(() => r.find((a) => a.route === s), [s, r]), C = n(() => r.filter((a) => a.isAllowed !== !1), [r]), I = n(() => h ? t?.component ? t.component : o ? /* @__PURE__ */ e($, { className: i.fullWidth, children: /* @__PURE__ */ e(F, { title: m }) }) : /* @__PURE__ */ e(d, {}) : /* @__PURE__ */ e(T, { ...p, fullWidth: !0 }), [t?.component, m, o, h, p]), { showList: S, showDetail: E } = n(() => o ? { showList: !0, showDetail: !0 } : { showList: !t, showDetail: !!t }, [t, o]), { ref: j, hasScrolled: G } = q([
45
45
  s,
46
46
  o
47
47
  ]);
@@ -49,7 +49,7 @@ import '../../assets/BaseView.css';const q = "_fullHeight_71rfc_1", z = "_fullWi
49
49
  l,
50
50
  {
51
51
  "data-testid": "base-view-container",
52
- className: `${i.fullHeight} ${k ?? ""}`,
52
+ className: `${A ? i.fullHeight : ""} ${y ?? ""}`,
53
53
  fullWidth: !0,
54
54
  children: [
55
55
  S && /* @__PURE__ */ c(
@@ -67,10 +67,10 @@ import '../../assets/BaseView.css';const q = "_fullHeight_71rfc_1", z = "_fullWi
67
67
  u && /* @__PURE__ */ e(
68
68
  w,
69
69
  {
70
- icon: N,
70
+ icon: W,
71
71
  "data-testid": "heading",
72
72
  heading: u,
73
- level: b,
73
+ level: H,
74
74
  marginBottom: 0,
75
75
  inList: !0,
76
76
  children: f
@@ -78,17 +78,17 @@ import '../../assets/BaseView.css';const q = "_fullHeight_71rfc_1", z = "_fullWi
78
78
  ),
79
79
  v,
80
80
  /* @__PURE__ */ e(
81
- F,
81
+ M,
82
82
  {
83
83
  hasLastItemNoRoundedEdges: _,
84
84
  elements: C,
85
85
  hasSearch: D,
86
- maxHeight: L,
87
- isSorted: W,
86
+ maxHeight: b,
87
+ isSorted: k,
88
88
  pathname: s,
89
89
  routerLinkElement: B,
90
- searchPlaceholder: R,
91
- isGrouped: A
90
+ searchPlaceholder: x,
91
+ isGrouped: R
92
92
  }
93
93
  )
94
94
  ]
@@ -105,13 +105,13 @@ import '../../assets/BaseView.css';const q = "_fullHeight_71rfc_1", z = "_fullWi
105
105
  /* @__PURE__ */ e(
106
106
  w,
107
107
  {
108
- className: i.maxWidth,
108
+ className: i.heading,
109
109
  heading: t?.detailTitle ?? t?.title ?? "",
110
- level: H,
110
+ level: N,
111
111
  icon: t?.hideIconInDetail === !0 ? void 0 : t?.detailIcon ?? t?.icon,
112
112
  marginBottom: 0,
113
113
  invisibleButton: t?.detailAction === void 0,
114
- withAvatar: x,
114
+ withAvatar: L,
115
115
  subHeading: t?.detailSubTitle,
116
116
  children: t?.detailAction ?? f
117
117
  }
@@ -135,5 +135,5 @@ import '../../assets/BaseView.css';const q = "_fullHeight_71rfc_1", z = "_fullWi
135
135
  );
136
136
  };
137
137
  export {
138
- ct as BaseView
138
+ ut as BaseView
139
139
  };
@@ -21,7 +21,7 @@ type DatePickerProps<T extends FieldValues> = {
21
21
  helperText?: string;
22
22
  /** Add the number of years to subtract from the current date as bottom of range */
23
23
  minRangeYear?: number;
24
- /** Add the number of years to add to the current date as top of range */
24
+ /** Add the number of years to add to the current date as top of the range */
25
25
  maxRangeYear?: number;
26
26
  /** Locale to be used for the date picker. */
27
27
  locale?: string;
@@ -30,6 +30,18 @@ type DatePickerProps<T extends FieldValues> = {
30
30
  * FormDatePicker is a custom form input component for selecting dates.
31
31
  * It is integrated with react-hook-form for form management.
32
32
  *
33
+ * Date handling model used by this component:
34
+ *
35
+ * - The persisted/form value is a "date-only" value stored as a Date at 00:00:00 UTC.
36
+ * - The UI date picker works with Date objects in the browser's local timezone.
37
+ * - Before rendering, the stored UTC date is converted into a local Date with the same
38
+ * calendar year/month/day so the picker shows the expected day for the user.
39
+ * - After selection, the picked local calendar date is converted back into a UTC-midnight Date
40
+ * before storing it in react-hook-form.
41
+ *
42
+ * This conversion is necessary to avoid timezone-related off-by-one-day issues when working
43
+ * with date-only values.
44
+ *
33
45
  * @param propertyName - the name of the property this date picker maps to in the form.
34
46
  * @param label - label displayed along with the date picker.
35
47
  * @param closeLabel - label displayed as close button text.
@@ -43,5 +55,5 @@ type DatePickerProps<T extends FieldValues> = {
43
55
  *
44
56
  * @returns A JSX element that renders a date picker form input.
45
57
  */
46
- export declare const FormDatePicker: <T extends FieldValues>({ propertyName, label, closeLabel, className, minRangeYear, maxRangeYear, locale, rules, helperText, ...props }: Omit<ElementDatePickerProps, "locale"> & DatePickerProps<T>) => import("react/jsx-runtime").JSX.Element;
58
+ export declare const FormDatePicker: <T extends FieldValues>({ propertyName, label, closeLabel, className, minRangeYear, maxRangeYear, locale, rules, helperText, ...props }: Omit<ElementDatePickerProps, "locale" | "useUtc"> & DatePickerProps<T>) => import("react/jsx-runtime").JSX.Element;
47
59
  export {};