@globalpayments-private/gpds-pattern-web 0.0.0-stage → 0.1.0-pr.7.gdcb74cd

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 (97) hide show
  1. package/README.md +567 -2
  2. package/dist/cjs/control-strategy-DhhYTbse.js +113 -0
  3. package/dist/cjs/gpds-pattern-web.cjs.js +24 -0
  4. package/dist/cjs/index-Dzm6P89U.js +1565 -0
  5. package/dist/cjs/index.cjs.js +180 -0
  6. package/dist/cjs/loader.cjs.js +12 -0
  7. package/dist/cjs/uds-pattern-login-card_2.cjs.entry.js +1662 -0
  8. package/dist/collection/collection-manifest.json +14 -0
  9. package/dist/collection/components/uds-pattern-login-card/slimmers/identity-memory.slimmer.js +63 -0
  10. package/dist/collection/components/uds-pattern-login-card/slimmers/login-workflow.slimmer.js +357 -0
  11. package/dist/collection/components/uds-pattern-login-card/slimmers/renderers/login-card-renderer.js +100 -0
  12. package/dist/collection/components/uds-pattern-login-card/slimmers/renderers/login-field-renderer.js +129 -0
  13. package/dist/collection/components/uds-pattern-login-card/slimmers/renderers/login-step-renderer.js +192 -0
  14. package/dist/collection/components/uds-pattern-login-card/slimmers/resend-throttle.slimmer.js +65 -0
  15. package/dist/collection/components/uds-pattern-login-card/uds-pattern-login-card.css +154 -0
  16. package/dist/collection/components/uds-pattern-login-card/uds-pattern-login-card.js +508 -0
  17. package/dist/collection/components/uds-pattern-login-card/validation/login-validation-rules.js +86 -0
  18. package/dist/collection/components/uds-pattern-login-card/view-model/login-card-handlers.js +1 -0
  19. package/dist/collection/components/uds-pattern-login-card/view-model/login-step.view-model.js +138 -0
  20. package/dist/collection/components/uds-pattern-login-page/uds-pattern-login-page.css +37 -0
  21. package/dist/collection/components/uds-pattern-login-page/uds-pattern-login-page.js +97 -0
  22. package/dist/collection/index.js +5 -0
  23. package/dist/collection/providers/auth-provider.js +28 -0
  24. package/dist/collection/providers/control-strategy.js +21 -0
  25. package/dist/collection/providers/login-config.js +4 -0
  26. package/dist/collection/providers/memory-auth-provider.js +133 -0
  27. package/dist/collection/providers/parse-auth-result.js +135 -0
  28. package/dist/collection/slimmer/common/log.js +14 -0
  29. package/dist/collection/slimmer/common/symbols.js +10 -0
  30. package/dist/collection/slimmer/common/types.js +2 -0
  31. package/dist/collection/slimmer/decorators/inject-slimmer.js +73 -0
  32. package/dist/collection/slimmer/decorators/map-to-component-field.js +41 -0
  33. package/dist/collection/slimmer/decorators/map-to-component-method.js +33 -0
  34. package/dist/collection/slimmer/decorators/slimmer.js +10 -0
  35. package/dist/collection/slimmer/index.js +5 -0
  36. package/dist/collection/utils/labels.js +81 -0
  37. package/dist/collection/utils/types.js +1 -0
  38. package/dist/components/index.d.ts +35 -0
  39. package/dist/components/index.js +1 -0
  40. package/dist/components/p-DOrg55po.js +1 -0
  41. package/dist/components/p-_G8A9gg0.js +1 -0
  42. package/dist/components/uds-pattern-login-card.d.ts +11 -0
  43. package/dist/components/uds-pattern-login-card.js +1 -0
  44. package/dist/components/uds-pattern-login-page.d.ts +11 -0
  45. package/dist/components/uds-pattern-login-page.js +1 -0
  46. package/dist/docs.d.ts +480 -0
  47. package/dist/docs.json +549 -0
  48. package/dist/esm/control-strategy-DOrg55po.js +105 -0
  49. package/dist/esm/gpds-pattern-web.js +20 -0
  50. package/dist/esm/index-DsXlLyGj.js +1537 -0
  51. package/dist/esm/index.js +170 -0
  52. package/dist/esm/loader.js +10 -0
  53. package/dist/esm/uds-pattern-login-card_2.entry.js +1659 -0
  54. package/dist/gpds-pattern-web/gpds-pattern-web.css +1 -0
  55. package/dist/gpds-pattern-web/gpds-pattern-web.esm.js +1 -0
  56. package/dist/gpds-pattern-web/index.esm.js +1 -0
  57. package/dist/gpds-pattern-web/p-2c97d2da.entry.js +1 -0
  58. package/dist/gpds-pattern-web/p-DOrg55po.js +1 -0
  59. package/dist/gpds-pattern-web/p-DsXlLyGj.js +3 -0
  60. package/dist/index.cjs.js +1 -0
  61. package/dist/index.js +1 -0
  62. package/dist/types/components/uds-pattern-login-card/slimmers/identity-memory.slimmer.d.ts +21 -0
  63. package/dist/types/components/uds-pattern-login-card/slimmers/login-workflow.slimmer.d.ts +100 -0
  64. package/dist/types/components/uds-pattern-login-card/slimmers/renderers/login-card-renderer.d.ts +44 -0
  65. package/dist/types/components/uds-pattern-login-card/slimmers/renderers/login-field-renderer.d.ts +91 -0
  66. package/dist/types/components/uds-pattern-login-card/slimmers/renderers/login-step-renderer.d.ts +40 -0
  67. package/dist/types/components/uds-pattern-login-card/slimmers/resend-throttle.slimmer.d.ts +21 -0
  68. package/dist/types/components/uds-pattern-login-card/uds-pattern-login-card.d.ts +134 -0
  69. package/dist/types/components/uds-pattern-login-card/validation/login-validation-rules.d.ts +72 -0
  70. package/dist/types/components/uds-pattern-login-card/view-model/login-card-handlers.d.ts +21 -0
  71. package/dist/types/components/uds-pattern-login-card/view-model/login-step.view-model.d.ts +96 -0
  72. package/dist/types/components/uds-pattern-login-page/uds-pattern-login-page.d.ts +21 -0
  73. package/dist/types/components.d.ts +327 -0
  74. package/dist/types/index.d.ts +10 -0
  75. package/dist/types/providers/auth-provider.d.ts +168 -0
  76. package/dist/types/providers/control-strategy.d.ts +144 -0
  77. package/dist/types/providers/login-config.d.ts +52 -0
  78. package/dist/types/providers/memory-auth-provider.d.ts +37 -0
  79. package/dist/types/providers/parse-auth-result.d.ts +8 -0
  80. package/dist/types/slimmer/common/log.d.ts +8 -0
  81. package/dist/types/slimmer/common/symbols.d.ts +10 -0
  82. package/dist/types/slimmer/common/types.d.ts +30 -0
  83. package/dist/types/slimmer/decorators/inject-slimmer.d.ts +24 -0
  84. package/dist/types/slimmer/decorators/map-to-component-field.d.ts +16 -0
  85. package/dist/types/slimmer/decorators/map-to-component-method.d.ts +11 -0
  86. package/dist/types/slimmer/decorators/slimmer.d.ts +10 -0
  87. package/dist/types/slimmer/index.d.ts +6 -0
  88. package/dist/types/stencil-public-runtime.d.ts +1879 -0
  89. package/dist/types/utils/labels.d.ts +13 -0
  90. package/dist/types/utils/types.d.ts +106 -0
  91. package/dist/types/vega.d.ts +11 -0
  92. package/loader/cdn.js +1 -0
  93. package/loader/index.cjs.js +1 -0
  94. package/loader/index.d.ts +24 -0
  95. package/loader/index.es2017.js +1 -0
  96. package/loader/index.js +2 -0
  97. package/package.json +82 -4
@@ -0,0 +1,508 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
4
+ r = Reflect.decorate(decorators, target, key, desc);
5
+ else
6
+ for (var i = decorators.length - 1; i >= 0; i--)
7
+ if (d = decorators[i])
8
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
9
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
10
+ };
11
+ import { h, Host } from "@stencil/core";
12
+ import { DEFAULT_LOGIN_LABELS } from "../../utils/labels";
13
+ import { InjectSlimmer } from "../../slimmer";
14
+ import { LoginWorkflowSlimmer } from "./slimmers/login-workflow.slimmer";
15
+ import { ResendThrottleSlimmer } from "./slimmers/resend-throttle.slimmer";
16
+ import { IdentityMemorySlimmer } from "./slimmers/identity-memory.slimmer";
17
+ import { LoginCardRenderer } from "./slimmers/renderers/login-card-renderer";
18
+ import { LoginStepViewModel } from "./view-model/login-step.view-model";
19
+ /**
20
+ * The GP login workflow, as a single pattern.
21
+ *
22
+ * Unlike a design-system component, this pattern **owns the workflow**: step
23
+ * sequencing, in-flight state, failure copy, resend throttling, lockout
24
+ * messaging, back-navigation, focus movement and identifier persistence all
25
+ * live inside the card. A consuming product does not implement any of it.
26
+ *
27
+ * Two aggregate seams are all a consumer wires:
28
+ *
29
+ * - **`auth`** — a `UdsAuthProvider` adapter saying *what the identity platform
30
+ * needs next*. The pattern decides what that looks like.
31
+ * - **`controlStrategy`** — an optional `UdsLoginControlStrategy` that intercepts
32
+ * every checkpoint in the workflow, for the cases where the course of the flow
33
+ * itself needs to change.
34
+ *
35
+ * ```ts
36
+ * card.auth = createAuthProvider({
37
+ * signIn: ({ identifier, password }) => oktaSdk.authn(identifier, password),
38
+ * verifyOtp: ({ code }) => oktaSdk.verifyFactor(code),
39
+ * });
40
+ * ```
41
+ *
42
+ * Which optional methods the adapter implements is also the configuration:
43
+ * implement `signUp` and the sign-up route appears; omit `requestPasswordReset`
44
+ * and no recovery link is rendered.
45
+ *
46
+ * This class deliberately holds only props, events, state and the render shell.
47
+ * Behaviour lives in slimmers (`./slimmers`), markup in renderer slimmers
48
+ * (`./slimmers/renderers`) and derivation in `./view-model` — see
49
+ * `src/slimmer/README.md`.
50
+ *
51
+ * @slot brand - Optional branding (logo, product name) rendered above the heading.
52
+ * @slot footer - Replaces the default help footer.
53
+ */
54
+ export class UdsPatternLoginCard {
55
+ constructor() {
56
+ // --- Slimmers -----------------------------------------------------------
57
+ // Each owns one responsibility and binds back to the state below.
58
+ this.workflow = new LoginWorkflowSlimmer();
59
+ this.resend = new ResendThrottleSlimmer();
60
+ this.memory = new IdentityMemorySlimmer();
61
+ this.renderer = new LoginCardRenderer();
62
+ // --- Props --------------------------------------------------------------
63
+ /**
64
+ * Everything that cannot be expressed as an attribute: the `auth` adapter,
65
+ * the `control` strategy and any `labels` overrides.
66
+ *
67
+ * The split is mechanical rather than a matter of taste — see
68
+ * `UdsLoginConfig`. Scalars below are attributes because they can be;
69
+ * objects and functions are gathered here because they cannot be.
70
+ *
71
+ * Also accepts a JSON string, so the `labels` member alone can be set from
72
+ * plain HTML markup.
73
+ */
74
+ this.config = {};
75
+ /** The step the workflow starts on. */
76
+ this.initialStep = 'identifier';
77
+ /** Pre-populates the identifier field, overriding any remembered value. */
78
+ this.identifier = '';
79
+ /** Default number of digit inputs, when the provider does not specify one. */
80
+ this.otpLength = 6;
81
+ /**
82
+ * Where the "Remember my email" value is persisted. Set to an empty string to
83
+ * disable persistence entirely.
84
+ */
85
+ this.rememberStorageKey = 'uds-pattern-login.identifier';
86
+ /** Renders the "Need help signing in?" footer. */
87
+ this.showHelpFooter = true;
88
+ // --- State --------------------------------------------------------------
89
+ // Written by the slimmers through `@MapToComponentField({ writable: true })`.
90
+ this.step = 'identifier';
91
+ this.busy = false;
92
+ this.methods = [];
93
+ this.nowTick = Date.now();
94
+ this.values = {};
95
+ /**
96
+ * The intents a renderer may raise. Held as one stable object — not rebuilt
97
+ * per render — so that binding to it from a slimmer is a fixed reference and
98
+ * the data half of the contract stays free of behaviour.
99
+ */
100
+ this.handlers = {
101
+ onSubmit: (event) => {
102
+ event.preventDefault();
103
+ void this.workflow.submit();
104
+ },
105
+ onNavigate: (step) => (event) => {
106
+ event.preventDefault();
107
+ this.workflow.navigateTo(step);
108
+ },
109
+ onAction: (action) => (event) => {
110
+ event.preventDefault();
111
+ this.udsLoginAction.emit({ action, step: this.step });
112
+ },
113
+ onResend: (event) => {
114
+ event.preventDefault();
115
+ void this.workflow.resendCode();
116
+ },
117
+ onValueChange: (name, value) => {
118
+ this.values = { ...this.values, [name]: value };
119
+ },
120
+ };
121
+ }
122
+ // --- Lifecycle ----------------------------------------------------------
123
+ // Bodies are intentionally empty: slimmers hook onto these by name via
124
+ // `@MapToComponentMethod`, and the hooks run after the method itself.
125
+ componentWillLoad() {
126
+ /* LoginWorkflowSlimmer.start */
127
+ }
128
+ disconnectedCallback() {
129
+ /* ResendThrottleSlimmer.stop */
130
+ }
131
+ componentDidRender() {
132
+ if (this.lastRenderedStep !== undefined && this.lastRenderedStep !== this.step) {
133
+ this.focusFirstControl();
134
+ }
135
+ this.lastRenderedStep = this.step;
136
+ }
137
+ /**
138
+ * Returns the workflow to its first step and clears all collected input.
139
+ * Useful after a sign-out, or to recover from a terminal step.
140
+ */
141
+ async reset() {
142
+ /* LoginWorkflowSlimmer.restart */
143
+ }
144
+ // --- Derived ------------------------------------------------------------
145
+ /** The resolved configuration, accepting a JSON string for HTML consumers. */
146
+ get resolvedConfig() {
147
+ return parseJsonProp(this.config, {});
148
+ }
149
+ /** The authentication seam. Read by the workflow slimmer. */
150
+ get auth() {
151
+ return this.resolvedConfig.auth;
152
+ }
153
+ /** The control seam. Read by the workflow slimmer at each checkpoint. */
154
+ get controlStrategy() {
155
+ return this.resolvedConfig.control;
156
+ }
157
+ /** Merged copy. Read by the slimmers as well, for error text. */
158
+ get copy() {
159
+ const overrides = this.resolvedConfig.labels ?? {};
160
+ return {
161
+ ...DEFAULT_LOGIN_LABELS,
162
+ ...overrides,
163
+ errors: { ...DEFAULT_LOGIN_LABELS.errors, ...(overrides.errors ?? {}) },
164
+ };
165
+ }
166
+ /**
167
+ * Everything the renderers need to draw the current step, and nothing else.
168
+ *
169
+ * Derivation happens in one place — `LoginStepViewModel.from` — rather than
170
+ * being assembled inline in `render()`, so it can be tested without a DOM and
171
+ * reviewed without reading JSX.
172
+ */
173
+ get viewModel() {
174
+ return LoginStepViewModel.from({
175
+ step: this.step,
176
+ copy: this.copy,
177
+ errorText: this.errorText,
178
+ busy: this.busy,
179
+ can: this.workflow.capabilities,
180
+ methods: this.methods,
181
+ values: this.values,
182
+ otpLength: this.workflow.codeLength,
183
+ resendSeconds: this.resend.secondsRemaining,
184
+ otpMethodLabel: this.otpMethodLabel,
185
+ destination: this.destination,
186
+ unlockMinutes: this.unlockMinutes,
187
+ });
188
+ }
189
+ focusFirstControl() {
190
+ // `shadow: true`, so a shadow root is always attached by the time a render
191
+ // has completed. The ambient type is nullable; the value is not.
192
+ const root = this.hostEl.shadowRoot;
193
+ // Vega fields are custom elements, so the focusable control is inside their
194
+ // own shadow root. Delegating to the element's own `focus()` lets Vega
195
+ // decide which of its internals should receive focus.
196
+ //
197
+ // Every step renders a heading, so the fallback always resolves — the
198
+ // first arm is the one that matters, moving focus into the form.
199
+ const target = root.querySelector('.form .field:not([disabled])') ??
200
+ root.querySelector('.card__heading');
201
+ target.focus();
202
+ }
203
+ // --- Rendering ----------------------------------------------------------
204
+ render() {
205
+ return (h(Host, { key: 'e8d37d2f818b9b2260fb2ccd3d784393a28385c4' }, h("section", { key: '1c0ce6ee5c73d24b06212d8a4b2f293c89e6cb70', class: "card", "aria-busy": String(this.busy) }, h("slot", { key: 'c87b3ceba0d974e15958aec53c19e76dc3996096', name: "brand" }), this.renderer.render(), this.showHelpFooter && (h("div", { key: '003268c5b8abf8755d55ba54e433fc8114171113', class: "card__footer" }, h("slot", { key: '376accf53b60a5cb489abde889ff74bf7fab3fe6', name: "footer" }, h("p", { key: 'a6834071896f9a3d988c089807fc6a77ee928ffc' }, this.copy.helpPrompt, ' ', h("vega-button-link", { key: '4645b67e1ccf70b0b386a516025659540a9308a9', class: "link", label: this.copy.help, eventful: true, onVegaClick: (event) => this.handlers.onAction('login-help')(event) }))))))));
206
+ }
207
+ static get is() { return "uds-pattern-login-card"; }
208
+ static get encapsulation() { return "shadow"; }
209
+ static get originalStyleUrls() {
210
+ return {
211
+ "$": ["uds-pattern-login-card.css"]
212
+ };
213
+ }
214
+ static get styleUrls() {
215
+ return {
216
+ "$": ["uds-pattern-login-card.css"]
217
+ };
218
+ }
219
+ static get properties() {
220
+ return {
221
+ "config": {
222
+ "type": "string",
223
+ "mutable": false,
224
+ "complexType": {
225
+ "original": "UdsLoginConfig | string",
226
+ "resolved": "UdsLoginConfig | string",
227
+ "references": {
228
+ "UdsLoginConfig": {
229
+ "location": "import",
230
+ "path": "../../providers/login-config",
231
+ "id": "src/providers/login-config.ts::UdsLoginConfig",
232
+ "referenceLocation": "UdsLoginConfig"
233
+ }
234
+ }
235
+ },
236
+ "required": false,
237
+ "optional": false,
238
+ "docs": {
239
+ "tags": [],
240
+ "text": "Everything that cannot be expressed as an attribute: the `auth` adapter,\nthe `control` strategy and any `labels` overrides.\n\nThe split is mechanical rather than a matter of taste \u2014 see\n`UdsLoginConfig`. Scalars below are attributes because they can be;\nobjects and functions are gathered here because they cannot be.\n\nAlso accepts a JSON string, so the `labels` member alone can be set from\nplain HTML markup."
241
+ },
242
+ "getter": false,
243
+ "setter": false,
244
+ "reflect": false,
245
+ "attribute": "config",
246
+ "defaultValue": "{}"
247
+ },
248
+ "initialStep": {
249
+ "type": "string",
250
+ "mutable": false,
251
+ "complexType": {
252
+ "original": "UdsLoginStep",
253
+ "resolved": "\"check-email\" | \"forgot-password\" | \"forgot-username\" | \"identifier\" | \"locked\" | \"mfa-method\" | \"otp\" | \"password\" | \"reset-password\" | \"sign-up\" | \"success\"",
254
+ "references": {
255
+ "UdsLoginStep": {
256
+ "location": "import",
257
+ "path": "../../utils/types",
258
+ "id": "src/utils/types.ts::UdsLoginStep",
259
+ "referenceLocation": "UdsLoginStep"
260
+ }
261
+ }
262
+ },
263
+ "required": false,
264
+ "optional": false,
265
+ "docs": {
266
+ "tags": [],
267
+ "text": "The step the workflow starts on."
268
+ },
269
+ "getter": false,
270
+ "setter": false,
271
+ "reflect": false,
272
+ "attribute": "initial-step",
273
+ "defaultValue": "'identifier'"
274
+ },
275
+ "identifier": {
276
+ "type": "string",
277
+ "mutable": false,
278
+ "complexType": {
279
+ "original": "string",
280
+ "resolved": "string",
281
+ "references": {}
282
+ },
283
+ "required": false,
284
+ "optional": false,
285
+ "docs": {
286
+ "tags": [],
287
+ "text": "Pre-populates the identifier field, overriding any remembered value."
288
+ },
289
+ "getter": false,
290
+ "setter": false,
291
+ "reflect": false,
292
+ "attribute": "identifier",
293
+ "defaultValue": "''"
294
+ },
295
+ "otpLength": {
296
+ "type": "number",
297
+ "mutable": false,
298
+ "complexType": {
299
+ "original": "number",
300
+ "resolved": "number",
301
+ "references": {}
302
+ },
303
+ "required": false,
304
+ "optional": false,
305
+ "docs": {
306
+ "tags": [],
307
+ "text": "Default number of digit inputs, when the provider does not specify one."
308
+ },
309
+ "getter": false,
310
+ "setter": false,
311
+ "reflect": false,
312
+ "attribute": "otp-length",
313
+ "defaultValue": "6"
314
+ },
315
+ "rememberStorageKey": {
316
+ "type": "string",
317
+ "mutable": false,
318
+ "complexType": {
319
+ "original": "string",
320
+ "resolved": "string",
321
+ "references": {}
322
+ },
323
+ "required": false,
324
+ "optional": false,
325
+ "docs": {
326
+ "tags": [],
327
+ "text": "Where the \"Remember my email\" value is persisted. Set to an empty string to\ndisable persistence entirely."
328
+ },
329
+ "getter": false,
330
+ "setter": false,
331
+ "reflect": false,
332
+ "attribute": "remember-storage-key",
333
+ "defaultValue": "'uds-pattern-login.identifier'"
334
+ },
335
+ "showHelpFooter": {
336
+ "type": "boolean",
337
+ "mutable": false,
338
+ "complexType": {
339
+ "original": "boolean",
340
+ "resolved": "boolean",
341
+ "references": {}
342
+ },
343
+ "required": false,
344
+ "optional": false,
345
+ "docs": {
346
+ "tags": [],
347
+ "text": "Renders the \"Need help signing in?\" footer."
348
+ },
349
+ "getter": false,
350
+ "setter": false,
351
+ "reflect": false,
352
+ "attribute": "show-help-footer",
353
+ "defaultValue": "true"
354
+ }
355
+ };
356
+ }
357
+ static get states() {
358
+ return {
359
+ "step": {},
360
+ "busy": {},
361
+ "errorText": {},
362
+ "methods": {},
363
+ "otpMethodLabel": {},
364
+ "destination": {},
365
+ "unlockMinutes": {},
366
+ "resendAt": {},
367
+ "nowTick": {},
368
+ "values": {}
369
+ };
370
+ }
371
+ static get events() {
372
+ return [{
373
+ "method": "udsLoginSuccess",
374
+ "name": "udsLoginSuccess",
375
+ "bubbles": true,
376
+ "cancelable": true,
377
+ "composed": true,
378
+ "docs": {
379
+ "tags": [],
380
+ "text": "Emitted once the provider reports successful authentication."
381
+ },
382
+ "complexType": {
383
+ "original": "{ session?: UdsSession }",
384
+ "resolved": "{ session?: unknown; }",
385
+ "references": {
386
+ "UdsSession": {
387
+ "location": "import",
388
+ "path": "../../providers/auth-provider",
389
+ "id": "src/providers/auth-provider.ts::UdsSession",
390
+ "referenceLocation": "UdsSession"
391
+ }
392
+ }
393
+ }
394
+ }, {
395
+ "method": "udsLoginStepChange",
396
+ "name": "udsLoginStepChange",
397
+ "bubbles": true,
398
+ "cancelable": true,
399
+ "composed": true,
400
+ "docs": {
401
+ "tags": [],
402
+ "text": "Emitted whenever the workflow moves to a different step."
403
+ },
404
+ "complexType": {
405
+ "original": "UdsLoginStepChangeDetail",
406
+ "resolved": "UdsLoginStepChangeDetail",
407
+ "references": {
408
+ "UdsLoginStepChangeDetail": {
409
+ "location": "import",
410
+ "path": "../../utils/types",
411
+ "id": "src/utils/types.ts::UdsLoginStepChangeDetail",
412
+ "referenceLocation": "UdsLoginStepChangeDetail"
413
+ }
414
+ }
415
+ }
416
+ }, {
417
+ "method": "udsLoginError",
418
+ "name": "udsLoginError",
419
+ "bubbles": true,
420
+ "cancelable": true,
421
+ "composed": true,
422
+ "docs": {
423
+ "tags": [],
424
+ "text": "Emitted when the provider reports a failure, after the card has displayed it."
425
+ },
426
+ "complexType": {
427
+ "original": "UdsLoginErrorDetail",
428
+ "resolved": "UdsLoginErrorDetail",
429
+ "references": {
430
+ "UdsLoginErrorDetail": {
431
+ "location": "import",
432
+ "path": "../../utils/types",
433
+ "id": "src/utils/types.ts::UdsLoginErrorDetail",
434
+ "referenceLocation": "UdsLoginErrorDetail"
435
+ }
436
+ }
437
+ }
438
+ }, {
439
+ "method": "udsLoginAction",
440
+ "name": "udsLoginAction",
441
+ "bubbles": true,
442
+ "cancelable": true,
443
+ "composed": true,
444
+ "docs": {
445
+ "tags": [],
446
+ "text": "Emitted for the two intents the pattern cannot resolve \u2014 the help links.\nIn-workflow navigation is handled internally and is not reported here."
447
+ },
448
+ "complexType": {
449
+ "original": "UdsLoginActionDetail",
450
+ "resolved": "UdsLoginActionDetail",
451
+ "references": {
452
+ "UdsLoginActionDetail": {
453
+ "location": "import",
454
+ "path": "../../utils/types",
455
+ "id": "src/utils/types.ts::UdsLoginActionDetail",
456
+ "referenceLocation": "UdsLoginActionDetail"
457
+ }
458
+ }
459
+ }
460
+ }];
461
+ }
462
+ static get methods() {
463
+ return {
464
+ "reset": {
465
+ "complexType": {
466
+ "signature": "() => Promise<void>",
467
+ "parameters": [],
468
+ "references": {
469
+ "Promise": {
470
+ "location": "global",
471
+ "id": "global::Promise"
472
+ }
473
+ },
474
+ "return": "Promise<void>"
475
+ },
476
+ "docs": {
477
+ "text": "Returns the workflow to its first step and clears all collected input.\nUseful after a sign-out, or to recover from a terminal step.",
478
+ "tags": []
479
+ }
480
+ }
481
+ };
482
+ }
483
+ static get elementRef() { return "hostEl"; }
484
+ }
485
+ __decorate([
486
+ InjectSlimmer()
487
+ ], UdsPatternLoginCard.prototype, "workflow", void 0);
488
+ __decorate([
489
+ InjectSlimmer()
490
+ ], UdsPatternLoginCard.prototype, "resend", void 0);
491
+ __decorate([
492
+ InjectSlimmer()
493
+ ], UdsPatternLoginCard.prototype, "memory", void 0);
494
+ __decorate([
495
+ InjectSlimmer()
496
+ ], UdsPatternLoginCard.prototype, "renderer", void 0);
497
+ /** Accepts either a parsed value or a JSON string (for plain-HTML consumers). */
498
+ function parseJsonProp(value, fallback) {
499
+ if (typeof value !== 'string') {
500
+ return value ?? fallback;
501
+ }
502
+ try {
503
+ return JSON.parse(value);
504
+ }
505
+ catch {
506
+ return fallback;
507
+ }
508
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * The pattern's own `vega-form` validation rules.
3
+ *
4
+ * ## Why rules rather than a pre-submit check
5
+ *
6
+ * `vega-form` already gates submission: its submit handler awaits `valid()` and
7
+ * only emits `vegaFormSubmit` when every field passes. Anything the pattern
8
+ * checks *outside* that gate is a second, competing validation pass — it fires
9
+ * at a different moment, reports through a different surface (a card-level
10
+ * banner rather than the field at fault), and has to be kept in step by hand.
11
+ *
12
+ * Expressing the same checks as rules puts them inside the one flow. The field
13
+ * that is wrong is the field that says so, the error clears as the user fixes
14
+ * it, and the submit gate needs no pattern-specific code at all.
15
+ *
16
+ * ## Why these two, and nothing else
17
+ *
18
+ * Everything Vega already derives from a prop — `required`, `type="email"`,
19
+ * `minLength` — is left to Vega, including its wording. Restating "this field
20
+ * is required" here would fork copy that the design system maintains for every
21
+ * Global Payments product. Only checks Vega cannot express from a prop alone
22
+ * live here: one that needs a sibling field's value, and one that needs the
23
+ * configured code length.
24
+ *
25
+ * ## Why they read through callbacks
26
+ *
27
+ * A rule is handed to `vega-input` as a prop and re-read when its identity
28
+ * changes, so rebuilding the array on each render would churn Vega's watchers
29
+ * every time any unrelated state moved. These are built once and resolve their
30
+ * inputs — the value to compare against, the message to show — when they are
31
+ * evaluated, so a single stable instance always sees current state.
32
+ */
33
+ /** Evaluated only once the field has a value; emptiness is `required`'s job. */
34
+ class NonEmptyStringRule {
35
+ canEvaluate(input, status) {
36
+ if (typeof input !== 'string' || input.length === 0) {
37
+ return false;
38
+ }
39
+ return status ? !status.disabled && status.visible : true;
40
+ }
41
+ /**
42
+ * Mirrors Vega's built-in rules: say nothing until the user has engaged with
43
+ * the field, so a freshly rendered step is not pre-littered with errors.
44
+ */
45
+ shouldShowError(status) {
46
+ return status ? !status.disabled && status.visible && (status.touched || status.modified) : true;
47
+ }
48
+ }
49
+ /**
50
+ * Requires a field to equal another field's current value.
51
+ *
52
+ * Used for the "confirm new password" pairing, which no single-field rule can
53
+ * express: the answer depends on a sibling that may change after this field was
54
+ * last touched.
55
+ */
56
+ export class MatchesFieldRule extends NonEmptyStringRule {
57
+ constructor(expected, message) {
58
+ super();
59
+ this.expected = expected;
60
+ this.message = message;
61
+ }
62
+ evaluate(input) {
63
+ const isValid = input === this.expected();
64
+ return { isValid, message: isValid ? '' : this.message() };
65
+ }
66
+ }
67
+ /**
68
+ * Requires every character of a passcode to be present.
69
+ *
70
+ * `required` alone is not enough here. It only asks whether the value is
71
+ * non-empty, so a half-typed code — three boxes of six — satisfies it and
72
+ * reaches the provider, which then has to answer a question the pattern could
73
+ * have answered without a round trip.
74
+ */
75
+ export class CompleteCodeRule extends NonEmptyStringRule {
76
+ constructor(length, message) {
77
+ super();
78
+ this.length = length;
79
+ this.message = message;
80
+ }
81
+ evaluate(input) {
82
+ const expected = this.length();
83
+ const isValid = input.length >= expected;
84
+ return { isValid, message: isValid ? '' : this.message(expected) };
85
+ }
86
+ }