PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / trunk
GiveWP – Donation Plugin and Fundraising Platform vtrunk
4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / src / DonationForms / resources / registrars / templates / fields / Amount / DonationAmountLevels.tsx
give / src / DonationForms / resources / registrars / templates / fields / Amount Last commit date
CurrencySwitcher.tsx 2 years ago CustomAmount.tsx 1 year ago DonationAmountCurrency.tsx 2 years ago DonationAmountLevels.tsx 1 month ago index.tsx 1 month ago withCurrencySettings.tsx 1 month ago
DonationAmountLevels.tsx
120 lines
1 import classNames from 'classnames';
2 import {__} from '@wordpress/i18n';
3 import {useEffect, useState} from '@wordpress/element';
4
5 /**
6 * @since 3.0.0
7 */
8 type DonationAmountLevelsProps = {
9 name: string;
10 currency: string;
11 levels: Level[];
12 onLevelClick?: (amount: number, index: number) => void;
13 };
14
15 type GroupedLevels = {
16 labeled: Level[];
17 unlabeled: Level[];
18 };
19
20 type Level = {label: string | null; value: number; checked?: boolean};
21
22 /**
23 * Prefer the level marked as checked in the form builder when amounts are duplicated.
24 *
25 * @since 4.16.5
26 */
27 function getSelectedLevelIndex(levels: Level[], amount: unknown): number {
28 const checkedIndex = levels.findIndex((level) => level.checked);
29
30 if (checkedIndex >= 0 && levels[checkedIndex].value === amount) {
31 return checkedIndex;
32 }
33
34 const matchingIndices = levels.reduce<number[]>((indices, level, index) => {
35 if (level.value === amount) {
36 indices.push(index);
37 }
38
39 return indices;
40 }, []);
41
42 return matchingIndices.length === 1 ? matchingIndices[0] : -1;
43 }
44
45 /**
46 * @since 4.16.5 Track the selected level by index to support duplicate amounts.
47 * @since 4.3.0 Add proper roles and ARIA attributes
48 * @since 3.12.0 add level descriptions.
49 * @since 3.0.0
50 */
51 export default function DonationAmountLevels({name, currency, levels, onLevelClick}: DonationAmountLevelsProps) {
52 const {useWatch, useCurrencyFormatter} = window.givewp.form.hooks;
53 const amount = useWatch({name});
54 const formatter = useCurrencyFormatter(currency);
55
56 const groupedLevels: GroupedLevels = levels.reduce(
57 (acc: GroupedLevels, level) => {
58 const key = level.label ? 'labeled' : 'unlabeled';
59 acc[key].push(level);
60 return acc;
61 },
62 {labeled: [], unlabeled: []}
63 );
64
65 const allLevels = [...groupedLevels.labeled, ...groupedLevels.unlabeled];
66
67 const [selectedIndex, setSelectedIndex] = useState<number>(() => getSelectedLevelIndex(allLevels, amount));
68
69 useEffect(() => {
70 if (allLevels[selectedIndex]?.value !== amount) {
71 setSelectedIndex(getSelectedLevelIndex(allLevels, amount));
72 }
73 }, [levels, amount]);
74
75 return (
76 <div
77 className={classNames('givewp-fields-amount__levels-container', {
78 'givewp-fields-amount__levels-container--has-descriptions': groupedLevels.labeled.length > 0,
79 })}
80 role="radiogroup"
81 aria-label={__('Donation Amount', 'give')}
82 >
83 {allLevels.map((level, index) => {
84 const label = formatter.format(level.value);
85 const selected = index === selectedIndex;
86 const hasDescription = level.label;
87
88 return (
89 <div
90 className={classNames('givewp-fields-amount__level-container', {
91 'givewp-fields-amount__level-container--col': hasDescription,
92 })}
93 key={index}
94 >
95 <button
96 className={classNames('givewp-fields-amount__level', {
97 'givewp-fields-amount__level--selected': selected,
98 'givewp-fields-amount__level--description': hasDescription,
99 })}
100 type="button"
101 role="radio"
102 aria-checked={selected}
103 onClick={() => {
104 setSelectedIndex(index);
105 onLevelClick(level.value, index);
106 }}
107 key={index}
108 >
109 {label}
110 </button>
111 {hasDescription && (
112 <span className={'givewp-fields-amount__level__description'}>{level.label}</span>
113 )}
114 </div>
115 );
116 })}
117 </div>
118 );
119 }
120