@vvedantb/native-ui 0.17.2 → 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/AlertDialog.jsx +123 -0
- package/dist/AmbientBackground.jsx +73 -0
- package/dist/ArtifactList.jsx +59 -0
- package/dist/Avatar.jsx +285 -0
- package/dist/Badge.jsx +154 -0
- package/dist/BottomSheetContainer.jsx +208 -0
- package/dist/BulkActionBar.jsx +717 -0
- package/dist/Button.jsx +344 -0
- package/dist/CaptureButton.jsx +104 -0
- package/dist/Card.jsx +371 -0
- package/dist/Checkbox.jsx +177 -0
- package/dist/Chip.jsx +79 -0
- package/dist/ColorSwatches.jsx +159 -0
- package/dist/ConfirmDialog.jsx +157 -0
- package/dist/DateTimeField.jsx +204 -0
- package/dist/Dialog.jsx +614 -0
- package/dist/DividedList.jsx +120 -0
- package/dist/DropdownMenu.jsx +849 -0
- package/dist/EmptyState.jsx +434 -0
- package/dist/ExpoWebRoot.jsx +134 -0
- package/dist/FloatingFAB.jsx +95 -0
- package/dist/FloatingSurface.jsx +226 -0
- package/dist/FloatingTabBar.jsx +403 -0
- package/dist/HeaderIconButton.jsx +53 -0
- package/dist/IconButton.jsx +157 -0
- package/dist/Input.jsx +96 -0
- package/dist/Label.jsx +96 -0
- package/dist/LabeledSwitchRow.jsx +170 -0
- package/dist/LiquidGlass.jsx +2 -0
- package/dist/ListRow.jsx +281 -0
- package/dist/LoadingState.jsx +205 -0
- package/dist/PageIndicator.jsx +128 -0
- package/dist/PageTitle.jsx +205 -0
- package/dist/Pager.jsx +105 -0
- package/dist/PasswordInput.jsx +120 -0
- package/dist/PillTabs.jsx +300 -0
- package/dist/PinnedBotTile.jsx +212 -0
- package/dist/Progress.jsx +147 -0
- package/dist/SafeAreaContainer.jsx +38 -0
- package/dist/ScreenContainer.jsx +117 -0
- package/dist/SearchInput.jsx +150 -0
- package/dist/SectionLabel.jsx +128 -0
- package/dist/Select.jsx +223 -0
- package/dist/Separator.jsx +95 -0
- package/dist/Sheet.jsx +343 -0
- package/dist/SheetRow.jsx +198 -0
- package/dist/Skeleton.jsx +311 -0
- package/dist/Spinner.jsx +195 -0
- package/dist/StackPageHeader.jsx +160 -0
- package/dist/StatGrid.jsx +74 -0
- package/dist/StatusDot.jsx +129 -0
- package/dist/SurfaceRow.jsx +143 -0
- package/dist/SwipeableRow.jsx +50 -0
- package/dist/Switch.jsx +130 -0
- package/dist/Tabs.jsx +385 -0
- package/dist/Textarea.jsx +103 -0
- package/dist/ThemeToggle.jsx +78 -0
- package/dist/Toast.jsx +396 -0
- package/dist/ai/activity-step-detail.jsx +179 -0
- package/dist/ai/activity-step-label.js +816 -0
- package/dist/ai/activity-step-types.js +14 -0
- package/dist/ai/activity-step.jsx +98 -0
- package/dist/ai/activity-tasks-utils.js +172 -0
- package/dist/ai/activity-timeline.js +47 -0
- package/dist/ai/attachments.jsx +258 -0
- package/dist/ai/card-button.jsx +188 -0
- package/dist/ai/chain-of-thought.jsx +459 -0
- package/dist/ai/chat-jump-rail.jsx +57 -0
- package/dist/ai/chat-text.js +44 -0
- package/dist/ai/chat-thread.jsx +135 -0
- package/dist/ai/choice-question.jsx +925 -0
- package/dist/ai/code-block.jsx +574 -0
- package/dist/ai/collapsible.jsx +275 -0
- package/dist/ai/conversation.jsx +723 -0
- package/dist/ai/file-chip.jsx +198 -0
- package/dist/ai/icon-button.jsx +179 -0
- package/dist/ai/index.js +37 -0
- package/dist/ai/message-action-sheet.jsx +408 -0
- package/dist/ai/message-quote.jsx +241 -0
- package/dist/ai/message.jsx +739 -0
- package/dist/ai/prompt-input-menu.jsx +365 -0
- package/dist/ai/prompt-input.jsx +626 -0
- package/dist/ai/reasoning.jsx +446 -0
- package/dist/ai/reply-quote-chip.jsx +278 -0
- package/dist/ai/response-text.jsx +130 -0
- package/dist/ai/shimmer.jsx +149 -0
- package/dist/ai/sources.jsx +260 -0
- package/dist/ai/subagent-cards.jsx +645 -0
- package/dist/ai/suggestion.jsx +186 -0
- package/dist/ai/tool-approval-card.jsx +359 -0
- package/dist/ai/trace.jsx +728 -0
- package/dist/ai/unified-diff.jsx +280 -0
- package/dist/ai/use-streaming-disclosure.js +70 -0
- package/dist/auth/AuthProviders.jsx +27 -0
- package/dist/auth/AuthScreen.jsx +292 -0
- package/dist/auth/GoogleSignInButton.jsx +188 -0
- package/dist/auth/SecondFactorScreen.jsx +133 -0
- package/dist/auth/SignInScreen.jsx +482 -0
- package/dist/auth/authErrors.js +131 -0
- package/dist/auth/index.js +11 -0
- package/dist/auth/totp.js +378 -0
- package/dist/blur.js +36 -0
- package/dist/brand/AppIcons.jsx +118 -0
- package/dist/brand/AppMark.jsx +128 -0
- package/dist/brand/AppWordmark.jsx +138 -0
- package/dist/brand/GoogleMark.jsx +71 -0
- package/dist/brand/ProviderIcon.jsx +192 -0
- package/dist/brand/familyApps.js +33 -0
- package/dist/brand/index.js +11 -0
- package/dist/brand/svg.js +252 -0
- package/dist/brand/vProAppBenefits.js +19 -0
- package/dist/cn.js +5 -0
- package/dist/colors.js +15 -0
- package/dist/configureTheme.js +72 -0
- package/dist/controlStyles.js +520 -0
- package/dist/definiteSize.js +12 -0
- package/dist/dialogLayout.js +18 -0
- package/dist/entries/ai.js +4 -0
- package/dist/entries/ambient.js +3 -0
- package/dist/entries/auth.js +5 -0
- package/dist/entries/bottom-sheet.js +2 -0
- package/dist/entries/brand.js +2 -0
- package/dist/entries/button.js +2 -0
- package/dist/entries/date-time.js +3 -0
- package/dist/entries/expo-router.js +4 -0
- package/dist/entries/expo-web-root.js +3 -0
- package/dist/entries/floating.js +7 -0
- package/dist/entries/gesture-handler.js +4 -0
- package/dist/entries/keyboard-controller.js +4 -0
- package/dist/entries/layout.js +16 -0
- package/dist/entries/markdown.js +4 -0
- package/dist/entries/marketing.js +3 -0
- package/dist/entries/page-title.js +7 -0
- package/dist/entries/password-input.js +3 -0
- package/dist/entries/primitives.js +57 -0
- package/dist/entries/search-input.js +3 -0
- package/dist/entries/tab-bar.js +4 -0
- package/dist/entries/theme.js +7 -0
- package/dist/entries/toast.js +5 -0
- package/dist/entries/video.js +3 -0
- package/dist/entries/webview.js +4 -0
- package/dist/examples/AiChatGallery.jsx +509 -0
- package/dist/examples/ParityGallery.jsx +1307 -0
- package/dist/floating.js +62 -0
- package/dist/glassBlur.jsx +145 -0
- package/dist/gradient.js +17 -0
- package/dist/haptics.js +44 -0
- package/dist/highlight.js +382 -0
- package/dist/index.js +85 -0
- package/dist/initials.js +4 -0
- package/dist/loadingGrid.js +81 -0
- package/dist/markdown/Markdown.jsx +515 -0
- package/dist/markdown/MarkdownTable.jsx +443 -0
- package/dist/markdown/tableText.js +68 -0
- package/dist/marketing/PricingModal.jsx +608 -0
- package/dist/marketing/UpgradeToProCard.jsx +164 -0
- package/dist/marketing/pricing.js +34 -0
- package/dist/media/ImageGallery.jsx +580 -0
- package/dist/media/MediaCard.jsx +162 -0
- package/dist/media/imageGrid.js +54 -0
- package/dist/motion.js +33 -0
- package/dist/pagerSwipe.js +104 -0
- package/dist/palette.js +104 -0
- package/dist/primitives/button.jsx +127 -0
- package/dist/primitives/card.jsx +249 -0
- package/dist/primitives/icon.jsx +37 -0
- package/dist/primitives/input.jsx +56 -0
- package/dist/primitives/keyboard-controller.jsx +207 -0
- package/dist/primitives/keyboard-parts.jsx +75 -0
- package/dist/primitives/native-only-animated-view.jsx +68 -0
- package/dist/primitives/overlay.jsx +391 -0
- package/dist/primitives/pager-gesture.jsx +131 -0
- package/dist/primitives/select-host.jsx +103 -0
- package/dist/primitives/select.jsx +555 -0
- package/dist/primitives/sheet-drag.jsx +420 -0
- package/dist/primitives/sheet-gesture.jsx +219 -0
- package/dist/primitives/swipe-row-gesture.jsx +341 -0
- package/dist/primitives/switch.jsx +105 -0
- package/dist/primitives/text.jsx +145 -0
- package/dist/primitives/toast-drag-gesture.jsx +94 -0
- package/dist/primitives/use-controllable-state.js +40 -0
- package/dist/primitives/web-click-guard.js +69 -0
- package/dist/push.js +166 -0
- package/dist/relativeTime.js +70 -0
- package/dist/router/RouterStackPageHeader.jsx +53 -0
- package/dist/selectA11y.js +32 -0
- package/dist/settings/MoreFromProjectV.jsx +168 -0
- package/dist/settings/SettingsEmptyState.jsx +102 -0
- package/dist/settings/SettingsField.jsx +49 -0
- package/dist/settings/SettingsSection.jsx +101 -0
- package/dist/settings/SettingsStack.jsx +17 -0
- package/dist/settings/SettingsToggleRow.jsx +163 -0
- package/dist/settings/projectVMobileApps.js +126 -0
- package/dist/settings/relaxedSizeStyle.js +11 -0
- package/dist/sheetDrag.js +76 -0
- package/dist/svgA11y.js +46 -0
- package/dist/swipeRow.js +161 -0
- package/dist/tabBarRoutes.js +41 -0
- package/dist/tabIndicator.js +139 -0
- package/dist/tailwind-preset.cjs +255 -0
- package/dist/tailwind-preset.d.cts +55 -0
- package/dist/theme.jsx +62 -0
- package/dist/toastChrome.js +110 -0
- package/dist/toastDrag.js +51 -0
- package/dist/toastStore.js +54 -0
- package/dist/tokens.js +70 -0
- package/dist/typography.js +40 -0
- package/dist/useReduceMotion.js +32 -0
- package/dist/useReduceTransparency.js +27 -0
- package/dist/useScheme.js +15 -0
- package/dist/video/InlineVideo.jsx +115 -0
- package/dist/webview/HtmlView.jsx +169 -0
- package/dist/webview/HtmlView.web.jsx +63 -0
- package/dist/webview/htmlView.js +43 -0
- package/package.json +70 -33
- package/src/DropdownMenu.tsx +28 -16
- package/src/FloatingTabBar.tsx +78 -41
- package/src/ai/conversation.tsx +12 -8
- package/src/glassBlur.tsx +47 -22
- package/src/primitives/swipe-row-gesture.tsx +11 -2
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import { c as _c } from "react/compiler-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { useSignIn } from "@clerk/clerk-expo";
|
|
4
|
+
import { authErrorMessage, DEFAULT_STAGE_TIMEOUT_MS, isAuthTimeoutError, logAuthFailure, withAuthTimeout } from "./authErrors";
|
|
5
|
+
|
|
6
|
+
/** Logs a timed-out stage. Other failures are not logged here. */
|
|
7
|
+
const logTimeout = (stage, error) => {
|
|
8
|
+
if (isAuthTimeoutError(error)) logAuthFailure(stage, error);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/** The messages the second-factor step can show. Generic: none names a provider. */
|
|
12
|
+
export const TOTP_MESSAGES = {
|
|
13
|
+
invalidCode: "Incorrect code. Check your authenticator app and try again.",
|
|
14
|
+
invalidCodeGeneric: "Incorrect code. Check it and try again.",
|
|
15
|
+
sendFailed: "Could not send the code. Try again.",
|
|
16
|
+
needsAnotherStep: "This account needs another step to sign in. Finish it on the web.",
|
|
17
|
+
notReady: "Sign in is not ready yet. Try again in a moment."
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/** The second-factor strategies the built-in step handles. */
|
|
21
|
+
|
|
22
|
+
/** Default order: the first one the account supports wins. */
|
|
23
|
+
export const SECOND_FACTOR_PREFERENCE = ["totp", "email_code", "phone_code", "backup_code"];
|
|
24
|
+
|
|
25
|
+
/** One entry of `signIn.supportedSecondFactors`. */
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The params of `prepareSecondFactor`. A union on `strategy`, as in Clerk's
|
|
29
|
+
* `PhoneCodeSecondFactorConfig | EmailCodeSecondFactorConfig`. One object with
|
|
30
|
+
* `strategy: "phone_code" | "email_code"` does not accept Clerk's
|
|
31
|
+
* `SignInResource` under `strictFunctionTypes`.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The params of `prepareFirstFactor`. A union on `strategy`, as in Clerk's
|
|
36
|
+
* `EmailCodeConfig | PhoneCodeConfig`, where the id is required.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/** The part of the sign-in resource that TOTP needs. Tests pass a mock. */
|
|
40
|
+
|
|
41
|
+
/** The part of the sign-in resource that any second factor needs. Tests pass a mock. */
|
|
42
|
+
|
|
43
|
+
/** The strategies in `factors` that the built-in step handles, in the order given. */
|
|
44
|
+
export function supportedSecondFactorStrategies(factors) {
|
|
45
|
+
const found = new Set((factors ?? []).map(factor => factor.strategy));
|
|
46
|
+
return SECOND_FACTOR_PREFERENCE.filter(strategy => found.has(strategy));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** The default strategy: `totp`, then `email_code`, `phone_code`, `backup_code`. `null` when none is supported. */
|
|
50
|
+
export function pickSecondFactorStrategy(factors) {
|
|
51
|
+
return supportedSecondFactorStrategies(factors)[0] ?? null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Sends the code for `phone_code` and `email_code`, with the `phoneNumberId` or
|
|
56
|
+
* `emailAddressId` of the matching factor. `totp` and `backup_code` need no
|
|
57
|
+
* prepare: it returns `{ ok: true }` without a call. Never throws.
|
|
58
|
+
*/
|
|
59
|
+
export async function prepareSecondFactorIfNeeded(args) {
|
|
60
|
+
const {
|
|
61
|
+
signIn,
|
|
62
|
+
strategy
|
|
63
|
+
} = args;
|
|
64
|
+
const ms = args.timeoutMs ?? DEFAULT_STAGE_TIMEOUT_MS;
|
|
65
|
+
if (strategy !== "phone_code" && strategy !== "email_code") return {
|
|
66
|
+
ok: true
|
|
67
|
+
};
|
|
68
|
+
if (!signIn.prepareSecondFactor) return {
|
|
69
|
+
ok: false,
|
|
70
|
+
error: TOTP_MESSAGES.sendFailed
|
|
71
|
+
};
|
|
72
|
+
const factor = args.factor ?? signIn.supportedSecondFactors?.find(item => item.strategy === strategy);
|
|
73
|
+
try {
|
|
74
|
+
if (strategy === "phone_code") {
|
|
75
|
+
await withAuthTimeout(signIn.prepareSecondFactor({
|
|
76
|
+
strategy,
|
|
77
|
+
...(factor?.phoneNumberId ? {
|
|
78
|
+
phoneNumberId: factor.phoneNumberId
|
|
79
|
+
} : {})
|
|
80
|
+
}), "prepare-second-factor", ms);
|
|
81
|
+
} else {
|
|
82
|
+
await withAuthTimeout(signIn.prepareSecondFactor({
|
|
83
|
+
strategy,
|
|
84
|
+
...(factor?.emailAddressId ? {
|
|
85
|
+
emailAddressId: factor.emailAddressId
|
|
86
|
+
} : {})
|
|
87
|
+
}), "prepare-second-factor", ms);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
ok: true
|
|
91
|
+
};
|
|
92
|
+
} catch (caught) {
|
|
93
|
+
logTimeout("prepare-second-factor", caught);
|
|
94
|
+
return {
|
|
95
|
+
ok: false,
|
|
96
|
+
error: authErrorMessage(caught, TOTP_MESSAGES.sendFailed)
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Checks a second-factor code and starts the session. Call
|
|
103
|
+
* `prepareSecondFactorIfNeeded` first for `phone_code` and `email_code`.
|
|
104
|
+
* Never throws: a failure is `{ ok: false, error }`. An API error shows its
|
|
105
|
+
* own text (such as "Incorrect code") unless it names the provider; anything
|
|
106
|
+
* else gives `TOTP_MESSAGES.invalidCode` (`totp`) or `invalidCodeGeneric`.
|
|
107
|
+
*/
|
|
108
|
+
export async function submitSecondFactor(args) {
|
|
109
|
+
const ms = args.timeoutMs ?? DEFAULT_STAGE_TIMEOUT_MS;
|
|
110
|
+
try {
|
|
111
|
+
const attempt = await withAuthTimeout(args.signIn.attemptSecondFactor({
|
|
112
|
+
strategy: args.strategy,
|
|
113
|
+
code: args.code
|
|
114
|
+
}), "attempt-second-factor", ms);
|
|
115
|
+
if (attempt.status === "complete" && attempt.createdSessionId) {
|
|
116
|
+
await withAuthTimeout(args.setActive({
|
|
117
|
+
session: attempt.createdSessionId
|
|
118
|
+
}), "set-active", ms);
|
|
119
|
+
return {
|
|
120
|
+
ok: true
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
ok: false,
|
|
125
|
+
error: TOTP_MESSAGES.needsAnotherStep
|
|
126
|
+
};
|
|
127
|
+
} catch (caught) {
|
|
128
|
+
logTimeout("attempt-second-factor", caught);
|
|
129
|
+
const fallback = args.strategy === "totp" ? TOTP_MESSAGES.invalidCode : TOTP_MESSAGES.invalidCodeGeneric;
|
|
130
|
+
return {
|
|
131
|
+
ok: false,
|
|
132
|
+
error: authErrorMessage(caught, fallback)
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** The first-factor code strategies the built-in step handles. */
|
|
138
|
+
|
|
139
|
+
/** Default order: `email_code`, then `phone_code`. */
|
|
140
|
+
export const FIRST_FACTOR_PREFERENCE = ["email_code", "phone_code"];
|
|
141
|
+
|
|
142
|
+
/** One entry of `signIn.supportedFirstFactors`. */
|
|
143
|
+
|
|
144
|
+
/** The part of the sign-in resource that a first-factor code needs. Tests pass a mock. */
|
|
145
|
+
|
|
146
|
+
/** A first-factor result: the attempt, for the caller to route, or an error. */
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The first-factor strategies in `factors` that the built-in step handles, in
|
|
150
|
+
* preference order. A factor counts only when it has the id that
|
|
151
|
+
* `prepareFirstFactor` needs (`emailAddressId` or `phoneNumberId`).
|
|
152
|
+
*/
|
|
153
|
+
export function supportedFirstFactorStrategies(factors) {
|
|
154
|
+
const list = factors ?? [];
|
|
155
|
+
return FIRST_FACTOR_PREFERENCE.filter(strategy => list.some(factor => factor.strategy === strategy && Boolean(strategy === "email_code" ? factor.emailAddressId : factor.phoneNumberId)));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** The default first-factor strategy: `email_code`, then `phone_code`. `null` when none is supported. */
|
|
159
|
+
export function pickFirstFactorStrategy(factors) {
|
|
160
|
+
return supportedFirstFactorStrategies(factors)[0] ?? null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Sends the first-factor code with the `emailAddressId` or `phoneNumberId` of
|
|
165
|
+
* the matching factor. Without that id it returns an error and makes no call.
|
|
166
|
+
* Never throws.
|
|
167
|
+
*/
|
|
168
|
+
export async function prepareFirstFactorIfNeeded(args) {
|
|
169
|
+
const {
|
|
170
|
+
signIn,
|
|
171
|
+
strategy
|
|
172
|
+
} = args;
|
|
173
|
+
const ms = args.timeoutMs ?? DEFAULT_STAGE_TIMEOUT_MS;
|
|
174
|
+
if (!signIn.prepareFirstFactor) return {
|
|
175
|
+
ok: false,
|
|
176
|
+
error: TOTP_MESSAGES.sendFailed
|
|
177
|
+
};
|
|
178
|
+
const factor = args.factor ?? signIn.supportedFirstFactors?.find(item => item.strategy === strategy);
|
|
179
|
+
try {
|
|
180
|
+
if (strategy === "phone_code") {
|
|
181
|
+
if (!factor?.phoneNumberId) return {
|
|
182
|
+
ok: false,
|
|
183
|
+
error: TOTP_MESSAGES.sendFailed
|
|
184
|
+
};
|
|
185
|
+
await withAuthTimeout(signIn.prepareFirstFactor({
|
|
186
|
+
strategy,
|
|
187
|
+
phoneNumberId: factor.phoneNumberId
|
|
188
|
+
}), "prepare-first-factor", ms);
|
|
189
|
+
} else {
|
|
190
|
+
if (!factor?.emailAddressId) return {
|
|
191
|
+
ok: false,
|
|
192
|
+
error: TOTP_MESSAGES.sendFailed
|
|
193
|
+
};
|
|
194
|
+
await withAuthTimeout(signIn.prepareFirstFactor({
|
|
195
|
+
strategy,
|
|
196
|
+
emailAddressId: factor.emailAddressId
|
|
197
|
+
}), "prepare-first-factor", ms);
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
ok: true
|
|
201
|
+
};
|
|
202
|
+
} catch (caught) {
|
|
203
|
+
logTimeout("prepare-first-factor", caught);
|
|
204
|
+
return {
|
|
205
|
+
ok: false,
|
|
206
|
+
error: authErrorMessage(caught, TOTP_MESSAGES.sendFailed)
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Checks a first-factor code. It does not start the session: the attempt may
|
|
213
|
+
* need a second factor or a new password, so the caller routes it. Never
|
|
214
|
+
* throws: a failure is `{ ok: false, error }`.
|
|
215
|
+
*/
|
|
216
|
+
export async function submitFirstFactor(args) {
|
|
217
|
+
try {
|
|
218
|
+
const attempt = await withAuthTimeout(args.signIn.attemptFirstFactor({
|
|
219
|
+
strategy: args.strategy,
|
|
220
|
+
code: args.code
|
|
221
|
+
}), "attempt-first-factor", args.timeoutMs ?? DEFAULT_STAGE_TIMEOUT_MS);
|
|
222
|
+
return {
|
|
223
|
+
ok: true,
|
|
224
|
+
attempt
|
|
225
|
+
};
|
|
226
|
+
} catch (caught) {
|
|
227
|
+
logTimeout("attempt-first-factor", caught);
|
|
228
|
+
return {
|
|
229
|
+
ok: false,
|
|
230
|
+
error: authErrorMessage(caught, TOTP_MESSAGES.invalidCodeGeneric)
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** Checks a TOTP code and starts the session. TOTP needs no `prepareSecondFactor`. Same as `submitSecondFactor` with `strategy: "totp"`. */
|
|
236
|
+
export function submitTotpSecondFactor(args) {
|
|
237
|
+
return submitSecondFactor({
|
|
238
|
+
signIn: args.signIn,
|
|
239
|
+
setActive: args.setActive,
|
|
240
|
+
code: args.code,
|
|
241
|
+
strategy: "totp",
|
|
242
|
+
timeoutMs: args.timeoutMs
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Completes a sign-in that returned `needs_second_factor`. Default strategy
|
|
247
|
+
* `"totp"` (an authenticator-app code); pass `{ strategy }` or call
|
|
248
|
+
* `setStrategy` for the others. Pair with `SecondFactorScreen`:
|
|
249
|
+
* `onSubmit={submit}`, `error={error}`, `loading={loading}`. After
|
|
250
|
+
* `{ ok: true }` the session is active: navigate in the caller.
|
|
251
|
+
*/
|
|
252
|
+
export function useSecondFactor(t0) {
|
|
253
|
+
const $ = _c(22);
|
|
254
|
+
let t1;
|
|
255
|
+
if ($[0] !== t0) {
|
|
256
|
+
t1 = t0 === undefined ? {} : t0;
|
|
257
|
+
$[0] = t0;
|
|
258
|
+
$[1] = t1;
|
|
259
|
+
} else {
|
|
260
|
+
t1 = $[1];
|
|
261
|
+
}
|
|
262
|
+
const options = t1;
|
|
263
|
+
const {
|
|
264
|
+
isLoaded,
|
|
265
|
+
signIn,
|
|
266
|
+
setActive
|
|
267
|
+
} = useSignIn();
|
|
268
|
+
const [chosen, setChosen] = useState(null);
|
|
269
|
+
const strategy = chosen ?? options.strategy ?? "totp";
|
|
270
|
+
const [loading, setLoading] = useState(false);
|
|
271
|
+
const [error, setError] = useState("");
|
|
272
|
+
const timeoutMs = options.stageTimeoutMs ?? DEFAULT_STAGE_TIMEOUT_MS;
|
|
273
|
+
let t2;
|
|
274
|
+
if ($[2] !== error || $[3] !== isLoaded || $[4] !== loading || $[5] !== setActive || $[6] !== signIn || $[7] !== strategy || $[8] !== timeoutMs) {
|
|
275
|
+
t2 = async code => {
|
|
276
|
+
if (loading) {
|
|
277
|
+
return {
|
|
278
|
+
ok: false,
|
|
279
|
+
error
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
if (!isLoaded || !signIn || !setActive) {
|
|
283
|
+
setError(TOTP_MESSAGES.notReady);
|
|
284
|
+
return {
|
|
285
|
+
ok: false,
|
|
286
|
+
error: TOTP_MESSAGES.notReady
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
setLoading(true);
|
|
290
|
+
setError("");
|
|
291
|
+
const result = await submitSecondFactor({
|
|
292
|
+
signIn,
|
|
293
|
+
setActive,
|
|
294
|
+
code,
|
|
295
|
+
strategy,
|
|
296
|
+
timeoutMs
|
|
297
|
+
});
|
|
298
|
+
if (!result.ok) {
|
|
299
|
+
setError(result.error);
|
|
300
|
+
}
|
|
301
|
+
setLoading(false);
|
|
302
|
+
return result;
|
|
303
|
+
};
|
|
304
|
+
$[2] = error;
|
|
305
|
+
$[3] = isLoaded;
|
|
306
|
+
$[4] = loading;
|
|
307
|
+
$[5] = setActive;
|
|
308
|
+
$[6] = signIn;
|
|
309
|
+
$[7] = strategy;
|
|
310
|
+
$[8] = timeoutMs;
|
|
311
|
+
$[9] = t2;
|
|
312
|
+
} else {
|
|
313
|
+
t2 = $[9];
|
|
314
|
+
}
|
|
315
|
+
const submit = t2;
|
|
316
|
+
let t3;
|
|
317
|
+
if ($[10] !== isLoaded || $[11] !== signIn || $[12] !== strategy || $[13] !== timeoutMs) {
|
|
318
|
+
t3 = async (t4, factor) => {
|
|
319
|
+
const prepareStrategy = t4 === undefined ? strategy : t4;
|
|
320
|
+
if (!isLoaded || !signIn) {
|
|
321
|
+
setError(TOTP_MESSAGES.notReady);
|
|
322
|
+
return {
|
|
323
|
+
ok: false,
|
|
324
|
+
error: TOTP_MESSAGES.notReady
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
setLoading(true);
|
|
328
|
+
setError("");
|
|
329
|
+
const result_0 = await prepareSecondFactorIfNeeded({
|
|
330
|
+
signIn,
|
|
331
|
+
strategy: prepareStrategy,
|
|
332
|
+
factor,
|
|
333
|
+
timeoutMs
|
|
334
|
+
});
|
|
335
|
+
if (!result_0.ok) {
|
|
336
|
+
setError(result_0.error);
|
|
337
|
+
}
|
|
338
|
+
setLoading(false);
|
|
339
|
+
return result_0;
|
|
340
|
+
};
|
|
341
|
+
$[10] = isLoaded;
|
|
342
|
+
$[11] = signIn;
|
|
343
|
+
$[12] = strategy;
|
|
344
|
+
$[13] = timeoutMs;
|
|
345
|
+
$[14] = t3;
|
|
346
|
+
} else {
|
|
347
|
+
t3 = $[14];
|
|
348
|
+
}
|
|
349
|
+
const prepare = t3;
|
|
350
|
+
let t4;
|
|
351
|
+
if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
|
|
352
|
+
t4 = () => setError("");
|
|
353
|
+
$[15] = t4;
|
|
354
|
+
} else {
|
|
355
|
+
t4 = $[15];
|
|
356
|
+
}
|
|
357
|
+
let t5;
|
|
358
|
+
if ($[16] !== error || $[17] !== loading || $[18] !== prepare || $[19] !== strategy || $[20] !== submit) {
|
|
359
|
+
t5 = {
|
|
360
|
+
submit,
|
|
361
|
+
prepare,
|
|
362
|
+
strategy,
|
|
363
|
+
setStrategy: setChosen,
|
|
364
|
+
loading,
|
|
365
|
+
error,
|
|
366
|
+
clearError: t4
|
|
367
|
+
};
|
|
368
|
+
$[16] = error;
|
|
369
|
+
$[17] = loading;
|
|
370
|
+
$[18] = prepare;
|
|
371
|
+
$[19] = strategy;
|
|
372
|
+
$[20] = submit;
|
|
373
|
+
$[21] = t5;
|
|
374
|
+
} else {
|
|
375
|
+
t5 = $[21];
|
|
376
|
+
}
|
|
377
|
+
return t5;
|
|
378
|
+
}
|
package/dist/blur.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
let expoBlur;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `expo-blur`, or `null` when the optional peer is not installed. Metro
|
|
5
|
+
* bundles a `require` placed directly in a `try` block as an optional
|
|
6
|
+
* dependency, so a missing peer does not break the bundle.
|
|
7
|
+
*/
|
|
8
|
+
export function loadBlur() {
|
|
9
|
+
if (expoBlur === undefined) {
|
|
10
|
+
try {
|
|
11
|
+
expoBlur = require("expo-blur");
|
|
12
|
+
} catch {
|
|
13
|
+
expoBlur = null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return expoBlur;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* How a floating surface draws its glass: a native `BlurView` on iOS and
|
|
20
|
+
* Android, a CSS backdrop blur on web, or the solid fill when blur is off,
|
|
21
|
+
* Reduce Transparency is on or `expo-blur` is missing.
|
|
22
|
+
*/
|
|
23
|
+
export function glassMode({
|
|
24
|
+
os,
|
|
25
|
+
blur,
|
|
26
|
+
reduceTransparency,
|
|
27
|
+
hasBlurView
|
|
28
|
+
}) {
|
|
29
|
+
if (!blur || reduceTransparency) {
|
|
30
|
+
return "solid";
|
|
31
|
+
}
|
|
32
|
+
if (os === "web") {
|
|
33
|
+
return "backdrop";
|
|
34
|
+
}
|
|
35
|
+
return (os === "ios" || os === "android") && hasBlurView ? "blur" : "solid";
|
|
36
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { c as _c } from "react/compiler-runtime";
|
|
2
|
+
import { Platform } from "react-native";
|
|
3
|
+
import Svg, { G, Path } from "react-native-svg";
|
|
4
|
+
import { svgA11yProps } from "../svgA11y";
|
|
5
|
+
import { tokens } from "../tokens";
|
|
6
|
+
import { useScheme } from "../useScheme";
|
|
7
|
+
import { APP_MARKS, APP_MARK_VIEWBOX, APP_MARK_VIEWBOX_START, APP_NAMES, markLinecap, markStrokeWidth } from "./svg";
|
|
8
|
+
function viewBoxSide(app) {
|
|
9
|
+
return Number(APP_MARK_VIEWBOX[app].split(" ")[3]);
|
|
10
|
+
}
|
|
11
|
+
function createAppIcon(app, displayName) {
|
|
12
|
+
function Icon(t0) {
|
|
13
|
+
const $ = _c(18);
|
|
14
|
+
const {
|
|
15
|
+
size: t1,
|
|
16
|
+
color,
|
|
17
|
+
stroke,
|
|
18
|
+
title,
|
|
19
|
+
align: t2,
|
|
20
|
+
testID,
|
|
21
|
+
style
|
|
22
|
+
} = t0;
|
|
23
|
+
const size = t1 === undefined ? 24 : t1;
|
|
24
|
+
const align = t2 === undefined ? "center" : t2;
|
|
25
|
+
const scheme = useScheme();
|
|
26
|
+
const fill = color ?? tokens.color.foreground[scheme];
|
|
27
|
+
const {
|
|
28
|
+
kind,
|
|
29
|
+
paths
|
|
30
|
+
} = APP_MARKS[app];
|
|
31
|
+
let t3;
|
|
32
|
+
if ($[0] !== size || $[1] !== stroke) {
|
|
33
|
+
t3 = stroke === undefined ? markStrokeWidth(app) : stroke * (viewBoxSide(app) / size);
|
|
34
|
+
$[0] = size;
|
|
35
|
+
$[1] = stroke;
|
|
36
|
+
$[2] = t3;
|
|
37
|
+
} else {
|
|
38
|
+
t3 = $[2];
|
|
39
|
+
}
|
|
40
|
+
const strokeWidth = t3;
|
|
41
|
+
let t4;
|
|
42
|
+
if ($[3] !== fill || $[4] !== strokeWidth) {
|
|
43
|
+
t4 = kind === "fill" ? {
|
|
44
|
+
fill
|
|
45
|
+
} : {
|
|
46
|
+
fill: "none",
|
|
47
|
+
stroke: fill,
|
|
48
|
+
strokeWidth,
|
|
49
|
+
strokeLinecap: markLinecap(app),
|
|
50
|
+
strokeLinejoin: "round"
|
|
51
|
+
};
|
|
52
|
+
$[3] = fill;
|
|
53
|
+
$[4] = strokeWidth;
|
|
54
|
+
$[5] = t4;
|
|
55
|
+
} else {
|
|
56
|
+
t4 = $[5];
|
|
57
|
+
}
|
|
58
|
+
const glyphProps = t4;
|
|
59
|
+
const t5 = align === "start" ? APP_MARK_VIEWBOX_START[app] : APP_MARK_VIEWBOX[app];
|
|
60
|
+
let t6;
|
|
61
|
+
if ($[6] !== testID || $[7] !== title) {
|
|
62
|
+
t6 = svgA11yProps({
|
|
63
|
+
title,
|
|
64
|
+
testID
|
|
65
|
+
}, Platform.OS);
|
|
66
|
+
$[6] = testID;
|
|
67
|
+
$[7] = title;
|
|
68
|
+
$[8] = t6;
|
|
69
|
+
} else {
|
|
70
|
+
t6 = $[8];
|
|
71
|
+
}
|
|
72
|
+
let t7;
|
|
73
|
+
if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
|
|
74
|
+
t7 = paths.map(_temp);
|
|
75
|
+
$[9] = t7;
|
|
76
|
+
} else {
|
|
77
|
+
t7 = $[9];
|
|
78
|
+
}
|
|
79
|
+
let t8;
|
|
80
|
+
if ($[10] !== glyphProps) {
|
|
81
|
+
t8 = <G {...glyphProps}>{t7}</G>;
|
|
82
|
+
$[10] = glyphProps;
|
|
83
|
+
$[11] = t8;
|
|
84
|
+
} else {
|
|
85
|
+
t8 = $[11];
|
|
86
|
+
}
|
|
87
|
+
let t9;
|
|
88
|
+
if ($[12] !== size || $[13] !== style || $[14] !== t5 || $[15] !== t6 || $[16] !== t8) {
|
|
89
|
+
t9 = <Svg width={size} height={size} viewBox={t5} preserveAspectRatio="xMidYMid meet" {...t6} style={style}>{t8}</Svg>;
|
|
90
|
+
$[12] = size;
|
|
91
|
+
$[13] = style;
|
|
92
|
+
$[14] = t5;
|
|
93
|
+
$[15] = t6;
|
|
94
|
+
$[16] = t8;
|
|
95
|
+
$[17] = t9;
|
|
96
|
+
} else {
|
|
97
|
+
t9 = $[17];
|
|
98
|
+
}
|
|
99
|
+
return t9;
|
|
100
|
+
}
|
|
101
|
+
function _temp(d) {
|
|
102
|
+
return <Path key={d} d={d} />;
|
|
103
|
+
}
|
|
104
|
+
Icon.displayName = displayName;
|
|
105
|
+
return Icon;
|
|
106
|
+
}
|
|
107
|
+
const iconName = app => `Icon${app === "projectv" ? "ProjectV" : app[0].toUpperCase() + app.slice(1)}`;
|
|
108
|
+
|
|
109
|
+
/** Plain app glyph components by app name, for dynamic lookup. Same paths and viewBoxes as the web `APP_ICONS`. */
|
|
110
|
+
export const APP_ICONS = Object.fromEntries(APP_NAMES.map(app => [app, createAppIcon(app, iconName(app))]));
|
|
111
|
+
export const IconVibot = APP_ICONS.vibot;
|
|
112
|
+
export const IconVhub = APP_ICONS.vhub;
|
|
113
|
+
export const IconVmem = APP_ICONS.vmem;
|
|
114
|
+
export const IconVerve = APP_ICONS.verve;
|
|
115
|
+
export const IconVelth = APP_ICONS.velth;
|
|
116
|
+
export const IconProjectV = APP_ICONS.projectv;
|
|
117
|
+
export const IconEva = APP_ICONS.eva;
|
|
118
|
+
export const IconBee = APP_ICONS.bee;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { c as _c } from "react/compiler-runtime";
|
|
2
|
+
import { Platform } from "react-native";
|
|
3
|
+
import Svg, { G, Path, Rect } from "react-native-svg";
|
|
4
|
+
import { svgA11yProps } from "../svgA11y";
|
|
5
|
+
import { APP_ICONS } from "./AppIcons";
|
|
6
|
+
import { APP_MARKS, MARK_VIEWBOX, TILE_RADIUS, markLinecap, markStrokeWidth } from "./svg";
|
|
7
|
+
const TILE_TONES = {
|
|
8
|
+
tile: {
|
|
9
|
+
bg: "#000",
|
|
10
|
+
fg: "#fff"
|
|
11
|
+
},
|
|
12
|
+
"tile-light": {
|
|
13
|
+
bg: "#fff",
|
|
14
|
+
fg: "#000"
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* One of the six family app marks, as on the web `AppMark`. Tiles share the
|
|
20
|
+
* 1024 grid with the plain mark, so a bare glyph matches the tile glyph.
|
|
21
|
+
* Prefer `APP_ICONS[app]` for plain marks; tiles are for app icons only.
|
|
22
|
+
*/
|
|
23
|
+
export function AppMark(t0) {
|
|
24
|
+
const $ = _c(26);
|
|
25
|
+
const {
|
|
26
|
+
app,
|
|
27
|
+
variant: t1,
|
|
28
|
+
size: t2,
|
|
29
|
+
title,
|
|
30
|
+
testID,
|
|
31
|
+
style
|
|
32
|
+
} = t0;
|
|
33
|
+
const variant = t1 === undefined ? "mark" : t1;
|
|
34
|
+
const size = t2 === undefined ? 24 : t2;
|
|
35
|
+
if (variant === "mark") {
|
|
36
|
+
const Icon = APP_ICONS[app];
|
|
37
|
+
let t3;
|
|
38
|
+
if ($[0] !== Icon || $[1] !== size || $[2] !== style || $[3] !== testID || $[4] !== title) {
|
|
39
|
+
t3 = <Icon size={size} title={title} testID={testID} style={style} />;
|
|
40
|
+
$[0] = Icon;
|
|
41
|
+
$[1] = size;
|
|
42
|
+
$[2] = style;
|
|
43
|
+
$[3] = testID;
|
|
44
|
+
$[4] = title;
|
|
45
|
+
$[5] = t3;
|
|
46
|
+
} else {
|
|
47
|
+
t3 = $[5];
|
|
48
|
+
}
|
|
49
|
+
return t3;
|
|
50
|
+
}
|
|
51
|
+
const {
|
|
52
|
+
kind,
|
|
53
|
+
paths
|
|
54
|
+
} = APP_MARKS[app];
|
|
55
|
+
const tone = TILE_TONES[variant];
|
|
56
|
+
let t3;
|
|
57
|
+
if ($[6] !== app || $[7] !== kind || $[8] !== tone.fg) {
|
|
58
|
+
t3 = kind === "fill" ? {
|
|
59
|
+
fill: tone.fg
|
|
60
|
+
} : {
|
|
61
|
+
fill: "none",
|
|
62
|
+
stroke: tone.fg,
|
|
63
|
+
strokeWidth: markStrokeWidth(app),
|
|
64
|
+
strokeLinecap: markLinecap(app),
|
|
65
|
+
strokeLinejoin: "round"
|
|
66
|
+
};
|
|
67
|
+
$[6] = app;
|
|
68
|
+
$[7] = kind;
|
|
69
|
+
$[8] = tone.fg;
|
|
70
|
+
$[9] = t3;
|
|
71
|
+
} else {
|
|
72
|
+
t3 = $[9];
|
|
73
|
+
}
|
|
74
|
+
const glyphProps = t3;
|
|
75
|
+
let t4;
|
|
76
|
+
if ($[10] !== testID || $[11] !== title) {
|
|
77
|
+
t4 = svgA11yProps({
|
|
78
|
+
title,
|
|
79
|
+
testID
|
|
80
|
+
}, Platform.OS);
|
|
81
|
+
$[10] = testID;
|
|
82
|
+
$[11] = title;
|
|
83
|
+
$[12] = t4;
|
|
84
|
+
} else {
|
|
85
|
+
t4 = $[12];
|
|
86
|
+
}
|
|
87
|
+
let t5;
|
|
88
|
+
if ($[13] !== tone.bg) {
|
|
89
|
+
t5 = <Rect width={1024} height={1024} rx={TILE_RADIUS} fill={tone.bg} />;
|
|
90
|
+
$[13] = tone.bg;
|
|
91
|
+
$[14] = t5;
|
|
92
|
+
} else {
|
|
93
|
+
t5 = $[14];
|
|
94
|
+
}
|
|
95
|
+
let t6;
|
|
96
|
+
if ($[15] !== paths) {
|
|
97
|
+
t6 = paths.map(_temp);
|
|
98
|
+
$[15] = paths;
|
|
99
|
+
$[16] = t6;
|
|
100
|
+
} else {
|
|
101
|
+
t6 = $[16];
|
|
102
|
+
}
|
|
103
|
+
let t7;
|
|
104
|
+
if ($[17] !== glyphProps || $[18] !== t6) {
|
|
105
|
+
t7 = <G {...glyphProps}>{t6}</G>;
|
|
106
|
+
$[17] = glyphProps;
|
|
107
|
+
$[18] = t6;
|
|
108
|
+
$[19] = t7;
|
|
109
|
+
} else {
|
|
110
|
+
t7 = $[19];
|
|
111
|
+
}
|
|
112
|
+
let t8;
|
|
113
|
+
if ($[20] !== size || $[21] !== style || $[22] !== t4 || $[23] !== t5 || $[24] !== t7) {
|
|
114
|
+
t8 = <Svg width={size} height={size} viewBox={MARK_VIEWBOX} preserveAspectRatio="xMidYMid meet" {...t4} style={style}>{t5}{t7}</Svg>;
|
|
115
|
+
$[20] = size;
|
|
116
|
+
$[21] = style;
|
|
117
|
+
$[22] = t4;
|
|
118
|
+
$[23] = t5;
|
|
119
|
+
$[24] = t7;
|
|
120
|
+
$[25] = t8;
|
|
121
|
+
} else {
|
|
122
|
+
t8 = $[25];
|
|
123
|
+
}
|
|
124
|
+
return t8;
|
|
125
|
+
}
|
|
126
|
+
function _temp(d) {
|
|
127
|
+
return <Path key={d} d={d} />;
|
|
128
|
+
}
|