Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .cursor/rules/testing-guidelines.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ alwaysApply: true
```typescript
import React from 'react'
import {render, fireEvent} from '@testing-library/react-native'
import {Button} from '../components/Button'
import {ButtonPrimary} from '../components/Button'
import {BaseProvider} from '../core/BaseProvider'

const renderWithProvider = (component: React.ReactElement) => {
Expand Down Expand Up @@ -55,9 +55,9 @@ describe('Button Component', () => {

it('applies correct styles for variants', () => {
const {getByTestId} = renderWithProvider(
<Button variant="primary" testID="primary-button">Primary</Button>
<ButtonPrimary testID="primary-button">Primary</ButtonPrimary>
)

const button = getByTestId('primary-button')
// Test styling expectations
})
Expand Down
34 changes: 23 additions & 11 deletions example/app/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
import { Stack } from 'expo-router'
import { ScreenProps, Stack } from 'expo-router'
import { StatusBar } from 'expo-status-bar'
import 'react-native-reanimated'

import React from 'react'
import { BaseProvider } from 'rn-base-component'

const baseHeaderOptions: ScreenProps['options']
= {
headerShown: true,
headerBackTitle: 'Back',
headerStyle: {
backgroundColor: '#f8f9fa',
},
headerTintColor: '#1a1a1a',
headerTitleStyle: {
fontWeight: 'bold',
fontSize: 18,
},
}

export default function RootLayout() {

return (
<BaseProvider>
<Stack>
Expand All @@ -20,16 +34,14 @@ export default function RootLayout() {
name="code-input"
options={{
title: 'CodeInput Component',
headerShown: true,
headerBackTitle: 'Back',
headerStyle: {
backgroundColor: '#f8f9fa',
},
headerTintColor: '#1a1a1a',
headerTitleStyle: {
fontWeight: 'bold',
fontSize: 18,
},
...baseHeaderOptions,
}}
/>
<Stack.Screen
name="text-input"
options={{
title: 'TextInput Component',
...baseHeaderOptions,
}}
/>
</Stack>
Expand Down
8 changes: 8 additions & 0 deletions example/app/text-input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react'
import { TextInputDemo } from '@/components/TextInputDemo'

const TextInputDemoScreen = () => {
return <TextInputDemo />
}

export default TextInputDemoScreen
60 changes: 60 additions & 0 deletions example/components/TextInputDemo/BasicExamples.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useState } from 'react'
import { Text, View } from 'react-native'
import { TextInput } from 'rn-base-component'
import { demoStyles } from './styles'

export const BasicExamples = () => {
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [phone, setPhone] = useState('')

return (
<View style={demoStyles.section}>
<Text style={demoStyles.sectionTitle}>📝 Basic Examples</Text>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Default TextInput</Text>
<TextInput
label="Full Name"
placeholder="Enter your full name"
value={name}
onChangeText={setName}
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Required Field with Label</Text>
<TextInput
label="Email Address"
placeholder="Enter your email"
value={email}
onChangeText={setEmail}
isRequire
keyboardType="email-address"
autoCapitalize="none"
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>With Placeholder and Keyboard Type</Text>
<TextInput
label="Phone Number"
placeholder="(123) 456-7890"
value={phone}
onChangeText={setPhone}
keyboardType="phone-pad"
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Password Input</Text>
<TextInput
label="Password"
placeholder="Enter your password"
secureTextEntry
isRequire
/>
</View>
</View>
)
}
106 changes: 106 additions & 0 deletions example/components/TextInputDemo/DisabledState.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import React from 'react'
import { Text, View } from 'react-native'
import { TextInput } from 'rn-base-component'
import { demoStyles } from './styles'

export const DisabledState = () => {
return (
<View style={demoStyles.section}>
<Text style={demoStyles.sectionTitle}>🚫 Disabled States</Text>
<Text style={demoStyles.sectionDescription}>
TextInput in disabled state for read-only scenarios
</Text>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Disabled Default Input</Text>
<TextInput
label="Disabled Field"
placeholder="This input is disabled"
editable={false}
value="This field is read-only"
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Disabled Outlined Input</Text>
<TextInput.Outlined
label="Read-only Email"
placeholder="user@example.com"
editable={false}
value="user@example.com"
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Disabled Flat Input</Text>
<TextInput.Flat
label="Read-only Name"
placeholder="John Doe"
editable={false}
value="John Doe"
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Disabled with Required Indicator</Text>
<TextInput
label="Required but Disabled"
placeholder="This is required but disabled"
isRequire
editable={false}
value="Pre-filled value"
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Disabled with Icons</Text>
<TextInput
label="Contact Info"
placeholder="Contact information"
editable={false}
value="+1 (555) 123-4567"
leftComponent={
<View style={{ paddingHorizontal: 8 }}>
<Text style={{ fontSize: 16 }}>📞</Text>
</View>
}
rightComponent={
<View style={{ paddingHorizontal: 8 }}>
<Text style={{ fontSize: 16 }}>✅</Text>
</View>
}
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Disabled Multiline Input</Text>
<TextInput
label="Read-only Description"
placeholder="Description"
editable={false}
multiline
numberOfLines={3}
value="This is a multi-line read-only text field that contains some example content to demonstrate how disabled multiline inputs appear in the interface."
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Comparison: Enabled vs Disabled</Text>
<View style={{ gap: 12 }}>
<TextInput
label="Enabled Input"
placeholder="You can type here"
value=""
/>

<TextInput
label="Disabled Input"
placeholder="You cannot type here"
editable={false}
value="Disabled content"
/>
</View>
</View>
</View>
)
}
133 changes: 133 additions & 0 deletions example/components/TextInputDemo/IconsAndComponents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import React, { useState } from 'react'
import { Text, TouchableOpacity, View } from 'react-native'
import { TextInput } from 'rn-base-component'
import { demoStyles } from './styles'

export const IconsAndComponents = () => {
const [searchText, setSearchText] = useState('')
const [phoneNumber, setPhoneNumber] = useState('')
const [isPasswordVisible, setIsPasswordVisible] = useState(false)

const SearchIcon = () => (
<View style={{ paddingHorizontal: 8 }}>
<Text style={{ fontSize: 16 }}>🔍</Text>
</View>
)

const PhoneIcon = () => (
<View style={{ paddingHorizontal: 8 }}>
<Text style={{ fontSize: 16 }}>📞</Text>
</View>
)

const EyeIcon = ({ visible }: { visible: boolean }) => (
<TouchableOpacity
onPress={() => setIsPasswordVisible(!visible)}
style={{ paddingHorizontal: 8 }}
>
<Text style={{ fontSize: 16 }}>{visible ? '👁️' : '🙈'}</Text>
</TouchableOpacity>
)

const ClearButton = ({ onClear }: { onClear: () => void }) => (
<TouchableOpacity onPress={onClear} style={{ paddingHorizontal: 8 }}>
<Text style={{ fontSize: 16 }}>❌</Text>
</TouchableOpacity>
)

const UnitLabel = ({ unit }: { unit: string }) => (
<View style={{ paddingHorizontal: 8, backgroundColor: '#f0f0f0', borderRadius: 4, paddingVertical: 2 }}>
<Text style={{ fontSize: 12, color: '#666' }}>{unit}</Text>
</View>
)

return (
<View style={demoStyles.section}>
<Text style={demoStyles.sectionTitle}>🎨 Icons and Components</Text>
<Text style={demoStyles.sectionDescription}>
TextInput with left and right components for enhanced UX
</Text>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Search Input with Icon</Text>
<TextInput
label="Search"
placeholder="Search for something..."
value={searchText}
onChangeText={setSearchText}
leftComponent={<SearchIcon />}
rightComponent={
searchText ? <ClearButton onClear={() => setSearchText('')} /> : undefined
}
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Phone Number Input</Text>
<TextInput
label="Phone Number"
placeholder="(123) 456-7890"
value={phoneNumber}
onChangeText={setPhoneNumber}
keyboardType="phone-pad"
leftComponent={<PhoneIcon />}
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Password with Visibility Toggle</Text>
<TextInput
label="Password"
placeholder="Enter your password"
secureTextEntry={!isPasswordVisible}
rightComponent={<EyeIcon visible={isPasswordVisible} />}
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Weight Input with Unit</Text>
<TextInput
label="Weight"
placeholder="Enter weight"
keyboardType="numeric"
rightComponent={<UnitLabel unit="kg" />}
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Price Input with Currency</Text>
<TextInput
label="Price"
placeholder="0.00"
keyboardType="numeric"
leftComponent={<UnitLabel unit="$" />}
/>
</View>

<View style={demoStyles.example}>
<Text style={demoStyles.exampleTitle}>Complex Example - Email with Actions</Text>
<TextInput
label="Email Address"
placeholder="your@email.com"
keyboardType="email-address"
autoCapitalize="none"
leftComponent={
<View style={{ paddingHorizontal: 8 }}>
<Text style={{ fontSize: 16 }}>✉️</Text>
</View>
}
rightComponent={
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity style={{ paddingHorizontal: 8 }}>
<Text style={{ fontSize: 16 }}>📎</Text>
</TouchableOpacity>
<TouchableOpacity style={{ paddingHorizontal: 8 }}>
<Text style={{ fontSize: 16 }}>⚙️</Text>
</TouchableOpacity>
</View>
}
/>
</View>
</View>
)
}
Loading