react-native-zuosh-fabric
v2.0.7
Published
A React Native Fabric button component with click animations
Maintainers
Readme
React Native Zuosh Fabric Button
A high-performance native button component for React Native 0.82+ built with the new Fabric architecture. Features smooth click animations, multiple button styles, and full TypeScript support.
Features
- 🎯 Fabric Architecture: Built with React Native's new rendering system
- 🎨 Multiple Styles: Solid, Outline, and Ghost button styles
- ✨ Click Animations: Smooth, native animations with customizable duration
- 📱 Cross-Platform: Full support for iOS and Android
- 🔷 TypeScript: Full type safety and IntelliSense support
- ♿ Accessibility: Full accessibility support
- 🎮 Event Support: Press, Long Press, Press In/Out events
Requirements
- React Native 0.82 or higher
- React 18.0 or higher
- iOS 11.0+ / Android API 21+
- New Architecture (Fabric) enabled
Installation
npm install react-native-zuosh-fabricor
yarn add react-native-zuosh-fabricSetup
1. Enable New Architecture
Make sure your app has the React Native New Architecture enabled. In your ios/Podfile:
# Podfile
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
platform :ios, '11.0'
use_react_native!(
:path => config[:reactNativePath],
:flipper_configuration => FlipperConfiguration.enabled,
:app_path => "#{Pod::Config.instance.installation_root}/.."
# Enable New Architecture
:new_arch_enabled => true
)2. Install Pods
cd ios && pod install && cd ..3. Android Setup
In your android/app/build.gradle, make sure you have the new architecture enabled:
android {
// ...
defaultConfig {
// ...
if (isNewArchitectureEnabled()) {
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", "true"
} else {
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", "false"
}
}
}
if (isNewArchitectureEnabled()) {
react {
jsRootDir = file("../")
cliFile = new File(["node", "--print", "require.resolve('@react-native-community/cli')"].execute().text.trim())
codegenDir = file("$buildDir/generated/source/codegen")
reactNativeDir = file("../node_modules/react-native")
hermesCommand = file("../node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc")
codegenJavaPackageName = "com.zuoshbutton"
}
}Usage
Basic Usage
import React from 'react';
import ZuoshButton from 'react-native-zuosh-fabric';
const App = () => {
return (
<ZuoshButton
title="Click Me"
onPress={() => console.log('Button pressed!')}
/>
);
};Advanced Usage
import React from 'react';
import { View, StyleSheet } from 'react-native';
import ZuoshButton from 'react-native-zuosh-fabric';
const App = () => {
const handlePress = (event) => {
console.log('Button pressed:', event.value);
};
const handleLongPress = (event) => {
console.log('Long pressed:', event.value);
};
return (
<View style={styles.container}>
{/* Solid Button */}
<ZuoshButton
title="Primary Button"
onPress={handlePress}
buttonStyle="solid"
backgroundColor="#2196F3"
textColor="#FFFFFF"
style={styles.button}
/>
{/* Outline Button */}
<ZuoshButton
title="Outline Button"
onPress={handlePress}
buttonStyle="outline"
backgroundColor="#2196F3"
textColor="#2196F3"
style={styles.button}
/>
{/* Ghost Button */}
<ZuoshButton
title="Ghost Button"
onPress={handlePress}
buttonStyle="ghost"
backgroundColor="#2196F3"
textColor="#2196F3"
style={styles.button}
/>
{/* Custom Animation */}
<ZuoshButton
title="Slow Animation"
onPress={handlePress}
buttonStyle="solid"
backgroundColor="#E91E63"
textColor="#FFFFFF"
animationDuration={300}
onLongPress={handleLongPress}
style={styles.button}
/>
{/* Disabled Button */}
<ZuoshButton
title="Disabled Button"
onPress={handlePress}
buttonStyle="solid"
backgroundColor="#607D8B"
textColor="#FFFFFF"
disabled={true}
style={styles.button}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
justifyContent: 'center',
alignItems: 'center',
},
button: {
marginVertical: 10,
},
});API Reference
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| title | string | Required | Button text content |
| onPress | function | Required | Callback when button is pressed |
| buttonStyle | 'solid' \| 'outline' \| 'ghost' | 'solid' | Button visual style |
| backgroundColor | string | '#2196F3' | Background color in hex format |
| textColor | string | '#FFFFFF' | Text color in hex format |
| disabled | boolean | false | Whether the button is disabled |
| animationDuration | number | 150 | Animation duration in milliseconds |
| onLongPress | function | undefined | Callback for long press |
| onPressIn | function | undefined | Callback when press starts |
| onPressOut | function | undefined | Callback when press ends |
Event Types
interface ZuoshButtonPressEvent {
value?: string; // The button title
}Button Styles
solid: Filled background with colored textoutline: Transparent background with colored border and textghost: Transparent background with colored text only
Development Setup
If you want to develop on this component:
1. Clone the Repository
git clone https://github.com/zuosh/react-native-zuosh-fabric.git
cd react-native-zuosh-fabric2. Install Dependencies
npm install3. Create Example App (React Native CLI)
# Create a new React Native app for testing
npx @react-native-community/cli@latest init ZuoshButtonExample --version 0.82.0
cd ZuoshButtonExample4. Link Local Component
# Add local component to example app
echo '"react-native-zuosh-fabric": "file:../"' >> package.json
npm install5. Enable New Architecture
Android
Ensure android/gradle.properties has:
newArchEnabled=trueiOS
Update ios/Podfile to include:
use_react_native!(
:path => config[:reactNativePath],
:app_path => "#{Pod::Config.instance.installation_root}/..",
:new_arch_enabled => true # Add this line
)Then run:
cd ios && RCT_NEW_ARCH_ENABLED=1 bundle exec pod install6. Run Codegen
Android (✅ Working)
cd android
./gradlew generateCodegenArtifactsFromSchemaiOS (⚠️ Requires Xcode)
cd ios && RCT_NEW_ARCH_ENABLED=1 bundle exec pod installNote: iOS requires Xcode to be installed for proper compilation.
7. Run Example App
Android (✅ Tested)
cd ZuoshButtonExample
npm run androidiOS (⚠️ Requires Xcode)
cd ZuoshButtonExample
npm run ios8. Troubleshooting
Android Issues:
- ✅ Codegen working:
generateCodegenArtifactsFromSchemashould succeed - ✅ Component interface generation: Check
android/build/generated/source/codegen/
iOS Issues:
- ⚠️ Xcode Required: Install from App Store
- ⚠️ Bundle Install: Run
bundle installin ios/ directory - ⚠️ Enum Default Values: Ensure optional enums have proper defaults
- ✅ Codegen Config:
RCT_NEW_ARCH_ENABLED=1environment variable
Current Development Status
- ✅ Android: Codegen working, interfaces generated successfully
- ✅ Component Architecture: Proper Fabric component with
codegenNativeComponent - ✅ TypeScript Support: Full type safety and IntelliSense
- ⚠️ iOS: Requires Xcode installation for full testing
- ✅ Example App: Ready for Android testing
Publishing to NPM
1. Update Version
Update the version in package.json:
{
"version": "1.1.0"
}2. Build the Package
npm run build3. Run Tests
npm test4. Publish to NPM
npm publishArchitecture
This component follows React Native's new architecture patterns using official Fabric component conventions:
File Structure
src/
├── ZuoshButtonNativeComponent.ts # Codegen spec + component export (NativeComponent suffix required)
└── index.ts # Public API exports
android/src/main/java/com/zuosh/button/
├── ZuoshButtonViewManager.kt # Android ViewManager (implements generated interface)
├── ZuoshButtonView.kt # Android View implementation
└── ZuoshButtonStyle.kt # Button style enum
ios/ZuoshButton/
├── ZuoshButtonViewManager.h/m # iOS ViewManager (implements generated protocol)
└── ZuoshButtonView.h/m # iOS View implementationOfficial Fabric Component Pattern
This component uses the official Fabric component pattern:
Codegen Spec File (
ZuoshButtonNativeComponent.ts):- Defines TypeScript interface
NativeProps - Uses
codegenNativeComponent<NativeProps>('ComponentName')to export - File name ends with
NativeComponent.ts(required by Codegen)
- Defines TypeScript interface
Direct Component Export:
export default codegenNativeComponent<NativeProps>( 'ZuoshButtonView', ) as HostComponent<NativeProps>;No Manual JS Wrapper:
- Unlike older approaches, we don't manually create a wrapper with
requireNativeComponent - Codegen handles the component registration and interface generation
- Unlike older approaches, we don't manually create a wrapper with
Codegen Configuration
The codegenConfig in package.json tells React Native's Codegen how to generate the native interfaces:
{
"codegenConfig": {
"name": "ZuoshButtonSpec",
"type": "components",
"jsSrcsDir": "src",
"android": {
"javaPackageName": "com.zuosh.button"
}
}
}Generated Code Structure
When Codegen runs, it creates:
Android (android/build/generated/source/codegen/):
ZuoshButtonViewManagerDelegate.javaZuoshButtonViewManagerInterface.java- C++ bridge code
iOS (ios/build/generated/ios/):
ZuoshButtonSpec.h/m- C++ bridge code
- Protocol definitions
The native implementations (ViewManager and View classes) must implement these generated interfaces.
Troubleshooting
Common Issues
- Build Failures: Make sure you have enabled the new architecture in your React Native app
- TypeScript Errors: Ensure you're using React Native 0.82+ with proper TypeScript setup
- Animation Issues: Check that
animationDurationis a positive number - Color Not Applying: Colors should be in hex format (e.g., "#FF0000")
Getting Help
- Check the example app for full usage examples
- Review React Native's New Architecture documentation
- Open an issue on GitHub
License
MIT License - see LICENSE file for details.
Contributing
Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.
Changelog
See CHANGELOG.md for a list of changes and version history.
