@owlmeans/web-payment 0.1.18-rc.2 → 0.1.18-rc.21

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 (203) hide show
  1. package/README.md +30 -1
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/web-payment/SKILL.md +287 -20
  4. package/build/@/components/ui/card.d.ts +10 -0
  5. package/build/@/components/ui/card.d.ts.map +1 -0
  6. package/build/@/components/ui/card.js +25 -0
  7. package/build/@/components/ui/card.js.map +1 -0
  8. package/build/@/components/ui/checkbox.d.ts +5 -0
  9. package/build/@/components/ui/checkbox.d.ts.map +1 -0
  10. package/build/@/components/ui/checkbox.js +6 -0
  11. package/build/@/components/ui/checkbox.js.map +1 -0
  12. package/build/@/components/ui/progress.d.ts +5 -0
  13. package/build/@/components/ui/progress.d.ts.map +1 -0
  14. package/build/@/components/ui/progress.js +11 -0
  15. package/build/@/components/ui/progress.js.map +1 -0
  16. package/build/@/components/ui/select.d.ts +8 -0
  17. package/build/@/components/ui/select.d.ts.map +1 -0
  18. package/build/@/components/ui/select.js +9 -0
  19. package/build/@/components/ui/select.js.map +1 -0
  20. package/build/capability-list.d.ts +7 -0
  21. package/build/capability-list.d.ts.map +1 -0
  22. package/build/capability-list.js +24 -0
  23. package/build/capability-list.js.map +1 -0
  24. package/build/checkout-limit.d.ts +11 -0
  25. package/build/checkout-limit.d.ts.map +1 -0
  26. package/build/checkout-limit.js +34 -0
  27. package/build/checkout-limit.js.map +1 -0
  28. package/build/consumer/cancellation.d.ts +20 -0
  29. package/build/consumer/cancellation.d.ts.map +1 -0
  30. package/build/consumer/cancellation.js +115 -0
  31. package/build/consumer/cancellation.js.map +1 -0
  32. package/build/consumer/copy.d.ts +23 -0
  33. package/build/consumer/copy.d.ts.map +1 -0
  34. package/build/consumer/copy.js +75 -0
  35. package/build/consumer/copy.js.map +1 -0
  36. package/build/consumer/ensure.d.ts +56 -0
  37. package/build/consumer/ensure.d.ts.map +1 -0
  38. package/build/consumer/ensure.js +71 -0
  39. package/build/consumer/ensure.js.map +1 -0
  40. package/build/consumer/fields.d.ts +43 -0
  41. package/build/consumer/fields.d.ts.map +1 -0
  42. package/build/consumer/fields.js +19 -0
  43. package/build/consumer/fields.js.map +1 -0
  44. package/build/consumer/hooks.d.ts +113 -0
  45. package/build/consumer/hooks.d.ts.map +1 -0
  46. package/build/consumer/hooks.js +225 -0
  47. package/build/consumer/hooks.js.map +1 -0
  48. package/build/consumer/index.d.ts +14 -0
  49. package/build/consumer/index.d.ts.map +1 -0
  50. package/build/consumer/index.js +12 -0
  51. package/build/consumer/index.js.map +1 -0
  52. package/build/consumer/legal.d.ts +53 -0
  53. package/build/consumer/legal.d.ts.map +1 -0
  54. package/build/consumer/legal.js +77 -0
  55. package/build/consumer/legal.js.map +1 -0
  56. package/build/consumer/performance-consent-dialog.d.ts +18 -0
  57. package/build/consumer/performance-consent-dialog.d.ts.map +1 -0
  58. package/build/consumer/performance-consent-dialog.js +71 -0
  59. package/build/consumer/performance-consent-dialog.js.map +1 -0
  60. package/build/consumer/provider.d.ts +33 -0
  61. package/build/consumer/provider.d.ts.map +1 -0
  62. package/build/consumer/provider.js +26 -0
  63. package/build/consumer/provider.js.map +1 -0
  64. package/build/consumer/refusal.d.ts +35 -0
  65. package/build/consumer/refusal.d.ts.map +1 -0
  66. package/build/consumer/refusal.js +98 -0
  67. package/build/consumer/refusal.js.map +1 -0
  68. package/build/consumer/subscription-start-dialog.d.ts +16 -0
  69. package/build/consumer/subscription-start-dialog.d.ts.map +1 -0
  70. package/build/consumer/subscription-start-dialog.js +43 -0
  71. package/build/consumer/subscription-start-dialog.js.map +1 -0
  72. package/build/consumer/types.d.ts +114 -0
  73. package/build/consumer/types.d.ts.map +1 -0
  74. package/build/consumer/types.js +2 -0
  75. package/build/consumer/types.js.map +1 -0
  76. package/build/consumer/withdrawal.d.ts +29 -0
  77. package/build/consumer/withdrawal.d.ts.map +1 -0
  78. package/build/consumer/withdrawal.js +140 -0
  79. package/build/consumer/withdrawal.js.map +1 -0
  80. package/build/copy.d.ts +14 -0
  81. package/build/copy.d.ts.map +1 -0
  82. package/build/copy.js +51 -0
  83. package/build/copy.js.map +1 -0
  84. package/build/dialog.d.ts +1 -1
  85. package/build/dialog.d.ts.map +1 -1
  86. package/build/dialog.js +46 -17
  87. package/build/dialog.js.map +1 -1
  88. package/build/entitlement.d.ts +26 -0
  89. package/build/entitlement.d.ts.map +1 -0
  90. package/build/entitlement.js +42 -0
  91. package/build/entitlement.js.map +1 -0
  92. package/build/estimate-cache.d.ts +14 -0
  93. package/build/estimate-cache.d.ts.map +1 -0
  94. package/build/estimate-cache.js +39 -0
  95. package/build/estimate-cache.js.map +1 -0
  96. package/build/estimate-summary.d.ts +64 -0
  97. package/build/estimate-summary.d.ts.map +1 -0
  98. package/build/estimate-summary.js +94 -0
  99. package/build/estimate-summary.js.map +1 -0
  100. package/build/estimate.d.ts +34 -0
  101. package/build/estimate.d.ts.map +1 -0
  102. package/build/estimate.js +92 -0
  103. package/build/estimate.js.map +1 -0
  104. package/build/format.d.ts +15 -0
  105. package/build/format.d.ts.map +1 -0
  106. package/build/format.js +68 -0
  107. package/build/format.js.map +1 -0
  108. package/build/hooks.d.ts +0 -4
  109. package/build/hooks.d.ts.map +1 -1
  110. package/build/hooks.js +3 -30
  111. package/build/hooks.js.map +1 -1
  112. package/build/i18n/be.json +1 -1
  113. package/build/i18n/de.json +1 -1
  114. package/build/i18n/en.json +1 -1
  115. package/build/i18n/es.json +1 -1
  116. package/build/i18n/fr.json +145 -0
  117. package/build/i18n/pl.json +1 -1
  118. package/build/i18n/ru.json +1 -1
  119. package/build/i18n/uk.json +1 -1
  120. package/build/i18n.d.ts +2 -1
  121. package/build/i18n.d.ts.map +1 -1
  122. package/build/i18n.js +11 -7
  123. package/build/i18n.js.map +1 -1
  124. package/build/index.d.ts +9 -0
  125. package/build/index.d.ts.map +1 -1
  126. package/build/index.js +9 -0
  127. package/build/index.js.map +1 -1
  128. package/build/limit-meter.d.ts +7 -0
  129. package/build/limit-meter.d.ts.map +1 -0
  130. package/build/limit-meter.js +26 -0
  131. package/build/limit-meter.js.map +1 -0
  132. package/build/plan-card.d.ts +7 -0
  133. package/build/plan-card.d.ts.map +1 -0
  134. package/build/plan-card.js +29 -0
  135. package/build/plan-card.js.map +1 -0
  136. package/build/poll.d.ts +7 -0
  137. package/build/poll.d.ts.map +1 -0
  138. package/build/poll.js +28 -0
  139. package/build/poll.js.map +1 -0
  140. package/build/selectors.d.ts +18 -0
  141. package/build/selectors.d.ts.map +1 -0
  142. package/build/selectors.js +78 -0
  143. package/build/selectors.js.map +1 -0
  144. package/build/types.d.ts +120 -2
  145. package/build/types.d.ts.map +1 -1
  146. package/package.json +22 -7
  147. package/src/@/components/ui/card.tsx +93 -0
  148. package/src/@/components/ui/checkbox.tsx +23 -0
  149. package/src/@/components/ui/progress.tsx +44 -0
  150. package/src/@/components/ui/select.tsx +62 -0
  151. package/src/@/globals.css +10 -0
  152. package/src/capability-list.tsx +50 -0
  153. package/src/checkout-limit.tsx +48 -0
  154. package/src/consumer/cancellation.tsx +214 -0
  155. package/src/consumer/copy.ts +93 -0
  156. package/src/consumer/ensure.ts +124 -0
  157. package/src/consumer/fields.tsx +89 -0
  158. package/src/consumer/hooks.ts +358 -0
  159. package/src/consumer/index.ts +13 -0
  160. package/src/consumer/legal.tsx +129 -0
  161. package/src/consumer/performance-consent-dialog.tsx +132 -0
  162. package/src/consumer/provider.tsx +49 -0
  163. package/src/consumer/refusal.ts +110 -0
  164. package/src/consumer/subscription-start-dialog.tsx +87 -0
  165. package/src/consumer/types.ts +121 -0
  166. package/src/consumer/withdrawal.tsx +279 -0
  167. package/src/copy.tsx +62 -0
  168. package/src/dialog.tsx +58 -25
  169. package/src/entitlement.ts +56 -0
  170. package/src/estimate-cache.ts +40 -0
  171. package/src/estimate-summary.tsx +172 -0
  172. package/src/estimate.ts +119 -0
  173. package/src/format.ts +71 -0
  174. package/src/hooks.ts +3 -35
  175. package/src/i18n/be.json +1 -1
  176. package/src/i18n/de.json +1 -1
  177. package/src/i18n/en.json +1 -1
  178. package/src/i18n/es.json +1 -1
  179. package/src/i18n/fr.json +145 -0
  180. package/src/i18n/pl.json +1 -1
  181. package/src/i18n/ru.json +1 -1
  182. package/src/i18n/uk.json +1 -1
  183. package/src/i18n.ts +12 -7
  184. package/src/index.ts +9 -0
  185. package/src/limit-meter.tsx +55 -0
  186. package/src/plan-card.tsx +67 -0
  187. package/src/poll.ts +27 -0
  188. package/src/selectors.ts +93 -0
  189. package/src/types.ts +142 -2
  190. package/tests/consent-refusal.spec.ts +83 -0
  191. package/tests/consumer-hooks.spec.ts +205 -0
  192. package/tests/consumer.spec.ts +343 -0
  193. package/tests/context.ts +9 -0
  194. package/tests/dialog.spec.ts +49 -0
  195. package/tests/entitlement.spec.ts +117 -0
  196. package/tests/estimate-cache.spec.ts +46 -0
  197. package/tests/harness/consumer-fixtures.ts +105 -0
  198. package/tests/harness/consumer.tsx +197 -0
  199. package/tests/harness/entitlement.tsx +159 -0
  200. package/tests/harness/estimate-fixtures.ts +48 -0
  201. package/tests/harness/mount.tsx +19 -3
  202. package/tests/i18n.spec.ts +78 -8
  203. package/tests/pieces.spec.ts +134 -0
@@ -0,0 +1,34 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useI18nLib, useLanguage } from '@owlmeans/client-i18n';
3
+ import { cn } from '@/lib/utils';
4
+ import { money, shortMomentUtc } from './format.js';
5
+ /** The reasons the package phrases itself; any other reads the generic sentence. */
6
+ const KNOWN_REASONS = ['per-purchase', 'window', 'hold'];
7
+ /**
8
+ * What an amount checkout is narrowed to for this entity now: the largest amount (or that nothing
9
+ * may be bought), why, and when it rises again — the same `CheckoutLimitView` the server refuses
10
+ * with, so the note and a refusal never disagree.
11
+ *
12
+ * `[data-checkout-limit]` carries `data-max-minor`, `data-blocked`, `data-reason` and, when known,
13
+ * `data-resets-at` (ISO).
14
+ */
15
+ export const CheckoutLimitNote = ({ limit, reasonLabel, className }) => {
16
+ const t = useI18nLib('web-payment', 'checkout-limit');
17
+ const [locale] = useLanguage();
18
+ if (limit == null || (!limit.narrowed && !limit.blocked)) {
19
+ return null;
20
+ }
21
+ const reason = limit.reason ?? '';
22
+ const custom = typeof reasonLabel === 'function' ? reasonLabel(reason) : reasonLabel;
23
+ const explained = custom != null && custom !== ''
24
+ ? custom
25
+ : t(`reason.${KNOWN_REASONS.includes(reason) ? reason : 'other'}`);
26
+ const resetsAt = limit.resetsAt != null ? new Date(limit.resetsAt) : null;
27
+ const resets = resetsAt != null && !Number.isNaN(resetsAt.getTime())
28
+ ? t('resets', { date: shortMomentUtc(resetsAt, locale), interpolation: { escapeValue: false } })
29
+ : null;
30
+ return _jsxs("div", { "data-checkout-limit": "", "data-max-minor": limit.maximumMinor, "data-blocked": limit.blocked ? 'true' : 'false', "data-reason": reason, "data-resets-at": resetsAt?.toISOString(), role: limit.blocked ? 'alert' : 'note', className: cn('grid gap-1 rounded-lg border p-3 text-sm', limit.blocked ? 'border-destructive/50' : 'bg-muted/30', className), children: [_jsx("p", { className: limit.blocked ? 'text-destructive font-medium' : 'font-medium', "data-checkout-limit-headline": "", children: limit.blocked
31
+ ? t('blocked')
32
+ : t('note', { amount: money(limit.maximumMinor, limit.currency, locale), interpolation: { escapeValue: false } }) }), _jsx("p", { className: "text-muted-foreground text-xs", "data-checkout-limit-reason": "", children: explained }), resets != null && _jsx("p", { className: "text-muted-foreground text-xs", "data-checkout-limit-resets": "", children: resets })] });
33
+ };
34
+ //# sourceMappingURL=checkout-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkout-limit.js","sourceRoot":"","sources":["../src/checkout-limit.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { CancellationFormProps } from './types.js';
2
+ /**
3
+ * The cancellation function (§ 312k BGB "Verträge hier kündigen" → "Jetzt kündigen"; L215-1-1 /
4
+ * D215-1 "Résilier votre contrat" → a summary → "Notification de la résiliation"), for a public
5
+ * page reachable without a login and for the same function in-app.
6
+ *
7
+ * Step 1 asks for the kind (ordinary, or extraordinary with its reason), the name, the contract or
8
+ * customer reference, the date (the earliest possible, or a specific one) and the e-mail address
9
+ * the acknowledgement goes to; a honeypot field no person reaches rides along. Step 2 is the
10
+ * summary with the statutory confirm button; step 3 the receipt — date and time of receipt in UTC,
11
+ * the effective date when known — with a print button, so it can be kept.
12
+ *
13
+ * Selectors: `[data-cancellation-form]` / `[data-cancellation-step="form|review|receipt"]` (also
14
+ * `data-step`, `data-language`, `data-mode`), `[data-cancellation-field="kind|reason|name|contract|
15
+ * effective|date|email"]`, `[data-cancellation-continue]`, `[data-cancellation-confirm]`,
16
+ * `[data-cancellation-receipt]` (`data-status`, `data-declaration-id`, `data-received-at`,
17
+ * `data-effective-at`), `[data-cancellation-print]`.
18
+ */
19
+ export declare const CancellationForm: ({ mode, language: contractLanguage, uiLanguage, defaults, pending, error, receipt, onSubmit, onPrint, onClose, className, }: CancellationFormProps) => import("react").JSX.Element;
20
+ //# sourceMappingURL=cancellation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cancellation.d.ts","sourceRoot":"","sources":["../../src/consumer/cancellation.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,qBAAqB,EAAmB,MAAM,YAAY,CAAA;AAOxE;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,gBAAgB,gIAG1B,qBAAqB,gCAiLvB,CAAA"}
@@ -0,0 +1,115 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { CancellationKind } from '@owlmeans/payment';
4
+ import { cn } from '@/lib/utils';
5
+ import { Button } from '@/components/ui/button';
6
+ import { dayUtc, momentUtc } from '../format.js';
7
+ import { useLegalText, usePaymentText } from './copy.js';
8
+ import { Choice, Field, Honeypot, isEmail } from './fields.js';
9
+ import { ErrorLine, LanguageToggle, useShownLanguage } from './legal.js';
10
+ const isCancellationReceipt = (receipt) => 'status' in receipt;
11
+ /** Today as a UTC calendar day, `YYYY-MM-DD` — the earliest date a termination may name. */
12
+ const todayUtc = () => new Date().toISOString().slice(0, 10);
13
+ /**
14
+ * The cancellation function (§ 312k BGB "Verträge hier kündigen" → "Jetzt kündigen"; L215-1-1 /
15
+ * D215-1 "Résilier votre contrat" → a summary → "Notification de la résiliation"), for a public
16
+ * page reachable without a login and for the same function in-app.
17
+ *
18
+ * Step 1 asks for the kind (ordinary, or extraordinary with its reason), the name, the contract or
19
+ * customer reference, the date (the earliest possible, or a specific one) and the e-mail address
20
+ * the acknowledgement goes to; a honeypot field no person reaches rides along. Step 2 is the
21
+ * summary with the statutory confirm button; step 3 the receipt — date and time of receipt in UTC,
22
+ * the effective date when known — with a print button, so it can be kept.
23
+ *
24
+ * Selectors: `[data-cancellation-form]` / `[data-cancellation-step="form|review|receipt"]` (also
25
+ * `data-step`, `data-language`, `data-mode`), `[data-cancellation-field="kind|reason|name|contract|
26
+ * effective|date|email"]`, `[data-cancellation-continue]`, `[data-cancellation-confirm]`,
27
+ * `[data-cancellation-receipt]` (`data-status`, `data-declaration-id`, `data-received-at`,
28
+ * `data-effective-at`), `[data-cancellation-print]`.
29
+ */
30
+ export const CancellationForm = ({ mode, language: contractLanguage, uiLanguage, defaults, pending = false, error, receipt, onSubmit, onPrint, onClose, className, }) => {
31
+ const language = useShownLanguage(contractLanguage, uiLanguage);
32
+ const legal = useLegalText(language.shown);
33
+ const text = usePaymentText(language.shown);
34
+ const [step, setStep] = useState('form');
35
+ const [kind, setKind] = useState(CancellationKind.Ordinary);
36
+ const [reason, setReason] = useState('');
37
+ const [name, setName] = useState(defaults?.name ?? '');
38
+ const [contractRef, setContractRef] = useState(defaults?.contractRef ?? '');
39
+ const [effective, setEffective] = useState('earliest');
40
+ const [date, setDate] = useState('');
41
+ const [email, setEmail] = useState(defaults?.email ?? '');
42
+ const [honeypot, setHoneypot] = useState('');
43
+ const [checked, setChecked] = useState(false);
44
+ const [submitted, setSubmitted] = useState(null);
45
+ useEffect(() => {
46
+ if (receipt == null && submitted != null)
47
+ setStep('form');
48
+ // eslint-disable-next-line react-hooks/exhaustive-deps
49
+ }, [receipt]);
50
+ const current = receipt != null ? 'receipt' : step;
51
+ const extraordinary = kind === CancellationKind.Extraordinary;
52
+ const earliestDate = todayUtc();
53
+ const errors = {
54
+ reason: extraordinary && reason.trim() === '' ? text('consumer.required') : null,
55
+ name: name.trim() === '' ? text('consumer.required') : null,
56
+ date: effective === 'date' && (!/^\d{4}-\d{2}-\d{2}$/.test(date) || date < earliestDate) ? text('consumer.date-invalid') : null,
57
+ email: email.trim() === '' ? text('consumer.required') : !isEmail(email.trim()) ? text('consumer.email-invalid') : null,
58
+ };
59
+ const shown = (key) => checked ? errors[key] : null;
60
+ const valid = Object.values(errors).every(value => value == null);
61
+ const body = () => ({
62
+ kind,
63
+ ...(extraordinary ? { reason: reason.trim() } : {}),
64
+ name: name.trim(),
65
+ ...(contractRef.trim() !== '' ? { contractRef: contractRef.trim() } : {}),
66
+ ...(defaults?.subscriptionId != null ? { subscriptionId: defaults.subscriptionId } : {}),
67
+ effective,
68
+ ...(effective === 'date' ? { date } : {}),
69
+ email: email.trim(),
70
+ language: language.shown,
71
+ ...(honeypot !== '' ? { honeypot } : {}),
72
+ });
73
+ const toReview = () => {
74
+ setChecked(true);
75
+ if (valid)
76
+ setStep('review');
77
+ };
78
+ const confirm = async () => {
79
+ if (!valid || pending)
80
+ return;
81
+ const declared = body();
82
+ setSubmitted(declared);
83
+ await onSubmit(declared);
84
+ };
85
+ const print = () => {
86
+ if (onPrint != null)
87
+ onPrint();
88
+ else if (typeof window !== 'undefined')
89
+ window.print();
90
+ };
91
+ const kindLabel = (value) => legal(value === CancellationKind.Extraordinary
92
+ ? 'cancellation.kind-extraordinary' : 'cancellation.kind-ordinary');
93
+ const effectiveLabel = (declared) => declared.effective === 'date' && declared.date != null
94
+ ? dayUtc(`${declared.date}T00:00:00Z`, language.shown) : legal('cancellation.effective-earliest');
95
+ const summary = (declared, hook) => _jsxs("dl", { className: "grid grid-cols-[auto_1fr] gap-x-4 gap-y-1.5 rounded-lg border bg-muted/30 p-4 text-sm", ...(hook != null ? { [hook]: '' } : {}), children: [_jsx("dt", { className: "text-muted-foreground", children: legal('cancellation.kind') }), _jsx("dd", { "data-summary": "kind", children: kindLabel(declared.kind) }), declared.reason != null && _jsxs(_Fragment, { children: [_jsx("dt", { className: "text-muted-foreground", children: legal('cancellation.reason') }), _jsx("dd", { "data-summary": "reason", className: "whitespace-pre-wrap", children: declared.reason })] }), _jsx("dt", { className: "text-muted-foreground", children: legal('cancellation.name') }), _jsx("dd", { "data-summary": "name", children: declared.name }), _jsx("dt", { className: "text-muted-foreground", children: legal('cancellation.contract') }), _jsx("dd", { "data-summary": "contract", children: declared.contractRef ?? '—' }), _jsx("dt", { className: "text-muted-foreground", children: legal('cancellation.effective') }), _jsx("dd", { "data-summary": "effective", children: effectiveLabel(declared) }), _jsx("dt", { className: "text-muted-foreground", children: legal('cancellation.email') }), _jsx("dd", { "data-summary": "email", children: declared.email })] });
96
+ let content;
97
+ if (current === 'receipt' && receipt != null) {
98
+ const receivedAt = new Date(receipt.receivedAt);
99
+ const declared = submitted ?? body();
100
+ const status = isCancellationReceipt(receipt) ? receipt.status : undefined;
101
+ const effectiveAt = isCancellationReceipt(receipt) && receipt.effectiveAt != null ? new Date(receipt.effectiveAt) : null;
102
+ const effectiveKnown = effectiveAt != null && !Number.isNaN(effectiveAt.getTime());
103
+ content = _jsxs("div", { className: "grid gap-4", "data-cancellation-receipt": "", "data-status": status ?? 'received', "data-declaration-id": receipt.declarationId, "data-received-at": Number.isNaN(receivedAt.getTime()) ? undefined : receivedAt.toISOString(), "data-effective-at": effectiveKnown ? effectiveAt.toISOString() : undefined, children: [_jsx("h3", { className: "text-sm font-medium", children: text('consumer.receipt') }), _jsx("p", { className: "text-sm", children: receipt.mailed
104
+ ? legal('cancellation.received', { date: momentUtc(receivedAt, language.shown), email: declared.email })
105
+ : `${text('consumer.received-at')}: ${momentUtc(receivedAt, language.shown)} (UTC). ${text('consumer.not-mailed')}` }), effectiveKnown && _jsx("p", { className: "text-sm font-medium", "data-cancellation-effective": "", children: text('cancellation.effective-at', { date: dayUtc(effectiveAt, language.shown) }) }), _jsxs("dl", { className: "grid grid-cols-[auto_1fr] gap-x-4 gap-y-1.5 rounded-lg border p-4 text-sm", children: [_jsx("dt", { className: "text-muted-foreground", children: text('consumer.reference') }), _jsx("dd", { "data-cancellation-reference": "", children: receipt.declarationId }), _jsx("dt", { className: "text-muted-foreground", children: text('consumer.received-at') }), _jsxs("dd", { "data-cancellation-received-at": "", children: [momentUtc(receivedAt, language.shown), " (UTC)"] }), status != null && _jsxs(_Fragment, { children: [_jsx("dt", { className: "text-muted-foreground", children: text('consumer.status') }), _jsx("dd", { "data-cancellation-status": "", children: text(`cancellation.status.${status}`) })] })] }), summary(declared), _jsxs("div", { className: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end print:hidden", children: [onClose != null && _jsx(Button, { type: "button", variant: "outline", onClick: onClose, children: text('consumer.close') }), _jsx(Button, { type: "button", variant: "outline", onClick: print, "data-cancellation-print": "", children: text('consumer.print') })] })] });
106
+ }
107
+ else if (current === 'review') {
108
+ content = _jsxs("div", { className: "grid gap-4", children: [_jsx("h3", { className: "text-sm font-medium", children: text('consumer.review') }), _jsx("p", { className: "text-sm", children: legal('cancellation.summary') }), summary(body(), 'data-cancellation-summary'), _jsx(ErrorLine, { error: error, text: text }), _jsxs("div", { className: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", children: [_jsx(Button, { type: "button", variant: "outline", disabled: pending, onClick: () => setStep('form'), "data-cancellation-back": "", children: text('consumer.back') }), _jsx(Button, { type: "button", disabled: pending || !valid, onClick: () => void confirm(), "data-cancellation-confirm": "", children: pending ? text('consumer.pending') : legal('cancellation.confirm') })] })] });
109
+ }
110
+ else {
111
+ content = _jsxs("form", { className: "relative grid gap-4", noValidate: true, onSubmit: event => { event.preventDefault(); toReview(); }, children: [_jsxs("fieldset", { className: "grid gap-2", children: [_jsx("legend", { className: "mb-1 text-sm font-medium", children: legal('cancellation.kind') }), [CancellationKind.Ordinary, CancellationKind.Extraordinary].map(value => _jsx(Choice, { id: `cancellation-kind-${value}`, name: "cancellation-kind", checked: kind === value, onSelect: () => setKind(value), disabled: pending, hook: { 'data-cancellation-field': 'kind', 'data-kind': value }, children: kindLabel(value) }, value))] }), extraordinary && _jsx(Field, { id: "cancellation-reason", label: legal('cancellation.reason'), value: reason, onChange: setReason, error: shown('reason'), disabled: pending, multiline: true, hook: { 'data-cancellation-field': 'reason' } }), _jsx(Field, { id: "cancellation-name", label: legal('cancellation.name'), value: name, onChange: setName, error: shown('name'), autoComplete: "name", disabled: pending, hook: { 'data-cancellation-field': 'name' } }), _jsx(Field, { id: "cancellation-contract", label: legal('cancellation.contract'), value: contractRef, onChange: setContractRef, disabled: pending, hook: { 'data-cancellation-field': 'contract' } }), _jsxs("fieldset", { className: "grid gap-2", children: [_jsx("legend", { className: "mb-1 text-sm font-medium", children: legal('cancellation.effective') }), _jsx(Choice, { id: "cancellation-effective-earliest", name: "cancellation-effective", checked: effective === 'earliest', onSelect: () => setEffective('earliest'), disabled: pending, hook: { 'data-cancellation-field': 'effective', 'data-effective': 'earliest' }, children: legal('cancellation.effective-earliest') }), _jsx(Choice, { id: "cancellation-effective-date", name: "cancellation-effective", checked: effective === 'date', onSelect: () => setEffective('date'), disabled: pending, hook: { 'data-cancellation-field': 'effective', 'data-effective': 'date' }, children: legal('cancellation.effective-date') }), effective === 'date' && _jsx(Field, { id: "cancellation-date", type: "date", label: legal('cancellation.effective-date'), value: date, onChange: setDate, min: earliestDate, error: shown('date'), disabled: pending, hook: { 'data-cancellation-field': 'date' } })] }), _jsx(Field, { id: "cancellation-email", type: "email", label: legal('cancellation.email'), value: email, onChange: setEmail, error: shown('email'), autoComplete: "email", disabled: pending, hook: { 'data-cancellation-field': 'email' } }), _jsx(Honeypot, { id: "cancellation-website", label: text('consumer.website'), value: honeypot, onChange: setHoneypot }), _jsx(ErrorLine, { error: error, text: text }), _jsx("div", { className: "flex justify-end", children: _jsx(Button, { type: "submit", disabled: pending, "data-cancellation-continue": "", children: text('consumer.continue') }) })] });
112
+ }
113
+ return _jsxs("section", { className: cn('grid gap-4', className), "data-cancellation-section": "", "data-language": language.shown, children: [_jsxs("header", { className: "grid gap-1.5", lang: language.shown, children: [_jsx("h2", { className: "text-lg font-semibold leading-none", children: legal('cancellation.title') }), current === 'form' && _jsx("p", { className: "text-muted-foreground text-sm", children: legal('cancellation.intro') })] }), _jsx(LanguageToggle, { language: language, hook: "data-cancellation-language-toggle" }), _jsx("div", { "data-cancellation-form": "", "data-cancellation-step": current, "data-step": current, "data-mode": mode, "data-language": language.shown, lang: language.shown, className: "grid gap-4", children: content })] });
114
+ };
115
+ //# sourceMappingURL=cancellation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cancellation.js","sourceRoot":"","sources":["../../src/consumer/cancellation.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { CopyValues } from '@owlmeans/payment';
2
+ /** A translator bound to ONE language, whatever the active i18n language is. */
3
+ export type FixedText = (key: string, values?: CopyValues) => string;
4
+ /**
5
+ * The package's own interface strings (`web-payment`, library tier, any application override
6
+ * included) in a FIXED language, merged key by key over English — no i18next instance and no
7
+ * draining (`resolveI18nResource`). What lets a consumer-rights dialog render wholly in the
8
+ * contract language while the rest of the page stays in the interface language.
9
+ */
10
+ export declare const paymentTextOf: (lng: string) => FixedText;
11
+ /**
12
+ * The legal copy of `@owlmeans/payment` (`payment-consumer-rights`) in a fixed language. A text
13
+ * that cannot be rendered in the language (a broken application override) falls back to English
14
+ * rather than blanking the page; one that cannot be rendered at all is `''`.
15
+ */
16
+ export declare const legalTextOf: (lng: string) => FixedText;
17
+ /** `paymentTextOf(lng)`, memoised for the language. */
18
+ export declare const usePaymentText: (lng: string) => FixedText;
19
+ /** `legalTextOf(lng)`, memoised for the language. */
20
+ export declare const useLegalText: (lng: string) => FixedText;
21
+ /** A language's own name in another language (`de` in `en` → "German"); the code when unknown. */
22
+ export declare const languageNameOf: (lng: string, inLanguage: string) => string;
23
+ //# sourceMappingURL=copy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.d.ts","sourceRoot":"","sources":["../../src/consumer/copy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAwCnD,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,UAAU,KAAK,MAAM,CAAA;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAS,MAAM,KAAG,SAQ3C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,QAAS,MAAM,KAAG,SAUzC,CAAA;AAED,uDAAuD;AACvD,eAAO,MAAM,cAAc,QAAS,MAAM,KAAG,SAAqD,CAAA;AAElG,qDAAqD;AACrD,eAAO,MAAM,YAAY,QAAS,MAAM,KAAG,SAAmD,CAAA;AAE9F,kGAAkG;AAClG,eAAO,MAAM,cAAc,QAAS,MAAM,cAAc,MAAM,KAAG,MAMhE,CAAA"}
@@ -0,0 +1,75 @@
1
+ import { useMemo } from 'react';
2
+ import { LIB_NAMESPACE, resolveI18nResource } from '@owlmeans/i18n';
3
+ import { baseLanguageOf, consumerText } from '@owlmeans/payment';
4
+ import { WEB_PAYMENT_RESOURCE } from '../i18n.js';
5
+ const isTree = (value) => value != null && typeof value === 'object' && !Array.isArray(value);
6
+ const merge = (base, over) => {
7
+ const result = { ...base };
8
+ for (const [key, value] of Object.entries(over ?? {})) {
9
+ if (isTree(value)) {
10
+ const current = result[key];
11
+ result[key] = merge(isTree(current) ? current : {}, value);
12
+ }
13
+ else if (typeof value === 'string') {
14
+ result[key] = value;
15
+ }
16
+ }
17
+ return result;
18
+ };
19
+ const bundleOf = (lng) => {
20
+ const base = baseLanguageOf(lng);
21
+ let tree = merge({}, resolveI18nResource('en', WEB_PAYMENT_RESOURCE, LIB_NAMESPACE));
22
+ if (base !== '' && base !== 'en') {
23
+ tree = merge(tree, resolveI18nResource(base, WEB_PAYMENT_RESOURCE, LIB_NAMESPACE));
24
+ }
25
+ if (lng !== base && lng.trim() !== '') {
26
+ tree = merge(tree, resolveI18nResource(lng, WEB_PAYMENT_RESOURCE, LIB_NAMESPACE));
27
+ }
28
+ return tree;
29
+ };
30
+ const fill = (text, values = {}) => text.replace(/\{\{\s*([\w-]+)\s*\}\}/g, (_, name) => values[name] != null ? String(values[name]) : '');
31
+ /**
32
+ * The package's own interface strings (`web-payment`, library tier, any application override
33
+ * included) in a FIXED language, merged key by key over English — no i18next instance and no
34
+ * draining (`resolveI18nResource`). What lets a consumer-rights dialog render wholly in the
35
+ * contract language while the rest of the page stays in the interface language.
36
+ */
37
+ export const paymentTextOf = (lng) => {
38
+ const tree = bundleOf(lng);
39
+ return (key, values) => {
40
+ const value = key.split('.').reduce((node, part) => isTree(node) ? node[part] : undefined, tree);
41
+ return typeof value === 'string' ? fill(value, values) : key;
42
+ };
43
+ };
44
+ /**
45
+ * The legal copy of `@owlmeans/payment` (`payment-consumer-rights`) in a fixed language. A text
46
+ * that cannot be rendered in the language (a broken application override) falls back to English
47
+ * rather than blanking the page; one that cannot be rendered at all is `''`.
48
+ */
49
+ export const legalTextOf = (lng) => (path, values) => {
50
+ try {
51
+ return consumerText(lng, path, values);
52
+ }
53
+ catch {
54
+ try {
55
+ return consumerText('en', path, values);
56
+ }
57
+ catch {
58
+ return '';
59
+ }
60
+ }
61
+ };
62
+ /** `paymentTextOf(lng)`, memoised for the language. */
63
+ export const usePaymentText = (lng) => useMemo(() => paymentTextOf(lng), [lng]);
64
+ /** `legalTextOf(lng)`, memoised for the language. */
65
+ export const useLegalText = (lng) => useMemo(() => legalTextOf(lng), [lng]);
66
+ /** A language's own name in another language (`de` in `en` → "German"); the code when unknown. */
67
+ export const languageNameOf = (lng, inLanguage) => {
68
+ try {
69
+ return new Intl.DisplayNames([inLanguage], { type: 'language' }).of(lng) ?? lng;
70
+ }
71
+ catch {
72
+ return lng;
73
+ }
74
+ };
75
+ //# sourceMappingURL=copy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.js","sourceRoot":"","sources":["../../src/consumer/copy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ export interface AskerOptions<Args extends unknown[], View, Answer> {
2
+ /** Read the current view. */
3
+ load: (...args: Args) => Promise<View>;
4
+ /** Whether the view asks the person anything. */
5
+ required: (view: View) => boolean;
6
+ /** Show the view to the person (open the dialog). */
7
+ show: (view: View) => void;
8
+ /**
9
+ * The answer when nothing needs asking — and when the read FAILS: the server's refusal stays
10
+ * the authority, and a flaky read must never block work that needs no consent.
11
+ */
12
+ skip: Answer;
13
+ }
14
+ export interface Asker<Args extends unknown[], Answer> {
15
+ /** Read, and ask only when the view requires it. Concurrent calls share ONE pending answer. */
16
+ ask: (...args: Args) => Promise<Answer>;
17
+ /** Answer the pending `ask` (the dialog confirmed or was declined); nothing when none waits. */
18
+ settle: (answer: Answer) => void;
19
+ /** Whether an `ask` is waiting for the person. */
20
+ waiting: () => boolean;
21
+ }
22
+ /**
23
+ * Read a view, show it when it asks for something, and answer once the person has — the state
24
+ * machine behind `usePerformanceConsent().ensure` and `useSubscriptionStart().ensure`, free of
25
+ * React so it is testable on its own. A burst of calls opens one dialog: they all get its answer.
26
+ */
27
+ export declare const makeAsker: <Args extends unknown[], View, Answer>(opts: AskerOptions<Args, View, Answer>) => Asker<Args, Answer>;
28
+ export interface EnsureOptions {
29
+ /**
30
+ * Asked after the server refused with a 428 although the last answer said nothing was needed.
31
+ * The view is always read fresh; `force` records why the caller asks.
32
+ */
33
+ force?: boolean;
34
+ }
35
+ export interface ConsentGate {
36
+ /**
37
+ * `true` when nothing needs consent or the person confirmed and it was recorded; `false` when
38
+ * they declined or closed the dialog. A failed read answers `true`. One pending answer is shared.
39
+ */
40
+ ensure: (opts?: EnsureOptions) => Promise<boolean>;
41
+ /**
42
+ * Run `action`; when it is refused for the spend consent (`isPerformanceConsentRefusal` — the
43
+ * class, its marker, or a bare 428, also wrapped inside another error), ask with
44
+ * `ensure({ force: true })` and run it again exactly ONCE. A decline throws `ConsentDeclined`;
45
+ * a second refusal, or any other failure, propagates as it is.
46
+ */
47
+ withConsent: <T>(action: () => Promise<T>) => Promise<T>;
48
+ }
49
+ /** A gate over an `ensure` — what `useConsentGate` answers inside a `PerformanceConsentProvider`. */
50
+ export declare const makeConsentGate: (ensure: ConsentGate['ensure']) => ConsentGate;
51
+ /**
52
+ * The gate outside any provider: nothing can be asked, so `ensure` answers `true` and a refusal
53
+ * propagates unchanged.
54
+ */
55
+ export declare const passThroughGate: ConsentGate;
56
+ //# sourceMappingURL=ensure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensure.d.ts","sourceRoot":"","sources":["../../src/consumer/ensure.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY,CAAC,IAAI,SAAS,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM;IAChE,6BAA6B;IAC7B,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC,iDAAiD;IACjD,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAA;IACjC,qDAAqD;IACrD,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAA;IAC1B;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,KAAK,CAAC,IAAI,SAAS,OAAO,EAAE,EAAE,MAAM;IACnD,+FAA+F;IAC/F,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IACvC,gGAAgG;IAChG,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,kDAAkD;IAClD,OAAO,EAAE,MAAM,OAAO,CAAA;CACvB;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,GAAI,IAAI,SAAS,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,QACtD,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,KACrC,KAAK,CAAC,IAAI,EAAE,MAAM,CAuCpB,CAAA;AAED,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAClD;;;;;OAKG;IACH,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;CACzD;AAED,qGAAqG;AACrG,eAAO,MAAM,eAAe,WAAY,WAAW,CAAC,QAAQ,CAAC,KAAG,WAgB9D,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,WAG7B,CAAA"}
@@ -0,0 +1,71 @@
1
+ import { ConsentKind } from '@owlmeans/payment';
2
+ import { ConsentDeclined, isPerformanceConsentRefusal } from './refusal.js';
3
+ /**
4
+ * Read a view, show it when it asks for something, and answer once the person has — the state
5
+ * machine behind `usePerformanceConsent().ensure` and `useSubscriptionStart().ensure`, free of
6
+ * React so it is testable on its own. A burst of calls opens one dialog: they all get its answer.
7
+ */
8
+ export const makeAsker = (opts) => {
9
+ let inflight = null;
10
+ let resolver = null;
11
+ const run = async (args) => {
12
+ let view;
13
+ try {
14
+ view = await opts.load(...args);
15
+ }
16
+ catch {
17
+ return opts.skip;
18
+ }
19
+ if (!opts.required(view)) {
20
+ return opts.skip;
21
+ }
22
+ return await new Promise(resolve => {
23
+ resolver = resolve;
24
+ opts.show(view);
25
+ });
26
+ };
27
+ return {
28
+ ask: async (...args) => {
29
+ if (inflight == null) {
30
+ inflight = run(args).finally(() => {
31
+ inflight = null;
32
+ resolver = null;
33
+ });
34
+ }
35
+ return await inflight;
36
+ },
37
+ settle: answer => {
38
+ const resolve = resolver;
39
+ resolver = null;
40
+ resolve?.(answer);
41
+ },
42
+ waiting: () => resolver != null,
43
+ };
44
+ };
45
+ /** A gate over an `ensure` — what `useConsentGate` answers inside a `PerformanceConsentProvider`. */
46
+ export const makeConsentGate = (ensure) => ({
47
+ ensure,
48
+ withConsent: async (action) => {
49
+ try {
50
+ return await action();
51
+ }
52
+ catch (e) {
53
+ if (!isPerformanceConsentRefusal(e)) {
54
+ throw e;
55
+ }
56
+ if (!await ensure({ force: true })) {
57
+ throw new ConsentDeclined(ConsentKind.Performance);
58
+ }
59
+ return await action();
60
+ }
61
+ },
62
+ });
63
+ /**
64
+ * The gate outside any provider: nothing can be asked, so `ensure` answers `true` and a refusal
65
+ * propagates unchanged.
66
+ */
67
+ export const passThroughGate = {
68
+ ensure: async () => true,
69
+ withConsent: async (action) => await action(),
70
+ };
71
+ //# sourceMappingURL=ensure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensure.js","sourceRoot":"","sources":["../../src/consumer/ensure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAA;AAyB3E;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,IAAsC,EACjB,EAAE;IACvB,IAAI,QAAQ,GAA2B,IAAI,CAAA;IAC3C,IAAI,QAAQ,GAAsC,IAAI,CAAA;IAEtD,MAAM,GAAG,GAAG,KAAK,EAAE,IAAU,EAAmB,EAAE;QAChD,IAAI,IAAU,CAAA;QACd,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC,IAAI,CAAA;QAClB,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,IAAI,CAAA;QAClB,CAAC;QAED,OAAO,MAAM,IAAI,OAAO,CAAS,OAAO,CAAC,EAAE;YACzC,QAAQ,GAAG,OAAO,CAAA;YAClB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjB,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,OAAO;QACL,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE;YACrB,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;gBACrB,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;oBAChC,QAAQ,GAAG,IAAI,CAAA;oBACf,QAAQ,GAAG,IAAI,CAAA;gBACjB,CAAC,CAAC,CAAA;YACJ,CAAC;YAED,OAAO,MAAM,QAAQ,CAAA;QACvB,CAAC;QACD,MAAM,EAAE,MAAM,CAAC,EAAE;YACf,MAAM,OAAO,GAAG,QAAQ,CAAA;YACxB,QAAQ,GAAG,IAAI,CAAA;YACf,OAAO,EAAE,CAAC,MAAM,CAAC,CAAA;QACnB,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,IAAI,IAAI;KAChC,CAAA;AACH,CAAC,CAAA;AAyBD,qGAAqG;AACrG,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAA6B,EAAe,EAAE,CAAC,CAAC;IAC9E,MAAM;IACN,WAAW,EAAE,KAAK,EAAK,MAAwB,EAAc,EAAE;QAC7D,IAAI,CAAC;YACH,OAAO,MAAM,MAAM,EAAE,CAAA;QACvB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpC,MAAM,CAAC,CAAA;YACT,CAAC;YACD,IAAI,CAAC,MAAM,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;gBACnC,MAAM,IAAI,eAAe,CAAC,WAAW,CAAC,WAAW,CAAC,CAAA;YACpD,CAAC;YAED,OAAO,MAAM,MAAM,EAAE,CAAA;QACvB,CAAC;IACH,CAAC;CACF,CAAC,CAAA;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAgB;IAC1C,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;IACxB,WAAW,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE,CAAC,MAAM,MAAM,EAAE;CAC5C,CAAA"}
@@ -0,0 +1,43 @@
1
+ import type { ReactNode } from 'react';
2
+ /** The shape the platform validates an e-mail address with (`@owlmeans/payment` `EmailSchema`). */
3
+ export declare const EMAIL_PATTERN: RegExp;
4
+ export declare const isEmail: (value: string) => boolean;
5
+ export interface FieldProps {
6
+ id: string;
7
+ label: string;
8
+ value: string;
9
+ onChange: (value: string) => void;
10
+ error?: string | null;
11
+ type?: 'text' | 'email' | 'date';
12
+ autoComplete?: string;
13
+ disabled?: boolean;
14
+ min?: string;
15
+ /** A `data-*` hook for tests (`data-withdrawal-field="name"`). */
16
+ hook?: Record<string, string>;
17
+ multiline?: boolean;
18
+ }
19
+ export declare const Field: ({ id, label, value, onChange, error, type, autoComplete, disabled, min, hook, multiline, }: FieldProps) => import("react").JSX.Element;
20
+ export interface ChoiceProps {
21
+ id: string;
22
+ name: string;
23
+ checked: boolean;
24
+ onSelect: () => void;
25
+ disabled?: boolean;
26
+ hook?: Record<string, string>;
27
+ children: ReactNode;
28
+ }
29
+ /** One option of a radio group — a native radio, so the group needs no extra primitive. */
30
+ export declare const Choice: ({ id, name, checked, onSelect, disabled, hook, children }: ChoiceProps) => import("react").JSX.Element;
31
+ export interface HoneypotProps {
32
+ id: string;
33
+ label: string;
34
+ value: string;
35
+ onChange: (value: string) => void;
36
+ }
37
+ /**
38
+ * A field a person never sees or reaches: off screen, out of the tab order and hidden from
39
+ * assistive technology, with a plausible name a form-filling bot completes. A filled one marks the
40
+ * declaration as a bot's, which the server answers like any other (it never says so).
41
+ */
42
+ export declare const Honeypot: ({ id, label, value, onChange }: HoneypotProps) => import("react").JSX.Element;
43
+ //# sourceMappingURL=fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../src/consumer/fields.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtC,mGAAmG;AACnG,eAAO,MAAM,aAAa,QAAsB,CAAA;AAEhD,eAAO,MAAM,OAAO,UAAW,MAAM,KAAG,OAAgF,CAAA;AAExH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAA;IAChC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,eAAO,MAAM,KAAK,+FAEf,UAAU,gCAkBP,CAAA;AAEN,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,2FAA2F;AAC3F,eAAO,MAAM,MAAM,8DAA+D,WAAW,gCASrF,CAAA;AAER,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAClC;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,mCAAoC,aAAa,gCAOhE,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '@/lib/utils';
3
+ import { Input } from '@/components/ui/input';
4
+ import { Label } from '@/components/ui/label';
5
+ /** The shape the platform validates an e-mail address with (`@owlmeans/payment` `EmailSchema`). */
6
+ export const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+$/;
7
+ export const isEmail = (value) => value.length >= 3 && value.length <= 254 && EMAIL_PATTERN.test(value);
8
+ export const Field = ({ id, label, value, onChange, error, type = 'text', autoComplete, disabled, min, hook, multiline = false, }) => _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { htmlFor: id, children: label }), multiline
9
+ ? _jsx("textarea", { id: id, value: value, disabled: disabled, rows: 3, maxLength: 2000, "aria-invalid": error != null, "aria-describedby": error != null ? `${id}-error` : undefined, onChange: event => onChange(event.target.value), className: cn('border-input bg-background placeholder:text-muted-foreground w-full min-w-0 rounded-md border px-3 py-2 text-sm shadow-xs outline-none', 'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:opacity-50 aria-invalid:border-destructive'), ...hook })
10
+ : _jsx(Input, { id: id, type: type, value: value, disabled: disabled, autoComplete: autoComplete, min: min, "aria-invalid": error != null, "aria-describedby": error != null ? `${id}-error` : undefined, onChange: event => onChange(event.target.value), ...hook }), error != null && _jsx("p", { id: `${id}-error`, className: "text-destructive text-xs", children: error })] });
11
+ /** One option of a radio group — a native radio, so the group needs no extra primitive. */
12
+ export const Choice = ({ id, name, checked, onSelect, disabled, hook, children }) => _jsxs("label", { htmlFor: id, className: cn('flex cursor-pointer items-start gap-3 rounded-md border p-3 text-sm', checked && 'border-primary bg-muted/30'), children: [_jsx("input", { id: id, type: "radio", name: name, checked: checked, disabled: disabled, onChange: onSelect, className: "accent-primary mt-0.5 size-4 shrink-0", ...hook }), _jsx("span", { className: "grid gap-0.5", children: children })] });
13
+ /**
14
+ * A field a person never sees or reaches: off screen, out of the tab order and hidden from
15
+ * assistive technology, with a plausible name a form-filling bot completes. A filled one marks the
16
+ * declaration as a bot's, which the server answers like any other (it never says so).
17
+ */
18
+ export const Honeypot = ({ id, label, value, onChange }) => _jsxs("div", { "aria-hidden": "true", "data-honeypot": "", style: { position: 'absolute', left: '-10000px', top: 'auto', width: 1, height: 1, overflow: 'hidden' }, children: [_jsx("label", { htmlFor: id, children: label }), _jsx("input", { id: id, name: "website", type: "text", tabIndex: -1, autoComplete: "off", value: value, onChange: event => onChange(event.target.value) })] });
19
+ //# sourceMappingURL=fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fields.js","sourceRoot":"","sources":["../../src/consumer/fields.tsx"],"names":[],"mappings":"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"}