jcicl 2.0.2 → 4.0.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.
@@ -7,18 +7,22 @@ export type StepProps = {
7
7
  export declare const Step: React.FC<PropsWithChildren<StepProps>>;
8
8
  /** Imperative handle for driving the stepper from a parent (e.g. jumping to a step with errors). */
9
9
  export type DesktopStepperHandle = {
10
- /** Animate to the given step index (clamped to the valid range). */
10
+ /** Animate to the given step index unless validation errors are found during onNext (clamped to the valid range). */
11
11
  goToStep: (index: number) => void;
12
12
  };
13
13
  export type DesktopStepperProps = {
14
14
  onNext?: (step?: number) => boolean;
15
15
  onFinish: () => Promise<void>;
16
16
  onBack?: () => void;
17
+ /** Determines which step titles are clickable. 'next' allows clicking on the next and all previous steps, 'back' allows clicking on previous steps (default), 'all' allows clicking on all steps, and 'none' disables clicking. */
18
+ clickVariant?: 'next' | 'back' | 'all' | 'none';
19
+ submitButtonLabel?: string;
17
20
  /** If true, the stepper will maintain the height of the tallest step. */
18
21
  staticHeight?: boolean;
19
22
  /** Optional imperative handle exposing `goToStep` for programmatic navigation. */
20
23
  ref?: React.Ref<DesktopStepperHandle>;
21
24
  children: React.ReactElement<StepProps>[];
25
+ className?: string;
22
26
  };
23
- declare const DesktopStepper: ({ onNext, onBack, onFinish, staticHeight, ref, children, }: PropsWithChildren<DesktopStepperProps>) => import("react/jsx-runtime").JSX.Element;
27
+ declare const DesktopStepper: ({ onNext, onBack, onFinish, staticHeight, clickVariant, submitButtonLabel, ref, children, className, }: PropsWithChildren<DesktopStepperProps>) => import("react/jsx-runtime").JSX.Element;
24
28
  export default DesktopStepper;
@@ -1,204 +1,245 @@
1
- import { jsx as t, jsxs as p, Fragment as G } from "react/jsx-runtime";
2
- import { useState as y, useRef as N, Children as le, isValidElement as se, useLayoutEffect as oe, useEffect as ie, useCallback as J, useImperativeHandle as ne, Fragment as ce } from "react";
3
- import { flushSync as C } from "react-dom";
4
- import { cn as s } from "../cn.js";
5
- import { Button as K } from "../Button/Button.js";
6
- import { Flex as T } from "../Flex/Flex.js";
7
- import { SlideOut as ae, SlideIn as ue, SlideInReverse as P, SlideOutReverse as de } from "../animation/Slide/Slide.js";
8
- import { useThemeColors as O } from "../ThemeContext.js";
9
- import x from "../theme.js";
10
- import { useIsMobile as U } from "../utils.js";
11
- import { C as me } from "../.chunks/check.js";
12
- const Me = ({ title: i, children: n, className: o }) => /* @__PURE__ */ t("div", { title: i, className: s("p-2.5 w-full", o), children: n }), pe = ({ label: i, number: n, completed: o, active: c }) => {
13
- const h = O(), R = U(), e = {
1
+ import { jsx as l, jsxs as h, Fragment as X } from "react/jsx-runtime";
2
+ import { useState as C, useRef as x, Children as ae, isValidElement as ue, useLayoutEffect as me, useEffect as de, useCallback as L, useImperativeHandle as fe } from "react";
3
+ import { flushSync as Y } from "react-dom";
4
+ import { cn as n } from "../cn.js";
5
+ import { Button as Z } from "../Button/Button.js";
6
+ import { Flex as _ } from "../Flex/Flex.js";
7
+ import { SlideOut as he, SlideIn as pe, SlideInReverse as V, SlideOutReverse as be } from "../animation/Slide/Slide.js";
8
+ import { useThemeColors as A } from "../ThemeContext.js";
9
+ import g from "../theme.js";
10
+ import { useIsMobile as ee } from "../utils.js";
11
+ import { C as ve } from "../.chunks/check.js";
12
+ const _e = ({ children: s, className: i }) => /* @__PURE__ */ l("div", { className: n("p-2.5 w-full", i), children: s }), Ce = ({ label: s, number: i, completed: u, active: c, onClick: m }) => {
13
+ const b = A(), j = ee(), N = {
14
14
  "--item-circle-transition-delay": c ? "0.3s" : "0s",
15
- "--item-circle-border": h.themeColor,
16
- "--item-circle-bg": c || o ? h.themeColor : "transparent",
17
- "--item-circle-color": c || o ? x.colors.white : h.themeColor,
18
- "--label-color": h.themeColor,
19
- "--label-opacity": c ? 1 : 0.7
15
+ "--item-circle-border": b.themeColor,
16
+ "--item-circle-bg": c || u ? b.themeColor : "transparent",
17
+ "--item-circle-color": c || u ? g.colors.white : b.themeColor,
18
+ "--label-color": b.themeColor,
19
+ "--label-opacity": c ? 1 : 0.8,
20
+ "--label-weight": c ? "500" : "400"
20
21
  };
21
- return /* @__PURE__ */ t("div", { style: e, className: s("stepperTitleItem font-medium justify-center items-center"), children: /* @__PURE__ */ p(T, { column: !0, alignItems: "center", gap: "4px", children: [
22
- /* @__PURE__ */ t("div", { className: s("itemCircle", "justify-center flex box-border items-center select-none transition-all duration-300 delay-(--item-circle-transition-delay) ease-in-out w-[35px] h-[35px] mx-[8px] rounded-full border-[2px] border-(--item-circle-border) bg-(--item-circle-bg) text-(--item-circle-color)"), children: o ? /* @__PURE__ */ t(me, { size: 18, strokeWidth: 3 }) : n }),
23
- /* @__PURE__ */ t("div", { className: s("label", "text-(--label-color) text-center opacity-(--label-opacity) transition-[all_0.5s_ease]", R && "px-[5px]"), children: i })
22
+ return /* @__PURE__ */ l("div", { style: N, className: n("stepperTitleItem font-medium justify-center items-center"), children: /* @__PURE__ */ h(_, { column: !0, alignItems: "center", gap: "4px", children: [
23
+ /* @__PURE__ */ l(
24
+ "button",
25
+ {
26
+ type: "button",
27
+ className: n("itemCircle", "font-[inherit] font-medium! justify-center flex box-border items-center select-none transition-all duration-300 delay-(--item-circle-transition-delay) ease-in-out w-[35px] h-[35px] mx-[8px] rounded-full border-[2px] border-(--item-circle-border) bg-(--item-circle-bg) text-(--item-circle-color)", m && "cursor-pointer"),
28
+ onClick: m,
29
+ disabled: !m,
30
+ children: u ? /* @__PURE__ */ l(ve, { size: 18, strokeWidth: 3 }) : i
31
+ }
32
+ ),
33
+ /* @__PURE__ */ l(
34
+ "div",
35
+ {
36
+ className: n("label", "cursor-default text-sm mx-1 text-(--label-color) text-center opacity-(--label-opacity) font-(--label-weight) transition-[all_0.5s_ease]", j && "px-[5px]", m && "cursor-pointer"),
37
+ onClick: m,
38
+ children: s
39
+ }
40
+ )
24
41
  ] }) });
25
- }, he = ({ activated: i }) => {
26
- const n = O(), o = {
27
- "--title-slider-active-color": n.themeColor,
28
- "--title-slider-active-percent": i ? "50%" : "49%",
29
- "--title-slider-inactive-color": n.themeLightA,
30
- "--title-slider-position": i ? "left bottom" : "right bottom"
42
+ }, ge = ({ activated: s }) => {
43
+ const i = A(), u = {
44
+ "--title-slider-active-color": i.themeColor,
45
+ "--title-slider-active-percent": s ? "50%" : "49%",
46
+ "--title-slider-inactive-color": i.themeLightA,
47
+ "--title-slider-position": s ? "left bottom" : "right bottom"
31
48
  };
32
- return /* @__PURE__ */ t("div", { className: s("flex-1 h-[3px] rounded-[2px] self-start mt-[16px] bg-[linear-gradient(to_right,var(--title-slider-active-color)_var(--title-slider-active-percent),var(--title-slider-inactive-color)_50%)] bg-size-[200%_100%] bg-[position:var(--title-slider-position)] transition-background-position duration-500 ease-in-out"), style: o });
33
- }, fe = "relative w-full h-full flex items-center justify-between flex-col gap-[15px] m-0 bg-transparent overflow-hidden", Q = "absolute top-0 w-full h-full", be = "relative w-full [&_.jcSlideContainer]:justify-items-center", Ce = "will-change-[height] transition-[height] duration-500 ease-[cubic-bezier(0.2,0,0,1)]", Ee = ({
34
- onNext: i = () => !0,
35
- onBack: n,
36
- onFinish: o,
49
+ return /* @__PURE__ */ l(
50
+ "div",
51
+ {
52
+ className: n(
53
+ "absolute top-4 left-[calc(50%+25px)] h-0.75 w-[calc(100%-50px)] rounded-sm bg-size-[200%_100%] duration-500 ease-in-out",
54
+ "bg-[linear-gradient(to_right,var(--title-slider-active-color)_var(--title-slider-active-percent),var(--title-slider-inactive-color)_50%)] bg-position-(--title-slider-position)"
55
+ ),
56
+ style: u
57
+ }
58
+ );
59
+ }, Se = "relative w-full h-full flex items-center justify-between flex-col gap-[15px] m-0 bg-transparent overflow-hidden", F = "absolute top-0 w-full h-full", ye = "relative w-full [&_.jcSlideContainer]:justify-items-center", we = "will-change-[height] transition-[height] duration-500 ease-[cubic-bezier(0.2,0,0,1)]", Ae = ({
60
+ onNext: s = () => !0,
61
+ onBack: i,
62
+ onFinish: u,
37
63
  staticHeight: c = !1,
38
- ref: h,
39
- children: R
64
+ clickVariant: m = "back",
65
+ submitButtonLabel: b,
66
+ ref: j,
67
+ children: N,
68
+ className: D
40
69
  }) => {
41
- const [e, w] = y(0), [v, f] = y("forward"), [z, I] = y(null), [B, k] = y(!1), [_, A] = y(!1), D = N(null), L = N([]), M = N(null), g = N(0), d = O(), H = U(), a = le.toArray(R).filter(
42
- (l) => se(l)
43
- ), E = a.map((l) => l.props.title || ""), X = E.some((l) => l !== ""), u = a.length, Y = {
70
+ const [e, te] = C(0), [S, H] = C("forward"), [W, k] = C(null), [T, R] = C(!1), [B, $] = C(!1), q = x(null), G = x([]), M = x(null), O = x(0), d = A(), J = ee(), a = ae.toArray(N).filter(
71
+ (t) => ue(t)
72
+ ), E = a.map((t) => t.props.title || ""), re = E.some((t) => t !== ""), y = a.length, p = e === y - 1, le = {
44
73
  "--progress-bar-bg": d.themeLightA,
45
74
  "--progress-bar-border": d.themeColor,
46
75
  "--progress-bar-color": d.themeColor
47
76
  };
48
- oe(() => {
77
+ me(() => {
49
78
  if (c) {
50
- const $ = L.current, V = () => {
51
- let m = 0;
52
- $.forEach((S) => {
53
- if (S) {
54
- const F = S.getBoundingClientRect().height;
55
- F > m && (m = F);
79
+ const I = G.current, P = () => {
80
+ let f = 0;
81
+ I.forEach((v) => {
82
+ if (v) {
83
+ const U = v.getBoundingClientRect().height;
84
+ U > f && (f = U);
56
85
  }
57
- }), I(m ? Math.ceil(m) : null);
86
+ }), k(f ? Math.ceil(f) : null);
58
87
  };
59
- if (V(), typeof ResizeObserver > "u") return;
60
- const q = [];
61
- return $.forEach((m) => {
62
- if (m) {
63
- const S = new ResizeObserver(V);
64
- S.observe(m), q.push(S);
88
+ if (P(), typeof ResizeObserver > "u") return;
89
+ const Q = [];
90
+ return I.forEach((f) => {
91
+ if (f) {
92
+ const v = new ResizeObserver(P);
93
+ v.observe(f), Q.push(v);
65
94
  }
66
- }), () => q.forEach((m) => m.disconnect());
95
+ }), () => Q.forEach((f) => f.disconnect());
67
96
  }
68
- const l = D.current;
69
- if (!l) return;
97
+ const t = q.current;
98
+ if (!t) return;
70
99
  const r = () => {
71
- I(Math.ceil(l.getBoundingClientRect().height));
100
+ k(Math.ceil(t.getBoundingClientRect().height));
72
101
  };
73
102
  if (r(), typeof ResizeObserver > "u") return;
74
- const b = new ResizeObserver(r);
75
- return b.observe(l), () => b.disconnect();
76
- }, [e, u, c]), ie(() => () => clearTimeout(M.current ?? void 0), []);
77
- const j = J(() => {
78
- A(!0), clearTimeout(M.current ?? void 0), M.current = setTimeout(() => {
79
- A(!1);
103
+ const o = new ResizeObserver(r);
104
+ return o.observe(t), () => o.disconnect();
105
+ }, [e, y, c]), de(() => () => clearTimeout(M.current ?? void 0), []);
106
+ const K = L(() => {
107
+ $(!0), clearTimeout(M.current ?? void 0), M.current = setTimeout(() => {
108
+ $(!1);
80
109
  }, 550);
81
- }, []), Z = async () => {
82
- if (e === u - 1) {
83
- k(!0);
110
+ }, []), w = L(
111
+ (t, r) => {
112
+ K(), O.current = e, Y(() => H("none")), Y(() => H(t)), te(r);
113
+ },
114
+ [K, e]
115
+ ), se = async () => {
116
+ if (p) {
117
+ R(!0);
84
118
  try {
85
- await (o == null ? void 0 : o());
119
+ await (u == null ? void 0 : u());
86
120
  } finally {
87
- k(!1);
121
+ R(!1);
88
122
  }
89
123
  } else {
90
- if (!(i == null ? void 0 : i(e))) {
91
- k(!1);
124
+ if (!(s == null ? void 0 : s(e))) {
125
+ R(!1);
92
126
  return;
93
127
  }
94
- j(), g.current = e, C(() => f("none")), C(() => f("forward")), w((r) => r + 1);
128
+ w("forward", e + 1);
95
129
  }
96
- }, ee = () => {
97
- j(), g.current = e, C(() => f("none")), C(() => f("reverse")), w((l) => l - 1), n == null || n();
98
- }, W = J(
99
- (l) => {
100
- const r = Math.max(0, Math.min(l, u - 1));
101
- if (r === e) return;
102
- j(), g.current = e;
103
- const b = r > e ? "forward" : "reverse";
104
- C(() => f("none")), C(() => f(b)), w(r);
130
+ }, ie = () => {
131
+ w("reverse", e - 1), i == null || i();
132
+ }, z = L(
133
+ (t) => {
134
+ let r = Math.max(0, Math.min(t, y - 1));
135
+ for (let o = e; o > r; o--)
136
+ i == null || i();
137
+ for (let o = e; o < r; o++)
138
+ if (!(s == null ? void 0 : s(o))) {
139
+ r = o;
140
+ break;
141
+ }
142
+ r !== e && w(r > e ? "forward" : "reverse", r);
105
143
  },
106
- [e, u, j]
144
+ [e, y, w, s, i]
107
145
  );
108
- ne(h, () => ({ goToStep: W }), [W]);
109
- const te = () => /* @__PURE__ */ t(
110
- K,
146
+ fe(j, () => ({ goToStep: z }), [z]);
147
+ const oe = () => /* @__PURE__ */ l(
148
+ Z,
111
149
  {
112
150
  variant: "custom",
113
- onClick: Z,
114
- backgroundColor: e === u - 1 ? x.colors.gold : d.themeColor,
115
- hoverColor: e === u - 1 ? x.colors.goldHover : d.themeDark,
116
- textColor: e === u - 1 ? x.colors.black : x.colors.white,
117
- disabled: B,
118
- children: e === u - 1 ? B ? "Submitting..." : "Submit" : "Next"
151
+ onClick: se,
152
+ backgroundColor: p ? g.colors.gold : d.themeColor,
153
+ hoverColor: p ? g.colors.goldHover : d.themeDark,
154
+ textColor: p ? g.colors.black : g.colors.white,
155
+ disabled: T,
156
+ children: p ? T ? "Submitting..." : b || "Submit" : "Next"
119
157
  }
120
- ), re = () => /* @__PURE__ */ t(
121
- K,
158
+ ), ne = () => /* @__PURE__ */ l(
159
+ Z,
122
160
  {
123
161
  variant: "custom",
124
- onClick: ee,
162
+ onClick: ie,
125
163
  backgroundColor: d.themeLight,
126
164
  borderColor: d.themeColor,
127
165
  hoverColor: d.themeMediumB,
128
166
  textColor: d.themeColor,
129
167
  children: "Back"
130
168
  }
131
- );
132
- return /* @__PURE__ */ p(T, { column: !0, justifyContent: "center", gap: "10px", className: s("jcStep"), children: [
133
- /* @__PURE__ */ t(T, { justifyContent: "space-between", width: "90%", className: s("jcDesktopStepHeader", "self-center"), children: E.map((l, r) => /* @__PURE__ */ p(ce, { children: [
134
- /* @__PURE__ */ t(
135
- pe,
169
+ ), ce = (t) => {
170
+ if (!T && !(m === "none" || t === e) && !(m === "back" && t > e) && !(m === "next" && t > e + 1))
171
+ return () => z(t);
172
+ };
173
+ return /* @__PURE__ */ h(_, { column: !0, justifyContent: "center", gap: "10px", className: n("jcStep", D), children: [
174
+ /* @__PURE__ */ l("ol", { className: "m-0 mb-1 flex w-full list-none items-start p-0", children: E.map((t, r) => /* @__PURE__ */ h("li", { className: "relative flex min-w-0 flex-1 flex-col items-center", children: [
175
+ /* @__PURE__ */ l(
176
+ Ce,
136
177
  {
137
- label: l,
178
+ label: t,
138
179
  number: r + 1,
139
180
  completed: r < e,
140
- active: r === e
141
- },
142
- r
181
+ active: r === e,
182
+ onClick: ce(r)
183
+ }
143
184
  ),
144
- r < E.length - 1 && (H !== X || !H) && /* @__PURE__ */ t(he, { activated: r < e })
185
+ r < E.length - 1 && (J !== re || !J) && /* @__PURE__ */ l(ge, { activated: r < e })
145
186
  ] }, r)) }),
146
- /* @__PURE__ */ p("div", { className: s("jcStep", fe), style: Y, children: [
147
- /* @__PURE__ */ p(
187
+ /* @__PURE__ */ h("div", { className: n("jcStep", Se), style: le, children: [
188
+ /* @__PURE__ */ h(
148
189
  "div",
149
190
  {
150
- className: s(be, _ && Ce),
191
+ className: n(ye, B && we),
151
192
  style: {
152
- height: c || z != null && _ ? `${z}px` : "auto"
193
+ height: c || W != null && B ? `${W}px` : "auto"
153
194
  },
154
195
  children: [
155
- c ? /* @__PURE__ */ t(
196
+ c ? /* @__PURE__ */ l(
156
197
  "div",
157
198
  {
158
199
  "aria-hidden": "true",
159
200
  className: "jcStepperMeasure pointer-events-none absolute left-0 top-0 invisible w-full",
160
- children: a.map((l, r) => /* @__PURE__ */ t(
201
+ children: a.map((t, r) => /* @__PURE__ */ l(
161
202
  "div",
162
203
  {
163
- ref: (b) => {
164
- L.current[r] = b;
204
+ ref: (o) => {
205
+ G.current[r] = o;
165
206
  },
166
207
  className: "w-full",
167
- children: l
208
+ children: t
168
209
  },
169
210
  r
170
211
  ))
171
212
  }
172
- ) : /* @__PURE__ */ t(
213
+ ) : /* @__PURE__ */ l(
173
214
  "div",
174
215
  {
175
- ref: D,
216
+ ref: q,
176
217
  "aria-hidden": "true",
177
218
  className: "jcStepperMeasure pointer-events-none absolute left-0 top-0 invisible w-full",
178
219
  children: a[e] ?? null
179
220
  }
180
221
  ),
181
- e === 0 && v === "forward" && /* @__PURE__ */ t("div", { className: s("jcSlideContainer"), children: a[e] ?? null }),
182
- e !== 0 && v === "forward" && /* @__PURE__ */ p(G, { children: [
183
- /* @__PURE__ */ t("div", { className: s("jcSlideOutContainer", Q), children: /* @__PURE__ */ t(ae, { className: "jcSlideContainer", children: a[g.current] ?? null }) }),
184
- /* @__PURE__ */ t(ue, { className: "jcSlideContainer", children: a[e] ?? null })
222
+ e === 0 && S === "forward" && /* @__PURE__ */ l("div", { className: n("jcSlideContainer"), children: a[e] ?? null }),
223
+ e !== 0 && S === "forward" && /* @__PURE__ */ h(X, { children: [
224
+ /* @__PURE__ */ l("div", { className: n("jcSlideOutContainer", F), children: /* @__PURE__ */ l(he, { className: "jcSlideContainer", children: a[O.current] ?? null }) }),
225
+ /* @__PURE__ */ l(pe, { className: "jcSlideContainer", children: a[e] ?? null })
185
226
  ] }),
186
- e === u - 1 && v === "reverse" && /* @__PURE__ */ t(P, { className: "jcSlideContainer", children: a[e] ?? null }),
187
- e !== u - 1 && v === "reverse" && /* @__PURE__ */ p(G, { children: [
188
- /* @__PURE__ */ t("div", { className: s("jcSlideOutContainer", Q), children: /* @__PURE__ */ t(de, { className: "jcSlideContainer", children: a[g.current] ?? null }) }),
189
- /* @__PURE__ */ t(P, { className: "jcSlideContainer", children: a[e] ?? null })
227
+ p && S === "reverse" && /* @__PURE__ */ l(V, { className: "jcSlideContainer", children: a[e] ?? null }),
228
+ !p && S === "reverse" && /* @__PURE__ */ h(X, { children: [
229
+ /* @__PURE__ */ l("div", { className: n("jcSlideOutContainer", F), children: /* @__PURE__ */ l(be, { className: "jcSlideContainer", children: a[O.current] ?? null }) }),
230
+ /* @__PURE__ */ l(V, { className: "jcSlideContainer", children: a[e] ?? null })
190
231
  ] })
191
232
  ]
192
233
  }
193
234
  ),
194
- /* @__PURE__ */ p(T, { gap: "10px", className: "self-end mb-[5px] mr-[5px]", children: [
195
- e !== 0 && re(),
196
- te()
235
+ /* @__PURE__ */ h(_, { gap: "10px", className: "self-end mb-[5px] mr-[5px]", children: [
236
+ e !== 0 && ne(),
237
+ oe()
197
238
  ] })
198
239
  ] })
199
240
  ] });
200
241
  };
201
242
  export {
202
- Me as Step,
203
- Ee as default
243
+ _e as Step,
244
+ Ae as default
204
245
  };
@@ -20,7 +20,8 @@ import "react-dom";
20
20
  import "../Accordion/Accordion.js";
21
21
  import "../ErrorBoundary/ErrorBoundary.js";
22
22
  import "../InfoCard/InfoCard.js";
23
- import "../LabeledInput/LabeledInput.js";
23
+ import "../theme.js";
24
+ import "../labeledFieldStyles.js";
24
25
  import "../List/List.js";
25
26
  import "../LogoLoop/LogoLoop.js";
26
27
  import "../Pagination/Pagination.js";
@@ -35,7 +36,7 @@ import "../Nav/Nav.js";
35
36
  import "../AuthContext/AuthProvider.js";
36
37
  import "../AppContainer/AppContainer.js";
37
38
  import "../DefaultTemplate/DefaultTemplate.js";
38
- const xo = ({
39
+ const Fo = ({
39
40
  title: h,
40
41
  fields: a,
41
42
  columns: w,
@@ -104,5 +105,5 @@ const xo = ({
104
105
  ] });
105
106
  };
106
107
  export {
107
- xo as default
108
+ Fo as default
108
109
  };
@@ -22,5 +22,26 @@ export type FormInputProps = Partial<Omit<AllInputProps, ConflictingKeys | 'type
22
22
  overrideValidation?: boolean;
23
23
  customValidation?: InputValidationFunction;
24
24
  };
25
+ /**
26
+ * The field's validation message, or undefined when it passes. Pure and module-level so it can be
27
+ * exercised directly, and so the component doesn't have to hold it in state: validation is a
28
+ * function of the props, and the useEffect form it replaced cost a second render on every
29
+ * keystroke — callers routinely pass a fresh `customValidation` closure each render, which no
30
+ * dependency array can compare usefully. Computing it inline also lands the error on the same
31
+ * commit as the value rather than one render later.
32
+ *
33
+ * checkbox/radio wrap MUI Checkbox/Radio, which have no helper-text slot, so there's nowhere to
34
+ * surface a message — they're skipped entirely.
35
+ */
36
+ export declare const resolveValidationError: ({ type, value, required, label, showError, overrideValidation, customValidation, }: {
37
+ type: FormInputType;
38
+ value: unknown;
39
+ required?: boolean;
40
+ label?: string;
41
+ showError?: boolean;
42
+ /** Skip the required and type-based rules, applying only `customValidation`. */
43
+ overrideValidation?: boolean;
44
+ customValidation?: InputValidationFunction;
45
+ }) => string | undefined;
25
46
  export declare const FormInput: React.FC<FormInputProps>;
26
47
  export default FormInput;
@@ -1,42 +1,53 @@
1
- import { jsx as o } from "react/jsx-runtime";
2
- import { useState as v, useEffect as E } from "react";
3
- import { LabeledInput as k } from "../LabeledInput/LabeledInput.js";
4
- import { LabeledCurrencyInput as w } from "../LabeledCurrencyInput/LabeledCurrencyInput.js";
5
- import { LabeledCheckbox as I } from "../LabeledCheckbox/LabeledCheckbox.js";
6
- import { LabeledRadio as V } from "../LabeledRadio/LabeledRadio.js";
7
- import { LabeledDropdown as q } from "../LabeledDropdown/LabeledDropdown.js";
8
- import { LabeledTextArea as C } from "../LabeledTextArea/LabeledTextArea.js";
9
- import { LabeledFormattedInput as D } from "../LabeledFormattedInput/LabeledFormattedInput.js";
10
- import { formattedOrMaskedTypes as F } from "../utils.js";
11
- import { inputValidatorsByType as T } from "../validators.js";
12
- const G = (a) => {
13
- const { type: r = "text", required: m, label: l, value: d } = a, { customValidation: s, showError: p, overrideValidation: f = !1, ...e } = a, [y, u] = v(!1), [L, c] = v(void 0), h = r !== "checkbox" && r !== "radio";
14
- E(() => {
15
- if (!p || !h) {
16
- u(!1), c(void 0);
17
- return;
18
- }
19
- const x = d === void 0 || d === "", n = [];
20
- m && !f && n.push(
21
- (t) => t === void 0 || t === "" ? `${l ?? "This field"} is required.` : void 0
22
- ), !f && T[r] && !x && n.push(T[r]), s && !x && n.push(s);
23
- const b = n.map((t) => t(d)).find((t) => t !== void 0);
24
- u(!!b), c(b);
25
- }, [p, d, r, m, l, s, f, h]);
26
- const i = {
27
- error: y || a.error,
28
- helperText: L ?? a.helperText
1
+ import { jsx as t } from "react/jsx-runtime";
2
+ import { LabeledInput as s } from "../LabeledInput/LabeledInput.js";
3
+ import { LabeledDateInput as u } from "../LabeledDateInput/LabeledDateInput.js";
4
+ import { LabeledCurrencyInput as c } from "../LabeledCurrencyInput/LabeledCurrencyInput.js";
5
+ import { LabeledCheckbox as b } from "../LabeledCheckbox/LabeledCheckbox.js";
6
+ import { LabeledRadio as x } from "../LabeledRadio/LabeledRadio.js";
7
+ import { LabeledDropdown as h } from "../LabeledDropdown/LabeledDropdown.js";
8
+ import { LabeledTextArea as L } from "../LabeledTextArea/LabeledTextArea.js";
9
+ import { LabeledFormattedInput as T } from "../LabeledFormattedInput/LabeledFormattedInput.js";
10
+ import { formattedOrMaskedTypes as v } from "../utils.js";
11
+ import { inputValidatorsByType as E } from "../validators.js";
12
+ const I = ({
13
+ type: o,
14
+ value: r,
15
+ required: m,
16
+ label: a,
17
+ showError: p,
18
+ overrideValidation: f = !1,
19
+ customValidation: d
20
+ }) => {
21
+ if (!p || o === "checkbox" || o === "radio") return;
22
+ const n = r === void 0 || r === "";
23
+ if (m && !f && n) return `${a ?? "This field"} is required.`;
24
+ if (n) return;
25
+ const e = f ? void 0 : E[o];
26
+ return (e == null ? void 0 : e(r)) ?? (d == null ? void 0 : d(r));
27
+ }, H = (o) => {
28
+ const { type: r = "text", required: m, label: a, value: p } = o, { customValidation: f, showError: d, overrideValidation: n = !1, ...e } = o, l = I({
29
+ type: r,
30
+ value: p,
31
+ required: m,
32
+ label: a,
33
+ showError: d,
34
+ overrideValidation: n,
35
+ customValidation: f
36
+ }), i = {
37
+ error: !!l || o.error,
38
+ helperText: l ?? o.helperText
29
39
  };
30
- return r === "dropdown" || r === "multiDropdown" ? /* @__PURE__ */ o(q, { ...e, ...i }) : r === "checkbox" ? /* @__PURE__ */ o(I, { ...e }) : r === "radio" ? /* @__PURE__ */ o(V, { ...e }) : r === "currency" ? /* @__PURE__ */ o(w, { ...e, ...i }) : r === "textarea" ? /* @__PURE__ */ o(C, { ...e, ...i }) : F.has(r) ? /* @__PURE__ */ o(
31
- D,
40
+ return r === "dropdown" || r === "multiDropdown" ? /* @__PURE__ */ t(h, { ...e, ...i }) : r === "checkbox" ? /* @__PURE__ */ t(b, { ...e }) : r === "radio" ? /* @__PURE__ */ t(x, { ...e }) : r === "currency" ? /* @__PURE__ */ t(c, { ...e, ...i }) : r === "textarea" ? /* @__PURE__ */ t(L, { ...e, ...i }) : r === "date" ? /* @__PURE__ */ t(u, { ...e, ...i }) : v.has(r) ? /* @__PURE__ */ t(
41
+ T,
32
42
  {
33
43
  ...e,
34
44
  type: r,
35
45
  ...i
36
46
  }
37
- ) : /* @__PURE__ */ o(k, { ...e, type: r, ...i });
47
+ ) : /* @__PURE__ */ t(s, { ...e, type: r, ...i });
38
48
  };
39
49
  export {
40
- G as FormInput,
41
- G as default
50
+ H as FormInput,
51
+ H as default,
52
+ I as resolveValidationError
42
53
  };
@@ -1 +1 @@
1
- export { default, type FormInputProps, type FormInputType } from './FormInput.tsx';
1
+ export { default, resolveValidationError, type FormInputProps, type FormInputType } from './FormInput.tsx';
@@ -1,4 +1,5 @@
1
- import { FormInput as t } from "./FormInput.js";
1
+ import { FormInput as a, resolveValidationError as e } from "./FormInput.js";
2
2
  export {
3
- t as default
3
+ a as default,
4
+ e as resolveValidationError
4
5
  };
@@ -1,8 +1,6 @@
1
1
  import { InputProps } from '../Input';
2
- export interface StyleProps {
3
- grid?: boolean;
4
- displayMode?: boolean;
5
- }
2
+ import { StyleProps } from '../labeledFieldStyles';
3
+ export type { StyleProps };
6
4
  export type LabeledCurrencyInputProps = InputProps & StyleProps & {
7
5
  label: string;
8
6
  noLabel?: boolean;
@@ -0,0 +1,13 @@
1
+ import { InputProps } from '../Input';
2
+ import { StyleProps } from '../labeledFieldStyles';
3
+ export type { StyleProps };
4
+ export type LabeledDateInputProps = InputProps & StyleProps & {
5
+ label?: string;
6
+ noLabel?: boolean;
7
+ /** Earliest selectable date. Takes the `YYYY-MM-DD` a date input expects; widened to match LabeledInput. */
8
+ min?: string | number;
9
+ /** Latest selectable date. Takes the `YYYY-MM-DD` a date input expects; widened to match LabeledInput. */
10
+ max?: string | number;
11
+ };
12
+ export declare const LabeledDateInput: React.FC<LabeledDateInputProps>;
13
+ export default LabeledDateInput;