add glassy effect to headers

This commit is contained in:
Samuel Newman
2025-03-04 00:02:44 +00:00
parent 95ab4fa0a1
commit a94a99bb40
9 changed files with 62 additions and 16 deletions
+4 -4
View File
@@ -240,7 +240,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
}
} else if (variant === 'ghost') {
if (!disabled) {
baseStyles.push(t.atoms.bg)
baseStyles.push(a.bg_transparent)
hoverStyles.push({
backgroundColor: t.palette.primary_100,
})
@@ -271,7 +271,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
}
} else if (variant === 'ghost') {
if (!disabled) {
baseStyles.push(t.atoms.bg)
baseStyles.push(a.bg_transparent)
hoverStyles.push({
backgroundColor: t.palette.contrast_25,
})
@@ -308,7 +308,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
}
} else if (variant === 'ghost') {
if (!disabled) {
baseStyles.push(t.atoms.bg)
baseStyles.push(a.bg_transparent)
hoverStyles.push({
backgroundColor: t.palette.contrast_25,
})
@@ -351,7 +351,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
}
} else if (variant === 'ghost') {
if (!disabled) {
baseStyles.push(t.atoms.bg)
baseStyles.push(a.bg_transparent)
hoverStyles.push({
backgroundColor: t.palette.negative_100,
})
@@ -0,0 +1,13 @@
import {View} from 'react-native'
import {atoms as a, useTheme} from '#/alf'
/**
* GlassyBackdrop component
* On web, it applies a backdrop filter to create a glassy effect.
* On native and non-safari mobile web, it's just a solid color.
*/
export function GlassyBackdrop() {
const t = useTheme()
return <View style={[a.absolute, a.inset_0, t.atoms.bg]} />
}
@@ -0,0 +1,31 @@
import {View} from 'react-native'
import {isAndroidWeb} from '#/lib/browser'
import {atoms as a, useTheme} from '#/alf'
/**
* GlassyBackdrop component
* On web, it applies a backdrop filter to create a glassy effect.
* On native and non-safari mobile web, it's just a solid color.
*/
export function GlassyBackdrop() {
const t = useTheme()
if (isAndroidWeb) {
return <View style={[a.absolute, a.inset_0, t.atoms.bg]} />
}
return (
<>
<View style={[a.absolute, a.inset_0, t.atoms.bg, {opacity: 0.9}]} />
<View
style={[
a.absolute,
a.inset_0,
a.pointer_events_none,
{backdropFilter: 'blur(16px)'},
]}
/>
</>
)
}
+4 -6
View File
@@ -29,6 +29,7 @@ import {
} from '#/components/Layout/const'
import {ScrollbarOffsetContext} from '#/components/Layout/context'
import {Text} from '#/components/Typography'
import {GlassyBackdrop} from './GlassyBackdrop'
export function Outer({
children,
@@ -56,7 +57,7 @@ export function Outer({
a.flex_row,
a.align_center,
a.gap_sm,
sticky && web([a.sticky, {top: 0}, a.z_10, t.atoms.bg]),
sticky && web([a.sticky, {top: 0}, a.z_10]),
gutters,
platform({
native: [a.pb_xs, {minHeight: 48}],
@@ -71,6 +72,7 @@ export function Outer({
],
},
]}>
{sticky && <GlassyBackdrop />}
{children}
</View>
)
@@ -131,11 +133,7 @@ export function BackButton({onPress, style, ...props}: Partial<ButtonProps>) {
shape="square"
onPress={onPressBack}
hitSlop={HITSLOP_30}
style={[
{marginLeft: -BUTTON_VISUAL_ALIGNMENT_OFFSET},
a.bg_transparent,
style,
]}
style={[{marginLeft: -BUTTON_VISUAL_ALIGNMENT_OFFSET}, style]}
{...props}>
<ButtonIcon icon={ArrowLeft} size="lg" />
</Button>
@@ -182,8 +182,7 @@ export function ProfileFeedHeader({info}: {info: FeedSourceFeedInfo}) {
return (
<>
<Layout.Center
style={[t.atoms.bg, a.z_10, web([a.sticky, a.z_10, {top: 0}])]}>
<Layout.Center style={[a.z_10, web([a.sticky, a.z_10, {top: 0}])]}>
<Layout.Header.Outer>
<Layout.Header.BackButton />
<Layout.Header.Content align="left">
+1 -1
View File
@@ -66,7 +66,7 @@ function HomeHeaderLayoutDesktopAndTablet({
)}
{tabBarAnchor}
<Layout.Center
style={[a.sticky, a.z_10, a.align_center, t.atoms.bg, {top: 0}]}
style={[a.sticky, a.z_10, a.align_center, {top: 0}]}
onLayout={e => {
headerHeight.set(e.nativeEvent.layout.height)
}}>
+2 -2
View File
@@ -11,7 +11,7 @@ import {emitSoftReset} from '#/state/events'
import {useSession} from '#/state/session'
import {useShellLayout} from '#/state/shell/shell-layout'
import {Logo} from '#/view/icons/Logo'
import {atoms as a, useTheme} from '#/alf'
import {atoms as a, native, useTheme} from '#/alf'
import {ButtonIcon} from '#/components/Button'
import {Hashtag_Stroke2_Corner0_Rounded as FeedsIcon} from '#/components/icons/Hashtag'
import * as Layout from '#/components/Layout'
@@ -35,7 +35,7 @@ export function HomeHeaderLayoutMobile({
style={[
a.fixed,
a.z_10,
t.atoms.bg,
native(t.atoms.bg),
{
top: 0,
left: 0,
+1
View File
@@ -30,6 +30,7 @@ export interface TabBarProps {
onPressSelected?: (index: number) => void
dragProgress: SharedValue<number>
dragState: SharedValue<'idle' | 'dragging' | 'settling'>
glassEffect?: boolean
}
const ITEM_PADDING = 10
+5 -1
View File
@@ -2,6 +2,7 @@ import {useCallback, useEffect, useRef} from 'react'
import {type ScrollView, StyleSheet, View} from 'react-native'
import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
import {GlassyBackdrop} from '#/components/Layout/Header/GlassyBackdrop'
import {Text} from '#/components/Typography'
import {PressableWithHover} from '../util/PressableWithHover'
import {DraggableScrollView} from './DraggableScrollView'
@@ -15,6 +16,7 @@ export interface TabBarProps {
onSelect?: (index: number) => void
onPressSelected?: (index: number) => void
glassEffect?: boolean
}
// How much of the previous/next item we're showing
@@ -27,6 +29,7 @@ export function TabBar({
items,
onSelect,
onPressSelected,
glassEffect = true,
}: TabBarProps) {
const t = useTheme()
const scrollElRef = useRef<ScrollView>(null)
@@ -92,8 +95,9 @@ export function TabBar({
return (
<View
testID={testID}
style={[t.atoms.bg, styles.outer]}
style={[styles.outer, !glassEffect && t.atoms.bg]}
accessibilityRole="tablist">
{glassEffect && <GlassyBackdrop />}
<DraggableScrollView
testID={`${testID}-selector`}
horizontal={true}