@lion/ui 0.13.1 → 0.14.1
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.
- package/components/input-amount-dropdown/src/LionInputAmountDropdown.js +554 -0
- package/components/input-amount-dropdown/src/currencyUtil.js +324 -0
- package/components/input-amount-dropdown/src/formatters.js +24 -0
- package/components/input-amount-dropdown/src/localizeNamespaceLoader.js +7 -0
- package/components/input-amount-dropdown/src/parsers.js +23 -0
- package/components/input-amount-dropdown/src/serializers.js +24 -0
- package/components/input-amount-dropdown/src/validators.js +22 -0
- package/components/input-amount-dropdown/test/LionInputAmountDropdown.test.js +200 -0
- package/components/input-amount-dropdown/test-helpers/mimicUserChangingDropdown.js +22 -0
- package/components/input-amount-dropdown/test-suites/LionInputAmountDropdown.suite.js +321 -0
- package/components/input-amount-dropdown/translations/en.js +5 -0
- package/components/input-amount-dropdown/types/index.ts +234 -0
- package/components/input-tel/types/index.ts +6 -0
- package/components/localize/src/number/getFractionDigits.js +1 -1
- package/custom-elements.json +5479 -1421
- package/dist-types/components/input-amount-dropdown/src/LionInputAmountDropdown.d.ts +221 -0
- package/dist-types/components/input-amount-dropdown/src/LionInputAmountDropdown.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/src/currencyUtil.d.ts +24 -0
- package/dist-types/components/input-amount-dropdown/src/currencyUtil.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/src/formatters.d.ts +4 -0
- package/dist-types/components/input-amount-dropdown/src/formatters.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/src/localizeNamespaceLoader.d.ts +2 -0
- package/dist-types/components/input-amount-dropdown/src/localizeNamespaceLoader.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/src/parsers.d.ts +2 -0
- package/dist-types/components/input-amount-dropdown/src/parsers.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/src/serializers.d.ts +3 -0
- package/dist-types/components/input-amount-dropdown/src/serializers.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/src/validators.d.ts +12 -0
- package/dist-types/components/input-amount-dropdown/src/validators.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/test/LionInputAmountDropdown.test.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/test/LionInputAmountDropdown.test.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/test-helpers/mimicUserChangingDropdown.d.ts +12 -0
- package/dist-types/components/input-amount-dropdown/test-helpers/mimicUserChangingDropdown.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/test-suites/LionInputAmountDropdown.suite.d.ts +13 -0
- package/dist-types/components/input-amount-dropdown/test-suites/LionInputAmountDropdown.suite.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/translations/en.d.ts +7 -0
- package/dist-types/components/input-amount-dropdown/translations/en.d.ts.map +1 -0
- package/dist-types/components/input-amount-dropdown/types/index.d.ts +86 -0
- package/dist-types/components/input-amount-dropdown/types/index.d.ts.map +1 -0
- package/dist-types/components/input-tel/types/index.d.ts +1 -1
- package/dist-types/components/input-tel/types/index.d.ts.map +1 -1
- package/dist-types/components/localize/src/number/getFractionDigits.d.ts +1 -1
- package/dist-types/exports/define/lion-input-amount-dropdown.d.ts +2 -0
- package/dist-types/exports/define/lion-input-amount-dropdown.d.ts.map +1 -0
- package/dist-types/exports/input-amount-dropdown-test-helpers.d.ts +2 -0
- package/dist-types/exports/input-amount-dropdown-test-helpers.d.ts.map +1 -0
- package/dist-types/exports/input-amount-dropdown-test-suites.d.ts +2 -0
- package/dist-types/exports/input-amount-dropdown-test-suites.d.ts.map +1 -0
- package/dist-types/exports/input-amount-dropdown.d.ts +2 -0
- package/dist-types/exports/input-amount-dropdown.d.ts.map +1 -0
- package/dist-types/exports/types/input-amount-dropdown.d.ts +2 -0
- package/dist-types/exports/types/input-amount-dropdown.d.ts.map +1 -0
- package/dist-types/tsconfig.tsbuildinfo +1 -1
- package/docs/components/checkbox-group/overview.md +2 -2
- package/docs/components/collapsible/overview.md +1 -1
- package/docs/components/combobox/overview.md +1 -1
- package/docs/components/combobox/use-cases.md +1 -1
- package/docs/components/dialog/overview.md +1 -1
- package/docs/components/fieldset/overview.md +5 -5
- package/docs/components/form/overview.md +3 -3
- package/docs/components/form/use-cases.md +2 -2
- package/docs/components/icon/use-cases.md +1 -1
- package/docs/components/input/overview.md +1 -1
- package/docs/components/input-amount/overview.md +3 -3
- package/docs/components/input-amount-dropdown/api-table.md +210 -0
- package/docs/components/input-amount-dropdown/index.md +13 -0
- package/docs/components/input-amount-dropdown/use-cases.md +103 -0
- package/docs/components/input-date/overview.md +3 -3
- package/docs/components/input-datepicker/overview.md +5 -5
- package/docs/components/input-email/overview.md +2 -2
- package/docs/components/input-file/overview.md +1 -1
- package/docs/components/input-iban/overview.md +2 -2
- package/docs/components/input-range/overview.md +2 -2
- package/docs/components/input-stepper/overview.md +1 -1
- package/docs/components/input-tel/overview.md +1 -1
- package/docs/components/input-tel/use-cases.md +6 -6
- package/docs/components/input-tel-dropdown/overview.md +1 -1
- package/docs/components/listbox/use-cases.md +1 -1
- package/docs/components/radio-group/overview.md +3 -3
- package/docs/components/select/use-cases.md +1 -1
- package/docs/components/select-rich/use-cases.md +1 -1
- package/docs/components/tabs/examples.md +1 -1
- package/docs/fundamentals/index.md +4 -4
- package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
- package/docs/fundamentals/rationales/accessibility.md +1 -1
- package/docs/fundamentals/systems/core/SlotMixin.md +1 -1
- package/docs/fundamentals/systems/core/overview.md +1 -1
- package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
- package/docs/fundamentals/systems/form/model-value.md +1 -1
- package/docs/fundamentals/systems/form/overview.md +28 -28
- package/docs/fundamentals/systems/form/validate.md +2 -2
- package/docs/fundamentals/systems/localize/overview.md +4 -4
- package/docs/fundamentals/systems/overlays/configuration.md +2 -2
- package/docs/fundamentals/systems/overlays/overview.md +5 -5
- package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
- package/docs/fundamentals/tools/helpers/overview.md +1 -1
- package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
- package/docs/guides/how-to/create-a-custom-field.md +5 -5
- package/docs/guides/how-to/create-a-form.md +4 -4
- package/docs/guides/how-to/extend-a-native-input.md +2 -2
- package/docs/guides/index.md +8 -8
- package/docs/guides/principles/index.md +5 -5
- package/docs/guides/principles/styling.md +1 -1
- package/exports/define/lion-input-amount-dropdown.js +3 -0
- package/exports/input-amount-dropdown-test-helpers.js +1 -0
- package/exports/input-amount-dropdown-test-suites.js +1 -0
- package/exports/input-amount-dropdown.js +1 -0
- package/exports/types/input-amount-dropdown.ts +9 -0
- package/input-amount-dropdown-test-helpers.js +1 -0
- package/input-amount-dropdown-test-suites.js +1 -0
- package/input-amount-dropdown.js +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This country to currency list was exported from Java.
|
|
3
|
+
* Java contains a country:currency map according to the i18n spec, but JS does not.
|
|
4
|
+
*
|
|
5
|
+
* @type {import("../types/index.js").countryToCurrencyList}
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // The following Java code can be used to export the countryToCurrencyList
|
|
9
|
+
*
|
|
10
|
+
* import java.util.Currency;
|
|
11
|
+
* import java.util.Locale;
|
|
12
|
+
*
|
|
13
|
+
* public class Main {
|
|
14
|
+
* public static void main(String[] args) {
|
|
15
|
+
* // get all ISO countries
|
|
16
|
+
* String[] ISOCountryCodes = Locale.getISOCountries();
|
|
17
|
+
*
|
|
18
|
+
* // loop over all the countries.
|
|
19
|
+
* for (String country : ISOCountryCodes) {
|
|
20
|
+
* try {
|
|
21
|
+
* // get the locale for said country
|
|
22
|
+
* Locale locale = new Locale("", country);
|
|
23
|
+
*
|
|
24
|
+
* // creates a Currency instance which has a bunch of standardized information.
|
|
25
|
+
* // from that class we can get the currency linked to the country.
|
|
26
|
+
* String currencyCode = Currency.getInstance(locale).getCurrencyCode();
|
|
27
|
+
*
|
|
28
|
+
* // prints to the console, which can be copied to update the map if changes occurred
|
|
29
|
+
* String output = country + ": '" + currencyCode + "',\n";
|
|
30
|
+
* System.out.print(output);
|
|
31
|
+
* } catch (Exception e) {
|
|
32
|
+
* }
|
|
33
|
+
* }
|
|
34
|
+
* }
|
|
35
|
+
* }
|
|
36
|
+
*/
|
|
37
|
+
const countryToCurrencyList = {
|
|
38
|
+
AD: 'EUR',
|
|
39
|
+
AE: 'AED',
|
|
40
|
+
AF: 'AFN',
|
|
41
|
+
AG: 'XCD',
|
|
42
|
+
AI: 'XCD',
|
|
43
|
+
AL: 'ALL',
|
|
44
|
+
AM: 'AMD',
|
|
45
|
+
AO: 'AOA',
|
|
46
|
+
AR: 'ARS',
|
|
47
|
+
AS: 'USD',
|
|
48
|
+
AT: 'EUR',
|
|
49
|
+
AU: 'AUD',
|
|
50
|
+
AW: 'AWG',
|
|
51
|
+
AX: 'EUR',
|
|
52
|
+
AZ: 'AZN',
|
|
53
|
+
BA: 'BAM',
|
|
54
|
+
BB: 'BBD',
|
|
55
|
+
BD: 'BDT',
|
|
56
|
+
BE: 'EUR',
|
|
57
|
+
BF: 'XOF',
|
|
58
|
+
BG: 'BGN',
|
|
59
|
+
BH: 'BHD',
|
|
60
|
+
BI: 'BIF',
|
|
61
|
+
BJ: 'XOF',
|
|
62
|
+
BL: 'EUR',
|
|
63
|
+
BM: 'BMD',
|
|
64
|
+
BN: 'BND',
|
|
65
|
+
BO: 'BOB',
|
|
66
|
+
BQ: 'USD',
|
|
67
|
+
BR: 'BRL',
|
|
68
|
+
BS: 'BSD',
|
|
69
|
+
BT: 'BTN',
|
|
70
|
+
BV: 'NOK',
|
|
71
|
+
BW: 'BWP',
|
|
72
|
+
BY: 'BYN',
|
|
73
|
+
BZ: 'BZD',
|
|
74
|
+
CA: 'CAD',
|
|
75
|
+
CC: 'AUD',
|
|
76
|
+
CD: 'CDF',
|
|
77
|
+
CF: 'XAF',
|
|
78
|
+
CG: 'XAF',
|
|
79
|
+
CH: 'CHF',
|
|
80
|
+
CI: 'XOF',
|
|
81
|
+
CK: 'NZD',
|
|
82
|
+
CL: 'CLP',
|
|
83
|
+
CM: 'XAF',
|
|
84
|
+
CN: 'CNY',
|
|
85
|
+
CO: 'COP',
|
|
86
|
+
CR: 'CRC',
|
|
87
|
+
CU: 'CUP',
|
|
88
|
+
CV: 'CVE',
|
|
89
|
+
CW: 'XCG',
|
|
90
|
+
CX: 'AUD',
|
|
91
|
+
CY: 'EUR',
|
|
92
|
+
CZ: 'CZK',
|
|
93
|
+
DE: 'EUR',
|
|
94
|
+
DJ: 'DJF',
|
|
95
|
+
DK: 'DKK',
|
|
96
|
+
DM: 'XCD',
|
|
97
|
+
DO: 'DOP',
|
|
98
|
+
DZ: 'DZD',
|
|
99
|
+
EC: 'USD',
|
|
100
|
+
EE: 'EUR',
|
|
101
|
+
EG: 'EGP',
|
|
102
|
+
EH: 'MAD',
|
|
103
|
+
ER: 'ERN',
|
|
104
|
+
ES: 'EUR',
|
|
105
|
+
ET: 'ETB',
|
|
106
|
+
FI: 'EUR',
|
|
107
|
+
FJ: 'FJD',
|
|
108
|
+
FK: 'FKP',
|
|
109
|
+
FM: 'USD',
|
|
110
|
+
FO: 'DKK',
|
|
111
|
+
FR: 'EUR',
|
|
112
|
+
GA: 'XAF',
|
|
113
|
+
GB: 'GBP',
|
|
114
|
+
GD: 'XCD',
|
|
115
|
+
GE: 'GEL',
|
|
116
|
+
GF: 'EUR',
|
|
117
|
+
GG: 'GBP',
|
|
118
|
+
GH: 'GHS',
|
|
119
|
+
GI: 'GIP',
|
|
120
|
+
GL: 'DKK',
|
|
121
|
+
GM: 'GMD',
|
|
122
|
+
GN: 'GNF',
|
|
123
|
+
GP: 'EUR',
|
|
124
|
+
GQ: 'XAF',
|
|
125
|
+
GR: 'EUR',
|
|
126
|
+
GS: 'GBP',
|
|
127
|
+
GT: 'GTQ',
|
|
128
|
+
GU: 'USD',
|
|
129
|
+
GW: 'XOF',
|
|
130
|
+
GY: 'GYD',
|
|
131
|
+
HK: 'HKD',
|
|
132
|
+
HM: 'AUD',
|
|
133
|
+
HN: 'HNL',
|
|
134
|
+
HR: 'EUR',
|
|
135
|
+
HT: 'HTG',
|
|
136
|
+
HU: 'HUF',
|
|
137
|
+
ID: 'IDR',
|
|
138
|
+
IE: 'EUR',
|
|
139
|
+
IL: 'ILS',
|
|
140
|
+
IM: 'GBP',
|
|
141
|
+
IN: 'INR',
|
|
142
|
+
IO: 'USD',
|
|
143
|
+
IQ: 'IQD',
|
|
144
|
+
IR: 'IRR',
|
|
145
|
+
IS: 'ISK',
|
|
146
|
+
IT: 'EUR',
|
|
147
|
+
JE: 'GBP',
|
|
148
|
+
JM: 'JMD',
|
|
149
|
+
JO: 'JOD',
|
|
150
|
+
JP: 'JPY',
|
|
151
|
+
KE: 'KES',
|
|
152
|
+
KG: 'KGS',
|
|
153
|
+
KH: 'KHR',
|
|
154
|
+
KI: 'AUD',
|
|
155
|
+
KM: 'KMF',
|
|
156
|
+
KN: 'XCD',
|
|
157
|
+
KP: 'KPW',
|
|
158
|
+
KR: 'KRW',
|
|
159
|
+
KW: 'KWD',
|
|
160
|
+
KY: 'KYD',
|
|
161
|
+
KZ: 'KZT',
|
|
162
|
+
LA: 'LAK',
|
|
163
|
+
LB: 'LBP',
|
|
164
|
+
LC: 'XCD',
|
|
165
|
+
LI: 'CHF',
|
|
166
|
+
LK: 'LKR',
|
|
167
|
+
LR: 'LRD',
|
|
168
|
+
LS: 'LSL',
|
|
169
|
+
LT: 'EUR',
|
|
170
|
+
LU: 'EUR',
|
|
171
|
+
LV: 'EUR',
|
|
172
|
+
LY: 'LYD',
|
|
173
|
+
MA: 'MAD',
|
|
174
|
+
MC: 'EUR',
|
|
175
|
+
MD: 'MDL',
|
|
176
|
+
ME: 'EUR',
|
|
177
|
+
MF: 'EUR',
|
|
178
|
+
MG: 'MGA',
|
|
179
|
+
MH: 'USD',
|
|
180
|
+
MK: 'MKD',
|
|
181
|
+
ML: 'XOF',
|
|
182
|
+
MM: 'MMK',
|
|
183
|
+
MN: 'MNT',
|
|
184
|
+
MO: 'MOP',
|
|
185
|
+
MP: 'USD',
|
|
186
|
+
MQ: 'EUR',
|
|
187
|
+
MR: 'MRU',
|
|
188
|
+
MS: 'XCD',
|
|
189
|
+
MT: 'EUR',
|
|
190
|
+
MU: 'MUR',
|
|
191
|
+
MV: 'MVR',
|
|
192
|
+
MW: 'MWK',
|
|
193
|
+
MX: 'MXN',
|
|
194
|
+
MY: 'MYR',
|
|
195
|
+
MZ: 'MZN',
|
|
196
|
+
NA: 'NAD',
|
|
197
|
+
NC: 'XPF',
|
|
198
|
+
NE: 'XOF',
|
|
199
|
+
NF: 'AUD',
|
|
200
|
+
NG: 'NGN',
|
|
201
|
+
NI: 'NIO',
|
|
202
|
+
NL: 'EUR',
|
|
203
|
+
NO: 'NOK',
|
|
204
|
+
NP: 'NPR',
|
|
205
|
+
NR: 'AUD',
|
|
206
|
+
NU: 'NZD',
|
|
207
|
+
NZ: 'NZD',
|
|
208
|
+
OM: 'OMR',
|
|
209
|
+
PA: 'PAB',
|
|
210
|
+
PE: 'PEN',
|
|
211
|
+
PF: 'XPF',
|
|
212
|
+
PG: 'PGK',
|
|
213
|
+
PH: 'PHP',
|
|
214
|
+
PK: 'PKR',
|
|
215
|
+
PL: 'PLN',
|
|
216
|
+
PM: 'EUR',
|
|
217
|
+
PN: 'NZD',
|
|
218
|
+
PR: 'USD',
|
|
219
|
+
PS: 'ILS',
|
|
220
|
+
PT: 'EUR',
|
|
221
|
+
PW: 'USD',
|
|
222
|
+
PY: 'PYG',
|
|
223
|
+
QA: 'QAR',
|
|
224
|
+
RE: 'EUR',
|
|
225
|
+
RO: 'RON',
|
|
226
|
+
RS: 'RSD',
|
|
227
|
+
RU: 'RUB',
|
|
228
|
+
RW: 'RWF',
|
|
229
|
+
SA: 'SAR',
|
|
230
|
+
SB: 'SBD',
|
|
231
|
+
SC: 'SCR',
|
|
232
|
+
SD: 'SDG',
|
|
233
|
+
SE: 'SEK',
|
|
234
|
+
SG: 'SGD',
|
|
235
|
+
SH: 'SHP',
|
|
236
|
+
SI: 'EUR',
|
|
237
|
+
SJ: 'NOK',
|
|
238
|
+
SK: 'EUR',
|
|
239
|
+
SL: 'SLE',
|
|
240
|
+
SM: 'EUR',
|
|
241
|
+
SN: 'XOF',
|
|
242
|
+
SO: 'SOS',
|
|
243
|
+
SR: 'SRD',
|
|
244
|
+
SS: 'SSP',
|
|
245
|
+
ST: 'STN',
|
|
246
|
+
SV: 'SVC',
|
|
247
|
+
SX: 'XCG',
|
|
248
|
+
SY: 'SYP',
|
|
249
|
+
SZ: 'SZL',
|
|
250
|
+
TC: 'USD',
|
|
251
|
+
TD: 'XAF',
|
|
252
|
+
TF: 'EUR',
|
|
253
|
+
TG: 'XOF',
|
|
254
|
+
TH: 'THB',
|
|
255
|
+
TJ: 'TJS',
|
|
256
|
+
TK: 'NZD',
|
|
257
|
+
TL: 'USD',
|
|
258
|
+
TM: 'TMT',
|
|
259
|
+
TN: 'TND',
|
|
260
|
+
TO: 'TOP',
|
|
261
|
+
TR: 'TRY',
|
|
262
|
+
TT: 'TTD',
|
|
263
|
+
TV: 'AUD',
|
|
264
|
+
TW: 'TWD',
|
|
265
|
+
TZ: 'TZS',
|
|
266
|
+
UA: 'UAH',
|
|
267
|
+
UG: 'UGX',
|
|
268
|
+
UM: 'USD',
|
|
269
|
+
US: 'USD',
|
|
270
|
+
UY: 'UYU',
|
|
271
|
+
UZ: 'UZS',
|
|
272
|
+
VA: 'EUR',
|
|
273
|
+
VC: 'XCD',
|
|
274
|
+
VE: 'VES',
|
|
275
|
+
VG: 'USD',
|
|
276
|
+
VI: 'USD',
|
|
277
|
+
VN: 'VND',
|
|
278
|
+
VU: 'VUV',
|
|
279
|
+
WF: 'XPF',
|
|
280
|
+
WS: 'WST',
|
|
281
|
+
YE: 'YER',
|
|
282
|
+
YT: 'EUR',
|
|
283
|
+
ZA: 'ZAR',
|
|
284
|
+
ZM: 'ZMW',
|
|
285
|
+
ZW: 'ZWG',
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Map containing all countries and its corresponding currency, following the i18n standard.
|
|
290
|
+
* @type {import("../types/index.js").RegionToCurrencyMap}
|
|
291
|
+
*/
|
|
292
|
+
const countryToCurrencyMap = /** @type {import("../types/index.js").RegionToCurrencyMap} */ (
|
|
293
|
+
new Map(Object.entries(countryToCurrencyList))
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Set with all possible currencies derived from the i18n standard.
|
|
298
|
+
* @type {import("../types/index.js").AllCurrenciesSet}
|
|
299
|
+
*/
|
|
300
|
+
const allCurrencies = new Set(Object.values(countryToCurrencyList).sort());
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Matches a currency symbol to a currency code, with a given locale based on Intl.numberFormat.
|
|
304
|
+
* @param {import("./LionInputAmountDropdown.js").CurrencyCode} currency
|
|
305
|
+
* @param {string} locale
|
|
306
|
+
* @returns {string}
|
|
307
|
+
*/
|
|
308
|
+
const getCurrencySymbol = (currency, locale) => {
|
|
309
|
+
if (!locale || !currency) {
|
|
310
|
+
return '';
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return (
|
|
314
|
+
new Intl.NumberFormat(locale, { style: 'currency', currency })
|
|
315
|
+
.formatToParts(1)
|
|
316
|
+
.find(x => x.type === 'currency')?.value || ''
|
|
317
|
+
);
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
export const currencyUtil = {
|
|
321
|
+
countryToCurrencyMap,
|
|
322
|
+
allCurrencies,
|
|
323
|
+
getCurrencySymbol,
|
|
324
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { formatAmount as _formatAmount } from '@lion/ui/input-amount.js';
|
|
2
|
+
import { currencyUtil } from './currencyUtil.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import('../../localize/types/LocalizeMixinTypes.js').FormatNumberOptions} FormatOptions
|
|
6
|
+
* @typedef {import('../types/index.js').AmountDropdownModelValue} AmountDropdownModelValue
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Formats a number considering the default fraction digits provided by Intl.
|
|
11
|
+
*
|
|
12
|
+
* @param {import('../types/index.js').AmountDropdownModelValue} modelValue to format
|
|
13
|
+
* @param {FormatOptions} [givenOptions]
|
|
14
|
+
* @param {AmountDropdownModelValue|undefined} [context]
|
|
15
|
+
*/
|
|
16
|
+
export const formatAmount = (modelValue, givenOptions, context) => {
|
|
17
|
+
// @ts-expect-error - cannot cast string to CurrencyCode outside a TS file
|
|
18
|
+
if (currencyUtil.allCurrencies.has(modelValue?.currency) && context) {
|
|
19
|
+
// TODO: better way of setting parent currency
|
|
20
|
+
context.currency = modelValue?.currency;
|
|
21
|
+
}
|
|
22
|
+
// @ts-expect-error - cannot cast string to CurrencyCode outside a TS file
|
|
23
|
+
return _formatAmount(modelValue?.amount, givenOptions);
|
|
24
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { parseAmount as _parseAmount } from '@lion/ui/input-amount.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Uses `parseAmount()` to parse a number string and return the best possible javascript number.
|
|
5
|
+
* Rounds up the number with the correct amount of decimals according to the currency.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* parseAmount('1,234.56', {currency: 'EUR'}); => { amount: 1234.56, currency: 'EUR' }
|
|
9
|
+
* parseAmount('1,234.56', {currency: 'JPY'}); => { amount: 1235, currency: 'JPY' }
|
|
10
|
+
* parseAmount('1,234.56', {currency: 'JOD'}); => { amount: 1234.560, currency: 'JOD' }
|
|
11
|
+
*
|
|
12
|
+
* @param {string} value Number to be parsed
|
|
13
|
+
* @param {import('../../localize/types/LocalizeMixinTypes.js').FormatNumberOptions} [givenOptions] Locale Options
|
|
14
|
+
* @returns {import('../types/index.js').AmountDropdownModelValue}
|
|
15
|
+
*/
|
|
16
|
+
export const parseAmount = (value, givenOptions) => {
|
|
17
|
+
const parsedAmount = _parseAmount(value, givenOptions);
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
amount: parsedAmount,
|
|
21
|
+
currency: givenOptions?.currency,
|
|
22
|
+
};
|
|
23
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serializes the modelValue to the international standard notation.
|
|
3
|
+
* @param {import("../types/index.js").AmountDropdownModelValue} modelValue
|
|
4
|
+
* @returns {string}
|
|
5
|
+
*/
|
|
6
|
+
export const serializer = modelValue =>
|
|
7
|
+
/**
|
|
8
|
+
* There seems to be some debate on a common international notation vs localization.
|
|
9
|
+
* The unwritten standard is, e.g: EUR 123
|
|
10
|
+
*/
|
|
11
|
+
`${modelValue?.currency} ${modelValue?.amount}`;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Deserializes the serializedValue back to modelValue.
|
|
15
|
+
* @param {string} serializedValue
|
|
16
|
+
* @returns {import("../types/index.js").AmountDropdownModelValue}
|
|
17
|
+
*/
|
|
18
|
+
export const deserializer = serializedValue => {
|
|
19
|
+
const [currency, amount] = serializedValue.split(' ');
|
|
20
|
+
return {
|
|
21
|
+
currency,
|
|
22
|
+
amount,
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { IsNumber, Validator } from '@lion/ui/form-core.js';
|
|
2
|
+
import { currencyUtil } from './currencyUtil.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import('../../form-core/types/validate/validate.js').FeedbackMessageData} FeedbackMessageData
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export class CurrencyAndAmount extends Validator {
|
|
9
|
+
static validatorName = 'CurrencyAndAmount';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {import('../types/index.js').AmountDropdownModelValue} modelValue amount and currency symbol
|
|
13
|
+
*/
|
|
14
|
+
// eslint-disable-next-line class-methods-use-this
|
|
15
|
+
execute(modelValue) {
|
|
16
|
+
// @ts-expect-error - cannot cast string to CurrencyCode outside a TS file
|
|
17
|
+
const validCurrencyCode = currencyUtil.allCurrencies.has(modelValue?.currency);
|
|
18
|
+
const isNumber = new IsNumber().execute(modelValue.amount);
|
|
19
|
+
|
|
20
|
+
return validCurrencyCode && isNumber;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { mimicUserChangingDropdown } from '@lion/ui/input-amount-dropdown-test-helpers.js';
|
|
2
|
+
import { runInputAmountDropdownSuite } from '@lion/ui/input-amount-dropdown-test-suites.js';
|
|
3
|
+
import { LionInputAmountDropdown } from '@lion/ui/input-amount-dropdown.js';
|
|
4
|
+
import { aTimeout, expect, fixture } from '@open-wc/testing';
|
|
5
|
+
import { LionSelectRich } from '@lion/ui/select-rich.js';
|
|
6
|
+
import { repeat } from 'lit/directives/repeat.js';
|
|
7
|
+
import { LionOption } from '@lion/ui/listbox.js';
|
|
8
|
+
import { ref } from 'lit/directives/ref.js';
|
|
9
|
+
import { html } from 'lit';
|
|
10
|
+
|
|
11
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
12
|
+
import { isActiveElement } from '../../core/test-helpers/isActiveElement.js';
|
|
13
|
+
import { ScopedElementsMixin } from '../../core/src/ScopedElementsMixin.js';
|
|
14
|
+
import '@lion/ui/define/lion-input-amount-dropdown.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {import('../types/index.js').TemplateDataForDropdownInputAmount} TemplateDataForDropdownInputAmount
|
|
18
|
+
* @typedef {HTMLSelectElement|HTMLElement & {modelValue:string}} DropdownElement
|
|
19
|
+
* @typedef {import('../types/index.js').RegionMeta} RegionMeta
|
|
20
|
+
* @typedef {import('lit').TemplateResult} TemplateResult
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
class WithFormControlInputAmountDropdown extends ScopedElementsMixin(LionInputAmountDropdown) {
|
|
24
|
+
/**
|
|
25
|
+
* @configure ScopedElementsMixin
|
|
26
|
+
*/
|
|
27
|
+
static scopedElements = {
|
|
28
|
+
...super.scopedElements,
|
|
29
|
+
'lion-select-rich': LionSelectRich,
|
|
30
|
+
'lion-option': LionOption,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
static templates = {
|
|
34
|
+
...(super.templates || {}),
|
|
35
|
+
/**
|
|
36
|
+
* @param {TemplateDataForDropdownInputAmount} templateDataForDropdown
|
|
37
|
+
*/
|
|
38
|
+
dropdown: templateDataForDropdown => {
|
|
39
|
+
const { refs, data } = templateDataForDropdown;
|
|
40
|
+
// TODO: once spread directive available, use it per ref (like ref(refs?.dropdown?.ref))
|
|
41
|
+
return html`
|
|
42
|
+
<lion-select-rich
|
|
43
|
+
${ref(refs?.dropdown?.ref)}
|
|
44
|
+
label="${refs?.dropdown?.labels?.country}"
|
|
45
|
+
label-sr-only
|
|
46
|
+
@model-value-changed="${refs?.dropdown?.listeners['model-value-changed']}"
|
|
47
|
+
style="${ifDefined(refs?.dropdown?.props?.style)}"
|
|
48
|
+
>
|
|
49
|
+
${repeat(
|
|
50
|
+
data.regionMetaList,
|
|
51
|
+
regionMeta => regionMeta.currencyCode,
|
|
52
|
+
regionMeta => html`
|
|
53
|
+
<lion-option .choiceValue="${regionMeta.currencyCode}"> </lion-option>
|
|
54
|
+
`,
|
|
55
|
+
)}
|
|
56
|
+
</lion-select-rich>
|
|
57
|
+
`;
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
runInputAmountDropdownSuite();
|
|
63
|
+
|
|
64
|
+
describe('WithFormControlInputAmountDropdown', () => {
|
|
65
|
+
// @ts-expect-error
|
|
66
|
+
// Runs it for LionSelectRich, which uses .modelValue/@model-value-changed instead of .value/@change
|
|
67
|
+
runInputAmountDropdownSuite({ klass: WithFormControlInputAmountDropdown });
|
|
68
|
+
|
|
69
|
+
it('focuses the textbox right after selection if selected via opened dropdown if interaction-mode is mac', async () => {
|
|
70
|
+
class InputAmountDropdownMac extends LionInputAmountDropdown {
|
|
71
|
+
static templates = {
|
|
72
|
+
...(super.templates || {}),
|
|
73
|
+
/**
|
|
74
|
+
* @param {TemplateDataForDropdownInputAmount} templateDataForDropdown
|
|
75
|
+
*/
|
|
76
|
+
dropdown: templateDataForDropdown => {
|
|
77
|
+
const { refs, data } = templateDataForDropdown;
|
|
78
|
+
// TODO: once spread directive available, use it per ref (like ref(refs?.dropdown?.ref))
|
|
79
|
+
return html`
|
|
80
|
+
<lion-select-rich
|
|
81
|
+
${ref(refs?.dropdown?.ref)}
|
|
82
|
+
label="${refs?.dropdown?.labels?.country}"
|
|
83
|
+
label-sr-only
|
|
84
|
+
@model-value-changed="${refs?.dropdown?.listeners['model-value-changed']}"
|
|
85
|
+
style="${ifDefined(refs?.dropdown?.props?.style)}"
|
|
86
|
+
interaction-mode="mac"
|
|
87
|
+
>
|
|
88
|
+
${repeat(
|
|
89
|
+
data.regionMetaList,
|
|
90
|
+
regionMeta => regionMeta.currencyCode,
|
|
91
|
+
regionMeta => html`
|
|
92
|
+
<lion-option .choiceValue="${regionMeta.currencyCode}"> </lion-option>
|
|
93
|
+
`,
|
|
94
|
+
)}
|
|
95
|
+
</lion-select-rich>
|
|
96
|
+
`;
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
customElements.define('input-amount-dropdown-mac', InputAmountDropdownMac);
|
|
101
|
+
const el = /** @type {LionInputAmountDropdown} */ (
|
|
102
|
+
await fixture(html`
|
|
103
|
+
<input-amount-dropdown-mac
|
|
104
|
+
.allowedCurrencies="${['GBP', 'EUR']}"
|
|
105
|
+
.modelValue="{ currency: 'GBP', amount: '123' }"
|
|
106
|
+
></input-amount-dropdown-mac>
|
|
107
|
+
`)
|
|
108
|
+
);
|
|
109
|
+
const dropdownElement = el.refs.dropdown.value;
|
|
110
|
+
// @ts-expect-error [allow-protected-in-tests]
|
|
111
|
+
if (dropdownElement?._overlayCtrl) {
|
|
112
|
+
// @ts-expect-error [allow-protected-in-tests]
|
|
113
|
+
dropdownElement._overlayCtrl.show();
|
|
114
|
+
mimicUserChangingDropdown(dropdownElement, 'EUR');
|
|
115
|
+
await el.updateComplete;
|
|
116
|
+
await aTimeout(0);
|
|
117
|
+
// @ts-expect-error [allow-protected-in-tests]
|
|
118
|
+
expect(isActiveElement(el._inputNode)).to.be.true;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('does not focus the textbox right after selection if selected via opened dropdown if interaction-mode is windows/linux', async () => {
|
|
123
|
+
class InputAmountDropdownWindows extends LionInputAmountDropdown {
|
|
124
|
+
static templates = {
|
|
125
|
+
...(super.templates || {}),
|
|
126
|
+
/**
|
|
127
|
+
* @param {TemplateDataForDropdownInputAmount} templateDataForDropdown
|
|
128
|
+
*/
|
|
129
|
+
dropdown: templateDataForDropdown => {
|
|
130
|
+
const { refs, data } = templateDataForDropdown;
|
|
131
|
+
// TODO: once spread directive available, use it per ref (like ref(refs?.dropdown?.ref))
|
|
132
|
+
return html`
|
|
133
|
+
<lion-select-rich
|
|
134
|
+
${ref(refs?.dropdown?.ref)}
|
|
135
|
+
label="${refs?.dropdown?.labels?.country}"
|
|
136
|
+
label-sr-only
|
|
137
|
+
@model-value-changed="${refs?.dropdown?.listeners['model-value-changed']}"
|
|
138
|
+
style="${ifDefined(refs?.dropdown?.props?.style)}"
|
|
139
|
+
interaction-mode="windows/linux"
|
|
140
|
+
>
|
|
141
|
+
${repeat(
|
|
142
|
+
data.regionMetaList,
|
|
143
|
+
regionMeta => regionMeta.currencyCode,
|
|
144
|
+
regionMeta => html`
|
|
145
|
+
<lion-option .choiceValue="${regionMeta.currencyCode}"> </lion-option>
|
|
146
|
+
`,
|
|
147
|
+
)}
|
|
148
|
+
</lion-select-rich>
|
|
149
|
+
`;
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
customElements.define('input-amount-dropdown-windows', InputAmountDropdownWindows);
|
|
154
|
+
const el = /** @type {LionInputAmountDropdown} */ (
|
|
155
|
+
await fixture(html`
|
|
156
|
+
<input-amount-dropdown-windows
|
|
157
|
+
.allowedCurrencies="${['GBP', 'EUR']}"
|
|
158
|
+
.modelValue="{ currency: 'GBP', amount: '123' }"
|
|
159
|
+
></input-amount-dropdown-windows>
|
|
160
|
+
`)
|
|
161
|
+
);
|
|
162
|
+
const dropdownElement = el.refs.dropdown.value;
|
|
163
|
+
// @ts-expect-error [allow-protected-in-tests]
|
|
164
|
+
if (dropdownElement?._overlayCtrl) {
|
|
165
|
+
// @ts-expect-error [allow-protected-in-tests]
|
|
166
|
+
dropdownElement._overlayCtrl.show();
|
|
167
|
+
mimicUserChangingDropdown(dropdownElement, 'EUR');
|
|
168
|
+
await el.updateComplete;
|
|
169
|
+
await aTimeout(0);
|
|
170
|
+
// @ts-expect-error [allow-protected-in-tests]
|
|
171
|
+
expect(isActiveElement(el._inputNode)).to.be.false;
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe('defaultValidators', () => {
|
|
176
|
+
it('without interaction are not called', async () => {
|
|
177
|
+
const el = /** @type {LionInputAmountDropdown} */ (
|
|
178
|
+
await fixture(html`
|
|
179
|
+
<lion-input-amount-dropdown .allowedCurrencies="${['EUR']}"></lion-input-amount-dropdown>
|
|
180
|
+
`)
|
|
181
|
+
);
|
|
182
|
+
await aTimeout(0);
|
|
183
|
+
expect(el.hasFeedbackFor).to.deep.equal([]);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('with interaction are called', async () => {
|
|
187
|
+
const el = /** @type {LionInputAmountDropdown} */ (
|
|
188
|
+
await fixture(html`
|
|
189
|
+
<lion-input-amount-dropdown
|
|
190
|
+
.allowedCurrencies="${['GBP', 'EUR']}"
|
|
191
|
+
></lion-input-amount-dropdown>
|
|
192
|
+
`)
|
|
193
|
+
);
|
|
194
|
+
el.modelValue = { currency: 'EUR' };
|
|
195
|
+
await aTimeout(0);
|
|
196
|
+
el.modelValue = { currency: 'EUR', amount: '' };
|
|
197
|
+
expect(el.hasFeedbackFor).to.deep.equal(['error']);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {HTMLSelectElement|HTMLElement & {modelValue:string}} DropdownElement
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {DropdownElement} dropdownEl
|
|
7
|
+
* @param {string} value
|
|
8
|
+
*/
|
|
9
|
+
export function mimicUserChangingDropdown(dropdownEl, value) {
|
|
10
|
+
if ('modelValue' in dropdownEl) {
|
|
11
|
+
// eslint-disable-next-line no-param-reassign
|
|
12
|
+
dropdownEl.modelValue = value;
|
|
13
|
+
dropdownEl.dispatchEvent(
|
|
14
|
+
new CustomEvent('model-value-changed', { detail: { isTriggeredByUser: true } }),
|
|
15
|
+
);
|
|
16
|
+
} else {
|
|
17
|
+
// eslint-disable-next-line no-param-reassign
|
|
18
|
+
dropdownEl.value = value;
|
|
19
|
+
dropdownEl.dispatchEvent(new Event('change'));
|
|
20
|
+
dropdownEl.dispatchEvent(new Event('input'));
|
|
21
|
+
}
|
|
22
|
+
}
|