@axos-web-dev/shared-components 2.2.2 → 2.2.4

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