{"id":26915923,"url":"https://github.com/composablehorizons/composetheme","last_synced_at":"2025-04-01T18:40:16.691Z","repository":{"id":245106199,"uuid":"815546912","full_name":"composablehorizons/ComposeTheme","owner":"composablehorizons","description":"🖌️ The API to your Compose Design System","archived":false,"fork":false,"pushed_at":"2024-07-06T06:18:45.000Z","size":3882,"stargazers_count":87,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-07-06T07:23:02.315Z","etag":null,"topics":["compose-multiplatform","design-system","jetpack-compose","styling"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"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/composablehorizons.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":"2024-06-15T12:34:52.000Z","updated_at":"2024-07-06T07:23:06.373Z","dependencies_parsed_at":"2024-06-25T11:01:52.085Z","dependency_job_id":null,"html_url":"https://github.com/composablehorizons/ComposeTheme","commit_stats":null,"previous_names":["composablehorizons/composetheme"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/composablehorizons%2FComposeTheme","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/composablehorizons%2FComposeTheme/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/composablehorizons%2FComposeTheme/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/composablehorizons%2FComposeTheme/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/composablehorizons","download_url":"https://codeload.github.com/composablehorizons/ComposeTheme/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246692685,"owners_count":20818725,"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":["compose-multiplatform","design-system","jetpack-compose","styling"],"created_at":"2025-04-01T18:40:16.074Z","updated_at":"2025-04-01T18:40:16.686Z","avatar_url":"https://github.com/composablehorizons.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\u003ch1\u003e\u003cimg src=\"./art/logo.svg\"\u003e Compose Theme\u003c/h1\u003e\n\u003cspan\u003eThe API to your Compose Design System\u003c/span\u003e\n\u003c/div\u003e\n\n## Installation\n\n```kts\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    implementation(\"com.composables:composetheme:1.2.0-alpha\")\n   \n    // includes extensions for material 3 compose\n    implementation (\"com.composables:composetheme-material3:1.2.0-alpha\")\n   \n    // includes extensions for material compose\n    implementation (\"com.composables:composetheme-material:1.2.0-alpha\")\n}\n```\n\n## An API, not a Design System\n\nCompose Theme provides you with the API to build your design system with. It does not come with a set of components that\nrequire specific design tokens or theming properties in order to be rendered.\n\nInstead, it gives you a flexible way to define your own design tokens and properties which are easily accessible from\nyour\ncomposables.\n\nAs a result, you have full control over how your app and API looks like.\n\n## Flexibility to the core\n\nYour app is unique and has unique design requirements. Compose Theme makes it super simple to add new design tokens and\ndesign properties to your themes, using the types you prefer.\n\n## Beautiful defaults\n\nCompose Theme provides you a set of defaults that you can use such as a `colors`, `textStyles` and `shapes`.\n\nYou can use them as is, or use them as a base for your own design system.\n\n## Theming Basics (How to theme your app in \u003c 30 seconds)\n\n1. Use the `buildComposeTheme {}` function to create a new theme. This returns a theme `@Composable` function that we\n   will use in a bit.\n\n```kotlin\nval MyTheme = buildComposeTheme { }\n```\n\n2. Use the returned `@Composable` function to wrap your Compose app:\n\n```kotlin\n@Composable\nfun App() {\n    MyTheme {\n        BasicText(\"Hello Beautiful world!\")\n    }\n}\n```\n\n3. Use the `ComposeTheme` object to use the properties of the currently resolved theme:\n\n```kotlin\n@Composable\nfun App() {\n    MyTheme {\n        BasicText(text = \"Hello Beautiful world!\", style = ComposeTheme.textStyles.base)\n    }\n}\n```\n\nThat's the gist. Keep reading to find out how to extend the default properties or even add your own.\n\n### Using default properties (colors, text styles and shapes)\n\nBy default, themes provide you with 3 sets of properties: colors, text styles and shapes.\n\nYou can access those properties by using the respective extension functions on the `ComposeTheme` object like so:\n\n```kotlin\nval aColor = ComposeTheme.colors.red500\n\nval aTextStyle = ComposeTheme.textStyles.base\n\nval aShape = ComposeTheme.shapes.round\n```\n\nYou can use those properties any way you like.\n\n### Extending the default properties (adding more colors, text styles and shapes)\n\n1. Create a new `DesignToken` for every new token you need:\n\n```kotlin\nval primary = DesignToken\u003cColor\u003e(\"primary\")\nval background = DesignToken\u003cColor\u003e(\"background\")\n```\n\n2. Use the new tokens while setting up your theme and assign a respective value:\n\n```kotlin\nval Theme = buildComposeTheme {\n    colors = DesignTokens(\n        primary to Color.Red,\n        background to Color.Gray,\n    )\n}\n```\n\n3. Wrap your content with the `Theme` function and use the `ComposeTheme` object to get the respective property when you\n   need it:\n\n```kotlin\n@Composable\nfun App() {\n    Theme {\n        Box(Modifier.fillMaxSize().background(ComposeTheme.colors[background])) {\n            Box(Modifier.size(56.dp).background(ComposeTheme.colors[primary]))\n        }\n    }\n}\n```\n\n\u003e [!WARNING]  \n\u003e It is not currently possible to override the default tokens of the default properties\n\n## Define your own design properties (ie adding transition speed)\n\n1. Create a new `DesignProperty` for every new property you need. Design Properties can contain any type:\n\n```kotlin\nval transitions = DesignProperty\u003cTransitions\u003e(\"transitions\")\n\n@Immutable\ndata class Transitions(\n    val fast: Int,\n    val faster: Int\n)\n```\n\n2. Use the new property while setting up your theme:\n\n```kotlin\nval Theme = buildComposeTheme { \n    properties[transitions] = Transitions(\n        fast = 200, \n        faster = 300\n    )\n}\n```\n\n3. Wrap your content with the `Theme` function and use the `ComposeTheme` object to get the respective property when you\n   need it:\n\n```kotlin\n@Composable\nfun App() {\n    Theme {\n        val animationSpeed = ComposeTheme[transition].fast \n        // ...\n    }\n}\n```\n\n## Extend ComposeTheme with existing design systems\n\nLet's assume you have an `ExistingTheme` composable function that uses one or more `CompositionLocalProvider`s that pushes custom colors (such as `tertiary`) down the Compose tree. You probably also have a respective `ExistingTheme` object with extension functions that get the respective `CompositionLocal.current` value. You also use this `ExistingTheme` object across your codebase to gain access to those colors by doing `ExistingTheme.colors.tetriary`.\n\nYou can extend your Compose Theme to use any existing design system using the `extend` function:\n\n```kotlin\nval ComposeThemeExtended = buildComposeTheme {\n    extend { content -\u003e\n        ExistingTheme {\n            content()\n        }\n    }\n}\n```\n\nThis will cause the children of created theme composable function (in this example `ComposeThemeExtended`) to have access to any `CompositionLocal` provided by the `ExistingTheme` function.\n\nYou can now use Compose Theme to easily build flexible themes, while the rest of your code base stays unmodified:\n\n```kotlin\n@Composable\nfun App() {\n   ComposeThemeExtended {\n       // both ExistingTheme \u0026 ComposeTheme are available here\n      Box(Modifier.fillMaxSize().background(ComposeTheme.colors.gray50)) {\n         Box(Modifier.clickable { }.background(ExistingTheme.colors.tertiary, ComposeTheme.shapes.round)) {\n            Text(\"Hello\")\n         }\n      }\n   }\n}\n```\n\n### Extend using Material 3 Compose \u0026 Material Compose \n\nWorking with Material Compose can be painful as it does not support adding new tokens or properties. [The official recommendation](https://developer.android.com/develop/ui/compose/designsystems/custom#extending-material) for adding new properties to your design system is rather verbose as it needs alot of boilerplate to setup and maintain. At the same time, any of our custom components that wrap the Material components require you to continue using `MaterialTheme` which can make the migration to a fully custom design system even harder.\n\nCompose Theme makes it simple to build new themes using existing Material Compose theme setups using the `composetheme-material3` and `composetheme-material` modules.\n\nThese modules add the respective `extendMaterial3` and `extendMaterial` functions that you can use to extend your new theme using Material Design. \n\nThey also add helpful extension functions to the `ComposeTheme` object, so that you can use `ComposeTheme.colorScheme.primary` or `ComposeTheme.typography.bodyLarge` instead of the respective `MaterialTheme` counterpart.\n\nThis gives you both the flexibility to create fully custom themes with any kind of design properties and tokens, while allowing you to continue using the components from Material Compose libraries:\n\n```kotlin\nval buttonLabel = DesignToken\u003cTextStyle\u003e(\"buttonLabel\")\n\nval Material3ThemeExtended = buildComposeTheme {\n    textStyles = DesignTokens(\n       buttonLabel to TextStyle(fontSize = 12.sp, lineHeight = 16.sp)\n    )\n\n   extendMaterial3 {\n      colorScheme = lightColorScheme(\n         primary = Color.Red,\n      )\n      typography = Typography()\n      shapes = Shapes()\n   }\n}\n\n@Composable\nfun App() {\n   Material3ThemeExtended {  \n      Button(onClick = { }) { // this button is rendered Red\n         Text(\"Click me!\", style = ComposeTheme.textStyles[buttonLabel])\n      }\n   }\n}\n```\n\n## Debugging (optional)\n\nYou can define a name to your theme. This is optional but recommended, especially when using multiple themes in your\napp (ie light/dark or nesting themes)\n\nThis will include the name of the resolved theme in error logs, when you try to access an attribute or property that\ndoes not exist in the current theme:\n\n```kotlin\nval primary = DesignToken\u003cColor\u003e(\"primary\")\n\nval LightTheme = buildComposeTheme {\n    name = \"LightTheme\"\n    colors = DesignTokens(\n        primary to Color.Red\n    )\n}\nval DarkTheme = buildComposeTheme {\n    name = \"DarkTheme\"\n}\n\n@Composable\nfun App() {\n    val AppTheme = if (isSystemInDarkTheme()) DarkTheme else LightTheme\n\n    AppTheme {\n        val color = ComposeTheme.colors[primary] // 💥 error while using DarkTheme\n    }\n}\n```\n\nthis will throw an error with the following message:\n`\nTried to access the value of the token called primary, but no tokens with that name are defined within the colors property. You probably forgot to set a primary token in your theme definition. The resolved theme was DarkTheme\n`\n\n## Contributing\n\nWe are currently accepting contributions in the form of bug reports and feature requests, in the form of Github issues.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomposablehorizons%2Fcomposetheme","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcomposablehorizons%2Fcomposetheme","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomposablehorizons%2Fcomposetheme/lists"}