makiolaj 1af24841ae feat(components): a named header above a run of grouped rows
A settings page with a dozen categories in one flat run has no way to say
which of them are about how the app behaves and which are about the app
itself. GroupedSectionHeader is that label: it starts on GroupedListInset,
the edge the cards it names start on, and owns the gap to the group above,
so a page writes header-then-rows and nothing else.

primary rather than onSurfaceVariant — after the Android-15 settings
pattern Position already follows, and because a header that matches the
summaries underneath it stops separating anything.
2026-09-09 15:17:56 +02:00
2026-07-17 14:56:18 +02:00
2026-08-10 17:20:57 +02:00

floret-kit

The shared Material 3 Expressive design system + plumbing for the Floret family of Android apps (Calendula, Agendula, and future siblings).

"Floret" is the family's design language: a Calendula flower head is a cluster of many small florets, and each app is one of them. This repo is the bloom they share — so a new app doesn't reinvent a settings screen, an edit form, or a theme; it draws from here.

How it's consumed

Each app embeds this repo as a git submodule and wires it in with a Gradle composite build, so the kit is always built from source (no published artifacts — keeps every app reproducible for F-Droid):

// app's settings.gradle.kts
includeBuild("floret-kit")
// app module's build.gradle.kts
implementation("de.jeanlucmakiola.floret:core-time")

Gradle's dependency substitution maps de.jeanlucmakiola.floret:<module> to the local source module — edit the kit and the app picks it up immediately. Android modules need an SDK location for the included build: set ANDROID_HOME (CI) or add a gitignored <app>/floret-kit/local.properties with sdk.dir (locally). See docs/ARCHITECTURE.md for the full consumption model.

Modules

Module Type What it holds
core-time JVM Date/time helpers: DayWindow local-day windows, locale/zone-aware Instant formatting, TimeBridge (millis ↔ Instant). No Android, no deps.
core-reminders JVM Reminder-lead plumbing: the lead-time unit model (ReminderUnit, decomposeReminderMinutes), the per-target override model (ReminderOverride + reminderLeadFor / applyReminderOverride) and the stored-format codec (ReminderOverrideCodec, separators configurable per app). Each app layers its own DataStore + string labels on top.
core-locale Android Everything "what language are we in". Per-app language plumbing (AppLanguage): read the shipped languages from the app's res/xml/locales_config.xml, get/set the applied language via AppCompatDelegate, render each language's autonym. Plus currentLocale() (observes the applied language from Compose) and localizedDateFormatter(locale, skeleton) (lays a field skeleton out in the locale's own order). The app passes its own locales_config.
core-crash Android Privacy-respecting on-device crash capture + report dialog + issue-tracker hand-off. Parameterized per app via CrashConfig.
identity Android The M3 Expressive theme factory FloretExpressiveTheme(…), rememberNavSlideSpec(), the content transitions (expandEnter/collapseExit/itemEnter/…) and the predictiveBack peek. Each app supplies its own seed/palette.
components Android Shared Compose vocabulary + recipes: GroupedSurface/GroupedRow, InlineTextField, OptionCard, CollapsingScaffold, OptionPicker, ReorderableColumn, DebugRibbon, pastelize(), DialogControls, OnboardingScaffold, OptionalFormSection, AboutCard, LanguagePickerRow, SnackChip.

The principle: the mechanics are shared, the look stays per-app. See docs/ROADMAP.md for what's extracted, deferred, and deliberately not shared.

Docs

See docs/ — start with docs/README.md (ARCHITECTURE, ROADMAP) and CONTRIBUTING.md to add or change a module. CHANGELOG.md tracks what landed.

Build

./gradlew :core-time:test          # JVM module tests
./gradlew :core-crash:testDebugUnitTest
./gradlew build                    # everything (Android modules need an SDK; see above)
S
Description
Build infrastructure only — canonical repo: https://codeberg.org/jlmakiola/floret-kit
Readme MIT
497 KiB
Languages
Kotlin 100%