From 52b0b86ce7430118ab988f784d6422ff8b780c93 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Mon, 2 Nov 2026 20:46:29 +0100 Subject: feat(ui-compose): add the breadcrumb model Co-Authored-By: Claude Opus 5.5 --- .../app/passwordstore/ui/compose/Breadcrumbs.kt | 16 +++++++++++ .../passwordstore/ui/compose/BreadcrumbsTest.kt | 33 ++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 ui/compose/src/main/kotlin/app/passwordstore/ui/compose/Breadcrumbs.kt create mode 100644 ui/compose/src/test/kotlin/app/passwordstore/ui/compose/BreadcrumbsTest.kt (limited to 'ui/compose/src') diff --git a/ui/compose/src/main/kotlin/app/passwordstore/ui/compose/Breadcrumbs.kt b/ui/compose/src/main/kotlin/app/passwordstore/ui/compose/Breadcrumbs.kt new file mode 100644 index 00000000..d8bc02fe --- /dev/null +++ b/ui/compose/src/main/kotlin/app/passwordstore/ui/compose/Breadcrumbs.kt @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2026 Danilo M. + * SPDX-License-Identifier: GPL-3.0-only + */ + +package app.passwordstore.ui.compose + +/** One breadcrumb chip. The root crumb has an empty [label] and [path]. */ +public data class Crumb(val label: String, val path: String) + +/** Crumbs for a folder at [relativePath] inside the store: root first, then each level. */ +public fun crumbsFor(relativePath: String): List { + val parts = relativePath.split('/').filter { it.isNotEmpty() } + return listOf(Crumb("", "")) + + parts.indices.map { i -> Crumb(parts[i], parts.subList(0, i + 1).joinToString("/")) } +} diff --git a/ui/compose/src/test/kotlin/app/passwordstore/ui/compose/BreadcrumbsTest.kt b/ui/compose/src/test/kotlin/app/passwordstore/ui/compose/BreadcrumbsTest.kt new file mode 100644 index 00000000..2eb4c3fc --- /dev/null +++ b/ui/compose/src/test/kotlin/app/passwordstore/ui/compose/BreadcrumbsTest.kt @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2026 Danilo M. + * SPDX-License-Identifier: GPL-3.0-only + */ + +package app.passwordstore.ui.compose + +import kotlin.test.Test +import kotlin.test.assertEquals + +class BreadcrumbsTest { + + @Test + fun rootOnly() { + assertEquals(listOf(Crumb("", "")), crumbsFor("")) + } + + @Test + fun nestedPath() { + assertEquals( + listOf(Crumb("", ""), Crumb("work", "work"), Crumb("servers", "work/servers")), + crumbsFor("work/servers"), + ) + } + + @Test + fun ignoresStraySlashes() { + assertEquals( + listOf(Crumb("", ""), Crumb("work", "work"), Crumb("servers", "work/servers")), + crumbsFor("/work//servers/"), + ) + } +} -- cgit v1.2.3