Support for customizing a page’s accent color in Swift-DocC

Hi all,

This post discusses an enhancement to Swift-DocC and Swift-DocC-Render that will allow developers to specify an accent color for a given documentation page. This is another step towards allowing for completely custom page types in Swift-DocC.

The proposed implementation for this feature is here:

Introduction

We’ve recently added a handful of directives to Swift-DocC with an overarching goal of allowing for more fun and creative documentation authoring while allowing projects with more complicated documentation needs the ability to create entirely custom page types. Using @Option and @Metadata directives in coordination with layout directives like @Row and @TabNavigator allow documentation authors to create truly unique documentation pages that feel at home with the specific technology their documenting.

However, a big gap in this story is the introduction and customization of accent colors. The uses for this range from using an in-theme color on a top-level page to align with a project’s design (for example, perhaps the Vapor project might like to use purple in their documentation), to creating distinct page types within a set of documentation. Tip articles, for example, might use yellow, while more technical deep-dive articles might use blue.

Solution

I want to be careful to keep the semantic nature of Swift-DocC’s directives intact while introducing the concept of color. I also want to ensure that accent color customization is easy to use for folks working without a designer – this should not be an advanced feature for a niche audience, it should be easily accessible to all Swift-DocC users.

For these reasons, I propose that we limit the supported colors to a set of standardized ones that can be context-dependent. This allows renderers (like Swift-DocC-Render) to use the given page color as a hint for the rest of the colors used on the page and ensure that all the colors are presented in an accessible way. The page color isn't tied to any specific element on the page and renderers (like Swift-DocC Render) may use various shades of the color on various elements to accent the page. Initially Swift-DocC-Render will use a shade of the color as the background behind the page's title. In the future DocC-Render may use the page color as an accent in more places.

Importantly, these colors should be further customizable using the theme-settings.json – allowing different documentation hosts to interpret the colors differently and better align with their overall website design.

This begs the question of how @PageColor and theme-settings.json relate to each other and how they can be used together. Both @PageColor and theme-settings.json are used to style content but they have very different levels of purpose and specificity. @PageColor specifies that “This page is blue” whereas theme-settings.json specifies that “when this page is blue, the light mode shade of blue for the intro background is X and the dark mode shade of blue for the intro background is Y.” The theme-settings.json file is also used for detailed customization of a theme that applies to all documentation pages. On the other hand, the @PageColor directive is a per-page configuration.

Details

Declaration

@PageColor(_ color: Color)

Overview

Use the PageColor directive to provide a hint to the Swift-DocC renderer as to what color should represent this page. The renderer will use this color, depending on the context, as a foundation for the other accent colors used in the page. For example, Swift-DocC-Render will use this color as the primary background color of a page’s introduction section and adjust the colors of the icon and text in the page’s introduction accordingly.

This directive is only valid within an @Metadata directive.

@Metadata {
    @PageColor(purple)
}

Parameters

@PageColor accepts the following parameters:

  • color: An unnamed parameter that accepts one of the following pre-defined colors. Each color is context-dependent.
    • blue
    • gray
    • green
    • orange
    • purple
    • red
    • yellow

Theme Settings

DocC-Render will add theme setting properties for each new color so that they can be customized. Initially @PageColor will only affect the introduction section’s fill color so the setting is designed to be specific to this part of the page. If we expand page color to affect additional parts of the page (font color, icon color, etc), additional properties can be added.

{
  "theme": {
    "color": {
      "standard-blue-documentation-intro-fill": "cornflowerblue",
      "standard-purple-documentation-intro-fill": "rebeccapurple"
    }
  }
}

An updated OpenAPI spec is available in the implementation PR.

Examples

The following screenshots show how Swift-DocC Render might interpret the given color inputs initially.

Future Directions

In the short term I can imagine expanding beyond this initial set of limited colors as we see a need in the community. These seven establish a good foundation but should not be viewed as a limit – we can add additional standard colors as needed.

Longer term, I see a need for two things. The first is a way to define truly custom colors. I think this should likely be integrated with the existing theming system – the color would be defined with a custom identifier in a separate JSON file and then referenced from the @PageColor directive.

@Metadata {
    @PageColor(custom: "swift-orange")
}

We’re also seeing a need for some kind of directive that would allow for standardizing the use of @Metadata directives across pages. For example, if all of my “Tip” pages use the following directives:

@Metadata {
    @TitleHeading("Tip")
    @PageColor(yellow)
    @PageImage(purpose: icon, source: "tip-icon")
}

There ought to be a way to collect these directives in a dynamic PageKind and then instead reference that kind on all of my tip pages.

@Metadata {
    @PageKind(tip)
}

Alternatives Considered

I initially considered allowing authors to specify arbitrary RGB values with something like the following:

@Metadata {
    @PageColor(red: 233, green: 58, blue: 43)
}

This was immediately problematic because of the potential for the number of colors a user would need to specify. Some that come to mind:

  • Light mode variants
  • Dark mode variants
  • P3 variants
  • Affected link colors
  • Affected font colors

It became clear that this kind of fully custom color authoring does not belong alongside the rest of the content in the markdown file. We should allow fully custom colors – but it should be done with the theming system as is described in Future Directions.

I would appreciate feedback on some alternative names for the directive. Some options I’m still considering:

@PageAccentColor
@AccentColor

I feel the pitched @PageColor is the best option of these three but would welcome counter arguments or alternative suggestions.

4 Likes

This change has landed as described above on the release/5.9 branch of Swift-DocC and Swift-DocC-Render and should be available in recent nightly toolchains.

Please let me know if you have any feedback after trying out the feature!

2 Likes