Thank you for your interest in contributing to PixaCompose! This document provides guidelines and instructions for contributing to the project.
PixaCompose is a production-ready UI component library for Compose Multiplatform mobile applications, built with:
- Mobile-first design principles
- Material 3 design system
- Clean, maintainable code
- Comprehensive documentation
- Excellent developer experience
- Code of Conduct
- Getting Started
- Development Setup
- Component Standards
- Pull Request Process
- Coding Conventions
- Testing Requirements
- Be respectful and inclusive
- Welcome newcomers and help them learn
- Focus on what is best for the community
- Show empathy towards other community members
- Harassment, discrimination, or offensive comments
- Personal or political attacks
- Public or private harassment
- Publishing others' private information
- Unprofessional conduct
- JDK 11 or higher
- Android Studio Hedgehog or later (for Android development)
- Xcode 14+ (for iOS development on macOS)
- Git
- Fork the repository on GitHub
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/PixaCompose.git
cd PixaCompose- Add upstream remote:
git remote add upstream https://github.com/pixamob/pixacompose.git./gradlew build# Android tests
./gradlew :library:testDebugUnitTest
# iOS tests
./gradlew :library:iosSimulatorArm64Test
# All tests
./gradlew testlibrary/src/commonMain/kotlin/com/pixamob/pixacompose/
βββ theme/ # Theme system (Color, Typography, Dimen, etc.)
βββ elements/ # UI components
βββ actions/ # Interactive components (Button, FAB, etc.)
βββ inputs/ # Form inputs (TextField, Checkbox, etc.)
βββ feedback/ # User feedback (Toast, Alert, etc.)
βββ display/ # Content display (Card, Avatar, etc.)
βββ navigation/ # Navigation components
βββ overlay/ # Modal/overlay components
βββ layout/ # Layout components
Every component MUST follow this structure:
package com.pixamob.pixacompose.elements.[category]
// ============================================================================
// CONFIGURATION
// ============================================================================
enum class ComponentVariant { /* variants */ }
enum class ComponentSize { /* sizes */ }
data class ComponentColors( /* color properties */ )
data class ComponentStateColors( /* state-based colors */ )
// ============================================================================
// THEME PROVIDER
// ============================================================================
@Composable
private fun getComponentTheme(
variant: ComponentVariant,
colors: ColorPalette
): ComponentStateColors { /* theme mapping */ }
// ============================================================================
// BASE COMPONENT (Internal)
// ============================================================================
@Composable
private fun BaseComponent( /* core implementation */ ) { }
// ============================================================================
// PUBLIC API
// ============================================================================
@Composable
fun Component( /* public interface */ ) { }
// ============================================================================
// CONVENIENCE VARIANTS (Optional)
// ============================================================================
@Composable
fun ComponentVariantOne( /* convenience functions */ ) = Component(...)
/**
* USAGE EXAMPLES:
*
* [Include clear usage examples]
*/- Build from Primitives: Use
Box,Row,Column,Canvas- NOT Material 3 wrappers - Single File Components: All logic in one file with clear sections
- Theme-Aware: Use
AppTheme.colors,AppTheme.typography, etc. - Mobile-First: Minimum 44dp touch targets
- Accessibility: Proper semantic roles and content descriptions
- Components: PascalCase (
Button,TextField) - Variants: PascalCase enums (
ButtonVariant.Flat) - Sizes: PascalCase enums (
ButtonSize.Medium) - Functions: camelCase (
onClick,getButtonTheme) - Files: Match component name (
Button.kt)
Every component must include:
- KDoc comments for public functions
- Parameter descriptions for complex parameters
- Usage examples at the end of the file
- State management documentation
- Accessibility notes where applicable
Example:
/**
* A primary action button with multiple variants, sizes, and states.
*
* @param text The button label text
* @param onClick Callback invoked when button is clicked
* @param modifier Modifier to be applied to the button
* @param variant Visual style variant (Flat, Outlined, Ghost)
* @param enabled Whether the button is interactive
* @param loading Whether to show loading indicator
* @param size Button size (Mini to Huge)
* @param shape Button shape (Default, Pill, Circle)
* @param leadingIcon Optional icon displayed before text
* @param trailingIcon Optional icon displayed after text
*/
@Composable
fun Button(
text: String,
onClick: () -> Unit,
modifier: Modifier = Modifier,
// ... other parameters
) { }- Update from upstream:
git fetch upstream
git rebase upstream/main- Run all tests:
./gradlew test- Check code formatting (if configured):
./gradlew spotlessCheck- Build successfully:
./gradlew build- Create a feature branch:
git checkout -b feature/component-name
# or
git checkout -b fix/issue-description-
Make your changes following coding conventions
-
Commit with clear messages:
git commit -m "feat: add Button component with variants"
# or
git commit -m "fix: correct TextField padding in small size"Commit message format:
feat:New featurefix:Bug fixdocs:Documentation onlystyle:Code style/formattingrefactor:Code refactoringtest:Adding testschore:Maintenance tasks
- Push to your fork:
git push origin feature/component-name- Open Pull Request on GitHub with:
- Clear title and description
- Reference to related issues
- Screenshots/GIFs for UI changes
- Checklist of completed items
- Code follows project structure and conventions
- All tests pass
- New tests added for new functionality
- Documentation updated (if applicable)
- Usage examples included
- No console warnings or errors
- Tested on both Android and iOS (if applicable)
- Accessibility considerations addressed
- Dark theme tested (if UI component)
- Automated checks must pass (CI/CD)
- At least one maintainer must review
- Address feedback by pushing new commits
- Maintainer will merge when approved
Every component must have unit tests covering:
- Component rendering
- Variant rendering
- State changes
- User interactions
- Edge cases
Example:
class ButtonTest {
@Test
fun button_rendersWithText() {
composeTestRule.setContent {
Button(text = "Click Me", onClick = {})
}
composeTestRule.onNodeWithText("Click Me").assertExists()
}
@Test
fun button_disabled_doesNotTriggerClick() {
var clicked = false
composeTestRule.setContent {
Button(
text = "Click Me",
onClick = { clicked = true },
enabled = false
)
}
composeTestRule.onNodeWithText("Click Me").performClick()
assertFalse(clicked)
}
}For UI components, include:
- Screenshots for each variant
- Dark/light theme comparison
- Different size variations
- State variations (default, disabled, etc.)
Each component needs:
- README section in main README.md (if major component)
- Usage examples in component file comments
- API documentation via KDoc
- Implementation notes in IMPLEMENTATION_GUIDE.md
/**
* USAGE EXAMPLES:
*
* Basic usage:
* ```
* Button(
* text = "Submit",
* onClick = { /* handle click */ }
* )
* ```
*
* With icon:
* ```
* Button(
* text = "Save",
* leadingIcon = painterResource(Res.drawable.ic_save),
* onClick = { /* handle click */ }
* )
* ```
*
* Loading state:
* ```
* var isLoading by remember { mutableStateOf(false) }
* Button(
* text = "Submit",
* loading = isLoading,
* onClick = {
* isLoading = true
* // perform async operation
* }
* )
* ```
*/Provide 2-4 practical variants:
- Primary: Most common use case (default)
- Secondary: Alternative styling
- Tertiary: Less emphasis
- (Optional) Special: Unique use cases
Provide 4-6 sizes:
- Small: Compact spaces
- Medium: Default (usually 44dp for touch targets)
- Large: Prominent elements
- (Optional) Mini/Huge: Edge cases
Handle these states:
- Default: Normal interactive state
- Hover: Desktop hover state (future)
- Focused: Keyboard focus
- Pressed: Active press state
- Disabled: Non-interactive state
- Loading: Async operation state (if applicable)
- Error: Error state (for inputs)
Include:
- Description: Clear description of the bug
- Steps to Reproduce: Detailed steps
- Expected Behavior: What should happen
- Actual Behavior: What actually happens
- Environment:
- OS (Android/iOS version)
- Library version
- Kotlin version
- Code Sample: Minimal reproduction code
- Screenshots: If applicable
Include:
- Use Case: Why this feature is needed
- Proposed Solution: Your idea for implementation
- Alternatives: Other solutions considered
- Additional Context: Any other relevant information
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: Implementation Guide
Contributors are recognized in:
- CONTRIBUTORS.md file
- Release notes
- Project README (major contributions)
By contributing, you agree that your contributions will be licensed under the Apache License 2.0, the same license as the project.
Thank you for contributing to PixaCompose! π