@panneau/fields 5.0.0-alpha.15 → 5.0.0-alpha.17

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 (167) hide show
  1. package/README.md +53 -3
  2. package/dist/address/AddressField.css +44 -0
  3. package/dist/address/AddressField.d.ts +37 -0
  4. package/dist/address/AddressField.d.ts.map +1 -0
  5. package/dist/address/AddressField.js +411 -0
  6. package/dist/address/AddressField.js.map +1 -0
  7. package/dist/address/AddressField.module.js +22 -0
  8. package/dist/address/AddressField.module.js.map +1 -0
  9. package/dist/address/address.d.ts +23 -0
  10. package/dist/address/address.d.ts.map +1 -0
  11. package/dist/address/address.js +58 -0
  12. package/dist/address/address.js.map +1 -0
  13. package/dist/address/index.d.ts +3 -0
  14. package/dist/address/index.d.ts.map +1 -0
  15. package/dist/address/index.js +3 -0
  16. package/dist/color/ColorField.css +9 -0
  17. package/dist/color/ColorField.d.ts +10 -3
  18. package/dist/color/ColorField.d.ts.map +1 -1
  19. package/dist/color/ColorField.js +341 -81
  20. package/dist/color/ColorField.js.map +1 -1
  21. package/dist/color/ColorField.module.js +4 -2
  22. package/dist/color/ColorField.module.js.map +1 -1
  23. package/dist/color/index.d.ts +1 -0
  24. package/dist/color/index.d.ts.map +1 -1
  25. package/dist/color/index.js +3 -1
  26. package/dist/color/palette.d.ts +23 -0
  27. package/dist/color/palette.d.ts.map +1 -0
  28. package/dist/color/palette.js +34 -0
  29. package/dist/color/palette.js.map +1 -0
  30. package/dist/country/CountryField.css +42 -0
  31. package/dist/country/CountryField.d.ts +19 -4
  32. package/dist/country/CountryField.d.ts.map +1 -1
  33. package/dist/country/CountryField.js +355 -82
  34. package/dist/country/CountryField.js.map +1 -1
  35. package/dist/country/CountryField.module.js +20 -0
  36. package/dist/country/CountryField.module.js.map +1 -0
  37. package/dist/country/index.d.ts +1 -1
  38. package/dist/country/index.d.ts.map +1 -1
  39. package/dist/daterange/DateRangeField.css +9 -0
  40. package/dist/daterange/DateRangeField.d.ts +31 -0
  41. package/dist/daterange/DateRangeField.d.ts.map +1 -0
  42. package/dist/daterange/DateRangeField.js +372 -0
  43. package/dist/daterange/DateRangeField.js.map +1 -0
  44. package/dist/daterange/DateRangeField.module.js +12 -0
  45. package/dist/daterange/DateRangeField.module.js.map +1 -0
  46. package/dist/daterange/index.d.ts +3 -0
  47. package/dist/daterange/index.d.ts.map +1 -0
  48. package/dist/daterange/index.js +3 -0
  49. package/dist/daterange/range.d.ts +61 -0
  50. package/dist/daterange/range.d.ts.map +1 -0
  51. package/dist/daterange/range.js +119 -0
  52. package/dist/daterange/range.js.map +1 -0
  53. package/dist/duration/DurationField.css +1 -1
  54. package/dist/duration/DurationField.d.ts +54 -13
  55. package/dist/duration/DurationField.d.ts.map +1 -1
  56. package/dist/duration/DurationField.js +205 -159
  57. package/dist/duration/DurationField.js.map +1 -1
  58. package/dist/duration/DurationField.module.js.map +1 -1
  59. package/dist/duration/index.d.ts +1 -1
  60. package/dist/duration/index.d.ts.map +1 -1
  61. package/dist/duration/index.js +1 -1
  62. package/dist/embed/EmbedField.d.ts +11 -2
  63. package/dist/embed/EmbedField.d.ts.map +1 -1
  64. package/dist/embed/EmbedField.js +179 -116
  65. package/dist/embed/EmbedField.js.map +1 -1
  66. package/dist/link/LinkField.css +12 -0
  67. package/dist/link/LinkField.d.ts +38 -0
  68. package/dist/link/LinkField.d.ts.map +1 -0
  69. package/dist/link/LinkField.js +742 -0
  70. package/dist/link/LinkField.js.map +1 -0
  71. package/dist/link/LinkField.module.js +8 -0
  72. package/dist/link/LinkField.module.js.map +1 -0
  73. package/dist/link/index.d.ts +3 -0
  74. package/dist/link/index.d.ts.map +1 -0
  75. package/dist/link/index.js +3 -0
  76. package/dist/link/link.d.ts +30 -0
  77. package/dist/link/link.d.ts.map +1 -0
  78. package/dist/link/link.js +63 -0
  79. package/dist/link/link.js.map +1 -0
  80. package/dist/link/pages.d.ts +17 -0
  81. package/dist/link/pages.d.ts.map +1 -0
  82. package/dist/link/pages.js +104 -0
  83. package/dist/link/pages.js.map +1 -0
  84. package/dist/location/LocationField.d.ts.map +1 -1
  85. package/dist/location/LocationField.js +9 -85
  86. package/dist/location/LocationField.js.map +1 -1
  87. package/dist/location/nominatim.d.ts +8 -2
  88. package/dist/location/nominatim.d.ts.map +1 -1
  89. package/dist/location/nominatim.js +32 -3
  90. package/dist/location/nominatim.js.map +1 -1
  91. package/dist/location/search.d.ts +10 -0
  92. package/dist/location/search.d.ts.map +1 -0
  93. package/dist/location/search.js +83 -0
  94. package/dist/location/search.js.map +1 -0
  95. package/dist/location/types.d.ts +8 -2
  96. package/dist/location/types.d.ts.map +1 -1
  97. package/dist/money/MoneyField.d.ts +28 -0
  98. package/dist/money/MoneyField.d.ts.map +1 -0
  99. package/dist/money/MoneyField.js +269 -0
  100. package/dist/money/MoneyField.js.map +1 -0
  101. package/dist/money/index.d.ts +3 -0
  102. package/dist/money/index.d.ts.map +1 -0
  103. package/dist/money/index.js +3 -0
  104. package/dist/money/money.d.ts +27 -0
  105. package/dist/money/money.d.ts.map +1 -0
  106. package/dist/money/money.js +56 -0
  107. package/dist/money/money.js.map +1 -0
  108. package/dist/region/RegionField.d.ts +2 -1
  109. package/dist/region/RegionField.d.ts.map +1 -1
  110. package/dist/region/RegionField.js +92 -54
  111. package/dist/region/RegionField.js.map +1 -1
  112. package/dist/region/RegionFlag.css +9 -0
  113. package/dist/region/RegionFlag.d.ts +20 -0
  114. package/dist/region/RegionFlag.d.ts.map +1 -0
  115. package/dist/region/RegionFlag.js +61 -0
  116. package/dist/region/RegionFlag.js.map +1 -0
  117. package/dist/region/RegionFlag.module.js +8 -0
  118. package/dist/region/RegionFlag.module.js.map +1 -0
  119. package/dist/region/flags/CA.d.ts +4 -0
  120. package/dist/region/flags/CA.d.ts.map +1 -0
  121. package/dist/region/flags/CA.js +21 -0
  122. package/dist/region/flags/CA.js.map +1 -0
  123. package/dist/region/flags/US.d.ts +4 -0
  124. package/dist/region/flags/US.d.ts.map +1 -0
  125. package/dist/region/flags/US.js +65 -0
  126. package/dist/region/flags/US.js.map +1 -0
  127. package/dist/region/flags.d.ts +17 -0
  128. package/dist/region/flags.d.ts.map +1 -0
  129. package/dist/region/flags.js +84 -0
  130. package/dist/region/flags.js.map +1 -0
  131. package/dist/region/index.d.ts +2 -0
  132. package/dist/region/index.d.ts.map +1 -1
  133. package/dist/region/index.js +3 -1
  134. package/dist/shared/CodeComboBox.d.ts +2 -1
  135. package/dist/shared/CodeComboBox.d.ts.map +1 -1
  136. package/dist/shared/CodeComboBox.js.map +1 -1
  137. package/dist/shared/builtIn.d.ts +3 -1
  138. package/dist/shared/builtIn.d.ts.map +1 -1
  139. package/dist/shared/builtIn.js +18 -8
  140. package/dist/shared/builtIn.js.map +1 -1
  141. package/dist/shared/dates.js +2 -2
  142. package/dist/shared/dates.js.map +1 -1
  143. package/dist/shared/flow.d.ts.map +1 -1
  144. package/dist/shared/flow.js +1 -0
  145. package/dist/shared/flow.js.map +1 -1
  146. package/dist/shared/part.d.ts +26 -0
  147. package/dist/shared/part.d.ts.map +1 -0
  148. package/dist/shared/part.js +64 -0
  149. package/dist/shared/part.js.map +1 -0
  150. package/dist/tel/TelField.css +25 -0
  151. package/dist/tel/TelField.d.ts +14 -2
  152. package/dist/tel/TelField.d.ts.map +1 -1
  153. package/dist/tel/TelField.js +246 -145
  154. package/dist/tel/TelField.js.map +1 -1
  155. package/dist/tel/TelField.module.js +12 -0
  156. package/dist/tel/TelField.module.js.map +1 -0
  157. package/dist/tel/index.d.ts +1 -1
  158. package/dist/tel/index.d.ts.map +1 -1
  159. package/dist/tel/index.js +2 -2
  160. package/dist/tel/phone.d.ts +28 -0
  161. package/dist/tel/phone.d.ts.map +1 -1
  162. package/dist/tel/phone.js +48 -1
  163. package/dist/tel/phone.js.map +1 -1
  164. package/dist/url/UrlField.d.ts.map +1 -1
  165. package/dist/url/UrlField.js +1 -1
  166. package/dist/url/UrlField.js.map +1 -1
  167. package/package.json +24 -4
@@ -0,0 +1,269 @@
1
+ import { getFieldProps, getRuleNumber, getSetting, isString } from "../shared/entry.js";
2
+ import { messages } from "../shared/messages.js";
3
+ import { CURRENCY_CODES, getCurrencyName, getMoneyFormatOptions, isMoneyValue, toMoneyValue } from "./money.js";
4
+ import { c } from "react/compiler-runtime";
5
+ import { fromMinorUnits } from "@panneau/protocol/runtime";
6
+ import { useState } from "react";
7
+ import { NumberInput, Select, usePanneauIntl } from "@panneau/ui";
8
+ import { jsx } from "react/jsx-runtime";
9
+ //#region src/money/MoneyField.tsx
10
+ /**
11
+ * An amount and its currency, `{ amount, currency }`, with the amount in minor units (decision
12
+ * 0053): typed in the currency format of the locale, with the digits of the currency, and turned
13
+ * into minor units without floating point errors. A fixed `currency` shows in the amount; otherwise
14
+ * a menu after the amount picks it. Clearing the amount gives `null`.
15
+ */
16
+ function MoneyField(t0) {
17
+ const $ = c(54);
18
+ let currencies;
19
+ let disabled;
20
+ let fixed;
21
+ let max;
22
+ let min;
23
+ let onChange;
24
+ let props;
25
+ let readOnly;
26
+ let required;
27
+ let value;
28
+ if ($[0] !== t0) {
29
+ ({value, onChange, currency: fixed, currencies, min, max, disabled, readOnly, required, ...props} = t0);
30
+ $[0] = t0;
31
+ $[1] = currencies;
32
+ $[2] = disabled;
33
+ $[3] = fixed;
34
+ $[4] = max;
35
+ $[5] = min;
36
+ $[6] = onChange;
37
+ $[7] = props;
38
+ $[8] = readOnly;
39
+ $[9] = required;
40
+ $[10] = value;
41
+ } else {
42
+ currencies = $[1];
43
+ disabled = $[2];
44
+ fixed = $[3];
45
+ max = $[4];
46
+ min = $[5];
47
+ onChange = $[6];
48
+ props = $[7];
49
+ readOnly = $[8];
50
+ required = $[9];
51
+ value = $[10];
52
+ }
53
+ const intl = usePanneauIntl();
54
+ const [picked, setPicked] = useState(null);
55
+ const current = isMoneyValue(value) ? value : null;
56
+ let t1;
57
+ if ($[11] !== currencies || $[12] !== fixed) {
58
+ t1 = fixed !== void 0 && fixed !== null ? [] : currencies !== void 0 && currencies !== null && currencies.length > 0 ? currencies : CURRENCY_CODES;
59
+ $[11] = currencies;
60
+ $[12] = fixed;
61
+ $[13] = t1;
62
+ } else t1 = $[13];
63
+ const choices = t1;
64
+ const currency = fixed ?? (current !== null ? current.currency : picked ?? currencies?.[0] ?? null);
65
+ const hasMenu = choices.length > 0;
66
+ let t2;
67
+ if ($[14] !== currency) {
68
+ t2 = (amount) => fromMinorUnits(amount, currency ?? "");
69
+ $[14] = currency;
70
+ $[15] = t2;
71
+ } else t2 = $[15];
72
+ const toMajor = t2;
73
+ let t3;
74
+ if ($[16] !== choices || $[17] !== currency || $[18] !== current || $[19] !== disabled || $[20] !== hasMenu || $[21] !== intl || $[22] !== onChange || $[23] !== readOnly || $[24] !== toMajor) {
75
+ t3 = hasMenu ? /* @__PURE__ */ jsx(Select, {
76
+ "aria-label": intl.formatMessage(messages.moneyCurrency),
77
+ appearance: "bare",
78
+ isRequired: true,
79
+ isDisabled: disabled === true || readOnly === true,
80
+ placeholder: intl.formatMessage(messages.moneyCurrency),
81
+ options: choices.map((code) => ({
82
+ value: code,
83
+ label: `${code} – ${getCurrencyName(code, intl.locale)}`
84
+ })),
85
+ value: currency,
86
+ renderValue: _temp,
87
+ onChange: (next) => {
88
+ const code_0 = next !== null ? String(next) : null;
89
+ setPicked(code_0);
90
+ if (current !== null) onChange?.(toMoneyValue(toMajor(current.amount), code_0));
91
+ }
92
+ }) : void 0;
93
+ $[16] = choices;
94
+ $[17] = currency;
95
+ $[18] = current;
96
+ $[19] = disabled;
97
+ $[20] = hasMenu;
98
+ $[21] = intl;
99
+ $[22] = onChange;
100
+ $[23] = readOnly;
101
+ $[24] = toMajor;
102
+ $[25] = t3;
103
+ } else t3 = $[25];
104
+ const menu = t3;
105
+ let t4;
106
+ if ($[26] !== current || $[27] !== toMajor) {
107
+ t4 = current !== null ? toMajor(current.amount) : null;
108
+ $[26] = current;
109
+ $[27] = toMajor;
110
+ $[28] = t4;
111
+ } else t4 = $[28];
112
+ let t5;
113
+ if ($[29] !== currency || $[30] !== onChange) {
114
+ t5 = (next_0) => onChange?.(next_0 === null ? null : toMoneyValue(next_0, currency));
115
+ $[29] = currency;
116
+ $[30] = onChange;
117
+ $[31] = t5;
118
+ } else t5 = $[31];
119
+ const t6 = hasMenu ? "narrowSymbol" : "symbol";
120
+ let t7;
121
+ if ($[32] !== currency || $[33] !== t6) {
122
+ t7 = getMoneyFormatOptions(currency, t6);
123
+ $[32] = currency;
124
+ $[33] = t6;
125
+ $[34] = t7;
126
+ } else t7 = $[34];
127
+ let t8;
128
+ if ($[35] !== min || $[36] !== toMajor) {
129
+ t8 = min !== void 0 ? { minValue: toMajor(min) } : {};
130
+ $[35] = min;
131
+ $[36] = toMajor;
132
+ $[37] = t8;
133
+ } else t8 = $[37];
134
+ let t9;
135
+ if ($[38] !== max || $[39] !== toMajor) {
136
+ t9 = max !== void 0 ? { maxValue: toMajor(max) } : {};
137
+ $[38] = max;
138
+ $[39] = toMajor;
139
+ $[40] = t9;
140
+ } else t9 = $[40];
141
+ let t10;
142
+ if ($[41] !== menu) {
143
+ t10 = menu !== void 0 ? { suffix: menu } : {};
144
+ $[41] = menu;
145
+ $[42] = t10;
146
+ } else t10 = $[42];
147
+ let t11;
148
+ if ($[43] !== disabled || $[44] !== props || $[45] !== readOnly || $[46] !== required || $[47] !== t10 || $[48] !== t4 || $[49] !== t5 || $[50] !== t7 || $[51] !== t8 || $[52] !== t9) {
149
+ t11 = /* @__PURE__ */ jsx(NumberInput, {
150
+ ...props,
151
+ value: t4,
152
+ onChange: t5,
153
+ formatOptions: t7,
154
+ ...t8,
155
+ ...t9,
156
+ ...t10,
157
+ isDisabled: disabled,
158
+ isReadOnly: readOnly,
159
+ isRequired: required
160
+ });
161
+ $[43] = disabled;
162
+ $[44] = props;
163
+ $[45] = readOnly;
164
+ $[46] = required;
165
+ $[47] = t10;
166
+ $[48] = t4;
167
+ $[49] = t5;
168
+ $[50] = t7;
169
+ $[51] = t8;
170
+ $[52] = t9;
171
+ $[53] = t11;
172
+ } else t11 = $[53];
173
+ return t11;
174
+ }
175
+ /** The `money` type: settings `currency` and `currencies`, `min` and `max` from its rules. */
176
+ function _temp(option) {
177
+ return String(option.value);
178
+ }
179
+ function MoneyFieldEntry(props) {
180
+ const $ = c(26);
181
+ const { field } = props;
182
+ let t0;
183
+ if ($[0] !== field) {
184
+ t0 = getRuleNumber(field, "min");
185
+ $[0] = field;
186
+ $[1] = t0;
187
+ } else t0 = $[1];
188
+ const min = t0;
189
+ let t1;
190
+ if ($[2] !== field) {
191
+ t1 = getRuleNumber(field, "max");
192
+ $[2] = field;
193
+ $[3] = t1;
194
+ } else t1 = $[3];
195
+ const max = t1;
196
+ let t2;
197
+ if ($[4] !== field) {
198
+ t2 = getSetting(field, "currency", isString);
199
+ $[4] = field;
200
+ $[5] = t2;
201
+ } else t2 = $[5];
202
+ const currency = t2;
203
+ let t3;
204
+ if ($[6] !== field) {
205
+ t3 = getSetting(field, "currencies", _temp2);
206
+ $[6] = field;
207
+ $[7] = t3;
208
+ } else t3 = $[7];
209
+ const currencies = t3;
210
+ let t4;
211
+ if ($[8] !== props) {
212
+ t4 = getFieldProps(props);
213
+ $[8] = props;
214
+ $[9] = t4;
215
+ } else t4 = $[9];
216
+ const t5 = isMoneyValue(props.value) ? props.value : null;
217
+ let t6;
218
+ if ($[10] !== currency) {
219
+ t6 = currency !== void 0 ? { currency } : {};
220
+ $[10] = currency;
221
+ $[11] = t6;
222
+ } else t6 = $[11];
223
+ let t7;
224
+ if ($[12] !== currencies) {
225
+ t7 = currencies !== void 0 ? { currencies } : {};
226
+ $[12] = currencies;
227
+ $[13] = t7;
228
+ } else t7 = $[13];
229
+ let t8;
230
+ if ($[14] !== min) {
231
+ t8 = min !== void 0 ? { min } : {};
232
+ $[14] = min;
233
+ $[15] = t8;
234
+ } else t8 = $[15];
235
+ let t9;
236
+ if ($[16] !== max) {
237
+ t9 = max !== void 0 ? { max } : {};
238
+ $[16] = max;
239
+ $[17] = t9;
240
+ } else t9 = $[17];
241
+ let t10;
242
+ if ($[18] !== props.onChange || $[19] !== t4 || $[20] !== t5 || $[21] !== t6 || $[22] !== t7 || $[23] !== t8 || $[24] !== t9) {
243
+ t10 = /* @__PURE__ */ jsx(MoneyField, {
244
+ ...t4,
245
+ value: t5,
246
+ onChange: props.onChange,
247
+ ...t6,
248
+ ...t7,
249
+ ...t8,
250
+ ...t9
251
+ });
252
+ $[18] = props.onChange;
253
+ $[19] = t4;
254
+ $[20] = t5;
255
+ $[21] = t6;
256
+ $[22] = t7;
257
+ $[23] = t8;
258
+ $[24] = t9;
259
+ $[25] = t10;
260
+ } else t10 = $[25];
261
+ return t10;
262
+ }
263
+ function _temp2(value) {
264
+ return Array.isArray(value) ? value.every(isString) : false;
265
+ }
266
+ //#endregion
267
+ export { MoneyField, MoneyFieldEntry };
268
+
269
+ //# sourceMappingURL=MoneyField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MoneyField.js","names":["useState","fromMinorUnits","NumberInput","Select","usePanneauIntl","getFieldProps","getRuleNumber","getSetting","isString","messages","FieldEntryProps","FieldProps","CURRENCY_CODES","MoneyFieldValue","getCurrencyName","getMoneyFormatOptions","isMoneyValue","toMoneyValue","MoneyFieldProps","currency","currencies","min","max","placeholder","controlClassName","inputClassName","MoneyField","t0","$","_c","disabled","fixed","onChange","props","readOnly","required","value","intl","picked","setPicked","current","t1","undefined","length","choices","hasMenu","t2","amount","toMajor","t3","formatMessage","moneyCurrency","map","code","label","locale","_temp","next","code_0","String","menu","t4","t5","next_0","t6","t7","t8","minValue","t9","maxValue","t10","suffix","t11","option","MoneyFieldEntry","field","_temp2","Array","isArray","every","_c"],"sources":["../../src/money/MoneyField.tsx"],"sourcesContent":["import { useState } from 'react';\n\nimport { fromMinorUnits } from '@panneau/protocol/runtime';\nimport { NumberInput, Select, usePanneauIntl } from '@panneau/ui';\n\nimport { getFieldProps, getRuleNumber, getSetting, isString } from '../shared/entry';\nimport { messages } from '../shared/messages';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\nimport {\n CURRENCY_CODES,\n type MoneyFieldValue,\n getCurrencyName,\n getMoneyFormatOptions,\n isMoneyValue,\n toMoneyValue,\n} from './money';\n\nexport interface MoneyFieldProps extends FieldProps<MoneyFieldValue> {\n /** The currency of every amount (`CAD`): the field shows it, and can't change it. */\n currency?: string | null;\n /**\n * The currencies the user picks from, the first one for a new amount. Without `currency` or\n * `currencies`, every currency.\n */\n currencies?: readonly string[] | null;\n /** The smallest amount, in minor units. */\n min?: number;\n /** The largest amount, in minor units. */\n max?: number;\n placeholder?: string;\n controlClassName?: string;\n inputClassName?: string;\n}\n\n/**\n * An amount and its currency, `{ amount, currency }`, with the amount in minor units (decision\n * 0053): typed in the currency format of the locale, with the digits of the currency, and turned\n * into minor units without floating point errors. A fixed `currency` shows in the amount; otherwise\n * a menu after the amount picks it. Clearing the amount gives `null`.\n */\nexport function MoneyField({\n value,\n onChange,\n currency: fixed,\n currencies,\n min,\n max,\n disabled,\n readOnly,\n required,\n ...props\n}: MoneyFieldProps) {\n const intl = usePanneauIntl();\n // The currency picked before an amount is typed: the value is still `null`.\n const [picked, setPicked] = useState<string | null>(null);\n const current = isMoneyValue(value) ? value : null;\n const choices =\n fixed !== undefined && fixed !== null\n ? []\n : currencies !== undefined && currencies !== null && currencies.length > 0\n ? currencies\n : CURRENCY_CODES;\n const currency =\n fixed ?? (current !== null ? current.currency : (picked ?? currencies?.[0] ?? null));\n const hasMenu = choices.length > 0;\n const toMajor = (amount: number) => fromMinorUnits(amount, currency ?? '');\n\n const menu = hasMenu ? (\n <Select\n aria-label={intl.formatMessage(messages.moneyCurrency)}\n appearance=\"bare\"\n isRequired\n isDisabled={disabled === true || readOnly === true}\n placeholder={intl.formatMessage(messages.moneyCurrency)}\n options={choices.map((code) => ({\n value: code,\n label: `${code} – ${getCurrencyName(code, intl.locale)}`,\n }))}\n value={currency}\n renderValue={(option) => String(option.value)}\n onChange={(next) => {\n const code = next !== null ? String(next) : null;\n setPicked(code);\n if (current !== null) {\n // The same amount, in the digits of the currency picked.\n onChange?.(toMoneyValue(toMajor(current.amount), code));\n }\n }}\n />\n ) : undefined;\n\n return (\n <NumberInput\n {...props}\n value={current !== null ? toMajor(current.amount) : null}\n onChange={(next) => onChange?.(next === null ? null : toMoneyValue(next, currency))}\n formatOptions={getMoneyFormatOptions(currency, hasMenu ? 'narrowSymbol' : 'symbol')}\n {...(min !== undefined ? { minValue: toMajor(min) } : {})}\n {...(max !== undefined ? { maxValue: toMajor(max) } : {})}\n {...(menu !== undefined ? { suffix: menu } : {})}\n isDisabled={disabled}\n isReadOnly={readOnly}\n isRequired={required}\n />\n );\n}\n\n/** The `money` type: settings `currency` and `currencies`, `min` and `max` from its rules. */\nexport function MoneyFieldEntry(props: FieldEntryProps) {\n const { field } = props;\n const min = getRuleNumber(field, 'min');\n const max = getRuleNumber(field, 'max');\n const currency = getSetting(field, 'currency', isString);\n const currencies = getSetting(field, 'currencies', (value): value is string[] =>\n Array.isArray(value) ? value.every(isString) : false,\n );\n return (\n <MoneyField\n {...getFieldProps(props)}\n value={isMoneyValue(props.value) ? props.value : null}\n onChange={props.onChange}\n {...(currency !== undefined ? { currency } : {})}\n {...(currencies !== undefined ? { currencies } : {})}\n {...(min !== undefined ? { min } : {})}\n {...(max !== undefined ? { max } : {})}\n />\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { MoneyField, MoneyFieldEntry, type MoneyFieldProps } from './MoneyField.js';
2
+ export { type MoneyFieldValue, formatMoney, getCurrencyName, getMoneyFormatOptions, isMoneyValue, toMoneyValue, } from './money.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/money/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EACH,KAAK,eAAe,EACpB,WAAW,EACX,eAAe,EACf,qBAAqB,EACrB,YAAY,EACZ,YAAY,GACf,MAAM,SAAS,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { formatMoney, getCurrencyName, getMoneyFormatOptions, isMoneyValue, toMoneyValue } from "./money.js";
2
+ import { MoneyField, MoneyFieldEntry } from "./MoneyField.js";
3
+ export { MoneyField, MoneyFieldEntry, formatMoney, getCurrencyName, getMoneyFormatOptions, isMoneyValue, toMoneyValue };
@@ -0,0 +1,27 @@
1
+ import { CURRENCY_CODES, fromMinorUnits, getCurrencyDigits, toMinorUnits } from '@panneau/protocol/runtime';
2
+ /**
3
+ * A `money` value as a field holds it (decision 0053): an amount in minor units, and its currency,
4
+ * `null` while an amount is typed before a currency is picked, which the `money` rule refuses.
5
+ */
6
+ export interface MoneyFieldValue {
7
+ amount: number;
8
+ currency: string | null;
9
+ }
10
+ /** Whether a value is a `money` value: an amount and a currency, as the field holds it. */
11
+ export declare function isMoneyValue(value: unknown): value is MoneyFieldValue;
12
+ /** The name of a currency in a locale (`dollar canadien`), or its code. */
13
+ export declare function getCurrencyName(code: string, locale: string): string;
14
+ /**
15
+ * The format of an amount of a currency in a locale, with the digits of the currency in ISO 4217:
16
+ * `12,50 $` for 12.50 CAD in French, `¥1,250` for JPY.
17
+ */
18
+ export declare function getMoneyFormatOptions(currency: string | null, currencyDisplay?: Intl.NumberFormatOptions['currencyDisplay']): Intl.NumberFormatOptions;
19
+ /**
20
+ * An amount in minor units with its currency, in the format of the locale: `1 250,00 $` for
21
+ * `{ "amount": 125000, "currency": "CAD" }` in French. `null` for a value that isn't money.
22
+ */
23
+ export declare function formatMoney(value: unknown, locale: string): string | null;
24
+ /** An amount typed in major units, in minor units of its currency. */
25
+ export declare function toMoneyValue(major: number, currency: string | null): MoneyFieldValue;
26
+ export { CURRENCY_CODES, fromMinorUnits, getCurrencyDigits, toMinorUnits };
27
+ //# sourceMappingURL=money.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"money.d.ts","sourceRoot":"","sources":["../../src/money/money.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,cAAc,EACd,cAAc,EACd,iBAAiB,EAEjB,YAAY,EACf,MAAM,2BAA2B,CAAC;AAEnC;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,2FAA2F;AAC3F,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAQrE;AAED,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAMpE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACjC,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,eAAe,GAAE,IAAI,CAAC,mBAAmB,CAAC,iBAAiB,CAAY,GACxE,IAAI,CAAC,mBAAmB,CAS1B;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYzE;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,eAAe,CAEpF;AAED,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,iBAAiB,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { CURRENCY_CODES, fromMinorUnits as fromMinorUnits$1, getCurrencyDigits, isCurrencyCode, toMinorUnits } from "@panneau/protocol/runtime";
2
+ //#region src/money/money.ts
3
+ /** Whether a value is a `money` value: an amount and a currency, as the field holds it. */
4
+ function isMoneyValue(value) {
5
+ return typeof value === "object" && value !== null && typeof value.amount === "number" && "currency" in value && (typeof value.currency === "string" || value.currency === null);
6
+ }
7
+ /** The name of a currency in a locale (`dollar canadien`), or its code. */
8
+ function getCurrencyName(code, locale) {
9
+ try {
10
+ return new Intl.DisplayNames([locale], { type: "currency" }).of(code) ?? code;
11
+ } catch {
12
+ return code;
13
+ }
14
+ }
15
+ /**
16
+ * The format of an amount of a currency in a locale, with the digits of the currency in ISO 4217:
17
+ * `12,50 $` for 12.50 CAD in French, `¥1,250` for JPY.
18
+ */
19
+ function getMoneyFormatOptions(currency, currencyDisplay = "symbol") {
20
+ const digits = getCurrencyDigits(currency ?? "");
21
+ return {
22
+ ...currency !== null && isCurrencyCode(currency) ? {
23
+ style: "currency",
24
+ currency,
25
+ currencyDisplay
26
+ } : {},
27
+ minimumFractionDigits: digits,
28
+ maximumFractionDigits: digits
29
+ };
30
+ }
31
+ /**
32
+ * An amount in minor units with its currency, in the format of the locale: `1 250,00 $` for
33
+ * `{ "amount": 125000, "currency": "CAD" }` in French. `null` for a value that isn't money.
34
+ */
35
+ function formatMoney(value, locale) {
36
+ if (!isMoneyValue(value)) return null;
37
+ const { amount, currency } = value;
38
+ const major = fromMinorUnits$1(amount, currency ?? "");
39
+ try {
40
+ const text = new Intl.NumberFormat(locale, getMoneyFormatOptions(currency)).format(major);
41
+ return currency !== null && !isCurrencyCode(currency) ? `${text} ${currency}` : text;
42
+ } catch {
43
+ return `${String(major)} ${currency ?? ""}`.trim();
44
+ }
45
+ }
46
+ /** An amount typed in major units, in minor units of its currency. */
47
+ function toMoneyValue(major, currency) {
48
+ return {
49
+ amount: toMinorUnits(major, currency ?? ""),
50
+ currency
51
+ };
52
+ }
53
+ //#endregion
54
+ export { CURRENCY_CODES, formatMoney, fromMinorUnits$1 as fromMinorUnits, getCurrencyDigits, getCurrencyName, getMoneyFormatOptions, isMoneyValue, toMinorUnits, toMoneyValue };
55
+
56
+ //# sourceMappingURL=money.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"money.js","names":["CURRENCY_CODES","fromMinorUnits","getCurrencyDigits","isCurrencyCode","toMinorUnits","MoneyFieldValue","amount","currency","isMoneyValue","value","getCurrencyName","code","locale","Intl","DisplayNames","type","of","getMoneyFormatOptions","currencyDisplay","NumberFormatOptions","digits","style","minimumFractionDigits","maximumFractionDigits","formatMoney","major","text","NumberFormat","format","String","trim","toMoneyValue","fromMinorUnits"],"sources":["../../src/money/money.ts"],"sourcesContent":["import {\n CURRENCY_CODES,\n fromMinorUnits,\n getCurrencyDigits,\n isCurrencyCode,\n toMinorUnits,\n} from '@panneau/protocol/runtime';\n\n/**\n * A `money` value as a field holds it (decision 0053): an amount in minor units, and its currency,\n * `null` while an amount is typed before a currency is picked, which the `money` rule refuses.\n */\nexport interface MoneyFieldValue {\n amount: number;\n currency: string | null;\n}\n\n/** Whether a value is a `money` value: an amount and a currency, as the field holds it. */\nexport function isMoneyValue(value: unknown): value is MoneyFieldValue {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as { amount?: unknown }).amount === 'number' &&\n 'currency' in value &&\n (typeof value.currency === 'string' || value.currency === null)\n );\n}\n\n/** The name of a currency in a locale (`dollar canadien`), or its code. */\nexport function getCurrencyName(code: string, locale: string): string {\n try {\n return new Intl.DisplayNames([locale], { type: 'currency' }).of(code) ?? code;\n } catch {\n return code;\n }\n}\n\n/**\n * The format of an amount of a currency in a locale, with the digits of the currency in ISO 4217:\n * `12,50 $` for 12.50 CAD in French, `¥1,250` for JPY.\n */\nexport function getMoneyFormatOptions(\n currency: string | null,\n currencyDisplay: Intl.NumberFormatOptions['currencyDisplay'] = 'symbol',\n): Intl.NumberFormatOptions {\n const digits = getCurrencyDigits(currency ?? '');\n return {\n ...(currency !== null && isCurrencyCode(currency)\n ? { style: 'currency', currency, currencyDisplay }\n : {}),\n minimumFractionDigits: digits,\n maximumFractionDigits: digits,\n };\n}\n\n/**\n * An amount in minor units with its currency, in the format of the locale: `1 250,00 $` for\n * `{ \"amount\": 125000, \"currency\": \"CAD\" }` in French. `null` for a value that isn't money.\n */\nexport function formatMoney(value: unknown, locale: string): string | null {\n if (!isMoneyValue(value)) {\n return null;\n }\n const { amount, currency } = value;\n const major = fromMinorUnits(amount, currency ?? '');\n try {\n const text = new Intl.NumberFormat(locale, getMoneyFormatOptions(currency)).format(major);\n return currency !== null && !isCurrencyCode(currency) ? `${text} ${currency}` : text;\n } catch {\n return `${String(major)} ${currency ?? ''}`.trim();\n }\n}\n\n/** An amount typed in major units, in minor units of its currency. */\nexport function toMoneyValue(major: number, currency: string | null): MoneyFieldValue {\n return { amount: toMinorUnits(major, currency ?? ''), currency };\n}\n\nexport { CURRENCY_CODES, fromMinorUnits, getCurrencyDigits, toMinorUnits };\n"],"mappings":";;;AAkBA,SAAgBQ,aAAaC,OAA0C;CACnE,OACI,OAAOA,UAAU,YACjBA,UAAU,QACV,OAAQA,MAA+BH,WAAW,YAClD,cAAcG,UACb,OAAOA,MAAMF,aAAa,YAAYE,MAAMF,aAAa;AAElE;;AAGA,SAAgBG,gBAAgBC,MAAcC,QAAwB;CAClE,IAAI;EACA,OAAO,IAAIC,KAAKC,aAAa,CAACF,MAAM,GAAG,EAAEG,MAAM,WAAW,CAAC,CAAC,CAACC,GAAGL,IAAI,KAAKA;CAC7E,QAAQ;EACJ,OAAOA;CACX;AACJ;;;;;AAMA,SAAgBM,sBACZV,UACAW,kBAA+D,UACvC;CACxB,MAAME,SAASlB,kBAAkBK,YAAY,EAAE;CAC/C,OAAO;EACH,GAAIA,aAAa,QAAQJ,eAAeI,QAAQ,IAC1C;GAAEc,OAAO;GAAYd;GAAUW;EAAgB,IAC/C,CAAC;EACPI,uBAAuBF;EACvBG,uBAAuBH;CAC3B;AACJ;;;;;AAMA,SAAgBI,YAAYf,OAAgBG,QAA+B;CACvE,IAAI,CAACJ,aAAaC,KAAK,GACnB,OAAO;CAEX,MAAM,EAAEH,QAAQC,aAAaE;CAC7B,MAAMgB,QAAQxB,iBAAeK,QAAQC,YAAY,EAAE;CACnD,IAAI;EACA,MAAMmB,OAAO,IAAIb,KAAKc,aAAaf,QAAQK,sBAAsBV,QAAQ,CAAC,CAAC,CAACqB,OAAOH,KAAK;EACxF,OAAOlB,aAAa,QAAQ,CAACJ,eAAeI,QAAQ,IAAI,GAAGmB,KAAI,GAAInB,aAAamB;CACpF,QAAQ;EACJ,OAAO,GAAGG,OAAOJ,KAAK,EAAC,GAAIlB,YAAY,KAAKuB,KAAK;CACrD;AACJ;;AAGA,SAAgBC,aAAaN,OAAelB,UAA0C;CAClF,OAAO;EAAED,QAAQF,aAAaqB,OAAOlB,YAAY,EAAE;EAAGA;CAAS;AACnE"}
@@ -9,7 +9,8 @@ export interface RegionFieldProps extends FieldProps<string> {
9
9
  /**
10
10
  * A state, a province or a territory of a country. For the countries that Panneau knows the
11
11
  * regions of, a combo box of their names in the user's locale, whose value is the code of the
12
- * region without its country (`QC`). For the others, the region as typed.
12
+ * region without its country (`QC`), with their flags for the countries that have them (Canada and
13
+ * the United States). For the others, the region as typed.
13
14
  */
14
15
  export declare function RegionField({ country, placeholder, ...props }: RegionFieldProps): import("react").JSX.Element;
15
16
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"RegionField.d.ts","sourceRoot":"","sources":["../../src/region/RegionField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAM/C,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAInE,MAAM,WAAW,gBAAiB,SAAQ,UAAU,CAAC,MAAM,CAAC;IACxD,oGAAoG;IACpG,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,+BAoB/E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQlF;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,+BAStD"}
1
+ {"version":3,"file":"RegionField.d.ts","sourceRoot":"","sources":["../../src/region/RegionField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAM/C,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAMnE,MAAM,WAAW,gBAAiB,SAAQ,UAAU,CAAC,MAAM,CAAC;IACxD,oGAAoG;IACpG,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,+BA0B/E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQlF;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,+BAStD"}
@@ -1,7 +1,9 @@
1
1
  import { getFieldProps, getSetting, isString } from "../shared/entry.js";
2
2
  import { messages } from "../shared/messages.js";
3
- import { TextField } from "../text/TextField.js";
4
3
  import { CodeComboBox } from "../shared/CodeComboBox.js";
4
+ import { TextField } from "../text/TextField.js";
5
+ import { getRegionFlag, useRegionFlags } from "./flags.js";
6
+ import { FlagImage } from "./RegionFlag.js";
5
7
  import { getRegions } from "./regions.js";
6
8
  import { c } from "react/compiler-runtime";
7
9
  import { usePanneauIntl } from "@panneau/ui";
@@ -10,10 +12,11 @@ import { jsx } from "react/jsx-runtime";
10
12
  /**
11
13
  * A state, a province or a territory of a country. For the countries that Panneau knows the
12
14
  * regions of, a combo box of their names in the user's locale, whose value is the code of the
13
- * region without its country (`QC`). For the others, the region as typed.
15
+ * region without its country (`QC`), with their flags for the countries that have them (Canada and
16
+ * the United States). For the others, the region as typed.
14
17
  */
15
18
  function RegionField(t0) {
16
- const $ = c(22);
19
+ const $ = c(31);
17
20
  let country;
18
21
  let placeholder;
19
22
  let props;
@@ -29,62 +32,97 @@ function RegionField(t0) {
29
32
  props = $[3];
30
33
  }
31
34
  const intl = usePanneauIntl();
35
+ const flags = useRegionFlags(country);
36
+ let T0;
32
37
  let t1;
33
- if ($[4] !== country || $[5] !== intl.locale) {
34
- t1 = getRegions(country, intl.locale);
35
- $[4] = country;
36
- $[5] = intl.locale;
37
- $[6] = t1;
38
- } else t1 = $[6];
39
- const regions = t1;
40
- if (regions === null) {
41
- let t2;
42
- if ($[7] !== placeholder) {
43
- t2 = placeholder !== void 0 ? { placeholder } : {};
44
- $[7] = placeholder;
45
- $[8] = t2;
46
- } else t2 = $[8];
47
- let t3;
48
- if ($[9] !== props || $[10] !== t2) {
49
- t3 = /* @__PURE__ */ jsx(TextField, {
50
- autoComplete: "address-level1",
51
- ...props,
52
- ...t2
53
- });
54
- $[9] = props;
55
- $[10] = t2;
56
- $[11] = t3;
57
- } else t3 = $[11];
58
- return t3;
59
- }
60
38
  let t2;
61
- if ($[12] !== intl || $[13] !== placeholder) {
62
- t2 = placeholder ?? intl.formatMessage(messages.regionPlaceholder);
63
- $[12] = intl;
64
- $[13] = placeholder;
65
- $[14] = t2;
66
- } else t2 = $[14];
67
39
  let t3;
68
- if ($[15] !== intl) {
69
- t3 = intl.formatMessage(messages.noRegions);
70
- $[15] = intl;
71
- $[16] = t3;
72
- } else t3 = $[16];
40
+ if ($[4] !== country || $[5] !== flags || $[6] !== intl.locale || $[7] !== placeholder || $[8] !== props) {
41
+ t3 = Symbol.for("react.early_return_sentinel");
42
+ bb0: {
43
+ const regions = getRegions(country, intl.locale);
44
+ if (regions === null) {
45
+ let t4;
46
+ if ($[13] !== placeholder) {
47
+ t4 = placeholder !== void 0 ? { placeholder } : {};
48
+ $[13] = placeholder;
49
+ $[14] = t4;
50
+ } else t4 = $[14];
51
+ let t5;
52
+ if ($[15] !== props || $[16] !== t4) {
53
+ t5 = /* @__PURE__ */ jsx(TextField, {
54
+ autoComplete: "address-level1",
55
+ ...props,
56
+ ...t4
57
+ });
58
+ $[15] = props;
59
+ $[16] = t4;
60
+ $[17] = t5;
61
+ } else t5 = $[17];
62
+ t3 = t5;
63
+ break bb0;
64
+ }
65
+ T0 = CodeComboBox;
66
+ t1 = props;
67
+ let t4;
68
+ if ($[18] !== flags) {
69
+ t4 = (region) => {
70
+ const flag = getRegionFlag(flags, region.code);
71
+ return flag !== void 0 ? {
72
+ ...region,
73
+ prefix: /* @__PURE__ */ jsx(FlagImage, { src: flag })
74
+ } : region;
75
+ };
76
+ $[18] = flags;
77
+ $[19] = t4;
78
+ } else t4 = $[19];
79
+ t2 = regions.map(t4);
80
+ }
81
+ $[4] = country;
82
+ $[5] = flags;
83
+ $[6] = intl.locale;
84
+ $[7] = placeholder;
85
+ $[8] = props;
86
+ $[9] = T0;
87
+ $[10] = t1;
88
+ $[11] = t2;
89
+ $[12] = t3;
90
+ } else {
91
+ T0 = $[9];
92
+ t1 = $[10];
93
+ t2 = $[11];
94
+ t3 = $[12];
95
+ }
96
+ if (t3 !== Symbol.for("react.early_return_sentinel")) return t3;
73
97
  let t4;
74
- if ($[17] !== props || $[18] !== regions || $[19] !== t2 || $[20] !== t3) {
75
- t4 = /* @__PURE__ */ jsx(CodeComboBox, {
76
- ...props,
77
- choices: regions,
78
- placeholder: t2,
79
- emptyMessage: t3
98
+ if ($[20] !== intl || $[21] !== placeholder) {
99
+ t4 = placeholder ?? intl.formatMessage(messages.regionPlaceholder);
100
+ $[20] = intl;
101
+ $[21] = placeholder;
102
+ $[22] = t4;
103
+ } else t4 = $[22];
104
+ let t5;
105
+ if ($[23] !== intl) {
106
+ t5 = intl.formatMessage(messages.noRegions);
107
+ $[23] = intl;
108
+ $[24] = t5;
109
+ } else t5 = $[24];
110
+ let t6;
111
+ if ($[25] !== T0 || $[26] !== t1 || $[27] !== t2 || $[28] !== t4 || $[29] !== t5) {
112
+ t6 = /* @__PURE__ */ jsx(T0, {
113
+ ...t1,
114
+ choices: t2,
115
+ placeholder: t4,
116
+ emptyMessage: t5
80
117
  });
81
- $[17] = props;
82
- $[18] = regions;
83
- $[19] = t2;
84
- $[20] = t3;
85
- $[21] = t4;
86
- } else t4 = $[21];
87
- return t4;
118
+ $[25] = T0;
119
+ $[26] = t1;
120
+ $[27] = t2;
121
+ $[28] = t4;
122
+ $[29] = t5;
123
+ $[30] = t6;
124
+ } else t6 = $[30];
125
+ return t6;
88
126
  }
89
127
  /**
90
128
  * The country of a `region` field: the value of the field that `from` names in the same object,
@@ -1 +1 @@
1
- {"version":3,"file":"RegionField.js","names":["Field","usePanneauIntl","CodeComboBox","getFieldProps","getSetting","isString","messages","FieldEntryProps","FieldProps","TextField","getRegions","RegionFieldProps","country","placeholder","controlClassName","RegionField","t0","$","_c","props","intl","t1","locale","regions","t2","undefined","t3","formatMessage","regionPlaceholder","noRegions","t4","getRegionCountry","field","parentValue","from","Record","RegionFieldEntry","value","onChange","_c"],"sources":["../../src/region/RegionField.tsx"],"sourcesContent":["import type { Field } from '@panneau/protocol';\nimport { usePanneauIntl } from '@panneau/ui';\n\nimport { CodeComboBox } from '../shared/CodeComboBox';\nimport { getFieldProps, getSetting, isString } from '../shared/entry';\nimport { messages } from '../shared/messages';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\nimport { TextField } from '../text/TextField';\nimport { getRegions } from './regions';\n\nexport interface RegionFieldProps extends FieldProps<string> {\n /** The country of the region (`CA`). Without it, or for a country without known regions, a text. */\n country?: string | null;\n placeholder?: string;\n controlClassName?: string;\n}\n\n/**\n * A state, a province or a territory of a country. For the countries that Panneau knows the\n * regions of, a combo box of their names in the user's locale, whose value is the code of the\n * region without its country (`QC`). For the others, the region as typed.\n */\nexport function RegionField({ country, placeholder, ...props }: RegionFieldProps) {\n const intl = usePanneauIntl();\n const regions = getRegions(country, intl.locale);\n if (regions === null) {\n return (\n <TextField\n autoComplete=\"address-level1\"\n {...props}\n {...(placeholder !== undefined ? { placeholder } : {})}\n />\n );\n }\n return (\n <CodeComboBox\n {...props}\n choices={regions}\n placeholder={placeholder ?? intl.formatMessage(messages.regionPlaceholder)}\n emptyMessage={intl.formatMessage(messages.noRegions)}\n />\n );\n}\n\n/**\n * The country of a `region` field: the value of the field that `from` names in the same object,\n * or `settings.country`.\n */\nexport function getRegionCountry(field: Field, parentValue: unknown): string | null {\n if (field.from !== undefined && parentValue !== null && typeof parentValue === 'object') {\n const country = (parentValue as Record<string, unknown>)[field.from];\n if (isString(country) && country !== '') {\n return country;\n }\n }\n return getSetting(field, 'country', isString) ?? null;\n}\n\n/** The `region` type: its country from `from` or `settings.country`. */\nexport function RegionFieldEntry(props: FieldEntryProps) {\n return (\n <RegionField\n {...getFieldProps(props)}\n country={getRegionCountry(props.field, props.parentValue)}\n value={isString(props.value) ? props.value : null}\n onChange={props.onChange}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAsBA,SAAOe,YAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAN;CAAA,IAAAC;CAAA,IAAAM;CAAA,IAAAF,EAAA,OAAAD,IAAA;EAAqB,CAAA,CAAAJ,SAAAC,aAAA,GAAAM,SAAAH;EAAoDC,EAAA,KAAAD;EAAAC,EAAA,KAAAL;EAAAK,EAAA,KAAAJ;EAAAI,EAAA,KAAAE;CAAA,OAAA;EAAAP,UAAAK,EAAA;EAAAJ,cAAAI,EAAA;EAAAE,QAAAF,EAAA;CAAA;CAC5E,MAAAG,OAAanB,eAAe;CAAE,IAAAoB;CAAA,IAAAJ,EAAA,OAAAL,WAAAK,EAAA,OAAAG,KAAAE,QAAA;EACdD,KAAAX,WAAWE,SAASQ,KAAIE,MAAO;EAACL,EAAA,KAAAL;EAAAK,EAAA,KAAAG,KAAAE;EAAAL,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CAAhD,MAAAM,UAAgBF;CAChB,IAAIE,YAAY,MAAI;EAAA,IAAAC;EAAA,IAAAP,EAAA,OAAAJ,aAAA;GAKHW,KAAAX,gBAAgBY,KAAAA,IAAhB,EAAAZ,YAA+C,IAA/C,CAA+C;GAACI,EAAA,KAAAJ;GAAAI,EAAA,KAAAO;EAAA,OAAAA,KAAAP,EAAA;EAAA,IAAAS;EAAA,IAAAT,EAAA,OAAAE,SAAAF,EAAA,QAAAO,IAAA;GAHzDE,KAAA,oBAAC,WAAD;IACiB,cAAA;IAAgB,GACzBP;IAAK,GACJK;GAAgD,CAAA;GACvDP,EAAA,KAAAE;GAAAF,EAAA,MAAAO;GAAAP,EAAA,MAAAS;EAAA,OAAAA,KAAAT,EAAA;EAAA,OAJFS;CAIE;CAET,IAAAF;CAAA,IAAAP,EAAA,QAAAG,QAAAH,EAAA,QAAAJ,aAAA;EAKoBW,KAAAX,eAAeO,KAAIO,cAAerB,SAAQsB,iBAAkB;EAACX,EAAA,MAAAG;EAAAH,EAAA,MAAAJ;EAAAI,EAAA,MAAAO;CAAA,OAAAA,KAAAP,EAAA;CAAA,IAAAS;CAAA,IAAAT,EAAA,QAAAG,MAAA;EAC5DM,KAAAN,KAAIO,cAAerB,SAAQuB,SAAU;EAACZ,EAAA,MAAAG;EAAAH,EAAA,MAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,IAAAa;CAAA,IAAAb,EAAA,QAAAE,SAAAF,EAAA,QAAAM,WAAAN,EAAA,QAAAO,MAAAP,EAAA,QAAAS,IAAA;EAJxDI,KAAA,oBAAC,cAAD;GAAa,GACLX;GACKI,SAAAA;GACI,aAAAC;GACC,cAAAE;EAAsC,CAAA;EACtDT,EAAA,MAAAE;EAAAF,EAAA,MAAAM;EAAAN,EAAA,MAAAO;EAAAP,EAAA,MAAAS;EAAAT,EAAA,MAAAa;CAAA,OAAAA,KAAAb,EAAA;CAAA,OALFa;AAKE;;;;;AAQV,SAAgBC,iBAAiBC,OAAcC,aAAqC;CAChF,IAAID,MAAME,SAAST,KAAAA,KAAaQ,gBAAgB,QAAQ,OAAOA,gBAAgB,UAAU;EACrF,MAAMrB,UAAWqB,YAAwCD,MAAME;EAC/D,IAAI7B,SAASO,OAAO,KAAKA,YAAY,IACjC,OAAOA;CAEf;CACA,OAAOR,WAAW4B,OAAO,WAAW3B,QAAQ,KAAK;AACrD;;AAGA,SAAO+B,iBAAAjB,OAAA;CAAA,MAAAF,IAAAC,EAAA,EAAA;CAAA,IAAAF;CAAA,IAAAC,EAAA,OAAAE,OAAA;EAGSH,KAAAb,cAAcgB,KAAK;EAACF,EAAA,KAAAE;EAAAF,EAAA,KAAAD;CAAA,OAAAA,KAAAC,EAAA;CAAA,IAAAI;CAAA,IAAAJ,EAAA,OAAAE,MAAAa,SAAAf,EAAA,OAAAE,MAAAc,aAAA;EACfZ,KAAAU,iBAAiBZ,MAAKa,OAAQb,MAAKc,WAAY;EAAChB,EAAA,KAAAE,MAAAa;EAAAf,EAAA,KAAAE,MAAAc;EAAAhB,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CAClD,MAAAO,KAAAnB,SAASc,MAAKkB,KAA2B,IAAjBlB,MAAKkB,QAA7B;CAA0C,IAAAX;CAAA,IAAAT,EAAA,OAAAE,MAAAmB,YAAArB,EAAA,OAAAD,MAAAC,EAAA,OAAAI,MAAAJ,EAAA,OAAAO,IAAA;EAHrDE,KAAA,oBAAC,aAAD;GAAY,GACJV;GACK,SAAAK;GACF,OAAAG;GACG,UAAAL,MAAKmB;EAAS,CAAA;EAC1BrB,EAAA,KAAAE,MAAAmB;EAAArB,EAAA,KAAAD;EAAAC,EAAA,KAAAI;EAAAJ,EAAA,KAAAO;EAAAP,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,OALFS;AAKE"}
1
+ {"version":3,"file":"RegionField.js","names":["Field","usePanneauIntl","CodeComboBox","getFieldProps","getSetting","isString","messages","FieldEntryProps","FieldProps","TextField","FlagImage","getRegionFlag","useRegionFlags","getRegions","RegionFieldProps","country","placeholder","controlClassName","RegionField","t0","$","_c","props","intl","flags","T0","t1","t2","t3","locale","Symbol","for","bb0","regions","t4","undefined","t5","region","flag","code","prefix","map","formatMessage","regionPlaceholder","noRegions","t6","getRegionCountry","field","parentValue","from","Record","RegionFieldEntry","value","onChange","_c"],"sources":["../../src/region/RegionField.tsx"],"sourcesContent":["import type { Field } from '@panneau/protocol';\nimport { usePanneauIntl } from '@panneau/ui';\n\nimport { CodeComboBox } from '../shared/CodeComboBox';\nimport { getFieldProps, getSetting, isString } from '../shared/entry';\nimport { messages } from '../shared/messages';\nimport type { FieldEntryProps, FieldProps } from '../shared/types';\nimport { TextField } from '../text/TextField';\nimport { FlagImage } from './RegionFlag';\nimport { getRegionFlag, useRegionFlags } from './flags';\nimport { getRegions } from './regions';\n\nexport interface RegionFieldProps extends FieldProps<string> {\n /** The country of the region (`CA`). Without it, or for a country without known regions, a text. */\n country?: string | null;\n placeholder?: string;\n controlClassName?: string;\n}\n\n/**\n * A state, a province or a territory of a country. For the countries that Panneau knows the\n * regions of, a combo box of their names in the user's locale, whose value is the code of the\n * region without its country (`QC`), with their flags for the countries that have them (Canada and\n * the United States). For the others, the region as typed.\n */\nexport function RegionField({ country, placeholder, ...props }: RegionFieldProps) {\n const intl = usePanneauIntl();\n const flags = useRegionFlags(country);\n const regions = getRegions(country, intl.locale);\n if (regions === null) {\n return (\n <TextField\n autoComplete=\"address-level1\"\n {...props}\n {...(placeholder !== undefined ? { placeholder } : {})}\n />\n );\n }\n return (\n <CodeComboBox\n {...props}\n choices={regions.map((region) => {\n const flag = getRegionFlag(flags, region.code);\n return flag !== undefined\n ? { ...region, prefix: <FlagImage src={flag} /> }\n : region;\n })}\n placeholder={placeholder ?? intl.formatMessage(messages.regionPlaceholder)}\n emptyMessage={intl.formatMessage(messages.noRegions)}\n />\n );\n}\n\n/**\n * The country of a `region` field: the value of the field that `from` names in the same object,\n * or `settings.country`.\n */\nexport function getRegionCountry(field: Field, parentValue: unknown): string | null {\n if (field.from !== undefined && parentValue !== null && typeof parentValue === 'object') {\n const country = (parentValue as Record<string, unknown>)[field.from];\n if (isString(country) && country !== '') {\n return country;\n }\n }\n return getSetting(field, 'country', isString) ?? null;\n}\n\n/** The `region` type: its country from `from` or `settings.country`. */\nexport function RegionFieldEntry(props: FieldEntryProps) {\n return (\n <RegionField\n {...getFieldProps(props)}\n country={getRegionCountry(props.field, props.parentValue)}\n value={isString(props.value) ? props.value : null}\n onChange={props.onChange}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAyBA,SAAOkB,YAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAN;CAAA,IAAAC;CAAA,IAAAM;CAAA,IAAAF,EAAA,OAAAD,IAAA;EAAqB,CAAA,CAAAJ,SAAAC,aAAA,GAAAM,SAAAH;EAAoDC,EAAA,KAAAD;EAAAC,EAAA,KAAAL;EAAAK,EAAA,KAAAJ;EAAAI,EAAA,KAAAE;CAAA,OAAA;EAAAP,UAAAK,EAAA;EAAAJ,cAAAI,EAAA;EAAAE,QAAAF,EAAA;CAAA;CAC5E,MAAAG,OAAatB,eAAe;CAC5B,MAAAuB,QAAcZ,eAAeG,OAAO;CAAE,IAAAU;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAR,EAAA,OAAAL,WAAAK,EAAA,OAAAI,SAAAJ,EAAA,OAAAG,KAAAM,UAAAT,EAAA,OAAAJ,eAAAI,EAAA,OAAAE,OAAA;EAI9BM,KAAAE,OAIEC,IAJF,6BAIC;EAACC,KAAA;GAPV,MAAAC,UAAgBpB,WAAWE,SAASQ,KAAIM,MAAO;GAC/C,IAAII,YAAY,MAAI;IAAA,IAAAC;IAAA,IAAAd,EAAA,QAAAJ,aAAA;KAKHkB,KAAAlB,gBAAgBmB,KAAAA,IAAhB,EAAAnB,YAA+C,IAA/C,CAA+C;KAACI,EAAA,MAAAJ;KAAAI,EAAA,MAAAc;IAAA,OAAAA,KAAAd,EAAA;IAAA,IAAAgB;IAAA,IAAAhB,EAAA,QAAAE,SAAAF,EAAA,QAAAc,IAAA;KAHzDE,KAAA,oBAAC,WAAD;MACiB,cAAA;MAAgB,GACzBd;MAAK,GACJY;KAAgD,CAAA;KACvDd,EAAA,MAAAE;KAAAF,EAAA,MAAAc;KAAAd,EAAA,MAAAgB;IAAA,OAAAA,KAAAhB,EAAA;IAJFQ,KAAAQ;IAAA,MAAAJ;GAIE;GAILP,KAAAvB;GACOoB,KAAAA;GAAK,IAAAY;GAAA,IAAAd,EAAA,QAAAI,OAAA;IACYU,MAAAG,WAAA;KACjB,MAAAC,OAAa3B,cAAca,OAAOa,OAAME,IAAK;KAAE,OACxCD,SAASH,KAAAA,IAAT;MAAA,GACIE;MAAMG,QAAU,oBAAC,WAAD,EAAgBF,KAAAA,KAAI,CAAA;KACpC,IAFJD;IAEK;IACfjB,EAAA,MAAAI;IAAAJ,EAAA,MAAAc;GAAA,OAAAA,KAAAd,EAAA;GALQO,KAAAM,QAAOQ,IAAKP,EAKpB;EAAC;EAAAd,EAAA,KAAAL;EAAAK,EAAA,KAAAI;EAAAJ,EAAA,KAAAG,KAAAM;EAAAT,EAAA,KAAAJ;EAAAI,EAAA,KAAAE;EAAAF,EAAA,KAAAK;EAAAL,EAAA,MAAAM;EAAAN,EAAA,MAAAO;EAAAP,EAAA,MAAAQ;CAAA,OAAA;EAAAH,KAAAL,EAAA;EAAAM,KAAAN,EAAA;EAAAO,KAAAP,EAAA;EAAAQ,KAAAR,EAAA;CAAA;CAAA,IAAAQ,OAAAE,OAAAC,IAAA,6BAAA,GAAA,OAAAH;CAAA,IAAAM;CAAA,IAAAd,EAAA,QAAAG,QAAAH,EAAA,QAAAJ,aAAA;EACWkB,KAAAlB,eAAeO,KAAImB,cAAepC,SAAQqC,iBAAkB;EAACvB,EAAA,MAAAG;EAAAH,EAAA,MAAAJ;EAAAI,EAAA,MAAAc;CAAA,OAAAA,KAAAd,EAAA;CAAA,IAAAgB;CAAA,IAAAhB,EAAA,QAAAG,MAAA;EAC5Da,KAAAb,KAAImB,cAAepC,SAAQsC,SAAU;EAACxB,EAAA,MAAAG;EAAAH,EAAA,MAAAgB;CAAA,OAAAA,KAAAhB,EAAA;CAAA,IAAAyB;CAAA,IAAAzB,EAAA,QAAAK,MAAAL,EAAA,QAAAM,MAAAN,EAAA,QAAAO,MAAAP,EAAA,QAAAc,MAAAd,EAAA,QAAAgB,IAAA;EATxDS,KAAA,oBAAC,IAAD;GAAa,GACLvB;GACK,SAAAK;GAMI,aAAAO;GACC,cAAAE;EAAsC,CAAA;EACtDhB,EAAA,MAAAK;EAAAL,EAAA,MAAAM;EAAAN,EAAA,MAAAO;EAAAP,EAAA,MAAAc;EAAAd,EAAA,MAAAgB;EAAAhB,EAAA,MAAAyB;CAAA,OAAAA,KAAAzB,EAAA;CAAA,OAVFyB;AAUE;;;;;AAQV,SAAgBC,iBAAiBC,OAAcC,aAAqC;CAChF,IAAID,MAAME,SAASd,KAAAA,KAAaa,gBAAgB,QAAQ,OAAOA,gBAAgB,UAAU;EACrF,MAAMjC,UAAWiC,YAAwCD,MAAME;EAC/D,IAAI5C,SAASU,OAAO,KAAKA,YAAY,IACjC,OAAOA;CAEf;CACA,OAAOX,WAAW2C,OAAO,WAAW1C,QAAQ,KAAK;AACrD;;AAGA,SAAO8C,iBAAA7B,OAAA;CAAA,MAAAF,IAAAC,EAAA,EAAA;CAAA,IAAAF;CAAA,IAAAC,EAAA,OAAAE,OAAA;EAGSH,KAAAhB,cAAcmB,KAAK;EAACF,EAAA,KAAAE;EAAAF,EAAA,KAAAD;CAAA,OAAAA,KAAAC,EAAA;CAAA,IAAAM;CAAA,IAAAN,EAAA,OAAAE,MAAAyB,SAAA3B,EAAA,OAAAE,MAAA0B,aAAA;EACftB,KAAAoB,iBAAiBxB,MAAKyB,OAAQzB,MAAK0B,WAAY;EAAC5B,EAAA,KAAAE,MAAAyB;EAAA3B,EAAA,KAAAE,MAAA0B;EAAA5B,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAClD,MAAAO,KAAAtB,SAASiB,MAAK8B,KAA2B,IAAjB9B,MAAK8B,QAA7B;CAA0C,IAAAxB;CAAA,IAAAR,EAAA,OAAAE,MAAA+B,YAAAjC,EAAA,OAAAD,MAAAC,EAAA,OAAAM,MAAAN,EAAA,OAAAO,IAAA;EAHrDC,KAAA,oBAAC,aAAD;GAAY,GACJT;GACK,SAAAO;GACF,OAAAC;GACG,UAAAL,MAAK+B;EAAS,CAAA;EAC1BjC,EAAA,KAAAE,MAAA+B;EAAAjC,EAAA,KAAAD;EAAAC,EAAA,KAAAM;EAAAN,EAAA,KAAAO;EAAAP,EAAA,KAAAQ;CAAA,OAAAA,KAAAR,EAAA;CAAA,OALFQ;AAKE"}
@@ -0,0 +1,9 @@
1
+ /* The size of a flag emoji, whatever the shape of the flag: about 4:3 in most emoji fonts. */
2
+ .panneau-region-flag-flag {
3
+ display: inline-block;
4
+ flex: none;
5
+ width: 1.25em;
6
+ height: 0.9375em;
7
+ object-fit: contain;
8
+ vertical-align: -0.125em;
9
+ }