makiolaj a366ca9188 feat(components): navigation slot and full-bleed content for the onboarding shell
A step that can be stepped back from passes navigationIcon. The slot's
width is reserved whether or not it is filled, and mirrored on the other
side, so the progress stays centred as steps come and go.

contentPadding lets a step built from grouped rows drop the column's own
inset, since those rows carry their own.
2026-08-10 17:17:16 +02:00
2026-07-17 14:56:18 +02:00
2026-07-17 15:36:44 +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
499 KiB
0 Stars 1 Watchers 0 Forks
Languages
Kotlin 100%