@entropy-softworks/ui 2026.910.2 → 2026.910.3
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/lib/components/index.d.ts +1 -1
- package/lib/components/index.d.ts.map +1 -1
- package/lib/components/index.js +1 -1
- package/lib/components/index.js.map +1 -1
- package/lib/components/social-connections.d.ts +60 -1
- package/lib/components/social-connections.d.ts.map +1 -1
- package/lib/components/social-connections.jsx +54 -2
- package/lib/components/social-connections.jsx.map +1 -1
- package/package.json +1 -1
- package/src/components/__tests__/social-connections.test.ts +35 -0
- package/src/components/index.ts +2 -0
- package/src/components/social-connections.tsx +127 -1
|
@@ -31,7 +31,7 @@ export { BottomNav, type BottomNavItem, type BottomNavProps } from "./bottom-nav
|
|
|
31
31
|
export { ItemIcon, type ItemIconProps } from "./item-icon";
|
|
32
32
|
export { TotpDisplay, type TotpDisplayProps } from "./totp-display";
|
|
33
33
|
export { UserAvatar, type UserAvatarProps } from "./user-avatar";
|
|
34
|
-
export { SocialConnections, visibleProviders, type SocialConnectionsProps, type Provider, type ProviderKey, type ProviderVisibility, } from "./social-connections";
|
|
34
|
+
export { SocialConnections, visibleProviders, customIcon, type SocialConnectionsProps, type Provider, type ProviderKey, type ProviderVisibility, type CustomProvider, } from "./social-connections";
|
|
35
35
|
export { ProfileDialog, ProfileTab, SecurityTab, type ProfileDialogProps, type ProfileTabProps, type SecurityTabProps, } from "./profile";
|
|
36
36
|
export { ServerSettings, type ServerSettingsProps } from "./server-settings";
|
|
37
37
|
export { ConnectionSettings, type ConnectionSettingsProps, type RunMode, } from "./connection-settings";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAEhE,OAAO,EACL,IAAI,EACJ,UAAU,EACV,WAAW,EACX,UAAU,EACV,SAAS,EACT,eAAe,EACf,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,oBAAoB,GAC1B,MAAM,QAAQ,CAAC;AAEhB,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE5F,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,EACxB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,WAAW,EACX,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAEvF,OAAO,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE1E,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAEnG,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAEnG,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEnD,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,eAAe,GACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EACL,eAAe,EACf,KAAK,oBAAoB,EACzB,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,WAAW,EACX,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,GAC1B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE5F,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE9F,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEnD,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAE5D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAElF,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,sBAAsB,EAC3B,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
|
package/lib/components/index.js
CHANGED
|
@@ -33,7 +33,7 @@ export { BottomNav } from "./bottom-nav";
|
|
|
33
33
|
export { ItemIcon } from "./item-icon";
|
|
34
34
|
export { TotpDisplay } from "./totp-display";
|
|
35
35
|
export { UserAvatar } from "./user-avatar";
|
|
36
|
-
export { SocialConnections, visibleProviders, } from "./social-connections";
|
|
36
|
+
export { SocialConnections, visibleProviders, customIcon, } from "./social-connections";
|
|
37
37
|
export { ProfileDialog, ProfileTab, SecurityTab, } from "./profile";
|
|
38
38
|
export { ServerSettings } from "./server-settings";
|
|
39
39
|
export { ConnectionSettings, } from "./connection-settings";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -51,6 +51,46 @@ export interface SocialConnectionsProps {
|
|
|
51
51
|
showGoogle?: boolean;
|
|
52
52
|
/** Whether to offer "Continue with Microsoft". Defaults to `true`. See {@link SocialConnectionsProps.showApple}. */
|
|
53
53
|
showMicrosoft?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Providers this component has no brand mark for, rendered after the four it
|
|
56
|
+
* does — Okta, Keycloak, GitHub, another Access instance, anything an
|
|
57
|
+
* operator configures.
|
|
58
|
+
*
|
|
59
|
+
* ## Why these are a caller-supplied list rather than more `ProviderKey`s
|
|
60
|
+
*
|
|
61
|
+
* The four above are a closed set with bundled glyphs and a fixed order, so
|
|
62
|
+
* they can be named in the type. What an operator connects is open: adding a
|
|
63
|
+
* key here for every provider anyone might configure is a release of this
|
|
64
|
+
* package per connector, and the whole point of the identity provider's
|
|
65
|
+
* connector table is that it does not need one.
|
|
66
|
+
*
|
|
67
|
+
* Ordered as given, after the built-ins, so the row is stable — the
|
|
68
|
+
* built-ins keep the positions users have learned and new connectors append.
|
|
69
|
+
*
|
|
70
|
+
* `iconUrl` is optional and points at whatever the operator supplied. Absent,
|
|
71
|
+
* unreachable, or malformed, the button falls back to a neutral glyph rather
|
|
72
|
+
* than an empty square: a connector with no icon must still be pressable and
|
|
73
|
+
* still be labelled.
|
|
74
|
+
*/
|
|
75
|
+
custom?: readonly CustomProvider[];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A provider this package does not ship a mark for.
|
|
79
|
+
*
|
|
80
|
+
* `key` only has to be unique within the row; it is not a {@link ProviderKey}
|
|
81
|
+
* and is never matched against one. Prefix collisions with the built-ins are
|
|
82
|
+
* impossible because the rendered React keys are namespaced.
|
|
83
|
+
*/
|
|
84
|
+
export interface CustomProvider {
|
|
85
|
+
key: string;
|
|
86
|
+
/** What the tooltip and the screen reader say: "Continue with {label}". */
|
|
87
|
+
label: string;
|
|
88
|
+
/**
|
|
89
|
+
* Absolute URL of the provider's mark. Rendered at 22px square, matching the
|
|
90
|
+
* bundled glyphs.
|
|
91
|
+
*/
|
|
92
|
+
iconUrl?: string | null;
|
|
93
|
+
onPress?: () => void;
|
|
54
94
|
}
|
|
55
95
|
/** The federated providers this row can draw. */
|
|
56
96
|
export type ProviderKey = "entropy" | "apple" | "google" | "microsoft";
|
|
@@ -74,6 +114,25 @@ export type ProviderVisibility = Record<ProviderKey, boolean>;
|
|
|
74
114
|
* reshuffle between renders or between consumers.
|
|
75
115
|
*/
|
|
76
116
|
export declare function visibleProviders(shown: ProviderVisibility): readonly Provider[];
|
|
117
|
+
/**
|
|
118
|
+
* What a caller-supplied provider's button should draw.
|
|
119
|
+
*
|
|
120
|
+
* Pure, exported and separate from the component for the same reason
|
|
121
|
+
* {@link visibleProviders} is: the fallback rule is the part worth testing, and
|
|
122
|
+
* the component pulls in `@expo/vector-icons` and reanimated, which the unit
|
|
123
|
+
* suite's transform does not process.
|
|
124
|
+
*
|
|
125
|
+
* A blank or whitespace-only URL counts as absent, not as a URL to fetch: an
|
|
126
|
+
* operator who clears the field in a form leaves `""` behind far more often
|
|
127
|
+
* than `null`, and `<Image source={{uri: ""}}>` is a request that fails
|
|
128
|
+
* silently on web and renders an empty square on native.
|
|
129
|
+
*/
|
|
130
|
+
export declare function customIcon(iconUrl: string | null | undefined, failed: boolean): {
|
|
131
|
+
kind: "image";
|
|
132
|
+
uri: string;
|
|
133
|
+
} | {
|
|
134
|
+
kind: "fallback";
|
|
135
|
+
};
|
|
77
136
|
/**
|
|
78
137
|
* Button row for federated sign-in: Entropy / Apple / Google / Microsoft.
|
|
79
138
|
*
|
|
@@ -94,6 +153,6 @@ export declare function visibleProviders(shown: ProviderVisibility): readonly Pr
|
|
|
94
153
|
* reader announces. Without the tooltip these are four unlabelled squares, and
|
|
95
154
|
* a user has to guess which mark is which.
|
|
96
155
|
*/
|
|
97
|
-
export declare function SocialConnections({ onApple, onGoogle, onMicrosoft, onEntropy, showEntropy, showApple, showGoogle, showMicrosoft, }: SocialConnectionsProps): React.JSX.Element;
|
|
156
|
+
export declare function SocialConnections({ onApple, onGoogle, onMicrosoft, onEntropy, showEntropy, showApple, showGoogle, showMicrosoft, custom, }: SocialConnectionsProps): React.JSX.Element;
|
|
98
157
|
export default SocialConnections;
|
|
99
158
|
//# sourceMappingURL=social-connections.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"social-connections.d.ts","sourceRoot":"","sources":["../../src/components/social-connections.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;;;;;;;;;;;;;OAcG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iHAAiH;IACjH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oHAAoH;IACpH,aAAa,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"social-connections.d.ts","sourceRoot":"","sources":["../../src/components/social-connections.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;;;;;;;;;;;;;OAcG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iHAAiH;IACjH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oHAAoH;IACpH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,MAAM,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CACpC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,iDAAiD;AACjD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEvE,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,WAAW,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,IAAI,EAAE,YAAY,GAAG,aAAa,GAAG,gBAAgB,GAAG,IAAI,CAAC;CAC9D;AAYD;8EAC8E;AAC9E,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAE9D;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,kBAAkB,GACxB,SAAS,QAAQ,EAAE,CAErB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAClC,MAAM,EAAE,OAAO,GACd;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAMvD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,QAAQ,EACR,WAAW,EACX,SAAS,EACT,WAAkB,EAClB,SAAgB,EAChB,UAAiB,EACjB,aAAoB,EACpB,MAAW,GACZ,EAAE,sBAAsB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA6D5C;AAqDD,eAAe,iBAAiB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Pressable, View } from "react-native";
|
|
2
|
+
import { Image, Pressable, View } from "react-native";
|
|
3
3
|
import { Ionicons } from "@expo/vector-icons";
|
|
4
4
|
import { useColorScheme } from "nativewind";
|
|
5
5
|
import { EntropyMark } from "./entropy-mark";
|
|
@@ -26,6 +26,26 @@ const PROVIDERS = [
|
|
|
26
26
|
export function visibleProviders(shown) {
|
|
27
27
|
return PROVIDERS.filter(({ key }) => shown[key]);
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* What a caller-supplied provider's button should draw.
|
|
31
|
+
*
|
|
32
|
+
* Pure, exported and separate from the component for the same reason
|
|
33
|
+
* {@link visibleProviders} is: the fallback rule is the part worth testing, and
|
|
34
|
+
* the component pulls in `@expo/vector-icons` and reanimated, which the unit
|
|
35
|
+
* suite's transform does not process.
|
|
36
|
+
*
|
|
37
|
+
* A blank or whitespace-only URL counts as absent, not as a URL to fetch: an
|
|
38
|
+
* operator who clears the field in a form leaves `""` behind far more often
|
|
39
|
+
* than `null`, and `<Image source={{uri: ""}}>` is a request that fails
|
|
40
|
+
* silently on web and renders an empty square on native.
|
|
41
|
+
*/
|
|
42
|
+
export function customIcon(iconUrl, failed) {
|
|
43
|
+
const uri = iconUrl?.trim();
|
|
44
|
+
if (!uri || failed) {
|
|
45
|
+
return { kind: "fallback" };
|
|
46
|
+
}
|
|
47
|
+
return { kind: "image", uri };
|
|
48
|
+
}
|
|
29
49
|
/**
|
|
30
50
|
* Button row for federated sign-in: Entropy / Apple / Google / Microsoft.
|
|
31
51
|
*
|
|
@@ -46,7 +66,7 @@ export function visibleProviders(shown) {
|
|
|
46
66
|
* reader announces. Without the tooltip these are four unlabelled squares, and
|
|
47
67
|
* a user has to guess which mark is which.
|
|
48
68
|
*/
|
|
49
|
-
export function SocialConnections({ onApple, onGoogle, onMicrosoft, onEntropy, showEntropy = true, showApple = true, showGoogle = true, showMicrosoft = true, }) {
|
|
69
|
+
export function SocialConnections({ onApple, onGoogle, onMicrosoft, onEntropy, showEntropy = true, showApple = true, showGoogle = true, showMicrosoft = true, custom = [], }) {
|
|
50
70
|
const { colorScheme } = useColorScheme();
|
|
51
71
|
const isDark = colorScheme === "dark";
|
|
52
72
|
const handlers = {
|
|
@@ -80,7 +100,39 @@ export function SocialConnections({ onApple, onGoogle, onMicrosoft, onEntropy, s
|
|
|
80
100
|
</TooltipTrigger>
|
|
81
101
|
<TooltipContent>{`Continue with ${label}`}</TooltipContent>
|
|
82
102
|
</Tooltip>))}
|
|
103
|
+
{custom.map((provider) => (<CustomProviderButton
|
|
104
|
+
// Namespaced so a caller's key cannot collide with a built-in's and
|
|
105
|
+
// silently replace it in the reconciler.
|
|
106
|
+
key={`custom:${provider.key}`} provider={provider} isDark={isDark}/>))}
|
|
83
107
|
</View>);
|
|
84
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* One caller-supplied provider.
|
|
111
|
+
*
|
|
112
|
+
* Its own component because it holds state the built-ins do not: whether the
|
|
113
|
+
* remote icon failed. A broken URL has to degrade to the neutral glyph, and
|
|
114
|
+
* `onError` can only be observed per image.
|
|
115
|
+
*/
|
|
116
|
+
function CustomProviderButton({ provider, isDark, }) {
|
|
117
|
+
const [iconFailed, setIconFailed] = React.useState(false);
|
|
118
|
+
const tint = isDark ? "#FFFFFF" : "#000000";
|
|
119
|
+
const icon = customIcon(provider.iconUrl, iconFailed);
|
|
120
|
+
return (<Tooltip delayDuration={200}>
|
|
121
|
+
<TooltipTrigger asChild>
|
|
122
|
+
<Pressable onPress={provider.onPress} className="h-12 w-12 items-center justify-center rounded-lg border border-border dark:border-neutral-600 active:opacity-70" accessibilityRole="button" accessibilityLabel={`Continue with ${provider.label}`}>
|
|
123
|
+
{icon.kind === "image" ? (<Image source={{ uri: icon.uri }} style={{ width: 22, height: 22 }}
|
|
124
|
+
// `contain` rather than `cover`: an operator's mark is whatever
|
|
125
|
+
// aspect ratio they have, and cropping somebody's logo to a
|
|
126
|
+
// square is worse than letterboxing it.
|
|
127
|
+
resizeMode="contain" onError={() => setIconFailed(true)} accessibilityIgnoresInvertColors/>) : (
|
|
128
|
+
// The neutral fallback. A key rather than a globe or a puzzle
|
|
129
|
+
// piece: this is a sign-in credential, and the glyph should say so
|
|
130
|
+
// without implying a vendor.
|
|
131
|
+
<Ionicons name="key-outline" size={22} color={tint}/>)}
|
|
132
|
+
</Pressable>
|
|
133
|
+
</TooltipTrigger>
|
|
134
|
+
<TooltipContent>{`Continue with ${provider.label}`}</TooltipContent>
|
|
135
|
+
</Tooltip>);
|
|
136
|
+
}
|
|
85
137
|
export default SocialConnections;
|
|
86
138
|
//# sourceMappingURL=social-connections.jsx.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"social-connections.jsx","sourceRoot":"","sources":["../../src/components/social-connections.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"social-connections.jsx","sourceRoot":"","sources":["../../src/components/social-connections.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
customIcon,
|
|
2
3
|
visibleProviders,
|
|
3
4
|
type ProviderKey,
|
|
4
5
|
type ProviderVisibility,
|
|
@@ -95,3 +96,37 @@ describe("visibleProviders", () => {
|
|
|
95
96
|
expect(byKey.get("microsoft")?.icon).toBe("logo-microsoft");
|
|
96
97
|
});
|
|
97
98
|
});
|
|
99
|
+
|
|
100
|
+
describe("customIcon", () => {
|
|
101
|
+
it("uses the operator's URL when there is one", () => {
|
|
102
|
+
expect(customIcon("https://cdn.example/okta.svg", false)).toEqual({
|
|
103
|
+
kind: "image",
|
|
104
|
+
uri: "https://cdn.example/okta.svg",
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("trims, because a pasted URL usually arrives with whitespace", () => {
|
|
109
|
+
expect(customIcon(" https://cdn.example/k.png\n", false)).toEqual({
|
|
110
|
+
kind: "image",
|
|
111
|
+
uri: "https://cdn.example/k.png",
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it.each([undefined, null, "", " "])(
|
|
116
|
+
"falls back when the URL is %p",
|
|
117
|
+
(value) => {
|
|
118
|
+
// A blank string is the case that matters: clearing a form field leaves
|
|
119
|
+
// "" far more often than null, and `<Image source={{uri: ""}}>` renders
|
|
120
|
+
// an empty square rather than failing loudly.
|
|
121
|
+
expect(customIcon(value, false)).toEqual({ kind: "fallback" });
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
it("falls back once the image has failed, URL or not", () => {
|
|
126
|
+
// An unreachable or malformed URL must still leave a pressable, labelled
|
|
127
|
+
// button — a connector the operator can see and use.
|
|
128
|
+
expect(customIcon("https://cdn.example/gone.png", true)).toEqual({
|
|
129
|
+
kind: "fallback",
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|
package/src/components/index.ts
CHANGED
|
@@ -132,10 +132,12 @@ export { UserAvatar, type UserAvatarProps } from "./user-avatar";
|
|
|
132
132
|
export {
|
|
133
133
|
SocialConnections,
|
|
134
134
|
visibleProviders,
|
|
135
|
+
customIcon,
|
|
135
136
|
type SocialConnectionsProps,
|
|
136
137
|
type Provider,
|
|
137
138
|
type ProviderKey,
|
|
138
139
|
type ProviderVisibility,
|
|
140
|
+
type CustomProvider,
|
|
139
141
|
} from "./social-connections";
|
|
140
142
|
|
|
141
143
|
export {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Pressable, View } from "react-native";
|
|
2
|
+
import { Image, Pressable, View } from "react-native";
|
|
3
3
|
import { Ionicons } from "@expo/vector-icons";
|
|
4
4
|
import { useColorScheme } from "nativewind";
|
|
5
5
|
import { EntropyMark } from "./entropy-mark";
|
|
@@ -57,6 +57,47 @@ export interface SocialConnectionsProps {
|
|
|
57
57
|
showGoogle?: boolean;
|
|
58
58
|
/** Whether to offer "Continue with Microsoft". Defaults to `true`. See {@link SocialConnectionsProps.showApple}. */
|
|
59
59
|
showMicrosoft?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Providers this component has no brand mark for, rendered after the four it
|
|
62
|
+
* does — Okta, Keycloak, GitHub, another Access instance, anything an
|
|
63
|
+
* operator configures.
|
|
64
|
+
*
|
|
65
|
+
* ## Why these are a caller-supplied list rather than more `ProviderKey`s
|
|
66
|
+
*
|
|
67
|
+
* The four above are a closed set with bundled glyphs and a fixed order, so
|
|
68
|
+
* they can be named in the type. What an operator connects is open: adding a
|
|
69
|
+
* key here for every provider anyone might configure is a release of this
|
|
70
|
+
* package per connector, and the whole point of the identity provider's
|
|
71
|
+
* connector table is that it does not need one.
|
|
72
|
+
*
|
|
73
|
+
* Ordered as given, after the built-ins, so the row is stable — the
|
|
74
|
+
* built-ins keep the positions users have learned and new connectors append.
|
|
75
|
+
*
|
|
76
|
+
* `iconUrl` is optional and points at whatever the operator supplied. Absent,
|
|
77
|
+
* unreachable, or malformed, the button falls back to a neutral glyph rather
|
|
78
|
+
* than an empty square: a connector with no icon must still be pressable and
|
|
79
|
+
* still be labelled.
|
|
80
|
+
*/
|
|
81
|
+
custom?: readonly CustomProvider[];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* A provider this package does not ship a mark for.
|
|
86
|
+
*
|
|
87
|
+
* `key` only has to be unique within the row; it is not a {@link ProviderKey}
|
|
88
|
+
* and is never matched against one. Prefix collisions with the built-ins are
|
|
89
|
+
* impossible because the rendered React keys are namespaced.
|
|
90
|
+
*/
|
|
91
|
+
export interface CustomProvider {
|
|
92
|
+
key: string;
|
|
93
|
+
/** What the tooltip and the screen reader say: "Continue with {label}". */
|
|
94
|
+
label: string;
|
|
95
|
+
/**
|
|
96
|
+
* Absolute URL of the provider's mark. Rendered at 22px square, matching the
|
|
97
|
+
* bundled glyphs.
|
|
98
|
+
*/
|
|
99
|
+
iconUrl?: string | null;
|
|
100
|
+
onPress?: () => void;
|
|
60
101
|
}
|
|
61
102
|
|
|
62
103
|
/** The federated providers this row can draw. */
|
|
@@ -99,6 +140,30 @@ export function visibleProviders(
|
|
|
99
140
|
return PROVIDERS.filter(({ key }) => shown[key]);
|
|
100
141
|
}
|
|
101
142
|
|
|
143
|
+
/**
|
|
144
|
+
* What a caller-supplied provider's button should draw.
|
|
145
|
+
*
|
|
146
|
+
* Pure, exported and separate from the component for the same reason
|
|
147
|
+
* {@link visibleProviders} is: the fallback rule is the part worth testing, and
|
|
148
|
+
* the component pulls in `@expo/vector-icons` and reanimated, which the unit
|
|
149
|
+
* suite's transform does not process.
|
|
150
|
+
*
|
|
151
|
+
* A blank or whitespace-only URL counts as absent, not as a URL to fetch: an
|
|
152
|
+
* operator who clears the field in a form leaves `""` behind far more often
|
|
153
|
+
* than `null`, and `<Image source={{uri: ""}}>` is a request that fails
|
|
154
|
+
* silently on web and renders an empty square on native.
|
|
155
|
+
*/
|
|
156
|
+
export function customIcon(
|
|
157
|
+
iconUrl: string | null | undefined,
|
|
158
|
+
failed: boolean
|
|
159
|
+
): { kind: "image"; uri: string } | { kind: "fallback" } {
|
|
160
|
+
const uri = iconUrl?.trim();
|
|
161
|
+
if (!uri || failed) {
|
|
162
|
+
return { kind: "fallback" };
|
|
163
|
+
}
|
|
164
|
+
return { kind: "image", uri };
|
|
165
|
+
}
|
|
166
|
+
|
|
102
167
|
/**
|
|
103
168
|
* Button row for federated sign-in: Entropy / Apple / Google / Microsoft.
|
|
104
169
|
*
|
|
@@ -128,6 +193,7 @@ export function SocialConnections({
|
|
|
128
193
|
showApple = true,
|
|
129
194
|
showGoogle = true,
|
|
130
195
|
showMicrosoft = true,
|
|
196
|
+
custom = [],
|
|
131
197
|
}: SocialConnectionsProps): React.JSX.Element {
|
|
132
198
|
const { colorScheme } = useColorScheme();
|
|
133
199
|
const isDark = colorScheme === "dark";
|
|
@@ -178,8 +244,68 @@ export function SocialConnections({
|
|
|
178
244
|
</Tooltip>
|
|
179
245
|
)
|
|
180
246
|
)}
|
|
247
|
+
{custom.map((provider) => (
|
|
248
|
+
<CustomProviderButton
|
|
249
|
+
// Namespaced so a caller's key cannot collide with a built-in's and
|
|
250
|
+
// silently replace it in the reconciler.
|
|
251
|
+
key={`custom:${provider.key}`}
|
|
252
|
+
provider={provider}
|
|
253
|
+
isDark={isDark}
|
|
254
|
+
/>
|
|
255
|
+
))}
|
|
181
256
|
</View>
|
|
182
257
|
);
|
|
183
258
|
}
|
|
184
259
|
|
|
260
|
+
/**
|
|
261
|
+
* One caller-supplied provider.
|
|
262
|
+
*
|
|
263
|
+
* Its own component because it holds state the built-ins do not: whether the
|
|
264
|
+
* remote icon failed. A broken URL has to degrade to the neutral glyph, and
|
|
265
|
+
* `onError` can only be observed per image.
|
|
266
|
+
*/
|
|
267
|
+
function CustomProviderButton({
|
|
268
|
+
provider,
|
|
269
|
+
isDark,
|
|
270
|
+
}: {
|
|
271
|
+
provider: CustomProvider;
|
|
272
|
+
isDark: boolean;
|
|
273
|
+
}): React.JSX.Element {
|
|
274
|
+
const [iconFailed, setIconFailed] = React.useState(false);
|
|
275
|
+
const tint = isDark ? "#FFFFFF" : "#000000";
|
|
276
|
+
const icon = customIcon(provider.iconUrl, iconFailed);
|
|
277
|
+
|
|
278
|
+
return (
|
|
279
|
+
<Tooltip delayDuration={200}>
|
|
280
|
+
<TooltipTrigger asChild>
|
|
281
|
+
<Pressable
|
|
282
|
+
onPress={provider.onPress}
|
|
283
|
+
className="h-12 w-12 items-center justify-center rounded-lg border border-border dark:border-neutral-600 active:opacity-70"
|
|
284
|
+
accessibilityRole="button"
|
|
285
|
+
accessibilityLabel={`Continue with ${provider.label}`}
|
|
286
|
+
>
|
|
287
|
+
{icon.kind === "image" ? (
|
|
288
|
+
<Image
|
|
289
|
+
source={{ uri: icon.uri }}
|
|
290
|
+
style={{ width: 22, height: 22 }}
|
|
291
|
+
// `contain` rather than `cover`: an operator's mark is whatever
|
|
292
|
+
// aspect ratio they have, and cropping somebody's logo to a
|
|
293
|
+
// square is worse than letterboxing it.
|
|
294
|
+
resizeMode="contain"
|
|
295
|
+
onError={() => setIconFailed(true)}
|
|
296
|
+
accessibilityIgnoresInvertColors
|
|
297
|
+
/>
|
|
298
|
+
) : (
|
|
299
|
+
// The neutral fallback. A key rather than a globe or a puzzle
|
|
300
|
+
// piece: this is a sign-in credential, and the glyph should say so
|
|
301
|
+
// without implying a vendor.
|
|
302
|
+
<Ionicons name="key-outline" size={22} color={tint} />
|
|
303
|
+
)}
|
|
304
|
+
</Pressable>
|
|
305
|
+
</TooltipTrigger>
|
|
306
|
+
<TooltipContent>{`Continue with ${provider.label}`}</TooltipContent>
|
|
307
|
+
</Tooltip>
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
185
311
|
export default SocialConnections;
|