-
Notifications
You must be signed in to change notification settings - Fork 9
Description
Component
- formulus (React Native mobile app)
- formulus-formplayer (React web app)
- synkronus (Go backend server)
- synkronus-cli (Command-line utility)
- Documentation
- synkronus-portal
Goal
Support project-specific (tenant) branding in Formulus so that when the app is used for a given research project (e.g. AnthroCollect), colors and optional assets (e.g. logo) can follow that project’s brand instead of default ODE branding, while keeping a single codebase and default ODE look when no project theme is set.
Problem Statement
Formulus is used by multiple research projects (e.g. AnthroCollect). Each project has its own brand (e.g. “terra cotta” orange, custom logo). Today, the app always uses ODE’s default palette (green primary, gold secondary). Project representatives want the app to feel like their project when their users are using it e.g. AnthroCollect’s orange instead of ODE green without maintaining a fork of Formulus.
We need a way for “this device/user is in project X” to drive which theme is applied (ODE default vs project-specific), and for project themes to be defined and applied in a consistent way.
Proposed Solution
According to some research, apparently we can achieve this in three ways, I personally have some clue on only a few of these ideas but perhaps the team might have interest in others as well;
-
1. Theme source: Define where project branding comes from, e.g.:
- Server-driven: backend (e.g. synkronus or project config API) returns theme for the current project/org (e.g.
primary,secondary, optionallogoUrl), or - Config/bundle: project-specific config or asset bundle that Formulus loads when a project is selected/synced.
- Server-driven: backend (e.g. synkronus or project config API) returns theme for the current project/org (e.g.
-
2. Formulus: When the app knows the current project (e.g. after login/sync or project selection), load that project’s theme (or fall back to ODE defaults). Apply theme via:
- A theme/context layer that overrides the values currently coming from
theme/colors.ts(or from@ode/tokensonce adopted), e.g. primary, secondary, and optionally neutral/accent, and/or - CSS-in-JS / StyleSheet overrides driven by a small set of “brand” variables (e.g.
brandPrimary,brandSecondary) so existing screens and the shared Button don’t need structural changes.
- A theme/context layer that overrides the values currently coming from
-
3. Persistence: Store the active project theme (or project id + cached theme) so it persists across restarts until project/account changes.
-
4. Formulus-formplayer (WebView): If formplayer is embedded and should match the host project’s brand, Formulus passes the resolved theme (e.g. primary/secondary hex) into the WebView (e.g. query param or injected script), and formplayer’s MUI theme uses those values when provided (otherwise ODE tokens).
-
5. Defaults: If no project theme is provided or project is “ODE”/default, use existing ODE colors so current behavior is unchanged.
-
6. Documentation: Document how a new project (e.g. AnthroCollect) can define and ship their theme (e.g. which fields, where they are configured or served from).
Success Criteria
- Formulus can display a project-specific primary (and optionally secondary) color when that project is active, and ODE default colors when no project theme is set.
- Mechanism to provide project theme is defined and implemented (server-driven and/or config), and documented.
- Optional: logo or other asset can be supplied per project and shown in the app (e.g. login or “More” screen).
- Embedded formplayer (if applicable) can receive and apply the same project colors when provided by the host.
- No regression for existing ODE-default usage.
Additional Context
- Current Formulus colors:
formulus/src/theme/colors.ts(ODE green/gold); Button and other components use these. Any project theming should override or feed the same consumption points. - AnthroCollect example: representative mentioned a “terra cotta” orange from their logo; that would be supplied as the project’s primary (or similar) once this capability exists.