@axos-web-dev/shared-components 2.0.0-dev.23 → 2.0.0-dev.24

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 (53) hide show
  1. package/dist/ATMLocator/ATMLocator.js +1 -1
  2. package/dist/Auth/ErrorAlert.js +1 -1
  3. package/dist/Button/Button.js +1 -1
  4. package/dist/Calculators/ApyCalculator/ApyCalculator.css.d.ts +5 -45
  5. package/dist/Calculators/ApyCalculator/ApyCalculator.css.js +19 -70
  6. package/dist/Calculators/ApyCalculator/index.js +293 -562
  7. package/dist/Calculators/MarginTradingCalculator/index.js +1 -1
  8. package/dist/Carousel/index.js +2 -2
  9. package/dist/Chevron/index.js +1 -1
  10. package/dist/Comparison/Comparison.js +1 -1
  11. package/dist/ExecutiveBio/ExecutiveBio.js +1 -1
  12. package/dist/FaqAccordion/index.js +1 -1
  13. package/dist/FooterSiteMap/AxosBank/FooterSiteMap.js +1 -1
  14. package/dist/Forms/ApplyNow.js +2 -2
  15. package/dist/Forms/ContactUsBusiness.js +1 -1
  16. package/dist/Forms/ContactUsBusinessNameEmail.js +1 -1
  17. package/dist/Forms/ContactUsNMLSId.js +1 -1
  18. package/dist/Forms/CpraRequest.js +1 -1
  19. package/dist/Forms/CraPublicFile.js +1 -1
  20. package/dist/Forms/EmailOnly.js +1 -1
  21. package/dist/Forms/MortgageRate/MortgageRateForm.js +2 -2
  22. package/dist/Forms/MortgageRate/MortgageRateWatch.js +2 -2
  23. package/dist/Forms/MortgageWarehouseLending.js +1 -1
  24. package/dist/Forms/SuccesForm.js +2 -2
  25. package/dist/Hyperlink/index.js +1 -1
  26. package/dist/ImageLink/ImageLink.js +2 -2
  27. package/dist/ImageLink/ImageLinkSet.js +1 -1
  28. package/dist/ImageLink/index.js +1 -1
  29. package/dist/Insight/Featured/CategorySelector.js +2 -2
  30. package/dist/Insight/Featured/Featured.js +2 -2
  31. package/dist/Insight/Featured/Header.js +2 -2
  32. package/dist/Interstitial/Interstitial.module.js +10 -10
  33. package/dist/Modal/Modal.js +1 -1
  34. package/dist/NavigationMenu/AxosALTS/index.js +1 -1
  35. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileMenu.js +1 -1
  36. package/dist/NavigationMenu/AxosBank/MobileMenu/MobileMenu.module.js +27 -27
  37. package/dist/NavigationMenu/AxosBank/SubNavBar.js +1 -1
  38. package/dist/NavigationMenu/AxosBank/index.js +1 -1
  39. package/dist/NavigationMenu/LaVictoire/index.js +1 -1
  40. package/dist/NavigationMenu/Navbar.js +1 -1
  41. package/dist/NavigationMenu/SignInNavButton.js +1 -1
  42. package/dist/SetContainer/SetContainer.js +2 -2
  43. package/dist/SocialMediaBar/iconsRepository.js +1 -1
  44. package/dist/VideoTile/VideoTile.js +1 -1
  45. package/dist/VideoWrapper/index.js +1 -1
  46. package/dist/assets/Calculators/ApyCalculator/ApyCalculator.css +64 -347
  47. package/dist/assets/DownloadTile/DownloadTile.css +7 -0
  48. package/dist/assets/ImageBillboard/ImageBillboard.css +1 -1
  49. package/dist/assets/Interstitial/Interstitial.css +142 -142
  50. package/dist/assets/NavigationMenu/AxosBank/MobileMenu/MobileMenu.css +353 -353
  51. package/dist/assets/SetContainer/SetContainer.css +3 -0
  52. package/dist/assets/TextBlock/TextBlock.css +7 -0
  53. package/package.json +1 -1
@@ -1,596 +1,327 @@
1
1
  "use client";
2
- import { jsxs, jsx, Fragment } 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 Image from "next/image.js";
6
- import { Field, Label, Input, Description, Listbox, ListboxButton, ListboxOptions, ListboxOption, Disclosure, DisclosureButton, DisclosurePanel } from "@headlessui/react";
7
- import { AnimatePresence, motion } from "framer-motion";
8
- import { useState, useCallback, useEffect, useRef } from "react";
9
- 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_image, result_value, scrambling, result_value_label, result_item, result_item_label, result_item_value, definitions_accordion, definitions_button, definitions_h2, definitions_columns, definitions_panel, definitions_column, definitions_item, definitions_term, definitions_text, container } from "./ApyCalculator.css.js";
10
- const COMPOUNDING_OPTIONS = [
11
- { value: 360, label: "Daily" },
12
- { value: 12, label: "Monthly" },
13
- { value: 4, label: "Quarterly" },
14
- { value: 2, label: "Semi-Annual" },
15
- { value: 1, label: "Yearly" }
16
- ];
17
- const CALCULATOR_DEFINITIONS = [
18
- {
19
- term: "Initial deposit",
20
- description: "The amount of money you're starting with."
21
- },
22
- {
23
- term: "APY (Annual Percentage Yield)",
24
- description: "The rate your money earns in a year, with compounding included."
25
- },
26
- {
27
- term: "Months",
28
- description: "How long you plan to keep your money in the account."
29
- },
30
- {
31
- term: "Compounding",
32
- description: "How often interest is calculated and added to your balance. APY on bank accounts usually compounds monthly."
33
- },
34
- {
35
- term: "Monthly deposits",
36
- description: "Any additional amount you plan to contribute each month."
37
- },
38
- {
39
- term: "Interest earned",
40
- description: "The amount gained from interest over the selected time period."
41
- },
42
- {
43
- term: "Ending balance",
44
- description: "Your projected balance at the end of the selected time period, based on the inputs above."
45
- },
46
- {
47
- term: "Total deposits",
48
- description: "The total money you contribute, including your initial and monthly deposits."
49
- }
50
- ];
51
- const SCRAMBLE_CHARS = "0123456789";
52
- const DEFINITIONS_ITEM_TRANSITION = {
53
- duration: 0.35,
54
- ease: [0.22, 1, 0.36, 1]
55
- };
56
- function scrambleCurrency(target, progress) {
57
- const formatted = target.toLocaleString("en-US", {
58
- style: "currency",
59
- currency: "USD"
60
- });
61
- return formatted.split("").map((char) => {
62
- if (char === "$" || char === "," || char === "." || char === "-") {
63
- return char;
64
- }
65
- if (/\d/.test(char)) {
66
- return Math.random() > progress ? SCRAMBLE_CHARS[Math.floor(Math.random() * SCRAMBLE_CHARS.length)] : char;
67
- }
68
- return char;
69
- }).join("");
70
- }
71
- function useScramble(targetValue, duration = 700) {
72
- const [display, setDisplay] = useState(
73
- () => targetValue.toLocaleString("en-US", { style: "currency", currency: "USD" })
74
- );
75
- const [isScrambling, setIsScrambling] = useState(false);
76
- const rafRef = useRef(null);
77
- const startRef = useRef(0);
78
- const prevTarget = useRef(targetValue);
79
- useEffect(() => {
80
- if (prevTarget.current === targetValue) return;
81
- prevTarget.current = targetValue;
82
- setIsScrambling(true);
83
- startRef.current = Date.now();
84
- const tick = () => {
85
- const elapsed = Date.now() - startRef.current;
86
- const progress = Math.min(elapsed / duration, 1);
87
- if (progress < 1) {
88
- setDisplay(scrambleCurrency(targetValue, progress));
89
- rafRef.current = setTimeout(tick, 40);
90
- } else {
91
- setDisplay(
92
- targetValue.toLocaleString("en-US", {
93
- style: "currency",
94
- currency: "USD"
95
- })
96
- );
97
- setIsScrambling(false);
98
- }
99
- };
100
- if (rafRef.current) clearTimeout(rafRef.current);
101
- rafRef.current = setTimeout(tick, 40);
102
- return () => {
103
- if (rafRef.current) clearTimeout(rafRef.current);
104
- };
105
- }, [targetValue, duration]);
106
- return { display, isScrambling };
107
- }
108
- function formatWithCommas(value) {
109
- return value.toLocaleString("en-US");
110
- }
111
- function parseCurrencyInput(raw) {
112
- const digits = raw.replace(/[^0-9]/g, "");
113
- return digits === "" ? 0 : parseInt(digits, 10);
114
- }
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";
115
12
  const ApyCalculator = ({
116
13
  header,
117
14
  body,
15
+ marketingTiles,
118
16
  disclosure,
119
17
  variant
120
18
  }) => {
121
19
  const { domains } = useGlobalContext();
122
20
  const calculator_variant = getVariant(variant);
123
- const [compoundingOption, setCompoundingOption] = useState(
124
- COMPOUNDING_OPTIONS[0]
125
- );
126
- const compounding = compoundingOption.value;
127
- const getAPR = useCallback(
128
- (apy) => {
129
- return Number.parseFloat(
130
- (((1 + apy / 100) ** (1 / compounding) - 1) * compounding * 100).toFixed(2)
131
- );
132
- },
133
- [compounding]
134
- );
135
- const AXOS_ONE_APY = Number(domains.AXOS_ONE_APY) || 4.21;
136
- const [initialDeposit, setInitialDeposit] = useState(1e4);
137
- const [initialDepositDisplay, setInitialDepositDisplay] = useState(
138
- formatWithCommas(1e4)
139
- );
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);
140
33
  const [APY, setAPY] = useState(AXOS_ONE_APY);
141
- const [APYDisplay, setAPYDisplay] = useState(APY.toString());
142
34
  const [months, setMonths] = useState(12);
143
- const [monthsDisplay, setMonthsDisplay] = useState(months.toString());
144
35
  const [monthlyDeposits, setMonthlyDeposits] = useState(100);
145
- const [monthlyDepositsDisplay, setMonthlyDepositsDisplay] = useState(
146
- formatWithCommas(100)
147
- );
148
- const [fieldErrors, setFieldErrors] = useState({});
149
- const handleInitialDepositChange = (e) => {
150
- const raw = e.target.value;
151
- const num = parseCurrencyInput(raw);
152
- setInitialDeposit(num);
153
- setInitialDepositDisplay(num > 0 ? formatWithCommas(num) : "");
154
- };
155
- const handleMonthlyDepositsChange = (e) => {
156
- const raw = e.target.value;
157
- if (raw === "") {
158
- setMonthlyDeposits(0);
159
- setMonthlyDepositsDisplay("");
160
- return;
161
- }
162
- const num = parseCurrencyInput(raw);
163
- setMonthlyDeposits(num);
164
- setMonthlyDepositsDisplay(formatWithCommas(num));
165
- };
166
- const handleMonthsChange = (e) => {
167
- const raw = e.target.value;
168
- const num = parseInt(raw.replace(/[^0-9]/g, ""), 10);
169
- setMonths(num);
170
- setMonthsDisplay(num > 0 ? num.toString() : "");
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;
171
45
  };
172
- const handleAPYChange = (e) => {
173
- const raw = e.target.value;
174
- const num = parseFloat(raw.replace(/[^0-9.]/g, ""));
175
- setAPY(num);
176
- setAPYDisplay(raw.replace(/[^0-9.]/g, ""));
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;
177
52
  };
178
- const [endingBalanceRaw, setEndingBalanceRaw] = useState(0);
179
- const [totalDepositsRaw, setTotalDepositsRaw] = useState(0);
180
- const [interestEarnedRaw, setInterestEarnedRaw] = useState(0);
181
- const { display: endingBalanceDisplay, isScrambling: balanceScrambling } = useScramble(endingBalanceRaw);
182
- const { display: totalDepositsDisplay, isScrambling: depositsScrambling } = useScramble(totalDepositsRaw);
183
- const { display: interestEarnedDisplay, isScrambling: interestScrambling } = useScramble(interestEarnedRaw);
184
- const midPoint = Math.ceil(CALCULATOR_DEFINITIONS.length / 2);
185
- const leftDefinitions = CALCULATOR_DEFINITIONS.slice(0, midPoint);
186
- const rightDefinitions = CALCULATOR_DEFINITIONS.slice(midPoint);
187
- const calculate = useCallback(() => {
188
- const newErrors = {};
189
- if (!initialDeposit || initialDeposit <= 0 || Number.isNaN(initialDeposit)) {
190
- 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.");
65
+ }
66
+ if (!isValidNumber(months)) {
67
+ newErrors.push("Months must be a positive number.");
191
68
  }
192
- if (!months || months < 1 || Number.isNaN(months)) {
193
- newErrors.months = "Please enter a term of at least 1 month.";
69
+ if (!isValidNumber(monthlyDeposits)) {
70
+ newErrors.push("Monthly Deposits must be a positive number.");
194
71
  }
195
- if (monthlyDeposits < 0 || Number.isNaN(monthlyDeposits)) {
196
- newErrors.monthlyDeposits = "Monthly deposit amount cannot be negative.";
72
+ if (!isValidAPY(APY)) {
73
+ newErrors.push("APY must be a positive number.");
197
74
  }
198
- if (!APY || APY <= 0 || Number.isNaN(APY)) {
199
- newErrors.APY = "Please enter a valid APY greater than 0.";
75
+ if (!isValidAPY(APR)) {
76
+ newErrors.push("APR must be a positive number.");
200
77
  }
201
- setFieldErrors(newErrors);
202
- if (Object.keys(newErrors).length > 0) return;
203
- const APR = getAPR(APY);
204
- const interestRate = 0.01 * APR;
205
- let total;
206
- if (compounding === 360) {
207
- total = initialDeposit * Math.pow(1 + interestRate / compounding, 30 * months) + (monthlyDeposits > 0 ? monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, 30 * months) - 1) : 0);
208
- } else if (compounding === 12) {
209
- total = initialDeposit * Math.pow(1 + interestRate / compounding, months) + (monthlyDeposits > 0 ? monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, months) - 1) : 0);
210
- } else if (compounding === 4) {
211
- total = initialDeposit * Math.pow(1 + interestRate / compounding, months / 3) + (monthlyDeposits > 0 ? monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, months / 3) - 1) : 0);
212
- } else if (compounding === 2) {
213
- total = initialDeposit * Math.pow(1 + interestRate / compounding, months / 6) + (monthlyDeposits > 0 ? monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, months / 6) - 1) : 0);
214
- } else if (compounding === 1) {
215
- total = initialDeposit * Math.pow(1 + interestRate, months / 12) + (monthlyDeposits > 0 ? monthlyDeposits / (interestRate / 12) * (Math.pow(1 + interestRate / compounding, months / 12) - 1) : 0);
78
+ if (newErrors.length > 0) {
79
+ setErrors(newErrors);
216
80
  } else {
217
- total = initialDeposit;
218
- for (let i = 0; i < months; i++) {
219
- total += monthlyDeposits;
220
- 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
+ }
221
100
  }
101
+ setEndingBalance(
102
+ total.toLocaleString("en-US", { style: "currency", currency: "USD" })
103
+ );
222
104
  }
223
- const deposits = initialDeposit + monthlyDeposits * months;
224
- const interest = total - deposits;
225
- setEndingBalanceRaw(total);
226
- setTotalDepositsRaw(deposits);
227
- setInterestEarnedRaw(interest > 0 ? interest : 0);
228
- }, [initialDeposit, APY, months, monthlyDeposits, compounding, getAPR]);
229
- useEffect(() => {
230
- calculate();
231
- }, [calculate]);
232
- return /* @__PURE__ */ jsxs(
233
- "section",
234
- {
235
- className: `${container({ variant: getVariant(variant) })} ${apy_calculator}`,
236
- children: [
237
- (header || body) && /* @__PURE__ */ jsxs("div", { className: `${section_header} containment`, children: [
238
- header && /* @__PURE__ */ jsx(
239
- "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",
240
252
  {
241
- className: `header_1 ${header_theme({ variant: calculator_variant })}`,
242
- 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
+ )
243
263
  }
244
264
  ),
245
- body && /* @__PURE__ */ jsx("div", { className: mt_8, children: body })
246
- ] }),
247
- /* @__PURE__ */ jsxs(
248
- "div",
249
- {
250
- className: `${apy_calculator} flex between`,
251
- style: { paddingBlock: "0px" },
252
- children: [
253
- /* @__PURE__ */ jsx("div", { className: calculator_section, children: /* @__PURE__ */ jsx("form", { id: "calculator_form", className: apy_calculator_form, children: /* @__PURE__ */ jsxs("div", { className: fieldset, children: [
254
- /* @__PURE__ */ jsxs(
255
- Field,
256
- {
257
- className: `${field_row} ${relative} flex flex_col`,
258
- style: { marginTop: 0 },
259
- children: [
260
- /* @__PURE__ */ jsx(Label, { className: field_label, children: "Initial Deposit" }),
261
- /* @__PURE__ */ jsx(
262
- Input,
263
- {
264
- className: `${field_row_input} ${fieldErrors.initialDeposit ? ` ${field_row_input_error}` : ""}`,
265
- id: "initDeposit",
266
- type: "text",
267
- inputMode: "numeric",
268
- name: "initDeposit",
269
- value: initialDepositDisplay ? `$${initialDepositDisplay}` : "",
270
- onChange: handleInitialDepositChange,
271
- "aria-invalid": !!fieldErrors.initialDeposit,
272
- "aria-describedby": fieldErrors.initialDeposit ? "initDeposit-error" : void 0
273
- }
274
- ),
275
- fieldErrors.initialDeposit && /* @__PURE__ */ jsx(
276
- Description,
277
- {
278
- as: "span",
279
- id: "initDeposit-error",
280
- className: field_error,
281
- role: "alert",
282
- children: fieldErrors.initialDeposit
283
- }
284
- )
285
- ]
286
- }
287
- ),
288
- /* @__PURE__ */ jsxs(Field, { className: `${field_row} ${relative} flex flex_col`, children: [
289
- /* @__PURE__ */ jsx(Label, { className: field_label, children: "APY (Annual Percentage Yield)" }),
290
- /* @__PURE__ */ jsx(
291
- "span",
292
- {
293
- className: `${label_symbol} ${percent}`,
294
- "aria-hidden": "true",
295
- children: "%"
296
- }
297
- ),
298
- /* @__PURE__ */ jsx(
299
- Input,
300
- {
301
- className: `${field_row_input} ${fieldErrors.APY ? ` ${field_row_input_error}` : ""}`,
302
- id: "apy",
303
- type: "text",
304
- inputMode: "numeric",
305
- name: "apy",
306
- value: APYDisplay,
307
- onChange: handleAPYChange,
308
- onWheel: (e) => e.currentTarget.blur(),
309
- "aria-invalid": !!fieldErrors.APY,
310
- "aria-describedby": fieldErrors.APY ? "apy-error" : void 0
311
- }
312
- ),
313
- fieldErrors.APY && /* @__PURE__ */ jsx(
314
- Description,
315
- {
316
- as: "span",
317
- id: "apy-error",
318
- className: field_error,
319
- role: "alert",
320
- children: fieldErrors.APY
321
- }
322
- )
323
- ] }),
324
- /* @__PURE__ */ jsxs(Field, { className: `${field_row} ${relative} flex flex_col`, children: [
325
- /* @__PURE__ */ jsx(Label, { className: field_label, children: "Months" }),
326
- /* @__PURE__ */ jsx(
327
- Input,
328
- {
329
- className: `${field_row_input}${fieldErrors.months ? ` ${field_row_input_error}` : ""}`,
330
- id: "months",
331
- min: 1,
332
- type: "text",
333
- inputMode: "numeric",
334
- name: "months",
335
- value: monthsDisplay,
336
- onChange: handleMonthsChange,
337
- "aria-invalid": !!fieldErrors.months,
338
- "aria-describedby": fieldErrors.months ? "months-error" : void 0
339
- }
340
- ),
341
- fieldErrors.months && /* @__PURE__ */ jsx(
342
- Description,
343
- {
344
- as: "span",
345
- id: "months-error",
346
- className: field_error,
347
- role: "alert",
348
- children: fieldErrors.months
349
- }
350
- )
351
- ] }),
352
- /* @__PURE__ */ jsxs(Field, { className: `${field_row} ${relative} flex flex_col`, children: [
353
- /* @__PURE__ */ jsx(Label, { className: field_label, htmlFor: "compounding", children: "Compounding" }),
354
- /* @__PURE__ */ jsxs(
355
- Listbox,
356
- {
357
- value: compoundingOption,
358
- onChange: setCompoundingOption,
359
- children: [
360
- /* @__PURE__ */ jsxs(
361
- ListboxButton,
362
- {
363
- id: "compounding",
364
- className: `${listbox_button} ${field_row_input}`,
365
- children: [
366
- /* @__PURE__ */ jsx("span", { children: compoundingOption.label }),
367
- /* @__PURE__ */ jsx(
368
- "svg",
369
- {
370
- className: chevron_icon,
371
- xmlns: "http://www.w3.org/2000/svg",
372
- viewBox: "0 0 20 20",
373
- fill: "currentColor",
374
- "aria-hidden": "true",
375
- children: /* @__PURE__ */ jsx(
376
- "path",
377
- {
378
- fillRule: "evenodd",
379
- 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",
380
- clipRule: "evenodd"
381
- }
382
- )
383
- }
384
- )
385
- ]
386
- }
387
- ),
388
- /* @__PURE__ */ jsx(
389
- ListboxOptions,
390
- {
391
- anchor: "bottom start",
392
- className: listbox_options,
393
- children: COMPOUNDING_OPTIONS.map((opt) => /* @__PURE__ */ jsx(
394
- ListboxOption,
395
- {
396
- value: opt,
397
- className: listbox_option,
398
- children: opt.label
399
- },
400
- opt.value
401
- ))
402
- }
403
- )
404
- ]
405
- }
406
- )
407
- ] }),
408
- /* @__PURE__ */ jsxs(Field, { className: `${field_row} ${relative} flex flex_col`, children: [
409
- /* @__PURE__ */ jsxs(Label, { className: field_label, children: [
410
- "Monthly Deposits",
411
- " ",
412
- /* @__PURE__ */ jsx("span", { className: optional_badge, children: "(optional)" })
413
- ] }),
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: [
414
281
  /* @__PURE__ */ jsx(
415
- Input,
282
+ "div",
416
283
  {
417
- className: `${field_row_input} ${fieldErrors.monthlyDeposits ? ` ${field_row_input_error}` : ""}`,
418
- id: "monthlyDeposits",
419
- type: "text",
420
- inputMode: "numeric",
421
- name: "monthlyDeposits",
422
- value: monthlyDepositsDisplay ? `$${monthlyDepositsDisplay}` : "",
423
- placeholder: "0",
424
- onChange: handleMonthlyDepositsChange,
425
- "aria-invalid": !!fieldErrors.monthlyDeposits,
426
- "aria-describedby": fieldErrors.monthlyDeposits ? "monthlyDeposits-error" : void 0
284
+ className: `header_3 ${header_theme({ variant: calculator_variant })}`,
285
+ children: headline
427
286
  }
428
287
  ),
429
- fieldErrors.monthlyDeposits && /* @__PURE__ */ jsx(
430
- Description,
431
- {
432
- as: "span",
433
- id: "monthlyDeposits-error",
434
- className: field_error,
435
- role: "alert",
436
- children: fieldErrors.monthlyDeposits
437
- }
438
- )
439
- ] }),
440
- disclosure && /* @__PURE__ */ jsx("div", { className: `${form_disclosure} push_up_24`, children: disclosure })
441
- ] }) }) }),
442
- /* @__PURE__ */ jsx("div", { className: results_wrapper, children: /* @__PURE__ */ jsxs("div", { className: result_card, children: [
443
- /* @__PURE__ */ jsxs(
444
- "div",
445
- {
446
- className: result_section,
447
- "aria-live": "polite",
448
- "aria-atomic": "true",
449
- "aria-label": `Interest earned: ${interestEarnedDisplay}`,
450
- children: [
451
- /* @__PURE__ */ jsx(
452
- Image,
453
- {
454
- src: "https://www.axos.com/images/5IyqVlv7El9K7hAX0vIGWG/axb-25th-growth-lg.png",
455
- alt: "",
456
- height: 173,
457
- width: 202,
458
- className: `img_fluid ${result_image}`,
459
- priority: true
460
- }
461
- ),
462
- /* @__PURE__ */ jsx(
463
- "div",
464
- {
465
- className: `${result_value} ${interestScrambling ? scrambling : ""}`,
466
- children: interestEarnedDisplay
467
- }
468
- ),
469
- /* @__PURE__ */ jsx("div", { className: result_value_label, children: "Interest Earned" })
470
- ]
471
- }
472
- ),
473
- /* @__PURE__ */ jsxs("div", { "aria-live": "polite", "aria-atomic": "true", children: [
474
- /* @__PURE__ */ jsxs("div", { className: result_item, children: [
475
- /* @__PURE__ */ jsx("span", { className: result_item_label, children: "Ending Balance:" }),
476
- /* @__PURE__ */ jsx(
477
- "span",
478
- {
479
- className: `${result_item_value} ${balanceScrambling ? scrambling : ""}`,
480
- children: endingBalanceDisplay
481
- }
482
- )
483
- ] }),
484
- /* @__PURE__ */ jsxs("div", { className: result_item, children: [
485
- /* @__PURE__ */ jsx("span", { className: result_item_label, children: "Total Deposits:" }),
486
- /* @__PURE__ */ jsx(
487
- "span",
488
- {
489
- className: `${result_item_value} ${depositsScrambling ? scrambling : ""}`,
490
- children: totalDepositsDisplay
491
- }
492
- )
493
- ] })
494
- ] })
495
- ] }) })
496
- ]
497
- }
498
- ),
499
- /* @__PURE__ */ jsx("div", { id: "definitions", className: "push_up_24", children: /* @__PURE__ */ jsx(
500
- "div",
501
- {
502
- className: `${definitions_accordion} ${apy_calculator}`,
503
- "aria-label": "Calculator definitions",
504
- style: { paddingBlock: "0px" },
505
- children: /* @__PURE__ */ jsx(Disclosure, { children: ({ open }) => /* @__PURE__ */ jsxs(Fragment, { children: [
506
- /* @__PURE__ */ jsxs(DisclosureButton, { className: definitions_button, children: [
507
- /* @__PURE__ */ jsx(
508
- "h2",
509
- {
510
- className: definitions_h2({ variant: getVariant(variant) }),
511
- children: "Calculator definitions"
512
- }
513
- ),
514
- /* @__PURE__ */ jsx(
515
- "svg",
516
- {
517
- xmlns: "http://www.w3.org/2000/svg",
518
- width: "20",
519
- height: "20",
520
- viewBox: "0 0 20 20",
521
- fill: "none",
522
- "aria-hidden": "true",
523
- children: /* @__PURE__ */ jsx(
524
- "path",
525
- {
526
- d: "M10 1.25C14.8325 1.25 18.75 5.16751 18.75 10C18.75 14.8325 14.8325 18.75 10 18.75C5.16751 18.75 1.25 14.8325 1.25 10C1.25 5.16751 5.16751 1.25 10 1.25ZM10 2.5C5.85786 2.5 2.5 5.85786 2.5 10C2.5 14.1421 5.85786 17.5 10 17.5C14.1421 17.5 17.5 14.1421 17.5 10C17.5 5.85786 14.1421 2.5 10 2.5ZM10.625 8.75V14.375H9.375V8.75H10.625ZM10 5.625C10.5178 5.625 10.9375 6.04473 10.9375 6.5625C10.9375 7.08027 10.5178 7.5 10 7.5C9.48223 7.5 9.0625 7.08027 9.0625 6.5625C9.0625 6.04473 9.48223 5.625 10 5.625Z",
527
- fill: "#435164"
528
- }
529
- )
530
- }
531
- )
532
- ] }),
533
- /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: open && /* @__PURE__ */ jsx(
534
- DisclosurePanel,
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,
535
301
  {
536
- static: true,
537
- as: motion.div,
538
- initial: { opacity: 0, height: 0, y: -6 },
539
- animate: { opacity: 1, height: "auto", y: 0 },
540
- exit: { opacity: 0, height: 0, y: -4 },
541
- style: { overflow: "hidden" },
542
- children: /* @__PURE__ */ jsxs(
543
- "div",
544
- {
545
- className: `${definitions_columns} ${definitions_panel}`,
546
- children: [
547
- /* @__PURE__ */ jsx("div", { className: definitions_column, children: leftDefinitions.map((definition, index) => /* @__PURE__ */ jsxs(
548
- motion.div,
549
- {
550
- className: definitions_item,
551
- initial: { opacity: 0, y: 8 },
552
- animate: { opacity: 1, y: 0 },
553
- exit: { opacity: 0, y: 6 },
554
- transition: {
555
- ...DEFINITIONS_ITEM_TRANSITION,
556
- delay: index * 0.045
557
- },
558
- children: [
559
- /* @__PURE__ */ jsx("h3", { className: definitions_term, children: definition.term }),
560
- /* @__PURE__ */ jsx("p", { className: definitions_text, children: definition.description })
561
- ]
562
- },
563
- definition.term
564
- )) }),
565
- /* @__PURE__ */ jsx("div", { className: definitions_column, children: rightDefinitions.map((definition, index) => /* @__PURE__ */ jsxs(
566
- motion.div,
567
- {
568
- className: definitions_item,
569
- initial: { opacity: 0, y: 8 },
570
- animate: { opacity: 1, y: 0 },
571
- exit: { opacity: 0, y: 6 },
572
- transition: {
573
- ...DEFINITIONS_ITEM_TRANSITION,
574
- delay: (leftDefinitions.length + index) * 0.045
575
- },
576
- children: [
577
- /* @__PURE__ */ jsx("h3", { className: definitions_term, children: definition.term }),
578
- /* @__PURE__ */ jsx("p", { className: definitions_text, children: definition.description })
579
- ]
580
- },
581
- definition.term
582
- )) })
583
- ]
584
- }
585
- )
586
- }
587
- ) })
588
- ] }) })
589
- }
590
- ) })
591
- ]
592
- }
593
- );
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
+ ] }) });
594
325
  };
595
326
  export {
596
327
  ApyCalculator