@ramses-superapp/ramses-ui
v0.1.9
Published
UI kit for Ramses Built Apps
Readme
Ramses UI
A modern, theme-aware UI kit for React Native, designed for Ramses-built apps. Includes customizable components, seamless light/dark theming, and built-in Cairo font support.
Features
- Light & dark mode with auto device detection
- Cairo font family integration (Android/iOS)
- Ready-to-use components: Button, Text, TextInput
- Simple, powerful theming via
ThemeProvider - Ergonomic, theme-aware styling utilities
Installation
npm install @ramses-superapp/ramses-ui
# or
yarn add @ramses-superapp/ramses-uiQuick Start
Wrap your app with the ThemeProvider for automatic theming:
import { ThemeProvider } from '@ramses-superapp/ramses-ui';
export default function App() {
return <ThemeProvider>{/* your app code */}</ThemeProvider>;
}What ThemeProvider Does
When you wrap your app with ThemeProvider, it does more than just provide theming:
- Safe Area Handling: Your app is automatically wrapped in a
SafeAreaViewfor proper layout on all devices. - Keyboard Avoidance: A
KeyboardAvoidingViewis included, so your UI adjusts automatically when the keyboard appears (on both iOS and Android). - Keyboard Dismissal: The entire app is wrapped in a touchable area, so tapping outside of inputs will dismiss the keyboard by default.
- Status Bar Styling: The status bar style and color are set based on the current theme.
This means you get best-practice layout and keyboard handling out of the box—no need to add these wrappers yourself!
Components
RsButton
title(string/number): Button labelprimary(bool): Primary style (default: true)isLoading(bool): Show spinnerdisabled(bool): Disable buttononPress(fn): Press handlerfontSize,fontWeight,textStyle,style,width
RsText
text(string/number): ContentfontSize,fontWeight,textAlign,textTransform,colorpressable(bool),onPress(fn)style,containerStyle
RsTextInput
- All standard
TextInputprops - All
RsTextstyle props containerStyle- Floating label with Cairo font
FontWeight
All components support:
'ExtraLight' | 'Light' | 'Regular' | 'Medium' | 'SemiBold' | 'Bold' | 'ExtraBold' | 'Black'
RsDivider
A flexible, theme-aware divider for separating content, supporting horizontal/vertical orientation, custom thickness, color, margin, and center content (text or custom node).
Props:
direction('row' | 'column'): Divider orientation.'column'(default) is horizontal,'row'is vertical.thickness(number): Line thickness. Default:1.color(string): Line color. Default: theme border color.margin(number): Margin in the opposite direction. Default:8.content(string | ReactNode): Center content (e.g., "or", icon, etc.). Optional.textProps(RsTextStyle): Props for customizingRsTextifcontentis a string.style(ViewStyle): Style for the outer container.lineStyle(ViewStyle): Style for the line(s).
Usage:
import { RsDivider } from '@ramses-superapp/ramses-ui';
// Horizontal divider with text
<RsDivider content="or" />
// Vertical divider (for row layouts)
<RsDivider direction="row" thickness={2} margin={16} />
// Divider with custom node in the center
<RsDivider content={<MyIcon />} color="#A549E5" />
// Simple horizontal line
<RsDivider />RsToggleButton
A two-option, animated toggle switch for binary choices (e.g., Yes/No, On/Off). Theme-aware, fully animated, and adapts to parent width.
Props:
choices([{ label: string, value: T }, { label: string, value: T }]): Array of two options to display. Each option has alabeland avalue.value(T): The currently selected value.onChange((value: T) => void): Callback when the selection changes.style(ViewStyle, optional): Style for the outer container.
Usage:
import { RsToggleButton } from '@ramses-superapp/ramses-ui';
const [value, setValue] = useState<'yes' | 'no'>('yes');
<RsToggleButton
choices={[
{ label: 'Yes', value: 'yes' },
{ label: 'No', value: 'no' },
]}
value={value}
onChange={setValue}
/>;Theming & Customization
ThemeProvider Props
mode:'light' | 'dark' | 'auto'(default:'auto')'auto': Follows device color scheme'light': Forces light mode'dark': Forces dark mode
customLightTheme: (optional) Custom theme object for light modecustomDarkTheme: (optional) Custom theme object for dark mode
Force Light or Dark Mode:
<ThemeProvider mode="light">{/* ... */}</ThemeProvider>
<ThemeProvider mode="dark">{/* ... */}</ThemeProvider>Provide Custom Themes:
import { ThemeProvider, colors } from '@ramses-superapp/ramses-ui';
const MyLightTheme = {
/* ...see below... */
};
const MyDarkTheme = {
/* ...see below... */
};
<ThemeProvider
mode="auto"
customLightTheme={MyLightTheme}
customDarkTheme={MyDarkTheme}
>
{/* ... */}
</ThemeProvider>;Theme Object Structure
type Theme = {
Background: {
screen: string;
input: string;
primaryButton: string;
secondaryButton: string;
};
Text: {
primaryTitle: string;
text: string;
highlightText: string;
inputText: string;
inputPlaceholder: string;
primaryButtonText: string;
secondaryButtonText: string;
};
Borders: {
primaryButton: string;
secondaryButton: string;
input: string;
inputActive: string;
};
StatusBar: {
barStyle: 'light-content' | 'dark-content';
};
};Accessing the Theme
Use the useTheme() hook in your components:
import { useTheme } from '@ramses-superapp/ramses-ui';
const theme = useTheme();Cairo Font Integration
- Fonts are auto-linked for Android/iOS.
- iOS only: Add to your
Info.plist:
<key>UIAppFonts</key>
<array>
<string>Cairo-Regular-Tight.ttf</string>
<string>Cairo-Bold-Tight.ttf</string>
<string>Cairo-ExtraBold-Tight.ttf</string>
<string>Cairo-Black-Tight.ttf</string>
<string>Cairo-ExtraLight-Tight.ttf</string>
<string>Cairo-Light-Tight.ttf</string>
<string>Cairo-Medium-Tight.ttf</string>
<string>Cairo-SemiBold-Tight.ttf</string>
</array>- Clean & rebuild your app after linking fonts.
Theme-Aware Styling
User-Friendly: useStyles
The easiest way to create theme-aware and dynamic styles.
Just provide a style object factory that receives the current theme and any state/props you want.
import { useStyles } from '@ramses-superapp/ramses-ui';
function MyComponent({ isActive }) {
const styles = useStyles(
(theme, { isActive }) => ({
container: {
backgroundColor: isActive
? theme.Background.primaryButton
: theme.Background.screen,
padding: 16,
borderRadius: 8,
},
text: {
color: theme.Text.text,
fontSize: 18,
},
}),
{ isActive }
);
return (
<View style={styles.container}>
<Text style={styles.text}>Hello Themed World</Text>
</View>
);
}- No need to call
StyleSheet.createoruseMemoyourself. - Styles update automatically when the theme or any prop/state changes.
Advanced: useThemedStyles
If you need more control over memoization or want to pass multiple arguments, use the lower-level useThemedStyles hook.
import { useThemedStyles, type Theme } from '@ramses-superapp/ramses-ui';
import { StyleSheet } from 'react-native';
const generateStyles = (theme: Theme, isActive: boolean) =>
StyleSheet.create({
container: {
backgroundColor: isActive
? theme.Background.primaryButton
: theme.Background.screen,
padding: 16,
borderRadius: 8,
},
text: {
color: theme.Text.text,
fontSize: 18,
},
});
function MyComponent({ isActive }) {
const styles = useThemedStyles(generateStyles, isActive);
return (
<View style={styles.container}>
<Text style={styles.text}>Hello Themed World</Text>
</View>
);
}Scripts
yarn test– Run testsyarn lint– Lint codeyarn typecheck– TypeScript checkyarn clean– Clean build artifactsyarn example– Run example app
License
MIT
Made with create-react-native-library
