• Stars
    star
    335
  • Rank 125,904 (Top 3 %)
  • Language
    Kotlin
  • Created over 2 years ago
  • Updated almost 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A proof-of-concept of a fractal/recursive navigation system.

compose-fractal-nav

A proof-of-concept of a fractal/recursive navigation system.

Instead of defining a bunch of top-level routes with navigation moving laterally between them, you define your navigation recursively. You can think of it like showing your entire composable UI at once, where certain parts can be zoomed-into. It's hard to explain and I'm writing this README after 3 straight days of hacking on my vacation, so easier to just show you. This is the app in this repo:

fractal-nav-long-demo.mp4

API

Like most navigation libraries, this one starts with a wrapper composable that defines the navigable area. It's called FractalNavHost. It provides a FractalNavScope to its content composable. Inside that block, you can define "zoomable" children with the FractalNavChild composable. Each child is identified with a string key, and you can zoom into a child by calling zoomToChild().

The content block of a FractalNavChild gets access to a few properties that describe whether or not it's zoomed in, how far it's zoomed, and a function that zooms it back out to its parent.

Children can also define their own children, recursing as deep as you like. The library will only compose what's necessary to show the active child. Everything between the FractalNavHost and the FractalNavChild will be removed from the composition – even when multiple children are nested. When a child zooms back out, its parent content is composed again, with any state from rememberSaveables restored.

For more details, take a look at FractalNavScope and FractalNavChildScope.

API sample

Let's build this simple app:

sample-demo.mp4

Here's the code:

// The host should wrap the root of your app.
FractalNavHost(Modifier.fillMaxSize()) {
    Row(Modifier.wrapContentSize()) {
        Text("Click ")
        Link("here") {
            Text(
                "42",
                // Scale the text in when clicked.
                modifier = Modifier.scaleByZoomFactor(),
                style = MaterialTheme.typography.h1,
                maxLines = 1
            )
        }
        Text(" to learn more.")
    }
}

And here's the Link function:

@Composable
fun FractalNavScope.Link(
    text: String,
    content: @Composable FractalNavChildScope.() -> Unit
) {
    // This creates some content that can be zoomed into.
    FractalNavChild(
        // It's identified by a string key…
        key = "link",
        modifier = Modifier.clickable {
            // …which can be used to expand its content. This will animate
            // the content block below to take up the full screen and also
            // zoom the parent content, that called this composable, out of
            // view.
            zoomToChild("link")
        }
    ) {
        Box(contentAlignment = Alignment.Center) {
            Text(text, Modifier.graphicsLayer {
                // The zoomFactor property is available inside the FractalNavChild
                // block. It starts at 0, then when zoomToChild is called it will
                // be animated up to 1. In this case, we want this text to start
                // at the full size and shrink when zoomed in.
                alpha = 1f - zoomFactor
            })

            // The isActive flag is also provided inside the FractalNavChild
            // content block, and means `zoomFactor > 0` – but is backed by
            // a derivedStateOf so it won't invalidate more than once during
            // the zoom animation.
            if (isActive) {
                content()
                BackHandler {
                    // This will animate zoomFactor back down to 0.
                    zoomToParent()
                }
            }
        }
    }
}

More Repositories

1

goadb

A Golang library for interacting with adb.
Go
229
star
2

adbfs

A FUSE filesystem that uses goadb to expose Android devices' filesystems.
Go
150
star
3

compose-undo

Undo snapshot state changes in Compose.
Kotlin
142
star
4

goregen

randexp for Go.
Go
90
star
5

compose-autotransition

A simple library for automatically animating between Compose states.
Kotlin
77
star
6

compose-seqdiag

Sequence diagram renderer for Jetpack Compose.
Kotlin
60
star
7

compose-revealer

Kotlin
47
star
8

compose-model

Kotlin
36
star
9

compose-touchbar

Kotlin
16
star
10

go-typedregexp

typedregexp matches regular expressions into structs.
Go
15
star
11

statedatastore

A snapshot state wrapper for the Jetpack Datastore library.
Kotlin
13
star
12

compose-worksheet-blog

Code for a blog post about derivedStateOf.
Kotlin
12
star
13

captivate

A simple service for detecting wifi hotspots that ask for information (captive portals), and automatically showing the login page.
Java
9
star
14

flow-operators

Some additional operators for Kotlin's cold stream library Flow
Kotlin
8
star
15

snapshot-state-swiftui-bridge

An experiment to consume Jetpack Compose's snapshot state change tracking from SwiftUI
Kotlin
7
star
16

web-adb

A Chrome extension and accompanying native adb proxy for working with Android devices over the Android Debug Bridge.
Go
7
star
17

regen

Simple command-line utility for generating strings from regular expression patterns.
Go
6
star
18

coroutine-workflows-poc

This is a proof-of-concept for entirely coroutine-based reactor + workflows.
Kotlin
6
star
19

rxkotlin

Pretending to write a cold streams library for Kotlin using coroutines.
Kotlin
5
star
20

textbuffer-sandbox

A repo for benchmarking different text buffer implementations.
Kotlin
5
star
21

go-pcomb

Parser Combinators for Golang
Go
4
star
22

gofontviewer

Render TTF fonts to an HTML5 Canvas in Go.
Go
3
star
23

zach-klippenstein.github.com

My personal website.
HTML
2
star
24

fraknums

Kotlin port of https://github.com/pyricau/fragnums
Kotlin
2
star
25

afpfs-ng

afpfs-ng is an Apple Filing Protocol client that will allow BSD, Linux and Mac OS X systems to access files exported from a Mac OS system with AFP over TCP.
Shell
2
star
26

with-intent

With Intent is a utility app for developers that lets you build and send intents without writing up a script or a test app.
Kotlin
2
star
27

ReproComposeAndroidViewTreeOwnersBugs

Kotlin
1
star
28

workflow-react-native-experiment

Experimenting with wiring up React Native to Workflow
Kotlin
1
star
29

snapshot-linked-list-blog

Kotlin
1
star
30

phrase-styling-example

Demonstrates a couple of different ways to style text with Phrase
Java
1
star