Make the pager take full width (#7066)
* Wide tabs for web * Wide tabs on mobile * Tweak min for profile * Driveby border fix * Fix single tab indicator
This commit is contained in:
@@ -107,7 +107,7 @@ export default function HashtagScreen({
|
||||
|
||||
return (
|
||||
<Layout.Screen>
|
||||
<Layout.Header.Outer>
|
||||
<Layout.Header.Outer noBottomBorder>
|
||||
<Layout.Header.BackButton />
|
||||
<Layout.Header.Content>
|
||||
<Layout.Header.TitleText>{headerTitle}</Layout.Header.TitleText>
|
||||
|
||||
@@ -51,6 +51,7 @@ export function TabBar({
|
||||
const containerSize = useSharedValue(0)
|
||||
const scrollX = useSharedValue(0)
|
||||
const layouts = useSharedValue<{x: number; width: number}[]>([])
|
||||
const textLayouts = useSharedValue<{width: number}[]>([])
|
||||
const itemsLength = items.length
|
||||
|
||||
const scrollToOffsetJS = useCallback(
|
||||
@@ -211,21 +212,40 @@ export function TabBar({
|
||||
[layouts],
|
||||
)
|
||||
|
||||
const onTextLayout = useCallback(
|
||||
(i: number, layout: {width: number}) => {
|
||||
'worklet'
|
||||
textLayouts.modify(ls => {
|
||||
ls[i] = layout
|
||||
return ls
|
||||
})
|
||||
},
|
||||
[textLayouts],
|
||||
)
|
||||
|
||||
const indicatorStyle = useAnimatedStyle(() => {
|
||||
if (!_WORKLET) {
|
||||
return {opacity: 0}
|
||||
}
|
||||
const layoutsValue = layouts.get()
|
||||
const textLayoutsValue = textLayouts.get()
|
||||
if (
|
||||
layoutsValue.length !== itemsLength ||
|
||||
layoutsValue.some(l => l === undefined)
|
||||
textLayoutsValue.length !== itemsLength
|
||||
) {
|
||||
return {
|
||||
opacity: 0,
|
||||
}
|
||||
}
|
||||
if (layoutsValue.length === 1) {
|
||||
return {opacity: 1}
|
||||
if (textLayoutsValue.length === 1) {
|
||||
return {
|
||||
opacity: 1,
|
||||
transform: [
|
||||
{
|
||||
scaleX: textLayoutsValue[0].width / contentSize.get(),
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
return {
|
||||
opacity: 1,
|
||||
@@ -240,10 +260,8 @@ export function TabBar({
|
||||
{
|
||||
scaleX: interpolate(
|
||||
dragProgress.get(),
|
||||
layoutsValue.map((l, i) => i),
|
||||
layoutsValue.map(
|
||||
l => (l.width - ITEM_PADDING * 2) / contentSize.get(),
|
||||
),
|
||||
textLayoutsValue.map((l, i) => i),
|
||||
textLayoutsValue.map(l => l.width / contentSize.get()),
|
||||
),
|
||||
},
|
||||
],
|
||||
@@ -287,7 +305,7 @@ export function TabBar({
|
||||
onLayout={e => {
|
||||
contentSize.set(e.nativeEvent.layout.width)
|
||||
}}
|
||||
style={{flexDirection: 'row'}}>
|
||||
style={{flexDirection: 'row', flexGrow: 1}}>
|
||||
{items.map((item, i) => {
|
||||
return (
|
||||
<TabBarItem
|
||||
@@ -298,6 +316,7 @@ export function TabBar({
|
||||
item={item}
|
||||
onPressItem={onPressItem}
|
||||
onItemLayout={onItemLayout}
|
||||
onTextLayout={onTextLayout}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
@@ -328,6 +347,7 @@ function TabBarItem({
|
||||
item,
|
||||
onPressItem,
|
||||
onItemLayout,
|
||||
onTextLayout,
|
||||
}: {
|
||||
index: number
|
||||
testID: string | undefined
|
||||
@@ -335,6 +355,7 @@ function TabBarItem({
|
||||
item: string
|
||||
onPressItem: (index: number) => void
|
||||
onItemLayout: (index: number, layout: {x: number; width: number}) => void
|
||||
onTextLayout: (index: number, layout: {width: number}) => void
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const style = useAnimatedStyle(() => {
|
||||
@@ -358,8 +379,15 @@ function TabBarItem({
|
||||
[index, onItemLayout],
|
||||
)
|
||||
|
||||
const handleTextLayout = useCallback(
|
||||
(e: LayoutChangeEvent) => {
|
||||
runOnUI(onTextLayout)(index, e.nativeEvent.layout)
|
||||
},
|
||||
[index, onTextLayout],
|
||||
)
|
||||
|
||||
return (
|
||||
<View onLayout={handleLayout}>
|
||||
<View onLayout={handleLayout} style={{flexGrow: 1}}>
|
||||
<PressableWithHover
|
||||
testID={`${testID}-selector-${index}`}
|
||||
style={styles.item}
|
||||
@@ -370,7 +398,8 @@ function TabBarItem({
|
||||
<Text
|
||||
emoji
|
||||
testID={testID ? `${testID}-${item}` : undefined}
|
||||
style={[t.atoms.text, a.text_md, a.font_bold, {lineHeight: 20}]}>
|
||||
style={[styles.itemText, t.atoms.text, a.text_md, a.font_bold]}
|
||||
onLayout={handleTextLayout}>
|
||||
{item}
|
||||
</Text>
|
||||
</Animated.View>
|
||||
@@ -381,19 +410,28 @@ function TabBarItem({
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
contentContainer: {
|
||||
flexGrow: 1,
|
||||
backgroundColor: 'transparent',
|
||||
paddingHorizontal: CONTENT_PADDING,
|
||||
},
|
||||
item: {
|
||||
flexGrow: 1,
|
||||
paddingTop: 10,
|
||||
paddingHorizontal: ITEM_PADDING,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
itemInner: {
|
||||
alignItems: 'center',
|
||||
flexGrow: 1,
|
||||
paddingBottom: 10,
|
||||
borderBottomWidth: 3,
|
||||
borderBottomColor: 'transparent',
|
||||
},
|
||||
itemText: {
|
||||
lineHeight: 20,
|
||||
minWidth: 45,
|
||||
textAlign: 'center',
|
||||
},
|
||||
outerBottomBorder: {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
|
||||
@@ -115,12 +115,14 @@ export function TabBar({
|
||||
hoverStyle={t.atoms.bg_contrast_25}
|
||||
onPress={() => onPressItem(i)}
|
||||
accessibilityRole="tab">
|
||||
<View style={[styles.itemInner, selected && indicatorStyle]}>
|
||||
<View style={styles.itemInner}>
|
||||
<Text
|
||||
emoji
|
||||
testID={testID ? `${testID}-${item}` : undefined}
|
||||
style={[
|
||||
styles.itemText,
|
||||
selected ? t.atoms.text : t.atoms.text_contrast_medium,
|
||||
selected && indicatorStyle,
|
||||
a.text_md,
|
||||
a.font_bold,
|
||||
{lineHeight: 20},
|
||||
@@ -143,15 +145,23 @@ const desktopStyles = StyleSheet.create({
|
||||
width: 598,
|
||||
},
|
||||
contentContainer: {
|
||||
flexGrow: 1,
|
||||
paddingHorizontal: 0,
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
item: {
|
||||
flexGrow: 1,
|
||||
alignItems: 'stretch',
|
||||
paddingTop: 14,
|
||||
paddingHorizontal: 14,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
itemInner: {
|
||||
alignItems: 'center',
|
||||
},
|
||||
itemText: {
|
||||
textAlign: 'center',
|
||||
minWidth: 45,
|
||||
paddingBottom: 12,
|
||||
borderBottomWidth: 3,
|
||||
borderBottomColor: 'transparent',
|
||||
@@ -170,15 +180,24 @@ const mobileStyles = StyleSheet.create({
|
||||
flexDirection: 'row',
|
||||
},
|
||||
contentContainer: {
|
||||
flexGrow: 1,
|
||||
backgroundColor: 'transparent',
|
||||
paddingHorizontal: 6,
|
||||
},
|
||||
item: {
|
||||
flexGrow: 1,
|
||||
alignItems: 'stretch',
|
||||
paddingTop: 10,
|
||||
paddingHorizontal: 10,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
itemInner: {
|
||||
flexGrow: 1,
|
||||
alignItems: 'center',
|
||||
},
|
||||
itemText: {
|
||||
textAlign: 'center',
|
||||
minWidth: 45,
|
||||
paddingBottom: 10,
|
||||
borderBottomWidth: 2,
|
||||
borderBottomColor: 'transparent',
|
||||
|
||||
Reference in New Issue
Block a user