Skip to content

fix: update secondary text color tokens#658

Open
edschema wants to merge 6 commits intoopenedx:developfrom
Schema-Education:openedx-app-ios-textSecondary-fix
Open

fix: update secondary text color tokens#658
edschema wants to merge 6 commits intoopenedx:developfrom
Schema-Education:openedx-app-ios-textSecondary-fix

Conversation

@edschema
Copy link
Copy Markdown

@edschema edschema commented Apr 27, 2026

Description

Fix for this issue: openedx/wg-mobile#42 but extends beyond to fix general issues with textSecondary.

This PR changes the definition of the secondary color text tokens for accessibility purposes. The initial plan was to simply re-define textSecondary light and dark theme color definitions.

The current textSecondary colors are:

theme iOS Android
light #97A5BB contrast ratio: 2.5:1 #B3B3B3 contrast ratio: 2.1:1
dark #79889F contrast ratio: 4.49:1 #B3B3B3 contrast ratio: 7.7:1

Proposed colors:

  • light: #3D4964 contrast ratio on white bg: 8.9:1
  • dark: #8E9BAE contrast ratio on dark bg: 5.7:1

Additionally, in reviewing the uses of textSecondary, I identified several other necessary changes.

  • textSecondary was used to define multiple icons. I added tokens for those cases so they are no longer defined by a text-related token
  • Added a Text Tertiary color for video subtitles (the subtitles that have not been spoken). In this case, Secondary Text coloring was too close to text primary to meaningfully distinguish between those two states. This color still meets minimum contrast requirements.
  • A few misc cleanups: all details below.

Out of Scope (to be addressed later)

  • Unitfy textSecondary and textSecondaryLight: the color definitions are identical. There was no clear reason for both. With the future color design tokens work, we hope to unify Android and iOS token names; we will handle this case as part of that effort (details here: Design Tokens for Mobile wg-mobile#16)

Additional Notes

In re-tokenizing icons, I also slightly shifted the color definition instead of keeping the old referenced "textSecondary" values; those values do not meet minimum contrast requirements. However, I used a slightly lighter shade than the new textSecondary colors. These colors should be evaluated as part of the future color design tokens work; the goal of this PR was to ensure accessibility.

I centralized the default course assignment colors on CourseProgressGradingPolicy because two colors were referencing textSecondary as a fallback color:

  • CourseProgressViewModel.getAssignmentColor(for:)
  • SegmentedProgressView assignment segment fallback

Instead the fallback color (instead of referencing a text-related token) goes back to the default course colors.

fix: replace non-text textSecondary usages

Status: Implemented and committed.

Commit: 3b5eb17 fix: replace non-text textSecondary usages

Change Log

  • Added SwiftUI access to the existing TabbarInactiveColor asset through Theme.Colors.tabbarInactiveColor.
  • Replaced the WhatsNew inactive page indicator color from textSecondaryLight to tabbarInactiveColor.
  • Replaced download progress track colors from textSecondary.opacity(0.5) to courseProgressBG.
  • Replaced unavailable assignment card border and background colors from textSecondary to neutral card stroke tokens.
  • Replaced the assignment detail unavailable border/progress strip from textSecondary to cardViewStroke.
  • Replaced inactive lesson progress dots from textSecondary to progressSkip.
  • Replaced course unit dropdown shadow color from textSecondary to shadowColor.
  • Centralized default course assignment colors on CourseProgressGradingPolicy.
  • Normalized missing or empty assignment_colors responses to the default assignment color palette.
  • Updated assignment progress fallback rendering so malformed or missing assignment colors fall back to the indexed assignment palette instead of textSecondary.
  • Added unit coverage for default assignment color fallback behavior, including empty API color arrays and palette looping.

Notes

  • This change intentionally does not redefine TextSecondary or TextSecondaryLight asset values. It prepares for that follow-up by removing pure non-text dependencies on those text tokens.
  • Remaining textSecondary / textSecondaryLight uses in the touched areas are text labels or mixed icon+text controls and are intentionally out of scope for this first pass.
  • ThemeAssets.swift is generated by SwiftGen and was not edited manually.
  • TabbarInactiveColor already existed in the asset catalog and UIKit theme surface; this change only adds the matching SwiftUI theme exposure.
  • Assignment progress fallback now keeps the existing data-visualization behavior: assignment colors continue to use the default assignment palette and loop when there are more assignment types than palette entries.

fix: update secondary text values and semantic retokens

Commits

  • 86aa7d6 fix: add secondary color theme tokens
  • b330a95 fix: retokenize placeholder and divider colors
  • f3cfa50 fix: retokenize empty state icon colors
  • f185ea5 fix: retokenize secondary content colors
  • d5a9d6e fix: retokenize inactive subtitle color

Change Log

  • Update TextSecondary asset values:
    • light: #3D4964
    • dark: #8E9BAE
  • Update TextSecondaryLight asset values to the same light/dark values while keeping the token separate.
  • Retokenize placeholder text from textSecondary to textInputPlaceholderColor:
    • feedback TextEditor placeholder in AppReviewView
    • fake search bar placeholder in DiscoveryView
  • Retokenize the fake search bar magnifying glass from textSecondary to textInputPlaceholderColor.
  • Add a dedicated empty-state icon color token with light #3D4964 and dark #8E9BAE.
  • Retokenize empty-state/error illustrations from textSecondary / textSecondaryLight to the new empty-state icon token:
    • FullScreenErrorView
    • NoCoursesView
    • AppDownloadsView
    • CoursesToSyncView
  • Add a TextTertiary text color token:
    • light: #5A6E8C
    • dark: #8E9BAE
  • Retokenize inactive video subtitle lines from textSecondary to TextTertiary while keeping active subtitle lines on textPrimary.
  • Add a SecondaryContentColor token for small secondary content/chrome that is not text-only.
  • Retokenize download icon + available-size label pairs in DownloadCourseCell from textSecondary to SecondaryContentColor so each icon and label stay visually equal.
  • Retokenize the edit-profile bottom sheet drag handle from textSecondary to SecondaryContentColor.
  • Retokenize the Delete Account password field label from textSecondary to textPrimary.
  • Retokenize profile support divider rectangles from textSecondary to cardViewStroke.

Expected Visual Impact

UI will look different

  • Approved textSecondary / textSecondaryLight text callsites will change color:
    • light mode: current #97A5BB -> #3D4964
    • dark mode: current #79889F -> #8E9BAE
    • Main effect: secondary text becomes much darker in light mode and slightly lighter in dark mode.
  • Inactive video subtitle lines will move to TextTertiary:
    • light mode: #5A6E8C
    • dark mode: #8E9BAE
    • Active subtitle lines remain textPrimary.
  • Profile support divider lines between rows like Contact Support, Terms of Use, Privacy Policy, FAQ, and version info will move from textSecondary to cardViewStroke:
    • light mode: current #97A5BB -> #CCD3DF
    • dark mode: current #79889F -> #4E5A6F
    • Main effect: dividers become visually subtler.
  • Delete Account password field label will move from textSecondary to textPrimary, matching other text field labels.
  • Empty/error illustrations will move to emptyStateIconColor, with light #3D4964 and dark #8E9BAE. They will visually change from today's old secondary color values while no longer depending on text tokens.
  • DownloadCourseCell icon + available-size label pairs will move to SecondaryContentColor, with the icon and label intentionally staying visually equal. If SecondaryContentColor uses light #3D4964 and dark #8E9BAE, these rows will visually change from today's old secondary color values.
  • The edit-profile bottom sheet drag handle will move to SecondaryContentColor, so it will visually change if that token uses the new secondary content values.
Old textSecondary Updated in this PR
image image
image image
image image

No visual difference expected

  • App review feedback placeholder will move from textSecondary to textInputPlaceholderColor.
  • Discovery search placeholder text and magnifying glass will move from textSecondary to textInputPlaceholderColor.
  • textInputPlaceholderColor currently matches the old secondary values: light #97A5BB, dark #79889F, so these are semantic corrections that should preserve current appearance unless placeholder values change separately.

@openedx-webhooks openedx-webhooks added the open-source-contribution PR author is not from Axim or 2U label Apr 27, 2026
@openedx-webhooks
Copy link
Copy Markdown

Thanks for the pull request, @edschema!

This repository is currently maintained by @openedx/openedx-mobile-maintainers.

Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review.

🔘 Get product approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.
🔘 Provide context

To help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads
🔘 Get a green build

If one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green.

Details
Where can I find more information?

If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources:

When can I expect my changes to be merged?

Our goal is to get community contributions seen and reviewed as efficiently as possible.

However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

@github-project-automation github-project-automation Bot moved this to Needs Triage in Contributions Apr 27, 2026
@mphilbrick211 mphilbrick211 requested a review from a team April 29, 2026 12:03
@mphilbrick211 mphilbrick211 moved this from Needs Triage to Ready for Review in Contributions Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

open-source-contribution PR author is not from Axim or 2U

Projects

Status: Ready for Review

Development

Successfully merging this pull request may close these issues.

3 participants