In a pretty good state, but might need to just go monolith

This commit is contained in:
Eric Bailey
2026-03-31 21:27:04 -05:00
parent 1a15717eca
commit 7f74dfd143
3 changed files with 58 additions and 41 deletions
+6 -1
View File
@@ -43,7 +43,12 @@ export function Autocomplete({
a.border, a.border,
t.atoms.border_contrast_low, t.atoms.border_contrast_low,
t.atoms.bg, t.atoms.bg,
!IS_WEB && a.w_full, a.w_full,
IS_WEB
? {
maxWidth: 300,
}
: {},
]} ]}
render={render} render={render}
/> />
@@ -44,6 +44,9 @@ export function useAutocomplete({
// TODO return recents // TODO return recents
if (!query) return [] if (!query) return []
// Going from "foo" to "foo." should not clear matches.
query = query.toLowerCase().trim().replace(/\.$/, '')
const res = await agent.searchActorsTypeahead({ const res = await agent.searchActorsTypeahead({
q: query, q: query,
limit: limit || 8, limit: limit || 8,
+49 -40
View File
@@ -161,10 +161,12 @@ export function Root({
const callbackRefs = useRef({ const callbackRefs = useRef({
onActiveFacetOuter, onActiveFacetOuter,
onFacetCommittedOuter, onFacetCommittedOuter,
focus: tapper.input.focus,
}) })
callbackRefs.current = { callbackRefs.current = {
onActiveFacetOuter, onActiveFacetOuter,
onFacetCommittedOuter, onFacetCommittedOuter,
focus: tapper.input.focus,
} }
useImperativeHandle( useImperativeHandle(
@@ -200,9 +202,13 @@ export function Root({
const offFacetCommitted = tapper.on('facetCommitted', facet => { const offFacetCommitted = tapper.on('facetCommitted', facet => {
callbackRefs.current.onFacetCommittedOuter?.(facet) callbackRefs.current.onFacetCommittedOuter?.(facet)
}) })
const offAfterInsert = tapper.on('afterInsert', () => {
callbackRefs.current?.focus()
})
return () => { return () => {
offActiveFacet() offActiveFacet()
offFacetCommitted() offFacetCommitted()
offAfterInsert()
} }
}, [tapper.on]) }, [tapper.on])
@@ -303,6 +309,15 @@ export function Input({
? {height: lineHeight + verticalSpace} ? {height: lineHeight + verticalSpace}
: {minHeight: mh, maxHeight: xh} : {minHeight: mh, maxHeight: xh}
/*
* On iOS especially, TextInput and Text line height does not render the
* same way, but setting this to undefined and using the default font
* metrics works fine.
*/
if (!IS_WEB) {
delete ts.lineHeight
}
return {textStyle: ts, textAreaStyle: tas, minHeight: mh, maxHeight: xh} return {textStyle: ts, textAreaStyle: tas, minHeight: mh, maxHeight: xh}
}, [t, fonts, padding, rawTextStyle, initialNumberOfLines, maxNumberOfLines]) }, [t, fonts, padding, rawTextStyle, initialNumberOfLines, maxNumberOfLines])
@@ -361,43 +376,39 @@ export function Input({
[onRequestSubmit], [onRequestSubmit],
) )
const textContent = (
<Text style={[textStyle, web({whiteSpace: 'pre-wrap'})]}>
{state.nodes.map((node, i) => {
switch (node.type) {
case 'text':
return <Span key={i}>{node.value}</Span>
case 'trigger':
case 'facet':
return (
<Span
key={i}
ref={IS_WEB ? sift.refs.setAnchor : undefined}
style={node.type === 'facet' && {color: t.palette.primary_500}}>
{node.raw}
</Span>
)
}
})}
</Text>
)
return ( return (
<View style={[a.relative, style]}> <View style={[a.relative, style]}>
{IS_WEB && ( <View
<View pointerEvents="none"
pointerEvents="none" style={[a.absolute, a.inset_0, a.z_10, {overflow: 'hidden'}]}>
style={[a.absolute, a.inset_0, a.z_10, {overflow: 'hidden'}]}> <Animated.View
<Animated.View style={[
style={[ padding,
padding, {position: 'absolute', left: 0, right: 0},
{position: 'absolute', left: 0, right: 0}, previewScrollStyle,
previewScrollStyle, ]}>
]}> <Text style={[textStyle, web({whiteSpace: 'pre-wrap'})]}>
{textContent} {state.nodes.map((node, i) => {
</Animated.View> switch (node.type) {
</View> case 'text':
)} return <Span key={i}>{node.value}</Span>
case 'trigger':
case 'facet':
return (
<Span
key={i}
ref={IS_WEB ? sift.refs.setAnchor : undefined}
style={
node.type === 'facet' && {color: t.palette.primary_500}
}>
{node.raw}
</Span>
)
}
})}
</Text>
</Animated.View>
</View>
<TextInput <TextInput
dirName="ltr" dirName="ltr"
autoCapitalize="none" autoCapitalize="none"
@@ -438,7 +449,6 @@ export function Input({
]} ]}
{...rest} {...rest}
{...tapper.inputProps} {...tapper.inputProps}
value={undefined}
{...sift.targetProps} {...sift.targetProps}
ref={mergeRefs([ ref={mergeRefs([
textInputRef, textInputRef,
@@ -464,9 +474,8 @@ export function Input({
// @ts-ignore web only // @ts-ignore web only
onCompositionEnd={() => { onCompositionEnd={() => {
isComposing.current = false isComposing.current = false
}}> }}
{IS_WEB ? null : textContent} />
</TextInput>
</View> </View>
) )
} }
@@ -514,7 +523,7 @@ function AutocompleteInner({
query: activeFacet.value, query: activeFacet.value,
}) })
return data ? ( return data && data.length ? (
<AutocompleteBase <AutocompleteBase
sift={sift} sift={sift}
data={data} data={data}