Skip to content

feat(ui): update Bible version picker to match Figma#267

Merged
jaredhightower-youversion merged 8 commits into
mainfrom
fix/update-bible-version-abbreviation-title-to-match-figma
Jun 26, 2026
Merged

feat(ui): update Bible version picker to match Figma#267
jaredhightower-youversion merged 8 commits into
mainfrom
fix/update-bible-version-abbreviation-title-to-match-figma

Conversation

@jaredhightower-youversion

@jaredhightower-youversion jaredhightower-youversion commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • BibleVersionPicker: abbreviation tile resized (48→64px, bg-secondary), tighter typography (px-1.5, leading-[1.03], text-foreground)
  • New VersionPublisherName sub-component fetches + renders organization name under each version
  • New OrganizationsClient in packages/core (Zod-validated UUID, GET /v1/organizations/:id)
  • New useOrganizationsClient + useOrganization hooks in packages/hooks
  • organization_id threaded into RecentVersion type so recents also display publisher
  • MSW handlers + mock data added to both core and UI test suites; 19 UI tests passing

PR Description

What changed

  • BibleVersionPicker tile: size size-12size-16, background bg-secondary, border radius rounded-md; abbreviation text uses px-1.5 / leading-[1.03] / text-foreground — matches Figma spec
  • Publisher name row: VersionPublisherName component renders organization name aen loading orunavailable — no layout shift)
  • **OrganizationsCgetOrganization(organizationId)` with UUID validation via Zod
  • useOrganization / useOrganizationsClient (packages/hooks): standard useApiData wrapper, memoized client scoped to YouVersionContext
  • Changeset entry added (packages/ui patch)

Why

Align BibleVersionign tile size, background, and publisher attribution were all missing or wrong.

Figma Link:

https://www.figma.com/design/temXvWs3FR8DZdM8C17ajf/YVP---Reader-SDK-Design-v2?node-id=1-6698&m=dev

Screenshots, Images, Videos, etc

Screenshot 2026-06-23 at 12 51 21 PM
Screen.Recording.2026-06-23.at.2.50.58.PM.mov

Greptile Summary

This PR updates the Bible Version Picker to match the latest Figma spec: the abbreviation tile is resized to 64 px with a secondary background, publisher names are fetched via a new OrganizationsClient / useOrganizations stack and displayed per row, and both brand fonts (Aktiv Grotesk App / Untitled Serif) are reverted to Inter / Source Serif 4 pending licensing review (documented in a new ADR).

  • New API layer (packages/core): OrganizationsClient.getOrganization() with Zod UUID validation; OrganizationSchema already existed and is reused for response validation.
  • New hooks (packages/hooks): useOrganizationsClient, useOrganization, and useOrganizations; the last one deduplicates requests with a per-instance ref-based cache, addressing the N+1 pattern that would otherwise arise from per-row fetching.
  • UI changes (packages/ui): VersionPublisherName sub-component, updated VersionAbbreviationIcon styling, organization_id threaded into RecentVersion (backward-compatible since the field is optional on BibleVersion).

Confidence Score: 5/5

Safe to merge — all three packages gain additive API surface only, no breaking changes, and the font revert eliminates the licensing exposure that existed before this PR.

The new OrganizationsClient, hooks, and UI changes are self-contained additions. The useOrganizations batch/dedupe cache works correctly in all tested scenarios, backward-compatible localStorage handling for pre-existing RecentVersion entries is correct, and the brand font removal is safe and well-documented.

packages/hooks/src/useOrganizations.ts — uniqueIds is captured via closure rather than listed in the effect deps, which may trigger ESLint exhaustive-deps warnings in CI.

Important Files Changed

Filename Overview
packages/hooks/src/useOrganizations.ts New hook that batches + deduplicates organization fetches with a ref-based cache; logic is correct but uniqueIds is captured via closure instead of being listed in the effect deps, which will trigger ESLint exhaustive-deps warnings.
packages/core/src/organizations.ts New OrganizationsClient with Zod UUID validation before the URL is constructed and full schema validation on the response; pure TypeScript, no React dependency (satisfies Zero React rule).
packages/hooks/src/useOrganizationsClient.ts Creates and memoizes an OrganizationsClient scoped to YouVersionContext; pattern is consistent with useBibleClient and other existing client hooks.
packages/ui/src/components/bible-version-picker.tsx Publisher names resolved once at Content level via useOrganizations (avoiding N+1), organization_id correctly treated as optional in RecentVersion, and backward-compatible with existing localStorage entries that predate this field.
packages/ui/src/styles/global.css Removes Aktiv Grotesk App @font-face declarations pending licensing; font revert is coherent with ADR and theme.css changes.
.changeset/bible-version-picker-figma-updates.md Bumps all three packages as minor (correct for new public API additions), though the PR description body says "patch" — a documentation inconsistency.
packages/ui/src/components/bible-version-picker.test.tsx Good coverage for tile styling, digit splitting, publisher name rendering, and recent-version tile parity; 19 tests for the new behaviour.
docs/adr/0001-revert-brand-fonts-pending-licensing.md Well-documented ADR explaining the licensing constraint and the re-application path once clearance is obtained.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant C as Content (BibleVersionPicker)
    participant UO as useOrganizations
    participant UC as useOrganizationsClient
    participant OC as OrganizationsClient
    participant API as GET /v1/organizations/:id

    C->>UO: useOrganizations([...version.organization_id])
    UO->>UC: useOrganizationsClient()
    UC-->>UO: OrganizationsClient (memoized)
    UO->>UO: toUniqueIds() deduplicate + filter nulls
    UO->>UO: cacheRef: find missing ids
    UO->>OC: fetchOrganizations(client, missing[])
    OC->>API: GET /v1/organizations/uuid-1
    OC->>API: GET /v1/organizations/uuid-2
    API-->>OC: Organization response
    API-->>OC: Organization response
    OC-->>UO: Map via Promise.allSettled
    UO->>UO: update cacheRef + setOrganizations(Map)
    UO-->>C: organizations Map
    C->>C: publisherName(version.organization_id)
    C->>C: VersionPublisherName render
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant C as Content (BibleVersionPicker)
    participant UO as useOrganizations
    participant UC as useOrganizationsClient
    participant OC as OrganizationsClient
    participant API as GET /v1/organizations/:id

    C->>UO: useOrganizations([...version.organization_id])
    UO->>UC: useOrganizationsClient()
    UC-->>UO: OrganizationsClient (memoized)
    UO->>UO: toUniqueIds() deduplicate + filter nulls
    UO->>UO: cacheRef: find missing ids
    UO->>OC: fetchOrganizations(client, missing[])
    OC->>API: GET /v1/organizations/uuid-1
    OC->>API: GET /v1/organizations/uuid-2
    API-->>OC: Organization response
    API-->>OC: Organization response
    OC-->>UO: Map via Promise.allSettled
    UO->>UO: update cacheRef + setOrganizations(Map)
    UO-->>C: organizations Map
    C->>C: publisherName(version.organization_id)
    C->>C: VersionPublisherName render
Loading

Reviews (6): Last reviewed commit: "fix(ui): seed recent versions via localS..." | Re-trigger Greptile

@changeset-bot

changeset-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 6ed6e3c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@youversion/platform-core Minor
@youversion/platform-react-hooks Minor
@youversion/platform-react-ui Minor
vite-react Patch

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

@jaredhightower-youversion jaredhightower-youversion requested review from bmanquen and cameronapak and removed request for cameronapak June 23, 2026 18:02
Comment thread packages/ui/src/components/bible-version-picker.tsx
Comment thread packages/hooks/src/useOrganizationsClient.ts
cameronapak
cameronapak previously approved these changes Jun 23, 2026

@cameronapak cameronapak left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address Greptile's comments and then let me know. The PR looks good to me! If you can create a video overviewing the UI changes, that would be very helpful. Please ping me on Teams or here!

Comment thread packages/core/src/organizations.ts
Comment thread packages/core/src/organizations.ts
@jaredhightower-youversion

Copy link
Copy Markdown
Collaborator Author

@cameronapak @bmanquen one thing I noticed when I was when I was making the PR updates, the Figma design has the following fonts that it's using "Untitled Serif" and "Aktiv Grotesk App". Is this something that we want to only apply to this component because I feel like this is more of a wider change that could affect all of the other UI components as well? How would you prefer I go about making this change?

@cameronapak

Copy link
Copy Markdown
Collaborator

@cameronapak @bmanquen one thing I noticed when I was when I was making the PR updates, the Figma design has the following fonts that it's using "Untitled Serif" and "Aktiv Grotesk App". Is this something that we want to only apply to this component because I feel like this is more of a wider change that could affect all of the other UI components as well? How would you prefer I go about making this change?

You don't need to do that. We have a ticket for adding the font. It's been a long running process because we needed that font to be protected from public use and only scoped to licensed usage. Long story short, we had to throw it behind a CDN. Dustin and I will work on that today, but you don't need to use those fonts. https://lifechurch.atlassian.net/browse/YPE-1350

P.S. Web does not have I believe legal ability to use "Aktiv Grotesk App" font, but we will work hard to get Untitled in there soon!

bmanquen
bmanquen previously approved these changes Jun 24, 2026
@bmanquen

Copy link
Copy Markdown
Collaborator

@cameronapak @bmanquen one thing I noticed when I was when I was making the PR updates, the Figma design has the following fonts that it's using "Untitled Serif" and "Aktiv Grotesk App". Is this something that we want to only apply to this component because I feel like this is more of a wider change that could affect all of the other UI components as well? How would you prefer I go about making this change?

You don't need to do that. We have a ticket for adding the font. It's been a long running process because we needed that font to be protected from public use and only scoped to licensed usage. Long story short, we had to throw it behind a CDN. Dustin and I will work on that today, but you don't need to use those fonts. https://lifechurch.atlassian.net/browse/YPE-1350

P.S. Web does not have I believe legal ability to use "Aktiv Grotesk App" font, but we will work hard to get Untitled in there soon!

It looks like @jaredhightower-youversion has already done this font work in this PR or is there more I am missing?

@cameronapak

cameronapak commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Yes, you're missing a convo from standup. @bmanquen All good! thinking...

@jaredhightower-youversion

Copy link
Copy Markdown
Collaborator Author

@cameronapak @bmanquen I just removed all global font work for Aktiv Grotesk and Untitled Serif to keep things clean. I put those changes in another branch so we can pick up where we left off once we have clarity on how we plan to move forward.

#272

@jaredhightower-youversion jaredhightower-youversion force-pushed the fix/update-bible-version-abbreviation-title-to-match-figma branch from 135cf7d to 7b20582 Compare June 24, 2026 20:17
@youversion youversion deleted a comment from syntax303 Jun 24, 2026

@cameronapak cameronapak left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two small, small UI changes. You've done some great work on this PR!

Comment thread packages/ui/src/components/bible-version-picker.tsx Outdated
Comment thread packages/ui/src/components/bible-version-picker.tsx Outdated
Comment thread packages/ui/src/components/bible-version-picker.tsx
Adds useOrganizations(organizationIds), which resolves many organizations
at once, deduplicated by id, so a list of versions sharing publishers only
fetches each organization once. Renames useOrganizationClient ->
useOrganizationsClient and exports the new hook.
… Figma

Default design tokens now use the brand fonts (--yv-font-sans: Aktiv Grotesk
App, --yv-font-serif: Untitled Serif) with Inter / Source Serif 4 as
fallbacks, applied SDK-wide. BibleVersionPicker labels, headings, version
titles, and publisher names render in Aktiv Grotesk App; the abbreviation
tile renders in Untitled Serif Bold. Publisher names are resolved once at
the list level via useOrganizations, avoiding N+1 requests when many
versions share a publisher.
…icensing

Revert Aktiv Grotesk App (--yv-font-sans) to Inter and Untitled Serif
(--yv-font-serif) to Source Serif 4. Remove both CDN @font-face blocks and
the --font-aktiv / --font-untitled-serif aliases, the Reader font picker's
brand options, and the picker abbreviation tile's brand-font class (now
yv:font-serif → Source Serif 4).

Licensing is unresolved: Aktiv (Dalton Maag) is breached the moment a
third-party developer accesses the font file via their app key; Untitled
(Klim) hinges on whether a Platform developer qualifies as a "partner"
under the Enterprise licence. See docs/adr/0001-revert-brand-fonts-pending-licensing.md.

The brand-font implementation is parked on branch feat/youversion-brand-fonts
for re-application via the gated /v1/fonts/{font_id}/stylesheet endpoint once
licensing clears.

Retained: useOrganizations hooks/client, publisher names, the abbreviation
tile redesign, and #265 Book/Chapter typography. Only the font family is
reverted.
Addresses PR review feedback: the abbreviation tiles rendered as full
circles due to the token-based rounded-md radius. Pin to explicit 8px
to match Figma and update tests accordingly.
@jaredhightower-youversion jaredhightower-youversion force-pushed the fix/update-bible-version-abbreviation-title-to-match-figma branch from fd4eb8c to 479c0b2 Compare June 26, 2026 15:58
@jaredhightower-youversion jaredhightower-youversion merged commit 0d184fc into main Jun 26, 2026
6 checks passed
@jaredhightower-youversion jaredhightower-youversion deleted the fix/update-bible-version-abbreviation-title-to-match-figma branch June 26, 2026 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants