@flow-industries/id 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sdk/client/flow-widget.js +11 -1
- package/dist/sdk/client/profile-button.js +17 -2
- package/dist/sdk/react/flow-widget.d.ts +4 -0
- package/dist/sdk/react/flow-widget.js +18 -3
- package/dist/sdk/react/profile-button.d.ts +5 -0
- package/dist/sdk/react/profile-button.js +19 -3
- package/dist/sdk/types/index.d.ts +1 -1
- package/dist/sdk/types/sdk.d.ts +20 -4
- package/package.json +1 -1
|
@@ -34,12 +34,13 @@ export function createFlowWidget(options) {
|
|
|
34
34
|
return {
|
|
35
35
|
frame: null,
|
|
36
36
|
post() { },
|
|
37
|
+
setTheme() { },
|
|
37
38
|
destroy() { },
|
|
38
39
|
};
|
|
39
40
|
const flow = options.flow ?? getFlow() ?? requireFlow();
|
|
40
41
|
const host = resolveIdHost(options.host ?? flow.host);
|
|
41
42
|
const hostOrigin = new URL(host).origin;
|
|
42
|
-
|
|
43
|
+
let theme = options.theme ?? "light dark";
|
|
43
44
|
const route = WIDGET_ROUTE[options.widget];
|
|
44
45
|
const frame = makeIframe(`${host}${route}`);
|
|
45
46
|
frame.style.background = "transparent";
|
|
@@ -70,6 +71,15 @@ export function createFlowWidget(options) {
|
|
|
70
71
|
post(message) {
|
|
71
72
|
frame.contentWindow?.postMessage(message, hostOrigin);
|
|
72
73
|
},
|
|
74
|
+
setTheme(next) {
|
|
75
|
+
if (next === theme)
|
|
76
|
+
return;
|
|
77
|
+
theme = next;
|
|
78
|
+
void bridge.send("__internal", {
|
|
79
|
+
type: "set-theme",
|
|
80
|
+
theme: { colorScheme: next },
|
|
81
|
+
});
|
|
82
|
+
},
|
|
73
83
|
destroy() {
|
|
74
84
|
bridge.destroy();
|
|
75
85
|
frame.remove();
|
|
@@ -29,11 +29,13 @@ const OVERLAY_STYLE = {
|
|
|
29
29
|
*/
|
|
30
30
|
export function createProfileButton(options) {
|
|
31
31
|
if (typeof document === "undefined")
|
|
32
|
-
return { destroy() { } };
|
|
32
|
+
return { setTheme() { }, destroy() { } };
|
|
33
33
|
const flow = options.flow ?? getFlow() ?? requireFlow();
|
|
34
34
|
const host = resolveIdHost(options.host ?? flow.host);
|
|
35
35
|
const hostOrigin = new URL(host).origin;
|
|
36
|
-
|
|
36
|
+
// Mutable so `setTheme` recolors over the open bridge, and so a dialog opened
|
|
37
|
+
// after a toggle is initialized with the theme the host is actually showing.
|
|
38
|
+
let theme = options.theme ?? "light dark";
|
|
37
39
|
let createdContainer = null;
|
|
38
40
|
let container = options.container ?? null;
|
|
39
41
|
if (!container) {
|
|
@@ -183,6 +185,19 @@ export function createProfileButton(options) {
|
|
|
183
185
|
pushIdentity();
|
|
184
186
|
const unsubscribe = flow.subscribe(pushIdentity);
|
|
185
187
|
return {
|
|
188
|
+
setTheme(next) {
|
|
189
|
+
if (next === theme)
|
|
190
|
+
return;
|
|
191
|
+
theme = next;
|
|
192
|
+
void pillBridge.send("__internal", {
|
|
193
|
+
type: "set-theme",
|
|
194
|
+
theme: { colorScheme: next },
|
|
195
|
+
});
|
|
196
|
+
void dialogBridge?.send("__internal", {
|
|
197
|
+
type: "set-theme",
|
|
198
|
+
theme: { colorScheme: next },
|
|
199
|
+
});
|
|
200
|
+
},
|
|
186
201
|
destroy() {
|
|
187
202
|
unsubscribe();
|
|
188
203
|
pillBridge.destroy();
|
|
@@ -8,5 +8,9 @@ import type { FlowWidgetProps } from "../types";
|
|
|
8
8
|
* Prefer this over embedding the widget's URL in your own `<iframe>`: only a
|
|
9
9
|
* frame mounted this way completes the handshake that lets it authenticate as
|
|
10
10
|
* the signed-in user from a cross-site page (AUTH-171).
|
|
11
|
+
*
|
|
12
|
+
* A changing `theme` recolors the mounted widget over its open bridge rather
|
|
13
|
+
* than remounting it — see `<ProfileButton>` for why the frame must survive a
|
|
14
|
+
* light/dark toggle.
|
|
11
15
|
*/
|
|
12
16
|
export declare function FlowWidget({ widget, className, host, theme, }: FlowWidgetProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -11,10 +11,16 @@ import { useFlow } from "./hooks";
|
|
|
11
11
|
* Prefer this over embedding the widget's URL in your own `<iframe>`: only a
|
|
12
12
|
* frame mounted this way completes the handshake that lets it authenticate as
|
|
13
13
|
* the signed-in user from a cross-site page (AUTH-171).
|
|
14
|
+
*
|
|
15
|
+
* A changing `theme` recolors the mounted widget over its open bridge rather
|
|
16
|
+
* than remounting it — see `<ProfileButton>` for why the frame must survive a
|
|
17
|
+
* light/dark toggle.
|
|
14
18
|
*/
|
|
15
19
|
export function FlowWidget({ widget, className, host, theme, }) {
|
|
16
20
|
const flow = useFlow();
|
|
17
21
|
const ref = useRef(null);
|
|
22
|
+
const handleRef = useRef(null);
|
|
23
|
+
const themeRef = useRef(theme);
|
|
18
24
|
useEffect(() => {
|
|
19
25
|
const container = ref.current;
|
|
20
26
|
if (!container)
|
|
@@ -24,14 +30,23 @@ export function FlowWidget({ widget, className, host, theme, }) {
|
|
|
24
30
|
container,
|
|
25
31
|
flow,
|
|
26
32
|
...(host ? { host } : {}),
|
|
27
|
-
...(
|
|
33
|
+
...(themeRef.current ? { theme: themeRef.current } : {}),
|
|
28
34
|
});
|
|
35
|
+
handleRef.current = handle;
|
|
29
36
|
if (handle.frame) {
|
|
30
37
|
handle.frame.style.width = "100%";
|
|
31
38
|
handle.frame.style.height = "100%";
|
|
32
39
|
handle.frame.style.display = "block";
|
|
33
40
|
}
|
|
34
|
-
return () =>
|
|
35
|
-
|
|
41
|
+
return () => {
|
|
42
|
+
handleRef.current = null;
|
|
43
|
+
handle.destroy();
|
|
44
|
+
};
|
|
45
|
+
}, [widget, flow, host]);
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
themeRef.current = theme;
|
|
48
|
+
if (theme)
|
|
49
|
+
handleRef.current?.setTheme(theme);
|
|
50
|
+
}, [theme]);
|
|
36
51
|
return _jsx("div", { ref: ref, className: className });
|
|
37
52
|
}
|
|
@@ -5,5 +5,10 @@ import type { ProfileButtonProps } from "../types";
|
|
|
5
5
|
* the pill iframe mounts into; the iframe itself is sized to its content and
|
|
6
6
|
* expands to the profile dialog on click. Resolves the Flow instance from a
|
|
7
7
|
* `<FlowIdProvider>` or the createFlow() singleton.
|
|
8
|
+
*
|
|
9
|
+
* A changing `theme` recolors the mounted pill over its open bridge rather than
|
|
10
|
+
* remounting it: `theme` is deliberately absent from the mount effect's deps,
|
|
11
|
+
* because tearing the iframe down on a light/dark toggle reloads the widget and
|
|
12
|
+
* drops the pill out of the host's layout mid-toggle.
|
|
8
13
|
*/
|
|
9
14
|
export declare function ProfileButton({ className, host, theme }: ProfileButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -8,10 +8,17 @@ import { useFlow } from "./hooks";
|
|
|
8
8
|
* the pill iframe mounts into; the iframe itself is sized to its content and
|
|
9
9
|
* expands to the profile dialog on click. Resolves the Flow instance from a
|
|
10
10
|
* `<FlowIdProvider>` or the createFlow() singleton.
|
|
11
|
+
*
|
|
12
|
+
* A changing `theme` recolors the mounted pill over its open bridge rather than
|
|
13
|
+
* remounting it: `theme` is deliberately absent from the mount effect's deps,
|
|
14
|
+
* because tearing the iframe down on a light/dark toggle reloads the widget and
|
|
15
|
+
* drops the pill out of the host's layout mid-toggle.
|
|
11
16
|
*/
|
|
12
17
|
export function ProfileButton({ className, host, theme }) {
|
|
13
18
|
const flow = useFlow();
|
|
14
19
|
const ref = useRef(null);
|
|
20
|
+
const handleRef = useRef(null);
|
|
21
|
+
const themeRef = useRef(theme);
|
|
15
22
|
useEffect(() => {
|
|
16
23
|
const container = ref.current;
|
|
17
24
|
if (!container)
|
|
@@ -20,9 +27,18 @@ export function ProfileButton({ className, host, theme }) {
|
|
|
20
27
|
container,
|
|
21
28
|
flow,
|
|
22
29
|
...(host ? { host } : {}),
|
|
23
|
-
...(
|
|
30
|
+
...(themeRef.current ? { theme: themeRef.current } : {}),
|
|
24
31
|
});
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
handleRef.current = handle;
|
|
33
|
+
return () => {
|
|
34
|
+
handleRef.current = null;
|
|
35
|
+
handle.destroy();
|
|
36
|
+
};
|
|
37
|
+
}, [flow, host]);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
themeRef.current = theme;
|
|
40
|
+
if (theme)
|
|
41
|
+
handleRef.current?.setTheme(theme);
|
|
42
|
+
}, [theme]);
|
|
27
43
|
return _jsx("div", { ref: ref, className: className });
|
|
28
44
|
}
|
|
@@ -6,7 +6,7 @@ export type { Call, ConnectCapabilities, ConnectRequest, ConnectResponse, GuestR
|
|
|
6
6
|
export { getConnectCapabilities, isPersonalSignParams, isSendCallsParams, isSendTransactionParams, } from "./protocol";
|
|
7
7
|
export type { CreateRoomEventInput, RoomEventAttendance, RoomEventFrequency, RoomEventInstance, RoomEventInterest, RoomEventInterestState, RoomEventList, RoomEventOccurrence, RoomEventRecurrence, RoomEventRoomRef, RoomEventSeries, RoomEventStatus, SetInterestInput, UpdateRoomEventInput, } from "./room-events";
|
|
8
8
|
export type { CreateRoomInput, GlobalRole, ModerationSubject, MyRooms, RoleChangeVerdict, RoomChannel, RoomDetail, RoomList, RoomMemberEntry, RoomMembers, RoomOccupancy, RoomOwner, RoomPresenceEntry, RoomPresenceSnapshot, RoomRestrictionKind, RoomRole, RoomSummary, RoomSurfaceSettings, RoomsApi, RoomVisibility, StaffEntry, UpdateRoomInput, VerifyRoomContext, Viewer, } from "./rooms";
|
|
9
|
-
export type { AccessKeyOptions, AccessKeyPreparation, Address, CreateDialogHostOptions, CreateFlowOptions, DialogHost, DialogOpenOptions, FinalizeAccessKeyParams, Flow, FlowConnectorParameters, FlowCookieNames, FlowIdProviderProps, FlowSessionState, FlowState, FlowWidgetHandle, FlowWidgetName, FlowWidgetProps, Listener, LoginOptions, MountFlowWidgetOptions, MountProfileOptions, PrepareArgsWithAuth, PrepareTransactionRequestPhase, ProfileButtonHandle, ProfileButtonProps, ProfilePosition, ResolveAccountParams, ResolvedAccessKeyOptions, RootCredential, RunLoginParams, RunLoginResult, SendCallsArgs, SendTransactionArgs, Session, SigningContext, SignMessageArgs, SignTypedDataArgs, Store, StoredAccessKey, WagmiConnectCapabilities, WagmiConnectParams, } from "./sdk";
|
|
9
|
+
export type { AccessKeyOptions, AccessKeyPreparation, Address, ColorScheme, CreateDialogHostOptions, CreateFlowOptions, DialogHost, DialogOpenOptions, FinalizeAccessKeyParams, Flow, FlowConnectorParameters, FlowCookieNames, FlowIdProviderProps, FlowSessionState, FlowState, FlowWidgetHandle, FlowWidgetName, FlowWidgetProps, Listener, LoginOptions, MountFlowWidgetOptions, MountProfileOptions, PrepareArgsWithAuth, PrepareTransactionRequestPhase, ProfileButtonHandle, ProfileButtonProps, ProfilePosition, ResolveAccountParams, ResolvedAccessKeyOptions, RootCredential, RunLoginParams, RunLoginResult, SendCallsArgs, SendTransactionArgs, Session, SigningContext, SignMessageArgs, SignTypedDataArgs, Store, StoredAccessKey, WagmiConnectCapabilities, WagmiConnectParams, } from "./sdk";
|
|
10
10
|
export type { ResolvedFlowSession, ResolveSessionOptions, SessionRouteOptions, SessionRouteResponse, SessionRouteSession, } from "./server";
|
|
11
11
|
export type { CoinAsset, IdentifiedTx, TxApprove, TxConvert, TxSend, TxSwap, } from "./tx";
|
|
12
12
|
export type { ActionDayContext, ActionEventKind, ActionSessionState, ActiveActionResponse, LevelProgress, PublicProfile, XpGrantResult, XpRecentGrant, XpSummary, } from "./xp";
|
package/dist/sdk/types/sdk.d.ts
CHANGED
|
@@ -187,6 +187,11 @@ export type DialogOpenOptions = {
|
|
|
187
187
|
icon?: string;
|
|
188
188
|
};
|
|
189
189
|
};
|
|
190
|
+
/**
|
|
191
|
+
* Color scheme for Flow ID iframe chrome. "light dark" follows the OS, which
|
|
192
|
+
* is the default; a host with its own theme toggle passes the resolved value.
|
|
193
|
+
*/
|
|
194
|
+
export type ColorScheme = "light" | "dark" | "light dark";
|
|
190
195
|
/** Anchor for an auto-created (host-less) profile widget container. */
|
|
191
196
|
export type ProfilePosition = "top-right" | "top-left" | "bottom-right" | "bottom-left";
|
|
192
197
|
export type MountProfileOptions = {
|
|
@@ -209,11 +214,17 @@ export type MountProfileOptions = {
|
|
|
209
214
|
* Color scheme for the widget chrome. Set this to match the host (the dark
|
|
210
215
|
* game UI passes "dark"). Defaults to "light dark" (follows the OS).
|
|
211
216
|
*/
|
|
212
|
-
theme?:
|
|
217
|
+
theme?: ColorScheme;
|
|
213
218
|
/** Explicit Flow instance. Defaults to the createFlow() singleton. */
|
|
214
219
|
flow?: Flow;
|
|
215
220
|
};
|
|
216
221
|
export type ProfileButtonHandle = {
|
|
222
|
+
/**
|
|
223
|
+
* Recolors the mounted pill (and its profile dialog) in place. A host with a
|
|
224
|
+
* theme toggle calls this instead of remounting: rebuilding the iframe would
|
|
225
|
+
* reload the widget and flash the pill out of the layout on every toggle.
|
|
226
|
+
*/
|
|
227
|
+
setTheme: (theme: ColorScheme) => void;
|
|
217
228
|
/** Tears down the iframe, listeners, and any auto-created container. */
|
|
218
229
|
destroy: () => void;
|
|
219
230
|
};
|
|
@@ -237,7 +248,7 @@ export type MountFlowWidgetOptions = {
|
|
|
237
248
|
* Color scheme for the widget chrome. Set this to match the host (the dark
|
|
238
249
|
* game UI passes "dark"). Defaults to "light dark" (follows the OS).
|
|
239
250
|
*/
|
|
240
|
-
theme?:
|
|
251
|
+
theme?: ColorScheme;
|
|
241
252
|
/** Explicit Flow instance. Defaults to the createFlow() singleton. */
|
|
242
253
|
flow?: Flow;
|
|
243
254
|
};
|
|
@@ -252,6 +263,11 @@ export type FlowWidgetHandle = {
|
|
|
252
263
|
* the Flow ID origin.
|
|
253
264
|
*/
|
|
254
265
|
post: (message: unknown) => void;
|
|
266
|
+
/**
|
|
267
|
+
* Recolors the mounted widget in place, for the same reason the pill exposes
|
|
268
|
+
* it: a remount reloads the frame and flashes it out of the host's layout.
|
|
269
|
+
*/
|
|
270
|
+
setTheme: (theme: ColorScheme) => void;
|
|
255
271
|
/** Tears down the iframe and its bridge. */
|
|
256
272
|
destroy: () => void;
|
|
257
273
|
};
|
|
@@ -263,7 +279,7 @@ export type FlowWidgetProps = {
|
|
|
263
279
|
/** Override the Flow ID origin; defaults to the resolved Flow's `host`. */
|
|
264
280
|
host?: string;
|
|
265
281
|
/** Color scheme for the widget chrome; defaults to "light dark" (the OS). */
|
|
266
|
-
theme?:
|
|
282
|
+
theme?: ColorScheme;
|
|
267
283
|
};
|
|
268
284
|
export type DialogHost = {
|
|
269
285
|
open: (options?: DialogOpenOptions) => void;
|
|
@@ -364,7 +380,7 @@ export type ProfileButtonProps = {
|
|
|
364
380
|
/** Override the Flow ID origin; defaults to the resolved Flow's `host`. */
|
|
365
381
|
host?: string;
|
|
366
382
|
/** Color scheme for the widget chrome; defaults to "light dark" (the OS). */
|
|
367
|
-
theme?:
|
|
383
|
+
theme?: ColorScheme;
|
|
368
384
|
};
|
|
369
385
|
export type RunLoginParams = {
|
|
370
386
|
dialog: DialogHost;
|