feat(ui): paint and clear non-palette highlight colors - #330
Conversation
Implement YPE-4494 web highlight paint/clear rules aligned with RN Expo: - Apply stays palette-only; reject non-palette writes - Paint valid non-palette API hex; drop invalid hex - Remove tray shows exact hex + checkmark for every distinct valid color (ANY rule) - Add buildVerseActionSwatches and highlight color helpers with unit tests
🦋 Changeset detectedLatest commit: bce34ee The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
cameronapak
left a comment
There was a problem hiding this comment.
Spec
Pass (minor soft edges) vs YPE-4494.
- Apply palette-only; non-palette apply →
noop - Paint accepts valid non-palette; invalid dropped
buildVerseActionSwatches: exact-hex remove + checkmark; apply palette-only; ANY kept- Hook/machine remove path allows non-palette clear
- Changeset present; no Swift/Kotlin
Soft: remove matching in places uses toLowerCase() rather than normalizeHighlightHex (# prefixed edge). Fine if API never sends #.
Standards
Mostly pass.
- Hard (test shape): new
highlight-colors.test.tshas four top-leveldescribes. RootAGENTS.mdMusts ask for one optional top-leveldescribeper module (no nested). Flatten or use one module describe. - Judgement: changeset also patches
@youversion/platform-core+@youversion/platform-react-hookswith no code changes there — confirm that’s intentional for unified versioning. - Judgement: palette-apply gates repeated across machine + hook (policy lives in
highlight-colors, enforcement still sprinkled).
Product rules look right; docs/test-shape nits only.
Code Reviewer bot, sent on behalf of Cam. Own-PR review → COMMENT (GitHub blocks self-approve).
Flatten highlight-colors.test.ts to one module describe with flat it blocks per AGENTS.md testing Musts. Scope the changeset to @youversion/platform-react-ui only; unified versioning is handled by the fixed group in changeset config.
cameronapak
left a comment
There was a problem hiding this comment.
Re-review @ 6cbfbbd
Follow-up addresses the prior Standards notes.
Spec
Pass. Unchanged product rules still match YPE-4494 (prior review).
Standards
Pass.
highlight-colors.test.tsnow uses a single top-leveldescribe('highlight-colors')- Changeset is
platform-react-uionly (core/hooks bump removed)
No remaining blocking findings from my side.
Code Reviewer bot, sent on behalf of Cam. Own-PR review → COMMENT (GitHub blocks self-approve).
Light-mode paints highlights at full strength, so black API colors sat under dark body text. Flip verse text and the remove checkmark to white when fill luma is dark. Co-authored-by: Cursor <cursoragent@cursor.com>
bmanquen
left a comment
There was a problem hiding this comment.
Two-axis review — Standards (repo conventions + Fowler smell baseline) and Spec (YPE-4494, web half only; RN Expo lands on platform-sdk-reactnative-expo#100). Findings are inline, as conventional comments. Nothing fixed — reporting only.
No hard standards violations. All web-half spec requirements are met: apply stays palette-only, paint accepts any valid hex, remove swatches use exact hex + checkmark, invalid hex dropped from paint and tray, ANY rule unchanged. 129 tests pass.
One finding has no diff line to anchor to:
suggestion (non-blocking): docs/highlight-flow-statechart.md:29 — "TAP_COLOR forks in flow: authorized / signed out / no permission" no longer describes the machine; tapInert now also swallows non-palette colors. bible-reader.tsx:241 prose was updated, the statechart and docs/adr/YPE-3705-controlled-mode.md ("Out of scope: … custom colors") were not.
…YPE-4494) - Normalize activeHighlights once in buildVerseActionSwatches (dedupe/casing) - Add Story 10, server-path invalid-hex, and normalization tests - Update highlight-flow and YPE-3705 ADR docs for YPE-4494 rules - Deduplicate hex prefix stripping; document non-palette sort rationale
Rebase left <<<<<<< markers in verse-action-popover.test.tsx at HEAD; keep Edge cases non-palette remove swatch test with fillFor(hex).
Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Review feedback addressed (Brenden / bmanquen)
Spec / correctness
buildVerseActionSwatchesnow normalizes everyactiveHighlightsentry once up front; remove/apply rows use that normalized set only (fixes uppercase/#palette colors missing from remove row and duplicate swatch keys).parseServerColorspath drops invalid hex.Docs
docs/highlight-flow-statechart.md: TAP_COLOR noop covers non-palette apply (YPE-4494).docs/adr/YPE-3705-controlled-mode.md: valid non-palette paint/clear in scope; custom apply creation still out of scope.Nits
stripHighlightHexPrefixhelper for validation + normalization..sort()for stable tray order.fillFor(hex)in popover test instead of magic rgb string.Explicitly not done: machine guard collapse, unified projector, export cleanup,
#rejection tightening.YPE-4494
Visual context (YPE-4494)
Policy in one pass:
Ownership:
Flow:
flowchart LR API[API / controlled highlight] --> Valid{Valid 6-digit hex?} Valid -->|no| Drop[Drop] Valid -->|yes| Paint[Normalize + paint] Paint --> Tray[Popover swatches] Tray --> Remove[Clear at exact hex] Apply[Apply tap] --> Gate{In HIGHLIGHT_COLORS?} Gate -->|yes| Write[Write highlight] Gate -->|no| Reject[Reject]Pairs with expo #131 for the native tray.
Greptile Summary
The PR extends Bible-reader highlight projection and removal to valid non-palette hexadecimal colors while retaining palette-only apply behavior and dropping invalid colors.
Confidence Score: 5/5
The PR appears safe to merge because no blocking failure remains.
No blocking failure remains.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart LR A[API or controlled highlight] --> B{Valid six-digit hex?} B -->|No| C[Drop] B -->|Yes| D[Normalize and paint] D --> E[Expose exact-color clear swatch] F[User apply tap] --> G{Palette color?} G -->|Yes| H[Apply highlight] G -->|No| I[No-op]Reviews (6): Last reviewed commit: "docs(ui): note HIGHLIGHT_COLORS re-expor..." | Re-trigger Greptile
Context used: