{"id":22957966,"url":"https://github.com/sergio11/brownie_ui_library","last_synced_at":"2025-08-13T04:33:01.295Z","repository":{"id":239070925,"uuid":"187466826","full_name":"sergio11/brownie_ui_library","owner":"sergio11","description":"Brownie 🍫: Jetpack Compose library for Android interfaces 📱, providing pre-defined components, efficient state management, and full compatibility with Jetpack Compose 🚀.","archived":false,"fork":false,"pushed_at":"2025-03-11T07:45:53.000Z","size":4375,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-01T16:21:27.289Z","etag":null,"topics":["android","android-library","clean-architecture","github-packages","jetpack-compose","jetpackcompose","mvi","mvi-architecture"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sergio11.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-05-19T11:15:52.000Z","updated_at":"2025-03-16T11:40:35.000Z","dependencies_parsed_at":"2024-05-17T20:24:06.913Z","dependency_job_id":"8da32e8b-6de4-419c-a2fa-b83543e8063e","html_url":"https://github.com/sergio11/brownie_ui_library","commit_stats":null,"previous_names":["sergio11/brownie_ui_library"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sergio11/brownie_ui_library","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergio11%2Fbrownie_ui_library","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergio11%2Fbrownie_ui_library/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergio11%2Fbrownie_ui_library/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergio11%2Fbrownie_ui_library/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sergio11","download_url":"https://codeload.github.com/sergio11/brownie_ui_library/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergio11%2Fbrownie_ui_library/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270182797,"owners_count":24541310,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-13T02:00:09.904Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-library","clean-architecture","github-packages","jetpack-compose","jetpackcompose","mvi","mvi-architecture"],"created_at":"2024-12-14T17:33:58.079Z","updated_at":"2025-08-13T04:32:58.360Z","avatar_url":"https://github.com/sergio11.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🍫 Brownie: Jetpack Compose UI Library 🚀\n\nBrownie is a 🌟 Jetpack Compose library module that provides a set of pre-defined components to accelerate the development of Android interfaces and applications. It is designed to help developers apply best practices in screen state management and utilize the most effective design patterns in their projects.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Android%20Studio-3DDC84.svg?style=for-the-badge\u0026logo=android-studio\u0026logoColor=white\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/kotlin-%237F52FF.svg?style=for-the-badge\u0026logo=kotlin\u0026logoColor=white\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Android-3DDC84?style=for-the-badge\u0026logo=android\u0026logoColor=white\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Material%20UI-007FFF?style=for-the-badge\u0026logo=mui\u0026logoColor=white\" /\u003e\n\u003c/p\u003e\n\n## Features 🎉\n\n- **Pre-defined Components:** Brownie offers a variety of ready-to-use components, from buttons to lists and cards, to facilitate the creation of attractive and consistent user interfaces.\n- **State Management:** Facilitates screen state management by implementing patterns such as MVI (Model-View-Intent) or MVVM (Model-View-ViewModel).\n- **Customization:** Brownie components are highly customizable and can easily adapt to the visual style of any application.\n- **Jetpack Compose Compatibility:** Fully integrated with Jetpack Compose, the modern Android UI library, to ensure optimal performance and a smooth development experience.\n\n## Model-View-Intent (MVI) Architecture 🏗️\n\nBrownie encourages the use of the Model-View-Intent (MVI) architecture pattern for effective screen state management. In this pattern:\n\n- **Model:** Represents the state of the UI. Brownie provides a `BrownieViewModel` class that extends from `ViewModel` and handles the UI state.\n- **View:** Renders the UI based on the state provided by the ViewModel. Brownie components are seamlessly integrated with Compose to create a declarative UI.\n- **Intent:** Represents user actions or events that trigger state changes. Brownie's components, like buttons and text fields, are designed to emit these intents efficiently.\n\nThis setup leverages Brownie's components and ViewModel to accelerate the development of robust features while adhering to best practices in architecture and UI design.\n\nHere's an example of how you can use Brownie components in a screen following the MVI pattern:\n\n```kotlin\n@Composable\nfun SignInScreen(\n    viewModel: SignInViewModel = hiltViewModel(),\n    onGoToHome: () -\u003e Unit,\n    onGoToProfileSelector: () -\u003e Unit,\n    onBackPressed: () -\u003e Unit,\n) {\n    BrownieScreen(\n        viewModel = viewModel,\n        onBackPressed = onBackPressed,\n        onInitialUiState = { SignInUiState() },\n        onSideEffect = {\n            when(it) {\n                SignInSideEffects.AuthenticationSuccessfully -\u003e onGoToHome()\n                SignInSideEffects.ProfileSelectionRequired -\u003e onGoToProfileSelector()\n            }\n        }\n    ) { uiState -\u003e\n        SignInScreenContent(\n            uiState = uiState,\n            onEmailChanged = viewModel::onEmailChanged,\n            onPasswordChanged = viewModel::onPasswordChanged,\n            onSignIn = viewModel::onSignIn\n        )\n    }\n}\n```\n\nInside the SignInScreen function, there's a BrownieScreen composable. This is a custom screen component provided by the Brownie library. It's responsible for managing the UI state and handling side effects in a declarative way. Here's what each parameter does:\n\n- **viewModel:** The **SignInViewModel** instance passed to the **BrownieScreen** component.\n- **onBackPressed:** The lambda function passed to the **BrownieScreen** component, which is called when the user navigates back from the screen.\n- **onInitialUiState:** A lambda function that provides the initial UI state for the screen. In this case, it returns a new instance of **SignInUiState.**\n- **onSideEffect:** A lambda function that handles side effects triggered by the ViewModel. When a side effect occurs (such as successful authentication or profile selection required), this function is called, and appropriate actions (navigating to home or profile selection) are performed.\n\nFinally, inside the BrownieScreen composable, there's another composable function called **SignInScreenContent.** This is the actual content of the sign-in screen, where UI elements like text fields, buttons, etc., are defined. It takes the current UI state (uiState) as a parameter and callback functions for handling user interactions:\n\n- **uiState:** The current state of the sign-in screen, which is provided by the BrownieScreen component.\n- **onEmailChanged:** A callback function for handling changes in the email input field.\n- **onPasswordChanged:** A callback function for handling changes in the password input field.\n- **onSignIn:** A callback function for handling the sign-in action.\n\nOverall, this implementation follows a declarative approach using Compose and Brownie components, making it easier to manage the UI state and handle user interactions in a clear and concise manner.\n\n```kotlin\n@Composable\nfun SignInScreenContent(\n    uiState: SignInUiState,\n    onEmailChanged: (String) -\u003e Unit,\n    onPasswordChanged: (String) -\u003e Unit,\n    onSignIn: () -\u003e Unit\n) {\n    BrownieLoadingDialog(\n        isShowingDialog = uiState.isLoading,\n        mainLogoRes = R.drawable.ic_launcher_foreground,\n        titleRes = R.string.loading_dialog_title,\n        descriptionRes = R.string.loading_dialog_description\n    )\n    BrownieScreenContent(\n        titleRes = R.string.signin_main_title_text\n    ) {\n        BrownieText(\n            modifier = Modifier\n                .padding(horizontal = 32.dp, vertical = 40.dp),\n            type = BrownieTextTypeEnum.HEADLINE_LARGE,\n            titleRes = R.string.onboarding_subtitle_text,\n            textBold = true\n        )\n        Spacer(modifier = Modifier.weight(1f))\n        BrownieCardColumn {\n            BrownieText(\n                modifier = Modifier.padding(horizontal = 20.dp, vertical = 15.dp),\n                type = BrownieTextTypeEnum.TITLE_MEDIUM,\n                titleRes = R.string.signin_secondary_title_text,\n                textAlign = TextAlign.Center\n            )\n            BrownieDefaultTextField(\n                labelRes = R.string.signin_input_email_label,\n                placeHolderRes = R.string.signin_input_email_placeholder,\n                keyboardType = KeyboardType.Email,\n                value = uiState.email,\n                onValueChanged = onEmailChanged\n            )\n            BrownieTextFieldPassword(\n                labelRes = R.string.signin_input_password_label,\n                placeHolderRes = R.string.signin_input_password_placeholder,\n                value = uiState.password,\n                onValueChanged = onPasswordChanged\n            )\n            BrownieContentDivider()\n            BrownieButton(\n                text = R.string.signin_login_button_text,\n                onClick = onSignIn\n            )\n            Spacer(modifier = Modifier.padding(bottom = 10.dp))\n        }\n    }\n}\n```\n\nThis is a Composable function named **SignInScreenContent**, responsible for rendering the content of the sign-in screen. It takes the following parameters:\n\n- **uiState:** The current state of the sign-in screen, containing properties like isLoading, email, and password.\n- **onEmailChanged:** A callback function that will be invoked when the email input field changes.\n- **onPasswordChanged:** A callback function that will be invoked when the password input field changes.\n- **onSignIn:** A callback function that will be invoked when the user clicks the sign-in button.\n\nThe **BrownieScreenContent** composable is used to create a screen layout. It takes a title resource as a parameter.\n\nInside the BrownieScreenContent, a BrownieCardColumn composable is used to arrange multiple UI components vertically. This includes text fields for email and password inputs, a button for sign-in, and a divider between them.\n\nOverall, the **SignInScreenContent** composable is responsible for rendering the content of the sign-in screen using Brownie's components. It ensures a consistent UI design and handles user interactions efficiently through callback functions.\n\n## Using Brownie UI Library\n\n### Step 1: Configuring Maven Repository\n\nEnsure to add the GitHub Maven repository to your `build.gradle` or `settings.gradle` file to access the dependency hosted on GitHub Packages:\n\n```kotlin\nrepositories {\n    maven {\n        url = uri(\"https://maven.pkg.github.com/sergio11/brownie_ui_library\")\n        credentials {\n            // Here, set your authentication credentials\n            username = githubProperties[\"gpr.usr\"] as String? ?: System.getenv(\"GPR_USER\")\n            password = githubProperties[\"gpr.key\"] as String? ?: System.getenv(\"GPR_API_KEY\")\n        }\n    }\n}\n```\n\n### Step 2: Adding the Dependency to the Project\nOnce the repository is configured, you can add the \"Brownie UI Library\" dependency to your project.\n\n```\nbrownie-ui = \"CURRENT_VERSION\"\nbrownie-ui = { module = \"com.dreamsoftware.libraries:brownie-ui\", version.ref = \"brownie-ui\" }\n```\n\n```kotin\nimplementation(libs.brownie.ui)\n```\n\n## Contribution\nContributions to Brownie UI library are highly encouraged! If you're interested in adding new features, resolving bugs, or enhancing the project's functionality, please feel free to submit pull requests.\n\n## Credits\nBrownie UI library is developed and maintained by Sergio Sánchez Sánchez (Dream Software). Special thanks to the open-source community and the contributors who have made this project possible. If you have any questions, feedback, or suggestions, feel free to reach out at dreamsoftware92@gmail.com.\n\n## Visitors Count\n\n\u003cimg width=\"auto\" src=\"https://profile-counter.glitch.me/brownie_ui_library/count.svg\" /\u003e\n \n ## Please Share \u0026 Star the repository to keep me motivated.\n  \u003ca href = \"https://github.com/sergio11/brownie_ui_library/stargazers\"\u003e\n     \u003cimg src = \"https://img.shields.io/github/stars/sergio11/brownie_ui_library\" /\u003e\n  \u003c/a\u003e\n\n## License ⚖️\n\nThis project is licensed under the MIT License, an open-source software license that allows developers to freely use, copy, modify, and distribute the software. 🛠️ This includes use in both personal and commercial projects, with the only requirement being that the original copyright notice is retained. 📄\n\nPlease note the following limitations:\n\n- The software is provided \"as is\", without any warranties, express or implied. 🚫🛡️\n- If you distribute the software, whether in original or modified form, you must include the original copyright notice and license. 📑\n- The license allows for commercial use, but you cannot claim ownership over the software itself. 🏷️\n\nThe goal of this license is to maximize freedom for developers while maintaining recognition for the original creators.\n\n```\nMIT License\n\nCopyright (c) 2024 Dream software - Sergio Sánchez \n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsergio11%2Fbrownie_ui_library","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsergio11%2Fbrownie_ui_library","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsergio11%2Fbrownie_ui_library/lists"}