From 93c4719a2140070b33f69dd0f12b4de2619a25a6 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Fri, 8 Aug 2025 01:01:01 +0300 Subject: Check handle as you type (#8601) * check handle as you type * metrics * add metric types * fix overflow * only check reserved handles for bsky.social, fix test * change validation check name * tweak input * move ghosttext component to textfield * tweak styles to try and match latest * add suggestions * improvements, metrics * share logic between typeahead and next button * Apply suggestions from code review Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * update checks, disable button if unavailable * convert to lowercase * fix bug with checkHandleAvailability * add gate * move files around to make clearer * fix bad import * Fix flashing next button * Enable for TF --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> Co-authored-by: Hailey Co-authored-by: Eric Bailey --- src/components/forms/TextField.tsx | 84 ++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 9 deletions(-) (limited to 'src/components/forms/TextField.tsx') diff --git a/src/components/forms/TextField.tsx b/src/components/forms/TextField.tsx index 9b7ada319..3913c3283 100644 --- a/src/components/forms/TextField.tsx +++ b/src/components/forms/TextField.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import {createContext, useContext, useMemo, useRef} from 'react' import { type AccessibilityProps, StyleSheet, @@ -16,7 +16,9 @@ import { applyFonts, atoms as a, ios, + platform, type TextStyleProp, + tokens, useAlf, useTheme, web, @@ -25,7 +27,7 @@ import {useInteractionState} from '#/components/hooks/useInteractionState' import {type Props as SVGIconProps} from '#/components/icons/common' import {Text} from '#/components/Typography' -const Context = React.createContext<{ +const Context = createContext<{ inputRef: React.RefObject | null isInvalid: boolean hovered: boolean @@ -48,7 +50,7 @@ const Context = React.createContext<{ export type RootProps = React.PropsWithChildren<{isInvalid?: boolean}> export function Root({children, isInvalid = false}: RootProps) { - const inputRef = React.useRef(null) + const inputRef = useRef(null) const { state: hovered, onIn: onHoverIn, @@ -56,7 +58,7 @@ export function Root({children, isInvalid = false}: RootProps) { } = useInteractionState() const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState() - const context = React.useMemo( + const context = useMemo( () => ({ inputRef, hovered, @@ -96,7 +98,7 @@ export function Root({children, isInvalid = false}: RootProps) { export function useSharedInputStyles() { const t = useTheme() - return React.useMemo(() => { + return useMemo(() => { const hover: ViewStyle[] = [ { borderColor: t.palette.contrast_100, @@ -158,7 +160,7 @@ export function createInput(Component: typeof TextInput) { }: InputProps) { const t = useTheme() const {fonts} = useAlf() - const ctx = React.useContext(Context) + const ctx = useContext(Context) const withinRoot = Boolean(ctx.inputRef) const {chromeHover, chromeFocus, chromeError, chromeErrorHover} = @@ -283,8 +285,8 @@ export function LabelText({ export function Icon({icon: Comp}: {icon: React.ComponentType}) { const t = useTheme() - const ctx = React.useContext(Context) - const {hover, focus, errorHover, errorFocus} = React.useMemo(() => { + const ctx = useContext(Context) + const {hover, focus, errorHover, errorFocus} = useMemo(() => { const hover: TextStyle[] = [ { color: t.palette.contrast_800, @@ -342,7 +344,7 @@ export function SuffixText({ } >) { const t = useTheme() - const ctx = React.useContext(Context) + const ctx = useContext(Context) return ( ) } + +export function GhostText({ + children, + value, +}: { + children: string + value: string +}) { + const t = useTheme() + // eslint-disable-next-line bsky-internal/avoid-unwrapped-text + return ( + + + {children} + + {value} + + + + ) +} -- cgit 1.4.1