+24
src/hooks/useRotatingPlaceholder.ts
+24
src/hooks/useRotatingPlaceholder.ts
···
1
+
import { useState, useEffect } from "react";
2
+
3
+
const PLATFORM_EXAMPLES = [
4
+
"username.bsky.social",
5
+
"username.blacksky.app",
6
+
"username.tgnl.sh",
7
+
"username.com",
8
+
];
9
+
10
+
const ROTATION_INTERVAL = 3000; // 3 seconds
11
+
12
+
export function useRotatingPlaceholder(): string {
13
+
const [index, setIndex] = useState(0);
14
+
15
+
useEffect(() => {
16
+
const interval = setInterval(() => {
17
+
setIndex((prev) => (prev + 1) % PLATFORM_EXAMPLES.length);
18
+
}, ROTATION_INTERVAL);
19
+
20
+
return () => clearInterval(interval);
21
+
}, []);
22
+
23
+
return PLATFORM_EXAMPLES[index];
24
+
}
+3
-1
src/pages/Login.tsx
+3
-1
src/pages/Login.tsx
···
3
3
import { ArrowRight, AlertCircle, Info } from "lucide-react";
4
4
import { useFormValidation } from "../hooks/useFormValidation";
5
5
import { validateHandle } from "../lib/validation";
6
+
import { useRotatingPlaceholder } from "../hooks/useRotatingPlaceholder";
6
7
import HeroSection from "../components/login/HeroSection";
7
8
import ValuePropsSection from "../components/login/ValuePropsSection";
8
9
import HowItWorksSection from "../components/login/HowItWorksSection";
···
25
26
const [isSubmitting, setIsSubmitting] = useState(false);
26
27
const [strippedAtMessage, setStrippedAtMessage] = useState(false);
27
28
const [selectedAvatar, setSelectedAvatar] = useState<string | null>(null);
29
+
const placeholder = useRotatingPlaceholder();
28
30
29
31
const { fields, setValue, validate, getFieldProps } = useFormValidation({
30
32
handle: "",
···
165
167
ref={inputRef}
166
168
id="atproto-handle"
167
169
{...getFieldProps("handle")}
168
-
placeholder="username.bsky.social"
170
+
placeholder={placeholder}
169
171
error={fields.handle.touched && !!fields.handle.error}
170
172
selectedAvatar={selectedAvatar}
171
173
aria-required="true"