feat(ui): update Bible version picker to match Figma#267
Conversation
🦋 Changeset detectedLatest commit: 6ed6e3c 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.
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!
|
@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? |
|
Yes, you're missing a convo from standup. @bmanquen All good! thinking... |
|
@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. |
135cf7d to
7b20582
Compare
cameronapak
left a comment
There was a problem hiding this comment.
Two small, small UI changes. You've done some great work on this PR!
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.
fd4eb8c to
479c0b2
Compare
Summary
BibleVersionPicker: abbreviation tile resized (48→64px, bg-secondary), tighter typography (px-1.5,leading-[1.03],text-foreground)VersionPublisherNamesub-component fetches + renders organization name under each versionOrganizationsClientinpackages/core(Zod-validated UUID, GET/v1/organizations/:id)useOrganizationsClient+useOrganizationhooks inpackages/hooksorganization_idthreaded intoRecentVersiontype so recents also display publisherPR Description
What changed
BibleVersionPickertile: sizesize-12→size-16, backgroundbg-secondary, border radiusrounded-md; abbreviation text usespx-1.5 / leading-[1.03] / text-foreground— matches Figma specVersionPublisherNamecomponent renders organization name aen loading orunavailable — no layout shift)OrganizationsCgetOrganization(organizationId)` with UUID validation via ZoduseOrganization/useOrganizationsClient(packages/hooks): standarduseApiDatawrapper, memoized client scoped toYouVersionContextpackages/uipatch)Why
Align
BibleVersionigntile 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
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
secondarybackground, publisher names are fetched via a newOrganizationsClient/useOrganizationsstack 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).packages/core):OrganizationsClient.getOrganization()with Zod UUID validation;OrganizationSchemaalready existed and is reused for response validation.packages/hooks):useOrganizationsClient,useOrganization, anduseOrganizations; 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.packages/ui):VersionPublisherNamesub-component, updatedVersionAbbreviationIconstyling,organization_idthreaded intoRecentVersion(backward-compatible since the field is optional onBibleVersion).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
uniqueIdsis captured via closure instead of being listed in the effect deps, which will trigger ESLint exhaustive-deps warnings.OrganizationsClientwith Zod UUID validation before the URL is constructed and full schema validation on the response; pure TypeScript, no React dependency (satisfies Zero React rule).OrganizationsClientscoped toYouVersionContext; pattern is consistent withuseBibleClientand other existing client hooks.Contentlevel viauseOrganizations(avoiding N+1),organization_idcorrectly treated as optional inRecentVersion, and backward-compatible with existing localStorage entries that predate this field.@font-facedeclarations pending licensing; font revert is coherent with ADR andtheme.csschanges.minor(correct for new public API additions), though the PR description body says "patch" — a documentation inconsistency.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%%{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 renderReviews (6): Last reviewed commit: "fix(ui): seed recent versions via localS..." | Re-trigger Greptile