dev #66
@@ -67,6 +67,7 @@ export function WelcomeOnboardingModal({
|
||||
const [escapeHatchEnabled, setEscapeHatchEnabled] = useState(false);
|
||||
const provisionedRef = useRef(false);
|
||||
const refAppliedRef = useRef(false);
|
||||
const completeCtaRef = useRef<HTMLButtonElement>(null);
|
||||
const MAX_FAILURES = 2;
|
||||
const STUCK_TIMEOUT_MS = 30_000;
|
||||
const [isDark] = useState(() => {
|
||||
@@ -161,6 +162,16 @@ export function WelcomeOnboardingModal({
|
||||
});
|
||||
}, [phase, animationEnded, trialMutation.isSuccess, queryClient]);
|
||||
|
||||
// Auto-focus the primary CTA when the completed card appears so keyboard
|
||||
// users can confirm with Enter without having to tab through the card.
|
||||
useEffect(() => {
|
||||
if (phase === "completed") {
|
||||
// Wait a tick so the element is in the DOM and Radix's focus trap has
|
||||
// already moved focus into the dialog.
|
||||
requestAnimationFrame(() => completeCtaRef.current?.focus());
|
||||
}
|
||||
}, [phase]);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open
|
||||
@@ -240,7 +251,7 @@ export function WelcomeOnboardingModal({
|
||||
)}
|
||||
{trialMutation.isError && !escapeHatchEnabled && (
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
<p className="text-sm leading-5 text-red-600 dark:text-red-400">
|
||||
<p className="text-sm leading-5 text-destructive">
|
||||
{t("subscription.onboarding.error")}
|
||||
</p>
|
||||
<Button variant="outline" onClick={() => trialMutation.mutate()}>
|
||||
@@ -332,6 +343,7 @@ export function WelcomeOnboardingModal({
|
||||
</ul>
|
||||
</div>
|
||||
<Button
|
||||
ref={completeCtaRef}
|
||||
size="lg"
|
||||
className="bg-brand text-brand-foreground hover:bg-brand/90"
|
||||
onClick={() => {
|
||||
|
||||
Reference in New Issue
Block a user