@rsliquidglass/react-native
v0.2.2
Published
Native iOS 26 Liquid Glass components for React Native.
Readme
@rsliquidglass/react-native
Native iOS 26 Liquid Glass components for React Native.
The package wraps UIKit system controls. It does not imitate Liquid Glass with blur views, gradients, screenshots, or custom animations.
Components
RSLiquidGlassTabBar— nativeUITabBar.RSLiquidGlassButton— nativeUIButtonusing glass button configurations.RSLiquidGlassToolbar— nativeUIToolbarwith grouped bar button items.RSLiquidGlassSearchBar— nativeUISearchBarwith a transparent container.
Requirements
- React Native 0.80 or later.
- React 19 or later.
- Xcode 26 SDK to compile the iOS 26 APIs.
- iOS 26 or later to render the Liquid Glass controls.
Every exported component returns null when Liquid Glass is not supported.
The consuming application owns its Android and pre-iOS 26 fallback UI.
Installation
npm install @rsliquidglass/react-native
cd ios && pod installRebuild the iOS application after installing the package or changing native component code. A Metro reload is not enough for Objective-C changes.
Platform check
import { isRSLiquidGlassSupported } from '@rsliquidglass/react-native';
if (!isRSLiquidGlassSupported) {
return <YourFallback />;
}Button
RSLiquidGlassButton supports the standard and prominent UIKit glass button
configurations. Icons use SF Symbol names.
import {
isRSLiquidGlassSupported,
RSLiquidGlassButton,
} from '@rsliquidglass/react-native';
import { Pressable, Text } from 'react-native';
function AddButton({ onPress }: { onPress: () => void }) {
if (!isRSLiquidGlassSupported) {
return (
<Pressable onPress={onPress}>
<Text>Add</Text>
</Pressable>
);
}
return (
<RSLiquidGlassButton
accessibilityLabel="Add item"
fillColor="#7B2ECB"
nativeSymbol="plus"
onPress={onPress}
style={{ height: 48, width: 48 }}
tintColor="#FFFFFF"
variant="prominentGlass"
/>
);
}Button props:
nativeSymbol— SF Symbol name.variant—glassorprominentGlass.tintColor— foreground and symbol color.fillColor— prominent background color.disabled— disables interaction.accessibilityLabel— required accessible name.
The native bridge uses the private event name onLiquidPress internally to
avoid conflicting with React Native's bubbling topPress event. The public
component API remains onPress.
Toolbar
RSLiquidGlassToolbar renders a UIKit toolbar. On iOS 26 its bar button items
participate in the system shared glass background.
import { RSLiquidGlassToolbar } from '@rsliquidglass/react-native';
const actions = [
{
accessibilityLabel: 'Search',
nativeSymbol: 'magnifyingglass',
},
{
accessibilityLabel: 'Filter',
nativeSymbol: 'line.3.horizontal.decrease',
},
];
<RSLiquidGlassToolbar
actions={actions}
onAction={index => {
if (index === 0) openSearch();
if (index === 1) openFilters();
}}
style={{ height: 44, width: 120 }}
tintColor="#7B2ECB"
/>;Actions are reported by their array index. Each action supports:
nativeSymbol;accessibilityLabel;disabled.
Search bar
RSLiquidGlassSearchBar is a controlled native search field. Its outer
UISearchBar background is transparent, so only the system search field is
visible.
import { useState } from 'react';
import { RSLiquidGlassSearchBar } from '@rsliquidglass/react-native';
function SearchControl() {
const [query, setQuery] = useState('');
return (
<RSLiquidGlassSearchBar
onChangeText={setQuery}
placeholder="Search conversations"
showsCancelButton={false}
style={{ height: 44, width: '100%' }}
tintColor="#7B2ECB"
value={query}
/>
);
}Use showsCancelButton only when the screen does not already provide its own
close or search-toggle button. onCancel runs when the native Cancel control
is selected.
Tab bar
import {
isRSLiquidGlassSupported,
RSLiquidGlassTabBar,
} from '@rsliquidglass/react-native';
import { useState } from 'react';
function AppTabBar() {
const [selectedIndex, setSelectedIndex] = useState(0);
if (!isRSLiquidGlassSupported) return <YourTabBar />;
return (
<RSLiquidGlassTabBar
activeColor="#7B2ECB"
inactiveColor="#6B7280"
items={[
{ title: 'Home', nativeSymbol: 'house' },
{ title: 'Profile', nativeSymbol: 'person' },
]}
onSelect={setSelectedIndex}
selectedIndex={selectedIndex}
style={{ height: 64, width: '100%' }}
/>
);
}activeColor maps to UITabBar.tintColor. inactiveColor maps to
UITabBar.unselectedItemTintColor.
React Navigation
React Navigation's tabBar option is a render callback. If the component that
renders the native tab bar uses hooks, return it as JSX from a separate
callback instead of passing the component directly.
import type { BottomTabBarProps } from '@react-navigation/bottom-tabs';
function renderTabBar(props: BottomTabBarProps) {
return <NavigationTabBar {...props} />;
}
function NavigationTabBar({ state }: BottomTabBarProps) {
return <YourTabBar selectedIndex={state.index} />;
}
<Tab.Navigator tabBar={renderTabBar}>{/* screens */}</Tab.Navigator>;Development
npm install
npm run typecheckTo validate native changes, install this package in a React Native application,
run pod install in that application's ios directory, and perform a full
Xcode build with the iOS 26 SDK.
