@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.
- package/README.md +567 -2
- package/dist/cjs/control-strategy-DhhYTbse.js +113 -0
- package/dist/cjs/gpds-pattern-web.cjs.js +24 -0
- package/dist/cjs/index-Dzm6P89U.js +1565 -0
- package/dist/cjs/index.cjs.js +180 -0
- package/dist/cjs/loader.cjs.js +12 -0
- package/dist/cjs/uds-pattern-login-card_2.cjs.entry.js +1662 -0
- package/dist/collection/collection-manifest.json +14 -0
- package/dist/collection/components/uds-pattern-login-card/slimmers/identity-memory.slimmer.js +63 -0
- package/dist/collection/components/uds-pattern-login-card/slimmers/login-workflow.slimmer.js +357 -0
- package/dist/collection/components/uds-pattern-login-card/slimmers/renderers/login-card-renderer.js +100 -0
- package/dist/collection/components/uds-pattern-login-card/slimmers/renderers/login-field-renderer.js +129 -0
- package/dist/collection/components/uds-pattern-login-card/slimmers/renderers/login-step-renderer.js +192 -0
- package/dist/collection/components/uds-pattern-login-card/slimmers/resend-throttle.slimmer.js +65 -0
- package/dist/collection/components/uds-pattern-login-card/uds-pattern-login-card.css +154 -0
- package/dist/collection/components/uds-pattern-login-card/uds-pattern-login-card.js +508 -0
- package/dist/collection/components/uds-pattern-login-card/validation/login-validation-rules.js +86 -0
- package/dist/collection/components/uds-pattern-login-card/view-model/login-card-handlers.js +1 -0
- package/dist/collection/components/uds-pattern-login-card/view-model/login-step.view-model.js +138 -0
- package/dist/collection/components/uds-pattern-login-page/uds-pattern-login-page.css +37 -0
- package/dist/collection/components/uds-pattern-login-page/uds-pattern-login-page.js +97 -0
- package/dist/collection/index.js +5 -0
- package/dist/collection/providers/auth-provider.js +28 -0
- package/dist/collection/providers/control-strategy.js +21 -0
- package/dist/collection/providers/login-config.js +4 -0
- package/dist/collection/providers/memory-auth-provider.js +133 -0
- package/dist/collection/providers/parse-auth-result.js +135 -0
- package/dist/collection/slimmer/common/log.js +14 -0
- package/dist/collection/slimmer/common/symbols.js +10 -0
- package/dist/collection/slimmer/common/types.js +2 -0
- package/dist/collection/slimmer/decorators/inject-slimmer.js +73 -0
- package/dist/collection/slimmer/decorators/map-to-component-field.js +41 -0
- package/dist/collection/slimmer/decorators/map-to-component-method.js +33 -0
- package/dist/collection/slimmer/decorators/slimmer.js +10 -0
- package/dist/collection/slimmer/index.js +5 -0
- package/dist/collection/utils/labels.js +81 -0
- package/dist/collection/utils/types.js +1 -0
- package/dist/components/index.d.ts +35 -0
- package/dist/components/index.js +1 -0
- package/dist/components/p-DOrg55po.js +1 -0
- package/dist/components/p-_G8A9gg0.js +1 -0
- package/dist/components/uds-pattern-login-card.d.ts +11 -0
- package/dist/components/uds-pattern-login-card.js +1 -0
- package/dist/components/uds-pattern-login-page.d.ts +11 -0
- package/dist/components/uds-pattern-login-page.js +1 -0
- package/dist/docs.d.ts +480 -0
- package/dist/docs.json +549 -0
- package/dist/esm/control-strategy-DOrg55po.js +105 -0
- package/dist/esm/gpds-pattern-web.js +20 -0
- package/dist/esm/index-DsXlLyGj.js +1537 -0
- package/dist/esm/index.js +170 -0
- package/dist/esm/loader.js +10 -0
- package/dist/esm/uds-pattern-login-card_2.entry.js +1659 -0
- package/dist/gpds-pattern-web/gpds-pattern-web.css +1 -0
- package/dist/gpds-pattern-web/gpds-pattern-web.esm.js +1 -0
- package/dist/gpds-pattern-web/index.esm.js +1 -0
- package/dist/gpds-pattern-web/p-2c97d2da.entry.js +1 -0
- package/dist/gpds-pattern-web/p-DOrg55po.js +1 -0
- package/dist/gpds-pattern-web/p-DsXlLyGj.js +3 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.js +1 -0
- package/dist/types/components/uds-pattern-login-card/slimmers/identity-memory.slimmer.d.ts +21 -0
- package/dist/types/components/uds-pattern-login-card/slimmers/login-workflow.slimmer.d.ts +100 -0
- package/dist/types/components/uds-pattern-login-card/slimmers/renderers/login-card-renderer.d.ts +44 -0
- package/dist/types/components/uds-pattern-login-card/slimmers/renderers/login-field-renderer.d.ts +91 -0
- package/dist/types/components/uds-pattern-login-card/slimmers/renderers/login-step-renderer.d.ts +40 -0
- package/dist/types/components/uds-pattern-login-card/slimmers/resend-throttle.slimmer.d.ts +21 -0
- package/dist/types/components/uds-pattern-login-card/uds-pattern-login-card.d.ts +134 -0
- package/dist/types/components/uds-pattern-login-card/validation/login-validation-rules.d.ts +72 -0
- package/dist/types/components/uds-pattern-login-card/view-model/login-card-handlers.d.ts +21 -0
- package/dist/types/components/uds-pattern-login-card/view-model/login-step.view-model.d.ts +96 -0
- package/dist/types/components/uds-pattern-login-page/uds-pattern-login-page.d.ts +21 -0
- package/dist/types/components.d.ts +327 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/providers/auth-provider.d.ts +168 -0
- package/dist/types/providers/control-strategy.d.ts +144 -0
- package/dist/types/providers/login-config.d.ts +52 -0
- package/dist/types/providers/memory-auth-provider.d.ts +37 -0
- package/dist/types/providers/parse-auth-result.d.ts +8 -0
- package/dist/types/slimmer/common/log.d.ts +8 -0
- package/dist/types/slimmer/common/symbols.d.ts +10 -0
- package/dist/types/slimmer/common/types.d.ts +30 -0
- package/dist/types/slimmer/decorators/inject-slimmer.d.ts +24 -0
- package/dist/types/slimmer/decorators/map-to-component-field.d.ts +16 -0
- package/dist/types/slimmer/decorators/map-to-component-method.d.ts +11 -0
- package/dist/types/slimmer/decorators/slimmer.d.ts +10 -0
- package/dist/types/slimmer/index.d.ts +6 -0
- package/dist/types/stencil-public-runtime.d.ts +1879 -0
- package/dist/types/utils/labels.d.ts +13 -0
- package/dist/types/utils/types.d.ts +106 -0
- package/dist/types/vega.d.ts +11 -0
- package/loader/cdn.js +1 -0
- package/loader/index.cjs.js +1 -0
- package/loader/index.d.ts +24 -0
- package/loader/index.es2017.js +1 -0
- package/loader/index.js +2 -0
- 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
|
+
}
|
package/dist/collection/components/uds-pattern-login-card/validation/login-validation-rules.js
ADDED
|
@@ -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
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|