@axos-web-dev/shared-components 2.0.0-dev.18-apy → 2.0.0-dev.19

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 (46) hide show
  1. package/README.md +111 -111
  2. package/dist/Avatar/Avatar.module.js +7 -7
  3. package/dist/Blockquote/Blockquote.module.js +3 -3
  4. package/dist/Calculators/ApyCalculator/ApyCalculator.css.d.ts +3 -20
  5. package/dist/Calculators/ApyCalculator/ApyCalculator.css.js +16 -51
  6. package/dist/Calculators/ApyCalculator/index.js +294 -410
  7. package/dist/Carousel/index.js +1 -1
  8. package/dist/FdicCallout/FdicCallout.module.js +2 -2
  9. package/dist/Forms/ApplyNow.js +1 -1
  10. package/dist/Forms/BoatMooringLocation.d.ts +4 -1
  11. package/dist/Forms/BoatMooringLocation.js +89 -8
  12. package/dist/Forms/MortgageRate/MortgageRateForm.js +1 -1
  13. package/dist/Forms/MortgageRate/MortgageRateWatch.js +1 -1
  14. package/dist/Forms/SuccesForm.js +1 -1
  15. package/dist/ImageLink/ImageLink.js +1 -1
  16. package/dist/Insight/Featured/CategorySelector.js +1 -1
  17. package/dist/Insight/Featured/Featured.js +1 -1
  18. package/dist/Insight/Featured/Header.js +1 -1
  19. package/dist/Interstitial/Interstitial.module.js +10 -10
  20. package/dist/NavigationMenu/AxosALTS/NavBar.module.js +23 -23
  21. package/dist/NavigationMenu/AxosAdvisor/NavBar.module.js +52 -52
  22. package/dist/NavigationMenu/AxosAdvisorServices/NavBar.module.js +53 -53
  23. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileMenu.module.js +27 -27
  24. package/dist/NavigationMenu/AxosBank/NavBar.module.js +39 -39
  25. package/dist/NavigationMenu/AxosClearing/NavBar.module.js +37 -37
  26. package/dist/NavigationMenu/AxosFiduciary/NavBar.module.js +41 -41
  27. package/dist/NavigationMenu/LaVictoire/NavBar.module.js +37 -37
  28. package/dist/SetContainer/SetContainer.js +1 -1
  29. package/dist/WalnutIframe/wrapper.module.js +3 -3
  30. package/dist/assets/Avatar/Avatar.css +59 -59
  31. package/dist/assets/Blockquote/Blockquote.css +72 -72
  32. package/dist/assets/Calculators/ApyCalculator/ApyCalculator.css +56 -230
  33. package/dist/assets/FdicCallout/FdicCallout.css +48 -48
  34. package/dist/assets/Interstitial/Interstitial.css +142 -142
  35. package/dist/assets/NavigationMenu/AxosALTS/NavBar.css +264 -264
  36. package/dist/assets/NavigationMenu/AxosAdvisor/NavBar.css +609 -609
  37. package/dist/assets/NavigationMenu/AxosAdvisorServices/NavBar.css +630 -630
  38. package/dist/assets/NavigationMenu/AxosBank/MobileMenu/MobileMenu.css +353 -353
  39. package/dist/assets/NavigationMenu/AxosBank/NavBar.css +445 -445
  40. package/dist/assets/NavigationMenu/AxosClearing/NavBar.css +484 -484
  41. package/dist/assets/NavigationMenu/AxosFiduciary/NavBar.css +427 -427
  42. package/dist/assets/NavigationMenu/LaVictoire/NavBar.css +429 -429
  43. package/dist/assets/WalnutIframe/wrapper.css +48 -48
  44. package/dist/assets/utils/optimizeImage/optimizeImage.css +47 -47
  45. package/dist/utils/optimizeImage/optimizeImage.module.js +3 -3
  46. package/package.json +148 -148
@@ -1,443 +1,327 @@
1
1
  "use client";
2
- import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { Button } from "../../Button/Button.js";
4
+ import { button } from "../../Button/Button.css.js";
5
+ import { useState, useCallback, useEffect } from "react";
6
+ import "react-use";
7
+ import { Chevron } from "../../Chevron/index.js";
8
+ import { section_container, content, headerIconBillboard, buttons } from "../../IconBillboard/IconBillboard.css.js";
3
9
  import { useGlobalContext } from "../../Modal/contextApi/store.js";
4
10
  import { getVariant } from "../../utils/getVariant.js";
5
- import { Field, Label, Input, Description, Listbox, ListboxButton, ListboxOptions, ListboxOption } from "@headlessui/react";
6
- import { useState, useCallback, useEffect, useRef } from "react";
7
- import { apy_calculator, section_header, header_theme, mt_8, calculator_section, apy_calculator_form, fieldset, field_row, relative, field_label, field_row_input, field_row_input_error, field_error, label_symbol, percent, listbox_button, chevron_icon, listbox_options, listbox_option, optional_badge, form_disclosure, results_wrapper, result_card, result_section, result_value, scrambling, result_value_label, result_item, result_item_label, result_item_value, container } from "./ApyCalculator.css.js";
8
- const COMPOUNDING_OPTIONS = [
9
- { value: 360, label: "Daily" },
10
- { value: 12, label: "Monthly" },
11
- { value: 4, label: "Quarterly" },
12
- { value: 2, label: "Semi-Annual" },
13
- { value: 1, label: "Yearly" }
14
- ];
15
- const SCRAMBLE_CHARS = "0123456789";
16
- function scrambleCurrency(target, progress) {
17
- const formatted = target.toLocaleString("en-US", {
18
- style: "currency",
19
- currency: "USD"
20
- });
21
- return formatted.split("").map((char) => {
22
- if (char === "$" || char === "," || char === "." || char === "-") {
23
- return char;
24
- }
25
- if (/\d/.test(char)) {
26
- return Math.random() > progress ? SCRAMBLE_CHARS[Math.floor(Math.random() * SCRAMBLE_CHARS.length)] : char;
27
- }
28
- return char;
29
- }).join("");
30
- }
31
- function useScramble(targetValue, duration = 700) {
32
- const [display, setDisplay] = useState(
33
- () => targetValue.toLocaleString("en-US", { style: "currency", currency: "USD" })
34
- );
35
- const [isScrambling, setIsScrambling] = useState(false);
36
- const rafRef = useRef(null);
37
- const startRef = useRef(0);
38
- const prevTarget = useRef(targetValue);
39
- useEffect(() => {
40
- if (prevTarget.current === targetValue) return;
41
- prevTarget.current = targetValue;
42
- setIsScrambling(true);
43
- startRef.current = Date.now();
44
- const tick = () => {
45
- const elapsed = Date.now() - startRef.current;
46
- const progress = Math.min(elapsed / duration, 1);
47
- if (progress < 1) {
48
- setDisplay(scrambleCurrency(targetValue, progress));
49
- rafRef.current = setTimeout(tick, 40);
50
- } else {
51
- setDisplay(
52
- targetValue.toLocaleString("en-US", {
53
- style: "currency",
54
- currency: "USD"
55
- })
56
- );
57
- setIsScrambling(false);
58
- }
59
- };
60
- if (rafRef.current) clearTimeout(rafRef.current);
61
- rafRef.current = setTimeout(tick, 40);
62
- return () => {
63
- if (rafRef.current) clearTimeout(rafRef.current);
64
- };
65
- }, [targetValue, duration]);
66
- return { display, isScrambling };
67
- }
68
- function formatWithCommas(value) {
69
- return value.toLocaleString("en-US");
70
- }
71
- function parseCurrencyInput(raw) {
72
- const digits = raw.replace(/[^0-9]/g, "");
73
- return digits === "" ? 0 : parseInt(digits, 10);
74
- }
11
+ import { apy_calculator, calculator_section, section_header, header_theme, mt_8, apy_calculator_form, pis_0, errorTag, fieldset, field_row, relative, label_symbol, cash, prefix_pad, percent, submit_section, span_12, form_disclosure, marketing, marketingTile, bodyContent, container } from "./ApyCalculator.css.js";
75
12
  const ApyCalculator = ({
76
13
  header,
77
14
  body,
15
+ marketingTiles,
78
16
  disclosure,
79
17
  variant
80
18
  }) => {
81
19
  const { domains } = useGlobalContext();
82
20
  const calculator_variant = getVariant(variant);
83
- const [compoundingOption, setCompoundingOption] = useState(
84
- COMPOUNDING_OPTIONS[0]
85
- );
86
- const compounding = compoundingOption.value;
87
- const getAPR = useCallback(
88
- (apy) => {
89
- return Number.parseFloat(
90
- (((1 + apy / 100) ** (1 / compounding) - 1) * compounding * 100).toFixed(2)
91
- );
92
- },
93
- [compounding]
94
- );
95
- const AXOS_ONE_APY = Number(domains.AXOS_ONE_APY) || 4.21;
96
- const [initialDeposit, setInitialDeposit] = useState(1e4);
97
- const [initialDepositDisplay, setInitialDepositDisplay] = useState(
98
- formatWithCommas(1e4)
99
- );
21
+ const [compounding, setCompounding] = useState(360);
22
+ const getAPR = (apy) => {
23
+ return Number.parseFloat(
24
+ (((1 + apy / 100) ** (1 / compounding) - 1) * compounding * 100).toFixed(
25
+ 2
26
+ )
27
+ );
28
+ };
29
+ const AXOS_ONE_APY = Number(domains.AXOS_ONE_APY);
30
+ const AXOS_ONE_APR = getAPR(AXOS_ONE_APY);
31
+ const [initialDeposit, setInititalDeposit] = useState(1e3);
32
+ const [APR, setAPR] = useState(AXOS_ONE_APR);
100
33
  const [APY, setAPY] = useState(AXOS_ONE_APY);
101
34
  const [months, setMonths] = useState(12);
102
35
  const [monthlyDeposits, setMonthlyDeposits] = useState(100);
103
- const [monthlyDepositsDisplay, setMonthlyDepositsDisplay] = useState(
104
- formatWithCommas(100)
105
- );
106
- const [fieldErrors, setFieldErrors] = useState({});
107
- const handleInitialDepositChange = (e) => {
108
- const raw = e.target.value;
109
- const num = parseCurrencyInput(raw);
110
- setInitialDeposit(num);
111
- setInitialDepositDisplay(num > 0 ? formatWithCommas(num) : "");
36
+ const [endingBalance, setEndingBalance] = useState("");
37
+ const [errors, setErrors] = useState([]);
38
+ const [interestRate, setInterestRate] = useState(0);
39
+ const isValidNumber = (input) => {
40
+ if (typeof input !== "number") {
41
+ return false;
42
+ } else if (input < 0 || Number.isNaN(input)) {
43
+ return false;
44
+ } else return true;
112
45
  };
113
- const handleMonthlyDepositsChange = (e) => {
114
- const raw = e.target.value;
115
- if (raw === "") {
116
- setMonthlyDeposits(0);
117
- setMonthlyDepositsDisplay("");
118
- return;
119
- }
120
- const num = parseCurrencyInput(raw);
121
- setMonthlyDeposits(num);
122
- setMonthlyDepositsDisplay(formatWithCommas(num));
46
+ const isValidAPY = (input) => {
47
+ if (typeof input !== "number") {
48
+ return false;
49
+ } else if (input <= 0 || Number.isNaN(input)) {
50
+ return false;
51
+ } else return true;
123
52
  };
124
- const [endingBalanceRaw, setEndingBalanceRaw] = useState(0);
125
- const [totalDepositsRaw, setTotalDepositsRaw] = useState(0);
126
- const [interestEarnedRaw, setInterestEarnedRaw] = useState(0);
127
- const { display: endingBalanceDisplay, isScrambling: balanceScrambling } = useScramble(endingBalanceRaw);
128
- const { display: totalDepositsDisplay, isScrambling: depositsScrambling } = useScramble(totalDepositsRaw);
129
- const { display: interestEarnedDisplay, isScrambling: interestScrambling } = useScramble(interestEarnedRaw);
130
- const calculate = useCallback(() => {
131
- const newErrors = {};
132
- if (!initialDeposit || initialDeposit <= 0 || Number.isNaN(initialDeposit)) {
133
- newErrors.initialDeposit = "Please enter an amount greater than 0.";
53
+ const convertInterest = useCallback(() => {
54
+ const newInterestRate = 0.01 * APR;
55
+ setInterestRate(newInterestRate);
56
+ }, [APR]);
57
+ useEffect(() => {
58
+ convertInterest();
59
+ }, [convertInterest, interestRate, setInterestRate]);
60
+ const handleCalculate = () => {
61
+ convertInterest();
62
+ let newErrors = [];
63
+ if (!isValidNumber(initialDeposit)) {
64
+ newErrors.push("Initial Deposit must be a positive number.");
134
65
  }
135
- if (!months || months < 1 || Number.isNaN(months)) {
136
- newErrors.months = "Please enter a term of at least 1 month.";
66
+ if (!isValidNumber(months)) {
67
+ newErrors.push("Months must be a positive number.");
137
68
  }
138
- if (monthlyDeposits < 0 || Number.isNaN(monthlyDeposits)) {
139
- newErrors.monthlyDeposits = "Monthly deposit amount cannot be negative.";
69
+ if (!isValidNumber(monthlyDeposits)) {
70
+ newErrors.push("Monthly Deposits must be a positive number.");
140
71
  }
141
- if (!APY || APY <= 0 || Number.isNaN(APY)) {
142
- newErrors.APY = "Please enter a valid APY greater than 0.";
72
+ if (!isValidAPY(APY)) {
73
+ newErrors.push("APY must be a positive number.");
143
74
  }
144
- setFieldErrors(newErrors);
145
- if (Object.keys(newErrors).length > 0) return;
146
- const APR = getAPR(APY);
147
- const interestRate = 0.01 * APR;
148
- let total;
149
- if (compounding === 360) {
150
- total = initialDeposit * Math.pow(1 + interestRate / compounding, 30 * months) + (monthlyDeposits > 0 ? monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, 30 * months) - 1) : 0);
151
- } else if (compounding === 12) {
152
- total = initialDeposit * Math.pow(1 + interestRate / compounding, months) + (monthlyDeposits > 0 ? monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, months) - 1) : 0);
153
- } else if (compounding === 4) {
154
- total = initialDeposit * Math.pow(1 + interestRate / compounding, months / 3) + (monthlyDeposits > 0 ? monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, months / 3) - 1) : 0);
155
- } else if (compounding === 2) {
156
- total = initialDeposit * Math.pow(1 + interestRate / compounding, months / 6) + (monthlyDeposits > 0 ? monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, months / 6) - 1) : 0);
157
- } else if (compounding === 1) {
158
- total = initialDeposit * Math.pow(1 + interestRate, months / 12) + (monthlyDeposits > 0 ? monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, months / 12) - 1) : 0);
75
+ if (!isValidAPY(APR)) {
76
+ newErrors.push("APR must be a positive number.");
77
+ }
78
+ if (newErrors.length > 0) {
79
+ setErrors(newErrors);
159
80
  } else {
160
- total = initialDeposit;
161
- for (let i = 0; i < months; i++) {
162
- total += monthlyDeposits;
163
- total *= Math.pow(1 + interestRate / compounding, compounding / 12);
81
+ newErrors = [];
82
+ setErrors([]);
83
+ let total;
84
+ if (compounding === 360) {
85
+ total = initialDeposit * Math.pow(1 + interestRate / compounding, 30 * months) + monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, 30 * months) - 1);
86
+ } else if (compounding === 12) {
87
+ total = initialDeposit * Math.pow(1 + interestRate / compounding, months) + monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, months) - 1);
88
+ } else if (compounding === 4) {
89
+ total = initialDeposit * Math.pow(1 + interestRate / compounding, months / 3) + monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, months / 3) - 1);
90
+ } else if (compounding === 2) {
91
+ total = initialDeposit * Math.pow(1 + interestRate / compounding, months / 6) + monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, months / 6) - 1);
92
+ } else if (compounding === 1) {
93
+ total = initialDeposit * Math.pow(1 + interestRate, months / 12) + monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, months / 12) - 1);
94
+ } else {
95
+ total = initialDeposit;
96
+ for (let i = 0; i < months; i++) {
97
+ total += monthlyDeposits;
98
+ total *= Math.pow(1 + interestRate / compounding, compounding / 12);
99
+ }
164
100
  }
101
+ setEndingBalance(
102
+ total.toLocaleString("en-US", { style: "currency", currency: "USD" })
103
+ );
165
104
  }
166
- const deposits = initialDeposit + monthlyDeposits * months;
167
- const interest = total - deposits;
168
- setEndingBalanceRaw(total);
169
- setTotalDepositsRaw(deposits);
170
- setInterestEarnedRaw(interest > 0 ? interest : 0);
171
- }, [initialDeposit, APY, months, monthlyDeposits, compounding, getAPR]);
172
- useEffect(() => {
173
- calculate();
174
- }, [calculate]);
175
- return /* @__PURE__ */ jsxs(
176
- "section",
177
- {
178
- className: `${container({ variant: getVariant(variant) })} ${apy_calculator}`,
179
- children: [
180
- (header || body) && /* @__PURE__ */ jsxs("div", { className: `${section_header} containment`, children: [
181
- header && /* @__PURE__ */ jsx(
182
- "h1",
105
+ };
106
+ const updateAPR = (value) => {
107
+ setAPR(value);
108
+ const new_apy = Number.parseFloat(
109
+ (100 * ((1 + value / 100 / compounding) ** compounding - 1)).toFixed(2)
110
+ );
111
+ setAPY(new_apy);
112
+ convertInterest();
113
+ };
114
+ const updateAPY = (value) => {
115
+ setAPY(value);
116
+ const new_apr = getAPR(value);
117
+ setAPR(new_apr);
118
+ convertInterest();
119
+ };
120
+ return /* @__PURE__ */ jsx("section", { className: `${container({ variant: getVariant(variant) })}`, children: /* @__PURE__ */ jsxs("div", { className: `${apy_calculator} containment flex between`, children: [
121
+ /* @__PURE__ */ jsxs("div", { className: `${calculator_section}`, children: [
122
+ (header || body) && /* @__PURE__ */ jsxs("div", { className: `${section_header}`, children: [
123
+ header && /* @__PURE__ */ jsx(
124
+ "h2",
125
+ {
126
+ className: `header_2 ${header_theme({ variant: calculator_variant })}`,
127
+ children: header
128
+ }
129
+ ),
130
+ body && /* @__PURE__ */ jsx("div", { className: mt_8, children: body })
131
+ ] }),
132
+ /* @__PURE__ */ jsxs("form", { id: "calculator_form", className: `${apy_calculator_form}`, children: [
133
+ /* @__PURE__ */ jsx("div", { id: "errmsgbox", className: " flex middle", children: errors.length > 0 && /* @__PURE__ */ jsx("ul", { className: pis_0, children: errors.map((error, index) => /* @__PURE__ */ jsx("li", { className: `${errorTag}`, children: error }, index)) }) }),
134
+ /* @__PURE__ */ jsxs("div", { className: `${fieldset}`, children: [
135
+ /* @__PURE__ */ jsxs("div", { className: `${field_row} ${relative} flex flex_col`, children: [
136
+ /* @__PURE__ */ jsx("label", { className: "input_label", htmlFor: "initDeposit", children: "Initial Deposit" }),
137
+ /* @__PURE__ */ jsx("label", { className: `${label_symbol} ${cash}`, children: "$" }),
138
+ /* @__PURE__ */ jsx(
139
+ "input",
140
+ {
141
+ className: `${prefix_pad} bordered`,
142
+ id: "initDeposit",
143
+ type: "number",
144
+ step: 100,
145
+ name: "initDeposit",
146
+ value: initialDeposit,
147
+ onChange: (e) => setInititalDeposit(parseInt(e.target.value))
148
+ }
149
+ )
150
+ ] }),
151
+ /* @__PURE__ */ jsxs("div", { className: `${field_row} ${relative} flex flex_col`, children: [
152
+ /* @__PURE__ */ jsx("label", { className: "input_label", htmlFor: "apr", children: "APR (Annual Percentage Rate)" }),
153
+ /* @__PURE__ */ jsx("label", { className: `${label_symbol} ${percent}`, children: "%" }),
154
+ /* @__PURE__ */ jsx(
155
+ "input",
156
+ {
157
+ className: `${prefix_pad} bordered`,
158
+ id: "apr",
159
+ type: "number",
160
+ step: 0.01,
161
+ name: "apr",
162
+ value: APR,
163
+ onChange: (e) => updateAPR(parseFloat(e.target.value))
164
+ }
165
+ )
166
+ ] }),
167
+ /* @__PURE__ */ jsxs("div", { className: `${field_row} ${relative} flex flex_col`, children: [
168
+ /* @__PURE__ */ jsx("label", { className: "input_label", htmlFor: "apy", children: "APY (Annual Percentage Yield)" }),
169
+ /* @__PURE__ */ jsx("label", { className: `${label_symbol} ${percent}`, children: "%" }),
170
+ /* @__PURE__ */ jsx(
171
+ "input",
172
+ {
173
+ className: `${prefix_pad} bordered`,
174
+ id: "apy",
175
+ type: "number",
176
+ step: 0.01,
177
+ name: "apy",
178
+ value: APY,
179
+ onChange: (e) => updateAPY(parseFloat(e.target.value))
180
+ }
181
+ )
182
+ ] }),
183
+ /* @__PURE__ */ jsxs("div", { className: `${field_row} ${relative} flex flex_col`, children: [
184
+ /* @__PURE__ */ jsx("label", { className: "input_label", htmlFor: "months", children: "Months" }),
185
+ /* @__PURE__ */ jsx(
186
+ "input",
187
+ {
188
+ className: `${prefix_pad} bordered`,
189
+ id: "months",
190
+ min: 1,
191
+ maxLength: 4,
192
+ type: "number",
193
+ name: "months",
194
+ value: months,
195
+ onChange: (e) => setMonths(parseInt(e.target.value))
196
+ }
197
+ )
198
+ ] }),
199
+ /* @__PURE__ */ jsxs("div", { className: `${field_row} ${relative} flex flex_col`, children: [
200
+ /* @__PURE__ */ jsx("label", { className: "input_label", htmlFor: "compounding", children: "Compounding" }),
201
+ /* @__PURE__ */ jsxs(
202
+ "select",
203
+ {
204
+ className: `${prefix_pad} bordered`,
205
+ id: "compounding",
206
+ name: "compounding",
207
+ value: compounding,
208
+ onChange: (e) => setCompounding(Number(e.target.value)),
209
+ children: [
210
+ /* @__PURE__ */ jsx("option", { value: 360, children: "Daily" }),
211
+ /* @__PURE__ */ jsx("option", { value: 12, children: "Monthly" }),
212
+ /* @__PURE__ */ jsx("option", { value: 4, children: "Quarterly" }),
213
+ /* @__PURE__ */ jsx("option", { value: 2, children: "Semi-Annual" }),
214
+ /* @__PURE__ */ jsx("option", { value: 1, children: "Yearly" })
215
+ ]
216
+ }
217
+ )
218
+ ] }),
219
+ /* @__PURE__ */ jsxs("div", { className: `${field_row} ${relative} flex flex_col`, children: [
220
+ /* @__PURE__ */ jsx("label", { className: "input_label", htmlFor: "monthlyDeposits", children: "Monthly Deposits" }),
221
+ /* @__PURE__ */ jsx("label", { className: `${label_symbol} ${cash}`, children: "$" }),
222
+ /* @__PURE__ */ jsx(
223
+ "input",
224
+ {
225
+ className: `${prefix_pad} bordered`,
226
+ id: "monthlyDeposits",
227
+ maxLength: 25,
228
+ type: "number",
229
+ value: monthlyDeposits,
230
+ name: "monthlyDeposits",
231
+ onChange: (e) => setMonthlyDeposits(parseInt(e.target.value))
232
+ }
233
+ )
234
+ ] }),
235
+ /* @__PURE__ */ jsxs("div", { className: `${field_row} ${relative} flex flex_col`, children: [
236
+ /* @__PURE__ */ jsx("label", { className: "input_label", htmlFor: "endBal", children: "Ending Balance" }),
237
+ /* @__PURE__ */ jsx(
238
+ "input",
239
+ {
240
+ className: `${prefix_pad} bordered`,
241
+ id: "endBal",
242
+ maxLength: 30,
243
+ type: "string",
244
+ readOnly: true,
245
+ name: "endBal",
246
+ value: endingBalance
247
+ }
248
+ )
249
+ ] }),
250
+ /* @__PURE__ */ jsx(
251
+ "div",
183
252
  {
184
- className: `header_1 ${header_theme({ variant: calculator_variant })}`,
185
- children: header
253
+ className: `${submit_section} ${span_12} flex center middle push_up_32`,
254
+ children: /* @__PURE__ */ jsx(
255
+ "input",
256
+ {
257
+ className: `${button({ color: "primary", size: "medium", rounded: "medium" })} center`,
258
+ type: "button",
259
+ value: "Calculate",
260
+ onClick: handleCalculate
261
+ }
262
+ )
186
263
  }
187
264
  ),
188
- body && /* @__PURE__ */ jsx("div", { className: mt_8, children: body })
189
- ] }),
190
- /* @__PURE__ */ jsxs(
191
- "div",
192
- {
193
- className: `${apy_calculator} containment flex between gap_24`,
194
- style: { paddingBlock: "0px" },
195
- children: [
196
- /* @__PURE__ */ jsx("div", { className: `${calculator_section}`, children: /* @__PURE__ */ jsx("form", { id: "calculator_form", className: `${apy_calculator_form}`, children: /* @__PURE__ */ jsxs("div", { className: `${fieldset}`, children: [
197
- /* @__PURE__ */ jsxs(
198
- Field,
199
- {
200
- className: `${field_row} ${relative} flex flex_col`,
201
- style: { marginTop: 0 },
202
- children: [
203
- /* @__PURE__ */ jsx(Label, { className: field_label, children: "Initial Deposit" }),
204
- /* @__PURE__ */ jsx(
205
- Input,
206
- {
207
- className: `${field_row_input} ${fieldErrors.initialDeposit ? ` ${field_row_input_error}` : ""}`,
208
- id: "initDeposit",
209
- type: "text",
210
- inputMode: "numeric",
211
- name: "initDeposit",
212
- value: initialDepositDisplay ? `$${initialDepositDisplay}` : "",
213
- onChange: handleInitialDepositChange,
214
- "aria-invalid": !!fieldErrors.initialDeposit,
215
- "aria-describedby": fieldErrors.initialDeposit ? "initDeposit-error" : void 0
216
- }
217
- ),
218
- fieldErrors.initialDeposit && /* @__PURE__ */ jsx(
219
- Description,
220
- {
221
- as: "span",
222
- id: "initDeposit-error",
223
- className: field_error,
224
- role: "alert",
225
- children: fieldErrors.initialDeposit
226
- }
227
- )
228
- ]
229
- }
230
- ),
231
- /* @__PURE__ */ jsxs(Field, { className: `${field_row} ${relative} flex flex_col`, children: [
232
- /* @__PURE__ */ jsx(Label, { className: field_label, children: "APY (Annual Percentage Yield)" }),
265
+ disclosure && /* @__PURE__ */ jsx("div", { className: `${form_disclosure} push_up_24`, children: disclosure })
266
+ ] })
267
+ ] })
268
+ ] }),
269
+ /* @__PURE__ */ jsx("div", { className: `${marketing} ${section_container}`, children: marketingTiles && marketingTiles?.map(
270
+ ({ id, headline, bodyCopy, callToActionRow }) => /* @__PURE__ */ jsxs(
271
+ "div",
272
+ {
273
+ className: `${container({ variant: getVariant(variant) })} ${marketingTile} rounded bordered`,
274
+ children: [
275
+ /* @__PURE__ */ jsx("div", { className: `${content} ${bodyContent}`, children: /* @__PURE__ */ jsxs(
276
+ "div",
277
+ {
278
+ className: headerIconBillboard,
279
+ style: { textAlign: "left" },
280
+ children: [
233
281
  /* @__PURE__ */ jsx(
234
- "span",
282
+ "div",
235
283
  {
236
- className: `${label_symbol} ${percent}`,
237
- "aria-hidden": "true",
238
- children: "%"
284
+ className: `header_3 ${header_theme({ variant: calculator_variant })}`,
285
+ children: headline
239
286
  }
240
287
  ),
241
- /* @__PURE__ */ jsx(
242
- Input,
243
- {
244
- className: `${field_row_input} ${fieldErrors.APY ? ` ${field_row_input_error}` : ""}`,
245
- id: "apy",
246
- type: "number",
247
- name: "apy",
248
- min: 0,
249
- value: APY,
250
- onChange: (e) => setAPY(parseFloat(e.target.value)),
251
- "aria-invalid": !!fieldErrors.APY,
252
- "aria-describedby": fieldErrors.APY ? "apy-error" : void 0
253
- }
254
- ),
255
- fieldErrors.APY && /* @__PURE__ */ jsx(
256
- Description,
257
- {
258
- as: "span",
259
- id: "apy-error",
260
- className: field_error,
261
- role: "alert",
262
- children: fieldErrors.APY
263
- }
264
- )
265
- ] }),
266
- /* @__PURE__ */ jsxs(Field, { className: `${field_row} ${relative} flex flex_col`, children: [
267
- /* @__PURE__ */ jsx(Label, { className: field_label, children: "Months" }),
268
- /* @__PURE__ */ jsx(
269
- Input,
270
- {
271
- className: `${field_row_input}${fieldErrors.months ? ` ${field_row_input_error}` : ""}`,
272
- id: "months",
273
- min: 1,
274
- type: "number",
275
- name: "months",
276
- value: months,
277
- onChange: (e) => setMonths(parseInt(e.target.value)),
278
- "aria-invalid": !!fieldErrors.months,
279
- "aria-describedby": fieldErrors.months ? "months-error" : void 0
280
- }
281
- ),
282
- fieldErrors.months && /* @__PURE__ */ jsx(
283
- Description,
284
- {
285
- as: "span",
286
- id: "months-error",
287
- className: field_error,
288
- role: "alert",
289
- children: fieldErrors.months
290
- }
291
- )
292
- ] }),
293
- /* @__PURE__ */ jsxs(Field, { className: `${field_row} ${relative} flex flex_col`, children: [
294
- /* @__PURE__ */ jsx(Label, { className: field_label, htmlFor: "compounding", children: "Compounding" }),
295
- /* @__PURE__ */ jsxs(
296
- Listbox,
297
- {
298
- value: compoundingOption,
299
- onChange: setCompoundingOption,
300
- children: [
301
- /* @__PURE__ */ jsxs(
302
- ListboxButton,
303
- {
304
- id: "compounding",
305
- className: `${listbox_button} ${field_row_input}`,
306
- children: [
307
- /* @__PURE__ */ jsx("span", { children: compoundingOption.label }),
308
- /* @__PURE__ */ jsx(
309
- "svg",
310
- {
311
- className: chevron_icon,
312
- xmlns: "http://www.w3.org/2000/svg",
313
- viewBox: "0 0 20 20",
314
- fill: "currentColor",
315
- "aria-hidden": "true",
316
- children: /* @__PURE__ */ jsx(
317
- "path",
318
- {
319
- fillRule: "evenodd",
320
- d: "M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z",
321
- clipRule: "evenodd"
322
- }
323
- )
324
- }
325
- )
326
- ]
327
- }
328
- ),
329
- /* @__PURE__ */ jsx(
330
- ListboxOptions,
331
- {
332
- anchor: "bottom start",
333
- className: listbox_options,
334
- children: COMPOUNDING_OPTIONS.map((opt) => /* @__PURE__ */ jsx(
335
- ListboxOption,
336
- {
337
- value: opt,
338
- className: listbox_option,
339
- children: opt.label
340
- },
341
- opt.value
342
- ))
343
- }
344
- )
345
- ]
346
- }
347
- )
348
- ] }),
349
- /* @__PURE__ */ jsxs(Field, { className: `${field_row} ${relative} flex flex_col`, children: [
350
- /* @__PURE__ */ jsxs(Label, { className: field_label, children: [
351
- "Monthly Deposits",
352
- " ",
353
- /* @__PURE__ */ jsx("span", { className: optional_badge, children: "(optional)" })
354
- ] }),
355
- /* @__PURE__ */ jsx(
356
- Input,
357
- {
358
- className: `${field_row_input} ${fieldErrors.monthlyDeposits ? ` ${field_row_input_error}` : ""}`,
359
- id: "monthlyDeposits",
360
- type: "text",
361
- inputMode: "numeric",
362
- name: "monthlyDeposits",
363
- value: monthlyDepositsDisplay ? `$${monthlyDepositsDisplay}` : "",
364
- placeholder: "0",
365
- onChange: handleMonthlyDepositsChange,
366
- "aria-invalid": !!fieldErrors.monthlyDeposits,
367
- "aria-describedby": fieldErrors.monthlyDeposits ? "monthlyDeposits-error" : void 0
368
- }
369
- ),
370
- fieldErrors.monthlyDeposits && /* @__PURE__ */ jsx(
371
- Description,
372
- {
373
- as: "span",
374
- id: "monthlyDeposits-error",
375
- className: field_error,
376
- role: "alert",
377
- children: fieldErrors.monthlyDeposits
378
- }
379
- )
380
- ] }),
381
- disclosure && /* @__PURE__ */ jsx("div", { className: `${form_disclosure} push_up_24`, children: disclosure })
382
- ] }) }) }),
383
- /* @__PURE__ */ jsx("div", { className: results_wrapper, children: /* @__PURE__ */ jsxs("div", { className: result_card, children: [
384
- /* @__PURE__ */ jsxs(
385
- "div",
386
- {
387
- className: result_section,
388
- "aria-live": "polite",
389
- "aria-atomic": "true",
390
- "aria-label": `Interest earned: ${interestEarnedDisplay}`,
391
- children: [
392
- /* @__PURE__ */ jsx(
393
- "img",
394
- {
395
- src: "https://www.axos.com/images/5IyqVlv7El9K7hAX0vIGWG/axb-25th-growth-lg.png",
396
- alt: "",
397
- height: 135,
398
- className: "img_fluid"
399
- }
400
- ),
401
- /* @__PURE__ */ jsx(
402
- "div",
403
- {
404
- className: `${result_value} ${interestScrambling ? scrambling : ""}`,
405
- children: interestEarnedDisplay
406
- }
407
- ),
408
- /* @__PURE__ */ jsx("div", { className: result_value_label, children: "Interest Earned" })
409
- ]
410
- }
411
- ),
412
- /* @__PURE__ */ jsxs("div", { "aria-live": "polite", "aria-atomic": "true", children: [
413
- /* @__PURE__ */ jsxs("div", { className: result_item, children: [
414
- /* @__PURE__ */ jsx("span", { className: result_item_label, children: "Ending Balance" }),
415
- /* @__PURE__ */ jsx(
416
- "span",
417
- {
418
- className: `${result_item_value} ${balanceScrambling ? scrambling : ""}`,
419
- children: endingBalanceDisplay
420
- }
421
- )
422
- ] }),
423
- /* @__PURE__ */ jsxs("div", { className: result_item, children: [
424
- /* @__PURE__ */ jsx("span", { className: result_item_label, children: "Total Deposits" }),
425
- /* @__PURE__ */ jsx(
426
- "span",
427
- {
428
- className: `${result_item_value} ${depositsScrambling ? scrambling : ""}`,
429
- children: totalDepositsDisplay
430
- }
431
- )
432
- ] })
433
- ] })
434
- ] }) })
435
- ]
436
- }
437
- )
438
- ]
439
- }
440
- );
288
+ /* @__PURE__ */ jsx("div", { children: bodyCopy })
289
+ ]
290
+ }
291
+ ) }),
292
+ callToActionRow && /* @__PURE__ */ jsx("div", { className: `${buttons} middle`, children: callToActionRow.map(
293
+ ({
294
+ id: id2,
295
+ variant: variant2,
296
+ displayText,
297
+ targetUrl,
298
+ type
299
+ }) => type === "Button" ? /* @__PURE__ */ jsx(
300
+ Button,
301
+ {
302
+ targetUrl,
303
+ color: getVariant(variant2),
304
+ size: "medium",
305
+ rounded: "medium",
306
+ children: displayText
307
+ },
308
+ id2
309
+ ) : /* @__PURE__ */ jsx(
310
+ Chevron,
311
+ {
312
+ targetUrl,
313
+ variant: getVariant(variant2),
314
+ children: displayText
315
+ },
316
+ id2
317
+ )
318
+ ) })
319
+ ]
320
+ },
321
+ id
322
+ )
323
+ ) })
324
+ ] }) });
441
325
  };
442
326
  export {
443
327
  ApyCalculator