Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/adrielcafe/bonsai
:deciduous_tree: A multiplatform tree view for Jetpack Compose
https://github.com/adrielcafe/bonsai
android android-library android-ui compose desktop expandable jetpack-compose kotlin kotlin-android kotlin-dsl kotlin-multiplatform selectable tree tree-structure treeview
Last synced: 5 days ago
JSON representation
:deciduous_tree: A multiplatform tree view for Jetpack Compose
- Host: GitHub
- URL: https://github.com/adrielcafe/bonsai
- Owner: adrielcafe
- License: mit
- Created: 2022-04-02T16:54:02.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-04-08T16:20:27.000Z (9 months ago)
- Last Synced: 2024-12-15T05:07:24.892Z (12 days ago)
- Topics: android, android-library, android-ui, compose, desktop, expandable, jetpack-compose, kotlin, kotlin-android, kotlin-dsl, kotlin-multiplatform, selectable, tree, tree-structure, treeview
- Language: Kotlin
- Homepage:
- Size: 274 KB
- Stars: 367
- Watchers: 8
- Forks: 15
- Open Issues: 14
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
Awesome Lists containing this project
README
[![Maven metadata URL](https://img.shields.io/maven-metadata/v?color=blue&metadataUrl=https://s01.oss.sonatype.org/service/local/repo_groups/public/content/cafe/adriel/bonsai/bonsai-core/maven-metadata.xml&style=for-the-badge)](https://repo.maven.apache.org/maven2/cafe/adriel/bonsai/)
[![Android API](https://img.shields.io/badge/api-21%2B-brightgreen.svg?style=for-the-badge)](https://android-arsenal.com/api?level=21)
[![kotlin](https://img.shields.io/github/languages/top/adrielcafe/bonsai.svg?style=for-the-badge&color=blueviolet)](https://kotlinlang.org/)
[![ktlint](https://img.shields.io/badge/code%20style-%E2%9D%A4-FF4081.svg?style=for-the-badge)](https://ktlint.github.io/)
[![License MIT](https://img.shields.io/github/license/adrielcafe/voyager.svg?style=for-the-badge&color=orange)](https://opensource.org/licenses/MIT)
Bonsai
A batteries-included Tree View for Jetpack Compose
#### Features
- [x] Multiplatform: Android, Desktop
- [x] State-aware: changes in the tree will trigger recomposition
- [x] Unlimited depth
- [x] Lazy loaded nodes
- [x] Survives activity recreation
- [x] [Built-in DSL](#usage)
- [x] [File System integration](#file-system-integration)
- [x] [JSON integration](#json-integration)
- [x] [Expandable](#expanding--collapsing)
- [x] [Selectable](#selecting)
- [x] [Clickable](#click-handling)
- [x] [Styleable](#styling)
- [x] [Extendable](#custom-nodes)#### Roadmap
- iOS support
- Draggable nodes
- FileObserver (Android) and/or WatchService (JVM) integration## Import to your project
Add the desired dependencies to your module's `build.gradle`:
```gradle
implementation "cafe.adriel.bonsai:bonsai-core:${latest-version}"
implementation "cafe.adriel.bonsai:bonsai-file-system:${latest-version}"
implementation "cafe.adriel.bonsai:bonsai-json:${latest-version}"
```Current version: ![Maven metadata URL](https://img.shields.io/maven-metadata/v?color=blue&metadataUrl=https://s01.oss.sonatype.org/service/local/repo_groups/public/content/cafe/adriel/bonsai/bonsai-core/maven-metadata.xml)
## Usage
Bonsai comes with a handy DSL for creating high-performance, customizable trees:
1. Start by creating a new tree with `Tree{}`
2. Create nodes with `Leaf()` and `Branch()`
3. Call `Bonsai()` to render the tree
```kotlin
@Composable
fun BonsaiExample() {
val tree = Tree {
Branch("Mammalia") {
Branch("Carnivora") {
Branch("Canidae") {
Branch("Canis") {
Leaf("Wolf", customIcon = { EmojiIcon("🐺") })
Leaf("Dog", customIcon = { EmojiIcon("🐶") })
}
}
Branch("Felidae") {
Branch("Felis") {
Leaf("Cat", customIcon = { EmojiIcon("🐱") })
}
Branch("Panthera") {
Leaf("Lion", customIcon = { EmojiIcon("🦁") })
}
}
}
}
}Bonsai(tree)
}
```Output:
**Take a look at the [sample app](https://github.com/adrielcafe/bonsai/blob/main/sample/src/main/java/cafe/adriel/bonsai/sample/) for working examples.**
### File System integration
Import `cafe.adriel.bonsai:bonsai-file-system` module to use it.```kotlin
val tree = FileSystemTree(
// Also works with java.nio.file.Path and okio.Path
rootPath = File(path),
// To show or not the root directory in the tree
selfInclude = true
)Bonsai(
tree = tree,
// Custom style
style = FileSystemBonsaiStyle()
)
```Output:
### JSON integration
Import `cafe.adriel.bonsai:bonsai-json` module to use it.```kotlin
val tree = JsonTree(
// Sample JSON from https://gateway.marvel.com/v1/public/characters
json = responseJson
)Bonsai(
tree = tree,
// Custom style
style = JsonBonsaiStyle()
)
```Output:
### Expanding & Collapsing
Easily control the expanded/collapsed state of your `Tree`:
* `toggleExpansion(node)`
* `collapseRoot()` / `expandRoot()`
* `collapseAll()` / `expandAll()`
* `collapseFrom(depth)` / `expandUntil(depth)`
* `collapseNode(node)` / `expandNode(node)`### Selecting
Selected/Unselected state is also pretty simple to control:
* `selectedNodes`
* `toggleSelection(node)`
* `selectNode(node)` / `unselectNode(node)`
* `clearSelection()`### Click handling
Its also possible to set custom click behaviors for your `Tree`. Control single, double and long clicks by using the [expand](#expanding--collapsing) and [select](#selecting) APIs.
```kotlin
Bonsai(
tree = tree,
onClick = { node ->
tree.clearSelection()
tree.toggleExpansion(node)
},
onDoubleClick = { node -> /* ... */ },
onLongClick = { node -> /* ... */ }
)
```### Styling
Change your `Tree` appearance as you wish. Take a look at `BonsaiStyle` class for all available customizations.
```kotlin
Bonsai(
tree = tree,
style = BonsaiStyle(
toggleIconRotationDegrees = 0f,
toggleIcon = { node ->
rememberVectorPainter(
if (node is BranchNode && node.isExpanded) Icons.Outlined.UnfoldLess
else Icons.Outlined.UnfoldMore
)
},
nodeIconSize = 18.dp,
nodeShape = CutCornerShape(percent = 20),
nodeCollapsedIcon = { rememberVectorPainter(Icons.Outlined.Circle) },
nodeExpandedIcon = { rememberVectorPainter(Icons.Outlined.Adjust) },
nodeNameTextStyle = MaterialTheme.typography.overline
)
)
```Output:
### Custom nodes
Need a deeper customization? You can set `customIcon`s and `customName`s for each `Leaf()` and `Branch()` nodes.
```kotlin
Leaf(
content = "Wolf",
customIcon = { EmojiIcon("🐺") }
)
```Output: