├── .github └── workflows │ ├── android.yml │ └── release.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── app ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── godaddy │ │ └── android │ │ └── colorpicker │ │ ├── ClassicColorPickerScreen.kt │ │ ├── ColorPreviewInfo.kt │ │ ├── HarmonyColorPickerScreen.kt │ │ ├── Route.kt │ │ ├── SampleColorPickerActivity.kt │ │ └── theme │ │ ├── Color.kt │ │ ├── Components.kt │ │ └── ComposeColorPickerTheme.kt │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ └── ic_launcher_background.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-mdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-xhdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-xxhdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-xxxhdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── values-night │ └── themes.xml │ └── values │ ├── colors.xml │ ├── strings.xml │ └── themes.xml ├── build.gradle.kts ├── color-picker ├── .gitignore ├── build.gradle.kts ├── consumer-rules.pro ├── gradle.properties ├── proguard-rules.pro └── src │ ├── androidMain │ └── kotlin │ │ └── com │ │ └── godaddy │ │ └── android │ │ └── colorpicker │ │ └── HsvColorExt.kt │ └── commonMain │ └── kotlin │ └── com │ └── godaddy │ └── android │ └── colorpicker │ ├── AlphaBar.kt │ ├── ClassicColorPicker.kt │ ├── HsvColor.kt │ ├── HueBar.kt │ ├── MathExt.kt │ ├── SaturationValueArea.kt │ ├── SelectorIndicator.kt │ └── harmony │ ├── BrightnessBar.kt │ ├── ColorHarmonyMode.kt │ ├── ColorWheel.kt │ ├── HarmonyColorMagnifiers.kt │ ├── HarmonyColorPicker.kt │ └── Magnifier.kt ├── desktop ├── .gitignore ├── build.gradle.kts └── src │ └── jvmMain │ └── kotlin │ ├── ClassicColorPickerScreen.kt │ ├── HarmonyColorPickerScreen.kt │ └── Main.kt ├── gradle.properties ├── gradle ├── spotless.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jsApp ├── build.gradle.kts └── src │ └── jsMain │ ├── kotlin │ ├── ClassicColorPickerScreen.kt │ ├── HarmonyColorPickerScreen.kt │ └── Main.js.kt │ └── resources │ ├── index.html │ └── style.css ├── kotlin-js-store └── yarn.lock ├── renovate.json └── settings.gradle.kts /.github/workflows/android.yml: -------------------------------------------------------------------------------- 1 | name: Main Build 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | - name: set up JDK 11 17 | uses: actions/setup-java@v3 18 | with: 19 | java-version: '11' 20 | distribution: 'temurin' 21 | cache: gradle 22 | 23 | - name: Grant execute permission for gradlew 24 | run: chmod +x gradlew 25 | - name: Build with Gradle 26 | env: 27 | ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }} 28 | ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} 29 | run: | 30 | ./gradlew build --no-parallel --no-daemon 31 | - name: Run spotless 32 | run: ./gradlew spotlessCheck 33 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to Sonatype 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | deploy: 8 | runs-on: ubuntu-latest 9 | timeout-minutes: 30 10 | env: 11 | TERM: dumb 12 | 13 | steps: 14 | - uses: actions/checkout@v3 15 | 16 | - name: Setup JDK 17 | uses: actions/setup-java@v3 18 | with: 19 | distribution: 'zulu' # See 'Supported distributions' for available options 20 | java-version: '11' 21 | - name: Configure GPG Key 22 | run: | 23 | mkdir ~/.gpgkey 24 | echo $GPG_KEY > ~/.gpgkey/secring.gpg.b64 25 | base64 -d ~/.gpgkey/secring.gpg.b64 > ~/.gpgkey/secring.gpg 26 | env: 27 | GPG_KEY: ${{ secrets.GPG_KEY }} 28 | - name: Deploy to Sonatype 29 | env: 30 | ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }} 31 | ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} 32 | run: | 33 | ./gradlew publishAllPublicationsToMavenRepository --no-parallel --no-daemon -Psigning.keyId=${{secrets.GPG_KEY_ID}} -Psigning.password=${{secrets.GPG_KEY_PASSWORD}} -Psigning.secretKeyRingFile=$(echo ~/.gpgkey/secring.gpg) 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | /.gradle 3 | /local.properties 4 | **/build 5 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, visible or invisible disability, ethnicity, sex characteristics, gender 9 | identity and expression, level of experience, education, socio-economic status, 10 | nationality, personal appearance, race, religion, or sexual identity 11 | and orientation. 12 | 13 | We pledge to act and interact in ways that contribute to an open, welcoming, 14 | diverse, inclusive, and healthy community. 15 | 16 | ## Our Standards 17 | 18 | Examples of behavior that contributes to a positive environment for our 19 | community include: 20 | 21 | * Demonstrating empathy and kindness toward other people 22 | * Being respectful of differing opinions, viewpoints, and experiences 23 | * Giving and gracefully accepting constructive feedback 24 | * Accepting responsibility and apologizing to those affected by our mistakes, 25 | and learning from the experience 26 | * Focusing on what is best not just for us as individuals, but for the 27 | overall community 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or 32 | advances of any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email 36 | address, without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official e-mail address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement at 64 | oss@godaddy.com. 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series 87 | of actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or 94 | permanent ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within 114 | the community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.0, available at 120 | [https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. 121 | 122 | Community Impact Guidelines were inspired by 123 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available 127 | at [https://www.contributor-covenant.org/translations][translations]. 128 | 129 | [homepage]: https://www.contributor-covenant.org 130 | [v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html 131 | [Mozilla CoC]: https://github.com/mozilla/diversity 132 | [FAQ]: https://www.contributor-covenant.org/faq 133 | [translations]: https://www.contributor-covenant.org/translations 134 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Everyone is welcome to contribute to GoDaddy's Open Source Software. 4 | Contributing doesn’t just mean submitting pull requests. To get involved, 5 | you can report or triage bugs, and participate in discussions on the 6 | evolution of each project. 7 | 8 | No matter how you want to get involved, we ask that you first learn what’s 9 | expected of anyone who participates in the project by reading the Contribution 10 | Guidelines and our [Code of Conduct][coc]. 11 | 12 | 13 | ## Answering Questions 14 | 15 | One of the most important and immediate ways you can support this project is 16 | to answer questions on [Github][issues]. Whether you’re 17 | helping a newcomer understand a feature or troubleshooting an edge case with a 18 | seasoned developer, your knowledge and experience with a programming language 19 | can go a long way to help others. 20 | 21 | ## Reporting Bugs 22 | 23 | **Do not report potential security vulnerabilities here. Refer to 24 | [SECURITY.md](./SECURITY.md) for more details about the process of reporting 25 | security vulnerabilities.** 26 | 27 | Before submitting a ticket, please search our [Issue Tracker][issues] to make 28 | sure it does not already exist and have a simple replication of the behavior. If 29 | the issue is isolated to one of the dependencies of this project, please create 30 | a Github issue in that project. All dependencies should be open source software 31 | and can be found on Github. 32 | 33 | Submit a ticket for your issue, assuming one does not already exist: 34 | - Create it on the project's [issue Tracker][issues]. 35 | - Clearly describe the issue by following the template layout 36 | - Make sure to include steps to reproduce the bug. 37 | - A reproducible (unit) test could be helpful in solving the bug. 38 | - Describe the environment that (re)produced the problem. 39 | 40 | ## Triaging bugs or contributing code 41 | 42 | If you're triaging a bug, first make sure that you can reproduce it. Once a bug 43 | can be reproduced, reduce it to the smallest amount of code possible. Reasoning 44 | about a sample or unit test that reproduces a bug in just a few lines of code 45 | is easier than reasoning about a longer sample. 46 | 47 | From a practical perspective, contributions are as simple as: 48 | 1. Fork and clone the repo, [see Github's instructions if you need help.][fork] 49 | 1. Create a branch for your PR with `git checkout -b pr/your-branch-name` 50 | 1. Make changes on the branch of your forked repository. 51 | 1. When committing, reference your issue (if present) and include a note about 52 | the fix. 53 | 1. Please also add/update unit tests for your changes. 54 | 1. Push the changes to your fork and submit a pull request to the 'main 55 | development branch' branch of the projects' repository. 56 | 57 | If you are interested in making a large change and feel unsure about its overall 58 | effect, start with opening an Issue in the project's [Issue Tracker][issues] 59 | with a high-level proposal and discuss it with the core contributors through 60 | Github comments. After reaching a consensus with core 61 | contributors about the change, discuss the best way to go about implementing it. 62 | 63 | > Tip: Keep your main branch pointing at the original repository and make 64 | > pull requests from branches on your fork. To do this, run: 65 | > ``` 66 | > git remote add upstream https://github.com/godaddy/compose-color-picker.git 67 | > git fetch upstream 68 | > git branch --set-upstream-to=upstream/main main 69 | > ``` 70 | > This will add the original repository as a "remote" called "upstream," Then 71 | > fetch the git information from that remote, then set your local main 72 | > branch to use the upstream main branch whenever you run git pull. Then you 73 | > can make all of your pull request branches based on this main branch. 74 | > Whenever you want to update your version of main, do a regular git pull. 75 | 76 | ## Code Review 77 | 78 | Any open source project relies heavily on code review to improve software 79 | quality. All significant changes, by all developers, must be reviewed before 80 | they are committed to the repository. Code reviews are conducted on GitHub 81 | through comments on pull requests or commits. The developer responsible for a 82 | code change is also responsible for making all necessary review-related changes. 83 | 84 | Sometimes code reviews will take longer than you would hope for, especially for 85 | larger features. Here are some accepted ways to speed up review times for your 86 | patches: 87 | 88 | - Review other people’s changes. If you help out, others will more likely be 89 | willing to do the same for you. 90 | - Split your change into multiple smaller changes. The smaller your change, 91 | the higher the probability that somebody will take a quick look at it. 92 | 93 | **Note that anyone is welcome to review and give feedback on a change, but only 94 | people with commit access to the repository can approve it.** 95 | 96 | ## Attribution of Changes 97 | 98 | When contributors submit a change to this project, after that change is 99 | approved, other developers with commit access may commit it for the author. When 100 | doing so, it is important to retain correct attribution of the contribution. 101 | Generally speaking, Git handles attribution automatically. 102 | 103 | ## Code Style and Documentation 104 | 105 | Ensure that your contribution follows the standards set by the project's style 106 | guide with respect to patterns, naming, documentation and testing. 107 | 108 | # Additional Resources 109 | 110 | - [General GitHub Documentation](https://help.github.com/) 111 | - [GitHub Pull Request documentation](https://help.github.com/send-pull-requests/) 112 | 113 | [issues]: https://github.com/godaddy/compose-color-picker/issues 114 | [coc]: ./CODE_OF_CONDUCT.md 115 | [fork]: https://help.github.com/en/articles/fork-a-repo 116 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021GoDaddy Operating Company, LLC. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android Jetpack Compose Color Picker 🎨 2 | 3 | ![Maven Central](https://img.shields.io/maven-central/v/com.godaddy.android.colorpicker/compose-color-picker-android?style=flat-square) 4 | 5 | A component that provides two different HSV color pickers, written in Jetpack Compose. 6 | 1. ClassicColorPicker - Square picker with alpha channel 7 | 2. HarmonyColorPicker - Circular wheel with harmony modes (ie complementary, triadic, analogous, shades, monochromatic, tetradic) 8 | 9 | 10 | https://user-images.githubusercontent.com/9973046/154516879-495a6816-9595-49b9-beaf-dafc2e1110ec.mp4 11 | 12 | https://user-images.githubusercontent.com/9973046/154515203-f0818a14-3bb0-4e5a-91fc-f3cac2e2e770.mp4 13 | 14 | 15 | ## How to get started 16 | 17 | Add the dependency to your `build.gradle` file: 18 | 19 | ``` 20 | implementation 'com.godaddy.android.colorpicker:compose-color-picker:' 21 | 22 | // with Android ColorInt extensions 23 | implementation 'com.godaddy.android.colorpicker:compose-color-picker-android:' 24 | // desktop jvm version 25 | implementation 'com.godaddy.android.colorpicker:compose-color-picker-jvm:' 26 | ``` 27 | 28 | Add `ClassicColorPicker` to your Compose hierarchy: 29 | 30 | ```kotlin 31 | import com.godaddy.android.colorpicker.HsvColor 32 | 33 | Column { 34 | ClassicColorPicker( 35 | onColorChanged = { color: HsvColor -> 36 | // Do something with the color 37 | } 38 | ) 39 | } 40 | ``` 41 | 42 | Or add the `HarmonyColorPicker` to your Compose hierarchy for an HSV color wheel implementation: 43 | 44 | ```kotlin 45 | HarmonyColorPicker( 46 | harmonyMode = harmonyMode.value, 47 | modifier = Modifier.size(400.dp), 48 | onColorChanged = { color -> 49 | currentColor.value = color 50 | extraColors.value = color.getColors(colorHarmonyMode = harmonyMode.value) 51 | }) 52 | ``` 53 | 54 | The `HarmonyColorPicker` allows for you to set a certain `ColorHarmonyMode` on the wheel. 55 | This will then display multiple magnifiers on top of the wheel for the different harmony modes: ie complementary, triadic, analogous, shades, monochromatic, tetradic. 56 | If you wish to not display other magnifiers - set `ColorHarmonyMode.NONE` as your `harmonyMode` on the wheel. 57 | 58 | # ClassicColorPicker: 59 | ## Customizing the control 60 | 61 | ### Size 62 | 63 | To change the size of the control, pass in the `Modifier` option: 64 | 65 | ```kotlin 66 | import com.godaddy.android.colorpicker.HsvColor 67 | 68 | ClassicColorPicker( 69 | modifier = Modifier.height(200.dp), 70 | onColorChanged = { color: HsvColor -> 71 | // Do something with the color 72 | } 73 | ) 74 | ``` 75 | 76 | ### Alpha 77 | 78 | To hide the alpha bar, change the `showAlphaBar` parameter: 79 | 80 | ```kotlin 81 | import com.godaddy.android.colorpicker.HsvColor 82 | 83 | ClassicColorPicker( 84 | showAlphaBar = false, 85 | onColorChanged = { color: HsvColor -> 86 | // Do something with the color 87 | } 88 | ) 89 | ``` 90 | 91 | ## HarmonyColorPicker 92 | 93 | ## Customizing the control 94 | 95 | ### Harmony Mode 96 | 97 | To change the harmony mode of the picker, pass in a different mode into the function: 98 | 99 | ```kotlin 100 | HarmonyColorPicker( 101 | harmonyMode = ColorHarmonyMode.SHADES, 102 | modifier = Modifier.size(400.dp), 103 | onColorChanged = { color -> 104 | // do stuff with new color 105 | }) 106 | ``` 107 | 108 | ### Size 109 | 110 | To change the size of the control, pass in the `Modifier` option: 111 | 112 | ```kotlin 113 | import com.godaddy.android.colorpicker.HsvColor 114 | 115 | HarmonyColorPicker( 116 | modifier = Modifier.height(200.dp), 117 | onColorChanged = { color: HsvColor -> 118 | // Do something with the color 119 | } 120 | ) 121 | ``` 122 | 123 | # Library Contribution Information 124 | 125 | ## Code Formatting 126 | 127 | This project uses spotless to enforce code formatting. Run `./gradlew spotlessApply` to run formatting before committing. 128 | 129 | ### Releases 130 | 131 | 1. Update the version number in color-picker/build.gradle.kts 132 | 2. Make a PR into main and get that merged 133 | 3. Run "Deploy to Sonatype" GitHub Action. 134 | 4. Login to Sonatype and "Close" release. After a few minutes, click "Release". 135 | 5. Release should then be available for download on maven (might take like 30 min to propagate). 136 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting Security Issues 2 | 3 | We take security very seriously at GoDaddy. We appreciate your efforts to 4 | responsibly disclose your findings, and will make every effort to acknowledge 5 | your contributions. 6 | 7 | ## Where should I report security issues? 8 | 9 | In order to give the community time to respond and upgrade, we strongly urge you 10 | report all security issues privately. 11 | 12 | To report a security issue in one of our Open Source projects email us directly 13 | at **oss@godaddy.com** and include the word "SECURITY" in the subject line. 14 | 15 | This mail is delivered to our Open Source Security team. 16 | 17 | After the initial reply to your report, the team will keep you informed of the 18 | progress being made towards a fix and announcement, and may ask for additional 19 | information or guidance. 20 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | 2 | plugins { 3 | id("org.jetbrains.compose") version "1.3.0" 4 | id("com.android.application") 5 | kotlin("android") 6 | } 7 | 8 | group = "com.godaddy" 9 | version = "1.0" 10 | 11 | 12 | dependencies { 13 | implementation(project(":color-picker")) 14 | implementation ("androidx.activity:activity-compose:1.6.1") 15 | implementation("com.google.android.material:material:1.7.0") 16 | implementation("androidx.navigation:navigation-runtime-ktx:2.5.3") 17 | implementation("androidx.navigation:navigation-compose:2.5.3") 18 | implementation(compose.material) 19 | } 20 | 21 | android { 22 | compileSdk = 33 23 | defaultConfig { 24 | applicationId = "com.godaddy.android.colorpicker" 25 | minSdk = 21 26 | targetSdk = 33 27 | versionCode = 1 28 | versionName = "1.0" 29 | } 30 | 31 | compileOptions { 32 | sourceCompatibility = JavaVersion.VERSION_1_8 33 | targetCompatibility = JavaVersion.VERSION_1_8 34 | } 35 | packagingOptions { 36 | resources.excludes += "/META-INF/{AL2.0,LGPL2.1}" 37 | } 38 | buildTypes { 39 | getByName("release") { 40 | isMinifyEnabled = false 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/godaddy/android/colorpicker/ClassicColorPickerScreen.kt: -------------------------------------------------------------------------------- 1 | package com.godaddy.android.colorpicker 2 | 3 | import androidx.compose.foundation.layout.Column 4 | import androidx.compose.foundation.layout.height 5 | import androidx.compose.foundation.layout.padding 6 | import androidx.compose.material.Text 7 | import androidx.compose.material.TopAppBar 8 | import androidx.compose.runtime.Composable 9 | import androidx.compose.runtime.getValue 10 | import androidx.compose.runtime.mutableStateOf 11 | import androidx.compose.runtime.remember 12 | import androidx.compose.runtime.setValue 13 | import androidx.compose.ui.Modifier 14 | import androidx.compose.ui.graphics.Color 15 | import androidx.compose.ui.res.stringResource 16 | import androidx.compose.ui.unit.dp 17 | import androidx.navigation.NavController 18 | import com.godaddy.android.colorpicker.theme.BackButton 19 | import com.godaddy.android.colorpicker.theme.ComposeColorPickerTheme 20 | 21 | @Composable 22 | fun ClassicColorPickerScreen(navController: NavController) { 23 | Column { 24 | TopAppBar( 25 | title = { 26 | Text(stringResource(R.string.classic_color_picker_sample)) 27 | }, 28 | navigationIcon = { 29 | BackButton { navController.navigateUp() } 30 | } 31 | ) 32 | var currentColor by remember { 33 | mutableStateOf(HsvColor.from(Color.Red)) 34 | } 35 | ColorPreviewInfo(currentColor = currentColor.toColor()) 36 | ClassicColorPicker( 37 | color = currentColor, 38 | modifier = Modifier 39 | .height(300.dp) 40 | .padding(16.dp), 41 | onColorChanged = { hsvColor: HsvColor -> 42 | // Triggered when the color changes, do something with the newly picked color here! 43 | currentColor = hsvColor 44 | } 45 | ) 46 | } 47 | } 48 | 49 | @Composable 50 | fun ClassicColorPickerPreview() { 51 | ComposeColorPickerTheme { 52 | ClassicColorPicker( 53 | modifier = Modifier.height(300.dp), 54 | color = HsvColor.from(Color.Green), 55 | onColorChanged = { 56 | } 57 | ) 58 | } 59 | } 60 | 61 | @Composable 62 | fun ClassicColorPickerNoAlphaPreview() { 63 | ComposeColorPickerTheme { 64 | ClassicColorPicker( 65 | modifier = Modifier.height(300.dp), 66 | color = HsvColor.from(color = Color.Magenta), 67 | showAlphaBar = false, 68 | onColorChanged = { 69 | } 70 | ) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/godaddy/android/colorpicker/ColorPreviewInfo.kt: -------------------------------------------------------------------------------- 1 | package com.godaddy.android.colorpicker 2 | 3 | import androidx.compose.foundation.Canvas 4 | import androidx.compose.foundation.background 5 | import androidx.compose.foundation.layout.Arrangement 6 | import androidx.compose.foundation.layout.Column 7 | import androidx.compose.foundation.layout.PaddingValues 8 | import androidx.compose.foundation.layout.Spacer 9 | import androidx.compose.foundation.layout.fillMaxWidth 10 | import androidx.compose.foundation.layout.height 11 | import androidx.compose.foundation.layout.padding 12 | import androidx.compose.foundation.layout.size 13 | import androidx.compose.foundation.lazy.grid.GridCells 14 | import androidx.compose.foundation.lazy.grid.LazyVerticalGrid 15 | import androidx.compose.foundation.lazy.grid.items 16 | import androidx.compose.foundation.shape.CircleShape 17 | import androidx.compose.material.Text 18 | import androidx.compose.runtime.Composable 19 | import androidx.compose.ui.Alignment 20 | import androidx.compose.ui.Modifier 21 | import androidx.compose.ui.graphics.Color 22 | import androidx.compose.ui.unit.dp 23 | 24 | @Composable 25 | fun ColorPreviewInfo(currentColor: Color) { 26 | Column(modifier = Modifier.fillMaxWidth()) { 27 | Text( 28 | modifier = Modifier.padding(16.dp), 29 | text = "a: ${currentColor.alpha} \n" + 30 | "r: ${currentColor.red} \n" + 31 | "g: ${currentColor.green} \n" + 32 | "b: ${currentColor.blue}" 33 | ) 34 | Spacer( 35 | modifier = Modifier 36 | .background( 37 | currentColor, 38 | shape = CircleShape 39 | ) 40 | .size(48.dp) 41 | .align(Alignment.CenterHorizontally) 42 | ) 43 | Spacer(Modifier.height(16.dp)) 44 | } 45 | } 46 | 47 | @Composable 48 | fun ColorPaletteBar( 49 | modifier: Modifier = Modifier, 50 | colors: List 51 | ) { 52 | LazyVerticalGrid( 53 | horizontalArrangement = Arrangement.spacedBy(4.dp), 54 | verticalArrangement = Arrangement.spacedBy(4.dp), 55 | columns = GridCells.Adaptive(48.dp), 56 | modifier = modifier 57 | .fillMaxWidth(), 58 | contentPadding = PaddingValues(16.dp), 59 | content = { 60 | items(colors) { color -> 61 | Canvas(modifier = Modifier.size(48.dp)) { 62 | drawCircle(color.toColor()) 63 | } 64 | } 65 | } 66 | ) 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/com/godaddy/android/colorpicker/HarmonyColorPickerScreen.kt: -------------------------------------------------------------------------------- 1 | package com.godaddy.android.colorpicker 2 | 3 | import androidx.compose.foundation.layout.Column 4 | import androidx.compose.foundation.layout.Row 5 | import androidx.compose.foundation.layout.fillMaxWidth 6 | import androidx.compose.foundation.layout.height 7 | import androidx.compose.foundation.layout.size 8 | import androidx.compose.material.DropdownMenu 9 | import androidx.compose.material.DropdownMenuItem 10 | import androidx.compose.material.Switch 11 | import androidx.compose.material.Text 12 | import androidx.compose.material.TextButton 13 | import androidx.compose.material.TopAppBar 14 | import androidx.compose.runtime.Composable 15 | import androidx.compose.runtime.getValue 16 | import androidx.compose.runtime.mutableStateOf 17 | import androidx.compose.runtime.remember 18 | import androidx.compose.runtime.setValue 19 | import androidx.compose.ui.Modifier 20 | import androidx.compose.ui.graphics.Color 21 | import androidx.compose.ui.res.stringResource 22 | import androidx.compose.ui.unit.dp 23 | import androidx.navigation.NavController 24 | import com.godaddy.android.colorpicker.harmony.ColorHarmonyMode 25 | import com.godaddy.android.colorpicker.harmony.HarmonyColorPicker 26 | import com.godaddy.android.colorpicker.theme.BackButton 27 | 28 | @Composable 29 | fun HarmonyColorPickerScreen(navController: NavController) { 30 | Column { 31 | TopAppBar( 32 | title = { 33 | Text(stringResource(R.string.harmony_color_picker_sample)) 34 | }, 35 | navigationIcon = { 36 | BackButton { navController.navigateUp() } 37 | } 38 | ) 39 | var currentColor by remember { 40 | mutableStateOf(HsvColor.from(Color.Red)) 41 | } 42 | var extraColors by remember { 43 | mutableStateOf(emptyList()) 44 | } 45 | ColorPreviewInfo(currentColor = currentColor.toColor()) 46 | var expanded by remember { 47 | mutableStateOf(false) 48 | } 49 | var harmonyMode by remember { 50 | mutableStateOf(ColorHarmonyMode.ANALOGOUS) 51 | } 52 | var showBrightnessBar by remember { 53 | mutableStateOf(true) 54 | } 55 | TextButton(onClick = { 56 | expanded = true 57 | }) { 58 | Text(harmonyMode.name) 59 | } 60 | DropdownMenu(expanded, onDismissRequest = { 61 | expanded = false 62 | }) { 63 | ColorHarmonyMode.values().forEach { 64 | DropdownMenuItem(onClick = { 65 | harmonyMode = it 66 | expanded = false 67 | }) { 68 | Text(it.name) 69 | } 70 | } 71 | } 72 | HarmonyColorPicker( 73 | modifier = Modifier.size(400.dp), 74 | harmonyMode = harmonyMode, 75 | color = currentColor, 76 | showBrightnessBar = showBrightnessBar 77 | ) { color -> 78 | currentColor = color 79 | extraColors = color.getColors(colorHarmonyMode = harmonyMode) 80 | } 81 | ColorPaletteBar(modifier = Modifier.fillMaxWidth().height(70.dp), colors = extraColors) 82 | Row { 83 | Text("Show Brightness Bar") 84 | Switch( 85 | checked = showBrightnessBar, 86 | onCheckedChange = { checked -> 87 | showBrightnessBar = checked 88 | } 89 | ) 90 | } 91 | TextButton(onClick = { currentColor = HsvColor.from(Color.Green) }) { 92 | Text("Reset To Green") 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /app/src/main/java/com/godaddy/android/colorpicker/Route.kt: -------------------------------------------------------------------------------- 1 | package com.godaddy.android.colorpicker 2 | 3 | sealed class Route(val link: String) { 4 | object Picker : Route("picker") 5 | object ClassicColorPicker : Route("classic") 6 | object HarmonyColorPicker : Route("harmony") 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/godaddy/android/colorpicker/SampleColorPickerActivity.kt: -------------------------------------------------------------------------------- 1 | package com.godaddy.android.colorpicker 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.compose.foundation.clickable 7 | import androidx.compose.foundation.layout.Column 8 | import androidx.compose.foundation.layout.defaultMinSize 9 | import androidx.compose.foundation.layout.fillMaxWidth 10 | import androidx.compose.foundation.layout.height 11 | import androidx.compose.foundation.layout.padding 12 | import androidx.compose.foundation.rememberScrollState 13 | import androidx.compose.foundation.verticalScroll 14 | import androidx.compose.material.AlertDialog 15 | import androidx.compose.material.MaterialTheme 16 | import androidx.compose.material.Surface 17 | import androidx.compose.material.Text 18 | import androidx.compose.material.TextButton 19 | import androidx.compose.material.TopAppBar 20 | import androidx.compose.runtime.Composable 21 | import androidx.compose.runtime.getValue 22 | import androidx.compose.runtime.mutableStateOf 23 | import androidx.compose.runtime.remember 24 | import androidx.compose.runtime.setValue 25 | import androidx.compose.ui.Modifier 26 | import androidx.compose.ui.graphics.Color 27 | import androidx.compose.ui.graphics.ExperimentalGraphicsApi 28 | import androidx.compose.ui.res.stringResource 29 | import androidx.compose.ui.unit.dp 30 | import androidx.navigation.NavController 31 | import androidx.navigation.compose.NavHost 32 | import androidx.navigation.compose.composable 33 | import androidx.navigation.compose.rememberNavController 34 | import com.godaddy.android.colorpicker.theme.ComposeColorPickerTheme 35 | 36 | @ExperimentalGraphicsApi 37 | class SampleColorPickerActivity : ComponentActivity() { 38 | 39 | override fun onCreate(savedInstanceState: Bundle?) { 40 | super.onCreate(savedInstanceState) 41 | setContent { 42 | ComposeColorPickerTheme { 43 | var openDialog by remember { mutableStateOf(false) } 44 | var currentColor by remember { 45 | mutableStateOf(HsvColor.from(Color.Black)) 46 | } 47 | Surface(color = MaterialTheme.colors.background) { 48 | val scrollState = rememberScrollState() 49 | Column(modifier = Modifier.verticalScroll(scrollState)) { 50 | val navController = rememberNavController() 51 | NavHost(navController = navController, startDestination = Route.Picker.link) { 52 | composable(Route.Picker.link) { ColorPickerTypeScreen(navController) } 53 | composable(Route.ClassicColorPicker.link) { ClassicColorPickerScreen(navController) } 54 | composable(Route.HarmonyColorPicker.link) { HarmonyColorPickerScreen(navController) } 55 | } 56 | Text( 57 | text = "Dialog", 58 | modifier = Modifier.clickable { 59 | openDialog = true 60 | }.padding(8.dp).fillMaxWidth() 61 | ) 62 | } 63 | } 64 | if (openDialog) { 65 | AlertDialog( 66 | onDismissRequest = { 67 | openDialog = false 68 | }, 69 | text = { 70 | ClassicColorPicker( 71 | color = currentColor, 72 | modifier = Modifier 73 | .height(300.dp) 74 | .padding(16.dp), 75 | onColorChanged = { hsvColor: HsvColor -> 76 | // Triggered when the color changes, do something with the newly picked color here! 77 | currentColor = hsvColor 78 | } 79 | ) 80 | }, 81 | confirmButton = { 82 | TextButton( 83 | onClick = { 84 | openDialog = false 85 | } 86 | ) { 87 | Text("Confirm") 88 | } 89 | }, 90 | dismissButton = { 91 | TextButton( 92 | onClick = { 93 | openDialog = false 94 | } 95 | ) { 96 | Text("Dismiss") 97 | } 98 | } 99 | ) 100 | } 101 | } 102 | } 103 | } 104 | } 105 | 106 | @Composable 107 | fun ColorPickerTypeScreen(navController: NavController) { 108 | Column(modifier = Modifier.fillMaxWidth()) { 109 | TopAppBar(title = { 110 | Text(stringResource(R.string.compose_color_picker_sample)) 111 | }) 112 | Text( 113 | stringResource(R.string.classic_color_picker_sample), 114 | modifier = Modifier.defaultMinSize(minHeight = 48.dp) 115 | .fillMaxWidth() 116 | .clickable { 117 | navController.navigate(Route.ClassicColorPicker.link) 118 | }.padding(8.dp) 119 | ) 120 | Text( 121 | stringResource(R.string.harmony_color_picker_sample), 122 | modifier = Modifier.defaultMinSize(minHeight = 48.dp) 123 | .fillMaxWidth() 124 | .clickable { 125 | navController.navigate(Route.HarmonyColorPicker.link) 126 | }.padding(8.dp) 127 | ) 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /app/src/main/java/com/godaddy/android/colorpicker/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package com.godaddy.android.colorpicker.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val Purple200 = Color(0xFFBB86FC) 6 | val Purple500 = Color(0xFF6200EE) 7 | val Purple700 = Color(0xFF3700B3) 8 | val Teal200 = Color(0xFF03DAC5) 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/godaddy/android/colorpicker/theme/Components.kt: -------------------------------------------------------------------------------- 1 | // ktlint-disable filename 2 | package com.godaddy.android.colorpicker.theme 3 | 4 | import androidx.compose.material.Icon 5 | import androidx.compose.material.IconButton 6 | import androidx.compose.material.MaterialTheme 7 | import androidx.compose.material.icons.Icons 8 | import androidx.compose.material.icons.filled.ArrowBack 9 | import androidx.compose.runtime.Composable 10 | import androidx.compose.ui.res.stringResource 11 | import com.godaddy.android.colorpicker.R 12 | 13 | @Composable 14 | fun BackButton(onBackPress: () -> Unit) { 15 | IconButton( 16 | onClick = { 17 | onBackPress() 18 | } 19 | ) { 20 | Icon( 21 | Icons.Filled.ArrowBack, 22 | tint = MaterialTheme.colors.onPrimary, 23 | contentDescription = stringResource(id = R.string.content_description_back_button) 24 | ) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/godaddy/android/colorpicker/theme/ComposeColorPickerTheme.kt: -------------------------------------------------------------------------------- 1 | package com.godaddy.android.colorpicker.theme 2 | 3 | import androidx.compose.foundation.isSystemInDarkTheme 4 | import androidx.compose.material.MaterialTheme 5 | import androidx.compose.material.darkColors 6 | import androidx.compose.material.lightColors 7 | import androidx.compose.runtime.Composable 8 | 9 | private val DarkColorPalette = darkColors( 10 | primary = Purple200, 11 | primaryVariant = Purple700, 12 | secondary = Teal200 13 | ) 14 | 15 | private val LightColorPalette = lightColors( 16 | primary = Purple500, 17 | primaryVariant = Purple700, 18 | secondary = Teal200 19 | 20 | /* Other default colors to override 21 | background = Color.White, 22 | surface = Color.White, 23 | onPrimary = Color.White, 24 | onSecondary = Color.Black, 25 | onBackground = Color.Black, 26 | onSurface = Color.Black, 27 | */ 28 | ) 29 | 30 | @Composable 31 | fun ComposeColorPickerTheme( 32 | darkTheme: Boolean = isSystemInDarkTheme(), 33 | content: @Composable () -> Unit 34 | ) { 35 | val colors = if (darkTheme) { 36 | DarkColorPalette 37 | } else { 38 | LightColorPalette 39 | } 40 | 41 | MaterialTheme( 42 | colors = colors, 43 | content = content 44 | ) 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godaddy/compose-color-picker/709d85c8648a98798a849e32367e16b58ea22410/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godaddy/compose-color-picker/709d85c8648a98798a849e32367e16b58ea22410/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godaddy/compose-color-picker/709d85c8648a98798a849e32367e16b58ea22410/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godaddy/compose-color-picker/709d85c8648a98798a849e32367e16b58ea22410/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godaddy/compose-color-picker/709d85c8648a98798a849e32367e16b58ea22410/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godaddy/compose-color-picker/709d85c8648a98798a849e32367e16b58ea22410/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godaddy/compose-color-picker/709d85c8648a98798a849e32367e16b58ea22410/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godaddy/compose-color-picker/709d85c8648a98798a849e32367e16b58ea22410/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godaddy/compose-color-picker/709d85c8648a98798a849e32367e16b58ea22410/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godaddy/compose-color-picker/709d85c8648a98798a849e32367e16b58ea22410/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Compose Color Picker 3 | Compose Color Picker 4 | Harmony Color Picker 5 | Classic Color Picker 6 | Back 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 21 | 22 |