{"id":13610766,"url":"https://github.com/maxkeppeler/sheets","last_synced_at":"2025-10-20T05:05:07.013Z","repository":{"id":40479514,"uuid":"315741849","full_name":"maxkeppeler/sheets","owner":"maxkeppeler","description":"⭐ ‎‎‎‏‏‎ ‎Offers a range of beautiful sheets (dialogs \u0026 bottom sheets) for quick use in your project. Includes many  ways to customize sheets.","archived":false,"fork":false,"pushed_at":"2023-04-27T18:49:13.000Z","size":148634,"stargazers_count":931,"open_issues_count":6,"forks_count":77,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-04-09T03:12:26.917Z","etag":null,"topics":["android","android-bottomsheet","android-design","android-library","bottom","bottom-sheets","bottomsheet","bottomsheet-android","bottomsheet-dialog","bottomsheetdialog","bottomsheetdialogfragment","bottomsheets","calendar-sheet","color-sheet","design-patterns","kotlin-library","material","material-design","sheets"],"latest_commit_sha":null,"homepage":"https://maxkeppeler.github.io/sheets/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/maxkeppeler.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null},"funding":{"github":"maxkeppeler","patreon":null,"open_collective":null,"ko_fi":"maxkeppeler","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["https://www.paypal.com/paypalme/maximiliankeppeler"]}},"created_at":"2020-11-24T20:12:50.000Z","updated_at":"2025-03-28T22:24:05.000Z","dependencies_parsed_at":"2023-02-17T23:31:07.010Z","dependency_job_id":"429ec940-4b82-4187-9c1b-52a820e0b7fb","html_url":"https://github.com/maxkeppeler/sheets","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxkeppeler%2Fsheets","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxkeppeler%2Fsheets/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxkeppeler%2Fsheets/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxkeppeler%2Fsheets/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maxkeppeler","download_url":"https://codeload.github.com/maxkeppeler/sheets/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254448579,"owners_count":22072764,"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","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-bottomsheet","android-design","android-library","bottom","bottom-sheets","bottomsheet","bottomsheet-android","bottomsheet-dialog","bottomsheetdialog","bottomsheetdialogfragment","bottomsheets","calendar-sheet","color-sheet","design-patterns","kotlin-library","material","material-design","sheets"],"created_at":"2024-08-01T19:01:47.778Z","updated_at":"2025-10-20T05:05:06.944Z","avatar_url":"https://github.com/maxkeppeler.png","language":"Kotlin","funding_links":["https://github.com/sponsors/maxkeppeler","https://ko-fi.com/maxkeppeler","https://www.paypal.com/paypalme/maximiliankeppeler","https://www.buymeacoffee.com/maxkeppeler","https://www.paypal.me/maximiliankeppeler"],"categories":["Kotlin"],"sub_categories":[],"readme":"# Sheets\n\n\u003cp\u003e\n\n  \u003cimg src=\"docs/res/ic_library.png\" width=\"96px\" height=\"96px\" alt=\"Sheets Library\" align=\"left\" style=\"margin-right: 24px; margin-bottom: 24px\"\u003e\n\n  \u003cp\u003e\n\nSleek dialogs and bottom-sheets for quick use in your app. Choose one of the available sheets or\nbuild custom sheets on top of the existing functionality.\n\n   \u003ca href=\"https://search.maven.org/search?q=g:%22com.maxkeppeler.sheets%22\"\u003e\n     \u003cimg style=\"margin-right: 4px; margin-bottom: 8px;\" alt=\"Version of Sheets library\" src=\"https://img.shields.io/maven-central/v/com.maxkeppeler.sheets/core.svg?label=Maven%20Central\"\u003e\n   \u003c/a\u003e\n\n   \u003ca href=\"https://github.com/maxkeppeler/sheets\"\u003e\n     \u003cimg style=\"margin-right: 4px; margin-bottom: 8px;\" alt=\"Codacy code quality of Sheets library\" src=\"https://img.shields.io/codacy/grade/9a3b68b152e149fd82f0873e2fed78d5?label=Code%20Quality\"\u003e\n   \u003c/a\u003e\n\n   \u003ca href=\"https://www.apache.org/licenses/LICENSE-2.0\"\u003e\n     \u003cimg style=\"margin-right: 4px; margin-bottom: 8px;\" alt=\"GitHub\" src=\"https://img.shields.io/github/license/maxkeppeler/sheets?color=%23007EC6\u0026label=\"\u003e\n   \u003c/a\u003e\n\n\u003ca href=\"https://github.com/maxkeppeler/sheets\"\u003e\n  \u003cimg style=\"margin-right: 4px; margin-bottom: 8px\" alt=\"Give this library a star\" src=\"https://img.shields.io/github/stars/maxkeppeler/sheets?style=social\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://github.com/maxkeppeler/sheets/fork\"\u003e\n  \u003cimg style=\"margin-right: 4px; margin-bottom: 8px\" alt=\"Fork this library\" src=\"https://img.shields.io/github/forks/maxkeppeler/sheets?style=social\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://github.com/maxkeppeler/sheets\"\u003e\n  \u003cimg style=\"margin-right: 4px; margin-bottom: 8px\" alt=\"Watch this library\" src=\"https://img.shields.io/github/watchers/maxkeppeler/sheets.svg?style=social\u0026amp;label=Watch\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://github.com/maxkeppeler/\"\u003e\n  \u003cimg style=\"margin-right: 4px; margin-bottom: 8px\" alt=\"Follow me on GitHub\" src=\"https://img.shields.io/github/followers/maxkeppeler?style=social\u0026label=Follow\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://twitter.com/intent/tweet?text=Checkout%20this%20beautiful%20library!%20%23android%20%23androiddev%20%23library%20%40max_keppeler%20%0A%0Ahttps%3A%2F%2Fgithub.com%2Fmaxkeppeler%2Fsheets\"\u003e\n  \u003cimg style=\"margin-right: 4px; margin-bottom: 8px\" alt=\"Share this library on Twitter\" src=\"https://img.shields.io/twitter/url?style=social\u0026url=https%3A%2F%2Fgithub.com%2Fmaxkeppeler%2Fsheets\u0026label=Share\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://twitter.com/max_keppeler\"\u003e\n  \u003cimg style=\"margin-right: 4px; margin-bottom: 8px\" alt=\"Follow Maximilian Keppeler on Twitter\" src=\"https://img.shields.io/twitter/follow/max_keppeler?label=Follow\u0026style=social\"\u003e\n\u003c/a\u003e\n\n  \u003c/p\u003e\n\u003c/p\u003e\n\n\u003cimg src=\"docs/res/showcase.png\" alt=\"Sheets Library\"\u003e\n\n# Get started\n\nThe library is available for compose as well. Check out [Sheets-Compose-Dialogs](https://github.com/maxkeppeler/sheets-compose-dialogs).\n\nA sheet can dynamically be displayed as either a dialog or as a bottom-sheet. Check out\nthe [sample](https://github.com/MaxKeppeler/sheets/blob/main/sample/sample.apk).\n\nYou have to use the `core` module as it is the foundation of any sheet.\n\nIn your top-level `build.gradle` file:\n\n```gradle\nrepositories {\n  ...\n  mavenCentral()\n}\n```\n\nIn your app `build.gradle` file:\n\n[ ![Download](https://img.shields.io/maven-central/v/com.maxkeppeler.sheets/core.svg?label=Maven%20Central) ](https://search.maven.org/artifact/com.maxkeppeler.sheets/core)\n\n```gradle\ndependencies {\n  ...\n  implementation 'com.maxkeppeler.sheets:core:\u003clatest-version\u003e'\n}\n```\n\nUse `build` to build a sheet and display it later.\n\n    val sheet = InfoSheet().build(context) {\n      // build sheet\n    }\n\n    sheet.show() // Show sheet when ready\n\nUse `show` if you want to build and then immediately display it.\n\n    InfoSheet().show(context) {\n      // build sheet\n    } // Show sheet\n\n# Resources \n\n📖 Get a better insight into the API\\\n[Sheets API Documentation](https://maxkeppeler.github.io/sheets/api/)\n\n# Info\n\n[ ![Download](https://img.shields.io/maven-central/v/com.maxkeppeler.sheets/info.svg?label=Maven%20Central) ](https://search.maven.org/artifact/com.maxkeppeler.sheets/core)\n\nThe `Info` Sheet lets you display information or warning.\n\n\u003cdetails open\u003e\n\u003cbr/\u003e\n\u003cbr/\u003e\n\u003csummary\u003eShowcase as Dialog\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/InfoSheet Dialog.png\" width=\"80%\" alt=\"Sheets InfoSheet Dialog\"\u003e\u003cbr/\u003e\n\u003cimg src=\"docs/res/InfoSheet Dialog Cover TopStyle Top.png\" width=\"80%\" alt=\"Sheets InfoSheet Dialog\"\u003e\u003cbr/\u003e\n\u003cimg src=\"docs/res/InfoSheet Dialog Cover TopStyle Bottom.png\" width=\"80%\" alt=\"Sheets InfoSheet Dialog\"\u003e\u003cbr/\u003e\n\u003cimg src=\"docs/res/InfoSheet Dialog Cover TopStyle Mixed.png\" width=\"80%\" alt=\"Sheets InfoSheet Dialog\"\u003e\u003cbr/\u003e\n\n\u003c/details\u003e\n\u003c/br\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eShowcase as BottomSheet\u003c/summary\u003e\n\n\u003cbr/\u003e\n\u003cbr/\u003e\n\u003cimg src=\"docs/res/InfoSheet BottomSheet.png\" width=\"80%\" alt=\"Sheets InfoSheet\"\u003e\u003cbr/\u003e\n\u003cimg src=\"docs/res/InfoSheet BottomSheet Cover TopStyle Top.png\" width=\"80%\" alt=\"Sheets InfoSheet BottomSheet\"\u003e\u003cbr/\u003e\n\u003cimg src=\"docs/res/InfoSheet BottomSheet Cover TopStyle Bottom.png\" width=\"80%\" alt=\"Sheets InfoSheet BottomSheet\"\u003e\u003cbr/\u003e\n\u003cimg src=\"docs/res/InfoSheet BottomSheet Cover TopStyle Mixed.png\" width=\"80%\" alt=\"Sheets InfoSheet BottomSheet\"\u003e\u003cbr/\u003e\n\u003c/details\u003e\n\n```gradle\ndependencies {\n  ...\n  implementation 'com.maxkeppeler.sheets:info:\u003clatest-version\u003e'\n}\n```\n\n### Usage\n\nFor the default info sheet use it as following:\n\n    InfoSheet().show(context) {\n      title(\"Do you want to install Awake?\")\n      content(\"Awake is a beautiful alarm app with morning challenges, advanced alarm management and more.\")\n      onNegative(\"No\") {\n        // Handle event\n      }\n      onPositive(\"Install\") {\n        // Handle event\n      }\n    }\n\n# Option\n\n[ ![Download](https://img.shields.io/maven-central/v/com.maxkeppeler.sheets/option.svg?label=Maven%20Central) ](https://search.maven.org/artifact/com.maxkeppeler.sheets/option)\n\nThe `Option` Sheet lets you display a grid or list of options.\n\n\u003cdetails open\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as Dialog\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/OptionsSheet Dialog Grid Middle.png\" width=\"80%\" alt=\"Sheets OptionsSheet Dialog\"\u003e\n\u003c/details\u003e\n\u003c/br\u003e\n\n\u003cdetails\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as BottomSheet\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/OptionsSheet BottomSheet Grid Middle.png\" width=\"80%\" alt=\"Sheets OptionsSheet BottomSheet\"\u003e\n\u003c/details\u003e\n\n\u003cbr/\u003e\n\u003cdetails\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase some variants as Dialogs\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/OptionsSheet Dialog List.png\" width=\"80%\" alt=\"Sheets OptionsSheet Dialog\"\u003e\u003cbr/\u003e\n\u003cimg src=\"docs/res/OptionsSheet Dialog Grid Small.png\" width=\"80%\" alt=\"Sheets OptionsSheet\" Dialog\u003e\u003cbr/\u003e\n\u003cimg src=\"docs/res/OptionsSheet Dialog Grid Large Horizontal.png\" width=\"80%\" alt=\"Sheets OptionsSheet\" Dialog\u003e\u003cbr/\u003e\n\n\u003c/details\u003e\n\u003c/br\u003e\n\n\u003cdetails\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase some variants as BottomSheets\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/OptionsSheet BottomSheet List.png\" width=\"80%\" alt=\"Sheets OptionsSheet BottomSheet\"\u003e\u003cbr/\u003e\n\u003cimg src=\"docs/res/OptionsSheet BottomSheet Grid Small.png\" width=\"80%\" alt=\"Sheets OptionsSheet\" BottomSheet\u003e\u003cbr/\u003e\n\u003cimg src=\"docs/res/OptionsSheet BottomSheet Grid Large Horizontal.png\" width=\"80%\" alt=\"Sheets OptionsSheet\" BottomSheet\u003e\u003cbr/\u003e\n\n\u003c/details\u003e\n\n```gradle\ndependencies {\n  ...\n  implementation 'com.maxkeppeler.sheets:info:\u003clatest-version\u003e'\n}\n```\n\n```gradle\ndependencies {\n  ...\n  implementation 'com.maxkeppeler.sheets:option:\u003clatest-version\u003e'\n}\n```\n\n### Usage\n\nFor the default options sheet use it as following:\n\n    OptionSheet().show(context) {\n      title(\"Text message\")\n      with(\n        Option(R.drawable.ic_copy, \"Copy\"),\n        Option(R.drawable.ic_translate, \"Translate\"),\n        Option(R.drawable.ic_paste, \"Paste\")\n      )\n      onPositive { index: Int, option: Option -\u003e\n        // Handle selected option\n      }\n    }\n\n# Clock\n\n[ ![Download](https://img.shields.io/maven-central/v/com.maxkeppeler.sheets/clock.svg?label=Maven%20Central) ](https://search.maven.org/artifact/com.maxkeppeler.sheets/clock)\n\nThe `Clock` Sheet lets you quickly pick a time.\n\n\u003cdetails\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as Dialog\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/ClockTimeSheet Dialog.png\" width=\"80%\" alt=\"Sheets OptionsSheet Dialog\"\u003e\n\u003c/details\u003e\n\u003c/br\u003e\n\n\u003cdetails open\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as BottomSheet\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/ClockTimeSheet BottomSheet.png\" width=\"80%\" alt=\"Sheets OptionsSheet BottomSheet\"\u003e\n\u003c/details\u003e\n\n```gradle\ndependencies {\n  ...\n  implementation 'com.maxkeppeler.sheets:clock:\u003clatest-version\u003e'\n}\n```\n\n### Usage\n\nFor the default clock time sheet, in 24-hours format, use it as following:\n\n    ClockSheet().show(context) {\n      title(\"Wake-up time\")\n      onPositive { clockTimeInMillis: Long -\u003e\n        // Handle selected time\n      }\n    }\n\n## Time\n\n[ ![Download](https://img.shields.io/maven-central/v/com.maxkeppeler.sheets/time.svg?label=Maven%20Central) ](https://search.maven.org/artifact/com.maxkeppeler.sheets/time)\n\nThe `Duration` Sheet lets you pick a duration time in a specific format.\n\n\u003cdetails open\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as Dialog\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/TimeSheet Dialog.png\" width=\"80%\" alt=\"Sheets TimeSheet Dialog\"\u003e\n\u003c/details\u003e\n\u003c/br\u003e\n\n\u003cdetails\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as BottomSheet\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/TimeSheet BottomSheet.png\" width=\"80%\" alt=\"Sheets TimeSheet BottomSheet\"\u003e\n\u003c/details\u003e\n\n```gradle\ndependencies {\n  ...\n  implementation 'com.maxkeppeler.sheets:duration:\u003clatest-version\u003e'\n}\n```\n\n### Usage\n\nFor the default time sheet use it as following:\n\n    DurationSheet().show(context) {\n      title(\"Snooze time\")\n      onPositive { durationTimeInMillis: Long -\u003e\n        // Handle selected time\n      }\n    }\n\n## Input\n\n[ ![Download](https://img.shields.io/maven-central/v/com.maxkeppeler.sheets/input.svg?label=Maven%20Central) ](https://search.maven.org/artifact/com.maxkeppeler.sheets/input)\n\nThe `Input` Sheet lets you display a form consisting of various inputs.\n\n\u003cdetails\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as Dialog\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/InputSheet Dialog Short.png\" width=\"80%\" alt=\"Sheets InputSheet Dialog\"\u003e\n\u003c/details\u003e\n\u003c/br\u003e\n\n\u003cdetails open\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as BottomSheet\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/InputSheet BottomSheet Short.png\" width=\"80%\" alt=\"Sheets InputSheet BottomSheet\"\u003e\n\u003c/details\u003e\n\n\u003cbr/\u003e\n\u003cdetails\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase some variants as Dialogs\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/InputSheet Dialog Long.png\" width=\"80%\" alt=\"Sheets InputSheet Dialog\"\u003e\u003cbr/\u003e\n\n\u003c/details\u003e\n\u003c/br\u003e\n\n\u003cdetails\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase some variants as BottomSheets\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/InputSheet BottomSheet Long.png\" width=\"80%\" alt=\"Sheets InputSheet BottomSheet\"\u003e\n\u003c/details\u003e\n\n```gradle\ndependencies {\n  ...\n  implementation 'com.maxkeppeler.sheets:input:\u003clatest-version\u003e'\n}\n```\n\n### Usage\n\nFor the default input sheet use it as following:\n\n    InputSheet().show(context) {\n        title(\"Short survey\")\n      with(InputEditText {\n        required()\n        label(\"Your favorite TV-Show\")\n        hint(\"The Mandalorian, ...\")\n        validationListener { value -\u003e } // Add custom validation logic\n        changeListener { value -\u003e } // Input value changed\n        resultListener { value -\u003e } // Input value changed when form finished\n      })\n      with(InputCheckBox(\"binge_watching\") { // Read value later by index or custom key from bundle\n        label(\"Binge Watching\")\n        text(\"I'm regularly binge watching shows on Netflix.\")\n        // ... more options\n      })\n      with(InputRadioButtons() {\n        required()\n        label(\"Streaming service of your choice\")\n        options(mutableListOf(\"Netflix\", \"Amazon\", \"Other\"))\n      })\n      // ... more input options\n      onNegative { showToast(\"InputSheet cancelled\", \"No result\") }\n      onPositive { result -\u003e\n          showToastLong(\"InputSheet result\", result.toString())\n          val text = result.getString(\"0\") // Read value of inputs by index\n          val check = result.getBoolean(\"binge_watching\") // Read value by passed key\n      }\n    }                                  |\n\n## Calendar\n\n[ ![Download](https://img.shields.io/maven-central/v/com.maxkeppeler.sheets/calendar.svg?label=Maven%20Central) ](https://search.maven.org/artifact/com.maxkeppeler.calendar/core)\n\nThe `Calendar` Sheet lets you pick a date or date range. This type was build using the\nlibrary [CalendarView](https://github.com/kizitonwose/CalendarView).\n\n\u003cdetails open\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as Dialog\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/CalendarSheet Dialog Period.png\" width=\"80%\" alt=\"Sheets CalendarSheet Dialog\"\u003e\n\u003c/details\u003e\n\u003c/br\u003e\n\n\u003cdetails\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as BottomSheet\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/CalendarSheet BottomSheet Period.png\" width=\"80%\" alt=\"Sheets CalendarSheet BottomSheet\"\u003e\n\u003c/details\u003e\n\n```gradle\ndependencies {\n  ...\n  implementation 'com.maxkeppeler.sheets:calendar:\u003clatest-version\u003e'\n}\n```\n\n### Usage\n\nFor the default time sheet use it as following:\n\n    CalendarSheet().show(this) { // Build and show\n      title(\"What's your date of birth?\") // Set the title of the sheet\n      onPositive { dateStart, dateEnd -\u003e\n        // Handle date or range\n      }                        |\n\n## Storage\n\n[ ![Download](https://img.shields.io/maven-central/v/com.maxkeppeler.sheets/storage.svg?label=Maven%20Central) ](https://search.maven.org/artifact/com.maxkeppeler.sheets/storage)\n\nThe `Storage` Sheet lets you pick one or more files or folders.\n\n\u003cdetails open\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as Dialog\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/StorageSheet Dialog.png\" width=\"80%\" alt=\"Sheets StorageSheet Dialog\"\u003e\n\u003c/details\u003e\n\u003c/br\u003e\n\n\u003cdetails\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as BottomSheet\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/StorageSheet BottomSheet.png\" width=\"80%\" alt=\"Sheets StorageSheet BottomSheet\"\u003e\n\u003c/details\u003e\n\n```gradle\ndependencies {\n  ...\n  implementation 'com.maxkeppeler.sheets:storage:\u003clatest-version\u003e'\n}\n```\n\n### Usage\n\nFor the default storage sheet use it as following:\n\n    StorageSheet().show(this) {\n      fileDisplayMode(FileDisplayMode.HORIZONTAL)\n      selectionMode(StorageSelectionMode.FILE)\n      onPositive { files -\u003e /* Handle files or folders */ }\n    }\n\n## Color\n\n[ ![Download](https://img.shields.io/maven-central/v/com.maxkeppeler.sheets/color.svg?label=Maven%20Central) ](https://search.maven.org/artifact/com.maxkeppeler.sheets/color)\n\nThe `Color` Sheet lets you pick a color. Display the default material colors or specify which colors\ncan be choosen from. You can allow to chose a custom color as well.\n\n\u003cdetails\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as Dialog\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/ColorSheet Dialog Templates.png\" width=\"80%\" alt=\"Sheets ColorSheet Dialog\"\u003e\u003cbr/\u003e\n\u003cimg src=\"docs/res/ColorSheet Dialog Custom.png\" width=\"80%\" alt=\"Sheets ColorSheet Dialog\"\u003e\n\n\u003c/details\u003e\n\u003c/br\u003e\n\n\u003cdetails open\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as BottomSheet\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/ColorSheet BottomSheet Templates.png\" width=\"80%\" alt=\"Sheets ColorSheet BottomSheet\"\u003e\u003cbr/\u003e\n\u003cimg src=\"docs/res/ColorSheet BottomSheet Custom.png\" width=\"80%\" alt=\"Sheets ColorSheet BottomSheet\"\u003e\n\n\u003c/details\u003e\n\n```gradle\ndependencies {\n  ...\n  implementation 'com.maxkeppeler.sheets:color:\u003clatest-version\u003e'\n}\n```\n\n### Usage\n\nFor the default color sheet use it as following:\n\n    ColorSheet().show(context) {\n      title(\"Background color\")\n      onPositive { color -\u003e\n        // Use color\n      }\n    }\n\n## Custom\n\nWith just the 'core' module you are able to create your own sheet based on this library. You can use\nsome components and styles within your own custom sheet automatically. By default the buttons and\ntoolbar view with logic is ready to be used by your own implementation.\n\n\u003cdetails\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as Dialog\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/Custom Sheet Dialog.png\" width=\"80%\" alt=\"Sheets Custom Dialog\"\u003e\n\u003c/details\u003e\n\u003c/br\u003e\n\n\u003cdetails open\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003csummary\u003eShowcase as BottomSheet\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/Custom Sheet BottomSheet.png\" width=\"80%\" alt=\"Sheets Custom BottomSheet\"\u003e\n\u003c/details\u003e\n\n```gradle\ndependencies {\n  ...\n  implementation 'com.maxkeppeler.sheets:core:\u003clatest-version\u003e'\n}\n```\n\n### Get started\n\nYou can find a custom sheet implementation in the sample module.\n\n1. Step: Create a class and extend from the class `Sheet`.\n\n   class CustomSheet : Sheet() {\n\n2. Step: Implement the method: `onCreateLayoutView` and pass your custom layout.\n\n   override fun onCreateLayoutView(): View { return LayoutInflater.from(activity).inflate(\n   R.layout.sheets_custom, null)\n   }\n\nAll of the base functionality can be used and on top of that you can extend the logic and behavior\nas you wish.\n\n### Components\n\nYou are free to use the components this library uses for it's sheet types.\n\n- `SheetsTitle`\n- `SheetsContent`\n- `SheetsDigit`\n- `SheetsNumericalInput`\n- `SheetsDivider`\n- `SheetsButton`\n- `SheetsEdit`\n- `SheetsRecyclerView`\n- `SheetsValue`\n\n## Lottie\n\n[ ![Download](https://img.shields.io/maven-central/v/com.maxkeppeler.sheets/lottie.svg?label=Maven%20Central) ](https://search.maven.org/artifact/com.maxkeppeler.sheets/lottie)\n\nThe `Lottie` modules gives you the ability to use\na [Lottie animations](https://airbnb.design/lottie/) as cover view.\n\n\u003cdetails open\u003e\n\u003cbr/\u003e\n\u003cbr/\u003e\n\u003csummary\u003eShowcase as Dialog\u003c/summary\u003e\n\n\u003cimg src=\"docs/res/InfoSheet Dialog Cover Lottie Animation.png\" width=\"80%\" alt=\"Sheets InfoSheet\"\u003e\n\u003c/details\u003e\n\u003c/br\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eShowcase as BottomSheet\u003c/summary\u003e\n\n\u003cbr/\u003e\n\u003cbr/\u003e\n\u003cimg src=\"docs/res/InfoSheet BottomSheet Cover Lottie Animation.png\" width=\"80%\" alt=\"Sheets InfoSheet\"\u003e\n\u003c/details\u003e\n\n```gradle\ndependencies {\n  ...\n  implementation 'com.maxkeppeler.sheets:lottie:\u003clatest-version\u003e'\n}\n```\n\n### Usage\n\nYou can use the Lottie animation as a cover for any type of sheet.\n\n    InfoSheet().show(this) {\n      title(\"Team Collaboration\")\n      content(\"In the world of software projects, it is inevitable...\")\n      ...\n      withCoverLottieAnimation(LottieAnimation {\n        setAnimation(R.raw.anim_lottie_business_team)\n        ... Setup Lottie animation\n      })\n      ...\n    }\n\n## Appearance\n\nBy default, the library switches to either day or night mode depending on the\nattr `textColorPrimary`. By default it uses the activity's colorPrimary. The\ndefault `highlightColor` is generated based on the color `sheetsPrimaryColor`, or if not\navailable `colorPrimary`.\n\n### Base\n\nYou want a different sheet background shape? Then just override the corner family and radius.\n\n    \u003citem name=\"sheetsCornerRadius\"\u003e12dp\u003c/item\u003e\n    \u003citem name=\"sheetsCornerFamily\"\u003ecut\u003c/item\u003e\n\nJust overwrite the base colors, if you want to achieve a different look of the sheets than your app.\n\n    \u003citem name=\"sheetsPrimaryColor\"\u003e@color/customPrimaryColor\u003c/item\u003e\n    \u003citem name=\"sheetsHighlightColor\"\u003e@color/customHighlightColor\u003c/item\u003e\n    \u003citem name=\"sheetsBackgroundColor\"\u003e@color/customBackgroundColor\u003c/item\u003e\n    \u003citem name=\"sheetsDividerColor\"\u003e@color/customDividerColor\u003c/item\u003e\n    \u003citem name=\"sheetsIconsColor\"\u003e@color/customIconsColor\u003c/item\u003e\n\nYou can override the basic style of a sheet. Instead of displaying the toolbar, you can just hide it\nand display the typical handle.\n\n    \u003citem name=\"sheetsDisplayHandle\"\u003etrue\u003c/item\u003e\n    \u003citem name=\"sheetsDisplayToolbar\"\u003efalse\u003c/item\u003e\n    \u003citem name=\"sheetsDisplayCloseButton\"\u003efalse\u003c/item\u003e\n\nChange the appearance of the title.\n\n    \u003citem name=\"sheetsTitleColor\"\u003e@color/customTitleTextColor\u003c/item\u003e\n    \u003citem name=\"sheetsTitleFont\"\u003e@font/font\u003c/item\u003e\n    \u003citem name=\"sheetsTitleLineHeight\"\u003e@dimen/dimen\u003c/item\u003e\n    \u003citem name=\"sheetsTitleLetterSpacing\"\u003evalue\u003c/item\u003e\n\nChange the appearance of the content text.\n\n    \u003citem name=\"sheetsContentColor\"\u003e@color/customContentTextColor\u003c/item\u003e\n    \u003citem name=\"sheetsContentInverseColor\"\u003e@color/customContentTextInverseColor\u003c/item\u003e\n    \u003citem name=\"sheetsContentFont\"\u003e@font/font\u003c/item\u003e\n    \u003citem name=\"sheetsContentLineHeight\"\u003e@dimen/dimen\u003c/item\u003e\n    \u003citem name=\"sheetsContentLetterSpacing\"\u003evalue\u003c/item\u003e\n\nChange the appearance of the value texts. (e.g. the time in the TimeSheet \u0026 ClockSheet or the\nselected date \u0026 period in the Calendarsheet.)\n\n    \u003citem name=\"sheetsValueTextActiveColor\"\u003e@color/customValueTextColor\u003c/item\u003e\n    \u003citem name=\"sheetsValueFont\"\u003e@font/font\u003c/item\u003e\n    \u003citem name=\"sheetsValueLineHeight\"\u003e@dimen/dimen\u003c/item\u003e\n    \u003citem name=\"sheetsValueLetterSpacing\"\u003evalue\u003c/item\u003e\n\nChange the appearance of the digit keys on the numerical input.\n\n    \u003citem name=\"sheetsDigitColor\"\u003e@color/customDigitTextColor\u003c/item\u003e\n    \u003citem name=\"sheetsDigitFont\"\u003e@font/font\u003c/item\u003e\n    \u003citem name=\"sheetsDigitLineHeight\"\u003e@dimen/dimen\u003c/item\u003e\n    \u003citem name=\"sheetsDigitLetterSpacing\"\u003evalue\u003c/item\u003e\n\n### Buttons\n\nOverride the appearance of the button text.\n\n    \u003citem name=\"sheetsButtonTextFont\"\u003e@font/font\u003c/item\u003e\n    \u003citem name=\"sheetsButtonTextLetterSpacing\"\u003evalue\u003c/item\u003e\n\nOverride the general appearance of the buttons (negative and positive button).\n\n    \u003citem name=\"sheetsButtonColor\"\u003e@color/customButtonColor\u003citem\u003e\n    \u003citem name=\"sheetsButtonTextFont\"\u003e@font/font\u003citem\u003e\n    \u003citem name=\"sheetsButtonTextLetterSpacing\"\u003evalue\u003citem\u003e\n    \u003citem name=\"sheetsButtonCornerRadius\"\u003e12dp\u003citem\u003e\n    \u003citem name=\"sheetsButtonCornerFamily\"\u003ecut\u003citem\u003e\n    \u003citem name=\"sheetsButtonWidth\"\u003ematch_content/wrap_content\u003citem\u003e\n\nOverride the appearance of the negative button.\n\n    \u003citem name=\"sheetsNegativeButtonType\"\u003etext_button/outlined_button/button\u003citem\u003e\n    \u003citem name=\"sheetsNegativeButtonColor\"\u003ecolor\u003citem\u003e\n    \u003citem name=\"sheetsNegativeButtonCornerRadius\"\u003e12dp\u003citem\u003e\n    \u003citem name=\"sheetsNegativeButtonCornerFamily\"\u003ecut\u003citem\u003e\n\nOverride the appearance of the positive button.\n\n    \u003citem name=\"sheetsPositiveButtonType\"\u003etext_button/outlined_button/button\u003citem\u003e\n    \u003citem name=\"sheetsPositiveButtonColor\"\u003ecolor\u003citem\u003e\n    \u003citem name=\"sheetsPositiveButtonCornerRadius\"\u003e12dp\u003citem\u003e\n    \u003citem name=\"sheetsPositiveButtonCornerFamily\"\u003ecut\u003citem\u003e\n\nOverride the border appearance of the outlined button.\n\n    \u003citem name=\"sheetsButtonOutlinedButtonBorderColor\"\u003e@color/borderColor\u003citem\u003e\n    \u003citem name=\"sheetsButtonOutlinedButtonBorderWidth\"\u003e1dp\u003citem\u003e\n\nThe corner family and radius is applied to the button shape or in the case of a outlined or text\nbutton, to the ripple background shape.\n\n**Fine control**\nYou can even define the corner family and radius of the negative and positive button for each\ncorner.\n\n    \u003citem name=\"sheetsNegativeButtonBottomLeftCornerRadius\"\u003e4dp\u003citem\u003e\n    \u003citem name=\"sheetsNegativeButtonBottomLeftCornerFamily\"\u003ecut\u003citem\u003e\n    ...\n    \u003citem name=\"sheetsPositiveButtonBottomRightCornerRadius\"\u003e8dp\u003citem\u003e\n    \u003citem name=\"sheetsPositiveButtonBottomRightCornerFamily\"\u003erounded\u003citem\u003e\n\n### Handle\n\nThe size and the appearance of the handle can be changed like this:\n\n    \u003citem name=\"sheetsHandleCornerRadius\"\u003e8dp\u003c/item\u003e\n    \u003citem name=\"sheetsHandleCornerFamily\"\u003erounded\u003c/item\u003e\n    \u003citem name=\"sheetsHandleFillColor\"\u003e?sheetPrimaryColor\u003c/item\u003e\n    \u003citem name=\"sheetsHandleBorderColor\"\u003e?sheetPrimaryColor\u003c/item\u003e\n    \u003citem name=\"sheetsHandleBorderWidth\"\u003e1dp\u003c/item\u003e\n    \u003citem name=\"sheetsHandleWidth\"\u003e42dp\u003c/item\u003e\n    \u003citem name=\"sheetsHandleHeight\"\u003e4dp\u003c/item\u003e\n\n### OptionSheet\n\nOverride appearance of selected options.\n\n    \u003citem name=\"sheetsOptionSelectedImageColor\"\u003e@color/customSelectedOptionImageColor\u003c/item\u003e\n    \u003citem name=\"sheetsOptionSelectedTextColor\"\u003e@color/customSelectedOptionTextColor\u003c/item\u003e\n\nOverride appearance of disabled options.\n\n    \u003citem name=\"sheetsOptionDisabledImageColor\"\u003e@color/customDisabledOptionImageColor\u003c/item\u003es\n    \u003citem name=\"sheetsOptionDisabledTextColor\"\u003e@color/customDisabledOptionImageColor\u003c/item\u003e\n    \u003citem name=\"sheetsOptionDisabledBackgroundColor\"\u003e@color/customDisabledOptionBackgColor\u003c/item\u003e\n\n### InputSheet\n\nOverride the appearance of the TextInputLayout (used for the InputEditText).\n\n    \u003citem name=\"sheetsTextInputLayoutCornerRadius\"\u003e12dp\u003c/item\u003e\n    \u003citem name=\"sheetsTextInputLayoutBottomLeftCornerRadius\"\u003e12dp\u003c/item\u003e\n    ... and for all other corners\n    \u003citem name=\"sheetsTextInputLayoutEndIconColor\"\u003e@color/customEndIconColor\u003c/item\u003e\n    \u003citem name=\"sheetsTextInputLayoutHelperTextColor\"\u003e@color/customHelperTextColor\u003c/item\u003e\n    \u003citem name=\"sheetsTextInputLayoutBoxStrokeColor\"\u003e@color/customBoxStrokeColor\u003c/item\u003e\n    \u003citem name=\"sheetsTextInputLayoutHintTextColor\"\u003e@color/customHintTextColor\u003c/item\u003e\n    \u003citem name=\"sheetsTextInputLayoutBoxStrokeErrorColor\"\u003e@color/customBoxStrokeErrorColor\u003c/item\u003e\n    \u003citem name=\"sheetsTextInputLayoutErrorTextColor\"\u003e@color/customErrorTextColor\u003c/item\u003e\n\n# Misc\n\n## Support this project\n\n- Leave a star and tell others about it\n- Watch for updates and improvements.\n- [Open an issue](https://github.com/MaxKeppeler/sheets/issues/) if you see or got any error.\n- Leave your\n  thanks [here](https://github.com/MaxKeppeler/sheets/discussions/categories/show-and-tell) and\n  showcase your implementation.\n- Donate me a coffee.\n\n## Contribute\n\n1. Open an issue to discuss what you would like to change.\n2. Fork the Project\n3. Create your feature branch (feature-[some-name])\n4. Commit your changes\n5. Push to the branch (origin feature-[some-name])\n6. Open a pull request\n\n## Donate\n\nShow your appreciation by donating me a coffee. Thank you very much!\n\n\u003ca href=\"https://ko-fi.com/maxkeppeler\" target='_blank'\u003e\n \u003cimg width=\"180\" src='https://cdn.ko-fi.com/cdn/kofi2.png?v=2' alt='Buy Me a Coffee at ko-fi.com' /\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://www.buymeacoffee.com/maxkeppeler\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png\" alt=\"Buy Me A Coffee\" width=\"160\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://www.paypal.me/maximiliankeppeler\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif\" alt=\"Donate on PaPal\" width=\"160\"\u003e\n\u003c/a\u003e\n\n## Showcase\n\nCheck out some apps which are using this library.\u003cbr/\u003e\n\n- [Aquafy](http://aquafy-mk.com) - Beautiful hydration tracker and reminder.\n- [Awake](http://awake-mk.com) - Intelligent alarms and wake-up challenges and sleep tracking to\n  improve your daily sleep and day-time quality.\n- [Sign for Spotify](https://play.google.com/store/apps/details?id=com.mk.sign.spotifyv2) - Playlist\n  and control widgets for Spotify content.\n\n- [Buddha Quotes](https://play.google.com/store/apps/details?id=org.bandev.buddhaquotes) - Open\n  Source Buddha Quotes.\n\n## License\n\n    Copyright 2020 Maximilian Keppeler https://maxkeppeler.com\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxkeppeler%2Fsheets","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaxkeppeler%2Fsheets","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxkeppeler%2Fsheets/lists"}