@foxy.io/elements 1.13.0 → 1.14.0-beta.12

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 (180) hide show
  1. package/README.md +1 -1
  2. package/dist/cdn/foxy-access-recovery-form.js +1 -1
  3. package/dist/cdn/foxy-address-card.js +1 -1
  4. package/dist/cdn/foxy-address-form.js +1 -1
  5. package/dist/cdn/foxy-applied-tax-card.js +1 -1
  6. package/dist/cdn/foxy-attribute-card.js +1 -1
  7. package/dist/cdn/foxy-attribute-form.js +1 -1
  8. package/dist/cdn/foxy-cancellation-form.js +1 -1
  9. package/dist/cdn/foxy-collection-page.js +1 -1
  10. package/dist/cdn/foxy-collection-pages.js +1 -1
  11. package/dist/cdn/foxy-custom-field-card.js +1 -1
  12. package/dist/cdn/foxy-custom-field-form.js +1 -1
  13. package/dist/cdn/foxy-customer-api.js +1 -1
  14. package/dist/cdn/foxy-customer-card.js +1 -1
  15. package/dist/cdn/foxy-customer-form.js +1 -1
  16. package/dist/cdn/foxy-customer-portal-settings.js +18 -18
  17. package/dist/cdn/foxy-customer-portal.js +18 -15
  18. package/dist/cdn/foxy-customer.js +4 -4
  19. package/dist/cdn/foxy-customers-table.js +1 -1
  20. package/dist/cdn/foxy-discount-card.js +1 -1
  21. package/dist/cdn/foxy-donation.js +1 -1
  22. package/dist/cdn/foxy-email-template-form.js +1 -0
  23. package/dist/cdn/foxy-error-entry-card.js +1 -1
  24. package/dist/cdn/foxy-form-dialog.js +1 -1
  25. package/dist/cdn/foxy-i18n.js +1 -1
  26. package/dist/cdn/foxy-items-form.js +1 -1
  27. package/dist/cdn/foxy-nucleon-element.js +1 -1
  28. package/dist/cdn/foxy-payment-card.js +1 -1
  29. package/dist/cdn/foxy-payment-method-card.js +1 -1
  30. package/dist/cdn/foxy-query-builder.js +1 -1
  31. package/dist/cdn/foxy-sign-in-form.js +1 -1
  32. package/dist/cdn/foxy-spinner.js +2 -2
  33. package/dist/cdn/foxy-subscription-card.js +1 -1
  34. package/dist/cdn/foxy-subscription-form.js +26 -9
  35. package/dist/cdn/foxy-subscriptions-table.js +1 -1
  36. package/dist/cdn/foxy-table.js +1 -1
  37. package/dist/cdn/foxy-tax-card.js +1 -1
  38. package/dist/cdn/foxy-tax-form.js +1 -1
  39. package/dist/cdn/foxy-template-config-form.js +1 -0
  40. package/dist/cdn/foxy-template-form.js +1 -0
  41. package/dist/cdn/foxy-transaction-card.js +1 -1
  42. package/dist/cdn/foxy-transactions-table.js +1 -1
  43. package/dist/cdn/foxy-user-form.js +1 -1
  44. package/dist/cdn/foxy-users-table.js +1 -1
  45. package/dist/cdn/{shared-d4dad105.js → shared-00563cb0.js} +1 -1
  46. package/dist/cdn/shared-07134f93.js +14 -0
  47. package/dist/cdn/{shared-b0b1d248.js → shared-07abcd7b.js} +1 -1
  48. package/dist/cdn/shared-0ced76a0.js +358 -0
  49. package/dist/cdn/{shared-f4119f12.js → shared-16f72e27.js} +1 -1
  50. package/dist/cdn/shared-1761daef.js +15 -0
  51. package/dist/cdn/{shared-5fedf5e4.js → shared-200f613b.js} +2 -2
  52. package/dist/cdn/{shared-4059f633.js → shared-218ba06e.js} +1 -1
  53. package/dist/cdn/{shared-f2cf6cfb.js → shared-322e60b1.js} +1 -1
  54. package/dist/cdn/{shared-e9920617.js → shared-34b2c1e2.js} +1 -1
  55. package/dist/cdn/shared-35dbd2c5.js +1 -0
  56. package/dist/cdn/{shared-cf248335.js → shared-44cfc617.js} +1 -1
  57. package/dist/cdn/{shared-45d647e4.js → shared-46ee137f.js} +1 -1
  58. package/dist/cdn/{shared-f0199313.js → shared-593f7e2c.js} +1 -1
  59. package/dist/cdn/shared-59e44f29.js +1 -0
  60. package/dist/cdn/{shared-f47647ac.js → shared-5c8b531d.js} +1 -1
  61. package/dist/cdn/{shared-91a9e922.js → shared-5f54e916.js} +4 -4
  62. package/dist/cdn/{shared-cd700eac.js → shared-60126eee.js} +1 -1
  63. package/dist/cdn/{shared-17968c53.js → shared-63eaded9.js} +3 -3
  64. package/dist/cdn/shared-6b7602c7.js +1 -0
  65. package/dist/cdn/{shared-98ee7fad.js → shared-6d45a07b.js} +1 -1
  66. package/dist/cdn/{shared-145cc9eb.js → shared-7a42073a.js} +5 -5
  67. package/dist/cdn/{shared-b77179fd.js → shared-8a7bee0d.js} +1 -1
  68. package/dist/cdn/{shared-a99dea97.js → shared-91e768be.js} +1 -1
  69. package/dist/cdn/{shared-84fa75d9.js → shared-9221e6b2.js} +1 -1
  70. package/dist/cdn/{shared-2860a3d3.js → shared-94b0ae99.js} +2 -2
  71. package/dist/cdn/shared-9a40309d.js +1 -0
  72. package/dist/cdn/shared-a46edf4b.js +1 -0
  73. package/dist/cdn/{shared-54702b33.js → shared-b0f0e8b5.js} +1 -1
  74. package/dist/cdn/shared-b5147166.js +314 -0
  75. package/dist/cdn/{shared-ed4ed7a5.js → shared-b710881a.js} +2 -2
  76. package/dist/cdn/{shared-3ae39e52.js → shared-bb824ab4.js} +3 -3
  77. package/dist/cdn/{shared-67157a25.js → shared-bc2bfe52.js} +1 -1
  78. package/dist/cdn/{shared-d9159fe1.js → shared-ce1da35d.js} +1 -1
  79. package/dist/cdn/shared-d01d809a.js +1 -0
  80. package/dist/cdn/shared-d8ffb279.js +264 -0
  81. package/dist/cdn/shared-df573cea.js +12 -0
  82. package/dist/cdn/{shared-036a8b21.js → shared-e5cbf291.js} +1 -1
  83. package/dist/cdn/{shared-e5de8675.js → shared-e7f8ffe9.js} +1 -1
  84. package/dist/cdn/{shared-54c485d2.js → shared-ec861f31.js} +21 -21
  85. package/dist/cdn/{shared-e0248713.js → shared-f0a83bd6.js} +1 -1
  86. package/dist/cdn/shared-f1dc1c6c.js +1 -0
  87. package/dist/cdn/{shared-747b0842.js → shared-ff79f3f9.js} +1 -1
  88. package/dist/cdn/translations/shared/de.json +94 -0
  89. package/dist/cdn/translations/shared/en.json +93 -0
  90. package/dist/cdn/translations/shared/es.json +93 -0
  91. package/dist/elements/private/Checkbox/Checkbox.d.ts +3 -1
  92. package/dist/elements/private/Checkbox/Checkbox.js +45 -12
  93. package/dist/elements/private/Checkbox/Checkbox.js.map +1 -1
  94. package/dist/elements/private/Choice/Choice.js +9 -9
  95. package/dist/elements/private/Choice/Choice.js.map +1 -1
  96. package/dist/elements/private/Group/Group.js +1 -1
  97. package/dist/elements/private/Group/Group.js.map +1 -1
  98. package/dist/elements/private/I18N/I18N.js +1 -1
  99. package/dist/elements/private/I18N/I18N.js.map +1 -1
  100. package/dist/elements/public/AddressForm/AddressForm.js +8 -4
  101. package/dist/elements/public/AddressForm/AddressForm.js.map +1 -1
  102. package/dist/elements/public/AttributeForm/AttributeForm.js +8 -4
  103. package/dist/elements/public/AttributeForm/AttributeForm.js.map +1 -1
  104. package/dist/elements/public/CustomFieldForm/CustomFieldForm.js +8 -4
  105. package/dist/elements/public/CustomFieldForm/CustomFieldForm.js.map +1 -1
  106. package/dist/elements/public/CustomerForm/CustomerForm.js +8 -4
  107. package/dist/elements/public/CustomerForm/CustomerForm.js.map +1 -1
  108. package/dist/elements/public/CustomerPortal/InternalCustomerPortalLink.d.ts +1 -0
  109. package/dist/elements/public/CustomerPortal/InternalCustomerPortalLink.js +17 -8
  110. package/dist/elements/public/CustomerPortal/InternalCustomerPortalLink.js.map +1 -1
  111. package/dist/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.js +11 -3
  112. package/dist/elements/public/CustomerPortal/InternalCustomerPortalSubscriptions.js.map +1 -1
  113. package/dist/elements/public/EmailTemplateForm/EmailTemplateForm.d.ts +46 -0
  114. package/dist/elements/public/EmailTemplateForm/EmailTemplateForm.js +350 -0
  115. package/dist/elements/public/EmailTemplateForm/EmailTemplateForm.js.map +1 -0
  116. package/dist/elements/public/EmailTemplateForm/index.d.ts +9 -0
  117. package/dist/elements/public/EmailTemplateForm/index.js +11 -0
  118. package/dist/elements/public/EmailTemplateForm/index.js.map +1 -0
  119. package/dist/elements/public/EmailTemplateForm/types.d.ts +17 -0
  120. package/dist/elements/public/EmailTemplateForm/types.js +2 -0
  121. package/dist/elements/public/EmailTemplateForm/types.js.map +1 -0
  122. package/dist/elements/public/ItemsForm/ItemsForm.js +2 -2
  123. package/dist/elements/public/ItemsForm/ItemsForm.js.map +1 -1
  124. package/dist/elements/public/ItemsForm/private/Picture.d.ts +1 -0
  125. package/dist/elements/public/ItemsForm/private/Picture.js +2 -0
  126. package/dist/elements/public/ItemsForm/private/Picture.js.map +1 -1
  127. package/dist/elements/public/NucleonElement/serveFromCache.js +1 -0
  128. package/dist/elements/public/NucleonElement/serveFromCache.js.map +1 -1
  129. package/dist/elements/public/SubscriptionForm/SubscriptionForm.js +12 -4
  130. package/dist/elements/public/SubscriptionForm/SubscriptionForm.js.map +1 -1
  131. package/dist/elements/public/TaxForm/TaxForm.js +8 -4
  132. package/dist/elements/public/TaxForm/TaxForm.js.map +1 -1
  133. package/dist/elements/public/TemplateConfigForm/CountriesList.d.ts +21 -0
  134. package/dist/elements/public/TemplateConfigForm/CountriesList.js +137 -0
  135. package/dist/elements/public/TemplateConfigForm/CountriesList.js.map +1 -0
  136. package/dist/elements/public/TemplateConfigForm/CountryCard.d.ts +20 -0
  137. package/dist/elements/public/TemplateConfigForm/CountryCard.js +160 -0
  138. package/dist/elements/public/TemplateConfigForm/CountryCard.js.map +1 -0
  139. package/dist/elements/public/TemplateConfigForm/TemplateConfigForm.d.ts +88 -0
  140. package/dist/elements/public/TemplateConfigForm/TemplateConfigForm.js +1333 -0
  141. package/dist/elements/public/TemplateConfigForm/TemplateConfigForm.js.map +1 -0
  142. package/dist/elements/public/TemplateConfigForm/defaults.d.ts +2 -0
  143. package/dist/elements/public/TemplateConfigForm/defaults.js +95 -0
  144. package/dist/elements/public/TemplateConfigForm/defaults.js.map +1 -0
  145. package/dist/elements/public/TemplateConfigForm/index.d.ts +9 -0
  146. package/dist/elements/public/TemplateConfigForm/index.js +11 -0
  147. package/dist/elements/public/TemplateConfigForm/index.js.map +1 -0
  148. package/dist/elements/public/TemplateConfigForm/types.d.ts +150 -0
  149. package/dist/elements/public/TemplateConfigForm/types.js +2 -0
  150. package/dist/elements/public/TemplateConfigForm/types.js.map +1 -0
  151. package/dist/elements/public/TemplateForm/TemplateForm.d.ts +45 -0
  152. package/dist/elements/public/TemplateForm/TemplateForm.js +343 -0
  153. package/dist/elements/public/TemplateForm/TemplateForm.js.map +1 -0
  154. package/dist/elements/public/TemplateForm/index.d.ts +9 -0
  155. package/dist/elements/public/TemplateForm/index.js +11 -0
  156. package/dist/elements/public/TemplateForm/index.js.map +1 -0
  157. package/dist/elements/public/TemplateForm/types.d.ts +17 -0
  158. package/dist/elements/public/TemplateForm/types.js +2 -0
  159. package/dist/elements/public/TemplateForm/types.js.map +1 -0
  160. package/dist/elements/public/index.d.ts +3 -0
  161. package/dist/elements/public/index.defined.d.ts +3 -0
  162. package/dist/elements/public/index.defined.js +3 -0
  163. package/dist/elements/public/index.defined.js.map +1 -1
  164. package/dist/elements/public/index.js +3 -0
  165. package/dist/elements/public/index.js.map +1 -1
  166. package/dist/mixins/themeable.js +143 -24
  167. package/dist/mixins/themeable.js.map +1 -1
  168. package/dist/mixins/translatable.js +1 -1
  169. package/dist/mixins/translatable.js.map +1 -1
  170. package/package.json +2 -7
  171. package/dist/cdn/shared-296637c5.js +0 -1
  172. package/dist/cdn/shared-4a990126.js +0 -1
  173. package/dist/cdn/shared-50744508.js +0 -15
  174. package/dist/cdn/shared-b98f88c9.js +0 -369
  175. package/dist/cdn/shared-bf09e011.js +0 -572
  176. package/dist/cdn/shared-c0161e6a.js +0 -1
  177. package/dist/cdn/shared-c1e0e11f.js +0 -1
  178. package/dist/cdn/shared-dbcffd8e.js +0 -1
  179. package/dist/cdn/shared-e21a2aac.js +0 -1
  180. package/dist/cdn/shared-e55b6bb7.js +0 -1
@@ -0,0 +1,1333 @@
1
+ import * as logos from "../PaymentMethodCard/logos.js";
2
+ import { ChoiceChangeEvent } from "../../private/events.js";
3
+ import { ScopedElementsMixin } from '@open-wc/scoped-elements';
4
+ import { html } from 'lit-html';
5
+ import { Checkbox } from "../../private/Checkbox/Checkbox.js";
6
+ import { Choice } from "../../private/Choice/Choice.js";
7
+ import { ConfigurableMixin } from "../../../mixins/configurable.js";
8
+ import { CountriesList } from "./CountriesList.js";
9
+ import { Group } from "../../private/Group/Group.js";
10
+ import { NucleonElement } from "../NucleonElement/NucleonElement.js";
11
+ import { ResponsiveMixin } from "../../../mixins/responsive.js";
12
+ import { ThemeableMixin } from "../../../mixins/themeable.js";
13
+ import { TranslatableMixin } from "../../../mixins/translatable.js";
14
+ import { classMap } from "../../../utils/class-map.js";
15
+ import { getDefaultJSON } from "./defaults.js";
16
+ import { live } from 'lit-html/directives/live';
17
+ const NS = 'template-config-form';
18
+ const Base = ScopedElementsMixin(ResponsiveMixin(ConfigurableMixin(ThemeableMixin(TranslatableMixin(NucleonElement, NS)))));
19
+ /**
20
+ * Form element for creating or editing template configs (`fx:template_config`).
21
+ *
22
+ * @slot cart-type:before
23
+ * @slot cart-type:after
24
+ *
25
+ * @slot foxycomplete:before
26
+ * @slot foxycomplete:after
27
+ *
28
+ * @slot locations:before
29
+ * @slot locations:after
30
+ *
31
+ * @slot hidden-fields:before
32
+ * @slot hidden-fields:after
33
+ *
34
+ * @slot cards:before
35
+ * @slot cards:after
36
+ *
37
+ * @slot checkout-type:before
38
+ * @slot checkout-type:after
39
+ *
40
+ * @slot consent:before
41
+ * @slot consent:after
42
+ *
43
+ * @slot fields:before
44
+ * @slot fields:after
45
+ *
46
+ * @slot google-analytics:before
47
+ * @slot google-analytics:after
48
+ *
49
+ * @slot segment-io:before
50
+ * @slot segment-io:after
51
+ *
52
+ * @slot troubleshooting:before
53
+ * @slot troubleshooting:after
54
+ *
55
+ * @slot custom-config:before
56
+ * @slot custom-config:after
57
+ *
58
+ * @slot header:before
59
+ * @slot header:after
60
+ *
61
+ * @slot custom-fields:before
62
+ * @slot custom-fields:after
63
+ *
64
+ * @slot footer:before
65
+ * @slot footer:after
66
+ *
67
+ * @element foxy-template-config-form
68
+ * @since 1.14.0
69
+ */
70
+ export class TemplateConfigForm extends Base {
71
+ constructor() {
72
+ super(...arguments);
73
+ this.templates = {};
74
+ /** URI of the `fx:countries` hAPI resource. */
75
+ this.countries = '';
76
+ /** URI of the `fx:regions` hAPI resource. */
77
+ this.regions = '';
78
+ this.__addHiddenFieldInputValue = '';
79
+ }
80
+ static get scopedElements() {
81
+ return {
82
+ 'vaadin-text-field': customElements.get('vaadin-text-field'),
83
+ 'vaadin-text-area': customElements.get('vaadin-text-area'),
84
+ 'iron-icon': customElements.get('iron-icon'),
85
+ 'foxy-internal-sandbox': customElements.get('foxy-internal-sandbox'),
86
+ 'foxy-spinner': customElements.get('foxy-spinner'),
87
+ 'foxy-i18n': customElements.get('foxy-i18n'),
88
+ 'x-countries-list': CountriesList,
89
+ 'x-checkbox': Checkbox,
90
+ 'x-choice': Choice,
91
+ 'x-group': Group,
92
+ };
93
+ }
94
+ static get properties() {
95
+ return {
96
+ ...super.properties,
97
+ __addHiddenFieldInputValue: { attribute: false },
98
+ countries: { type: String },
99
+ regions: { type: String },
100
+ };
101
+ }
102
+ render() {
103
+ var _a, _b;
104
+ const hidden = this.hiddenSelector;
105
+ const json = this.form.json ? JSON.parse(this.form.json) : getDefaultJSON();
106
+ return html `
107
+ <div class="relative" aria-busy=${this.in('busy')} aria-live="polite">
108
+ <div class="space-y-l">
109
+ ${hidden.matches('cart-type', true) ? '' : this.__renderCartType(json)}
110
+ ${hidden.matches('foxycomplete', true) ? '' : this.__renderFoxycomplete(json)}
111
+ ${hidden.matches('locations', true) ? '' : this.__renderLocations(json)}
112
+ ${hidden.matches('hidden-fields', true) ? '' : this.__renderHiddenFields(json)}
113
+ ${hidden.matches('cards', true) ? '' : this.__renderCards(json)}
114
+ ${hidden.matches('checkout-type', true) ? '' : this.__renderCheckoutType(json)}
115
+ ${hidden.matches('consent', true) ? '' : this.__renderConsent(json)}
116
+ ${hidden.matches('fields', true) ? '' : this.__renderFields(json)}
117
+ ${hidden.matches('google-analytics', true) ? '' : this.__renderGoogleAnalytics(json)}
118
+ ${hidden.matches('segment-io', true) ? '' : this.__renderSegmentIo(json)}
119
+ ${hidden.matches('troubleshooting', true) ? '' : this.__renderTroubleshooting(json)}
120
+ ${hidden.matches('custom-config', true) ? '' : this.__renderCustomConfig(json)}
121
+ ${hidden.matches('header', true) ? '' : this.__renderHeader(json)}
122
+ ${hidden.matches('custom-fields', true) ? '' : this.__renderCustomFields(json)}
123
+ ${hidden.matches('footer', true) ? '' : this.__renderFooter(json)}
124
+ </div>
125
+
126
+ <div
127
+ class=${classMap({
128
+ 'transition duration-500 ease-in-out absolute inset-0 flex': true,
129
+ 'opacity-0 pointer-events-none': this.in('idle'),
130
+ })}
131
+ >
132
+ <foxy-spinner
133
+ layout="vertical"
134
+ class="m-auto p-m bg-base shadow-xs rounded-t-l rounded-b-l"
135
+ state=${this.in('fail') ? 'error' : 'busy'}
136
+ lang=${this.lang}
137
+ ns="${this.ns} ${(_b = (_a = customElements.get('foxy-spinner')) === null || _a === void 0 ? void 0 : _a.defaultNS) !== null && _b !== void 0 ? _b : ''}"
138
+ >
139
+ </foxy-spinner>
140
+ </div>
141
+ </div>
142
+ `;
143
+ }
144
+ __renderCartType(json) {
145
+ const { lang, ns } = this;
146
+ const items = ['default', 'fullpage', 'custom'];
147
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('cart-type', true);
148
+ return html `
149
+ <div data-testid="cart-type">
150
+ ${this.renderTemplateOrSlot('cart-type:before')}
151
+
152
+ <x-group frame>
153
+ <foxy-i18n
154
+ class=${isDisabled ? 'text-disabled' : ''}
155
+ slot="header"
156
+ lang=${lang}
157
+ key="cart_type"
158
+ ns=${ns}
159
+ >
160
+ </foxy-i18n>
161
+
162
+ <x-choice
163
+ data-testid="cart-type-choice"
164
+ .value=${json.cart_type}
165
+ .items=${items}
166
+ ?disabled=${isDisabled}
167
+ ?readonly=${this.readonlySelector.matches('cart-type', true)}
168
+ @change=${(evt) => {
169
+ this.edit({ json: JSON.stringify({ ...json, cart_type: evt.detail }) });
170
+ }}
171
+ >
172
+ ${items.map(item => {
173
+ return html `
174
+ <div slot="${item}-label" class="grid leading-s py-s">
175
+ <foxy-i18n lang=${lang} key="cart_type_${item}" ns=${ns}></foxy-i18n>
176
+ <foxy-i18n
177
+ class="text-xs ${isDisabled ? 'text-disabled' : 'text-secondary'}"
178
+ lang=${lang}
179
+ key="cart_type_${item}_explainer"
180
+ ns=${ns}
181
+ >
182
+ </foxy-i18n>
183
+ </div>
184
+ `;
185
+ })}
186
+ </x-choice>
187
+ </x-group>
188
+
189
+ ${this.renderTemplateOrSlot('cart-type:after')}
190
+ </div>
191
+ `;
192
+ }
193
+ __renderFoxycomplete(json) {
194
+ const { lang, ns } = this;
195
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('foxycomplete', true);
196
+ const isReadonly = this.readonlySelector.matches('foxycomplete', true);
197
+ const config = json.foxycomplete;
198
+ const items = ['combobox', 'search', 'disabled'];
199
+ const value = config.usage === 'none' ? 'disabled' : config.show_combobox ? 'combobox' : 'search';
200
+ const flagsCheckbox = html `
201
+ <x-checkbox
202
+ data-testid="foxycomplete-flags-check"
203
+ ?disabled=${isDisabled}
204
+ ?readonly=${isReadonly}
205
+ ?checked=${config.show_flags}
206
+ @change=${(evt) => {
207
+ config.show_flags = evt.detail;
208
+ this.edit({ json: JSON.stringify(json) });
209
+ }}
210
+ >
211
+ <foxy-i18n lang=${lang} key="show_country_flags" ns=${ns}></foxy-i18n>
212
+ </x-checkbox>
213
+ `;
214
+ return html `
215
+ <div data-testid="foxycomplete">
216
+ ${this.renderTemplateOrSlot('foxycomplete:before')}
217
+
218
+ <x-group frame>
219
+ <foxy-i18n
220
+ class=${isDisabled ? 'text-disabled' : ''}
221
+ slot="header"
222
+ lang=${lang}
223
+ key="foxycomplete"
224
+ ns=${ns}
225
+ >
226
+ </foxy-i18n>
227
+
228
+ <x-choice
229
+ data-testid="foxycomplete-choice"
230
+ .value=${value}
231
+ .items=${items}
232
+ ?disabled=${isDisabled}
233
+ ?readonly=${isReadonly}
234
+ @change=${(evt) => {
235
+ if (!(evt instanceof ChoiceChangeEvent))
236
+ return;
237
+ config.usage = evt.detail === 'disabled' ? 'none' : 'required';
238
+ config.show_combobox = evt.detail === 'combobox';
239
+ this.edit({ json: JSON.stringify(json) });
240
+ }}
241
+ >
242
+ ${items.map(item => {
243
+ return html `
244
+ <div slot="${item}-label" class="grid leading-s py-s">
245
+ <foxy-i18n lang=${lang} key="foxycomplete_${item}" ns=${ns}></foxy-i18n>
246
+ <foxy-i18n
247
+ class="text-xs ${isDisabled ? 'text-disabled' : 'text-secondary'}"
248
+ lang=${lang}
249
+ key="foxycomplete_${item}_explainer"
250
+ ns=${ns}
251
+ >
252
+ </foxy-i18n>
253
+ </div>
254
+ `;
255
+ })}
256
+
257
+ <div slot="combobox" class="space-y-m pb-s" ?hidden=${value !== 'combobox'}>
258
+ <div class="grid grid-cols-2 gap-m" style="max-width: 16rem">
259
+ ${['open', 'close'].map(action => {
260
+ const field = action === 'open' ? 'combobox_open' : 'combobox_close';
261
+ return html `
262
+ <vaadin-text-field
263
+ data-testid="foxycomplete-${action}-icon"
264
+ label=${this.t(`${action}_icon`)}
265
+ .value=${config[field]}
266
+ ?disabled=${isDisabled}
267
+ ?readonly=${isReadonly}
268
+ @keydown=${(evt) => evt.key === 'Enter' && this.submit()}
269
+ @input=${(evt) => {
270
+ config[field] = evt.currentTarget.value;
271
+ this.edit({ json: JSON.stringify(json) });
272
+ }}
273
+ >
274
+ </vaadin-text-field>
275
+ `;
276
+ })}
277
+ </div>
278
+
279
+ ${flagsCheckbox}
280
+ </div>
281
+
282
+ <div slot="search" class="pb-s" ?hidden=${value !== 'search'}>${flagsCheckbox}</div>
283
+ </x-choice>
284
+
285
+ <div class="border-t border-contrast-10 p-m">
286
+ <x-checkbox
287
+ data-testid="foxycomplete-lookup-check"
288
+ ?disabled=${isDisabled}
289
+ ?readonly=${isReadonly}
290
+ ?checked=${json.postal_code_lookup.usage === 'enabled'}
291
+ @change=${(evt) => {
292
+ json.postal_code_lookup.usage = evt.detail ? 'enabled' : 'none';
293
+ this.edit({ json: JSON.stringify(json) });
294
+ }}
295
+ >
296
+ <foxy-i18n lang=${lang} key="enable_postcode_lookup" ns=${ns}></foxy-i18n>
297
+ </x-checkbox>
298
+ </div>
299
+ </x-group>
300
+
301
+ ${this.renderTemplateOrSlot('foxycomplete:after')}
302
+ </div>
303
+ `;
304
+ }
305
+ __renderLocations(json) {
306
+ const { lang, ns } = this;
307
+ const config = json.location_filtering;
308
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('locations', true);
309
+ const isReadonly = this.readonlySelector.matches('locations', true);
310
+ const shippingChoice = config.shipping_filter_type === 'blacklist' ? 'block' : 'allow';
311
+ const billingChoice = config.usage === 'both'
312
+ ? 'copy'
313
+ : config.billing_filter_type === 'blacklist'
314
+ ? 'block'
315
+ : 'allow';
316
+ const normalize = () => {
317
+ if (config.usage === 'both') {
318
+ config.billing_filter_type = config.shipping_filter_type;
319
+ config.billing_filter_values = config.shipping_filter_values;
320
+ }
321
+ else {
322
+ const hasBillingFilters = Object.keys(config.billing_filter_values).length > 0;
323
+ const hasShippingFilters = Object.keys(config.shipping_filter_values).length > 0;
324
+ if (!hasBillingFilters && !hasShippingFilters) {
325
+ config.usage = 'none';
326
+ }
327
+ else if (hasBillingFilters && !hasShippingFilters) {
328
+ config.usage = 'billing';
329
+ }
330
+ else if (hasShippingFilters && !hasBillingFilters) {
331
+ config.usage = 'shipping';
332
+ }
333
+ else {
334
+ config.usage = 'independent';
335
+ }
336
+ }
337
+ };
338
+ return html `
339
+ <div data-testid="locations">
340
+ ${this.renderTemplateOrSlot('locations:before')}
341
+
342
+ <x-group frame>
343
+ <foxy-i18n
344
+ class=${isDisabled ? 'text-disabled' : ''}
345
+ slot="header"
346
+ lang=${lang}
347
+ key="location_plural"
348
+ ns=${ns}
349
+ >
350
+ </foxy-i18n>
351
+
352
+ <div class="grid sm-grid-cols-2 bg-contrast-10" style="gap: 1px">
353
+ <x-group class="bg-base pt-m">
354
+ <foxy-i18n
355
+ class=${isDisabled ? 'text-disabled' : 'text-tertiary'}
356
+ slot="header"
357
+ lang=${lang}
358
+ key="shipping"
359
+ ns=${ns}
360
+ >
361
+ </foxy-i18n>
362
+
363
+ <x-choice
364
+ data-testid="locations-shipping-choice"
365
+ .items=${['allow', 'block']}
366
+ .value=${shippingChoice}
367
+ ?disabled=${isDisabled}
368
+ ?readonly=${isReadonly}
369
+ @change=${(evt) => {
370
+ if (config.usage !== 'both')
371
+ config.usage = 'independent';
372
+ config.shipping_filter_type = evt.detail === 'block' ? 'blacklist' : 'whitelist';
373
+ normalize();
374
+ this.edit({ json: JSON.stringify(json) });
375
+ }}
376
+ >
377
+ <foxy-i18n slot="allow-label" lang=${lang} key="allowlist" ns=${ns}></foxy-i18n>
378
+ <foxy-i18n slot="block-label" lang=${lang} key="blocklist" ns=${ns}></foxy-i18n>
379
+
380
+ <x-countries-list
381
+ data-testid="locations-shipping-list"
382
+ countries=${JSON.stringify(config.shipping_filter_values)}
383
+ regions=${this.regions}
384
+ class="mb-m"
385
+ href=${this.countries}
386
+ slot=${shippingChoice}
387
+ lang=${lang}
388
+ ns=${ns}
389
+ ?disabled=${isDisabled}
390
+ ?readonly=${isReadonly}
391
+ @update:countries=${(evt) => {
392
+ config.shipping_filter_values = evt.currentTarget.countries;
393
+ normalize();
394
+ this.edit({ json: JSON.stringify(json) });
395
+ }}
396
+ >
397
+ </x-countries-list>
398
+ </x-choice>
399
+ </x-group>
400
+
401
+ <x-group class="bg-base pt-m">
402
+ <foxy-i18n
403
+ class=${isDisabled ? 'text-disabled' : 'text-tertiary'}
404
+ slot="header"
405
+ lang=${lang}
406
+ key="billing"
407
+ ns=${ns}
408
+ >
409
+ </foxy-i18n>
410
+
411
+ <x-choice
412
+ data-testid="locations-billing-choice"
413
+ .items=${['allow', 'block', 'copy']}
414
+ .value=${billingChoice}
415
+ ?disabled=${isDisabled}
416
+ ?readonly=${isReadonly}
417
+ @change=${(evt) => {
418
+ if (evt.detail === 'copy') {
419
+ config.usage = 'both';
420
+ }
421
+ else {
422
+ config.usage = 'independent';
423
+ config.billing_filter_type = evt.detail === 'block' ? 'blacklist' : 'whitelist';
424
+ }
425
+ normalize();
426
+ this.edit({ json: JSON.stringify(json) });
427
+ }}
428
+ >
429
+ <foxy-i18n slot="allow-label" lang=${lang} key="allowlist" ns=${ns}></foxy-i18n>
430
+ <foxy-i18n slot="block-label" lang=${lang} key="blocklist" ns=${ns}></foxy-i18n>
431
+ <foxy-i18n slot="copy-label" lang=${lang} key="same_as_shipping" ns=${ns}>
432
+ </foxy-i18n>
433
+
434
+ <x-countries-list
435
+ data-testid="locations-billing-list"
436
+ countries=${JSON.stringify(config.billing_filter_values)}
437
+ regions=${this.regions}
438
+ class="mb-m"
439
+ href=${this.countries}
440
+ slot=${billingChoice}
441
+ lang=${lang}
442
+ ns=${ns}
443
+ ?disabled=${isDisabled}
444
+ ?readonly=${isReadonly}
445
+ ?hidden=${billingChoice === 'copy'}
446
+ @update:countries=${(evt) => {
447
+ config.billing_filter_values = evt.currentTarget.countries;
448
+ normalize();
449
+ this.edit({ json: JSON.stringify(json) });
450
+ }}
451
+ >
452
+ </x-countries-list>
453
+ </x-choice>
454
+ </x-group>
455
+ </div>
456
+ </x-group>
457
+
458
+ ${this.renderTemplateOrSlot('locations:after')}
459
+ </div>
460
+ `;
461
+ }
462
+ __renderHiddenFields(json) {
463
+ const { lang, ns } = this;
464
+ const suggestions = [];
465
+ const fields = [];
466
+ const config = json.cart_display_config;
467
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('hidden-fields', true);
468
+ const isReadonly = this.readonlySelector.matches('hidden-fields', true);
469
+ for (const key in config) {
470
+ if (!key.startsWith('show_'))
471
+ continue;
472
+ const field = key.substring(5);
473
+ suggestions.push(field);
474
+ if (config.usage === 'required' && !config[key])
475
+ fields.push(field);
476
+ }
477
+ if (config.usage === 'required') {
478
+ fields.push(...config.hidden_product_options);
479
+ }
480
+ const addField = () => {
481
+ config.usage = 'required';
482
+ if (suggestions.includes(this.__addHiddenFieldInputValue)) {
483
+ config[`show_${this.__addHiddenFieldInputValue}`] = false;
484
+ }
485
+ else if (!config.hidden_product_options.includes(this.__addHiddenFieldInputValue)) {
486
+ config.hidden_product_options.push(this.__addHiddenFieldInputValue);
487
+ }
488
+ this.edit({ json: JSON.stringify(json) });
489
+ this.__addHiddenFieldInputValue = '';
490
+ };
491
+ const radius = 'calc(var(--lumo-border-radius-l) / 1.2)';
492
+ const inputRadius = fields.length === 0 ? [radius] : ['0', '0', radius, radius];
493
+ const isAddButtonDisabled = isDisabled || !this.__addHiddenFieldInputValue;
494
+ return html `
495
+ <div data-testid="hidden-fields">
496
+ ${this.renderTemplateOrSlot('hidden-fields:before')}
497
+
498
+ <x-group frame>
499
+ <foxy-i18n
500
+ class=${isDisabled ? 'text-disabled' : ''}
501
+ slot="header"
502
+ lang=${lang}
503
+ key="hidden_fields"
504
+ ns=${ns}
505
+ >
506
+ </foxy-i18n>
507
+
508
+ <div class="divide-y divide-contrast-10" data-testid="hidden-fields-list">
509
+ ${fields.map(field => {
510
+ return html `
511
+ <div
512
+ class=${classMap({
513
+ 'h-m ml-m pr-xs flex items-center justify-between': true,
514
+ 'text-secondary': isReadonly,
515
+ 'text-disabled': isDisabled,
516
+ })}
517
+ >
518
+ ${suggestions.includes(field)
519
+ ? html `<foxy-i18n lang=${lang} key=${field} ns=${ns}></foxy-i18n>`
520
+ : html `<span>${field}</span>`}
521
+
522
+ <button
523
+ aria-label=${this.t('delete')}
524
+ class=${classMap({
525
+ 'w-xs h-xs rounded-full transition-colors': true,
526
+ 'hover-bg-error-10 hover-text-error': !isDisabled,
527
+ 'focus-outline-none focus-ring-2 ring-inset ring-error-50': !isDisabled,
528
+ 'cursor-default': isDisabled,
529
+ 'flex': !isReadonly,
530
+ 'hidden': isReadonly,
531
+ })}
532
+ ?disabled=${isDisabled}
533
+ @click=${() => {
534
+ if (typeof config[`show_${field}`] === 'boolean') {
535
+ config[`show_${field}`] = true;
536
+ }
537
+ else {
538
+ config.hidden_product_options = config.hidden_product_options.filter(option => option !== field);
539
+ }
540
+ this.edit({ json: JSON.stringify(json) });
541
+ }}
542
+ >
543
+ <iron-icon icon="icons:close" class="icon-inline text-m m-auto"></iron-icon>
544
+ </button>
545
+ </div>
546
+ `;
547
+ })}
548
+ </div>
549
+
550
+ <div
551
+ data-testid="hidden-fields-new"
552
+ style="border-radius: ${inputRadius.join(' ')}"
553
+ class=${classMap({
554
+ 'h-m flex items-center ring-inset ring-primary-50 focus-within-ring-2': true,
555
+ 'border-t border-contrast-10': fields.length > 0,
556
+ 'flex': !isReadonly,
557
+ 'hidden': isReadonly,
558
+ })}
559
+ >
560
+ <input
561
+ placeholder=${this.t('add_field')}
562
+ class="w-full bg-transparent appearance-none h-m px-m focus-outline-none"
563
+ list="hidden-fields-list"
564
+ .value=${live(this.__addHiddenFieldInputValue)}
565
+ ?disabled=${isDisabled}
566
+ ?readonly=${isReadonly}
567
+ @keydown=${(evt) => evt.key === 'Enter' && addField()}
568
+ @input=${(evt) => {
569
+ this.__addHiddenFieldInputValue = evt.currentTarget.value;
570
+ }}
571
+ />
572
+
573
+ <datalist id="hidden-fields-list">
574
+ ${suggestions
575
+ .filter(suggestion => !fields.includes(suggestion))
576
+ .map(suggestion => html `<option value=${suggestion}>${this.t(suggestion)}</option>`)}
577
+ </datalist>
578
+
579
+ <button
580
+ aria-label=${this.t('add_field')}
581
+ class=${classMap({
582
+ 'w-xs h-xs mr-xs flex-shrink-0 ring-inset ring-success-50': true,
583
+ 'flex items-center justify-center rounded-full transition-colors': true,
584
+ 'bg-contrast-5 text-disabled cursor-default': isAddButtonDisabled,
585
+ 'bg-success-10 text-success cursor-pointer': !isAddButtonDisabled,
586
+ 'hover-bg-success hover-text-success-contrast': !isAddButtonDisabled,
587
+ 'focus-outline-none focus-ring-2': !isAddButtonDisabled,
588
+ })}
589
+ ?disabled=${isAddButtonDisabled}
590
+ @click=${addField}
591
+ >
592
+ <iron-icon icon="icons:add" class="icon-inline text-m"></iron-icon>
593
+ </button>
594
+ </div>
595
+ </x-group>
596
+
597
+ ${this.renderTemplateOrSlot('hidden-fields:after')}
598
+ </div>
599
+ `;
600
+ }
601
+ __renderCards(json) {
602
+ const { lang, ns } = this;
603
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('cards', true);
604
+ const isReadonly = this.readonlySelector.matches('cards', true);
605
+ const config = json.supported_payment_cards;
606
+ let skipForSaved;
607
+ let skipForSSO;
608
+ if (json.csc_requirements === 'all_cards') {
609
+ skipForSaved = false;
610
+ skipForSSO = false;
611
+ }
612
+ else if (json.csc_requirements === 'sso_only') {
613
+ skipForSaved = true;
614
+ skipForSSO = false;
615
+ }
616
+ else {
617
+ skipForSaved = true;
618
+ skipForSSO = true;
619
+ }
620
+ const typeToName = {
621
+ amex: 'American Express',
622
+ diners: 'Diners Club',
623
+ discover: 'Discover',
624
+ jcb: 'JCB',
625
+ maestro: 'Maestro',
626
+ mastercard: 'Mastercard',
627
+ unionpay: 'UnionPay',
628
+ visa: 'Visa',
629
+ };
630
+ return html `
631
+ <div data-testid="cards">
632
+ ${this.renderTemplateOrSlot('cards:before')}
633
+
634
+ <div class="space-y-xs">
635
+ <x-group frame>
636
+ <foxy-i18n
637
+ class=${isDisabled ? 'text-disabled' : ''}
638
+ slot="header"
639
+ lang=${lang}
640
+ key="supported_cards"
641
+ ns=${ns}
642
+ >
643
+ </foxy-i18n>
644
+
645
+ <div class="flex flex-wrap m-xs p-s">
646
+ ${Object.entries(logos).map(([type, logo]) => {
647
+ if (!typeToName[type])
648
+ return;
649
+ const isChecked = config.includes(type);
650
+ return html `
651
+ <div
652
+ class=${classMap({
653
+ 'm-xs rounded': true,
654
+ 'opacity-50 cursor-default': isDisabled,
655
+ 'cursor-pointer ring-primary-50 focus-within-ring-2': !isDisabled,
656
+ })}
657
+ >
658
+ <label
659
+ class=${classMap({
660
+ 'overflow-hidden transition-colors flex rounded border': true,
661
+ 'border-primary bg-primary-10 text-primary': isChecked && !isReadonly,
662
+ 'border-contrast bg-contrast-5 text-secondary': isChecked && isReadonly,
663
+ 'hover-text-body': isChecked && !isDisabled && !isReadonly,
664
+ 'border-contrast-10': !isChecked,
665
+ 'hover-border-primary': !isChecked && !isDisabled && !isReadonly,
666
+ 'hover-text-primary': !isChecked && !isDisabled && !isReadonly,
667
+ })}
668
+ >
669
+ <div class="h-s">${logo}</div>
670
+
671
+ <div class="text-s font-medium mx-s my-auto leading-none">
672
+ ${typeToName[type]}
673
+ </div>
674
+
675
+ <input
676
+ type="checkbox"
677
+ class="sr-only"
678
+ ?disabled=${isDisabled}
679
+ ?readonly=${isReadonly}
680
+ ?checked=${isChecked}
681
+ @change=${(evt) => {
682
+ if (isReadonly)
683
+ return evt.preventDefault();
684
+ evt.stopPropagation();
685
+ if (evt.currentTarget.checked) {
686
+ config.push(type);
687
+ }
688
+ else {
689
+ config.splice(config.indexOf(type), 1);
690
+ }
691
+ this.edit({ json: JSON.stringify(json) });
692
+ }}
693
+ />
694
+ </label>
695
+ </div>
696
+ `;
697
+ })}
698
+ </div>
699
+
700
+ <div class="flex flex-wrap p-s border-t border-contrast-10">
701
+ <x-checkbox
702
+ data-testid="cards-saved-check"
703
+ class="m-s"
704
+ ?disabled=${isDisabled || json.csc_requirements === 'new_cards_only'}
705
+ ?readonly=${isReadonly}
706
+ ?checked=${skipForSaved}
707
+ @change=${(evt) => {
708
+ json.csc_requirements = evt.detail ? 'sso_only' : 'all_cards';
709
+ this.edit({ json: JSON.stringify(json) });
710
+ }}
711
+ >
712
+ <foxy-i18n class="leading-s block" lang=${lang} key="skip_csc_for_saved" ns=${ns}>
713
+ </foxy-i18n>
714
+ </x-checkbox>
715
+
716
+ <x-checkbox
717
+ data-testid="cards-sso-check"
718
+ class="m-s"
719
+ ?disabled=${isDisabled}
720
+ ?readonly=${isReadonly}
721
+ ?checked=${skipForSSO}
722
+ @change=${(evt) => {
723
+ json.csc_requirements = evt.detail
724
+ ? 'new_cards_only'
725
+ : skipForSaved
726
+ ? 'sso_only'
727
+ : 'all_cards';
728
+ this.edit({ json: JSON.stringify(json) });
729
+ }}
730
+ >
731
+ <foxy-i18n class="leading-s block" lang=${lang} key="skip_csc_for_sso" ns=${ns}>
732
+ </foxy-i18n>
733
+ </x-checkbox>
734
+ </div>
735
+ </x-group>
736
+
737
+ <foxy-i18n
738
+ class="text-xs leading-s block ${isDisabled ? 'text-disabled' : 'text-secondary'}"
739
+ lang=${lang}
740
+ key="supported_cards_disclaimer"
741
+ ns=${ns}
742
+ >
743
+ </foxy-i18n>
744
+ </div>
745
+
746
+ ${this.renderTemplateOrSlot('cards:after')}
747
+ </div>
748
+ `;
749
+ }
750
+ __renderCheckoutType(json) {
751
+ const { lang, ns } = this;
752
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('checkout-type', true);
753
+ const isReadonly = this.readonlySelector.matches('checkout-type', true);
754
+ return html `
755
+ <div data-testid="checkout-type">
756
+ ${this.renderTemplateOrSlot('checkout-type:before')}
757
+
758
+ <div class="space-y-xs">
759
+ <x-group frame>
760
+ <foxy-i18n
761
+ class=${isDisabled ? 'text-disabled' : ''}
762
+ slot="header"
763
+ lang=${lang}
764
+ key="checkout_type"
765
+ ns=${ns}
766
+ >
767
+ </foxy-i18n>
768
+
769
+ <x-choice
770
+ data-testid="checkout-type-choice"
771
+ ?disabled=${isDisabled}
772
+ ?readonly=${isReadonly}
773
+ .items=${['default_account', 'default_guest', 'guest_only', 'account_only']}
774
+ .value=${json.checkout_type}
775
+ .getText=${(item) => this.t(`checkout_type_${item}`)}
776
+ @change=${(evt) => {
777
+ json.checkout_type = evt.detail;
778
+ this.edit({ json: JSON.stringify(json) });
779
+ }}
780
+ >
781
+ </x-choice>
782
+ </x-group>
783
+
784
+ <foxy-i18n
785
+ class="text-xs leading-s block ${isDisabled ? 'text-disabled' : 'text-secondary'}"
786
+ lang=${lang}
787
+ key="checkout_type_helper_text"
788
+ ns=${ns}
789
+ >
790
+ </foxy-i18n>
791
+ </div>
792
+
793
+ ${this.renderTemplateOrSlot('checkout-type:after')}
794
+ </div>
795
+ `;
796
+ }
797
+ __renderConsent(json) {
798
+ const { lang, ns } = this;
799
+ const tosConfig = json.tos_checkbox_settings;
800
+ const mailConfig = json.newsletter_subscribe;
801
+ const sdtaConfig = json.eu_secure_data_transfer_consent;
802
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('consent', true);
803
+ const isReadonly = this.readonlySelector.matches('consent', true);
804
+ const dividerStyle = 'margin-left: calc(1.125rem + (var(--lumo-space-m) * 2))';
805
+ return html `
806
+ <div data-testid="consent">
807
+ ${this.renderTemplateOrSlot('consent:before')}
808
+
809
+ <x-group frame>
810
+ <foxy-i18n
811
+ class=${isDisabled ? 'text-disabled' : ''}
812
+ slot="header"
813
+ lang=${lang}
814
+ key="consent"
815
+ ns=${ns}
816
+ >
817
+ </foxy-i18n>
818
+
819
+ <x-checkbox
820
+ data-testid="consent-tos-check"
821
+ ?disabled=${isDisabled}
822
+ ?readonly=${isReadonly}
823
+ ?checked=${tosConfig.usage === 'required' || tosConfig.usage === 'optional'}
824
+ class="m-m"
825
+ @change=${(evt) => {
826
+ tosConfig.initial_state = evt.detail ? tosConfig.initial_state : 'unchecked';
827
+ tosConfig.is_hidden = false;
828
+ tosConfig.usage = evt.detail ? 'required' : 'none';
829
+ tosConfig.url = evt.detail ? tosConfig.url : '';
830
+ this.edit({ json: JSON.stringify(json) });
831
+ }}
832
+ >
833
+ <div class="flex flex-col">
834
+ <foxy-i18n lang=${lang} key="display_tos_link" ns=${ns}></foxy-i18n>
835
+ <foxy-i18n
836
+ class="text-xs leading-s ${isDisabled ? 'text-disabled' : 'text-secondary'}"
837
+ lang=${lang}
838
+ key="display_tos_link_explainer"
839
+ ns=${ns}
840
+ >
841
+ </foxy-i18n>
842
+ </div>
843
+
844
+ <div slot="content" ?hidden=${tosConfig.usage === 'none'}>
845
+ <vaadin-text-field
846
+ data-testid="consent-tos-field"
847
+ label=${this.t('location_url')}
848
+ class="w-full mt-m"
849
+ placeholder="https://example.com/path/to/tos"
850
+ clear-button-visible
851
+ ?disabled=${isDisabled}
852
+ ?readonly=${isReadonly}
853
+ .value=${tosConfig.url}
854
+ @input=${(evt) => {
855
+ tosConfig.url = evt.currentTarget.value;
856
+ this.edit({ json: JSON.stringify(json) });
857
+ }}
858
+ >
859
+ </vaadin-text-field>
860
+
861
+ <div class="flex flex-wrap -mx-s -mb-s mt-s">
862
+ <x-checkbox
863
+ data-testid="consent-tos-require-check"
864
+ class="m-s"
865
+ ?disabled=${isDisabled}
866
+ ?readonly=${isReadonly}
867
+ ?checked=${tosConfig.usage === 'required'}
868
+ @change=${(evt) => {
869
+ tosConfig.usage = evt.detail ? 'required' : 'optional';
870
+ this.edit({ json: JSON.stringify(json) });
871
+ }}
872
+ >
873
+ <foxy-i18n class="leading-s block" lang=${lang} key="require_consent" ns=${ns}>
874
+ </foxy-i18n>
875
+ </x-checkbox>
876
+
877
+ <x-checkbox
878
+ data-testid="consent-tos-state-check"
879
+ class="m-s"
880
+ ?disabled=${isDisabled}
881
+ ?readonly=${isReadonly}
882
+ ?checked=${tosConfig.initial_state === 'checked'}
883
+ @change=${(evt) => {
884
+ tosConfig.initial_state = evt.detail ? 'checked' : 'unchecked';
885
+ this.edit({ json: JSON.stringify(json) });
886
+ }}
887
+ >
888
+ <foxy-i18n class="leading-s block" lang=${lang} key="checked_by_default" ns=${ns}>
889
+ </foxy-i18n>
890
+ </x-checkbox>
891
+ </div>
892
+ </div>
893
+ </x-checkbox>
894
+
895
+ <div style=${dividerStyle} class="border-b border-contrast-10"></div>
896
+
897
+ <x-checkbox
898
+ data-testid="consent-mail-check"
899
+ ?disabled=${isDisabled}
900
+ ?readonly=${isReadonly}
901
+ ?checked=${mailConfig.usage === 'required'}
902
+ class="m-m"
903
+ @change=${(evt) => {
904
+ mailConfig.usage = evt.detail ? 'required' : 'none';
905
+ this.edit({ json: JSON.stringify(json) });
906
+ }}
907
+ >
908
+ <div class="flex flex-col">
909
+ <foxy-i18n lang=${lang} key="newsletter_subscribe" ns=${ns}></foxy-i18n>
910
+ <foxy-i18n
911
+ class="text-xs leading-s ${isDisabled ? 'text-disabled' : 'text-secondary'}"
912
+ lang=${lang}
913
+ key="newsletter_subscribe_explainer"
914
+ ns=${ns}
915
+ >
916
+ </foxy-i18n>
917
+ </div>
918
+ </x-checkbox>
919
+
920
+ <div style=${dividerStyle} class="border-b border-contrast-10"></div>
921
+
922
+ <x-checkbox
923
+ data-testid="consent-sdta-check"
924
+ ?disabled=${isDisabled}
925
+ ?readonly=${isReadonly}
926
+ ?checked=${sdtaConfig.usage === 'required'}
927
+ class="m-m"
928
+ @change=${(evt) => {
929
+ sdtaConfig.usage = evt.detail ? 'required' : 'none';
930
+ this.edit({ json: JSON.stringify(json) });
931
+ }}
932
+ >
933
+ <div class="flex flex-col">
934
+ <foxy-i18n lang=${lang} key="display_sdta" ns=${ns}></foxy-i18n>
935
+ <foxy-i18n
936
+ class="text-xs leading-s ${isDisabled ? 'text-disabled' : 'text-secondary'}"
937
+ lang=${lang}
938
+ key="display_sdta_explainer"
939
+ ns=${ns}
940
+ >
941
+ </foxy-i18n>
942
+ </div>
943
+ </x-checkbox>
944
+ </x-group>
945
+
946
+ ${this.renderTemplateOrSlot('consent:after')}
947
+ </div>
948
+ `;
949
+ }
950
+ __renderFields(json) {
951
+ const { lang, ns } = this;
952
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('fields', true);
953
+ const isReadonly = this.readonlySelector.matches('fields', true);
954
+ const config = json.custom_checkout_field_requirements;
955
+ const options = {
956
+ cart_controls: ['enabled', 'disabled'],
957
+ coupon_entry: ['enabled', 'disabled'],
958
+ billing_first_name: ['default', 'optional', 'required', 'hidden'],
959
+ billing_last_name: ['default', 'optional', 'required', 'hidden'],
960
+ billing_company: ['default', 'optional', 'required', 'hidden'],
961
+ billing_tax_id: ['default', 'optional', 'required', 'hidden'],
962
+ billing_phone: ['default', 'optional', 'required', 'hidden'],
963
+ billing_address1: ['default', 'optional', 'required', 'hidden'],
964
+ billing_address2: ['default', 'optional', 'required', 'hidden'],
965
+ billing_city: ['default', 'optional', 'required', 'hidden'],
966
+ billing_region: ['default', 'optional', 'required', 'hidden'],
967
+ billing_postal_code: ['default', 'optional', 'required', 'hidden'],
968
+ billing_country: ['default', 'optional', 'required', 'hidden'],
969
+ };
970
+ return html `
971
+ <div data-testid="fields">
972
+ ${this.renderTemplateOrSlot('fields:before')}
973
+
974
+ <x-group frame>
975
+ <foxy-i18n
976
+ class=${isDisabled ? 'text-disabled' : ''}
977
+ slot="header"
978
+ lang=${lang}
979
+ key="field_plural"
980
+ ns=${ns}
981
+ >
982
+ </foxy-i18n>
983
+
984
+ <div class="bg-contrast-10 grid grid-cols-1 md-grid-cols-2" style="gap: 1px">
985
+ ${Object.entries(options).map(([property, values]) => {
986
+ return html `
987
+ <label
988
+ class=${classMap({
989
+ 'flex items-center pl-m bg-base': true,
990
+ 'text-secondary': isReadonly,
991
+ 'text-disabled': isDisabled,
992
+ })}
993
+ >
994
+ <foxy-i18n
995
+ class="flex-1"
996
+ lang=${lang}
997
+ key=${property.replace('billing_', '')}
998
+ ns=${ns}
999
+ >
1000
+ </foxy-i18n>
1001
+
1002
+ <div
1003
+ class=${classMap({
1004
+ 'flex items-center text-right font-medium h-s px-s m-xs': isReadonly,
1005
+ 'hidden': !isReadonly,
1006
+ })}
1007
+ >
1008
+ ${this.t(values.find(value => config[property] === value))}
1009
+ </div>
1010
+
1011
+ <div
1012
+ class=${classMap({
1013
+ 'px-s m-xs flex items-center rounded leading-none': true,
1014
+ 'ring-primary-50 ring-inset focus-within-ring-2': !isDisabled,
1015
+ 'hover-text-primary': !isDisabled,
1016
+ 'cursor-pointer': !isDisabled,
1017
+ 'cursor-default': isDisabled,
1018
+ 'flex': !isReadonly,
1019
+ 'hidden': isReadonly,
1020
+ })}
1021
+ >
1022
+ <select
1023
+ data-testid="fields-${property}"
1024
+ class=${classMap({
1025
+ 'h-s mr-xs text-right appearance-none bg-transparent font-medium': true,
1026
+ 'focus-outline-none cursor-pointer': !isDisabled,
1027
+ 'cursor-default': isDisabled,
1028
+ })}
1029
+ ?disabled=${isDisabled}
1030
+ ?readonly=${isReadonly}
1031
+ @change=${(evt) => {
1032
+ const select = evt.currentTarget;
1033
+ const value = select.options[select.options.selectedIndex].value;
1034
+ config[property] = value;
1035
+ this.edit({ json: JSON.stringify(json) });
1036
+ }}
1037
+ >
1038
+ ${values.map(value => {
1039
+ return html `
1040
+ <option
1041
+ value=${value}
1042
+ ?selected=${config[property] === value}
1043
+ >
1044
+ ${this.t(value)}
1045
+ </option>
1046
+ `;
1047
+ })}
1048
+ </select>
1049
+
1050
+ <iron-icon
1051
+ class="pointer-events-none icon-inline text-xl"
1052
+ icon="icons:expand-more"
1053
+ >
1054
+ </iron-icon>
1055
+ </div>
1056
+ </label>
1057
+ `;
1058
+ })}
1059
+
1060
+ <div class="bg-base hidden md-block"></div>
1061
+ </div>
1062
+ </x-group>
1063
+
1064
+ ${this.renderTemplateOrSlot('fields:after')}
1065
+ </div>
1066
+ `;
1067
+ }
1068
+ __renderGoogleAnalytics(json) {
1069
+ const { lang, ns } = this;
1070
+ const config = json.analytics_config;
1071
+ const sioConfig = config.segment_io;
1072
+ const gaConfig = config.google_analytics;
1073
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('google-analytics', true);
1074
+ const isReadonly = this.readonlySelector.matches('google-analytics', true);
1075
+ return html `
1076
+ <div data-testid="google-analytics">
1077
+ ${this.renderTemplateOrSlot('google-analytics:before')}
1078
+
1079
+ <x-group frame>
1080
+ <span class=${isDisabled ? 'text-disabled' : ''} slot="header">Google Analytics</span>
1081
+
1082
+ <div class="p-m space-y-m">
1083
+ <vaadin-text-field
1084
+ data-testid="google-analytics-field"
1085
+ class="w-full"
1086
+ label=${this.t('ga_account_id')}
1087
+ placeholder="UA-1234567-1"
1088
+ helper-text=${this.t('ga_account_id_explainer')}
1089
+ .value=${live(gaConfig.account_id)}
1090
+ ?disabled=${isDisabled}
1091
+ ?readonly=${isReadonly}
1092
+ clear-button-visible
1093
+ @keydown=${(evt) => evt.key === 'Enter' && this.submit()}
1094
+ @input=${(evt) => {
1095
+ gaConfig.account_id = evt.currentTarget.value;
1096
+ gaConfig.usage = gaConfig.account_id ? 'required' : 'none';
1097
+ config.usage = gaConfig.account_id || sioConfig.account_id ? 'required' : 'none';
1098
+ this.edit({ json: JSON.stringify(json) });
1099
+ }}
1100
+ >
1101
+ </vaadin-text-field>
1102
+
1103
+ <x-checkbox
1104
+ data-testid="google-analytics-check"
1105
+ ?disabled=${isDisabled}
1106
+ ?readonly=${isReadonly}
1107
+ ?checked=${gaConfig.include_on_site}
1108
+ @change=${(evt) => {
1109
+ gaConfig.include_on_site = evt.detail;
1110
+ this.edit({ json: JSON.stringify(json) });
1111
+ }}
1112
+ >
1113
+ <div class="flex flex-col">
1114
+ <foxy-i18n lang=${lang} key="ga_include_on_site" ns=${ns}></foxy-i18n>
1115
+ <foxy-i18n
1116
+ class="text-xs leading-s ${isDisabled ? 'text-disabled' : 'text-secondary'}"
1117
+ lang=${lang}
1118
+ key="ga_include_on_site_explainer"
1119
+ ns=${ns}
1120
+ >
1121
+ </foxy-i18n>
1122
+ </div>
1123
+ </x-checkbox>
1124
+ </div>
1125
+ </x-group>
1126
+
1127
+ ${this.renderTemplateOrSlot('google-analytics:after')}
1128
+ </div>
1129
+ `;
1130
+ }
1131
+ __renderSegmentIo(json) {
1132
+ const config = json.analytics_config;
1133
+ const sioConfig = config.segment_io;
1134
+ const gaConfig = config.google_analytics;
1135
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('segment-io', true);
1136
+ const isReadonly = this.readonlySelector.matches('segment-io', true);
1137
+ return html `
1138
+ <div data-testid="segment-io">
1139
+ ${this.renderTemplateOrSlot('segment-io:before')}
1140
+
1141
+ <x-group frame>
1142
+ <span class=${isDisabled ? 'text-disabled' : ''} slot="header">Segment.io</span>
1143
+
1144
+ <div class="p-m">
1145
+ <vaadin-text-field
1146
+ data-testid="segment-io-field"
1147
+ class="w-full"
1148
+ label=${this.t('sio_account_id')}
1149
+ placeholder="MY-WRITE-KEY"
1150
+ helper-text=${this.t('sio_account_id_explainer')}
1151
+ .value=${live(sioConfig.account_id)}
1152
+ ?disabled=${isDisabled}
1153
+ ?readonly=${isReadonly}
1154
+ clear-button-visible
1155
+ @keydown=${(evt) => evt.key === 'Enter' && this.submit()}
1156
+ @input=${(evt) => {
1157
+ sioConfig.account_id = evt.currentTarget.value;
1158
+ sioConfig.usage = sioConfig.account_id ? 'required' : 'none';
1159
+ config.usage = gaConfig.account_id || sioConfig.account_id ? 'required' : 'none';
1160
+ this.edit({ json: JSON.stringify(json) });
1161
+ }}
1162
+ >
1163
+ </vaadin-text-field>
1164
+ </div>
1165
+ </x-group>
1166
+
1167
+ ${this.renderTemplateOrSlot('segment-io:after')}
1168
+ </div>
1169
+ `;
1170
+ }
1171
+ __renderTroubleshooting(json) {
1172
+ const { lang, ns } = this;
1173
+ const config = json.debug;
1174
+ const isDisabled = !this.in('idle') || this.disabledSelector.matches('troubleshooting', true);
1175
+ const isReadonly = this.readonlySelector.matches('troubleshooting', true);
1176
+ return html `
1177
+ <div data-testid="troubleshooting">
1178
+ ${this.renderTemplateOrSlot('troubleshooting:before')}
1179
+
1180
+ <x-group frame>
1181
+ <foxy-i18n
1182
+ class=${isDisabled ? 'text-disabled' : ''}
1183
+ slot="header"
1184
+ lang=${lang}
1185
+ key="troubleshooting"
1186
+ ns=${ns}
1187
+ >
1188
+ </foxy-i18n>
1189
+
1190
+ <div class="p-m space-y-m">
1191
+ <x-checkbox
1192
+ data-testid="troubleshooting-check"
1193
+ ?disabled=${isDisabled}
1194
+ ?readonly=${isReadonly}
1195
+ ?checked=${config.usage === 'required'}
1196
+ @change=${(evt) => {
1197
+ config.usage = evt.detail ? 'required' : 'none';
1198
+ this.edit({ json: JSON.stringify(json) });
1199
+ }}
1200
+ >
1201
+ <div class="flex flex-col">
1202
+ <foxy-i18n lang=${lang} key="troubleshooting_debug" ns=${ns}></foxy-i18n>
1203
+ <foxy-i18n
1204
+ class="text-xs leading-s ${isDisabled ? 'text-disabled' : 'text-secondary'}"
1205
+ lang=${lang}
1206
+ key="troubleshooting_debug_explainer"
1207
+ ns=${ns}
1208
+ >
1209
+ </foxy-i18n>
1210
+ </div>
1211
+ </x-checkbox>
1212
+ </div>
1213
+ </x-group>
1214
+
1215
+ ${this.renderTemplateOrSlot('troubleshooting:after')}
1216
+ </div>
1217
+ `;
1218
+ }
1219
+ __renderCustomConfig(json) {
1220
+ return html `
1221
+ <div data-testid="custom-config">
1222
+ ${this.renderTemplateOrSlot('custom-config:before')}
1223
+
1224
+ <vaadin-text-area
1225
+ data-testid="custom-config-field"
1226
+ class="w-full"
1227
+ label=${this.t('custom_config')}
1228
+ placeholder='{ "key": "value" }'
1229
+ helper-text=${this.t('custom_config_helper_text')}
1230
+ .value=${json.custom_config ? JSON.stringify(json.custom_config, null, 2) : ''}
1231
+ ?disabled=${!this.in('idle') || this.disabledSelector.matches('custom-config', true)}
1232
+ ?readonly=${this.readonlySelector.matches('custom-config', true)}
1233
+ @input=${(evt) => {
1234
+ const input = evt.currentTarget;
1235
+ try {
1236
+ json.custom_config = input.value ? JSON.parse(input.value) : '';
1237
+ this.edit({ json: JSON.stringify(json) });
1238
+ input.invalid = false;
1239
+ }
1240
+ catch (_a) {
1241
+ input.invalid = true;
1242
+ }
1243
+ }}
1244
+ >
1245
+ </vaadin-text-area>
1246
+
1247
+ ${this.renderTemplateOrSlot('custom-config:after')}
1248
+ </div>
1249
+ `;
1250
+ }
1251
+ __renderHeader(json) {
1252
+ return html `
1253
+ <div data-testid="header">
1254
+ ${this.renderTemplateOrSlot('header:before')}
1255
+
1256
+ <vaadin-text-area
1257
+ data-testid="header-field"
1258
+ class="w-full"
1259
+ label=${this.t('custom_header')}
1260
+ helper-text=${this.t('custom_header_helper_text')}
1261
+ .value=${json.custom_script_values.header}
1262
+ ?disabled=${!this.in('idle') || this.disabledSelector.matches('header', true)}
1263
+ ?readonly=${this.readonlySelector.matches('header', true)}
1264
+ @input=${(evt) => {
1265
+ const target = evt.currentTarget;
1266
+ const newConfig = {
1267
+ ...json.custom_script_values,
1268
+ header: target.value,
1269
+ };
1270
+ this.edit({ json: JSON.stringify({ ...json, custom_script_values: newConfig }) });
1271
+ }}
1272
+ >
1273
+ </vaadin-text-area>
1274
+
1275
+ ${this.renderTemplateOrSlot('header:after')}
1276
+ </div>
1277
+ `;
1278
+ }
1279
+ __renderCustomFields(json) {
1280
+ return html `
1281
+ <div data-testid="custom-fields">
1282
+ ${this.renderTemplateOrSlot('custom-fields:before')}
1283
+
1284
+ <vaadin-text-area
1285
+ data-testid="custom-fields-field"
1286
+ class="w-full"
1287
+ label=${this.t('custom_fields')}
1288
+ helper-text=${this.t('custom_fields_helper_text')}
1289
+ .value=${json.custom_script_values.checkout_fields}
1290
+ ?disabled=${!this.in('idle') || this.disabledSelector.matches('custom-fields', true)}
1291
+ ?readonly=${this.readonlySelector.matches('custom-fields', true)}
1292
+ @input=${(evt) => {
1293
+ const newValue = evt.currentTarget.value;
1294
+ json.custom_script_values.checkout_fields = newValue;
1295
+ this.edit({ json: JSON.stringify(json) });
1296
+ }}
1297
+ >
1298
+ </vaadin-text-area>
1299
+
1300
+ ${this.renderTemplateOrSlot('custom-fields:after')}
1301
+ </div>
1302
+ `;
1303
+ }
1304
+ __renderFooter(json) {
1305
+ return html `
1306
+ <div data-testid="footer">
1307
+ ${this.renderTemplateOrSlot('footer:before')}
1308
+
1309
+ <vaadin-text-area
1310
+ data-testid="footer-field"
1311
+ class="w-full"
1312
+ label=${this.t('custom_footer')}
1313
+ helper-text=${this.t('custom_footer_helper_text')}
1314
+ .value=${json.custom_script_values.footer}
1315
+ ?disabled=${!this.in('idle') || this.disabledSelector.matches('footer', true)}
1316
+ ?readonly=${this.readonlySelector.matches('footer', true)}
1317
+ @input=${(evt) => {
1318
+ const target = evt.currentTarget;
1319
+ const newConfig = {
1320
+ ...json.custom_script_values,
1321
+ footer: target.value,
1322
+ };
1323
+ this.edit({ json: JSON.stringify({ ...json, custom_script_values: newConfig }) });
1324
+ }}
1325
+ >
1326
+ </vaadin-text-area>
1327
+
1328
+ ${this.renderTemplateOrSlot('footer:after')}
1329
+ </div>
1330
+ `;
1331
+ }
1332
+ }
1333
+ //# sourceMappingURL=TemplateConfigForm.js.map