rn-button-component
4
总安装量
2
周安装量
#53451
全站排名
安装命令
npx skills add https://github.com/jchaselubitz/drill-app --skill rn-button-component
Agent 安装分布
windsurf
1
opencode
1
weavefox
1
codex
1
claude-code
1
antigravity
1
Skill 文档
Button Component
Guide for using the unified Button component with state management, icon support, and glass effect integration.
Overview
- Location:
@/components/Button - Features: State management, icon support, loading states, success/error states, glass effect on iOS
- Design: Rounded corners (borderRadius: 25), glass effect on iOS when available
Basic Usage
import { Button } from '@/components/Button';
<Button text="Click Me" onPress={() => console.log('Pressed')} />
Props
Required Props
text: string | React.ReactNode– Button label textonPress: () => void– Press handler function
Optional Props
variant?: 'primary' | 'secondary' | 'destructive'– Button style variant (default:'primary')buttonState?: ButtonState– Current button state (default:'default')loadingText?: string | React.ReactNode– Text shown during loading statesuccessText?: string | React.ReactNode– Text shown during success stateerrorText?: string | React.ReactNode– Text shown during error stateicon?: { name, size?, position? }– Icon configurationsuccessIcon?: { name, size? }– Icon shown in success state (default:'checkmark')reset?: boolean– Auto-reset from success to default after 2 seconds (default:false)setButtonState?: (state: ButtonState) => void– External state control functionstyle?: StyleProp<ViewStyle>– Additional styles
Button States
export type ButtonState = 'default' | 'disabled' | 'loading' | 'success' | 'error';
State Behavior
'default': Normal interactive state'disabled': Button is disabled and non-interactive'loading': Shows loading spinner with optionalloadingText'success': Shows success icon with optionalsuccessText'error': Shows error message witherrorText
Common Patterns
Basic Button
<Button text="Save" onPress={handleSave} />
Button with Variant
<Button text="Cancel" onPress={handleCancel} variant="secondary" />
<Button text="Delete" onPress={handleDelete} variant="destructive" />
Loading State
const [isSaving, setIsSaving] = useState(false);
<Button
text="Save"
onPress={handleSave}
buttonState={isSaving ? 'loading' : 'default'}
loadingText="Saving..."
/>
Disabled State
<Button
text="Submit"
onPress={handleSubmit}
buttonState={!isValid ? 'disabled' : 'default'}
/>
Button with Icon
<Button
text="Create Lesson"
onPress={handleCreate}
icon={{ name: 'add', size: 24, position: 'left' }}
variant="secondary"
/>
Success State with Auto-Reset
const [buttonState, setButtonState] = useState<ButtonState>('default');
const handleSave = async () => {
setButtonState('loading');
try {
await saveData();
setButtonState('success');
} catch (error) {
setButtonState('error');
}
};
<Button
text="Save"
onPress={handleSave}
buttonState={buttonState}
setButtonState={setButtonState}
loadingText="Saving..."
successText="Saved!"
errorText="Failed to save"
reset={true} // Auto-resets to 'default' after 2 seconds
/>
Combined Loading and Disabled
<Button
text="Save Lesson"
onPress={handleSave}
buttonState={isSaving ? 'loading' : isLoading ? 'disabled' : 'default'}
loadingText="Saving..."
/>
Icon Configuration
Icon Props
icon?: {
name: keyof typeof Ionicons.glyphMap; // Required: Ionicons icon name
size?: number; // Optional: Icon size (default: 24)
position?: 'left' | 'right'; // Optional: Icon position (default: 'left')
}
Examples
// Left icon (default)
<Button
text="Add Item"
icon={{ name: 'add', position: 'left' }}
onPress={handleAdd}
/>
// Right icon
<Button
text="Next"
icon={{ name: 'arrow-forward', position: 'right' }}
onPress={handleNext}
/>
// Custom size
<Button
text="Settings"
icon={{ name: 'settings', size: 20 }}
onPress={handleSettings}
/>
State Management
Internal State (Default)
The button manages its own state internally when setButtonState is not provided:
<Button
text="Click Me"
onPress={handleClick}
buttonState="loading" // State is managed internally
/>
External State Control
Provide setButtonState to control state externally:
const [state, setState] = useState<ButtonState>('default');
<Button
text="Submit"
onPress={handleSubmit}
buttonState={state}
setButtonState={setState}
loadingText="Submitting..."
/>
Auto-Reset Pattern
When reset={true} and button reaches 'success' state, it automatically resets to 'default' after 2 seconds:
const [state, setState] = useState<ButtonState>('default');
<Button
text="Save"
onPress={async () => {
setState('loading');
await save();
setState('success');
}}
buttonState={state}
setButtonState={setState}
reset={true}
successText="Saved!"
/>
Glass Effect
The button automatically uses glass effect on iOS when available:
- iOS 26+: Uses
GlassViewwith liquid glass effect - Other platforms: Falls back to regular
Viewwith background color - Automatic: No configuration needed, handled internally
The glass effect respects:
variantprop for tint colorbuttonStatefor disabled/loading tint- Interactive glass effect enabled automatically
Styling
Default Styles
borderRadius: 25– Fully rounded cornerspaddingVertical: 14paddingHorizontal: 24minHeight: 48
Custom Styles
<Button
text="Custom Button"
onPress={handlePress}
style={{ marginTop: 16, width: '100%' }}
/>
Complete Examples
Form Submit Button
const [isSubmitting, setIsSubmitting] = useState(false);
const [submitState, setSubmitState] = useState<ButtonState>('default');
const handleSubmit = async () => {
setIsSubmitting(true);
setSubmitState('loading');
try {
await submitForm();
setSubmitState('success');
} catch (error) {
setSubmitState('error');
} finally {
setIsSubmitting(false);
}
};
<Button
text="Submit Form"
onPress={handleSubmit}
buttonState={submitState}
setButtonState={setSubmitState}
loadingText="Submitting..."
successText="Submitted!"
errorText="Submission failed"
reset={true}
disabled={!isFormValid}
/>
Action Button with Icon
<Button
text="Create Lesson"
onPress={openModal}
icon={{ name: 'add', size: 24, position: 'left' }}
variant="secondary"
/>
Conditional Loading
<Button
text="Translate"
onPress={handleTranslate}
buttonState={isTranslating ? 'loading' : 'default'}
loadingText="Translating..."
variant="secondary"
/>
Best Practices
- Always provide
loadingTextwhen using loading state for better UX - Use
setButtonStatefor complex state management scenarios - Use
reset={true}for temporary success states (e.g., form submissions) - Provide
errorTextwhen handling error states - Use icons sparingly – only when they add clarity
- Choose appropriate variants – use
destructiveonly for destructive actions
TypeScript
import { Button, ButtonState } from '@/components/Button';
const [state, setState] = useState<ButtonState>('default');
References
- Component location:
components/Button.tsx - Uses:
expo-glass-effect,@expo/vector-icons, React NativePressable