@netlib/widerrufsbutton 1.0.6 → 1.1.0
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/README.md +6 -6
- package/dist/fallback.d.ts +8 -0
- package/dist/index.cjs.js +126 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.es.js +273 -107
- package/dist/styles.d.ts +1 -0
- package/dist/types.d.ts +15 -1
- package/dist/widerruf.html +323 -0
- package/dist/widerrufsbutton.iife.js +29 -10
- package/package.json +3 -2
package/dist/index.es.js
CHANGED
|
@@ -1,79 +1,90 @@
|
|
|
1
|
-
import { jsx as r, jsxs as
|
|
2
|
-
import { useState as
|
|
3
|
-
import { createPortal as
|
|
4
|
-
async function
|
|
1
|
+
import { jsx as r, jsxs as d, Fragment as j } from "react/jsx-runtime";
|
|
2
|
+
import { useState as p, useRef as T, useEffect as I } from "react";
|
|
3
|
+
import { createPortal as q } from "react-dom";
|
|
4
|
+
async function O(e, t) {
|
|
5
5
|
const n = {
|
|
6
6
|
"Content-Type": "application/json"
|
|
7
7
|
};
|
|
8
8
|
e.authToken && (n.Authorization = `Bearer ${e.authToken}`);
|
|
9
|
-
const
|
|
9
|
+
const b = {
|
|
10
10
|
action: e.action,
|
|
11
11
|
payload: {
|
|
12
|
-
...
|
|
12
|
+
...t,
|
|
13
13
|
datum: (/* @__PURE__ */ new Date()).toISOString()
|
|
14
14
|
}
|
|
15
15
|
}, i = await fetch(e.apiUrl, {
|
|
16
16
|
method: "PATCH",
|
|
17
17
|
headers: n,
|
|
18
|
-
body: JSON.stringify(
|
|
18
|
+
body: JSON.stringify(b)
|
|
19
19
|
});
|
|
20
|
+
let o;
|
|
21
|
+
try {
|
|
22
|
+
o = await i.json();
|
|
23
|
+
} catch {
|
|
24
|
+
if (!i.ok) throw new Error(`Server antwortete mit Status ${i.status}`);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (o !== null && typeof o == "object" && "ok" in o && o.ok === !1) {
|
|
28
|
+
const l = o.message;
|
|
29
|
+
throw new Error(typeof l == "string" && l ? l : `Server antwortete mit Status ${i.status}`);
|
|
30
|
+
}
|
|
20
31
|
if (!i.ok)
|
|
21
32
|
throw new Error(`Server antwortete mit Status ${i.status}`);
|
|
22
33
|
}
|
|
23
|
-
const
|
|
34
|
+
const W = (/* @__PURE__ */ new Date()).toLocaleDateString("de-DE", {
|
|
24
35
|
day: "2-digit",
|
|
25
36
|
month: "2-digit",
|
|
26
37
|
year: "numeric"
|
|
27
|
-
}),
|
|
38
|
+
}), D = {
|
|
28
39
|
name: "",
|
|
29
40
|
email: "",
|
|
30
41
|
vertragId: "",
|
|
31
42
|
widerrufsgrund: "",
|
|
32
|
-
datum:
|
|
43
|
+
datum: W
|
|
33
44
|
};
|
|
34
|
-
function
|
|
35
|
-
const
|
|
36
|
-
return e.name.trim() || (
|
|
37
|
-
}
|
|
38
|
-
function
|
|
39
|
-
const [n,
|
|
40
|
-
|
|
41
|
-
var
|
|
42
|
-
(
|
|
43
|
-
const
|
|
44
|
-
return document.addEventListener("keydown",
|
|
45
|
-
}, [
|
|
46
|
-
function
|
|
47
|
-
const
|
|
48
|
-
if (
|
|
49
|
-
const
|
|
50
|
-
|
|
45
|
+
function N(e) {
|
|
46
|
+
const t = {};
|
|
47
|
+
return e.name.trim() || (t.name = "Bitte geben Sie Ihren Namen an."), e.email.trim() ? /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e.email) || (t.email = "Bitte geben Sie eine gültige E-Mail-Adresse an.") : t.email = "Bitte geben Sie Ihre E-Mail-Adresse an.", e.vertragId.trim() || (t.vertragId = "Bitte geben Sie die Bestellnummer oder Vertragsnummer an."), t;
|
|
48
|
+
}
|
|
49
|
+
function F({ config: e, onClose: t }) {
|
|
50
|
+
const [n, b] = p(D), [i, o] = p({}), [l, m] = p({}), [h, v] = p("idle"), [E, S] = p(""), $ = T(null);
|
|
51
|
+
I(() => {
|
|
52
|
+
var c;
|
|
53
|
+
(c = $.current) == null || c.focus();
|
|
54
|
+
const a = (s) => s.key === "Escape" && t();
|
|
55
|
+
return document.addEventListener("keydown", a), () => document.removeEventListener("keydown", a);
|
|
56
|
+
}, [t]);
|
|
57
|
+
function g(a, c) {
|
|
58
|
+
const s = { ...n, [a]: c };
|
|
59
|
+
if (b(s), l[a]) {
|
|
60
|
+
const f = N(s);
|
|
61
|
+
o((x) => ({ ...x, [a]: f[a] }));
|
|
51
62
|
}
|
|
52
63
|
}
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
64
|
+
function k(a) {
|
|
65
|
+
m((s) => ({ ...s, [a]: !0 }));
|
|
66
|
+
const c = N(n);
|
|
67
|
+
o((s) => ({ ...s, [a]: c[a] }));
|
|
57
68
|
}
|
|
58
|
-
async function
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
69
|
+
async function C(a) {
|
|
70
|
+
var f, x;
|
|
71
|
+
a.preventDefault();
|
|
72
|
+
const c = Object.fromEntries(
|
|
73
|
+
Object.keys(n).map((y) => [y, !0])
|
|
62
74
|
);
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
66
|
-
|
|
75
|
+
m(c);
|
|
76
|
+
const s = N(n);
|
|
77
|
+
if (o(s), !(Object.keys(s).length > 0)) {
|
|
78
|
+
v("loading"), S("");
|
|
67
79
|
try {
|
|
68
|
-
await
|
|
69
|
-
} catch (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
), h("error");
|
|
80
|
+
await O(e, n), v("success"), (f = e.onSuccess) == null || f.call(e);
|
|
81
|
+
} catch (y) {
|
|
82
|
+
const z = y instanceof Error ? y : new Error("Ein unbekannter Fehler ist aufgetreten.");
|
|
83
|
+
S(z.message), v("error"), (x = e.onError) == null || x.call(e, z);
|
|
73
84
|
}
|
|
74
85
|
}
|
|
75
86
|
}
|
|
76
|
-
const
|
|
87
|
+
const L = e.companyName ? `Widerruf – ${e.companyName}` : "Widerrufsformular";
|
|
77
88
|
return /* @__PURE__ */ r(
|
|
78
89
|
"div",
|
|
79
90
|
{
|
|
@@ -81,97 +92,100 @@ function O({ config: e, onClose: a }) {
|
|
|
81
92
|
role: "dialog",
|
|
82
93
|
"aria-modal": "true",
|
|
83
94
|
"aria-labelledby": "wrb-title",
|
|
84
|
-
onClick: (
|
|
85
|
-
children: /* @__PURE__ */
|
|
86
|
-
/* @__PURE__ */
|
|
87
|
-
/* @__PURE__ */ r("h2", { className: "wrb-modal-title", id: "wrb-title", children:
|
|
95
|
+
onClick: (a) => a.target === a.currentTarget && t(),
|
|
96
|
+
children: /* @__PURE__ */ d("div", { className: "wrb-modal", children: [
|
|
97
|
+
/* @__PURE__ */ d("div", { className: "wrb-modal-header", children: [
|
|
98
|
+
/* @__PURE__ */ r("h2", { className: "wrb-modal-title", id: "wrb-title", children: L }),
|
|
88
99
|
/* @__PURE__ */ r(
|
|
89
100
|
"button",
|
|
90
101
|
{
|
|
91
102
|
className: "wrb-close-btn",
|
|
92
|
-
onClick:
|
|
103
|
+
onClick: t,
|
|
93
104
|
"aria-label": "Schließen",
|
|
94
105
|
type: "button",
|
|
95
106
|
children: "✕"
|
|
96
107
|
}
|
|
97
108
|
)
|
|
98
109
|
] }),
|
|
99
|
-
|
|
100
|
-
/* @__PURE__ */
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
h === "success" ? /* @__PURE__ */ d("div", { className: "wrb-modal-body", children: [
|
|
111
|
+
/* @__PURE__ */ d("div", { className: "wrb-success", children: [
|
|
112
|
+
/* @__PURE__ */ r("span", { className: "wrb-success-icon", children: "✓" }),
|
|
113
|
+
/* @__PURE__ */ r("h3", { children: "Widerruf eingegangen" }),
|
|
114
|
+
/* @__PURE__ */ d("p", { children: [
|
|
115
|
+
"Ihr Widerruf wurde erfolgreich übermittelt. Sie erhalten in Kürze eine Bestätigung an ",
|
|
116
|
+
/* @__PURE__ */ r("strong", { children: n.email }),
|
|
117
|
+
"."
|
|
118
|
+
] })
|
|
119
|
+
] }),
|
|
120
|
+
/* @__PURE__ */ r(B, { links: e.legalLinks })
|
|
121
|
+
] }) : /* @__PURE__ */ d("div", { className: "wrb-modal-body", children: [
|
|
108
122
|
e.introText && /* @__PURE__ */ r("p", { className: "wrb-intro", children: e.introText }),
|
|
109
|
-
|
|
110
|
-
/* @__PURE__ */
|
|
123
|
+
h === "error" && E && /* @__PURE__ */ r("div", { className: "wrb-alert wrb-alert-error", role: "alert", children: E }),
|
|
124
|
+
/* @__PURE__ */ d("form", { onSubmit: C, noValidate: !0, children: [
|
|
111
125
|
/* @__PURE__ */ r(
|
|
112
|
-
|
|
126
|
+
w,
|
|
113
127
|
{
|
|
114
128
|
label: "Name",
|
|
115
129
|
required: !0,
|
|
116
|
-
error:
|
|
130
|
+
error: l.name ? i.name : void 0,
|
|
117
131
|
children: /* @__PURE__ */ r(
|
|
118
132
|
"input",
|
|
119
133
|
{
|
|
120
|
-
ref:
|
|
121
|
-
className: `wrb-input${
|
|
134
|
+
ref: $,
|
|
135
|
+
className: `wrb-input${l.name && i.name ? " wrb-error" : ""}`,
|
|
122
136
|
type: "text",
|
|
123
137
|
autoComplete: "name",
|
|
124
138
|
value: n.name,
|
|
125
|
-
onChange: (
|
|
126
|
-
onBlur: () =>
|
|
139
|
+
onChange: (a) => g("name", a.target.value),
|
|
140
|
+
onBlur: () => k("name"),
|
|
127
141
|
placeholder: "Vor- und Nachname"
|
|
128
142
|
}
|
|
129
143
|
)
|
|
130
144
|
}
|
|
131
145
|
),
|
|
132
146
|
/* @__PURE__ */ r(
|
|
133
|
-
|
|
147
|
+
w,
|
|
134
148
|
{
|
|
135
149
|
label: "E-Mail-Adresse",
|
|
136
150
|
required: !0,
|
|
137
151
|
hint: "Hierüber erhalten Sie die Eingangsbestätigung.",
|
|
138
|
-
error:
|
|
152
|
+
error: l.email ? i.email : void 0,
|
|
139
153
|
children: /* @__PURE__ */ r(
|
|
140
154
|
"input",
|
|
141
155
|
{
|
|
142
|
-
className: `wrb-input${
|
|
156
|
+
className: `wrb-input${l.email && i.email ? " wrb-error" : ""}`,
|
|
143
157
|
type: "email",
|
|
144
158
|
autoComplete: "email",
|
|
145
159
|
value: n.email,
|
|
146
|
-
onChange: (
|
|
147
|
-
onBlur: () =>
|
|
160
|
+
onChange: (a) => g("email", a.target.value),
|
|
161
|
+
onBlur: () => k("email"),
|
|
148
162
|
placeholder: "name@beispiel.de"
|
|
149
163
|
}
|
|
150
164
|
)
|
|
151
165
|
}
|
|
152
166
|
),
|
|
153
167
|
/* @__PURE__ */ r(
|
|
154
|
-
|
|
168
|
+
w,
|
|
155
169
|
{
|
|
156
170
|
label: "Bestell- / Auftrags- / Vertragsnummer",
|
|
157
171
|
required: !0,
|
|
158
172
|
hint: "Zu finden in Ihrer Bestellbestätigung.",
|
|
159
|
-
error:
|
|
173
|
+
error: l.vertragId ? i.vertragId : void 0,
|
|
160
174
|
children: /* @__PURE__ */ r(
|
|
161
175
|
"input",
|
|
162
176
|
{
|
|
163
|
-
className: `wrb-input${
|
|
177
|
+
className: `wrb-input${l.vertragId && i.vertragId ? " wrb-error" : ""}`,
|
|
164
178
|
type: "text",
|
|
165
179
|
value: n.vertragId,
|
|
166
|
-
onChange: (
|
|
167
|
-
onBlur: () =>
|
|
180
|
+
onChange: (a) => g("vertragId", a.target.value),
|
|
181
|
+
onBlur: () => k("vertragId"),
|
|
168
182
|
placeholder: "z.B. 10045678"
|
|
169
183
|
}
|
|
170
184
|
)
|
|
171
185
|
}
|
|
172
186
|
),
|
|
173
187
|
/* @__PURE__ */ r(
|
|
174
|
-
|
|
188
|
+
w,
|
|
175
189
|
{
|
|
176
190
|
label: "Widerrufsgrund",
|
|
177
191
|
hint: "Freiwillige Angabe – ein Widerruf ist ohne Angabe von Gründen möglich.",
|
|
@@ -180,21 +194,21 @@ function O({ config: e, onClose: a }) {
|
|
|
180
194
|
{
|
|
181
195
|
className: "wrb-textarea",
|
|
182
196
|
value: n.widerrufsgrund,
|
|
183
|
-
onChange: (
|
|
197
|
+
onChange: (a) => g("widerrufsgrund", a.target.value),
|
|
184
198
|
placeholder: "Optional",
|
|
185
199
|
rows: 3
|
|
186
200
|
}
|
|
187
201
|
)
|
|
188
202
|
}
|
|
189
203
|
),
|
|
190
|
-
/* @__PURE__ */ r(
|
|
191
|
-
/* @__PURE__ */
|
|
204
|
+
/* @__PURE__ */ r(w, { label: "Datum der Widerrufserklärung", children: /* @__PURE__ */ r("div", { className: "wrb-date-display", children: W }) }),
|
|
205
|
+
/* @__PURE__ */ d("div", { className: "wrb-actions", children: [
|
|
192
206
|
/* @__PURE__ */ r(
|
|
193
207
|
"button",
|
|
194
208
|
{
|
|
195
209
|
type: "button",
|
|
196
210
|
className: "wrb-cancel-btn",
|
|
197
|
-
onClick:
|
|
211
|
+
onClick: t,
|
|
198
212
|
children: e.cancelLabel ?? "Abbrechen"
|
|
199
213
|
}
|
|
200
214
|
),
|
|
@@ -203,32 +217,43 @@ function O({ config: e, onClose: a }) {
|
|
|
203
217
|
{
|
|
204
218
|
type: "submit",
|
|
205
219
|
className: "wrb-submit-btn",
|
|
206
|
-
disabled:
|
|
207
|
-
children:
|
|
220
|
+
disabled: h === "loading",
|
|
221
|
+
children: h === "loading" ? "Wird gesendet…" : e.submitLabel ?? "Absenden"
|
|
208
222
|
}
|
|
209
223
|
)
|
|
210
224
|
] })
|
|
211
|
-
] })
|
|
225
|
+
] }),
|
|
226
|
+
/* @__PURE__ */ r(B, { links: e.legalLinks })
|
|
212
227
|
] })
|
|
213
228
|
] })
|
|
214
229
|
}
|
|
215
230
|
);
|
|
216
231
|
}
|
|
217
|
-
function
|
|
218
|
-
return /* @__PURE__ */
|
|
219
|
-
/* @__PURE__ */
|
|
232
|
+
function w({ label: e, required: t, hint: n, error: b, children: i }) {
|
|
233
|
+
return /* @__PURE__ */ d("div", { className: "wrb-field", children: [
|
|
234
|
+
/* @__PURE__ */ d("label", { className: "wrb-label", children: [
|
|
220
235
|
e,
|
|
221
|
-
|
|
236
|
+
t && /* @__PURE__ */ r("span", { className: "wrb-required", "aria-hidden": "true", children: "*" })
|
|
222
237
|
] }),
|
|
223
238
|
i,
|
|
224
|
-
n && !
|
|
225
|
-
|
|
239
|
+
n && !b && /* @__PURE__ */ r("p", { className: "wrb-hint", children: n }),
|
|
240
|
+
b && /* @__PURE__ */ r("p", { className: "wrb-field-error", role: "alert", children: b })
|
|
226
241
|
] });
|
|
227
242
|
}
|
|
228
|
-
function
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
243
|
+
function B({ links: e }) {
|
|
244
|
+
return e != null && e.length ? /* @__PURE__ */ r("div", { className: "wrb-legal-links", children: e.map((t) => /* @__PURE__ */ r(
|
|
245
|
+
"a",
|
|
246
|
+
{
|
|
247
|
+
href: t.href,
|
|
248
|
+
className: "wrb-legal-link",
|
|
249
|
+
target: "_blank",
|
|
250
|
+
rel: "noopener noreferrer",
|
|
251
|
+
children: t.name
|
|
252
|
+
},
|
|
253
|
+
t.href
|
|
254
|
+
)) }) : null;
|
|
255
|
+
}
|
|
256
|
+
const A = `
|
|
232
257
|
/* Widerrufsbutton widget — prefix: wrb- */
|
|
233
258
|
.wrb-btn {
|
|
234
259
|
display: inline-flex;
|
|
@@ -430,14 +455,37 @@ function $() {
|
|
|
430
455
|
font-size: 14px;
|
|
431
456
|
}
|
|
432
457
|
.wrb-alert-error { background: #fef2f2; border: 1px solid #fecaca; color: #991b1b; }
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
458
|
+
|
|
459
|
+
/* Legal links */
|
|
460
|
+
.wrb-legal-links {
|
|
461
|
+
display: flex;
|
|
462
|
+
flex-wrap: wrap;
|
|
463
|
+
gap: 4px 16px;
|
|
464
|
+
margin-top: 16px;
|
|
465
|
+
padding-top: 12px;
|
|
466
|
+
border-top: 1px solid #e5e7eb;
|
|
467
|
+
}
|
|
468
|
+
.wrb-legal-link {
|
|
469
|
+
font-size: 12px;
|
|
470
|
+
color: #6b7280;
|
|
471
|
+
text-decoration: none;
|
|
472
|
+
}
|
|
473
|
+
.wrb-legal-link:hover {
|
|
474
|
+
color: #374151;
|
|
475
|
+
text-decoration: underline;
|
|
476
|
+
}
|
|
477
|
+
`;
|
|
478
|
+
function M() {
|
|
479
|
+
const e = "wrb-styles";
|
|
480
|
+
if (document.getElementById(e)) return;
|
|
481
|
+
const t = document.createElement("style");
|
|
482
|
+
t.id = e, t.textContent = A, document.head.appendChild(t);
|
|
483
|
+
}
|
|
484
|
+
function P({ config: e }) {
|
|
485
|
+
const [t, n] = p(!1);
|
|
486
|
+
return I(() => {
|
|
487
|
+
M();
|
|
488
|
+
}, []), /* @__PURE__ */ d(j, { children: [
|
|
441
489
|
/* @__PURE__ */ r(
|
|
442
490
|
"button",
|
|
443
491
|
{
|
|
@@ -447,13 +495,131 @@ function L({ config: e }) {
|
|
|
447
495
|
children: e.buttonLabel ?? "Vertrag widerrufen"
|
|
448
496
|
}
|
|
449
497
|
),
|
|
450
|
-
|
|
451
|
-
/* @__PURE__ */ r(
|
|
498
|
+
t && q(
|
|
499
|
+
/* @__PURE__ */ r(F, { config: e, onClose: () => n(!1) }),
|
|
452
500
|
document.body
|
|
453
501
|
)
|
|
454
502
|
] });
|
|
455
503
|
}
|
|
504
|
+
function u(e) {
|
|
505
|
+
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
506
|
+
}
|
|
507
|
+
function R(e) {
|
|
508
|
+
var l;
|
|
509
|
+
const t = (/* @__PURE__ */ new Date()).toLocaleDateString("de-DE", {
|
|
510
|
+
day: "2-digit",
|
|
511
|
+
month: "2-digit",
|
|
512
|
+
year: "numeric"
|
|
513
|
+
}), n = e.companyName ? `Widerruf – ${u(e.companyName)}` : "Widerrufsformular", b = u(e.formAction ?? e.apiUrl ?? "/rest/v1/apiCancellation"), i = e.introText ? `<p class="wrb-intro">${u(e.introText)}</p>` : "", o = (l = e.legalLinks) != null && l.length ? `
|
|
514
|
+
<div class="wrb-legal-links">
|
|
515
|
+
${e.legalLinks.map((m) => `<a href="${u(m.href)}" class="wrb-legal-link" rel="noopener noreferrer">${u(m.name)}</a>`).join(`
|
|
516
|
+
`)}
|
|
517
|
+
</div>` : "";
|
|
518
|
+
return `<!DOCTYPE html>
|
|
519
|
+
<html lang="de">
|
|
520
|
+
<head>
|
|
521
|
+
<meta charset="UTF-8">
|
|
522
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
523
|
+
<title>${n}</title>
|
|
524
|
+
<style>
|
|
525
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
526
|
+
body { margin: 0; background: #f9fafb; }
|
|
527
|
+
.wrb-page {
|
|
528
|
+
min-height: 100vh;
|
|
529
|
+
display: flex;
|
|
530
|
+
align-items: flex-start;
|
|
531
|
+
justify-content: center;
|
|
532
|
+
padding: 40px 16px;
|
|
533
|
+
}
|
|
534
|
+
.wrb-page .wrb-modal { max-height: none; }
|
|
535
|
+
.wrb-page .wrb-modal-title { font-size: 20px; }
|
|
536
|
+
${A}
|
|
537
|
+
</style>
|
|
538
|
+
</head>
|
|
539
|
+
<body>
|
|
540
|
+
<div class="wrb-page">
|
|
541
|
+
<div class="wrb-modal">
|
|
542
|
+
<div class="wrb-modal-header">
|
|
543
|
+
<h1 class="wrb-modal-title">${n}</h1>
|
|
544
|
+
</div>
|
|
545
|
+
<div class="wrb-modal-body">
|
|
546
|
+
${i}
|
|
547
|
+
<form method="POST" action="${b}" novalidate>
|
|
548
|
+
<div class="wrb-field">
|
|
549
|
+
<label class="wrb-label">
|
|
550
|
+
Name <span class="wrb-required" aria-hidden="true">*</span>
|
|
551
|
+
</label>
|
|
552
|
+
<input
|
|
553
|
+
class="wrb-input"
|
|
554
|
+
type="text"
|
|
555
|
+
name="name"
|
|
556
|
+
autocomplete="name"
|
|
557
|
+
placeholder="Vor- und Nachname"
|
|
558
|
+
required
|
|
559
|
+
>
|
|
560
|
+
</div>
|
|
561
|
+
<div class="wrb-field">
|
|
562
|
+
<label class="wrb-label">
|
|
563
|
+
E-Mail-Adresse <span class="wrb-required" aria-hidden="true">*</span>
|
|
564
|
+
</label>
|
|
565
|
+
<input
|
|
566
|
+
class="wrb-input"
|
|
567
|
+
type="email"
|
|
568
|
+
name="email"
|
|
569
|
+
autocomplete="email"
|
|
570
|
+
placeholder="name@beispiel.de"
|
|
571
|
+
required
|
|
572
|
+
>
|
|
573
|
+
<p class="wrb-hint">Hierüber erhalten Sie die Eingangsbestätigung.</p>
|
|
574
|
+
</div>
|
|
575
|
+
<div class="wrb-field">
|
|
576
|
+
<label class="wrb-label">
|
|
577
|
+
Bestell- / Auftrags- / Vertragsnummer
|
|
578
|
+
<span class="wrb-required" aria-hidden="true">*</span>
|
|
579
|
+
</label>
|
|
580
|
+
<input
|
|
581
|
+
class="wrb-input"
|
|
582
|
+
type="text"
|
|
583
|
+
name="vertragId"
|
|
584
|
+
placeholder="z.B. 10045678"
|
|
585
|
+
required
|
|
586
|
+
>
|
|
587
|
+
<p class="wrb-hint">Zu finden in Ihrer Bestellbestätigung.</p>
|
|
588
|
+
</div>
|
|
589
|
+
<div class="wrb-field">
|
|
590
|
+
<label class="wrb-label">Widerrufsgrund</label>
|
|
591
|
+
<textarea
|
|
592
|
+
class="wrb-textarea"
|
|
593
|
+
name="widerrufsgrund"
|
|
594
|
+
placeholder="Optional"
|
|
595
|
+
rows="3"
|
|
596
|
+
></textarea>
|
|
597
|
+
<p class="wrb-hint">
|
|
598
|
+
Freiwillige Angabe – ein Widerruf ist ohne Angabe von Gründen möglich.
|
|
599
|
+
</p>
|
|
600
|
+
</div>
|
|
601
|
+
<div class="wrb-field">
|
|
602
|
+
<label class="wrb-label">Datum der Widerrufserklärung</label>
|
|
603
|
+
<div class="wrb-date-display">${t}</div>
|
|
604
|
+
<input type="hidden" name="datum" value="${t}">
|
|
605
|
+
</div>
|
|
606
|
+
<input type="hidden" name="action" value="${u(e.action)}">
|
|
607
|
+
${e.successUrl ? `<input type="hidden" name="successUrl" value="${u(e.successUrl)}">` : ""}
|
|
608
|
+
<div class="wrb-actions">
|
|
609
|
+
<button type="submit" class="wrb-submit-btn">
|
|
610
|
+
${u(e.submitLabel ?? "Absenden")}
|
|
611
|
+
</button>
|
|
612
|
+
</div>
|
|
613
|
+
</form>
|
|
614
|
+
${o}
|
|
615
|
+
</div>
|
|
616
|
+
</div>
|
|
617
|
+
</div>
|
|
618
|
+
</body>
|
|
619
|
+
</html>`;
|
|
620
|
+
}
|
|
456
621
|
export {
|
|
457
|
-
|
|
458
|
-
|
|
622
|
+
F as WiderrufsModal,
|
|
623
|
+
P as WiderrufsWidget,
|
|
624
|
+
R as generateFallbackHtml
|
|
459
625
|
};
|
package/dist/styles.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
+
export declare const WRB_CSS = "\n/* Widerrufsbutton widget \u2014 prefix: wrb- */\n.wrb-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 10px 20px;\n background: #c0392b;\n color: #fff;\n border: none;\n border-radius: 6px;\n font-size: 15px;\n font-weight: 600;\n cursor: pointer;\n font-family: inherit;\n transition: background 0.2s;\n text-decoration: none;\n}\n.wrb-btn:hover { background: #a93226; }\n.wrb-btn:focus-visible { outline: 3px solid #e74c3c; outline-offset: 2px; }\n\n/* Overlay */\n.wrb-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0,0,0,0.55);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 99999;\n padding: 16px;\n animation: wrb-fade-in 0.15s ease;\n}\n@keyframes wrb-fade-in { from { opacity: 0 } to { opacity: 1 } }\n\n/* Modal box */\n.wrb-modal {\n background: #fff;\n border-radius: 10px;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n width: 100%;\n max-width: 540px;\n max-height: 90vh;\n overflow-y: auto;\n animation: wrb-slide-up 0.2s ease;\n font-family: system-ui, -apple-system, sans-serif;\n font-size: 15px;\n color: #1a1a1a;\n}\n@keyframes wrb-slide-up { from { transform: translateY(20px); opacity: 0 } to { transform: none; opacity: 1 } }\n\n.wrb-modal-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 20px 24px 16px;\n border-bottom: 1px solid #e5e7eb;\n gap: 12px;\n}\n.wrb-modal-title {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: #111;\n line-height: 1.3;\n}\n.wrb-close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: #6b7280;\n padding: 4px;\n border-radius: 4px;\n font-size: 20px;\n line-height: 1;\n flex-shrink: 0;\n}\n.wrb-close-btn:hover { color: #111; background: #f3f4f6; }\n\n.wrb-modal-body {\n padding: 20px 24px 24px;\n}\n\n.wrb-intro {\n margin: 0 0 20px;\n color: #4b5563;\n line-height: 1.6;\n font-size: 14px;\n}\n\n/* Form */\n.wrb-field {\n margin-bottom: 16px;\n}\n.wrb-label {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: #374151;\n margin-bottom: 5px;\n}\n.wrb-required {\n color: #c0392b;\n margin-left: 2px;\n}\n.wrb-input,\n.wrb-textarea {\n width: 100%;\n padding: 9px 12px;\n border: 1.5px solid #d1d5db;\n border-radius: 6px;\n font-size: 15px;\n font-family: inherit;\n color: #111;\n background: #fff;\n box-sizing: border-box;\n transition: border-color 0.15s;\n}\n.wrb-input:focus,\n.wrb-textarea:focus {\n outline: none;\n border-color: #c0392b;\n box-shadow: 0 0 0 3px rgba(192,57,43,0.12);\n}\n.wrb-input.wrb-error,\n.wrb-textarea.wrb-error {\n border-color: #c0392b;\n}\n.wrb-field-error {\n color: #c0392b;\n font-size: 12px;\n margin-top: 4px;\n}\n.wrb-textarea { resize: vertical; min-height: 80px; }\n\n.wrb-hint {\n font-size: 12px;\n color: #6b7280;\n margin-top: 4px;\n}\n\n.wrb-date-display {\n padding: 9px 12px;\n background: #f9fafb;\n border: 1.5px solid #e5e7eb;\n border-radius: 6px;\n color: #6b7280;\n font-size: 15px;\n}\n\n/* Actions */\n.wrb-actions {\n display: flex;\n gap: 10px;\n justify-content: flex-end;\n margin-top: 24px;\n padding-top: 16px;\n border-top: 1px solid #e5e7eb;\n}\n.wrb-submit-btn {\n padding: 10px 22px;\n background: #c0392b;\n color: #fff;\n border: none;\n border-radius: 6px;\n font-size: 15px;\n font-weight: 600;\n cursor: pointer;\n font-family: inherit;\n transition: background 0.2s;\n}\n.wrb-submit-btn:hover:not(:disabled) { background: #a93226; }\n.wrb-submit-btn:disabled { opacity: 0.6; cursor: not-allowed; }\n.wrb-cancel-btn {\n padding: 10px 18px;\n background: transparent;\n color: #374151;\n border: 1.5px solid #d1d5db;\n border-radius: 6px;\n font-size: 15px;\n cursor: pointer;\n font-family: inherit;\n transition: background 0.15s;\n}\n.wrb-cancel-btn:hover { background: #f3f4f6; }\n\n/* Success / Error states */\n.wrb-success {\n text-align: center;\n padding: 32px 24px;\n}\n.wrb-success-icon { font-size: 48px; display: block; margin-bottom: 12px; }\n.wrb-success h3 { margin: 0 0 8px; font-size: 20px; color: #111; }\n.wrb-success p { margin: 0; color: #4b5563; line-height: 1.6; }\n\n.wrb-alert {\n padding: 12px 16px;\n border-radius: 6px;\n margin-bottom: 16px;\n font-size: 14px;\n}\n.wrb-alert-error { background: #fef2f2; border: 1px solid #fecaca; color: #991b1b; }\n\n/* Legal links */\n.wrb-legal-links {\n display: flex;\n flex-wrap: wrap;\n gap: 4px 16px;\n margin-top: 16px;\n padding-top: 12px;\n border-top: 1px solid #e5e7eb;\n}\n.wrb-legal-link {\n font-size: 12px;\n color: #6b7280;\n text-decoration: none;\n}\n.wrb-legal-link:hover {\n color: #374151;\n text-decoration: underline;\n}\n";
|
|
1
2
|
/** Injects scoped CSS once into the document head */
|
|
2
3
|
export declare function injectStyles(): void;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export interface LegalLink {
|
|
2
|
+
name: string;
|
|
3
|
+
href: string;
|
|
4
|
+
}
|
|
1
5
|
export interface WiderrufsConfig {
|
|
2
6
|
/** PATCH endpoint, e.g. /rest/v1/systemLog */
|
|
3
7
|
apiUrl: string;
|
|
@@ -15,8 +19,18 @@ export interface WiderrufsConfig {
|
|
|
15
19
|
authToken?: string;
|
|
16
20
|
/** Label for the cancel button (default: "Abbrechen") */
|
|
17
21
|
cancelLabel?: string;
|
|
18
|
-
/** Label for the submit button (default: "
|
|
22
|
+
/** Label for the submit button (default: "Absenden") */
|
|
19
23
|
submitLabel?: string;
|
|
24
|
+
/** Legal navigation links shown in modal footer and static fallback page */
|
|
25
|
+
legalLinks?: LegalLink[];
|
|
26
|
+
/** POST action URL for the static HTML fallback form (defaults to apiUrl) */
|
|
27
|
+
formAction?: string;
|
|
28
|
+
/** Redirect URL after successful submit on the static fallback page */
|
|
29
|
+
successUrl?: string;
|
|
30
|
+
/** Called after a successful submit in the modal */
|
|
31
|
+
onSuccess?: () => void;
|
|
32
|
+
/** Called after a failed submit in the modal */
|
|
33
|
+
onError?: (error: Error) => void;
|
|
20
34
|
}
|
|
21
35
|
export interface WiderrufsFormData {
|
|
22
36
|
name: string;
|