@tesouro/embedded-components-react 0.3.43 → 0.3.45
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 +18 -2
- package/dist/experimental/index.d.ts +1 -975
- package/dist/experimental/index.js +0 -6
- package/dist/index.css +10 -0
- package/dist/index.d.ts +1730 -1425
- package/dist/index.js +65 -61
- package/dist/lib/WidgetProvider.js +7 -7
- package/dist/lib/WidgetSuite.d.ts +2081 -0
- package/dist/lib/WidgetSuite.js +5 -0
- package/dist/libs/tesouro-embedded-components-react/accept-disclosures-widget/feature/dist/index5.js +60 -60
- package/dist/libs/tesouro-embedded-components-react/accept-disclosures-widget/ui/dist/lib/AcceptDisclosuresWidget/AcceptDisclosuresWidget.js +6 -6
- package/dist/libs/tesouro-embedded-components-react/bank-accounts-widget/feature/dist/index7.js +18 -18
- package/dist/libs/tesouro-embedded-components-react/bank-accounts-widget/feature/dist/index8.js +16 -16
- package/dist/libs/tesouro-embedded-components-react/bank-accounts-widget/ui/dist/lib/BankAccountsWidgetUi.js +10 -10
- package/dist/libs/tesouro-embedded-components-react/settings-widget/feature/dist/index6.js +45 -45
- package/dist/libs/tesouro-embedded-components-react/shared/feature/dist/lib/WidgetProvider/RootWidgetProvider.js +18 -18
- package/dist/libs/tesouro-embedded-components-react/shared/feature/dist/lib/WidgetProvider/WidgetProvider.js +118 -118
- package/dist/libs/tesouro-embedded-components-react/shared/feature/dist/lib/analytics/build-info.js +1 -1
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index.js +6 -5
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index10.js +33 -0
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index11.js +23 -0
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index12.js +19 -0
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index13.js +16 -0
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index14.js +21 -0
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index15.js +22 -0
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index16.js +116 -0
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index4.js +46 -23
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index5.js +20 -88
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index6.js +31 -34
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index7.js +12 -132
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index8.js +11 -137
- package/dist/libs/tesouro-embedded-components-react/widget-suite/feature/dist/index9.js +33 -0
- package/dist/libs/tesouro-embedded-components-react/widget-suite/ui/dist/index3.js +12 -12
- package/dist/packages/shared-ui-shadcn/dist/index.js +113 -113
- package/package.json +1 -1
- package/dist/experimental/WidgetSuite.d.ts +0 -976
- package/dist/experimental/WidgetSuite.js +0 -6
|
@@ -0,0 +1,2081 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ComponentType, AnchorHTMLAttributes, ReactNode, ErrorInfo, ReactElement } from 'react';
|
|
3
|
+
import { FallbackProps } from 'react-error-boundary';
|
|
4
|
+
|
|
5
|
+
type AuthToken = string | undefined;
|
|
6
|
+
interface Auth {
|
|
7
|
+
/**
|
|
8
|
+
* Which part of the request do we use to send the auth?
|
|
9
|
+
*
|
|
10
|
+
* @default 'header'
|
|
11
|
+
*/
|
|
12
|
+
in?: 'header' | 'query' | 'cookie';
|
|
13
|
+
/**
|
|
14
|
+
* A unique identifier for the security scheme.
|
|
15
|
+
*
|
|
16
|
+
* Defined only when there are multiple security schemes whose `Auth`
|
|
17
|
+
* shape would otherwise be identical.
|
|
18
|
+
*/
|
|
19
|
+
key?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Header or query parameter name.
|
|
22
|
+
*
|
|
23
|
+
* @default 'Authorization'
|
|
24
|
+
*/
|
|
25
|
+
name?: string;
|
|
26
|
+
scheme?: 'basic' | 'bearer';
|
|
27
|
+
type: 'apiKey' | 'http';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface SerializerOptions<T> {
|
|
31
|
+
/**
|
|
32
|
+
* @default true
|
|
33
|
+
*/
|
|
34
|
+
explode: boolean;
|
|
35
|
+
style: T;
|
|
36
|
+
}
|
|
37
|
+
type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited';
|
|
38
|
+
type ObjectStyle = 'form' | 'deepObject';
|
|
39
|
+
|
|
40
|
+
type QuerySerializer = (query: Record<string, unknown>) => string;
|
|
41
|
+
type BodySerializer = (body: unknown) => unknown;
|
|
42
|
+
type QuerySerializerOptionsObject = {
|
|
43
|
+
allowReserved?: boolean;
|
|
44
|
+
array?: Partial<SerializerOptions<ArrayStyle>>;
|
|
45
|
+
object?: Partial<SerializerOptions<ObjectStyle>>;
|
|
46
|
+
};
|
|
47
|
+
type QuerySerializerOptions = QuerySerializerOptionsObject & {
|
|
48
|
+
/**
|
|
49
|
+
* Per-parameter serialization overrides. When provided, these settings
|
|
50
|
+
* override the global array/object settings for specific parameter names.
|
|
51
|
+
*/
|
|
52
|
+
parameters?: Record<string, QuerySerializerOptionsObject>;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
type HttpMethod = 'connect' | 'delete' | 'get' | 'head' | 'options' | 'patch' | 'post' | 'put' | 'trace';
|
|
56
|
+
type Client$1<RequestFn = never, Config = unknown, MethodFn = never, BuildUrlFn = never, SseFn = never> = {
|
|
57
|
+
/**
|
|
58
|
+
* Returns the final request URL.
|
|
59
|
+
*/
|
|
60
|
+
buildUrl: BuildUrlFn;
|
|
61
|
+
getConfig: () => Config;
|
|
62
|
+
request: RequestFn;
|
|
63
|
+
setConfig: (config: Config) => Config;
|
|
64
|
+
} & {
|
|
65
|
+
[K in HttpMethod]: MethodFn;
|
|
66
|
+
} & ([SseFn] extends [never] ? {
|
|
67
|
+
sse?: never;
|
|
68
|
+
} : {
|
|
69
|
+
sse: {
|
|
70
|
+
[K in HttpMethod]: SseFn;
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
interface Config$1 {
|
|
74
|
+
/**
|
|
75
|
+
* Auth token or a function returning auth token. The resolved value will be
|
|
76
|
+
* added to the request payload as defined by its `security` array.
|
|
77
|
+
*/
|
|
78
|
+
auth?: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken;
|
|
79
|
+
/**
|
|
80
|
+
* A function for serializing request body parameter. By default,
|
|
81
|
+
* {@link JSON.stringify()} will be used.
|
|
82
|
+
*/
|
|
83
|
+
bodySerializer?: BodySerializer | null;
|
|
84
|
+
/**
|
|
85
|
+
* An object containing any HTTP headers that you want to pre-populate your
|
|
86
|
+
* `Headers` object with.
|
|
87
|
+
*
|
|
88
|
+
* {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more}
|
|
89
|
+
*/
|
|
90
|
+
headers?: RequestInit['headers'] | Record<string, string | number | boolean | (string | number | boolean)[] | null | undefined | unknown>;
|
|
91
|
+
/**
|
|
92
|
+
* The request method.
|
|
93
|
+
*
|
|
94
|
+
* {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more}
|
|
95
|
+
*/
|
|
96
|
+
method?: Uppercase<HttpMethod>;
|
|
97
|
+
/**
|
|
98
|
+
* A function for serializing request query parameters. By default, arrays
|
|
99
|
+
* will be exploded in form style, objects will be exploded in deepObject
|
|
100
|
+
* style, and reserved characters are percent-encoded.
|
|
101
|
+
*
|
|
102
|
+
* This method will have no effect if the native `paramsSerializer()` Axios
|
|
103
|
+
* API function is used.
|
|
104
|
+
*
|
|
105
|
+
* {@link https://swagger.io/docs/specification/serialization/#query View examples}
|
|
106
|
+
*/
|
|
107
|
+
querySerializer?: QuerySerializer | QuerySerializerOptions;
|
|
108
|
+
/**
|
|
109
|
+
* A function validating request data. This is useful if you want to ensure
|
|
110
|
+
* the request conforms to the desired shape, so it can be safely sent to
|
|
111
|
+
* the server.
|
|
112
|
+
*/
|
|
113
|
+
requestValidator?: (data: unknown) => Promise<unknown>;
|
|
114
|
+
/**
|
|
115
|
+
* A function transforming response data before it's returned. This is useful
|
|
116
|
+
* for post-processing data, e.g., converting ISO strings into Date objects.
|
|
117
|
+
*/
|
|
118
|
+
responseTransformer?: (data: unknown) => Promise<unknown>;
|
|
119
|
+
/**
|
|
120
|
+
* A function validating response data. This is useful if you want to ensure
|
|
121
|
+
* the response conforms to the desired shape, so it can be safely passed to
|
|
122
|
+
* the transformers and returned to the user.
|
|
123
|
+
*/
|
|
124
|
+
responseValidator?: (data: unknown) => Promise<unknown>;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
type ServerSentEventsOptions<TData = unknown> = Omit<RequestInit, 'method'> & Pick<Config$1, 'method' | 'responseTransformer' | 'responseValidator'> & {
|
|
128
|
+
/**
|
|
129
|
+
* Fetch API implementation. You can use this option to provide a custom
|
|
130
|
+
* fetch instance.
|
|
131
|
+
*
|
|
132
|
+
* @default globalThis.fetch
|
|
133
|
+
*/
|
|
134
|
+
fetch?: typeof fetch;
|
|
135
|
+
/**
|
|
136
|
+
* Implementing clients can call request interceptors inside this hook.
|
|
137
|
+
*/
|
|
138
|
+
onRequest?: (url: string, init: RequestInit) => Promise<Request>;
|
|
139
|
+
/**
|
|
140
|
+
* Callback invoked when a network or parsing error occurs during streaming.
|
|
141
|
+
*
|
|
142
|
+
* This option applies only if the endpoint returns a stream of events.
|
|
143
|
+
*
|
|
144
|
+
* @param error The error that occurred.
|
|
145
|
+
*/
|
|
146
|
+
onSseError?: (error: unknown) => void;
|
|
147
|
+
/**
|
|
148
|
+
* Callback invoked when an event is streamed from the server.
|
|
149
|
+
*
|
|
150
|
+
* This option applies only if the endpoint returns a stream of events.
|
|
151
|
+
*
|
|
152
|
+
* @param event Event streamed from the server.
|
|
153
|
+
* @returns Nothing (void).
|
|
154
|
+
*/
|
|
155
|
+
onSseEvent?: (event: StreamEvent<TData>) => void;
|
|
156
|
+
serializedBody?: RequestInit['body'];
|
|
157
|
+
/**
|
|
158
|
+
* Default retry delay in milliseconds.
|
|
159
|
+
*
|
|
160
|
+
* This option applies only if the endpoint returns a stream of events.
|
|
161
|
+
*
|
|
162
|
+
* @default 3000
|
|
163
|
+
*/
|
|
164
|
+
sseDefaultRetryDelay?: number;
|
|
165
|
+
/**
|
|
166
|
+
* Maximum number of retry attempts before giving up.
|
|
167
|
+
*/
|
|
168
|
+
sseMaxRetryAttempts?: number;
|
|
169
|
+
/**
|
|
170
|
+
* Maximum retry delay in milliseconds.
|
|
171
|
+
*
|
|
172
|
+
* Applies only when exponential backoff is used.
|
|
173
|
+
*
|
|
174
|
+
* This option applies only if the endpoint returns a stream of events.
|
|
175
|
+
*
|
|
176
|
+
* @default 30000
|
|
177
|
+
*/
|
|
178
|
+
sseMaxRetryDelay?: number;
|
|
179
|
+
/**
|
|
180
|
+
* Optional sleep function for retry backoff.
|
|
181
|
+
*
|
|
182
|
+
* Defaults to using `setTimeout`.
|
|
183
|
+
*/
|
|
184
|
+
sseSleepFn?: (ms: number) => Promise<void>;
|
|
185
|
+
url: string;
|
|
186
|
+
};
|
|
187
|
+
interface StreamEvent<TData = unknown> {
|
|
188
|
+
data: TData;
|
|
189
|
+
event?: string;
|
|
190
|
+
id?: string;
|
|
191
|
+
retry?: number;
|
|
192
|
+
}
|
|
193
|
+
type ServerSentEventsResult<TData = unknown, TReturn = void, TNext = unknown> = {
|
|
194
|
+
stream: AsyncGenerator<TData extends Record<string, unknown> ? TData[keyof TData] : TData, TReturn, TNext>;
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
type ErrInterceptor<Err, Res, Req, Options> = (error: Err,
|
|
198
|
+
/** response may be undefined due to a network error where no response object is produced */
|
|
199
|
+
response: Res | undefined,
|
|
200
|
+
/** request may be undefined, because error may be from building the request object itself */
|
|
201
|
+
request: Req | undefined, options: Options) => Err | Promise<Err>;
|
|
202
|
+
type ReqInterceptor<Req, Options> = (request: Req, options: Options) => Req | Promise<Req>;
|
|
203
|
+
type ResInterceptor<Res, Req, Options> = (response: Res, request: Req, options: Options) => Res | Promise<Res>;
|
|
204
|
+
declare class Interceptors<Interceptor> {
|
|
205
|
+
fns: Array<Interceptor | null>;
|
|
206
|
+
clear(): void;
|
|
207
|
+
eject(id: number | Interceptor): void;
|
|
208
|
+
exists(id: number | Interceptor): boolean;
|
|
209
|
+
getInterceptorIndex(id: number | Interceptor): number;
|
|
210
|
+
update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false;
|
|
211
|
+
use(fn: Interceptor): number;
|
|
212
|
+
}
|
|
213
|
+
interface Middleware<Req, Res, Err, Options> {
|
|
214
|
+
error: Interceptors<ErrInterceptor<Err, Res, Req, Options>>;
|
|
215
|
+
request: Interceptors<ReqInterceptor<Req, Options>>;
|
|
216
|
+
response: Interceptors<ResInterceptor<Res, Req, Options>>;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
type ResponseStyle = 'data' | 'fields';
|
|
220
|
+
interface Config<T extends ClientOptions$1 = ClientOptions$1> extends Omit<RequestInit, 'body' | 'headers' | 'method'>, Config$1 {
|
|
221
|
+
/**
|
|
222
|
+
* Base URL for all requests made by this client.
|
|
223
|
+
*/
|
|
224
|
+
baseUrl?: T['baseUrl'];
|
|
225
|
+
/**
|
|
226
|
+
* Fetch API implementation. You can use this option to provide a custom
|
|
227
|
+
* fetch instance.
|
|
228
|
+
*
|
|
229
|
+
* @default globalThis.fetch
|
|
230
|
+
*/
|
|
231
|
+
fetch?: typeof fetch;
|
|
232
|
+
/**
|
|
233
|
+
* Please don't use the Fetch client for Next.js applications. The `next`
|
|
234
|
+
* options won't have any effect.
|
|
235
|
+
*
|
|
236
|
+
* Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead.
|
|
237
|
+
*/
|
|
238
|
+
next?: never;
|
|
239
|
+
/**
|
|
240
|
+
* Return the response data parsed in a specified format. By default, `auto`
|
|
241
|
+
* will infer the appropriate method from the `Content-Type` response header.
|
|
242
|
+
* You can override this behavior with any of the {@link Body} methods.
|
|
243
|
+
* Select `stream` if you don't want to parse response data at all.
|
|
244
|
+
*
|
|
245
|
+
* @default 'auto'
|
|
246
|
+
*/
|
|
247
|
+
parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text';
|
|
248
|
+
/**
|
|
249
|
+
* Should we return only data or multiple fields (data, error, response, etc.)?
|
|
250
|
+
*
|
|
251
|
+
* @default 'fields'
|
|
252
|
+
*/
|
|
253
|
+
responseStyle?: ResponseStyle;
|
|
254
|
+
/**
|
|
255
|
+
* Throw an error instead of returning it in the response?
|
|
256
|
+
*
|
|
257
|
+
* @default false
|
|
258
|
+
*/
|
|
259
|
+
throwOnError?: T['throwOnError'];
|
|
260
|
+
}
|
|
261
|
+
interface RequestOptions<TData = unknown, TResponseStyle extends ResponseStyle = 'fields', ThrowOnError extends boolean = boolean, Url extends string = string> extends Config<{
|
|
262
|
+
responseStyle: TResponseStyle;
|
|
263
|
+
throwOnError: ThrowOnError;
|
|
264
|
+
}>, Pick<ServerSentEventsOptions<TData>, 'onRequest' | 'onSseError' | 'onSseEvent' | 'sseDefaultRetryDelay' | 'sseMaxRetryAttempts' | 'sseMaxRetryDelay'> {
|
|
265
|
+
/**
|
|
266
|
+
* Any body that you want to add to your request.
|
|
267
|
+
*
|
|
268
|
+
* {@link https://developer.mozilla.org/docs/Web/API/fetch#body}
|
|
269
|
+
*/
|
|
270
|
+
body?: unknown;
|
|
271
|
+
path?: Record<string, unknown>;
|
|
272
|
+
query?: Record<string, unknown>;
|
|
273
|
+
/**
|
|
274
|
+
* Security mechanism(s) to use for the request.
|
|
275
|
+
*/
|
|
276
|
+
security?: ReadonlyArray<Auth>;
|
|
277
|
+
url: Url;
|
|
278
|
+
}
|
|
279
|
+
interface ResolvedRequestOptions<TResponseStyle extends ResponseStyle = 'fields', ThrowOnError extends boolean = boolean, Url extends string = string> extends RequestOptions<unknown, TResponseStyle, ThrowOnError, Url> {
|
|
280
|
+
headers: Headers;
|
|
281
|
+
serializedBody?: string;
|
|
282
|
+
}
|
|
283
|
+
type RequestResult<TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, TResponseStyle extends ResponseStyle = 'fields'> = ThrowOnError extends true ? Promise<TResponseStyle extends 'data' ? TData extends Record<string, unknown> ? TData[keyof TData] : TData : {
|
|
284
|
+
data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
|
|
285
|
+
request: Request;
|
|
286
|
+
response: Response;
|
|
287
|
+
}> : Promise<TResponseStyle extends 'data' ? (TData extends Record<string, unknown> ? TData[keyof TData] : TData) | undefined : ({
|
|
288
|
+
data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
|
|
289
|
+
error: undefined;
|
|
290
|
+
} | {
|
|
291
|
+
data: undefined;
|
|
292
|
+
error: TError extends Record<string, unknown> ? TError[keyof TError] : TError;
|
|
293
|
+
}) & {
|
|
294
|
+
/** request may be undefined, because error may be from building the request object itself */
|
|
295
|
+
request?: Request;
|
|
296
|
+
/** response may be undefined, because error may be from building the request object itself or from a network error */
|
|
297
|
+
response?: Response;
|
|
298
|
+
}>;
|
|
299
|
+
interface ClientOptions$1 {
|
|
300
|
+
baseUrl?: string;
|
|
301
|
+
responseStyle?: ResponseStyle;
|
|
302
|
+
throwOnError?: boolean;
|
|
303
|
+
}
|
|
304
|
+
type MethodFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
|
|
305
|
+
type SseFn = <TData = unknown, _TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<never, TResponseStyle, ThrowOnError>, 'method'>) => Promise<ServerSentEventsResult<TData>>;
|
|
306
|
+
type RequestFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'> & Pick<Required<RequestOptions<TData, TResponseStyle, ThrowOnError>>, 'method'>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
|
|
307
|
+
type BuildUrlFn = <TData extends {
|
|
308
|
+
body?: unknown;
|
|
309
|
+
path?: Record<string, unknown>;
|
|
310
|
+
query?: Record<string, unknown>;
|
|
311
|
+
url: string;
|
|
312
|
+
}>(options: TData & Options<TData>) => string;
|
|
313
|
+
type Client = Client$1<RequestFn, Config, MethodFn, BuildUrlFn, SseFn> & {
|
|
314
|
+
interceptors: Middleware<Request, Response, unknown, ResolvedRequestOptions>;
|
|
315
|
+
};
|
|
316
|
+
interface TDataShape {
|
|
317
|
+
body?: unknown;
|
|
318
|
+
headers?: unknown;
|
|
319
|
+
path?: unknown;
|
|
320
|
+
query?: unknown;
|
|
321
|
+
url: string;
|
|
322
|
+
}
|
|
323
|
+
type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>;
|
|
324
|
+
type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown, TResponseStyle extends ResponseStyle = 'fields'> = OmitKeys<RequestOptions<TResponse, TResponseStyle, ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & ([TData] extends [never] ? unknown : Omit<TData, 'url'>);
|
|
325
|
+
|
|
326
|
+
type ClientOptions = {
|
|
327
|
+
baseUrl: 'https://api.stage.tesouro.com' | 'https://api.sandbox.stage.tesouro.com' | 'https://api.stage.business-banking.app' | 'https://api.tesouro.com' | 'https://api.sandbox.tesouro.com' | 'https://api.business-banking.app' | (string & {});
|
|
328
|
+
};
|
|
329
|
+
type CreditCardStatus = 'PENDING_ACTIVATION' | 'ACTIVE' | 'LOCKED' | 'CLOSED';
|
|
330
|
+
type CreditCardType = 'DIGITAL' | 'PHYSICAL';
|
|
331
|
+
/**
|
|
332
|
+
* The rolling period a velocity control's amount and usage limits are evaluated over.
|
|
333
|
+
* `TRANSACTION` applies the limit per-transaction and therefore carries no usage limit.
|
|
334
|
+
*/
|
|
335
|
+
type VelocityWindow = 'DAY' | 'LIFETIME' | 'MONTH' | 'TRANSACTION' | 'WEEK';
|
|
336
|
+
|
|
337
|
+
type EmbeddedClient = Client;
|
|
338
|
+
type ExtractLiterals<T> = T extends string ? string extends T ? never : T : never;
|
|
339
|
+
type BaseUrl = ExtractLiterals<ClientOptions['baseUrl']>;
|
|
340
|
+
|
|
341
|
+
type LinkComponentProps = AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
342
|
+
children?: ReactNode;
|
|
343
|
+
};
|
|
344
|
+
type LinkComponent = ComponentType<LinkComponentProps>;
|
|
345
|
+
/**
|
|
346
|
+
* The UI frameworks a widget's UI layer can render with.
|
|
347
|
+
*
|
|
348
|
+
* - `shadcn` — the shadcn/Tailwind implementation. This is the default and the
|
|
349
|
+
* implicit fallback, so existing consumers that select nothing keep rendering
|
|
350
|
+
* shadcn.
|
|
351
|
+
* - `tecton` — the Tecton implementation.
|
|
352
|
+
*
|
|
353
|
+
* Declared as an `as const` object (not a TypeScript `enum`) per repo
|
|
354
|
+
* convention.
|
|
355
|
+
*/
|
|
356
|
+
declare const UIFramework: {
|
|
357
|
+
readonly Shadcn: "shadcn";
|
|
358
|
+
readonly Tecton: "tecton";
|
|
359
|
+
};
|
|
360
|
+
type UIFramework = (typeof UIFramework)[keyof typeof UIFramework];
|
|
361
|
+
|
|
362
|
+
interface PaginationFooterLabels {
|
|
363
|
+
rowsPerPageLabel: string;
|
|
364
|
+
previousPageButton: string;
|
|
365
|
+
nextPageButton: string;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* The implementation a widget renders with.
|
|
370
|
+
*
|
|
371
|
+
* - `native` — the Tesouro-native implementation. This is the default and the
|
|
372
|
+
* implicit fallback, so consumers that select nothing keep rendering native.
|
|
373
|
+
* - `monite` — the Monite SDK implementation.
|
|
374
|
+
*
|
|
375
|
+
* Declared as an `as const` object (not a TypeScript `enum`) per repo
|
|
376
|
+
* convention.
|
|
377
|
+
*/
|
|
378
|
+
declare const Implementation: {
|
|
379
|
+
readonly Native: "native";
|
|
380
|
+
readonly Monite: "monite";
|
|
381
|
+
};
|
|
382
|
+
type Implementation = (typeof Implementation)[keyof typeof Implementation];
|
|
383
|
+
/**
|
|
384
|
+
* The settable fields of the widget config cascade.
|
|
385
|
+
*
|
|
386
|
+
* This is the type accepted by {@link setGlobalWidgetConfig} and all provider props.
|
|
387
|
+
* It intentionally excludes `initResponse`, which is populated automatically by the
|
|
388
|
+
* provider after a successful fetch and must never be set manually.
|
|
389
|
+
*
|
|
390
|
+
* The `null` vs `undefined` distinction on `widgetToken` and `organizationId` is intentional:
|
|
391
|
+
* - `undefined` — not set at this level; inherit from the nearest ancestor or global store.
|
|
392
|
+
* - `null` — explicitly cleared; downstream sees "no value" even if an ancestor had one
|
|
393
|
+
* (e.g. after logout or deliberate de-scoping).
|
|
394
|
+
*
|
|
395
|
+
* @see {@link WidgetConfig} for the resolved output type (includes `initResponse`)
|
|
396
|
+
* @see {@link RootWidgetProvider}
|
|
397
|
+
* @see {@link WidgetProvider}
|
|
398
|
+
* @see {@link setGlobalWidgetConfig}
|
|
399
|
+
*/
|
|
400
|
+
interface WidgetConfigInput {
|
|
401
|
+
/**
|
|
402
|
+
* Base URL of the Tesouro embedded API (e.g. `"https://api.tesouro.com"`).
|
|
403
|
+
*
|
|
404
|
+
* When omitted the nearest ancestor's `baseUrl` or the global store value is used.
|
|
405
|
+
* Changing this recreates the underlying HTTP client so all subsequent requests
|
|
406
|
+
* go to the new host.
|
|
407
|
+
*/
|
|
408
|
+
baseUrl?: BaseUrl;
|
|
409
|
+
/**
|
|
410
|
+
* Bearer token used to authenticate widget requests.
|
|
411
|
+
*
|
|
412
|
+
* Injected as `Authorization: Bearer <token>` on every outgoing request via an
|
|
413
|
+
* interceptor on the scoped HTTP client. Token updates are picked up immediately
|
|
414
|
+
* without recreating the client.
|
|
415
|
+
*
|
|
416
|
+
* - `string` — send this token on all requests from this level downward.
|
|
417
|
+
* - `null` — explicitly cleared; no auth header is sent and fetching is suppressed.
|
|
418
|
+
* - `undefined` — not set at this level; inherit from the nearest ancestor or global store.
|
|
419
|
+
*/
|
|
420
|
+
widgetToken?: string | null;
|
|
421
|
+
/**
|
|
422
|
+
* Organization ID forwarded as the `x-organization-id` request header.
|
|
423
|
+
*
|
|
424
|
+
* Passed through {@link EmbedApiProvider} context rather than the auth interceptor,
|
|
425
|
+
* so individual data-access hooks can opt in per-request.
|
|
426
|
+
*
|
|
427
|
+
* - `string` — use this organization for downstream data requests.
|
|
428
|
+
* - `null` — explicitly cleared; queries that require an org ID will be disabled.
|
|
429
|
+
* - `undefined` — not set at this level; inherit from the nearest ancestor or global store.
|
|
430
|
+
*
|
|
431
|
+
* When `undefined` across the **whole** cascade (no prop, no ancestor, no global
|
|
432
|
+
* value), the resolved org defaults to the loaded `initResponse.organizationId`
|
|
433
|
+
* (see {@link WidgetConfig.initResponse}) once the widget-init fetch settles. This
|
|
434
|
+
* is the lowest-priority fallback — any explicit `string` or `null` at any cascade
|
|
435
|
+
* level wins, and an explicit `null` is preserved and never falls back.
|
|
436
|
+
*
|
|
437
|
+
* Only an **explicit** ancestor org is inherited. An ancestor's *init-derived*
|
|
438
|
+
* default does not propagate into a descendant that owns its own fetch (its own
|
|
439
|
+
* `baseUrl`/`widgetToken`); such a descendant defaults to its own
|
|
440
|
+
* `initResponse.organizationId` instead, so it never sends an ancestor's org with
|
|
441
|
+
* its own token.
|
|
442
|
+
*/
|
|
443
|
+
organizationId?: string | null;
|
|
444
|
+
/**
|
|
445
|
+
* Optional post-creation hook for the scoped HTTP client.
|
|
446
|
+
*
|
|
447
|
+
* Called once after the provider creates its scoped {@link EmbeddedClient} and
|
|
448
|
+
* applies the built-in `Authorization: Bearer` interceptor. Receives the
|
|
449
|
+
* fully-configured client and must return the client to be used for the lifetime of
|
|
450
|
+
* this provider level — either the same instance (with additional interceptors
|
|
451
|
+
* attached) or a new client entirely.
|
|
452
|
+
*
|
|
453
|
+
* **Order:** The built-in auth interceptor is always applied first. `configClient`
|
|
454
|
+
* is called on top of it, so any interceptors you add here run after auth is set.
|
|
455
|
+
*
|
|
456
|
+
* **Any prop triggers a scoped client.** A {@link WidgetProvider} creates its own
|
|
457
|
+
* scoped client whenever any prop is set — including `configClient` alone, without
|
|
458
|
+
* `baseUrl` or `widgetToken`. Only a fully props-free pass-through provider skips
|
|
459
|
+
* client creation and never calls this function.
|
|
460
|
+
*
|
|
461
|
+
* **Stability:** The function reference is included in the client creation memo's
|
|
462
|
+
* dependency array. Passing an unstable (inline) function recreates the client on
|
|
463
|
+
* every render. Stabilize with `useCallback` or define the function outside the
|
|
464
|
+
* component.
|
|
465
|
+
*
|
|
466
|
+
* **Cascade:** Inherits from the nearest ancestor when `undefined`. A child
|
|
467
|
+
* {@link WidgetProvider} that creates its own scoped client will use the resolved
|
|
468
|
+
* `configClient` from the cascade unless it provides its own override.
|
|
469
|
+
*
|
|
470
|
+
* @example
|
|
471
|
+
* ```tsx
|
|
472
|
+
* const addLogging = useCallback(
|
|
473
|
+
* (client: EmbeddedClient) => {
|
|
474
|
+
* client.interceptors.request.use((req) => {
|
|
475
|
+
* console.log('[widget]', req.method, req.url);
|
|
476
|
+
* return req;
|
|
477
|
+
* });
|
|
478
|
+
* return client;
|
|
479
|
+
* },
|
|
480
|
+
* [],
|
|
481
|
+
* );
|
|
482
|
+
*
|
|
483
|
+
* <RootWidgetProvider
|
|
484
|
+
* baseUrl="https://api.tesouro.com"
|
|
485
|
+
* widgetToken={token}
|
|
486
|
+
* configClient={addLogging}
|
|
487
|
+
* >
|
|
488
|
+
* <App />
|
|
489
|
+
* </RootWidgetProvider>
|
|
490
|
+
* ```
|
|
491
|
+
*/
|
|
492
|
+
configClient?: (client: EmbeddedClient) => EmbeddedClient;
|
|
493
|
+
/**
|
|
494
|
+
* Overrides the widget-gateway routing decision for the scoped HTTP client.
|
|
495
|
+
*
|
|
496
|
+
* Any caller reaching the Tesouro API with a widget token must route data
|
|
497
|
+
* requests through the widget gateway: prefix the path with
|
|
498
|
+
* `/api/widget-gateway/proxy` and carry the token as `X-Widget-Token`. The
|
|
499
|
+
* provider applies both automatically per request when the request origin is
|
|
500
|
+
* a known Tesouro API host (`WIDGET_GATEWAY_HOSTS`, derived from the
|
|
501
|
+
* generated `ClientOptions['baseUrl']`); `/api/widget-gateway/*` paths (the
|
|
502
|
+
* init round-trip) always pass through untouched.
|
|
503
|
+
*
|
|
504
|
+
* - `undefined` — decide from the request origin, as above. Inherits from
|
|
505
|
+
* the nearest ancestor or global store like every other config field.
|
|
506
|
+
* - `true` — always apply the rewrite, even for an unlisted base URL (e.g. a
|
|
507
|
+
* custom domain in front of the gateway).
|
|
508
|
+
* - `false` — never apply it. For hosts that route widget requests their own
|
|
509
|
+
* way, such as a same-origin BFF whose `configClient` retargets every
|
|
510
|
+
* request.
|
|
511
|
+
*
|
|
512
|
+
* Independent of {@link configClient}: a host that only adds a header keeps
|
|
513
|
+
* the built-in routing, and the built-in interceptor runs before any
|
|
514
|
+
* `configClient` interceptor.
|
|
515
|
+
*/
|
|
516
|
+
gatewayRouting?: boolean;
|
|
517
|
+
/**
|
|
518
|
+
* Component the embedded widgets should render in place of plain `<a>` tags.
|
|
519
|
+
*
|
|
520
|
+
* Pass e.g. Next.js's `Link` to make in-app navigation use the host router.
|
|
521
|
+
* Cascades like other config: provider prop > nearest ancestor > global store.
|
|
522
|
+
* When no value is set anywhere, widgets fall back to a plain `<a>` element.
|
|
523
|
+
*/
|
|
524
|
+
linkComponent?: LinkComponent;
|
|
525
|
+
/**
|
|
526
|
+
* Which UI framework the widget UI layer should render with.
|
|
527
|
+
*
|
|
528
|
+
* Lets a consuming context bind widgets to either the shadcn/Tailwind or the
|
|
529
|
+
* Tecton implementation behind the same outward-facing API. The selection is
|
|
530
|
+
* a presentation concern only — it cascades through the provider tree exactly
|
|
531
|
+
* like {@link linkComponent} and is read by UI libraries via `useUIFramework`;
|
|
532
|
+
* it never appears in any widget's feature-library or component props.
|
|
533
|
+
*
|
|
534
|
+
* - `'shadcn'` — the shadcn/Tailwind implementation.
|
|
535
|
+
* - `'tecton'` — the Tecton implementation.
|
|
536
|
+
* - `null` / `undefined` — not set at this level; inherit from the nearest
|
|
537
|
+
* ancestor or global store, falling back to `shadcn` when unset everywhere.
|
|
538
|
+
* `shadcn` is the implicit default, so existing consumers need no changes.
|
|
539
|
+
*/
|
|
540
|
+
uiFramework?: UIFramework | null;
|
|
541
|
+
/**
|
|
542
|
+
* Which implementation a widget renders with.
|
|
543
|
+
*
|
|
544
|
+
* Lets a consuming context bind widgets to either the Tesouro-native or the
|
|
545
|
+
* Monite SDK implementation behind the same outward-facing API. It cascades
|
|
546
|
+
* through the provider tree exactly like {@link linkComponent} and
|
|
547
|
+
* {@link uiFramework} — provider prop > nearest ancestor > global store — and
|
|
548
|
+
* is read via `useImplementation`.
|
|
549
|
+
*
|
|
550
|
+
* - `'native'` — the Tesouro-native implementation.
|
|
551
|
+
* - `'monite'` — the Monite SDK implementation.
|
|
552
|
+
* - `null` / `undefined` — not set at this level; inherit from the nearest
|
|
553
|
+
* ancestor or global store, falling back to `native` when unset everywhere.
|
|
554
|
+
* `native` is the implicit default, so existing consumers need no changes.
|
|
555
|
+
*/
|
|
556
|
+
implementation?: Implementation | null;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Props shared by every analytics-owner-capable widget provider.
|
|
560
|
+
*
|
|
561
|
+
* Combines the full settable cascade ({@link WidgetConfigInput}) with the
|
|
562
|
+
* analytics opt-out honored by analytics owners. Both {@link RootWidgetProvider}
|
|
563
|
+
* and {@link WidgetProvider} build their public props on top of this; the latter
|
|
564
|
+
* adds error-boundary props of its own.
|
|
565
|
+
*
|
|
566
|
+
* @see {@link WidgetConfigInput} for per-field cascade and `null` vs omitted semantics
|
|
567
|
+
*/
|
|
568
|
+
interface WidgetProviderBaseProps extends WidgetConfigInput {
|
|
569
|
+
/**
|
|
570
|
+
* Opt out of all analytics capture and prevent PostHog from loading. Default `true`.
|
|
571
|
+
*
|
|
572
|
+
* Honored only by an analytics **owner** — a {@link RootWidgetProvider} or a
|
|
573
|
+
* standalone {@link WidgetProvider} with no parent provider. When `false`,
|
|
574
|
+
* owner-bound `track` calls in this subtree become no-ops and the PostHog
|
|
575
|
+
* installer is never dynamically imported for this owner's environment.
|
|
576
|
+
* Setting it on a nested {@link WidgetProvider} is ignored in v1 (a one-time
|
|
577
|
+
* `console.warn` is emitted to make the no-op discoverable).
|
|
578
|
+
*/
|
|
579
|
+
analytics?: boolean;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Copy for the states `WidgetProvider` renders *itself*, in place of the widget:
|
|
584
|
+
* the error-boundary fallback and the disclosures gate. A host overrides any
|
|
585
|
+
* subset through the `providerLabels` prop, which cascades like
|
|
586
|
+
* `disclosuresAcceptance`.
|
|
587
|
+
*
|
|
588
|
+
* Not named `Labels` on the public surface: a widget's own `labels` prop is a
|
|
589
|
+
* different thing, and these two travel together on every widget's props type.
|
|
590
|
+
*/
|
|
591
|
+
interface WidgetProviderLabels {
|
|
592
|
+
/** Default copy for the built-in error boundary fallback. */
|
|
593
|
+
errorBoundaryFallback: string;
|
|
594
|
+
/** Heading when init reports disclosures are required and not yet accepted. */
|
|
595
|
+
disclosuresRequiredTitle: string;
|
|
596
|
+
/** Heading while a token-only refresh leaves init stale for the live token. */
|
|
597
|
+
disclosuresRefreshingTitle: string;
|
|
598
|
+
/** Supporting copy while the accept action is withheld for a stale init. */
|
|
599
|
+
disclosuresRefreshingDescription: string;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Props for {@link WidgetProvider}.
|
|
604
|
+
*
|
|
605
|
+
* All fields are optional. When **all** are omitted the provider is a transparent
|
|
606
|
+
* pass-through: no fetch is issued and all resolved values cascade unchanged from
|
|
607
|
+
* the nearest ancestor.
|
|
608
|
+
*/
|
|
609
|
+
interface WidgetProviderProps extends WidgetProviderBaseProps {
|
|
610
|
+
/**
|
|
611
|
+
* Fallback rendered when a render-time exception is caught inside this
|
|
612
|
+
* provider's subtree. Pass either a `ReactNode` (rendered directly) or a
|
|
613
|
+
* render-prop receiving `{ error, resetErrorBoundary }` from
|
|
614
|
+
* `react-error-boundary`. Default is a plain `role="alert"` div whose copy
|
|
615
|
+
* comes from `providerLabels.errorBoundaryFallback`.
|
|
616
|
+
*/
|
|
617
|
+
errorFallback?: ReactNode | ((props: FallbackProps) => ReactNode);
|
|
618
|
+
/**
|
|
619
|
+
* Called once when the boundary catches an error, before the fallback
|
|
620
|
+
* renders. Use for telemetry / Sentry / partner logging. Exceptions
|
|
621
|
+
* thrown from `onError` propagate per `react-error-boundary` semantics.
|
|
622
|
+
*/
|
|
623
|
+
onError?: (error: unknown, info: ErrorInfo) => void;
|
|
624
|
+
/**
|
|
625
|
+
* Accept surface shown when the caller owes disclosures — an INVITED
|
|
626
|
+
* teammate (including `NOT_REQUIRED` orgs, who still need Accept to
|
|
627
|
+
* activate) or an ACTIVE user who owes a new version. Pass
|
|
628
|
+
* `<AcceptDisclosuresWidget />`. Cascades like `linkComponent`.
|
|
629
|
+
* WidgetProvider cannot import the widget itself (cycle).
|
|
630
|
+
*/
|
|
631
|
+
disclosuresAcceptance?: ReactNode;
|
|
632
|
+
/**
|
|
633
|
+
* Overrides for the copy this provider renders in place of the widget: the
|
|
634
|
+
* built-in error-boundary fallback and the disclosures gate. Any subset;
|
|
635
|
+
* unlisted keys keep their defaults. Cascades like `linkComponent`.
|
|
636
|
+
*
|
|
637
|
+
* Named `providerLabels` rather than `labels` because a widget's own
|
|
638
|
+
* `labels` prop sits alongside this one on the same props type.
|
|
639
|
+
*/
|
|
640
|
+
providerLabels?: Partial<WidgetProviderLabels>;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Which issuing product a card belongs to. A card list shows exactly one
|
|
645
|
+
* program at a time, and the value selects the endpoint the data-access layer
|
|
646
|
+
* calls: `credit` → `/embedded-banking/v1/credit-cards`, `debit` →
|
|
647
|
+
* `/embedded-banking/v1/debit-cards`.
|
|
648
|
+
*
|
|
649
|
+
* Defined here rather than in either widget because `CardsWidget` and
|
|
650
|
+
* `CardDetailsWidget` both publish it as a required public prop. Declared
|
|
651
|
+
* inline in each, the literal would become public API twice with no single
|
|
652
|
+
* definition — and `cards-widget/ui` ↔ `card-details-widget/ui` imports are
|
|
653
|
+
* lint-banned while the reverse feature import would be an Nx cycle, so
|
|
654
|
+
* `shared/feature` is the only home that serves both without duplication.
|
|
655
|
+
*
|
|
656
|
+
* Deliberately **not** the generated `CardTypeEnum` (`credit | debit | prepaid
|
|
657
|
+
* | unknown`), which greps as an exact match for this concept but belongs to
|
|
658
|
+
* the unrelated snake_case third-party schema family (its sibling fields are
|
|
659
|
+
* `card_type`, `last4`, `background_color`) and carries two members neither
|
|
660
|
+
* widget supports. In this codebase "card type" is the DIGITAL/PHYSICAL form
|
|
661
|
+
* factor instead — see `CardType` in `./cardPresentation`.
|
|
662
|
+
*
|
|
663
|
+
* Const-object-plus-type rather than a bare union, mirroring `UIFramework` in
|
|
664
|
+
* `shared/ui` — the other two-member literal that ships as a public prop type.
|
|
665
|
+
*/
|
|
666
|
+
declare const CardProgram: {
|
|
667
|
+
readonly Credit: "credit";
|
|
668
|
+
readonly Debit: "debit";
|
|
669
|
+
};
|
|
670
|
+
type CardProgram = (typeof CardProgram)[keyof typeof CardProgram];
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* A card's lifecycle status, program-agnostic. Aliases the credit union because
|
|
674
|
+
* one of the two has to be the base; the parity assertions below are what keep
|
|
675
|
+
* that choice arbitrary.
|
|
676
|
+
*/
|
|
677
|
+
type CardStatus = CreditCardStatus;
|
|
678
|
+
/**
|
|
679
|
+
* A card's physical form factor — the codebase's meaning of "card type". The
|
|
680
|
+
* credit/debit axis is `CardProgram`, not this.
|
|
681
|
+
*/
|
|
682
|
+
type CardType = CreditCardType;
|
|
683
|
+
|
|
684
|
+
interface BalancesWidgetLabels {
|
|
685
|
+
/** Card header title (e.g. next to the building icon) */
|
|
686
|
+
widgetTitle: string;
|
|
687
|
+
/** Shown under the total amount */
|
|
688
|
+
totalAvailableBalance: string;
|
|
689
|
+
/** Full explanation shown in the info tooltip */
|
|
690
|
+
totalAvailableBalanceTooltip: string;
|
|
691
|
+
/** Short label for the info control (e.g. `aria-label`) */
|
|
692
|
+
totalAvailableBalanceInfoAriaLabel: string;
|
|
693
|
+
/** CTA to open the full accounts list */
|
|
694
|
+
viewAllAccounts: string;
|
|
695
|
+
/** Shown when there are no balances to list */
|
|
696
|
+
noBalancesFound: string;
|
|
697
|
+
/** Shown when the bank account request failed */
|
|
698
|
+
loadErrorTitle: string;
|
|
699
|
+
loadErrorDescription: string;
|
|
700
|
+
/** Label for retry after a failed load */
|
|
701
|
+
loadErrorRetry: string;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
interface BalancesWidgetWithContextProps {
|
|
705
|
+
/**
|
|
706
|
+
* Maximum number of account rows to render in-card. Anything beyond this
|
|
707
|
+
* cap is reachable only via the View-all CTA. Default 5.
|
|
708
|
+
*/
|
|
709
|
+
maxAccounts?: number;
|
|
710
|
+
labels?: Partial<BalancesWidgetLabels>;
|
|
711
|
+
onBalanceRowClick?: (accountId: string) => void;
|
|
712
|
+
onViewAllAccountsClick?: () => void;
|
|
713
|
+
}
|
|
714
|
+
type BalancesWidgetPassthroughProps = Pick<BalancesWidgetWithContextProps, 'maxAccounts' | 'labels' | 'onBalanceRowClick' | 'onViewAllAccountsClick'>;
|
|
715
|
+
interface BalancesWidgetProps extends WidgetProviderProps, BalancesWidgetPassthroughProps {
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
interface Labels$2 {
|
|
719
|
+
bankingTaglinePrefix: string;
|
|
720
|
+
availableBalanceLabel: string;
|
|
721
|
+
availableBalanceTooltip: string;
|
|
722
|
+
accountNumberLabel: string;
|
|
723
|
+
routingNumberLabel: string;
|
|
724
|
+
addAccountButton: string;
|
|
725
|
+
emptyAccountsLabel: string;
|
|
726
|
+
createDialogTitle: string;
|
|
727
|
+
createDialogSubtitle: string;
|
|
728
|
+
createNicknameLabel: string;
|
|
729
|
+
createNicknameRequiredError: string;
|
|
730
|
+
/** Use `{agreementLink}` for the deposit-agreement link placeholder. */
|
|
731
|
+
createLegalTemplate: string;
|
|
732
|
+
/**
|
|
733
|
+
* Rendered instead of {@link Labels.createLegalTemplate} when the host supplies
|
|
734
|
+
* no `depositAgreementUrl`. Must not reference an agreement — see
|
|
735
|
+
* `CreateAccountDialog`.
|
|
736
|
+
*/
|
|
737
|
+
createLegalTemplateWithoutAgreement: string;
|
|
738
|
+
createLegalAgreementLink: string;
|
|
739
|
+
createTeamAccessHeading: string;
|
|
740
|
+
createDialogCloseAriaLabel: string;
|
|
741
|
+
createCancelButton: string;
|
|
742
|
+
createSubmitButton: string;
|
|
743
|
+
teamMembersLoadingLabel: string;
|
|
744
|
+
teamMembersErrorTitle: string;
|
|
745
|
+
teamMembersEmptyLabel: string;
|
|
746
|
+
teamMemberAccessTooltip: string;
|
|
747
|
+
toggleAccountNumberVisibility: string;
|
|
748
|
+
copyAccountNumber: string;
|
|
749
|
+
copyRoutingNumber: string;
|
|
750
|
+
copiedLabel: string;
|
|
751
|
+
openAccountAriaLabel: string;
|
|
752
|
+
loadingLabel: string;
|
|
753
|
+
errorTitle: string;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
interface Labels$1 {
|
|
757
|
+
backToAccounts: string;
|
|
758
|
+
bankingTaglinePrefix: string;
|
|
759
|
+
availableBalanceLabel: string;
|
|
760
|
+
availableBalanceTooltip: string;
|
|
761
|
+
transactionsTab: string;
|
|
762
|
+
statementsTab: string;
|
|
763
|
+
detailsTab: string;
|
|
764
|
+
noTransactionsLabel: string;
|
|
765
|
+
transactionDateColumn: string;
|
|
766
|
+
transactionDescriptionColumn: string;
|
|
767
|
+
transactionAmountColumn: string;
|
|
768
|
+
transactionBalanceColumn: string;
|
|
769
|
+
exportButton: string;
|
|
770
|
+
exportDialogTitle: string;
|
|
771
|
+
exportDialogDescription: string;
|
|
772
|
+
exportDialogCloseAriaLabel: string;
|
|
773
|
+
exportStartDateLabel: string;
|
|
774
|
+
exportEndDateLabel: string;
|
|
775
|
+
exportStartDatePlaceholder: string;
|
|
776
|
+
exportEndDatePlaceholder: string;
|
|
777
|
+
exportCancelButton: string;
|
|
778
|
+
exportDownloadButton: string;
|
|
779
|
+
noStatementsLabel: string;
|
|
780
|
+
editAccountMenuItem: string;
|
|
781
|
+
editDialogTitle: string;
|
|
782
|
+
editNicknameLabel: string;
|
|
783
|
+
editDialogCloseAriaLabel: string;
|
|
784
|
+
editCancelButton: string;
|
|
785
|
+
editSaveButton: string;
|
|
786
|
+
editErrorTitle: string;
|
|
787
|
+
detailsSectionTitle: string;
|
|
788
|
+
receiveMoneySectionTitle: string;
|
|
789
|
+
domesticWireTitle: string;
|
|
790
|
+
domesticWireIntro: string;
|
|
791
|
+
domesticWireNote: string;
|
|
792
|
+
wireDetailsSectionTitle: string;
|
|
793
|
+
bankNameLabel: string;
|
|
794
|
+
bankAddressLabel: string;
|
|
795
|
+
thingsToKnowHeading: string;
|
|
796
|
+
thingsToKnowBody: string;
|
|
797
|
+
supportQuestionsPrefix: string;
|
|
798
|
+
supportTeamLink: string;
|
|
799
|
+
routingNumberLabel: string;
|
|
800
|
+
accountNumberLabel: string;
|
|
801
|
+
copyLabel: string;
|
|
802
|
+
copiedLabel: string;
|
|
803
|
+
toggleAccountNumberVisibility: string;
|
|
804
|
+
loadingLabel: string;
|
|
805
|
+
errorTitle: string;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
interface FeatureLabels$2 {
|
|
809
|
+
accountFallback: string;
|
|
810
|
+
createSuccessToast: string;
|
|
811
|
+
editSuccessToast: string;
|
|
812
|
+
copyAccountNumberToast: string;
|
|
813
|
+
copyRoutingNumberToast: string;
|
|
814
|
+
/** Account-details export toast — forwarded to AccountDetailsWidget. */
|
|
815
|
+
exportLoadingToast: string;
|
|
816
|
+
/** Account-details export toast — forwarded to AccountDetailsWidget. */
|
|
817
|
+
exportSuccessToast: string;
|
|
818
|
+
/** Account-details export toast — forwarded to AccountDetailsWidget. */
|
|
819
|
+
exportErrorToast: string;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
interface BankAccountsWidgetProps extends WidgetProviderProps {
|
|
823
|
+
labels?: Partial<Labels$2>;
|
|
824
|
+
accountDetailsLabels?: Partial<Labels$1>;
|
|
825
|
+
featureLabels?: Partial<FeatureLabels$2>;
|
|
826
|
+
isBankingTaglineVisible?: boolean;
|
|
827
|
+
/**
|
|
828
|
+
* Bank logo for the tagline row. The widget ships no bank artwork of its own —
|
|
829
|
+
* an embeddable library must not depend on a Tesouro-hosted asset a host page's
|
|
830
|
+
* content-security policy can block (PLAT-1179). Omit it and the row renders
|
|
831
|
+
* the bank name alone.
|
|
832
|
+
*/
|
|
833
|
+
bankLogoSrc?: string;
|
|
834
|
+
bankLogoAlt?: string;
|
|
835
|
+
/** Deposit-agreement PDF linked from the create-account legal copy when supplied. */
|
|
836
|
+
depositAgreementUrl?: string;
|
|
837
|
+
/** Bank postal address shown in the account-details domestic wire panel. */
|
|
838
|
+
bankAddress?: string;
|
|
839
|
+
/** Support URL linked from the account-details domestic wire copy. */
|
|
840
|
+
supportTeamUrl?: string;
|
|
841
|
+
'data-testid'?: string;
|
|
842
|
+
/**
|
|
843
|
+
* Controlled selection. Pass `null` to clear, a string to select an account.
|
|
844
|
+
* Leave undefined for uncontrolled behavior (driven by `defaultSelectedAccountId`).
|
|
845
|
+
*/
|
|
846
|
+
selectedAccountId?: string | null;
|
|
847
|
+
/** Initial selected account when uncontrolled. */
|
|
848
|
+
defaultSelectedAccountId?: string | null;
|
|
849
|
+
/** Called when the user opens account details or goes back to the list. */
|
|
850
|
+
onSelectedAccountIdChange?: (accountId: string | null) => void;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* Every key of `T` optional, recursively, so a consumer can override one nested
|
|
855
|
+
* label without restating its siblings. Defined locally because the repo has no
|
|
856
|
+
* shared deep-partial type and does not depend on `type-fest`.
|
|
857
|
+
*/
|
|
858
|
+
type PartialDeep$4<T> = {
|
|
859
|
+
[K in keyof T]?: T[K] extends object ? PartialDeep$4<T[K]> : T[K];
|
|
860
|
+
};
|
|
861
|
+
interface CardsListColumnHeaderLabels {
|
|
862
|
+
cardName: string;
|
|
863
|
+
fundingAccount: string;
|
|
864
|
+
cardholder: string;
|
|
865
|
+
status: string;
|
|
866
|
+
limit: string;
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* Screen-reader-only copy naming the details sheet a row click opens.
|
|
870
|
+
*
|
|
871
|
+
* Both strings are invisible by design: the sheet's visible header belongs to
|
|
872
|
+
* whatever the owner slots into it (`CardDetailsPanel`, via `CardsWidget`), and a
|
|
873
|
+
* second visible title would duplicate it. They exist because the sheet is a
|
|
874
|
+
* dialog, and a dialog without an accessible name is announced as nothing.
|
|
875
|
+
*/
|
|
876
|
+
interface CardsListDetailsSheetLabels {
|
|
877
|
+
/** Accessible name for the sheet. */
|
|
878
|
+
title: string;
|
|
879
|
+
/** Accessible description, announced after the name. */
|
|
880
|
+
description: string;
|
|
881
|
+
}
|
|
882
|
+
/**
|
|
883
|
+
* Every user-facing string the cards list renders, including screen-reader-only
|
|
884
|
+
* copy and the decorative separators.
|
|
885
|
+
*
|
|
886
|
+
* There is intentionally **no** card-type or card-status map here: the row
|
|
887
|
+
* arrives with `typeLabel` and `statusLabel` already resolved, so the
|
|
888
|
+
* `DIGITAL`/`PHYSICAL` and `PENDING_ACTIVATION`/`ACTIVE`/`LOCKED`/`CLOSED` maps
|
|
889
|
+
* live in `shared/feature` keyed on the generated types (EMBD-4404 amendment;
|
|
890
|
+
* see `statusBadge.ts`). That is also where the "label keys carry the code term,
|
|
891
|
+
* values carry the copy" rule applies — `digital`, never `virtual`, so a later
|
|
892
|
+
* wording change is not a breaking rename.
|
|
893
|
+
*/
|
|
894
|
+
interface CardsListLabels {
|
|
895
|
+
title: string;
|
|
896
|
+
/** Accessible name for the list region. */
|
|
897
|
+
regionLabel: string;
|
|
898
|
+
columnHeaders: CardsListColumnHeaderLabels;
|
|
899
|
+
/** Screen-reader name for the unheaded trailing row-actions column. */
|
|
900
|
+
rowActionsColumn: string;
|
|
901
|
+
showMyCardsToggle: string;
|
|
902
|
+
createCardButton: string;
|
|
903
|
+
activateButton: string;
|
|
904
|
+
/** Accessible name for a row's Activate button; the card name is appended. */
|
|
905
|
+
activateButtonForCard: string;
|
|
906
|
+
/** Accessible name for a row's open-details control; card name appended. */
|
|
907
|
+
selectCardButton: string;
|
|
908
|
+
/** Separator between a card's nickname and its last four digits. */
|
|
909
|
+
cardNameSeparator: string;
|
|
910
|
+
/** Stands in for the limit when a card has none set. */
|
|
911
|
+
noLimit: string;
|
|
912
|
+
/** Announced while a page of cards is loading. */
|
|
913
|
+
loadingLabel: string;
|
|
914
|
+
emptyTitle: string;
|
|
915
|
+
emptyDescription: string;
|
|
916
|
+
errorTitle: string;
|
|
917
|
+
errorDescription: string;
|
|
918
|
+
retryButton: string;
|
|
919
|
+
pagination: PaginationFooterLabels;
|
|
920
|
+
/**
|
|
921
|
+
* Copy for the details sheet a row click opens. Rendered by
|
|
922
|
+
* `CardsListDetailsSheet` rather than by the table, but part of this surface
|
|
923
|
+
* because it is one screen and one `labels` prop — the same reason `pagination`
|
|
924
|
+
* sits here for a footer that lives in `shared/ui`.
|
|
925
|
+
*/
|
|
926
|
+
detailsSheet: CardsListDetailsSheetLabels;
|
|
927
|
+
/**
|
|
928
|
+
* Screen-reader copy for the same sheet when Create card is slotted in, rather
|
|
929
|
+
* than a selected card's details. Same chrome, different accessible name.
|
|
930
|
+
*/
|
|
931
|
+
createSheet: CardsListDetailsSheetLabels;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
/** Accessible copy for the panel header's controls. */
|
|
935
|
+
interface CardDetailsHeaderLabels {
|
|
936
|
+
/** Fallback title when the card has no nickname. */
|
|
937
|
+
untitledCard: string;
|
|
938
|
+
/** Accessible name for the kebab that opens the card actions menu. */
|
|
939
|
+
menuTriggerAriaLabel: string;
|
|
940
|
+
/** Accessible name for the close (X) control. */
|
|
941
|
+
closeAriaLabel: string;
|
|
942
|
+
}
|
|
943
|
+
/** Accessible copy for the simplified card face. */
|
|
944
|
+
interface CardDetailsCardFaceLabels {
|
|
945
|
+
/** Alt text for the bank logo when the caller supplies no `bankLogoAlt`. */
|
|
946
|
+
bankLogoAlt: string;
|
|
947
|
+
}
|
|
948
|
+
/** Row headings and per-row copy affordance names for the details table. */
|
|
949
|
+
interface CardDetailsFieldLabels {
|
|
950
|
+
cardholder: string;
|
|
951
|
+
nickname: string;
|
|
952
|
+
billingAddress: string;
|
|
953
|
+
/** Sub-header over the merchant categories / velocity control rows. */
|
|
954
|
+
cardControlsHeading: string;
|
|
955
|
+
allowedCategories: string;
|
|
956
|
+
spendLimit: string;
|
|
957
|
+
perTransactionMax: string;
|
|
958
|
+
/** Stands in for a row whose value the card does not carry. */
|
|
959
|
+
emptyValue: string;
|
|
960
|
+
copyCardholderAriaLabel: string;
|
|
961
|
+
copyNicknameAriaLabel: string;
|
|
962
|
+
copyBillingAddressAriaLabel: string;
|
|
963
|
+
}
|
|
964
|
+
/** Copy for the controls the owner can switch on alongside the details. */
|
|
965
|
+
interface CardDetailsActionLabels {
|
|
966
|
+
/** Primary control that opens the Activate Card form. */
|
|
967
|
+
activateCard: string;
|
|
968
|
+
/** Secondary control that asks the owner to reveal the card's credentials. */
|
|
969
|
+
viewCard: string;
|
|
970
|
+
/** The same control, once the credentials are on screen. */
|
|
971
|
+
hideCard: string;
|
|
972
|
+
}
|
|
973
|
+
/**
|
|
974
|
+
* Copy for the revealed card credentials. The values themselves never have a
|
|
975
|
+
* default here — the panel is handed them or renders the field blank.
|
|
976
|
+
*/
|
|
977
|
+
interface CardDetailsCredentialsLabels {
|
|
978
|
+
cardNumber: string;
|
|
979
|
+
expirationDate: string;
|
|
980
|
+
securityCode: string;
|
|
981
|
+
copyCardNumberAriaLabel: string;
|
|
982
|
+
copyExpirationDateAriaLabel: string;
|
|
983
|
+
copySecurityCodeAriaLabel: string;
|
|
984
|
+
/** Shown next to the control when the reveal failed. */
|
|
985
|
+
errorDescription: string;
|
|
986
|
+
}
|
|
987
|
+
/** Copy for the three non-loaded screens. */
|
|
988
|
+
interface CardDetailsStatusScreenLabels {
|
|
989
|
+
/** Accessible name announced while the panel is loading. */
|
|
990
|
+
loadingAriaLabel: string;
|
|
991
|
+
errorTitle: string;
|
|
992
|
+
errorDescription: string;
|
|
993
|
+
errorRetry: string;
|
|
994
|
+
notFoundTitle: string;
|
|
995
|
+
notFoundDescription: string;
|
|
996
|
+
}
|
|
997
|
+
interface CardDetailsPanelLabels {
|
|
998
|
+
header: CardDetailsHeaderLabels;
|
|
999
|
+
cardFace: CardDetailsCardFaceLabels;
|
|
1000
|
+
fields: CardDetailsFieldLabels;
|
|
1001
|
+
actions: CardDetailsActionLabels;
|
|
1002
|
+
credentials: CardDetailsCredentialsLabels;
|
|
1003
|
+
status: CardDetailsStatusScreenLabels;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* Deep partial for label overrides.
|
|
1008
|
+
*
|
|
1009
|
+
* Both label surfaces this widget exposes have nested groups, and a shallow
|
|
1010
|
+
* `Partial` would let a consumer who overrides one nested string drop the rest
|
|
1011
|
+
* of that group. The repo has no shared `PartialDeep` and does not depend on
|
|
1012
|
+
* `type-fest`, so each labels module defines its own — `card-details-widget/ui`
|
|
1013
|
+
* has an identical one for the panel's labels, and this declaration also types
|
|
1014
|
+
* that prop here so the widget carries one such helper rather than two.
|
|
1015
|
+
*/
|
|
1016
|
+
type PartialDeep$3<T> = {
|
|
1017
|
+
[K in keyof T]?: T[K] extends object ? PartialDeep$3<T[K]> : T[K];
|
|
1018
|
+
};
|
|
1019
|
+
/**
|
|
1020
|
+
* Copy the **feature** layer owns, as opposed to the panel's own
|
|
1021
|
+
* `CardDetailsPanelLabels`.
|
|
1022
|
+
*
|
|
1023
|
+
* The split follows where the string is resolved, not where it is painted. A
|
|
1024
|
+
* status badge word is chosen by mapping a generated `cardStatus` enum member,
|
|
1025
|
+
* which is a data-access-typed decision the presentational layer is not allowed
|
|
1026
|
+
* to make — so it is overridable here even though the panel renders it. The
|
|
1027
|
+
* panel's own labels stay with the panel.
|
|
1028
|
+
*/
|
|
1029
|
+
interface CardDetailsFeatureLabels {
|
|
1030
|
+
/** Confirmation toast after a copy affordance writes to the clipboard. */
|
|
1031
|
+
copySuccessToast: string;
|
|
1032
|
+
/**
|
|
1033
|
+
* Replaces the panel's generic reveal error when the credentials call was
|
|
1034
|
+
* refused (HTTP 403).
|
|
1035
|
+
*
|
|
1036
|
+
* It lives here rather than on the panel because deciding that a failure was a
|
|
1037
|
+
* refusal means reading the error, which is this layer's job — the panel is
|
|
1038
|
+
* handed one already-chosen sentence either way, and its own
|
|
1039
|
+
* `credentials.errorDescription` still covers every other failure.
|
|
1040
|
+
*
|
|
1041
|
+
* The wording deliberately does not tell the reader to ask for a permission.
|
|
1042
|
+
* Reading a debit card and reading its credentials take the same scope, so a
|
|
1043
|
+
* reader looking at this panel already holds it; a 403 here means the call was
|
|
1044
|
+
* refused for this session, which asking an admin for a role will not fix.
|
|
1045
|
+
*/
|
|
1046
|
+
revealNotPermittedDescription: string;
|
|
1047
|
+
/** Program wording on the card face, keyed on the widget's `cardProgram`. */
|
|
1048
|
+
programLabels: Record<CardProgram, string>;
|
|
1049
|
+
/** Status badge wording, keyed on the generated card status. */
|
|
1050
|
+
statusLabels: Record<CardStatus, string>;
|
|
1051
|
+
/** Form-factor subtitle wording, keyed on the generated card type. */
|
|
1052
|
+
formFactorLabels: Record<CardType, string>;
|
|
1053
|
+
/**
|
|
1054
|
+
* A velocity control's reset-period wording, keyed on the generated
|
|
1055
|
+
* `velocityWindow`. Used to build the spend limit row, e.g. "$500 / month".
|
|
1056
|
+
* `TRANSACTION` is unused there (it drives the separate per-transaction max
|
|
1057
|
+
* row instead) but is still a real enum member, so it stays in the map.
|
|
1058
|
+
*/
|
|
1059
|
+
velocityWindowLabels: Record<VelocityWindow, string>;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
interface CardDetailsWidgetProps extends WidgetProviderProps {
|
|
1063
|
+
/** Id of the card to show. */
|
|
1064
|
+
cardId: string;
|
|
1065
|
+
/**
|
|
1066
|
+
* Which issuing product `cardId` belongs to. **Required, with no default** —
|
|
1067
|
+
* it selects the endpoint the card is fetched from, and a wrong guess would
|
|
1068
|
+
* 404 a card that exists. `CardsWidget` publishes the same required prop, so
|
|
1069
|
+
* one value configures a list and its detail panel together.
|
|
1070
|
+
*
|
|
1071
|
+
* A JavaScript consumer, or a host passing a route param straight through, can
|
|
1072
|
+
* still get a value past the type. **There is no catch-all and no default:**
|
|
1073
|
+
* anything that is not explicitly one of the two programs fetches nothing and
|
|
1074
|
+
* renders the panel's error state with no retry, and the reason is named on the
|
|
1075
|
+
* console. That covers an absent prop (`undefined` / `null`) as well as an
|
|
1076
|
+
* unrecognised one (`'prepaid'`, a case-wrong `'Credit'`), because the widget
|
|
1077
|
+
* cannot know which product to ask about in either case.
|
|
1078
|
+
*
|
|
1079
|
+
* A host that resolves the program asynchronously should gate its own render on
|
|
1080
|
+
* it rather than mounting this widget without it — an absent program is not
|
|
1081
|
+
* read as "still loading".
|
|
1082
|
+
*/
|
|
1083
|
+
cardProgram: CardProgram;
|
|
1084
|
+
/**
|
|
1085
|
+
* Called when the header's close control is pressed. Omitting it renders no
|
|
1086
|
+
* close control at all: a standalone card page has nothing to close back to,
|
|
1087
|
+
* while a host rendering the panel in a drawer supplies this and suppresses
|
|
1088
|
+
* its own chrome's close button so the two do not sit side by side.
|
|
1089
|
+
*/
|
|
1090
|
+
onClose?: () => void;
|
|
1091
|
+
/** Overrides for the panel's own copy. */
|
|
1092
|
+
labels?: PartialDeep$3<CardDetailsPanelLabels>;
|
|
1093
|
+
/** Overrides for the copy this layer resolves — see `CardDetailsFeatureLabels`. */
|
|
1094
|
+
featureLabels?: PartialDeep$3<CardDetailsFeatureLabels>;
|
|
1095
|
+
/**
|
|
1096
|
+
* Bank logo for the card face. The widget ships no bank artwork of its own and
|
|
1097
|
+
* resolves none from the init response: an embeddable library must not depend
|
|
1098
|
+
* on a Tesouro-hosted asset a host page's content-security policy can block,
|
|
1099
|
+
* and a bundled bank-name→URL table would put internal CDN links in the
|
|
1100
|
+
* published package (PLAT-1179, embedded ADR 0005). Omit it and the card face
|
|
1101
|
+
* renders without a logo rather than with a placeholder.
|
|
1102
|
+
*/
|
|
1103
|
+
bankLogoSrc?: string;
|
|
1104
|
+
bankLogoAlt?: string;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
* Reset-period tab labels and notice copy are deliberately absent: the owner
|
|
1109
|
+
* supplies those through `spendLimitPeriodOptions` / `spendLimitPeriodNotices`,
|
|
1110
|
+
* so declaring them here would give consumers override keys that no component
|
|
1111
|
+
* ever reads.
|
|
1112
|
+
*/
|
|
1113
|
+
interface CardControlsLabels {
|
|
1114
|
+
currencySymbol: string;
|
|
1115
|
+
spendLimit: {
|
|
1116
|
+
title: string;
|
|
1117
|
+
description: string;
|
|
1118
|
+
amountPlaceholder: string;
|
|
1119
|
+
amountAriaLabel: string;
|
|
1120
|
+
};
|
|
1121
|
+
merchantCategories: {
|
|
1122
|
+
title: string;
|
|
1123
|
+
description: string;
|
|
1124
|
+
};
|
|
1125
|
+
perTransactionMaximum: {
|
|
1126
|
+
title: string;
|
|
1127
|
+
description: string;
|
|
1128
|
+
amountPlaceholder: string;
|
|
1129
|
+
amountAriaLabel: string;
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
type PartialDeep$2<T> = {
|
|
1134
|
+
[K in keyof T]?: T[K] extends object ? PartialDeep$2<T[K]> : T[K];
|
|
1135
|
+
};
|
|
1136
|
+
interface CreateCardWidgetLabels {
|
|
1137
|
+
header: {
|
|
1138
|
+
title: string;
|
|
1139
|
+
closeAriaLabel: string;
|
|
1140
|
+
};
|
|
1141
|
+
cardArtAlt: string;
|
|
1142
|
+
setup: {
|
|
1143
|
+
sectionTitle: string;
|
|
1144
|
+
cardholderLabel: string;
|
|
1145
|
+
cardholderPlaceholder: string;
|
|
1146
|
+
cardFormatLabel: string;
|
|
1147
|
+
cardFormatPlaceholder: string;
|
|
1148
|
+
cardFormatVirtual: string;
|
|
1149
|
+
cardFormatPhysical: string;
|
|
1150
|
+
fundingAccountLabel: string;
|
|
1151
|
+
fundingAccountPlaceholder: string;
|
|
1152
|
+
};
|
|
1153
|
+
mailing: {
|
|
1154
|
+
sectionTitle: string;
|
|
1155
|
+
sectionDescription: string;
|
|
1156
|
+
businessTitle: string;
|
|
1157
|
+
businessDescription: string;
|
|
1158
|
+
customTitle: string;
|
|
1159
|
+
customDescription: string;
|
|
1160
|
+
};
|
|
1161
|
+
manualAddress: {
|
|
1162
|
+
streetLabel: string;
|
|
1163
|
+
cityLabel: string;
|
|
1164
|
+
stateLabel: string;
|
|
1165
|
+
statePlaceholder: string;
|
|
1166
|
+
zipLabel: string;
|
|
1167
|
+
};
|
|
1168
|
+
cardControls: CardControlsLabels;
|
|
1169
|
+
preparing: {
|
|
1170
|
+
title: string;
|
|
1171
|
+
description: string;
|
|
1172
|
+
};
|
|
1173
|
+
success: {
|
|
1174
|
+
title: string;
|
|
1175
|
+
description: string;
|
|
1176
|
+
createAnother: string;
|
|
1177
|
+
viewCard: string;
|
|
1178
|
+
};
|
|
1179
|
+
footer: {
|
|
1180
|
+
cancel: string;
|
|
1181
|
+
createCard: string;
|
|
1182
|
+
};
|
|
1183
|
+
cardholderError: {
|
|
1184
|
+
title: string;
|
|
1185
|
+
description: string;
|
|
1186
|
+
retry: string;
|
|
1187
|
+
};
|
|
1188
|
+
fundingAccountError: {
|
|
1189
|
+
title: string;
|
|
1190
|
+
description: string;
|
|
1191
|
+
retry: string;
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
interface CreateCardFeatureLabels {
|
|
1196
|
+
toast: {
|
|
1197
|
+
creating: string;
|
|
1198
|
+
success: string;
|
|
1199
|
+
error: string;
|
|
1200
|
+
/**
|
|
1201
|
+
* Card issued but a follow-up velocity-control POST failed. The card
|
|
1202
|
+
* already exists; this must not read as a create failure.
|
|
1203
|
+
*/
|
|
1204
|
+
controlsWarning: string;
|
|
1205
|
+
/**
|
|
1206
|
+
* Card issued but granting company admins access to it failed. The card
|
|
1207
|
+
* already exists; this must not read as a create failure.
|
|
1208
|
+
*/
|
|
1209
|
+
companyAdminAccessWarning: string;
|
|
1210
|
+
/**
|
|
1211
|
+
* Card issued, but BOTH the velocity-control POST(s) and the company-admin
|
|
1212
|
+
* access grant failed. Distinct from the two single-failure warnings above
|
|
1213
|
+
* so an issuer who hits both is told about both, not just whichever this
|
|
1214
|
+
* code checks first.
|
|
1215
|
+
*/
|
|
1216
|
+
controlsAndAccessWarning: string;
|
|
1217
|
+
/**
|
|
1218
|
+
* The roster of users to grant access to a new card failed to load.
|
|
1219
|
+
* Shown with a retry action; Create stays disabled until it resolves so
|
|
1220
|
+
* a card is never issued without its required admin grants.
|
|
1221
|
+
*/
|
|
1222
|
+
debitCardIssuersError: string;
|
|
1223
|
+
retry: string;
|
|
1224
|
+
};
|
|
1225
|
+
untitledFundingAccount: string;
|
|
1226
|
+
/**
|
|
1227
|
+
* API-required `name` on a velocity control. Not shown in this widget;
|
|
1228
|
+
* may surface on a later controls list.
|
|
1229
|
+
*/
|
|
1230
|
+
velocityControlNames: {
|
|
1231
|
+
spendLimit: string;
|
|
1232
|
+
perTransactionMaximum: string;
|
|
1233
|
+
};
|
|
1234
|
+
/**
|
|
1235
|
+
* Spend-limit reset-period tab labels and notices. Owned here (not UI
|
|
1236
|
+
* labels) because the feature layer decides what each opaque period value
|
|
1237
|
+
* means.
|
|
1238
|
+
*/
|
|
1239
|
+
spendLimit: {
|
|
1240
|
+
periodOneTime: string;
|
|
1241
|
+
periodDaily: string;
|
|
1242
|
+
periodMonthly: string;
|
|
1243
|
+
oneTimeWarningTitle: string;
|
|
1244
|
+
oneTimeWarningDescription: string;
|
|
1245
|
+
dailyResetNotice: string;
|
|
1246
|
+
monthlyResetNotice: string;
|
|
1247
|
+
};
|
|
1248
|
+
/**
|
|
1249
|
+
* Success-screen copy chosen from the create response's `cardStatus`.
|
|
1250
|
+
* Active/ready wording lives on the UI defaults; these cover statuses that
|
|
1251
|
+
* must not claim the card is already usable.
|
|
1252
|
+
*/
|
|
1253
|
+
success: {
|
|
1254
|
+
pendingActivationTitle: string;
|
|
1255
|
+
pendingActivationDescription: string;
|
|
1256
|
+
createdTitle: string;
|
|
1257
|
+
createdDescription: string;
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
type CreateCardWidgetProps = WidgetProviderProps & {
|
|
1262
|
+
/** Static card plastic image URL (no overlays). Host / white-label supplied. */
|
|
1263
|
+
cardArtSrc: string;
|
|
1264
|
+
labels?: PartialDeep$2<CreateCardWidgetLabels>;
|
|
1265
|
+
featureLabels?: Partial<{
|
|
1266
|
+
toast: Partial<CreateCardFeatureLabels['toast']>;
|
|
1267
|
+
untitledFundingAccount: string;
|
|
1268
|
+
velocityControlNames: Partial<CreateCardFeatureLabels['velocityControlNames']>;
|
|
1269
|
+
spendLimit: Partial<CreateCardFeatureLabels['spendLimit']>;
|
|
1270
|
+
success: Partial<CreateCardFeatureLabels['success']>;
|
|
1271
|
+
}>;
|
|
1272
|
+
className?: string;
|
|
1273
|
+
onClose?: () => void;
|
|
1274
|
+
onCancel?: () => void;
|
|
1275
|
+
/** Fired with the new debit card id after a successful create. */
|
|
1276
|
+
onViewCard?: (cardId: string) => void;
|
|
1277
|
+
};
|
|
1278
|
+
|
|
1279
|
+
/**
|
|
1280
|
+
* Every key of `T` optional, recursively, so a consumer can override one nested
|
|
1281
|
+
* label without restating its siblings. Defined locally because the repo has no
|
|
1282
|
+
* shared deep-partial type and does not depend on `type-fest` — same helper the
|
|
1283
|
+
* two card `ui` libs declare.
|
|
1284
|
+
*/
|
|
1285
|
+
type PartialDeep$1<T> = {
|
|
1286
|
+
[K in keyof T]?: T[K] extends object ? PartialDeep$1<T[K]> : T[K];
|
|
1287
|
+
};
|
|
1288
|
+
/**
|
|
1289
|
+
* Strings this layer produces rather than passes through.
|
|
1290
|
+
*
|
|
1291
|
+
* They are separate from `CardsListLabels` (the `ui` lib's) because the cells
|
|
1292
|
+
* reaching that library are already formatted: the em-dash, the nickname
|
|
1293
|
+
* fallback and the "Viewing" prefix are all written *here*, so the UI lib has
|
|
1294
|
+
* no key to override them with. `bank-accounts-widget`'s `featureLabels` is the
|
|
1295
|
+
* precedent for the split.
|
|
1296
|
+
*
|
|
1297
|
+
* The status and form-factor maps live here for the same reason. EMBD-4503's
|
|
1298
|
+
* amendment put them in `shared/feature` keyed on the generated unions, and the
|
|
1299
|
+
* row arrives with `statusLabel` / `typeLabel` resolved — so this is the only
|
|
1300
|
+
* layer a consumer could reach them through.
|
|
1301
|
+
*/
|
|
1302
|
+
interface CardsFeatureLabels {
|
|
1303
|
+
/**
|
|
1304
|
+
* Stands in for a cell the card program carries no value for — credit has no
|
|
1305
|
+
* funding account, and a debit card's funding account is unresolvable without
|
|
1306
|
+
* the bank-account read scope.
|
|
1307
|
+
*/
|
|
1308
|
+
emptyValue: string;
|
|
1309
|
+
/** Name shown for a card with no nickname set. */
|
|
1310
|
+
untitledCard: string;
|
|
1311
|
+
/**
|
|
1312
|
+
* Last-resort name for a funding account with neither a nickname nor an
|
|
1313
|
+
* account number to mask. An account with no nickname shows `••••1234`
|
|
1314
|
+
* instead, so that two unnamed accounts stay distinguishable — this is only
|
|
1315
|
+
* for the case where there is nothing at all to show.
|
|
1316
|
+
*/
|
|
1317
|
+
untitledFundingAccount: string;
|
|
1318
|
+
/** Display copy per card lifecycle status; keys are the generated code terms. */
|
|
1319
|
+
cardStatus: Record<CardStatus, string>;
|
|
1320
|
+
/** Display copy per card form factor; keys are the generated code terms. */
|
|
1321
|
+
cardType: Record<CardType, string>;
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
interface CardsWidgetPagination {
|
|
1325
|
+
/** Cursor for the page on screen. Omit for the first page. */
|
|
1326
|
+
paginationToken?: string;
|
|
1327
|
+
/** Number of rows requested per page. */
|
|
1328
|
+
pageSize: number;
|
|
1329
|
+
}
|
|
1330
|
+
interface CardsWidgetPaginationInput {
|
|
1331
|
+
paginationToken?: string;
|
|
1332
|
+
pageSize?: number;
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
interface CardsWidgetProps extends WidgetProviderProps {
|
|
1336
|
+
/**
|
|
1337
|
+
* Which issuing program the list shows — `'credit'` or `'debit'`.
|
|
1338
|
+
*
|
|
1339
|
+
* **Required, with no default.** A cards list shows exactly one program, and
|
|
1340
|
+
* the value selects the endpoint that is read as well as which scopes gate the
|
|
1341
|
+
* affordances. Defaulting it would make the choice invisible at the call site
|
|
1342
|
+
* and would silently pick a program for a host that meant the other one.
|
|
1343
|
+
*/
|
|
1344
|
+
cardProgram: CardProgram;
|
|
1345
|
+
/**
|
|
1346
|
+
* Controlled cursor/page-size metadata. Supply with `onPaginationChange` when
|
|
1347
|
+
* a host owns the list position, e.g. URL-backed pagination.
|
|
1348
|
+
*/
|
|
1349
|
+
pagination?: CardsWidgetPaginationInput;
|
|
1350
|
+
/**
|
|
1351
|
+
* Initial cursor/page-size metadata for uncontrolled usage. Omit for first
|
|
1352
|
+
* page with the default page size. Ignored when `pagination` is supplied.
|
|
1353
|
+
*/
|
|
1354
|
+
defaultPagination?: CardsWidgetPaginationInput;
|
|
1355
|
+
/**
|
|
1356
|
+
* Called whenever the widget changes its cursor/page-size pair through pagination
|
|
1357
|
+
* controls or a cursor-invalidating reset such as page-size changes. Hosts that
|
|
1358
|
+
* persist list position should store this whole object, not the token alone.
|
|
1359
|
+
*/
|
|
1360
|
+
onPaginationChange?: (pagination: CardsWidgetPagination) => void;
|
|
1361
|
+
/**
|
|
1362
|
+
* Overrides for the list's own copy, merged per nested group. Typed with the
|
|
1363
|
+
* `ui` lib's own deep-partial helper (each labels module declares one — the
|
|
1364
|
+
* repo has no shared version) so this prop follows that library's contract.
|
|
1365
|
+
*/
|
|
1366
|
+
labels?: PartialDeep$4<CardsListLabels>;
|
|
1367
|
+
/**
|
|
1368
|
+
* Overrides for the copy this layer produces rather than passes through — the
|
|
1369
|
+
* status and form-factor vocabulary, the empty-cell placeholder, the nickname
|
|
1370
|
+
* fallbacks, and the pagination range prefix. Separate from `labels` because
|
|
1371
|
+
* the list library receives those values already formatted and so has no key
|
|
1372
|
+
* for them; `BankAccountsWidget.featureLabels` is the same split.
|
|
1373
|
+
*/
|
|
1374
|
+
featureLabels?: PartialDeep$1<CardsFeatureLabels>;
|
|
1375
|
+
/**
|
|
1376
|
+
* The card whose details panel is open. Supply with `onSelectedCardIdChange`
|
|
1377
|
+
* when the host owns that state — a deep-linked `/cards/[id]`, say. `null`
|
|
1378
|
+
* closes the panel; omit the prop for uncontrolled behaviour.
|
|
1379
|
+
*
|
|
1380
|
+
* Pinning it to `null` and navigating from `onSelectedCardIdChange` is how a
|
|
1381
|
+
* host suppresses the built-in panel entirely and owns navigation itself: the
|
|
1382
|
+
* click is still reported, and because the value never comes back non-null,
|
|
1383
|
+
* nothing ever opens.
|
|
1384
|
+
*/
|
|
1385
|
+
selectedCardId?: string | null;
|
|
1386
|
+
/** Initial selection when uncontrolled. Ignored when `selectedCardId` is supplied. */
|
|
1387
|
+
defaultSelectedCardId?: string | null;
|
|
1388
|
+
/**
|
|
1389
|
+
* Called whenever the open card changes, including on close (`null`).
|
|
1390
|
+
*
|
|
1391
|
+
* Supplying it does **not** change what renders — a host can observe row clicks
|
|
1392
|
+
* for analytics, or mirror the selection into a query param, and still get the
|
|
1393
|
+
* built-in panel. (The removed `onCardSelect` could not: its presence
|
|
1394
|
+
* suppressed the panel, so those two intents were unexpressible together.)
|
|
1395
|
+
*/
|
|
1396
|
+
onSelectedCardIdChange?: (cardId: string | null) => void;
|
|
1397
|
+
/**
|
|
1398
|
+
* Label overrides forwarded into the nested card details panel, mirroring
|
|
1399
|
+
* `BankAccountsWidgetProps.accountDetailsLabels`.
|
|
1400
|
+
*
|
|
1401
|
+
* Derived from the receiving prop rather than restated, so the forwarded and
|
|
1402
|
+
* received types cannot drift. Naming the panel's labels type directly is not
|
|
1403
|
+
* an option anyway: a cross-widget `type:ui` import is banned by
|
|
1404
|
+
* `EMBEDDED_DEP_CONSTRAINTS`, and this indexed access reaches it through the
|
|
1405
|
+
* sanctioned feature → feature edge without re-exporting anything. It already
|
|
1406
|
+
* carries `card-details-widget`'s own deep partial, so no wrapper here.
|
|
1407
|
+
*/
|
|
1408
|
+
cardDetailsLabels?: CardDetailsWidgetProps['labels'];
|
|
1409
|
+
/**
|
|
1410
|
+
* Overrides for the copy the panel's *feature* layer resolves — its status
|
|
1411
|
+
* vocabulary, form-factor wording, program label and copy-success toast.
|
|
1412
|
+
*
|
|
1413
|
+
* Distinct from `featureLabels`, which covers the list's own vocabulary.
|
|
1414
|
+
* Without this prop the panel is unreachable for that copy, so a host that
|
|
1415
|
+
* renames a status in the list would still read the default inside the panel.
|
|
1416
|
+
*/
|
|
1417
|
+
cardDetailsFeatureLabels?: CardDetailsWidgetProps['featureLabels'];
|
|
1418
|
+
/**
|
|
1419
|
+
* Bank logo for the details panel's card face. Forwarded verbatim; the panel
|
|
1420
|
+
* renders no logo without it, so omitting these leaves the built-in sheet
|
|
1421
|
+
* showing a logo-less card rather than a placeholder.
|
|
1422
|
+
*
|
|
1423
|
+
* These stay props because the package ships no bank artwork and resolves none
|
|
1424
|
+
* from the init response (PLAT-1179, embedded ADR 0005).
|
|
1425
|
+
*/
|
|
1426
|
+
bankLogoSrc?: string;
|
|
1427
|
+
bankLogoAlt?: string;
|
|
1428
|
+
/**
|
|
1429
|
+
* Plastic art for the built-in debit create sheet. Forwarded verbatim into
|
|
1430
|
+
* nested `CreateCardWidget`. Required for that sheet: omitting it (with no
|
|
1431
|
+
* host `onCreateCard`) hides Create card rather than opening a panel that
|
|
1432
|
+
* cannot render. Same PLAT-1179 / ADR 0005 rule as `bankLogoSrc` — the package
|
|
1433
|
+
* ships no card artwork.
|
|
1434
|
+
*/
|
|
1435
|
+
cardArtSrc?: string;
|
|
1436
|
+
/**
|
|
1437
|
+
* Label overrides forwarded into the nested create-card panel. Indexed off
|
|
1438
|
+
* `CreateCardWidgetProps` so the forwarded and received types cannot drift,
|
|
1439
|
+
* the same feature → feature edge as `cardDetailsLabels`.
|
|
1440
|
+
*/
|
|
1441
|
+
createCardLabels?: CreateCardWidgetProps['labels'];
|
|
1442
|
+
/**
|
|
1443
|
+
* Overrides for the copy the create panel's *feature* layer resolves — mutation
|
|
1444
|
+
* toasts, the untitled funding-account fallback, and pending-activation success
|
|
1445
|
+
* copy.
|
|
1446
|
+
*/
|
|
1447
|
+
createCardFeatureLabels?: CreateCardWidgetProps['featureLabels'];
|
|
1448
|
+
/**
|
|
1449
|
+
* Called when Create card is clicked. When supplied, the host owns the
|
|
1450
|
+
* gesture: the built-in debit sheet does **not** open. Omit it on a debit list
|
|
1451
|
+
* with `cardArtSrc` to use the built-in `CreateCardWidget` sheet. Credit has
|
|
1452
|
+
* no in-package issuance widget, so credit Create card still requires this
|
|
1453
|
+
* callback — omitting it hides the button rather than offering a control that
|
|
1454
|
+
* does nothing.
|
|
1455
|
+
*/
|
|
1456
|
+
onCreateCard?: () => void;
|
|
1457
|
+
/**
|
|
1458
|
+
* Called with the card's id when a row's Activate button is clicked. The button
|
|
1459
|
+
* renders only on cards in `PENDING_ACTIVATION`, and only when the widget token
|
|
1460
|
+
* also holds the program's activate scope.
|
|
1461
|
+
*
|
|
1462
|
+
* Host-owned for the same reason as `onCreateCard`: EMBD-4398 designs no
|
|
1463
|
+
* activation flow, and `POST /debit-cards/{id}/activate` does not exist even
|
|
1464
|
+
* though `debit_card:activate:org` does — so a built-in flow could serve only
|
|
1465
|
+
* one of the two programs.
|
|
1466
|
+
*/
|
|
1467
|
+
onActivateCard?: (cardId: string) => void;
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
interface InsightsWidgetLabels {
|
|
1471
|
+
widgetTitle: string;
|
|
1472
|
+
activeTab: string;
|
|
1473
|
+
dismissedTab: string;
|
|
1474
|
+
noInsightsFound: string;
|
|
1475
|
+
loadErrorTitle: string;
|
|
1476
|
+
loadErrorDescription: string;
|
|
1477
|
+
loadErrorRetry: string;
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
/**
|
|
1481
|
+
* Presentational model for one insight row — screen-shaped only (no domain ids or types).
|
|
1482
|
+
*/
|
|
1483
|
+
interface InsightRowView {
|
|
1484
|
+
displayText: string;
|
|
1485
|
+
createdDate: string;
|
|
1486
|
+
badgeLabel: string;
|
|
1487
|
+
badgeIcon: ReactElement;
|
|
1488
|
+
showDismissButton: boolean;
|
|
1489
|
+
showToggle: boolean;
|
|
1490
|
+
toggleLabel?: string;
|
|
1491
|
+
/** Required when `onToggle` is set — owner-controlled switch state. */
|
|
1492
|
+
toggleChecked?: boolean;
|
|
1493
|
+
onToggle?: (checked: boolean) => void;
|
|
1494
|
+
navigationLinkText?: string;
|
|
1495
|
+
onNavigationClick?: () => void;
|
|
1496
|
+
actionText?: string;
|
|
1497
|
+
onActionClick?: () => void;
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
interface SingleInsightLabels {
|
|
1501
|
+
dismissInsightAriaLabel: string;
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
interface InsightsFeatureLabels {
|
|
1505
|
+
onboardingBadgeLabel: string;
|
|
1506
|
+
routingOnboardingText: string;
|
|
1507
|
+
enableRoutingToggle: string;
|
|
1508
|
+
createAccountText: string;
|
|
1509
|
+
connectExternalText: string;
|
|
1510
|
+
linkAccountAction: string;
|
|
1511
|
+
verifyExternalAccountText: (nickname: string) => string;
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
/** Domain model for one generated insight — stays in the feature layer only. */
|
|
1515
|
+
interface InsightItem {
|
|
1516
|
+
id: string;
|
|
1517
|
+
isDismissed: boolean;
|
|
1518
|
+
showToggle: boolean;
|
|
1519
|
+
canDismiss: boolean;
|
|
1520
|
+
displayText: string;
|
|
1521
|
+
toggleLabel?: string;
|
|
1522
|
+
toggleChecked?: boolean;
|
|
1523
|
+
onToggle?: (checked: boolean) => void;
|
|
1524
|
+
actionText?: string;
|
|
1525
|
+
onActionClick?: () => void;
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
declare function mapInsightToRowView(insight: InsightItem, labels: InsightsFeatureLabels, createdDate: string): InsightRowView;
|
|
1529
|
+
|
|
1530
|
+
interface SingleInsightProps {
|
|
1531
|
+
insight: InsightItem;
|
|
1532
|
+
createdDate: string;
|
|
1533
|
+
featureLabels: Parameters<typeof mapInsightToRowView>[1];
|
|
1534
|
+
onDismissClick: (id: string) => void;
|
|
1535
|
+
labels?: Partial<SingleInsightLabels>;
|
|
1536
|
+
}
|
|
1537
|
+
declare const SingleInsight: ({ insight, createdDate, featureLabels, onDismissClick, labels, }: SingleInsightProps) => React.JSX.Element;
|
|
1538
|
+
|
|
1539
|
+
interface InsightsWidgetInternalProps {
|
|
1540
|
+
labels?: Partial<InsightsWidgetLabels>;
|
|
1541
|
+
singleInsightLabels?: Parameters<typeof SingleInsight>[0]['labels'];
|
|
1542
|
+
}
|
|
1543
|
+
interface InsightsWidgetWithContextProps {
|
|
1544
|
+
labels?: Partial<InsightsWidgetLabels>;
|
|
1545
|
+
singleInsightLabels?: InsightsWidgetInternalProps['singleInsightLabels'];
|
|
1546
|
+
featureLabels?: Partial<InsightsFeatureLabels>;
|
|
1547
|
+
routingEnabled?: boolean;
|
|
1548
|
+
onRoutingToggleChange?: (enabled: boolean) => void;
|
|
1549
|
+
onLinkExternalAccountClick?: () => void;
|
|
1550
|
+
}
|
|
1551
|
+
type InsightsWidgetPassthroughProps = Pick<InsightsWidgetWithContextProps, 'labels' | 'singleInsightLabels' | 'featureLabels' | 'routingEnabled' | 'onRoutingToggleChange' | 'onLinkExternalAccountClick'>;
|
|
1552
|
+
interface InsightsWidgetProps extends WidgetProviderProps, InsightsWidgetPassthroughProps {
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
interface Labels {
|
|
1556
|
+
description?: string;
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
interface SettingsWidgetSection {
|
|
1560
|
+
id: string;
|
|
1561
|
+
label: string;
|
|
1562
|
+
content: ReactNode;
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
interface FinopsThemeColors {
|
|
1566
|
+
primary?: string;
|
|
1567
|
+
primaryForeground?: string;
|
|
1568
|
+
}
|
|
1569
|
+
interface MoniteWrapperProps {
|
|
1570
|
+
finopsThemeColors?: FinopsThemeColors;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
type MoniteRegionProviderProps = WidgetProviderProps & MoniteWrapperProps;
|
|
1574
|
+
|
|
1575
|
+
interface FeatureLabels$1 {
|
|
1576
|
+
profileSection: string;
|
|
1577
|
+
teamSection: string;
|
|
1578
|
+
invoiceSection: string;
|
|
1579
|
+
billPaySection: string;
|
|
1580
|
+
accountingSection: string;
|
|
1581
|
+
tagsSection: string;
|
|
1582
|
+
expenseSection: string;
|
|
1583
|
+
helpSection: string;
|
|
1584
|
+
expenseApprovalsTab: string;
|
|
1585
|
+
expenseRequirementsTab: string;
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
/**
|
|
1589
|
+
* The sections this widget renders itself. These ids are the public vocabulary
|
|
1590
|
+
* a host uses to deep-link into a section, so they are part of the package's
|
|
1591
|
+
* API surface — renaming one is a breaking change.
|
|
1592
|
+
*/
|
|
1593
|
+
declare const SettingsSection: {
|
|
1594
|
+
readonly Profile: "profile";
|
|
1595
|
+
readonly Team: "team";
|
|
1596
|
+
readonly Invoice: "invoice";
|
|
1597
|
+
readonly Expense: "expense";
|
|
1598
|
+
readonly BillPay: "bill-pay";
|
|
1599
|
+
readonly Accounting: "accounting";
|
|
1600
|
+
readonly Tags: "tags";
|
|
1601
|
+
readonly Help: "help";
|
|
1602
|
+
};
|
|
1603
|
+
type SettingsSection = (typeof SettingsSection)[keyof typeof SettingsSection];
|
|
1604
|
+
/**
|
|
1605
|
+
* A selectable section id: one of the built-ins, or the id of a host-supplied
|
|
1606
|
+
* {@link SettingsWidgetAdditionalSection}. The `string & {}` arm keeps the
|
|
1607
|
+
* built-in literals visible to editor autocomplete while still accepting a
|
|
1608
|
+
* host's own id.
|
|
1609
|
+
*/
|
|
1610
|
+
type SettingsWidgetSectionId = SettingsSection | (string & {});
|
|
1611
|
+
/**
|
|
1612
|
+
* A section contributed by the host, rendered alongside the built-in ones.
|
|
1613
|
+
*
|
|
1614
|
+
* This exists for surfaces the published package cannot own — the white-label
|
|
1615
|
+
* dashboard's password management, for instance, which is an app-auth concern
|
|
1616
|
+
* rather than an embedded one. Prefer the `*Content` props when replacing the
|
|
1617
|
+
* content of a section that already exists.
|
|
1618
|
+
*/
|
|
1619
|
+
interface SettingsWidgetAdditionalSection extends SettingsWidgetSection {
|
|
1620
|
+
/**
|
|
1621
|
+
* Place this section immediately after the named built-in one. Sections with
|
|
1622
|
+
* no `after` — and those whose anchor is hidden by scope gating — are
|
|
1623
|
+
* appended to the end of the list.
|
|
1624
|
+
*/
|
|
1625
|
+
after?: SettingsSection;
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
interface SettingsWidgetProps extends MoniteRegionProviderProps {
|
|
1629
|
+
labels?: Partial<Labels>;
|
|
1630
|
+
featureLabels?: Partial<FeatureLabels$1>;
|
|
1631
|
+
/** Forwarded to the embedded Team section's {@link TeamWidget} — the
|
|
1632
|
+
* allowlisted URL invite emails link to. Defaults to
|
|
1633
|
+
* `${window.location.origin}/accept-invite`; set it when the host app's
|
|
1634
|
+
* registered landing route differs from that default, or the origin is
|
|
1635
|
+
* not on the OIDC redirect-URI allowlist (preview/localhost). */
|
|
1636
|
+
acceptInviteRedirectUri?: string;
|
|
1637
|
+
/** Forwarded to the embedded Help section's {@link HelpWidget} — where its
|
|
1638
|
+
* "Contact Us" line links (a support page URL or a `mailto:`). The line is
|
|
1639
|
+
* hidden entirely when unset, since the package has no tenant-agnostic
|
|
1640
|
+
* support address to fall back on. The bank name in that line comes from
|
|
1641
|
+
* widget init, so this is the only value a host needs to supply. */
|
|
1642
|
+
helpContactUrl?: string;
|
|
1643
|
+
/** Forwarded to the embedded Profile section's {@link ProfileWidget} — where
|
|
1644
|
+
* its "to change this information, contact your bank" line links. The line
|
|
1645
|
+
* falls back to a plain, unlinked sentence when unset, for the same reason
|
|
1646
|
+
* {@link SettingsWidgetProps.helpContactUrl} does. */
|
|
1647
|
+
profileContactUrl?: string;
|
|
1648
|
+
/** The section to show. Leave unset to let the widget own the selection;
|
|
1649
|
+
* supply it (with {@link SettingsWidgetProps.onSelectedSectionChange}) to
|
|
1650
|
+
* drive navigation from a route, a search param, or host state. A section
|
|
1651
|
+
* hidden by the user's scopes falls back to the first visible one. */
|
|
1652
|
+
selectedSection?: SettingsWidgetSectionId;
|
|
1653
|
+
/** The section to open on, for a host that wants a deep link without taking
|
|
1654
|
+
* ownership of the selection. Ignored when
|
|
1655
|
+
* {@link SettingsWidgetProps.selectedSection} is supplied; defaults to the
|
|
1656
|
+
* first visible section. Scopes arrive with the init response, so a section
|
|
1657
|
+
* this names opens as soon as it becomes visible, and one the user's scopes
|
|
1658
|
+
* never grant leaves the first visible section on screen. */
|
|
1659
|
+
defaultSelectedSection?: SettingsWidgetSectionId;
|
|
1660
|
+
/** Called with the id of the section the user selected. Fires whether or not
|
|
1661
|
+
* {@link SettingsWidgetProps.selectedSection} is supplied, so a host can mirror
|
|
1662
|
+
* the selection into its URL without taking ownership of it. */
|
|
1663
|
+
onSelectedSectionChange?: (section: SettingsWidgetSectionId) => void;
|
|
1664
|
+
/** Host-owned sections rendered alongside the built-in ones. */
|
|
1665
|
+
additionalSections?: SettingsWidgetAdditionalSection[];
|
|
1666
|
+
profileContent?: ReactNode;
|
|
1667
|
+
teamContent?: ReactNode;
|
|
1668
|
+
billPayContent?: ReactNode;
|
|
1669
|
+
helpContent?: ReactNode;
|
|
1670
|
+
expenseContent?: ReactNode;
|
|
1671
|
+
accountingContent?: ReactNode;
|
|
1672
|
+
tagsContent?: ReactNode;
|
|
1673
|
+
invoiceContent?: ReactNode;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
interface TransfersWidgetLabels {
|
|
1677
|
+
widgetTitle: string;
|
|
1678
|
+
transferMoneyCta: string;
|
|
1679
|
+
/** Tooltip when the transfer CTA is disabled for insufficient eligible accounts. */
|
|
1680
|
+
transferMoneyCtaDisabledTooltip: string;
|
|
1681
|
+
/** Fallback when an account has no nickname in lists or options. */
|
|
1682
|
+
accountFallbackName: string;
|
|
1683
|
+
/** Mask prefix before last four digits on account options. */
|
|
1684
|
+
embeddedAccountMaskPrefix: string;
|
|
1685
|
+
/** Prefix before full account number on review cards (e.g. "Account #:"). */
|
|
1686
|
+
modalReviewAccountNumberPrefix: string;
|
|
1687
|
+
/** Separator between from and to account names in the route line. */
|
|
1688
|
+
listAccountsSeparator: string;
|
|
1689
|
+
loadErrorTitle: string;
|
|
1690
|
+
loadErrorDescription: string;
|
|
1691
|
+
loadErrorRetry: string;
|
|
1692
|
+
emptyTitle: string;
|
|
1693
|
+
emptyDescription: string;
|
|
1694
|
+
modalTitle: string;
|
|
1695
|
+
/** Shown under the title on the accounts step (e.g. ACH timing). */
|
|
1696
|
+
modalAccountsSubtitle: string;
|
|
1697
|
+
/** Placeholder inside the From account select on the accounts step. */
|
|
1698
|
+
modalFromAccountPlaceholder: string;
|
|
1699
|
+
/** Placeholder inside the To account select on the accounts step. */
|
|
1700
|
+
modalToAccountPlaceholder: string;
|
|
1701
|
+
/** Primary action on the accounts step (legacy: full-width Confirm). */
|
|
1702
|
+
modalAccountsConfirm: string;
|
|
1703
|
+
modalStepAccounts: string;
|
|
1704
|
+
modalStepAmount: string;
|
|
1705
|
+
modalStepReview: string;
|
|
1706
|
+
modalStepResult: string;
|
|
1707
|
+
modalFromLabel: string;
|
|
1708
|
+
modalToLabel: string;
|
|
1709
|
+
modalAmountLabel: string;
|
|
1710
|
+
/** Placeholder for the amount input (e.g. "0.00"). */
|
|
1711
|
+
modalAmountPlaceholder: string;
|
|
1712
|
+
modalContinue: string;
|
|
1713
|
+
modalBack: string;
|
|
1714
|
+
modalSubmit: string;
|
|
1715
|
+
modalClose: string;
|
|
1716
|
+
modalReviewHeading: string;
|
|
1717
|
+
modalReviewFromAccountLabel: string;
|
|
1718
|
+
modalReviewToAccountLabel: string;
|
|
1719
|
+
modalAvailableBalanceCaption: string;
|
|
1720
|
+
modalConfirmTransfer: string;
|
|
1721
|
+
modalGoBack: string;
|
|
1722
|
+
modalSuccessTitle: string;
|
|
1723
|
+
modalSuccessDescription: string;
|
|
1724
|
+
modalResultSuccessTitle: string;
|
|
1725
|
+
modalResultErrorTitle: string;
|
|
1726
|
+
modalResultTransferMessagePrefix: string;
|
|
1727
|
+
modalResultSuccessMessageSuffix: string;
|
|
1728
|
+
modalResultErrorMessageSuffix: string;
|
|
1729
|
+
modalBackToTransfers: string;
|
|
1730
|
+
modalSelectPlaceholder: string;
|
|
1731
|
+
rowStatusCompleted: string;
|
|
1732
|
+
rowStatusPending: string;
|
|
1733
|
+
rowStatusFailed: string;
|
|
1734
|
+
rowTypeInternal: string;
|
|
1735
|
+
rowTypeToExternal: string;
|
|
1736
|
+
rowTypeFromExternal: string;
|
|
1737
|
+
modalAmountInvalidError: string;
|
|
1738
|
+
/** Shown under the amount field when the from (embedded) balance is too low. */
|
|
1739
|
+
modalInsufficientFundsError: string;
|
|
1740
|
+
/** Resets from, to, and amount on the accounts step. */
|
|
1741
|
+
modalClearSelections: string;
|
|
1742
|
+
modalUnsupportedPairError: string;
|
|
1743
|
+
modalSubmitFailedError: string;
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
interface FeatureLabels {
|
|
1747
|
+
unavailableLabel: string;
|
|
1748
|
+
routeSeparator: string;
|
|
1749
|
+
defaultCurrencyCode: string;
|
|
1750
|
+
defaultSecCode: string;
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
interface TransfersWidgetPassthroughProps {
|
|
1754
|
+
labels?: Partial<TransfersWidgetLabels>;
|
|
1755
|
+
featureLabels?: Partial<FeatureLabels>;
|
|
1756
|
+
/**
|
|
1757
|
+
* Whether the transfer money modal is showing. Supplying it makes the modal
|
|
1758
|
+
* controlled: the widget reports every open and close through
|
|
1759
|
+
* `onTransferMoneyOpenChange` and changes nothing on screen until the host
|
|
1760
|
+
* supplies a new value. Omit to let the widget own it.
|
|
1761
|
+
*/
|
|
1762
|
+
isTransferMoneyOpen?: boolean;
|
|
1763
|
+
/** The modal's state on first render, for a host that only wants to seed it. */
|
|
1764
|
+
defaultIsTransferMoneyOpen?: boolean;
|
|
1765
|
+
/**
|
|
1766
|
+
* Called on every open and close — the CTA, the modal's own dismissals, and
|
|
1767
|
+
* the close that follows a completed transfer — whether or not the modal is
|
|
1768
|
+
* controlled.
|
|
1769
|
+
*/
|
|
1770
|
+
onTransferMoneyOpenChange?: (open: boolean) => void;
|
|
1771
|
+
}
|
|
1772
|
+
interface TransfersWidgetProps extends WidgetProviderProps, TransfersWidgetPassthroughProps {
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
/**
|
|
1776
|
+
* Copy the shell owns. The section names are deliberately absent: they arrive on
|
|
1777
|
+
* each `SuiteSection`, because whoever decides which sections exist is also the
|
|
1778
|
+
* only layer that can name them.
|
|
1779
|
+
*/
|
|
1780
|
+
interface WidgetSuiteShellLabels {
|
|
1781
|
+
/** Names the section menu for assistive technology. */
|
|
1782
|
+
navAriaLabel: string;
|
|
1783
|
+
/**
|
|
1784
|
+
* Announces the placeholder shell while the caller resolves which sections
|
|
1785
|
+
* exist. Read out in place of the menu, which has no items yet to name.
|
|
1786
|
+
*/
|
|
1787
|
+
loadingAriaLabel: string;
|
|
1788
|
+
/** Shown in place of the menu when the caller supplies no sections. */
|
|
1789
|
+
emptyState: {
|
|
1790
|
+
title: string;
|
|
1791
|
+
body: string;
|
|
1792
|
+
};
|
|
1793
|
+
}
|
|
1794
|
+
/**
|
|
1795
|
+
* `Labels` has a nested group, so a shallow `{ ...defaults, ...overrides }`
|
|
1796
|
+
* would let a consumer overriding one `emptyState` string drop the other. The
|
|
1797
|
+
* repo has no shared deep-partial type, so each labels module declares its own.
|
|
1798
|
+
*/
|
|
1799
|
+
type PartialDeep<T> = {
|
|
1800
|
+
[K in keyof T]?: T[K] extends object ? PartialDeep<T[K]> : T[K];
|
|
1801
|
+
};
|
|
1802
|
+
|
|
1803
|
+
/**
|
|
1804
|
+
* The section id vocabulary, and the shape of a registry entry.
|
|
1805
|
+
*
|
|
1806
|
+
* A leaf module on purpose: it imports no widget feature library and never
|
|
1807
|
+
* reaches the provider, so `labels.ts` and `WidgetSuiteProvider.tsx` can take
|
|
1808
|
+
* the ids from here without sitting downstream of the eight widgets the registry
|
|
1809
|
+
* pulls in.
|
|
1810
|
+
*/
|
|
1811
|
+
/**
|
|
1812
|
+
* The sections the suite can offer, declared in the default menu order. Order
|
|
1813
|
+
* here is documentation only — the suite renders whatever order its `sections`
|
|
1814
|
+
* prop lists.
|
|
1815
|
+
*/
|
|
1816
|
+
declare const WidgetSuiteSectionId: {
|
|
1817
|
+
readonly Dashboard: "dashboard";
|
|
1818
|
+
readonly Accounts: "accounts";
|
|
1819
|
+
readonly Cards: "cards";
|
|
1820
|
+
readonly Transfers: "transfers";
|
|
1821
|
+
readonly BillPay: "bill-pay";
|
|
1822
|
+
readonly Invoicing: "invoicing";
|
|
1823
|
+
readonly Expenses: "expenses";
|
|
1824
|
+
readonly Settings: "settings";
|
|
1825
|
+
};
|
|
1826
|
+
type WidgetSuiteSectionId = (typeof WidgetSuiteSectionId)[keyof typeof WidgetSuiteSectionId];
|
|
1827
|
+
/**
|
|
1828
|
+
* The whole surface in the shipped white-label header order
|
|
1829
|
+
* (`useDashboardLayout.tsx`): its banking group, then its finops group, then
|
|
1830
|
+
* Settings, which white label keeps in the avatar menu rather than the header.
|
|
1831
|
+
*
|
|
1832
|
+
* This is what `sections` defaults to, and it is exported as well so a host can
|
|
1833
|
+
* spread it and edit the list — dropping a section, or reordering one — without
|
|
1834
|
+
* writing the whole thing out.
|
|
1835
|
+
*/
|
|
1836
|
+
declare const WIDGET_SUITE_DEFAULT_SECTIONS: readonly ["dashboard", "accounts", "cards", "transfers", "bill-pay", "invoicing", "expenses", "settings"];
|
|
1837
|
+
|
|
1838
|
+
/**
|
|
1839
|
+
* The section names in the suite menu.
|
|
1840
|
+
*
|
|
1841
|
+
* Keyed by section id rather than hand-listed, so adding a section to the
|
|
1842
|
+
* registry fails the build here until it is named — the menu can never render a
|
|
1843
|
+
* section with no label. The ids come from the leaf `sectionIds` module, so this
|
|
1844
|
+
* reaches neither the registry nor the widgets behind it.
|
|
1845
|
+
*/
|
|
1846
|
+
type WidgetSuiteMenuLabels = Record<WidgetSuiteSectionId, string>;
|
|
1847
|
+
/** Copy for the heading above a section, as opposed to its menu item. */
|
|
1848
|
+
interface WidgetSuiteSectionTitleLabels {
|
|
1849
|
+
/**
|
|
1850
|
+
* The bank attribution beneath the heading. `{bankName}` is replaced with the
|
|
1851
|
+
* bank `/init` names, so a translation can put it anywhere in the sentence
|
|
1852
|
+
* rather than after a fixed lead-in. An override that drops the placeholder
|
|
1853
|
+
* shows no name.
|
|
1854
|
+
*/
|
|
1855
|
+
bankTagline: string;
|
|
1856
|
+
}
|
|
1857
|
+
/**
|
|
1858
|
+
* Copy for the states where the suite cannot prove it may show normal content.
|
|
1859
|
+
*
|
|
1860
|
+
* Both are places the gate cannot proceed, and neither is reachable by a correct
|
|
1861
|
+
* integration against a healthy API.
|
|
1862
|
+
*/
|
|
1863
|
+
interface WidgetSuiteDisclosureLabels {
|
|
1864
|
+
/**
|
|
1865
|
+
* The first init fetch failed before the disclosure flags were known. The suite
|
|
1866
|
+
* must fail closed here, because an unknown requirement is not permission to
|
|
1867
|
+
* show ungated sections.
|
|
1868
|
+
*/
|
|
1869
|
+
initFailedState: {
|
|
1870
|
+
title: string;
|
|
1871
|
+
body: string;
|
|
1872
|
+
retryButton: string;
|
|
1873
|
+
};
|
|
1874
|
+
/**
|
|
1875
|
+
* The acceptance was recorded and the init refresh that clears the gate
|
|
1876
|
+
* failed, so only our view of it is stale.
|
|
1877
|
+
*
|
|
1878
|
+
* The failure is the title and the reassurance is the body, in that order on
|
|
1879
|
+
* purpose: `ErrorState` puts a destructive-toned glyph above the title, so
|
|
1880
|
+
* leading with "accepted" reads at a glance as the acceptance having failed —
|
|
1881
|
+
* the one thing this state must not imply, since a user who believes that will
|
|
1882
|
+
* try to accept again.
|
|
1883
|
+
*/
|
|
1884
|
+
refreshFailedState: {
|
|
1885
|
+
title: string;
|
|
1886
|
+
body: string;
|
|
1887
|
+
retryButton: string;
|
|
1888
|
+
};
|
|
1889
|
+
}
|
|
1890
|
+
/**
|
|
1891
|
+
* A widget's whole copy surface: every label prop it accepts, spread onto it so
|
|
1892
|
+
* the props keep the names that widget's own doc gives them.
|
|
1893
|
+
*
|
|
1894
|
+
* Derived rather than hand-listed: `CardsWidget` alone has six, so a written-out
|
|
1895
|
+
* list goes stale the next time one grows a panel. `providerLabels` is excluded
|
|
1896
|
+
* because the suite addresses the provider once, at the top level.
|
|
1897
|
+
*/
|
|
1898
|
+
type WidgetLabelProps<T> = Omit<Pick<T, Extract<keyof T, 'labels' | `${string}Labels`>>, 'providerLabels'>;
|
|
1899
|
+
type WidgetSuiteBalancesLabels = WidgetLabelProps<BalancesWidgetProps>;
|
|
1900
|
+
type WidgetSuiteInsightsLabels = WidgetLabelProps<InsightsWidgetProps>;
|
|
1901
|
+
type WidgetSuiteAccountsLabels = WidgetLabelProps<BankAccountsWidgetProps>;
|
|
1902
|
+
type WidgetSuiteCardsListLabels = WidgetLabelProps<CardsWidgetProps>;
|
|
1903
|
+
type WidgetSuiteTransfersLabels = WidgetLabelProps<TransfersWidgetProps>;
|
|
1904
|
+
type WidgetSuiteSettingsLabels = WidgetLabelProps<SettingsWidgetProps>;
|
|
1905
|
+
/** The two widgets the Dashboard section pairs, each taking its own copy. */
|
|
1906
|
+
interface WidgetSuiteDashboardLabels {
|
|
1907
|
+
balances?: WidgetSuiteBalancesLabels;
|
|
1908
|
+
insights?: WidgetSuiteInsightsLabels;
|
|
1909
|
+
}
|
|
1910
|
+
/**
|
|
1911
|
+
* The two card lists.
|
|
1912
|
+
*
|
|
1913
|
+
* `labels.title` is the one leaf the suite defaults anywhere under `sections`:
|
|
1914
|
+
* `CardsList` titles itself "Cards", and two instances stack in this section, so
|
|
1915
|
+
* each is retitled by program.
|
|
1916
|
+
*/
|
|
1917
|
+
interface WidgetSuiteCardsLabels {
|
|
1918
|
+
creditCards: WidgetSuiteCardsListLabels;
|
|
1919
|
+
debitCards: WidgetSuiteCardsListLabels;
|
|
1920
|
+
}
|
|
1921
|
+
/** Expenses is only a placeholder until the suite wires a read/self surface. */
|
|
1922
|
+
interface WidgetSuiteExpensesLabels {
|
|
1923
|
+
expensesUnavailable: string;
|
|
1924
|
+
}
|
|
1925
|
+
/**
|
|
1926
|
+
* Copy the suite puts *inside* a section's panel, one group per section.
|
|
1927
|
+
*
|
|
1928
|
+
* A group is shaped as the override its widget accepts, so it is handed down by
|
|
1929
|
+
* reference rather than remapped key by key.
|
|
1930
|
+
*
|
|
1931
|
+
* Two sections have no group: Bill Pay and Invoicing both mount a Monite
|
|
1932
|
+
* surface, which carries its own copy and takes no label props at all. They get
|
|
1933
|
+
* one when the native builds replace them, and adding a group to an
|
|
1934
|
+
* already-optional tree breaks nobody.
|
|
1935
|
+
*/
|
|
1936
|
+
interface WidgetSuiteSectionContentLabels {
|
|
1937
|
+
dashboard: WidgetSuiteDashboardLabels;
|
|
1938
|
+
accounts?: WidgetSuiteAccountsLabels;
|
|
1939
|
+
cards: WidgetSuiteCardsLabels;
|
|
1940
|
+
transfers?: WidgetSuiteTransfersLabels;
|
|
1941
|
+
expenses: WidgetSuiteExpensesLabels;
|
|
1942
|
+
settings?: WidgetSuiteSettingsLabels;
|
|
1943
|
+
}
|
|
1944
|
+
/**
|
|
1945
|
+
* Every string the suite puts on screen, including the copy inside the widgets
|
|
1946
|
+
* it mounts. Two kinds of group, differing in who holds the default:
|
|
1947
|
+
*
|
|
1948
|
+
* - **Suite-owned** — `shell`, `menu`, `sectionTitle`, `disclosure`,
|
|
1949
|
+
* `sections.expenses`, and the two card-list titles. Defaulted in
|
|
1950
|
+
* {@link WIDGET_SUITE_LABELS_EN}, with an override merged over it.
|
|
1951
|
+
* - **Forwarded** — every other key under `sections`. Handed down untouched for
|
|
1952
|
+
* the widget to merge over its own defaults, so the suite carries no copy of a
|
|
1953
|
+
* widget's strings and cannot go stale against one.
|
|
1954
|
+
*
|
|
1955
|
+
* `WidgetProvider`'s copy is deliberately absent: it is already reachable
|
|
1956
|
+
* through the inherited `providerLabels` prop, and two routes to one string
|
|
1957
|
+
* could disagree.
|
|
1958
|
+
*/
|
|
1959
|
+
interface WidgetSuiteLabels {
|
|
1960
|
+
/** The shell's own copy — the nav landmark name, the empty state. */
|
|
1961
|
+
shell: WidgetSuiteShellLabels;
|
|
1962
|
+
menu: WidgetSuiteMenuLabels;
|
|
1963
|
+
sectionTitle: WidgetSuiteSectionTitleLabels;
|
|
1964
|
+
disclosure: WidgetSuiteDisclosureLabels;
|
|
1965
|
+
sections: WidgetSuiteSectionContentLabels;
|
|
1966
|
+
}
|
|
1967
|
+
/**
|
|
1968
|
+
* The `labels` prop: a deep partial of {@link WidgetSuiteLabels}.
|
|
1969
|
+
*
|
|
1970
|
+
* `sections` is exempted from `PartialDeep` on purpose — every group under it is
|
|
1971
|
+
* already the exact override its widget accepts, so deepening it again would
|
|
1972
|
+
* admit a shape the suite cannot forward and would flatten a non-plain member
|
|
1973
|
+
* (`PartialDeep` maps a function-valued label to `{}`). The two suite-owned
|
|
1974
|
+
* groups under it are made partial one level for the same reason.
|
|
1975
|
+
*/
|
|
1976
|
+
type WidgetSuiteLabelOverrides = PartialDeep<Omit<WidgetSuiteLabels, 'sections'>> & {
|
|
1977
|
+
sections?: Partial<Omit<WidgetSuiteSectionContentLabels, 'cards' | 'expenses'>> & {
|
|
1978
|
+
cards?: Partial<WidgetSuiteCardsLabels>;
|
|
1979
|
+
expenses?: Partial<WidgetSuiteExpensesLabels>;
|
|
1980
|
+
};
|
|
1981
|
+
};
|
|
1982
|
+
declare const WIDGET_SUITE_LABELS_EN: WidgetSuiteLabels;
|
|
1983
|
+
|
|
1984
|
+
interface WidgetSuiteProps extends WidgetProviderProps {
|
|
1985
|
+
/**
|
|
1986
|
+
* Which sections the suite offers, in menu order.
|
|
1987
|
+
*
|
|
1988
|
+
* Defaults to {@link WIDGET_SUITE_DEFAULT_SECTIONS}, the whole surface in the
|
|
1989
|
+
* shipped white-label header order, so mounting the suite with auth props
|
|
1990
|
+
* alone gives a complete banking page. Name the list to compose a narrower
|
|
1991
|
+
* page, or to order it differently.
|
|
1992
|
+
*
|
|
1993
|
+
* A section listed here is still hidden when the token does not earn it, so
|
|
1994
|
+
* this is the ceiling rather than a promise of what renders — which is also
|
|
1995
|
+
* why the default is safe: a section added to the registry reaches a host that
|
|
1996
|
+
* took the default, and a user who cannot see it still does not.
|
|
1997
|
+
*/
|
|
1998
|
+
sections?: readonly WidgetSuiteSectionId[];
|
|
1999
|
+
/**
|
|
2000
|
+
* Which section is showing, for a host that owns navigation — a URL, a router,
|
|
2001
|
+
* its own state.
|
|
2002
|
+
*
|
|
2003
|
+
* Puts the menu in controlled mode for the lifetime of the mount, so supply it
|
|
2004
|
+
* with `onSectionChange` or the surface will not move when the user clicks.
|
|
2005
|
+
*
|
|
2006
|
+
* The suite is addressable at exactly this depth and no deeper: what a section
|
|
2007
|
+
* has open — an account, a card, a settings tab — belongs to the widget behind
|
|
2008
|
+
* it, so a host that needs to deep-link one of those mounts that widget itself.
|
|
2009
|
+
*/
|
|
2010
|
+
section?: WidgetSuiteSectionId;
|
|
2011
|
+
/**
|
|
2012
|
+
* Which section the suite opens on, for a host that wants a deep link but not
|
|
2013
|
+
* ownership. Read once per mount, and ignored when `section` is supplied.
|
|
2014
|
+
*
|
|
2015
|
+
* Defaults to the first entry in `sections`.
|
|
2016
|
+
*/
|
|
2017
|
+
defaultSection?: WidgetSuiteSectionId;
|
|
2018
|
+
/**
|
|
2019
|
+
* The section a person moved to, from a menu click or a dashboard affordance.
|
|
2020
|
+
*
|
|
2021
|
+
* Never fired for the entitlement fallback, and never fired on mount, so a
|
|
2022
|
+
* host mirroring this into its URL cannot overwrite the deep link it was just
|
|
2023
|
+
* handed.
|
|
2024
|
+
*/
|
|
2025
|
+
onSectionChange?: (section: WidgetSuiteSectionId) => void;
|
|
2026
|
+
/**
|
|
2027
|
+
* Every string the suite puts on screen, in one tree: the shell's own copy,
|
|
2028
|
+
* the menu names, the section heading, the disclosure states, and a group per
|
|
2029
|
+
* section carrying the copy of the widget that section mounts.
|
|
2030
|
+
*
|
|
2031
|
+
* Override any leaf and its siblings keep their defaults, at every depth. See
|
|
2032
|
+
* {@link WidgetSuiteLabels} for which groups the suite defaults and which it
|
|
2033
|
+
* forwards to a widget untouched.
|
|
2034
|
+
*
|
|
2035
|
+
* `WidgetProvider`'s own copy is not in here — it has its own `providerLabels`
|
|
2036
|
+
* prop, inherited from `WidgetProviderProps`.
|
|
2037
|
+
*/
|
|
2038
|
+
labels?: WidgetSuiteLabelOverrides;
|
|
2039
|
+
/**
|
|
2040
|
+
* Shows a heading above each section, named as its menu item is.
|
|
2041
|
+
*
|
|
2042
|
+
* Defaults to `true`: the suite owns its page, and a page with a menu but no
|
|
2043
|
+
* heading reads as a fragment of someone else's. Set `false` when the host
|
|
2044
|
+
* already renders a heading of its own above the suite.
|
|
2045
|
+
*
|
|
2046
|
+
* Every section gets one: no widget heads itself any more (embedded ADR
|
|
2047
|
+
* 0010), so the suite is the only thing that can name them.
|
|
2048
|
+
*/
|
|
2049
|
+
showSectionTitle?: boolean;
|
|
2050
|
+
}
|
|
2051
|
+
/**
|
|
2052
|
+
* A suite of widgets bound together by navigation.
|
|
2053
|
+
*
|
|
2054
|
+
* Unlike a widget — a content area an integrator drops onto a page they own — a
|
|
2055
|
+
* suite owns the page it is placed on, exists once per page, and decides which
|
|
2056
|
+
* widgets appear on it.
|
|
2057
|
+
*
|
|
2058
|
+
* One `/init` serves the whole surface: this provider owns the fetch, and every
|
|
2059
|
+
* composed widget is handed no auth props, so its own provider runs in
|
|
2060
|
+
* pass-through mode. See `sections/sectionIds.ts` for the two composition rules
|
|
2061
|
+
* that arrangement depends on.
|
|
2062
|
+
*
|
|
2063
|
+
* That one response also decides which state the suite is in before the shell
|
|
2064
|
+
* renders: placeholders while init has not settled, a closed retry state when
|
|
2065
|
+
* init fails before answering the disclosure flags, the acceptance surface
|
|
2066
|
+
* alone when the session owes the bank's disclosures, or the nav over its
|
|
2067
|
+
* sections. States rather than an overlay over a mounted shell — see
|
|
2068
|
+
* `WidgetSuiteSurface` for why each boundary sits where it does.
|
|
2069
|
+
*
|
|
2070
|
+
* Navigation is one value: which section is showing, published to the sections
|
|
2071
|
+
* through `WidgetSuiteProvider` and drivable by a host through `section` /
|
|
2072
|
+
* `defaultSection` / `onSectionChange`. Nothing deeper is addressable. Only the
|
|
2073
|
+
* open panel is mounted and every widget owns its own state, so leaving a
|
|
2074
|
+
* section and coming back shows it as it opens: the account list, the card
|
|
2075
|
+
* lists, the widget's own opening tab. A host that needs to deep-link into one
|
|
2076
|
+
* of those mounts that widget itself rather than reaching through the suite.
|
|
2077
|
+
*/
|
|
2078
|
+
declare function WidgetSuite({ baseUrl, widgetToken, organizationId, configClient, gatewayRouting, linkComponent, implementation, uiFramework, errorFallback, onError, analytics, disclosuresAcceptance, providerLabels, ...innerProps }: WidgetSuiteProps): React.JSX.Element;
|
|
2079
|
+
|
|
2080
|
+
export { WIDGET_SUITE_DEFAULT_SECTIONS, WIDGET_SUITE_LABELS_EN, WidgetSuite, WidgetSuiteSectionId };
|
|
2081
|
+
export type { WidgetSuiteCardsLabels, WidgetSuiteDashboardLabels, WidgetSuiteDisclosureLabels, WidgetSuiteExpensesLabels, WidgetSuiteLabelOverrides, WidgetSuiteLabels, WidgetSuiteMenuLabels, WidgetSuiteProps, WidgetSuiteSectionContentLabels, WidgetSuiteSectionTitleLabels };
|