Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/w2sv/composed

A collection of utils to facilitate development with Jetpack Compose.
https://github.com/w2sv/composed

android android-development android-library jetpack-android jetpack-compose utils utils-library

Last synced: 2 months ago
JSON representation

A collection of utils to facilitate development with Jetpack Compose.

Awesome Lists containing this project

README

        

Composed



API



JitPack


Build

GitHub License

------


A collection of utils to facilitate development with Jetpack Compose.

------

# Installation

Make sure you have jitpack added to your dependency resolution repositories by adding the following to your `settings.gradle.kts`:

```kotlin
dependencyResolutionManagement {
repositories {
maven("https://jitpack.io")
}
}
```

Then add the dependencies you lust for to your `build.gradle.kts` files:

```kotlin
dependencies {
// Core utils
implementation "com.github.w2sv.Composed:composed:"
// Permission utils
implementation "com.github.w2sv.Composed:permissions:"
}
```

# Contents

- [State Savers](#state-savers)
- [Styled Text](#styled-text)
- [Modifiers](#modifiers)
- [Layout](#layout)
- [Flow Collectors](#flow-collectors)
- [Lifecycle Observers](#lifecycle-observers)
- [Orientation](#orientation)
- [Dimension Conversion](#dimension-conversion)
- [Color Conversion](#color-conversion)
- [Map Conversion](#map-conversion)
- [Drawer State](#drawerstate)
- [SnackbarHostState](#snackbarhoststate)
- [Easing](#easing)
- [Permission States](#permission-states)

## State Savers

```kotlin
/**
* Returns a rememberSavable state saver for Color.
*/
fun colorSaver(): Saver

/**
* Returns a rememberSavable state saver for an optional Color.
*/
fun nullableColorSaver(): Saver

/**
* listSaver for an optional object, enabling handling of non-null instances only.
*/
fun nullableListSaver(
saveNonNull: SaverScope.(value: Original) -> List,
restoreNonNull: (list: List) -> Original?
): Saver

/**
* mapSaver for an optional object, enabling handling of non-null instances only.
*/
fun nullableMapSaver(
saveNonNull: SaverScope.(value: T) -> Map,
restoreNonNull: (Map) -> T
): Saver
```

## Styled Text

```kotlin
/**
* Converts a HTML-styled string resource text to a remembered AnnotatedString.
*/
@Composable
fun rememberStyledTextResource(@StringRes id: Int, vararg formatArgs: Any): AnnotatedString
```

## Modifiers

```kotlin
/**
* Applies modifiers depending on a condition.
*/
inline fun Modifier.thenIf(
condition: Boolean,
onFalse: Modifier.() -> Modifier = { this },
onTrue: Modifier.() -> Modifier = { this },
): Modifier
```

## Layout

```kotlin
/**
* [Column] whose [elements], rendered through [makeElement], will be divided by [makeDivider]. [makeDivider] will be invoked only in between elements, that is, neither before the first, nor after the last element.
*/
@Composable
fun InterElementDividedColumn(
elements: List,
makeElement: @Composable ColumnScope.(T) -> Unit,
modifier: Modifier = Modifier,
makeDivider: @Composable ColumnScope.() -> Unit = { HorizontalDivider() },
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
)

/**
* [Row] whose [elements], rendered through [makeElement], will be divided by [makeDivider]. [makeDivider] will be invoked only in between elements, that is, neither before the first, nor after the last element.
*/
@Composable
fun InterElementDividedRow(
elements: List,
makeElement: @Composable RowScope.(T) -> Unit,
modifier: Modifier = Modifier,
makeDivider: @Composable RowScope.() -> Unit = { VerticalDivider() },
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
verticalAlignment: Alignment.Vertical = Alignment.Top,
)
```

## Flow Collectors

```kotlin
/**
* Collects from a flow and emits values into a collector.
*/
@Composable
fun CollectFromFlow(
flow: Flow,
key1: Any? = null,
key2: Any? = null,
collector: FlowCollector
)

/**
* Collects latest from a flow with given action.
*/
@Composable
fun CollectLatestFromFlow(
flow: Flow,
key1: Any? = null,
key2: Any? = null,
action: suspend (value: T) -> Unit
)
```

## Lifecycle Observers

```kotlin
/**
* Runs a callback whenever the lifecycleOwner reaches the given lifecycleEvent.
*/
@Composable
fun OnLifecycleEvent(
lifecycleEvent: Lifecycle.Event,
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
key1: Any? = null,
key2: Any? = null,
callback: () -> Unit
)

/**
* Runs a callback when removed from composition.
*/
@Composable
fun OnDispose(callback: () -> Unit)
```

## Orientation

```kotlin
/**
* Returns true if the landscape mode is active, false otherwise.
*/
val isLandscapeModeActive: Boolean

/**
* Returns true if the portrait mode is active, false otherwise.
*/
val isPortraitModeActive: Boolean
```

## Dimension Conversion

```kotlin
/**
* Converts Dp to pixels.
*/
@Composable
@ReadOnlyComposable
fun Dp.toPx(): Float

/**
* Converts pixels to Dp.
*/
@Composable
@ReadOnlyComposable
fun Int.toDp(): Dp

/**
* Converts pixels to Dp.
*/
@Composable
@ReadOnlyComposable
fun Float.toDp(): Dp
```

## Color Conversion

```kotlin
/**
* Converts a hex color string to Color.
*/
fun String.toComposeColor(): Color
```

## Map Conversion

```kotlin
/**
* Converts a regular Map to a SnapshotStateMap.
*/
fun Map.toMutableStateMap(): SnapshotStateMap
```

## DrawerState

```kotlin
/**
* Returns a State whose value ranges from 0.0 (drawer closed) to 1.0 (drawer fully open).
*/
fun DrawerState.visibilityPercentage(@FloatRange(from = 0.0) maxWidthPx: Float): State

/**
* Remembers a visibility percentage for the drawer.
*/
@Composable
fun DrawerState.rememberVisibilityPercentage(@FloatRange(from = 0.0) maxWidthPx: Float = DrawerDefaults.MaximumDrawerWidth.toPx()): State
```

## SnackbarHostState

```kotlin
/**
* Dismisses the currently showing snackbar if there is one and shows a new one with the given [snackbarVisuals].
*/
suspend fun SnackbarHostState.dismissCurrentSnackbarAndShow(snackbarVisuals: SnackbarVisuals)

/**
* Dismisses the currently showing snackbar if there is one and shows a new one with the given parameters.
*/
suspend fun SnackbarHostState.dismissCurrentSnackbarAndShow(
message: String,
actionLabel: String? = null,
withDismissAction: Boolean = false,
duration: SnackbarDuration = if (actionLabel == null) SnackbarDuration.Short else SnackbarDuration.Indefinite
)
```

## Easing

```kotlin
fun TimeInterpolator.toEasing() = Easing
```

## Permission States

```kotlin
/**
* Permission state which, as opposed to the accompanist ones,
* - exposes a [grantedFromRequest] shared flow to allow for distributed subscription and callback invocation, instead of only being able to pass a onPermissionResult callback upon instantiation, which needs to cover all granting reactions, possibly impacting various components
* - allows for callbacks upon permission requesting being suppressed
*/
@Stable
interface ExtendedPermissionState {
val granted: Boolean
val grantedFromRequest: SharedFlow
fun launchRequest(onSuppressed: (() -> Unit)? = null)
}

// With the implementations:

@Stable
open class ExtendedSinglePermissionState(
private val requestLaunchedBefore: StateFlow,
permissionState: PermissionState,
override val grantedFromRequest: SharedFlow,
private val defaultOnLaunchingSuppressed: () -> Unit = {}
) : PermissionState by permissionState, ExtendedPermissionState

@Composable
fun rememberExtendedSinglePermissionState(
permission: String,
requestLaunchedBefore: StateFlow,
saveRequestLaunched: () -> Unit,
defaultOnPermissionResult: (Boolean) -> Unit = {},
defaultOnLaunchingSuppressed: () -> Unit = {},
scope: CoroutineScope = rememberCoroutineScope()
): ExtendedSinglePermissionState

// And

@Stable
open class ExtendedMultiplePermissionsState(
private val requestLaunchedBefore: StateFlow,
multiplePermissionsState: MultiplePermissionsState,
override val grantedFromRequest: SharedFlow,
private val defaultOnLaunchingSuppressed: () -> Unit = {}
) : MultiplePermissionsState by multiplePermissionsState, ExtendedPermissionState

@Composable
fun rememberExtendedMultiplePermissionsState(
permissions: List,
requestLaunchedBefore: StateFlow,
saveRequestLaunched: () -> Unit,
defaultOnPermissionResult: (Map) -> Unit = {},
defaultOnLaunchingSuppressed: () -> Unit = {},
scope: CoroutineScope = rememberCoroutineScope()
): ExtendedMultiplePermissionsState
```

# License
```xml
Designed and developed by 2024 w2sv (Janek Zangenberg)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```