@mujohn/ui
v0.1.12
Published
Reusable React Native UI toolkit with components, hooks, utilities, and theme support.
Maintainers
Readme
@mujohn/ui
Comprehensive, reusable React Native UI toolkit with components, hooks, utilities, and theme support.
Installation
npm install @mujohn/uiPeer Dependencies
npm install react-native-vector-icons react-native-safe-area-context react-native-toast-message react-native-reanimatedFor iOS projects using CocoaPods:
npx pod-install ios🚀 Root Setup
Wrap your application entry point with ThemeProvider, AppSafeArea, AppAlertProvider, and Toast:
import React from 'react';
import {
ThemeProvider,
AppSafeArea,
AppAlertProvider,
AppStatusBar,
toastConfig,
} from '@mujohn/ui';
import Toast from 'react-native-toast-message';
export default function App() {
return (
<ThemeProvider>
<AppSafeArea style={{ flex: 1 }}>
<AppAlertProvider>
<AppStatusBar backgroundColor="#69c6d8" barStyle="light-content" />
{/* Your App Content */}
<Toast config={toastConfig} />
</AppAlertProvider>
</AppSafeArea>
</ThemeProvider>
);
}📦 Component Usage Guide
1. Buttons & Controls
AppButton
import React from 'react';
import { AppButton } from '@mujohn/ui';
function Example() {
return (
<AppButton
title="Submit"
variant="primary" // 'primary' | 'outline' | 'ghost'
loading={false}
fullWidth
onPress={() => console.log('Pressed')}
/>
);
}AppBottomButton
Sticky bottom button with safe area inset handling:
import React from 'react';
import { AppBottomButton } from '@mujohn/ui';
function Example() {
return (
<AppBottomButton title="Continue" onPress={() => console.log('Continue')} />
);
}AppSwitch
import React, { useState } from 'react';
import { AppSwitch } from '@mujohn/ui';
function Example() {
const [enabled, setEnabled] = useState(false);
return <AppSwitch value={enabled} onValueChange={setEnabled} />;
}2. Inputs & Selection
AppInput
import React, { useState } from 'react';
import { AppInput } from '@mujohn/ui';
function Example() {
const [email, setEmail] = useState('');
return (
<AppInput
label="Email Address"
placeholder="enter email..."
value={email}
onChangeText={setEmail}
showPaste
/>
);
}AppOTP
import React, { useState } from 'react';
import { AppOTP } from '@mujohn/ui';
function Example() {
const [otp, setOtp] = useState('');
return (
<AppOTP
value={otp}
length={6}
onChange={setOtp}
title="Enter Verification Code"
/>
);
}AppDropdown
import React, { useState } from 'react';
import { AppDropdown } from '@mujohn/ui';
const data = [
{ label: 'Option 1', value: 'opt1' },
{ label: 'Option 2', value: 'opt2' },
];
function Example() {
const [selected, setSelected] = useState('');
return (
<AppDropdown
label="Select Option"
placeholder="Choose an option"
data={data}
value={selected}
onSelect={(item) => setSelected(item.value)}
/>
);
}AppCountryCodePicker
import React, { useState } from 'react';
import { AppCountryCodePicker } from '@mujohn/ui';
function Example() {
const [code, setCode] = useState('+1');
return (
<AppCountryCodePicker code={code} setPhoneCode={(_, val) => setCode(val)} />
);
}AppDatePicker
import React, { useState } from 'react';
import { AppDatePicker } from '@mujohn/ui';
function Example() {
const [visible, setVisible] = useState(false);
const [dob, setDob] = useState('1995-05-15');
return (
<AppDatePicker
visible={visible}
value={dob}
onClose={() => setVisible(false)}
onConfirm={(date) => {
setDob(date);
setVisible(false);
}}
/>
);
}DatePickerFullPage
import React, { useState } from 'react';
import { DatePickerFullPage } from '@mujohn/ui';
function Example() {
const [open, setOpen] = useState(false);
const [date, setDate] = useState('1990-01-01');
return (
<DatePickerFullPage
visible={open}
value={date}
onClose={() => setOpen(false)}
onConfirm={(selectedDate) => {
setDate(selectedDate);
setOpen(false);
}}
/>
);
}3. Modals & Sheets
AppModal
import React, { useState } from 'react';
import { AppModal, AppText, AppButton } from '@mujohn/ui';
function Example() {
const [visible, setVisible] = useState(false);
return (
<>
<AppButton title="Show Modal" onPress={() => setVisible(true)} />
<AppModal visible={visible} onClose={() => setVisible(false)}>
<AppText variant="title">Modal Header</AppText>
<AppText>Modal body content goes here.</AppText>
</AppModal>
</>
);
}AppBottomSheet
import React, { useRef } from 'react';
import {
AppBottomSheet,
AppButton,
AppText,
RBSheetRefProps,
} from '@mujohn/ui';
function Example() {
const sheetRef = useRef<RBSheetRefProps>(null);
return (
<>
<AppButton
title="Open Bottom Sheet"
onPress={() => sheetRef.current?.open()}
/>
<AppBottomSheet ref={sheetRef} label="Sheet Title" height={400}>
<AppText>Bottom sheet scrollable content.</AppText>
</AppBottomSheet>
</>
);
}AppRBSheet
import React, { useRef } from 'react';
import { AppRBSheet, AppButton, AppText, RBSheetRefProps } from '@mujohn/ui';
function Example() {
const sheetRef = useRef<RBSheetRefProps>(null);
return (
<>
<AppButton
title="Open RBSheet"
onPress={() => sheetRef.current?.open()}
/>
<AppRBSheet ref={sheetRef} label="Options" height={350}>
<AppText>Custom RBSheet content</AppText>
</AppRBSheet>
</>
);
}AppAlert & useAppAlert
import React from 'react';
import { AppButton, useAppAlert } from '@mujohn/ui';
function Example() {
const alert = useAppAlert();
const handleAlert = () => {
alert?.show('Confirmation', 'Are you sure you want to proceed?', [
{ text: 'Cancel', style: 'cancel' },
{
text: 'Delete',
style: 'destructive',
onPress: () => console.log('Deleted'),
},
]);
};
return <AppButton title="Delete Item" onPress={handleAlert} />;
}4. Navigation & Layout
AppHeader
import React from 'react';
import { AppHeader } from '@mujohn/ui';
function Example() {
return (
<AppHeader
title="Dashboard"
subtitle="Welcome back"
left="back"
onLeftPress={() => console.log('Back')}
/>
);
}AppTopTab
import React, { useState } from 'react';
import { AppTopTab } from '@mujohn/ui';
const options = [
{ key: 'all', label: 'All' },
{ key: 'pending', label: 'Pending' },
{ key: 'completed', label: 'Completed' },
];
function Example() {
const [tab, setTab] = useState('all');
return <AppTopTab options={options} value={tab} onChange={setTab} />;
}AppTabBar
import React, { useState } from 'react';
import { AppTabBar } from '@mujohn/ui';
const tabs = [
{ key: 'home', label: 'Home' },
{ key: 'profile', label: 'Profile' },
];
function Example() {
const [active, setActive] = useState('home');
return <AppTabBar tabs={tabs} value={active} onChange={setActive} />;
}AppCard
import React from 'react';
import { AppCard, AppText } from '@mujohn/ui';
function Example() {
return (
<AppCard elevated>
<AppText variant="title">Card Title</AppText>
<AppText color="gray">Card description content.</AppText>
</AppCard>
);
}AppSafeArea & AppStatusBar
import React from 'react';
import { AppSafeArea, AppStatusBar, AppText } from '@mujohn/ui';
function Example() {
return (
<AppSafeArea>
<AppStatusBar backgroundColor="#ffffff" barStyle="dark-content" />
<AppText>Content inside Safe Area</AppText>
</AppSafeArea>
);
}5. Display & Media
AppText
import React from 'react';
import { AppText } from '@mujohn/ui';
function Example() {
return (
<AppText variant="heading" weight="bold" color="#2568EF" align="center">
Hello World
</AppText>
);
}AppIcon
import React from 'react';
import { AppIcon } from '@mujohn/ui';
function Example() {
return (
<AppIcon
type="Feather"
name="check-circle"
size={24}
color="#16A34A"
onPress={() => console.log('Icon pressed')}
/>
);
}AppAvatar
import React from 'react';
import { AppAvatar } from '@mujohn/ui';
function Example() {
return <AppAvatar name="John Doe" size={48} />;
}AppLogo & AppName
import React from 'react';
import { AppLogo, AppName } from '@mujohn/ui';
function Example() {
return (
<>
<AppLogo title="MyApp" width={100} height={30} />
<AppName firstLabel="My" secondLabel="App" />
</>
);
}AppProgressBar
import React from 'react';
import { AppProgressBar } from '@mujohn/ui';
function Example() {
return <AppProgressBar progress={0.75} height={10} color="#2568EF" />;
}AppLoader
import React from 'react';
import { AppLoader } from '@mujohn/ui';
function Example() {
return <AppLoader visible label="Loading data..." overlay />;
}AppTimer
Countdown timer component (MM:SS):
import React from 'react';
import { AppTimer } from '@mujohn/ui';
function Example() {
return (
<AppTimer
seconds={120}
fontSize={16}
onChangeTimer={(sec) => console.log('Remaining:', sec)}
apiRefetch={() => console.log('Timer expired!')}
/>
);
}AppTooltip
import React from 'react';
import { AppTooltip, AppText, AppIcon } from '@mujohn/ui';
function Example() {
return (
<AppTooltip content="This is helpful information" placement="top">
<AppIcon type="Feather" name="info" size={20} />
</AppTooltip>
);
}AppRenderHTML
import React from 'react';
import { AppRenderHTML } from '@mujohn/ui';
function Example() {
return (
<AppRenderHTML html="<h2>HTML Content</h2><p>Rendered seamlessly.</p>" />
);
}AppMoment
import React from 'react';
import { AppMoment, moment } from '@mujohn/ui';
function Example() {
return (
<>
<AppMoment date={new Date()} format="DD MMM YYYY" />
<AppText>{moment(new Date()).format('YYYY-MM-DD')}</AppText>
</>
);
}6. Screens & States
AppUnderMaintenanceScreen
import React from 'react';
import { AppUnderMaintenanceScreen } from '@mujohn/ui';
function MaintenancePage() {
return (
<AppUnderMaintenanceScreen
title="System Maintenance"
description="We are upgrading our servers. Please check back soon."
showRetry
onRetry={() => console.log('Retrying...')}
/>
);
}AppTextLogoScreen
import React from 'react';
import { AppTextLogoScreen } from '@mujohn/ui';
function SplashPage() {
return (
<AppTextLogoScreen firstLabel="WELCOME TO" secondLabel="JOHN CREATION" />
);
}⚓ Custom Hooks
useTheme(): Access current theme colors, spacing, typography, and dark/light mode context.useCountdown(initialSeconds): Countdown timer logic returning{ secondsLeft, start, stop, reset }.useDebounce(value, delay): Debounce state changes.useKeyboard(): Returns{ isKeyboardVisible, keyboardHeight }.usePagination(options): Pagination helper logic for list views.
🛠 Utilities
import {
formatCurrency,
formatDate,
responsiveFont,
responsiveSize,
validateEmail,
storage,
Colors,
} from '@mujohn/ui';
// Currency formatting
const price = formatCurrency(1500, { symbol: '$' }); // "$1,500.00"
// Date formatting
const formatted = formatDate(new Date(), { format: 'YYYY-MM-DD' });
// Responsive scaling
const fontSize = responsiveFont(16);
const width = responsiveSize(100);
// Validation
const isValid = validateEmail('[email protected]');
// Storage wrapper (AsyncStorage)
await storage.set('user_token', 'abc-123');
const token = await storage.get('user_token');
// Theme Color Palette
console.log(Colors.PRIMARY, Colors.WHITE, Colors.BLACK);