jcicl 1.1.5 → 1.2.2

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 (49) hide show
  1. package/Button/Button.d.ts +1 -0
  2. package/Button/Button.js +73 -70
  3. package/DesktopStepper/DesktopStepper.d.ts +24 -0
  4. package/DesktopStepper/DesktopStepper.js +204 -0
  5. package/DesktopStepper/index.d.ts +1 -0
  6. package/DesktopStepper/index.js +5 -0
  7. package/FieldGroup/FieldGroup.js +15 -12
  8. package/FieldVisibilityWrapper/FieldVisibilityWrapper.d.ts +11 -0
  9. package/FieldVisibilityWrapper/FieldVisibilityWrapper.js +48 -0
  10. package/FieldVisibilityWrapper/index.d.ts +1 -0
  11. package/FieldVisibilityWrapper/index.js +4 -0
  12. package/FormContext/createFormContext.js +91 -72
  13. package/FormContext/types.d.ts +8 -0
  14. package/FormFields/FormFields.d.ts +2 -2
  15. package/FormFields/FormFields.js +18 -18
  16. package/FormInput/FormInput.d.ts +4 -0
  17. package/FormInput/FormInput.js +39 -14
  18. package/LabeledCheckbox/LabeledCheckbox.js +4 -4
  19. package/LabeledCurrencyInput/LabeledCurrencyInput.js +33 -33
  20. package/LabeledInput/LabeledInput.d.ts +2 -0
  21. package/LabeledInput/LabeledInput.js +16 -14
  22. package/LabeledRadio/LabeledRadio.js +12 -12
  23. package/Nav/Nav.js +174 -151
  24. package/SelectableItemCard/SelectableItemCard.d.ts +9 -0
  25. package/SelectableItemCard/SelectableItemCard.js +24 -0
  26. package/SelectableItemCard/index.d.ts +1 -0
  27. package/SelectableItemCard/index.js +4 -0
  28. package/Stepper/Stepper.js +184 -226
  29. package/Table/Table.js +236 -234
  30. package/Tabs/Tabs.d.ts +42 -0
  31. package/Tabs/Tabs.js +121 -0
  32. package/Tabs/index.d.ts +1 -0
  33. package/Tabs/index.js +4 -0
  34. package/api.d.ts +16 -5
  35. package/api.js +42 -28
  36. package/assets/style.css +1 -1
  37. package/assets/tailwind.css +2 -2
  38. package/constants.js +1 -1
  39. package/formatters.d.ts +1 -0
  40. package/formatters.js +30 -17
  41. package/index.d.ts +2 -0
  42. package/index.js +64 -62
  43. package/package.json +1 -1
  44. package/problemDetails.d.ts +20 -0
  45. package/problemDetails.js +19 -0
  46. package/utils.d.ts +2 -2
  47. package/utils.js +35 -29
  48. package/validators.d.ts +8 -0
  49. package/validators.js +19 -9
package/index.js CHANGED
@@ -4,7 +4,7 @@ import { Button as m } from "./Button/Button.js";
4
4
  import { ChevronOval as x } from "./ChevronOval/ChevronOval.js";
5
5
  import { Divider as s } from "./Divider/Divider.js";
6
6
  import { Flex as d } from "./Flex/Flex.js";
7
- import { FormFieldCheckboxContainer as u, FormFieldGrid as C, FormSection as c, FormSectionTitle as h, FormSubsectionTitle as T, FormSubtitle as A, FormTextLine as F } from "./FormComponents/FormComponents.js";
7
+ import { FormFieldCheckboxContainer as u, FormFieldGrid as C, FormSection as c, FormSectionTitle as T, FormSubsectionTitle as h, FormSubtitle as A, FormTextLine as F } from "./FormComponents/FormComponents.js";
8
8
  import { Grid as S } from "./Grid/Grid.js";
9
9
  import { default as g } from "./Icon/Icon.js";
10
10
  import { Input as D } from "./Input/Input.js";
@@ -23,59 +23,60 @@ import { default as Z } from "./List/List.js";
23
23
  import { default as $ } from "./LogoLoop/LogoLoop.js";
24
24
  import { default as ro } from "./Pagination/Pagination.js";
25
25
  import { SiteBanner as to } from "./SiteBanner/SiteBanner.js";
26
- import { Tooltip as fo } from "./Tooltip/Tooltip.js";
27
- import { default as po } from "./WithLabel/WithLabel.js";
28
- import { default as io } from "./WithLoading/WithLoading.js";
29
- import { Card as lo, CardBody as no, CardHeader as uo, CiwaCowsSummary as Co, SectionTitle as co, VitalsDisplay as ho } from "./RecordCard/RecordCard.js";
30
- import { ClientMatchCard as Ao } from "./ClientMatchCard/ClientMatchCard.js";
31
- import { ExpandableSection as Lo } from "./ExpandableSection/ExpandableSection.js";
32
- import { default as bo } from "./Toast/Toast.js";
33
- import { Toaster as vo } from "./Toast/Toaster.js";
34
- import { handleDismissToast as Io, saveToastForRedirect as Po, showSavedToast as yo, showToast as Bo } from "./Toast/ToastHelpers.js";
35
- import { useToast as Eo } from "./Toast/useToast.js";
36
- import { useRedirectToast as Wo } from "./Toast/useRedirectToast.js";
37
- import { formatDateDisplay as Mo, formatPhone as Ro, formatSsnLast4 as Vo, normalizePhone as ko } from "./format.js";
38
- import { A as No } from "./.chunks/AppHeader.js";
39
- import { EditableInfoCard as jo } from "./EditableInfoCard/EditableInfoCard.js";
40
- import { default as Jo } from "./FieldGroup/FieldGroup.js";
41
- import { Nav as Qo } from "./Nav/Nav.js";
42
- import { default as Xo } from "./LoginPage/LoginPage.js";
43
- import { default as Zo } from "./AppContainer/AppContainer.js";
44
- import { default as $o } from "./DataPage/DataPage.js";
26
+ import { Tabs as fo } from "./Tabs/Tabs.js";
27
+ import { Tooltip as po } from "./Tooltip/Tooltip.js";
28
+ import { default as io } from "./WithLabel/WithLabel.js";
29
+ import { default as lo } from "./WithLoading/WithLoading.js";
30
+ import { Card as uo, CardBody as Co, CardHeader as co, CiwaCowsSummary as To, SectionTitle as ho, VitalsDisplay as Ao } from "./RecordCard/RecordCard.js";
31
+ import { ClientMatchCard as Lo } from "./ClientMatchCard/ClientMatchCard.js";
32
+ import { ExpandableSection as bo } from "./ExpandableSection/ExpandableSection.js";
33
+ import { default as vo } from "./Toast/Toast.js";
34
+ import { Toaster as Io } from "./Toast/Toaster.js";
35
+ import { handleDismissToast as yo, saveToastForRedirect as Bo, showSavedToast as wo, showToast as Eo } from "./Toast/ToastHelpers.js";
36
+ import { useToast as Wo } from "./Toast/useToast.js";
37
+ import { useRedirectToast as Mo } from "./Toast/useRedirectToast.js";
38
+ import { formatDateDisplay as Vo, formatPhone as ko, formatSsnLast4 as zo, normalizePhone as No } from "./format.js";
39
+ import { A as jo } from "./.chunks/AppHeader.js";
40
+ import { EditableInfoCard as Jo } from "./EditableInfoCard/EditableInfoCard.js";
41
+ import { default as Qo } from "./FieldGroup/FieldGroup.js";
42
+ import { Nav as Xo } from "./Nav/Nav.js";
43
+ import { default as Zo } from "./LoginPage/LoginPage.js";
44
+ import { default as $o } from "./AppContainer/AppContainer.js";
45
+ import { default as rr } from "./DataPage/DataPage.js";
45
46
  import "react";
46
- import { default as rr } from "./DefaultTemplate/DefaultTemplate.js";
47
- import { AuthContext as tr, AuthProvider as ar, useAuthContext as fr } from "./AuthContext/AuthProvider.js";
48
- import { createMsalInstance as pr } from "./AuthContext/msalConfig.js";
49
- import { AuthenticatedApiClient as ir } from "./AuthenticatedApiClient.js";
47
+ import { default as tr } from "./DefaultTemplate/DefaultTemplate.js";
48
+ import { AuthContext as fr, AuthProvider as mr, useAuthContext as pr } from "./AuthContext/AuthProvider.js";
49
+ import { createMsalInstance as ir } from "./AuthContext/msalConfig.js";
50
+ import { AuthenticatedApiClient as lr } from "./AuthenticatedApiClient.js";
50
51
  export {
51
52
  j as Accordion,
52
- Zo as AppContainer,
53
- No as AppHeader,
54
- tr as AuthContext,
55
- ar as AuthProvider,
56
- ir as AuthenticatedApiClient,
53
+ $o as AppContainer,
54
+ jo as AppHeader,
55
+ fr as AuthContext,
56
+ mr as AuthProvider,
57
+ lr as AuthenticatedApiClient,
57
58
  a as AvatarWithImage,
58
59
  m as Button,
59
- lo as Card,
60
- no as CardBody,
61
- uo as CardHeader,
60
+ uo as Card,
61
+ Co as CardBody,
62
+ co as CardHeader,
62
63
  x as ChevronOval,
63
- Co as CiwaCowsSummary,
64
- Ao as ClientMatchCard,
64
+ To as CiwaCowsSummary,
65
+ Lo as ClientMatchCard,
65
66
  k as CustomAlert,
66
- $o as DataPage,
67
- rr as DefaultTemplate,
67
+ rr as DataPage,
68
+ tr as DefaultTemplate,
68
69
  s as Divider,
69
- jo as EditableInfoCard,
70
+ Jo as EditableInfoCard,
70
71
  J as ErrorBoundary,
71
- Lo as ExpandableSection,
72
- Jo as FieldGroup,
72
+ bo as ExpandableSection,
73
+ Qo as FieldGroup,
73
74
  d as Flex,
74
75
  u as FormFieldCheckboxContainer,
75
76
  C as FormFieldGrid,
76
77
  c as FormSection,
77
- h as FormSectionTitle,
78
- T as FormSubsectionTitle,
78
+ T as FormSectionTitle,
79
+ h as FormSubsectionTitle,
79
80
  A as FormSubtitle,
80
81
  F as FormTextLine,
81
82
  S as Grid,
@@ -87,32 +88,33 @@ export {
87
88
  Z as List,
88
89
  B as ListButton,
89
90
  E as Loading,
90
- Xo as LoginPage,
91
+ Zo as LoginPage,
91
92
  $ as LogoLoop,
92
- Qo as Nav,
93
+ Xo as Nav,
93
94
  ro as Pagination,
94
95
  W as ScrollContainer,
95
- co as SectionTitle,
96
+ ho as SectionTitle,
96
97
  to as SiteBanner,
97
- bo as Toast,
98
- vo as Toaster,
99
- fo as Tooltip,
100
- ho as VitalsDisplay,
101
- po as WithLabel,
102
- io as WithLoading,
98
+ fo as Tabs,
99
+ vo as Toast,
100
+ Io as Toaster,
101
+ po as Tooltip,
102
+ Ao as VitalsDisplay,
103
+ io as WithLabel,
104
+ lo as WithLoading,
103
105
  M as createDobToAgeExtension,
104
106
  R as createFormContext,
105
- pr as createMsalInstance,
106
- Mo as formatDateDisplay,
107
- Ro as formatPhone,
108
- Vo as formatSsnLast4,
109
- Io as handleDismissToast,
110
- ko as normalizePhone,
111
- Po as saveToastForRedirect,
112
- yo as showSavedToast,
113
- Bo as showToast,
114
- fr as useAuthContext,
107
+ ir as createMsalInstance,
108
+ Vo as formatDateDisplay,
109
+ ko as formatPhone,
110
+ zo as formatSsnLast4,
111
+ yo as handleDismissToast,
112
+ No as normalizePhone,
113
+ Bo as saveToastForRedirect,
114
+ wo as showSavedToast,
115
+ Eo as showToast,
116
+ pr as useAuthContext,
115
117
  N as useCustomAlert,
116
- Wo as useRedirectToast,
117
- Eo as useToast
118
+ Mo as useRedirectToast,
119
+ Wo as useToast
118
120
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jcicl",
3
3
  "private": false,
4
- "version": "1.1.5",
4
+ "version": "1.2.2",
5
5
  "description": "Component library for the websites of Johnson County Iowa",
6
6
  "license": "MIT",
7
7
  "homepage": "https://devops.jc.net/JCIT/Business%20Solutions%20Delivery/_git/JCComponentLibrary?path=%2FREADME.md&version=GBmaster",
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Helpers for consuming an RFC 7807 / 9457 ProblemDetails error body — specifically the
3
+ * `errors` map produced by ASP.NET Core ValidationProblemDetails (field key → messages).
4
+ */
5
+ /**
6
+ * The first non-empty message from a ProblemDetails `errors` map, or undefined if there is none.
7
+ * Useful as a human-readable fallback when the body has no `detail`/`title` (e.g. ValidationProblemDetails).
8
+ */
9
+ export declare function firstProblemMessage(errors: Record<string, string[]> | undefined): string | undefined;
10
+ /**
11
+ * Flatten a ProblemDetails `errors` map (field → messages) into a single message per field,
12
+ * keyed for direct use as a form's field errors (e.g. `setFieldErrors` on a jcicl form context).
13
+ *
14
+ * @param errors - The `errors` map from `ApiResponse.error.errors`.
15
+ * @param keyOverrides - Optional server-key → form-key remap, for when the backend emits keys that
16
+ * don't match the form's field keys (e.g. nested `"address.city"` → `"city"`). When a server key
17
+ * has no override it is used as-is.
18
+ * @returns A `Record<formKey, message>` with the first message for each field. Empty if no errors.
19
+ */
20
+ export declare function mapProblemDetailsErrors(errors: Record<string, string[]> | undefined, keyOverrides?: Record<string, string>): Record<string, string>;
@@ -0,0 +1,19 @@
1
+ function l(o) {
2
+ var t;
3
+ return o ? (t = Object.values(o).find((n) => n == null ? void 0 : n.length)) == null ? void 0 : t[0] : void 0;
4
+ }
5
+ function r(o, t) {
6
+ if (!o) return {};
7
+ const n = {};
8
+ for (const [f, c] of Object.entries(o)) {
9
+ const u = c == null ? void 0 : c[0];
10
+ if (!u) continue;
11
+ const i = (t == null ? void 0 : t[f]) ?? f;
12
+ n[i] = u;
13
+ }
14
+ return n;
15
+ }
16
+ export {
17
+ l as firstProblemMessage,
18
+ r as mapProblemDetailsErrors
19
+ };
package/utils.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { states } from './constants';
2
- export { isValidEmail, isValidPhoneNumber, isValidZipCode, isValidCityName, isValidSSN } from './validators';
3
- export { formatDate, formatDateTime, formatPhoneNumber, formatZipCode, formatSSN, formatAddress, formatTimestamp, formattersByType, type FormatterFunction, } from './formatters';
2
+ export { isValidEmail, isValidPhoneNumber, isValidZipCode, isValidCityName, isValidSSN, inputValidatorsByType, validateEmail, validatePhoneNumber, validateSSN, validateZipCode, type InputValidationFunction, } from './validators';
3
+ export { formatDate, formatDateTime, formatPhoneNumber, formatZipCode, formatSSN, formatCurrency, formatAddress, formatTimestamp, formattersByType, type FormatterFunction, } from './formatters';
4
4
  export { maskSSN, defaultMasker, maskersByType, type MaskerFunction } from './maskers';
5
5
  /** A collection of input types that can be either formatted or masked, 'text' is also included so that custom maskers/formatters can be applied */
6
6
  export declare const formattedOrMaskedTypes: Set<string>;
package/utils.js CHANGED
@@ -1,42 +1,48 @@
1
- import s from "./theme.js";
1
+ import m from "./theme.js";
2
2
  import { formattersByType as i } from "./formatters.js";
3
- import { formatAddress as S, formatDate as T, formatDateTime as g, formatPhoneNumber as k, formatSSN as D, formatTimestamp as M, formatZipCode as N } from "./formatters.js";
4
- import { maskersByType as f } from "./maskers.js";
5
- import { defaultMasker as V, maskSSN as C } from "./maskers.js";
6
- import { states as j } from "./constants.js";
7
- import { isValidCityName as A, isValidEmail as B, isValidPhoneNumber as F, isValidSSN as I, isValidZipCode as P } from "./validators.js";
8
- import { u as m } from "./.chunks/useMediaQuery.js";
9
- const c = /* @__PURE__ */ new Set([
3
+ import { formatAddress as x, formatCurrency as N, formatDate as T, formatDateTime as g, formatPhoneNumber as k, formatSSN as D, formatTimestamp as M, formatZipCode as V } from "./formatters.js";
4
+ import { maskersByType as l } from "./maskers.js";
5
+ import { defaultMasker as C, maskSSN as v } from "./maskers.js";
6
+ import { states as O } from "./constants.js";
7
+ import { inputValidatorsByType as Z, isValidCityName as j, isValidEmail as z, isValidPhoneNumber as A, isValidSSN as E, isValidZipCode as F, validateEmail as I, validatePhoneNumber as Y, validateSSN as $, validateZipCode as Q } from "./validators.js";
8
+ import { u as s } from "./.chunks/useMediaQuery.js";
9
+ const u = /* @__PURE__ */ new Set([
10
10
  ...Object.keys(i),
11
- ...Object.keys(f),
11
+ ...Object.keys(l),
12
12
  "text"
13
- ]), u = () => m(`(max-width: ${s.screenSizes.mobile})`), y = () => m(`(max-width: ${s.screenSizes.tablet})`), x = (e) => {
13
+ ]), c = () => s(`(max-width: ${m.screenSizes.mobile})`), y = () => s(`(max-width: ${m.screenSizes.tablet})`), S = (e) => {
14
14
  e = e.slice(0, 10) + "T00:00:00";
15
- const t = /* @__PURE__ */ new Date(), o = new Date(e);
16
- let r = t.getFullYear() - o.getFullYear();
17
- const a = t.getMonth() - o.getMonth();
18
- return (a < 0 || a === 0 && t.getDate() < o.getDate()) && r--, r;
15
+ const t = /* @__PURE__ */ new Date(), a = new Date(e);
16
+ let o = t.getFullYear() - a.getFullYear();
17
+ const r = t.getMonth() - a.getMonth();
18
+ return (r < 0 || r === 0 && t.getDate() < a.getDate()) && o--, o;
19
19
  };
20
20
  export {
21
- x as calculateAge,
22
- V as defaultMasker,
23
- S as formatAddress,
21
+ S as calculateAge,
22
+ C as defaultMasker,
23
+ x as formatAddress,
24
+ N as formatCurrency,
24
25
  T as formatDate,
25
26
  g as formatDateTime,
26
27
  k as formatPhoneNumber,
27
28
  D as formatSSN,
28
29
  M as formatTimestamp,
29
- N as formatZipCode,
30
- c as formattedOrMaskedTypes,
30
+ V as formatZipCode,
31
+ u as formattedOrMaskedTypes,
31
32
  i as formattersByType,
32
- A as isValidCityName,
33
- B as isValidEmail,
34
- F as isValidPhoneNumber,
35
- I as isValidSSN,
36
- P as isValidZipCode,
37
- C as maskSSN,
38
- f as maskersByType,
39
- j as states,
40
- u as useIsMobile,
41
- y as useIsTablet
33
+ Z as inputValidatorsByType,
34
+ j as isValidCityName,
35
+ z as isValidEmail,
36
+ A as isValidPhoneNumber,
37
+ E as isValidSSN,
38
+ F as isValidZipCode,
39
+ v as maskSSN,
40
+ l as maskersByType,
41
+ O as states,
42
+ c as useIsMobile,
43
+ y as useIsTablet,
44
+ I as validateEmail,
45
+ Y as validatePhoneNumber,
46
+ $ as validateSSN,
47
+ Q as validateZipCode
42
48
  };
package/validators.d.ts CHANGED
@@ -1,5 +1,13 @@
1
+ import { FormInputType } from './inputTypes';
1
2
  export declare const isValidEmail: (email: string) => boolean;
2
3
  export declare const isValidPhoneNumber: (phone: string) => boolean;
3
4
  export declare const isValidZipCode: (zip: string) => boolean;
4
5
  export declare const isValidCityName: (city: string) => boolean;
5
6
  export declare const isValidSSN: (ssn: string) => boolean;
7
+ export type InputValidationFunction = (value: string) => string | undefined;
8
+ export declare const validateEmail: InputValidationFunction;
9
+ export declare const validatePhoneNumber: InputValidationFunction;
10
+ export declare const validateSSN: InputValidationFunction;
11
+ export declare const validateZipCode: InputValidationFunction;
12
+ /** Input validation functions that are automatically applied to FormInput based on the type */
13
+ export declare const inputValidatorsByType: Partial<Record<FormInputType, InputValidationFunction>>;
package/validators.js CHANGED
@@ -1,12 +1,22 @@
1
- const i = (e) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e.trim()), n = (e) => {
1
+ const s = (e) => /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(e.trim()), i = (e) => {
2
2
  if (!e) return !1;
3
- const s = e.replace(/\D/g, "");
4
- return !!(e.trim() == s && s.length >= 10 && s.length <= 16 || /^\s*(?:\+?1\s*(?:[-\s]\s*)?)?(?:\(\s*\d{3}\s*\)|\d{3})(?:\s*[-\s]\s*)?\d{3}(?:\s*[-\s]\s*)?\d{4}(?:\s*(?:#|x\.?|ext\.?|extension)\s*\d{1,6})?\s*$/.test(e.trim()));
5
- }, r = (e) => /^\d{5}(?:\s*-?\s*\d{4})?$/.test(e), d = (e) => /^[a-zA-Z\s'.-]+$/.test(e), c = (e) => /^\d{3}-\d{2}-\d{4}$|^\d{9}$/.test(e);
3
+ const t = e.replace(/\D/g, "");
4
+ return !!(e.trim() == t && t.length >= 10 && t.length <= 16 || /^\s*(?:\+?1\s*(?:[-\s]\s*)?)?(?:\(\s*\d{3}\s*\)|\d{3})(?:\s*[-\s]\s*)?\d{3}(?:\s*[-\s]\s*)?\d{4}(?:\s*(?:#|x\.?|ext\.?|extension)\s*\d{1,6})?\s*$/.test(e.trim()));
5
+ }, n = (e) => /^\d{5}(?:\s*-?\s*\d{4})?$/.test(e), m = (e) => /^[a-zA-Z\s'.-]+$/.test(e), a = (e) => /^\d{3}-\d{2}-\d{4}$|^\d{9}$/.test(e), d = (e) => s(e) ? void 0 : "Invalid email format (e.g., name@example.com).", o = (e) => i(e) ? void 0 : "Enter a valid phone number.", r = (e) => a(e) ? void 0 : "SSN must be 9 digits.", l = (e) => n(e) ? void 0 : "Zip code must be 5 or 9 digits.", g = {
6
+ email: d,
7
+ phone: o,
8
+ zip: l,
9
+ ssn: r
10
+ };
6
11
  export {
7
- d as isValidCityName,
8
- i as isValidEmail,
9
- n as isValidPhoneNumber,
10
- c as isValidSSN,
11
- r as isValidZipCode
12
+ g as inputValidatorsByType,
13
+ m as isValidCityName,
14
+ s as isValidEmail,
15
+ i as isValidPhoneNumber,
16
+ a as isValidSSN,
17
+ n as isValidZipCode,
18
+ d as validateEmail,
19
+ o as validatePhoneNumber,
20
+ r as validateSSN,
21
+ l as validateZipCode
12
22
  };