recur-tw 0.9.11 → 0.9.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +182 -91
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +182 -91
- package/dist/recur.umd.js +204 -142
- package/dist/server.cjs +1 -1
- package/dist/server.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -657,11 +657,11 @@ var init_payment_form_skeleton2 = __esm({
|
|
|
657
657
|
<h3 class="section-title">訂單摘要</h3>
|
|
658
658
|
<div class="order-summary">
|
|
659
659
|
<div class="order-row">
|
|
660
|
-
<span class="order-label"
|
|
661
|
-
<div class="skeleton skeleton-order-value"></div>
|
|
660
|
+
<span class="order-label">方案</span>
|
|
661
|
+
<div class="skeleton skeleton-order-value" style="width: 120px;"></div>
|
|
662
662
|
</div>
|
|
663
663
|
<div class="order-row">
|
|
664
|
-
<span class="order-label"
|
|
664
|
+
<span class="order-label">小計</span>
|
|
665
665
|
<div class="skeleton skeleton-order-value"></div>
|
|
666
666
|
</div>
|
|
667
667
|
<div class="coupon-section">
|
|
@@ -1035,7 +1035,7 @@ var init_payment_form_shadow = __esm({
|
|
|
1035
1035
|
var payment_form_light_default;
|
|
1036
1036
|
var init_payment_form_light = __esm({
|
|
1037
1037
|
"src/components/styles/payment-form-light.css"() {
|
|
1038
|
-
payment_form_light_default = "/**\n * Payment Form - Light DOM Styles\n * These styles are applied to slotted content in the Light DOM\n * Using BEM naming convention with 'recur-' prefix for isolation\n */\n\n/* ============================================\n * Order Summary Styles\n * ============================================ */\n.recur-order-summary {\n background: #f7fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n}\n\n.recur-order-summary__row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.recur-order-summary__row--total {\n margin-bottom: 0;\n padding-top: 12px;\n border-top: 1px solid #e2e8f0;\n}\n\n.recur-order-summary__label {\n font-size: 14px;\n color: #4a5568;\n}\n\n.recur-order-summary__value {\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n color: #2d3748;\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.recur-order-summary__total {\n font-size: 18px;\n line-height: 26px;\n font-weight: 700;\n color: #1a202c;\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n/* ============================================\n * Coupon Section Styles\n * ============================================ */\n.recur-coupon {\n padding: 12px 0;\n border-top: 1px solid #e2e8f0;\n margin-top: 12px;\n min-height: 36px;\n display: flex;\n align-items: center;\n}\n\n.recur-coupon__trigger {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n height: 36px;\n background: none;\n border: none;\n padding: 0;\n font-size: 14px;\n line-height: 1;\n color: #718096;\n cursor: pointer;\n transition: color 0.2s;\n}\n\n.recur-coupon__trigger:hover {\n color: #4a5568;\n}\n\n.recur-coupon__trigger-icon {\n width: 16px;\n height: 16px;\n}\n\n.recur-coupon__input-row {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 36px;\n}\n\n.recur-coupon__input {\n flex: 1;\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n text-transform: uppercase;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n\n.recur-coupon__input::placeholder {\n text-transform: none;\n}\n\n.recur-coupon__input:focus {\n border-color: #
|
|
1038
|
+
payment_form_light_default = "/**\n * Payment Form - Light DOM Styles\n * These styles are applied to slotted content in the Light DOM\n * Using BEM naming convention with 'recur-' prefix for isolation\n */\n\n/* ============================================\n * Order Summary Styles\n * ============================================ */\n.recur-order-summary {\n background: #f7fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n padding: 16px;\n}\n\n.recur-order-summary__row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.recur-order-summary__row--total {\n margin-bottom: 0;\n padding-top: 12px;\n border-top: 1px solid #e2e8f0;\n}\n\n.recur-order-summary__label {\n font-size: 14px;\n color: #4a5568;\n}\n\n.recur-order-summary__value {\n font-size: 14px;\n line-height: 20px;\n font-weight: 500;\n color: #2d3748;\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.recur-order-summary__total {\n font-size: 18px;\n line-height: 26px;\n font-weight: 700;\n color: #1a202c;\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n/* ============================================\n * Coupon Section Styles\n * ============================================ */\n.recur-coupon {\n padding: 12px 0;\n border-top: 1px solid #e2e8f0;\n margin-top: 12px;\n min-height: 36px;\n display: flex;\n align-items: center;\n}\n\n.recur-coupon__trigger {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n height: 36px;\n background: none;\n border: none;\n padding: 0;\n font-size: 14px;\n line-height: 1;\n color: #718096;\n cursor: pointer;\n transition: color 0.2s;\n}\n\n.recur-coupon__trigger:hover {\n color: #4a5568;\n}\n\n.recur-coupon__trigger-icon {\n width: 16px;\n height: 16px;\n}\n\n.recur-coupon__input-row {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 36px;\n}\n\n.recur-coupon__input-wrapper {\n position: relative;\n flex: 1;\n}\n\n.recur-coupon__input {\n width: 100%;\n height: 36px;\n padding: 0 32px 0 12px;\n font-size: 14px;\n text-transform: uppercase;\n background-color: #ffffff;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s, box-shadow 0.2s;\n}\n\n.recur-coupon__input::placeholder {\n text-transform: none;\n}\n\n.recur-coupon__input:hover:not(:focus) {\n border-color: #9ca3af;\n}\n\n.recur-coupon__input:focus {\n border-color: var(--ring, hsl(215 16% 47%));\n outline: 0;\n box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring, hsl(215 16% 47%)) 50%, transparent);\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.recur-coupon__clear {\n position: absolute;\n right: 8px;\n top: 50%;\n transform: translateY(-50%);\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: #9ca3af;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: color 0.2s;\n}\n\n.recur-coupon__clear:hover {\n color: #6b7280;\n}\n\n.recur-coupon__clear-icon {\n width: 16px;\n height: 16px;\n}\n\n.recur-coupon__btn {\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.2s, opacity 0.2s;\n white-space: nowrap;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.recur-coupon__btn--apply {\n background: #18181b;\n color: white;\n border: none;\n min-width: 52px;\n}\n\n.recur-coupon__btn--apply .recur-coupon__spinner {\n width: 14px;\n height: 14px;\n}\n\n.recur-coupon__btn--apply:hover:not(:disabled) {\n background: #27272a;\n}\n\n.recur-coupon__btn--apply:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.recur-coupon__error {\n width: 100%;\n margin-top: 8px;\n font-size: 13px;\n color: #dc2626;\n}\n\n.recur-coupon__applied-wrapper {\n width: 100%;\n}\n\n.recur-coupon__description {\n font-size: 12px;\n color: #6b7280;\n margin: 4px 0 0 22px;\n}\n\n.recur-coupon__bonus {\n display: flex;\n align-items: center;\n gap: 6px;\n background: #dcfce7;\n border-radius: 6px;\n padding: 8px 12px;\n margin-top: 8px;\n font-size: 12px;\n color: #15803d;\n}\n\n.recur-coupon__applied {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 36px;\n}\n\n.recur-coupon__applied-info {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n flex: 1;\n}\n\n.recur-coupon__applied-icon {\n width: 16px;\n height: 16px;\n color: #dc2626;\n flex-shrink: 0;\n}\n\n.recur-coupon__applied-name {\n font-size: 14px;\n font-weight: 500;\n color: #dc2626;\n white-space: nowrap;\n}\n\n.recur-coupon__applied-code {\n font-size: 14px;\n color: #9ca3af;\n white-space: nowrap;\n margin-right: 2px;\n}\n\n.recur-coupon__applied-amount {\n font-size: 14px;\n font-weight: 500;\n color: #dc2626;\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n flex-shrink: 0;\n margin-left: auto;\n}\n\n.recur-coupon__remove {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: #9ca3af;\n border-radius: 4px;\n transition: color 0.2s, background-color 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.recur-coupon__remove:hover {\n color: #6b7280;\n background: rgba(0, 0, 0, 0.05);\n}\n\n.recur-coupon__remove-icon {\n width: 14px;\n height: 14px;\n}\n\n.recur-coupon__spinner {\n width: 14px;\n height: 14px;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: recur-spin 0.6s linear infinite;\n}\n\n/* Discount Row */\n.recur-order-summary__row--discount {\n color: #16a34a;\n}\n\n.recur-order-summary__row--discount .recur-order-summary__value {\n color: #16a34a;\n font-weight: 500;\n}\n\n/* ============================================\n * Customer Info Styles\n * ============================================ */\n.recur-info-display {\n background: #f7fafc;\n border: 1px solid #e2e8f0;\n border-radius: 6px;\n padding: 12px;\n margin-bottom: 8px;\n}\n\n.recur-info-row {\n margin-bottom: 12px;\n}\n\n.recur-info-row:last-child {\n margin-bottom: 0;\n}\n\n.recur-info-label {\n display: block;\n font-size: 12px;\n line-height: 16px;\n color: #718096;\n margin-bottom: 2px;\n}\n\n.recur-info-value {\n display: block;\n font-size: 14px;\n line-height: 20px;\n min-height: 20px;\n color: #2d3748;\n font-weight: 500;\n word-break: break-all;\n}\n\n.recur-form-group {\n margin-bottom: 16px;\n}\n\n.recur-form-label {\n display: block;\n font-size: 14px;\n font-weight: 500;\n color: #2d3748;\n margin-bottom: 6px;\n}\n\n.recur-form-input {\n width: 100%;\n height: 36px;\n padding: 0 12px;\n font-size: 14px;\n border: 1px solid #d1d5db;\n border-radius: 6px;\n transition: border-color 0.2s;\n box-sizing: border-box;\n}\n\n.recur-form-input:focus {\n border-color: var(--ring, hsl(215 16% 47%));\n outline: 0;\n box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring, hsl(215 16% 47%)) 50%, transparent);\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n.recur-form-input:hover:not(:focus) {\n border-color: #9ca3af;\n}\n\n/* ============================================\n * Card Fields Styles\n * ============================================ */\n.recur-card-field {\n margin-bottom: 16px;\n}\n\n.recur-card-field-label {\n display: block;\n font-size: 14px;\n font-weight: 500;\n color: #2d3748;\n margin-bottom: 6px;\n}\n\n.recur-payuni-iframe {\n height: 36px;\n width: 100%;\n max-width: 100%;\n box-sizing: border-box;\n touch-action: manipulation;\n}\n\n.recur-card-row {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n column-gap: 16px;\n max-width: 100%;\n box-sizing: border-box;\n}\n\n.recur-card-field-container {\n position: relative;\n touch-action: manipulation;\n}\n\n.recur-card-skeleton {\n position: absolute;\n top: 0;\n left: 0;\n height: 36px;\n width: 100%;\n background: linear-gradient(90deg, #f0f0f0 0%, #e8e8e8 50%, #f0f0f0 100%);\n background-size: 200% 100%;\n animation: recur-skeleton-loading 1.5s ease-in-out infinite;\n border-radius: 4px;\n z-index: 1;\n pointer-events: none;\n}\n\n.recur-card-skeleton.hidden {\n display: none;\n}\n\n@keyframes recur-skeleton-loading {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* ============================================\n * Submit Button Styles\n * ============================================ */\n.recur-submit-button {\n width: 100%;\n padding: 14px 20px;\n font-size: 16px;\n font-weight: 500;\n color: #ffffff;\n background: #18181b;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: background-color 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n box-sizing: border-box;\n}\n\n.recur-submit-button:hover:not(:disabled) {\n background: #27272a;\n}\n\n.recur-submit-button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.recur-submit-button.loading {\n cursor: wait;\n}\n\n.recur-loading-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid currentColor;\n border-top-color: transparent;\n border-radius: 50%;\n animation: recur-spin 0.6s linear infinite;\n}\n\n@keyframes recur-spin {\n to { transform: rotate(360deg); }\n}\n\n/* ============================================\n * Skeleton Loading Styles\n * ============================================ */\n.recur-skeleton {\n display: inline-block;\n background: linear-gradient(90deg, #f0f0f0 0%, #e8e8e8 50%, #f0f0f0 100%);\n background-size: 200% 100%;\n animation: recur-skeleton-loading 1.5s ease-in-out infinite;\n border-radius: 4px;\n}\n";
|
|
1039
1039
|
}
|
|
1040
1040
|
});
|
|
1041
1041
|
|
|
@@ -1069,6 +1069,11 @@ var init_payment_form = __esm({
|
|
|
1069
1069
|
<svg class="recur-coupon__remove-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1070
1070
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
1071
1071
|
</svg>
|
|
1072
|
+
`,
|
|
1073
|
+
clearInput: litHtml.html`
|
|
1074
|
+
<svg class="recur-coupon__clear-icon" width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1075
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
1076
|
+
</svg>
|
|
1072
1077
|
`,
|
|
1073
1078
|
spinner: litHtml.html`<span class="recur-coupon__spinner"></span>`
|
|
1074
1079
|
};
|
|
@@ -1224,19 +1229,12 @@ var init_payment_form = __esm({
|
|
|
1224
1229
|
const amount = this.getAttribute("amount");
|
|
1225
1230
|
const interval = this.getAttribute("interval");
|
|
1226
1231
|
if (!productName || !amount) {
|
|
1227
|
-
const isSubscription2 = !!interval;
|
|
1228
1232
|
return litHtml.html`
|
|
1229
1233
|
<div class="recur-order-summary" id="${this.containerId}-order-summary">
|
|
1230
1234
|
<div class="recur-order-summary__row">
|
|
1231
|
-
<span class="recur-order-summary__label"
|
|
1232
|
-
<span class="recur-order-summary__value recur-skeleton" style="width:
|
|
1235
|
+
<span class="recur-order-summary__label">方案</span>
|
|
1236
|
+
<span class="recur-order-summary__value recur-skeleton" style="width: 120px; height: 20px;"></span>
|
|
1233
1237
|
</div>
|
|
1234
|
-
${isSubscription2 ? litHtml.html`
|
|
1235
|
-
<div class="recur-order-summary__row">
|
|
1236
|
-
<span class="recur-order-summary__label">計費週期</span>
|
|
1237
|
-
<span class="recur-order-summary__value recur-skeleton" style="width: 40px; height: 20px;"></span>
|
|
1238
|
-
</div>
|
|
1239
|
-
` : litHtml.nothing}
|
|
1240
1238
|
<div class="recur-order-summary__row">
|
|
1241
1239
|
<span class="recur-order-summary__label">小計</span>
|
|
1242
1240
|
<span class="recur-order-summary__value recur-skeleton" style="width: 80px; height: 20px;"></span>
|
|
@@ -1261,21 +1259,14 @@ var init_payment_form = __esm({
|
|
|
1261
1259
|
const originalAmount = Number(amount);
|
|
1262
1260
|
const discountAmount = this._appliedCoupon?.discountAmount || 0;
|
|
1263
1261
|
const finalAmount = originalAmount - discountAmount;
|
|
1264
|
-
const
|
|
1262
|
+
const productDisplay = periodText ? `${productName} / \u6BCF${periodText}` : productName;
|
|
1265
1263
|
return litHtml.html`
|
|
1266
1264
|
<div class="recur-order-summary" id="${this.containerId}-order-summary">
|
|
1267
1265
|
<div class="recur-order-summary__row">
|
|
1268
|
-
<span class="recur-order-summary__label"
|
|
1269
|
-
<span class="recur-order-summary__value">${
|
|
1266
|
+
<span class="recur-order-summary__label">方案</span>
|
|
1267
|
+
<span class="recur-order-summary__value">${productDisplay}</span>
|
|
1270
1268
|
</div>
|
|
1271
1269
|
|
|
1272
|
-
${isSubscription ? litHtml.html`
|
|
1273
|
-
<div class="recur-order-summary__row">
|
|
1274
|
-
<span class="recur-order-summary__label">計費週期</span>
|
|
1275
|
-
<span class="recur-order-summary__value">每${periodText}</span>
|
|
1276
|
-
</div>
|
|
1277
|
-
` : litHtml.nothing}
|
|
1278
|
-
|
|
1279
1270
|
<!-- 小計 (Subtotal) - always show -->
|
|
1280
1271
|
<div class="recur-order-summary__row">
|
|
1281
1272
|
<span class="recur-order-summary__label">小計</span>
|
|
@@ -1295,30 +1286,106 @@ var init_payment_form = __esm({
|
|
|
1295
1286
|
</div>
|
|
1296
1287
|
`;
|
|
1297
1288
|
}
|
|
1289
|
+
// Helper to get interval text in Chinese
|
|
1290
|
+
getIntervalText(interval, count) {
|
|
1291
|
+
if (!interval) return "";
|
|
1292
|
+
const countText = count && count > 1 ? count.toString() : "";
|
|
1293
|
+
switch (interval.toUpperCase()) {
|
|
1294
|
+
case "MONTH":
|
|
1295
|
+
return `${countText}\u6708`;
|
|
1296
|
+
case "YEAR":
|
|
1297
|
+
return `${countText}\u5E74`;
|
|
1298
|
+
case "WEEK":
|
|
1299
|
+
return `${countText}\u9031`;
|
|
1300
|
+
case "DAY":
|
|
1301
|
+
return `${countText}\u5929`;
|
|
1302
|
+
default:
|
|
1303
|
+
return "";
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
// Get discount description based on type and duration
|
|
1307
|
+
getDiscountDescription() {
|
|
1308
|
+
if (!this._appliedCoupon) return null;
|
|
1309
|
+
const { discountType, duration, durationMonths, productPrice, productInterval, productIntervalCount } = this._appliedCoupon;
|
|
1310
|
+
const intervalText = this.getIntervalText(productInterval, productIntervalCount);
|
|
1311
|
+
const originalPriceText = productPrice && intervalText ? `NT$ ${productPrice.toLocaleString()}/${intervalText}` : productPrice ? `NT$ ${productPrice.toLocaleString()}` : "";
|
|
1312
|
+
const amount = parseInt(this.getAttribute("amount") || "0", 10);
|
|
1313
|
+
const finalAmount = amount - this._appliedCoupon.discountAmount;
|
|
1314
|
+
if (discountType === "FIRST_PERIOD_PRICE") {
|
|
1315
|
+
if (originalPriceText) {
|
|
1316
|
+
return `\u9996\u671F\u53EA\u9700 NT$ ${finalAmount.toLocaleString()}\uFF0C\u4E4B\u5F8C ${originalPriceText}`;
|
|
1317
|
+
}
|
|
1318
|
+
return `\u9996\u671F\u53EA\u9700 NT$ ${finalAmount.toLocaleString()}`;
|
|
1319
|
+
}
|
|
1320
|
+
if (duration) {
|
|
1321
|
+
switch (duration) {
|
|
1322
|
+
case "ONCE":
|
|
1323
|
+
if (originalPriceText) {
|
|
1324
|
+
return `\u9996\u671F\u6298\u6263\uFF0C\u4E4B\u5F8C ${originalPriceText}`;
|
|
1325
|
+
}
|
|
1326
|
+
return "\u50C5\u9650\u9996\u671F";
|
|
1327
|
+
case "REPEATING":
|
|
1328
|
+
if (durationMonths) {
|
|
1329
|
+
return `\u524D ${durationMonths} \u671F\u4EAB\u512A\u60E0\uFF0C\u4E4B\u5F8C\u6062\u5FA9\u539F\u50F9`;
|
|
1330
|
+
}
|
|
1331
|
+
return null;
|
|
1332
|
+
case "FOREVER":
|
|
1333
|
+
return "\u7D42\u8EAB\u512A\u60E0";
|
|
1334
|
+
default:
|
|
1335
|
+
return null;
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
return null;
|
|
1339
|
+
}
|
|
1340
|
+
// Get bonus description
|
|
1341
|
+
getBonusDescription() {
|
|
1342
|
+
if (!this._appliedCoupon) return null;
|
|
1343
|
+
const parts = [];
|
|
1344
|
+
if (this._appliedCoupon.bonusTrialDays) {
|
|
1345
|
+
parts.push(`\u5EF6\u9577\u8A66\u7528 ${this._appliedCoupon.bonusTrialDays} \u5929`);
|
|
1346
|
+
}
|
|
1347
|
+
if (this._appliedCoupon.bonusMonths) {
|
|
1348
|
+
parts.push(`\u52A0\u9001 ${this._appliedCoupon.bonusMonths} \u500B\u6708`);
|
|
1349
|
+
}
|
|
1350
|
+
return parts.length > 0 ? parts.join("\u3001") : null;
|
|
1351
|
+
}
|
|
1298
1352
|
renderCoupon() {
|
|
1299
1353
|
if (this._appliedCoupon) {
|
|
1354
|
+
const discountDescription = this.getDiscountDescription();
|
|
1355
|
+
const bonusDescription = this.getBonusDescription();
|
|
1300
1356
|
return litHtml.html`
|
|
1301
|
-
<div class="recur-coupon__applied">
|
|
1302
|
-
<div class="recur-coupon__applied
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1357
|
+
<div class="recur-coupon__applied-wrapper">
|
|
1358
|
+
<div class="recur-coupon__applied">
|
|
1359
|
+
<div class="recur-coupon__applied-info">
|
|
1360
|
+
${icons.tagApplied}
|
|
1361
|
+
${this._appliedCoupon.couponName ? litHtml.html`
|
|
1362
|
+
<span class="recur-coupon__applied-name">${this._appliedCoupon.couponName}</span>
|
|
1363
|
+
<span class="recur-coupon__applied-code">(${this._appliedCoupon.code})</span>
|
|
1364
|
+
` : litHtml.html`
|
|
1365
|
+
<span class="recur-coupon__applied-name">${this._appliedCoupon.code}</span>
|
|
1366
|
+
`}
|
|
1367
|
+
<button
|
|
1368
|
+
type="button"
|
|
1369
|
+
class="recur-coupon__remove"
|
|
1370
|
+
?disabled=${this._couponLoading}
|
|
1371
|
+
@click=${() => this.removeCoupon()}
|
|
1372
|
+
>
|
|
1373
|
+
${this._couponLoading ? icons.spinner : icons.close}
|
|
1374
|
+
</button>
|
|
1375
|
+
</div>
|
|
1376
|
+
<span class="recur-coupon__applied-amount">
|
|
1377
|
+
-NT$ ${this._appliedCoupon.discountAmount.toLocaleString()}
|
|
1378
|
+
</span>
|
|
1318
1379
|
</div>
|
|
1319
|
-
|
|
1320
|
-
-
|
|
1321
|
-
|
|
1380
|
+
${discountDescription ? litHtml.html`
|
|
1381
|
+
<p class="recur-coupon__description">${discountDescription}</p>
|
|
1382
|
+
` : litHtml.nothing}
|
|
1383
|
+
${bonusDescription ? litHtml.html`
|
|
1384
|
+
<div class="recur-coupon__bonus">
|
|
1385
|
+
<span>✨</span>
|
|
1386
|
+
<span>${bonusDescription}</span>
|
|
1387
|
+
</div>
|
|
1388
|
+
` : litHtml.nothing}
|
|
1322
1389
|
</div>
|
|
1323
1390
|
`;
|
|
1324
1391
|
}
|
|
@@ -1326,16 +1393,28 @@ var init_payment_form = __esm({
|
|
|
1326
1393
|
return litHtml.html`
|
|
1327
1394
|
<div style="width: 100%;">
|
|
1328
1395
|
<div class="recur-coupon__input-row">
|
|
1329
|
-
<
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1396
|
+
<div class="recur-coupon__input-wrapper">
|
|
1397
|
+
<input
|
|
1398
|
+
type="text"
|
|
1399
|
+
class="recur-coupon__input"
|
|
1400
|
+
id="${this.containerId}-coupon-input"
|
|
1401
|
+
placeholder="輸入優惠碼"
|
|
1402
|
+
.value=${this._couponCode}
|
|
1403
|
+
?disabled=${this._couponLoading}
|
|
1404
|
+
@input=${(e) => this.handleCouponInputChange(e)}
|
|
1405
|
+
@keydown=${(e) => this.handleCouponKeydown(e)}
|
|
1406
|
+
/>
|
|
1407
|
+
${this._couponCode && !this._couponLoading ? litHtml.html`
|
|
1408
|
+
<button
|
|
1409
|
+
type="button"
|
|
1410
|
+
class="recur-coupon__clear"
|
|
1411
|
+
@click=${() => this.clearCouponInput()}
|
|
1412
|
+
aria-label="清除"
|
|
1413
|
+
>
|
|
1414
|
+
${icons.clearInput}
|
|
1415
|
+
</button>
|
|
1416
|
+
` : litHtml.nothing}
|
|
1417
|
+
</div>
|
|
1339
1418
|
<button
|
|
1340
1419
|
type="button"
|
|
1341
1420
|
class="recur-coupon__btn recur-coupon__btn--apply"
|
|
@@ -1344,14 +1423,6 @@ var init_payment_form = __esm({
|
|
|
1344
1423
|
>
|
|
1345
1424
|
${this._couponLoading ? icons.spinner : "\u5957\u7528"}
|
|
1346
1425
|
</button>
|
|
1347
|
-
<button
|
|
1348
|
-
type="button"
|
|
1349
|
-
class="recur-coupon__btn recur-coupon__btn--cancel"
|
|
1350
|
-
?disabled=${this._couponLoading}
|
|
1351
|
-
@click=${() => this.cancelCouponInput()}
|
|
1352
|
-
>
|
|
1353
|
-
取消
|
|
1354
|
-
</button>
|
|
1355
1426
|
</div>
|
|
1356
1427
|
${this._couponError ? litHtml.html`
|
|
1357
1428
|
<div class="recur-coupon__error">${this._couponError}</div>
|
|
@@ -1386,6 +1457,15 @@ var init_payment_form = __esm({
|
|
|
1386
1457
|
this._couponError = null;
|
|
1387
1458
|
this.updateCouponSectionDOM();
|
|
1388
1459
|
}
|
|
1460
|
+
clearCouponInput() {
|
|
1461
|
+
this._couponCode = "";
|
|
1462
|
+
this._couponError = null;
|
|
1463
|
+
this.updateCouponSectionDOM();
|
|
1464
|
+
requestAnimationFrame(() => {
|
|
1465
|
+
const input = document.getElementById(`${this.containerId}-coupon-input`);
|
|
1466
|
+
input?.focus();
|
|
1467
|
+
});
|
|
1468
|
+
}
|
|
1389
1469
|
handleCouponInputChange(e) {
|
|
1390
1470
|
this._couponCode = e.target.value.toUpperCase();
|
|
1391
1471
|
this._couponError = null;
|
|
@@ -1433,17 +1513,25 @@ var init_payment_form = __esm({
|
|
|
1433
1513
|
}
|
|
1434
1514
|
getCouponInputHTML() {
|
|
1435
1515
|
const errorHTML = this._couponError ? `<div class="recur-coupon__error">${this._couponError}</div>` : "";
|
|
1516
|
+
const clearBtnHTML = this._couponCode && !this._couponLoading ? `<button type="button" class="recur-coupon__clear" aria-label="\u6E05\u9664">
|
|
1517
|
+
<svg class="recur-coupon__clear-icon" width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1518
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
1519
|
+
</svg>
|
|
1520
|
+
</button>` : "";
|
|
1436
1521
|
return `
|
|
1437
1522
|
<div style="width: 100%;">
|
|
1438
1523
|
<div class="recur-coupon__input-row">
|
|
1439
|
-
<
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1524
|
+
<div class="recur-coupon__input-wrapper">
|
|
1525
|
+
<input
|
|
1526
|
+
type="text"
|
|
1527
|
+
class="recur-coupon__input"
|
|
1528
|
+
id="${this.containerId}-coupon-input"
|
|
1529
|
+
placeholder="\u8F38\u5165\u512A\u60E0\u78BC"
|
|
1530
|
+
value="${this._couponCode}"
|
|
1531
|
+
${this._couponLoading ? "disabled" : ""}
|
|
1532
|
+
/>
|
|
1533
|
+
${clearBtnHTML}
|
|
1534
|
+
</div>
|
|
1447
1535
|
<button
|
|
1448
1536
|
type="button"
|
|
1449
1537
|
class="recur-coupon__btn recur-coupon__btn--apply"
|
|
@@ -1451,13 +1539,6 @@ var init_payment_form = __esm({
|
|
|
1451
1539
|
>
|
|
1452
1540
|
${this._couponLoading ? '<span class="recur-coupon__spinner"></span>' : "\u5957\u7528"}
|
|
1453
1541
|
</button>
|
|
1454
|
-
<button
|
|
1455
|
-
type="button"
|
|
1456
|
-
class="recur-coupon__btn recur-coupon__btn--cancel"
|
|
1457
|
-
${this._couponLoading ? "disabled" : ""}
|
|
1458
|
-
>
|
|
1459
|
-
\u53D6\u6D88
|
|
1460
|
-
</button>
|
|
1461
1542
|
</div>
|
|
1462
1543
|
${errorHTML}
|
|
1463
1544
|
</div>
|
|
@@ -1466,18 +1547,26 @@ var init_payment_form = __esm({
|
|
|
1466
1547
|
getCouponAppliedHTML() {
|
|
1467
1548
|
const coupon = this._appliedCoupon;
|
|
1468
1549
|
const nameHTML = coupon.couponName ? `<span class="recur-coupon__applied-name">${coupon.couponName}</span><span class="recur-coupon__applied-code">(${coupon.code})</span>` : `<span class="recur-coupon__applied-name">${coupon.code}</span>`;
|
|
1550
|
+
const discountDescription = this.getDiscountDescription();
|
|
1551
|
+
const bonusDescription = this.getBonusDescription();
|
|
1552
|
+
const descriptionHTML = discountDescription ? `<p class="recur-coupon__description">${discountDescription}</p>` : "";
|
|
1553
|
+
const bonusHTML = bonusDescription ? `<div class="recur-coupon__bonus"><span>\u2728</span><span>${bonusDescription}</span></div>` : "";
|
|
1469
1554
|
return `
|
|
1470
|
-
<div class="recur-coupon__applied">
|
|
1471
|
-
<div class="recur-coupon__applied
|
|
1472
|
-
<
|
|
1473
|
-
<
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1555
|
+
<div class="recur-coupon__applied-wrapper">
|
|
1556
|
+
<div class="recur-coupon__applied">
|
|
1557
|
+
<div class="recur-coupon__applied-info">
|
|
1558
|
+
<svg class="recur-coupon__applied-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
1559
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z" />
|
|
1560
|
+
</svg>
|
|
1561
|
+
${nameHTML}
|
|
1562
|
+
<button type="button" class="recur-coupon__remove" ${this._couponLoading ? "disabled" : ""}>
|
|
1563
|
+
${this._couponLoading ? '<span class="recur-coupon__spinner"></span>' : '<svg class="recur-coupon__remove-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /></svg>'}
|
|
1564
|
+
</button>
|
|
1565
|
+
</div>
|
|
1566
|
+
<span class="recur-coupon__applied-amount">-NT$ ${coupon.discountAmount.toLocaleString()}</span>
|
|
1479
1567
|
</div>
|
|
1480
|
-
|
|
1568
|
+
${descriptionHTML}
|
|
1569
|
+
${bonusHTML}
|
|
1481
1570
|
</div>
|
|
1482
1571
|
`;
|
|
1483
1572
|
}
|
|
@@ -1488,11 +1577,11 @@ var init_payment_form = __esm({
|
|
|
1488
1577
|
bindCouponInputEvents(container) {
|
|
1489
1578
|
const input = container.querySelector(".recur-coupon__input");
|
|
1490
1579
|
const applyBtn = container.querySelector(".recur-coupon__btn--apply");
|
|
1491
|
-
const
|
|
1580
|
+
const clearBtn = container.querySelector(".recur-coupon__clear");
|
|
1492
1581
|
input?.addEventListener("input", (e) => this.handleCouponInputChange(e));
|
|
1493
1582
|
input?.addEventListener("keydown", (e) => this.handleCouponKeydown(e));
|
|
1494
1583
|
applyBtn?.addEventListener("click", () => this.applyCoupon());
|
|
1495
|
-
|
|
1584
|
+
clearBtn?.addEventListener("click", () => this.clearCouponInput());
|
|
1496
1585
|
}
|
|
1497
1586
|
bindCouponAppliedEvents(container) {
|
|
1498
1587
|
const removeBtn = container.querySelector(".recur-coupon__remove");
|
|
@@ -1552,7 +1641,10 @@ var init_payment_form = __esm({
|
|
|
1552
1641
|
duration: data.discount.duration,
|
|
1553
1642
|
durationMonths: data.discount.durationMonths,
|
|
1554
1643
|
bonusTrialDays: data.discount.bonusTrialDays,
|
|
1555
|
-
bonusMonths: data.discount.bonusMonths
|
|
1644
|
+
bonusMonths: data.discount.bonusMonths,
|
|
1645
|
+
productInterval: data.discount.productInterval,
|
|
1646
|
+
productIntervalCount: data.discount.productIntervalCount,
|
|
1647
|
+
productPrice: data.discount.productPrice
|
|
1556
1648
|
};
|
|
1557
1649
|
this._showCouponInput = false;
|
|
1558
1650
|
this._couponCode = "";
|
|
@@ -2560,7 +2652,7 @@ function toCamelCase(obj) {
|
|
|
2560
2652
|
|
|
2561
2653
|
// package.json
|
|
2562
2654
|
var package_default = {
|
|
2563
|
-
version: "0.9.
|
|
2655
|
+
version: "0.9.13"};
|
|
2564
2656
|
var SDK_VERSION = package_default.version;
|
|
2565
2657
|
var SDK_TYPE = "react";
|
|
2566
2658
|
var RecurContext = React.createContext(null);
|
|
@@ -2896,7 +2988,6 @@ function RecurProvider({ children, config: initialConfig = {} }) {
|
|
|
2896
2988
|
paymentForm.setAttribute("interval", checkoutResult.product.interval);
|
|
2897
2989
|
}
|
|
2898
2990
|
const customStyles = `
|
|
2899
|
-
/* PAYUNi SDK focus \u6A23\u5F0F - shadcn \u98A8\u683C */
|
|
2900
2991
|
.form-input-focus {
|
|
2901
2992
|
border-color: var(--ring, hsl(215 16% 47%)) !important;
|
|
2902
2993
|
outline: 0 !important;
|
package/dist/index.d.cts
CHANGED
|
@@ -511,9 +511,13 @@ declare class RecurPaymentForm extends HTMLElement {
|
|
|
511
511
|
private getCustomStyles;
|
|
512
512
|
private updateCustomStyles;
|
|
513
513
|
private renderOrderSummary;
|
|
514
|
+
private getIntervalText;
|
|
515
|
+
private getDiscountDescription;
|
|
516
|
+
private getBonusDescription;
|
|
514
517
|
private renderCoupon;
|
|
515
518
|
private showCouponInput;
|
|
516
519
|
private cancelCouponInput;
|
|
520
|
+
private clearCouponInput;
|
|
517
521
|
private handleCouponInputChange;
|
|
518
522
|
private handleCouponKeydown;
|
|
519
523
|
private updateApplyButtonState;
|
|
@@ -539,6 +543,9 @@ declare class RecurPaymentForm extends HTMLElement {
|
|
|
539
543
|
durationMonths?: number;
|
|
540
544
|
bonusTrialDays?: number;
|
|
541
545
|
bonusMonths?: number;
|
|
546
|
+
productInterval?: string;
|
|
547
|
+
productIntervalCount?: number;
|
|
548
|
+
productPrice?: number;
|
|
542
549
|
} | null;
|
|
543
550
|
private renderCustomerInfo;
|
|
544
551
|
private renderCardFields;
|
package/dist/index.d.ts
CHANGED
|
@@ -511,9 +511,13 @@ declare class RecurPaymentForm extends HTMLElement {
|
|
|
511
511
|
private getCustomStyles;
|
|
512
512
|
private updateCustomStyles;
|
|
513
513
|
private renderOrderSummary;
|
|
514
|
+
private getIntervalText;
|
|
515
|
+
private getDiscountDescription;
|
|
516
|
+
private getBonusDescription;
|
|
514
517
|
private renderCoupon;
|
|
515
518
|
private showCouponInput;
|
|
516
519
|
private cancelCouponInput;
|
|
520
|
+
private clearCouponInput;
|
|
517
521
|
private handleCouponInputChange;
|
|
518
522
|
private handleCouponKeydown;
|
|
519
523
|
private updateApplyButtonState;
|
|
@@ -539,6 +543,9 @@ declare class RecurPaymentForm extends HTMLElement {
|
|
|
539
543
|
durationMonths?: number;
|
|
540
544
|
bonusTrialDays?: number;
|
|
541
545
|
bonusMonths?: number;
|
|
546
|
+
productInterval?: string;
|
|
547
|
+
productIntervalCount?: number;
|
|
548
|
+
productPrice?: number;
|
|
542
549
|
} | null;
|
|
543
550
|
private renderCustomerInfo;
|
|
544
551
|
private renderCardFields;
|