@hortiview/shared-components 2.21.0 → 2.23.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ ## [2.23.0](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/compare/v2.22.0...v2.23.0) (2026-04-13)
2
+
3
+ ### Features
4
+
5
+ * improve FormDatePicker UTC handling and date conversion logic ([d2e6000](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/d2e6000f5e6e60acdd4c424297b76ea5d1d2f88a))
6
+
7
+ ### Code Refactoring
8
+
9
+ * extract FormDatePicker utility functions into a separate service file; linting ([7908c2c](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/7908c2c5233c841965a515f7144656fdd0d12285))
10
+ * 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))
11
+
12
+ ## [2.22.0](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/compare/v2.21.0...v2.22.0) (2026-04-13)
13
+
14
+ ### Features
15
+
16
+ * add ErrorBanner component with styling and storybook integration ([22029ee](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/22029eeb746c4c4ad325d5ce5ace3c7ed0bb0a91))
17
+ * add sentiment-very-dissatisfied icon and update related components ([4a12a29](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/4a12a293d210fc1391c4439665884f00a39693cd))
18
+ * export ErrorBanner component in main module ([2372df8](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/2372df8227645fc5b5ff4755e231af024d54af20))
19
+ * integrate ErrorBanner into Modal and add useContainerWidth hook for responsive design ([9e503e9](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/9e503e9f46ef0758dc63ede5330796e551cb03a5))
20
+
21
+ ### Bug Fixes
22
+
23
+ * remove unused test ([b213a2e](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/b213a2e8f2940a27b028364ee2aee08e966c593d))
24
+
25
+ ### Code Refactoring
26
+
27
+ * changes after review ([9a6b586](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/commit/9a6b58619a2d4dba76e6d93b1d2cc452a5ab9bdd))
28
+
1
29
  ## [2.21.0](https://dev.azure.com/sdundc/HV%20Platform/_git/HortiView-Frontend-Shared/compare/v2.20.1...v2.21.0) (2026-04-13)
2
30
 
3
31
  ### Features
package/README.md CHANGED
@@ -31,6 +31,7 @@ Additionally the library provides form components using [react-hook-form](https:
31
31
  1. [DeleteModal](#deletemodal)
32
32
  1. [Disclaimer](#disclaimer)
33
33
  1. [EmptyView](#emptyview)
34
+ 1. [ErrorBanner] (#errorbanner)
34
35
  1. [Filter](#filter)
35
36
  1. [FormattedNumberDisplay](#formattednumberdisplay)
36
37
  1. [FormComponents](#formcomponents)
@@ -258,6 +259,31 @@ import { EmptyView } from '@hortiview/shared-components';
258
259
  <EmptyView title='No Content' subtitle='nothing' icon='grass' />;
259
260
  ```
260
261
 
262
+ ### ErrorBanner
263
+
264
+ Displays an error message with optional actions. Can be used below a header (default) or as a standalone banner (e.g., in a modal).
265
+
266
+ ```jsx
267
+ import { ErrorBanner } from '@hortiview/shared-components';
268
+
269
+ <ErrorBanner
270
+ title='Something went wrong'
271
+ description='An unexpected error occurred. Please try again or contact support.'
272
+ showBanner={true}
273
+ isOpen={true}
274
+ isStandalone={false} // set true for standalone usage
275
+ primaryActionLabel='Retry'
276
+ onPrimaryAction={() => alert('Retry clicked')}
277
+ secondaryActionLabel='Contact Support'
278
+ onSecondaryAction={() => alert('Support clicked')}
279
+ />;
280
+ ```
281
+
282
+ **Usage notes:**
283
+
284
+ - Use `isStandalone` for modal usage. Default style is for inline placement below a header.
285
+ - Both action buttons are optional; omit their labels to hide them.
286
+
261
287
  ### Filter
262
288
 
263
289
  A filter component, which provides a well designed filter experience. It contains a filter button and a modal for different select inputs.
@@ -0,0 +1 @@
1
+ ._bannerPadding_1ka2b_1{width:100%;box-sizing:border-box;background-color:var(--lmnt-theme-secondary-50)}._bottomBorder_1ka2b_7{border-top:1px solid var(--lmnt-theme-secondary-100);border-bottom:1px solid var(--lmnt-theme-secondary-100)}._standaloneBorder_1ka2b_12{border-color:var(--lmnt-theme-secondary-100);border-width:1px;border-style:solid;border-radius:.5rem}
@@ -1 +1 @@
1
- ._modal_mu9y6_1 div[class*=lmnt-modal__surface]{max-height:100svh!important;max-width:100svw!important}._modal_mu9y6_1 div:not([class*=mdc-dialog--fullscreen]) div[class*=lmnt-modal__surface]{border-radius:1rem!important}._modal_mu9y6_1 footer{margin-bottom:0!important}._gap_mu9y6_14{gap:4px!important}._title_mu9y6_18{header{display:flex;justify-content:start;padding-left:.5rem!important;>div{width:100%;margin-left:0!important}}}._titleWithoutCloseIcon_mu9y6_31{margin-left:1rem!important}._closeButton_mu9y6_35{color:var(--lmnt-theme-on-surface-inactive)}._closeButton_mu9y6_35:before{display:none!important}._closeButton_mu9y6_35:hover{background-color:var(--lmnt-theme-surface-variant)!important}
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}
@@ -0,0 +1,25 @@
1
+ export type ErrorBannerProps = {
2
+ title?: string;
3
+ description?: string;
4
+ isOpen?: boolean;
5
+ primaryActionLabel?: string;
6
+ onPrimaryAction?: () => void;
7
+ secondaryActionLabel?: string;
8
+ onSecondaryAction?: () => void;
9
+ isStandalone?: boolean;
10
+ };
11
+ /**
12
+ * Error banner component to display error messages with optional actions.
13
+ * Designed to be used below a header or as a standalone banner in a modal.
14
+ *
15
+ * @param {string} title - Title text displayed in the banner
16
+ * @param {string} description - Description text displayed below the title
17
+ * @param {boolean} isOpen - Controls the open/visible state of the banner
18
+ * @param {string} primaryActionLabel - Label for the primary action button. If not provided, button will not be rendered.
19
+ * @param {() => void} onPrimaryAction - Handler for the primary action button
20
+ * @param {string} secondaryActionLabel - Label for the secondary action button. If not provided, button will not be rendered.
21
+ * @param {() => void} onSecondaryAction - Handler for the secondary action button
22
+ * @param {boolean} isStandalone - When true, renders the banner with a rounded border instead of a bottom border
23
+ * @returns {JSX.Element|null} The rendered ErrorBanner component or null if not visible
24
+ */
25
+ export declare const ErrorBanner: ({ title, description, isOpen, isStandalone, ...props }: ErrorBannerProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,70 @@
1
+ import { jsx as r, jsxs as o } from "react/jsx-runtime";
2
+ import { B as c } from "../../index.es-B19PQgzU.js";
3
+ import { G as t } from "../../index.es-Z0aF-7Cn.js";
4
+ import { P as f } from "../../index.es-DgncYOqO.js";
5
+ import { T as u, a as b } from "../../index.es-DUrjyxNI.js";
6
+ import { c as h } from "../../index-Df2FYN-K.js";
7
+ import { useContainerWidth as B } from "../../hooks/useContainerWidth.js";
8
+ import { Iconify as g } from "../Iconify/Iconify.js";
9
+ import '../../assets/ErrorBanner.css';const y = "_bannerPadding_1ka2b_1", _ = "_bottomBorder_1ka2b_7", P = "_standaloneBorder_1ka2b_12", s = {
10
+ bannerPadding: y,
11
+ bottomBorder: _,
12
+ standaloneBorder: P
13
+ }, E = ({
14
+ title: n,
15
+ description: a,
16
+ isOpen: e,
17
+ isStandalone: i,
18
+ ...d
19
+ }) => {
20
+ const { ref: m, isWide: l } = B(), p = h(
21
+ s.bannerPadding,
22
+ i ? s.standaloneBorder : s.bottomBorder
23
+ );
24
+ return e ? /* @__PURE__ */ r(f, { customPadding: "0.5rem 1rem", className: p, "data-testid": "error-banner", children: /* @__PURE__ */ o(
25
+ t,
26
+ {
27
+ ref: m,
28
+ fullWidth: !0,
29
+ direction: l ? "horizontal" : "vertical",
30
+ secondaryAlign: "center",
31
+ children: [
32
+ /* @__PURE__ */ o(t, { fullWidth: !0, primaryAlign: "space-between", secondaryAlign: l ? "center" : "start", children: [
33
+ /* @__PURE__ */ r(g, { icon: "sentiment-very-dissatisfied", iconSize: "large", variant: "color-primary" }),
34
+ /* @__PURE__ */ o(t, { direction: "vertical", fullWidth: !0, gap: "none", children: [
35
+ /* @__PURE__ */ r(u, { bold: !0, level: 2, themeColor: "primary", children: n }),
36
+ /* @__PURE__ */ r(b, { children: a })
37
+ ] })
38
+ ] }),
39
+ /* @__PURE__ */ r(v, { ...d, isWide: l })
40
+ ]
41
+ }
42
+ ) }) : null;
43
+ }, v = ({
44
+ primaryActionLabel: n,
45
+ onPrimaryAction: a,
46
+ secondaryActionLabel: e,
47
+ onSecondaryAction: i,
48
+ isWide: d
49
+ }) => /* @__PURE__ */ o(t, { fullWidth: !d, primaryAlign: "end", secondaryAlign: "center", children: [
50
+ n && /* @__PURE__ */ r(
51
+ c,
52
+ {
53
+ label: n,
54
+ onClick: a,
55
+ "data-testid": "error-banner-primary-action"
56
+ }
57
+ ),
58
+ e && /* @__PURE__ */ r(
59
+ c,
60
+ {
61
+ label: e,
62
+ variant: "outlined",
63
+ onClick: i,
64
+ "data-testid": "error-banner-secondary-action"
65
+ }
66
+ )
67
+ ] });
68
+ export {
69
+ E as ErrorBanner
70
+ };
@@ -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 {};