Skip to content

Spike: choose the cross-platform styling approach #591

Description

@gaidheal1

Summary

Decide how styling works on both platforms before porting 7,200 lines of SCSS. This spike produces a written decision that gates the porting work in #588.

What the decision has to satisfy

This is not a generic "pick a CSS-in-JS library" question. The existing Sass layer does specific things that any replacement must be able to express, and they're the hard requirements to evaluate against:

  1. Responsive typographyapply-text-style (106 uses) takes a map shaped (base: (...), md: (...), lg: (...)) and emits the base properties plus a media query per breakpoint layer. A replacement needs responsive token values, not just responsive layout.
  2. Variant systems with generated states$button-variants and $list-variants map a variant key to bg/hover/active/disabled, and apply-button-variant / apply-list-variant generate the interaction states from it. apply-list-variant even takes an $is-selected flag that switches the tone. This is logic, and it needs a runtime home.
  3. Breakpoints — 47 responsive rules (40 respond-to, 7 raw @media), with respond-to supporting both up/down directions and raw pixel values.
  4. Composition mixinspage-layout (15 uses) and the list-page-* family (~30 uses) exist so pages share structure. Whatever replaces them needs a composition story.
  5. Colour scales derived at build timetokens/_colors.scss generates 10-step scales via color.adjust($base, $lightness: ±n%). Either precompute these or find a runtime equivalent.

Options to weigh

  • Keep CSS Modules for web, write RN styles separately. Two styling layers, shared tokens only. Lowest risk to the existing web app, highest ongoing duplication cost.
  • Utility/atomic CSS with an RN compiler (e.g. NativeWind-style). One authoring model both platforms understand; means re-expressing the entire layer in utilities and losing the semantic Sass API.
  • Runtime style objects with a theme (RN StyleSheet + a typed theme, or a themed styling library). Closest conceptual match to the current semantic/variant system, since maps-and-functions translate naturally into objects-and-functions. Needs its own responsive solution.
  • A cross-platform UI kit that owns styling. Overlaps with the Radix replacement in Epic: Replace Radix UI with cross-platform primitives (RN/Expo migration prep) #578 — if a kit is chosen there, it likely decides this too. Coordinate the two spikes; don't answer them independently.

Evaluate against: the five requirements above, web bundle size and runtime cost, whether it forces the visual result to change, TypeScript support, and how incrementally it can be adopted (can 57 modules migrate in tranches, or is it all-or-nothing?).

Acceptance criteria

Notes

Timebox it. The realistic outcome is likely "shared TS tokens + runtime style objects", but the responsive-typography and variant requirements are unusual enough to be worth checking properly rather than assumed.

⚠️ Do this after the two cleanup issues — porting a layer that still has duplicate spacing scales and dead partials just carries the mess across.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions