More wiki updating for design token overriding

Mike Schreiber 2022-07-25 20:52:20 -07:00
Родитель 184b8a7f89
Коммит 7c9f91773f
2 изменённых файлов: 86 добавлений и 29 удалений

@ -1,5 +1,7 @@
# Overview
This document covers the basics of our design token system and how it is implemented internally. For details of how to customize tokens in your component or app, see [Overriding Tokens](https://github.com/microsoft/fluentui-apple/wiki/Overriding-Tokens).
## Tokens
Design tokens come in three tiers.
@ -9,17 +11,7 @@ Design tokens come in three tiers.
* Example: `neutral background 2 = gray 98 @ light, gray 36 @ dark`
* Control tokens define how a given control draws itself using alias tokens. This is most likely to be defined in a platform-specific manner.
* Example: `button background = neutral background 2`
Our Swift representation of tokens will reflect his hierarchy, with a unidirectional dependency hierarchy. Controls should only depend on Control tokens, without ever directly referring to an alias or global token.
## Theme customization
Our clients will need to customize these components in two different levels.
The first and simplest level is brand coloring. These apps all use identically-themed controls, with app-appropriate brand coloring replacing our standard blue. This will be provided by a simple color customization API, as described below.
The second, more interesting (and more challenging) level, is a richer themeing support required by some partners. These apps will require near-total customization of components, from colors to fonts to corner radiuses.
To enable this, the aforementioned Control Token classes will be fully customizable, with every property being individually replaceable. See below for more details.
Our Swift representation of tokens will reflect his hierarchy, with a unidirectional dependency hierarchy. Controls should only depend on Control tokens, without ever directly referring to an alias or global token.
# APIs
@ -85,12 +77,7 @@ public final class GlobalTokens {
}
```
These tokens can be read or modified by creating an instance of GlobalTokens and using publicly-accessible subscript notation for any given `TokenSet`:
```swift
let globalTokens = GlobalTokens()
globalTokens.brandColors[.primary] = ColorSet(light: 0xEFF6FC, dark: 0x001526)
```
These tokens can be read or modified by creating an instance of GlobalTokens and using publicly-accessible subscript notation for any given `TokenSet`.
## Alias Tokens
@ -172,18 +159,6 @@ open class CardNudgeTokens: ControlTokens {
}
```
To customize this component, consumers can create a subclass of the token class in their own code, overriding properties as needed, and provide an instance of this subclass in the control's `overrideTokens` property.
```swift
class CustomTokens: CardNudgeTokens {
override var accentIconSize: CGFloat {
return 27
}
}
self.cardNudge.state.overrideTokens = CustomTokens()
```
## Sub-Control tokens
Tokens for controls contained within another control should be defined in the hosting controls tokens as optional, then passed down as a custom subclass of the contained controls tokens to the contained control through override tokens.
@ -232,6 +207,8 @@ From here, our controls will fetch the appropriate FluentTheme from their curren
Note that all approaches described in the following sections are fully interoperable. In fact, if your app mixes SwiftUI and UIKit, youll almost certainly need to implement both solutions. Feel free to provide the same custom theme implementation in both cases to conserve memory.
For more details, see [Overriding Tokens](https://github.com/microsoft/fluentui-apple/wiki/Overriding-Tokens).
## SwiftUI
Our framework provides a simple `ViewModifier` called `fluentTheme(_:)` which takes a `FluentTheme` instance as its only argument. Simply add this view modifier to the highest point in your view hierarchy in which youd like the custom theme to apply, and well take care of the rest.

80
Overriding-Tokens.md Normal file

@ -0,0 +1,80 @@
# Overriding Tokens
This document explains how to override tokens from the Fluent Design System using FluentUI's Theming system.
## Overriding Global Tokens
Global tokens are our most fundamental atoms of design information. Overriding these values will likely have *significant* impact across your app, and is not recommended.
However, there are occasionally scenarios where this will be helpful. To do so, create a unique instance of `GlobalTokens` and provide custom values for any token.
```swift
import FluentUI
let globalTokens = GlobalTokens()
// Any Fluent-defined global tokens can be replaced here.
globalTokens.brandColors[.primary] = DynamicColor(light: ColorValue(0xEFF6FC),
dark: ColorValue(0x001526))
globalTokens.spacing[.medium] = 27
```
Next, this custom instance of GlobalTokens can be used to initialize a FluentTheme:
```swift
let fluentTheme = FluentTheme(globalTokens: globalTokens)
```
Finally, this custom theme can be attached to the root view of any hierarchy which you'd like to customize:
```swift
self.view.fluentTheme = fluentTheme
```
## Overriding Alias Tokens
Like global tokens, alias tokens are stored on the FluentTheme object, so overriding them uses the same mechanism as described in [Overriding Global Tokens](#overriding-global-tokens).
In addition to hard-coded values, your custom alias tokens can also reference global tokens:
```swift
import FluentUI
let aliasTokens = AliasTokens()
// Hard-coded values work fine.
aliasTokens.foregroundColors[.neutral2] = DynamicColor(light: ColorValue(0xEFF6FC),
dark: ColorValue(0x001526))
// You can also reference global tokens.
let globalTokens = GlobalTokens()
aliasTokens.strokeColors[.neutral1] = globalTokens.brandColors[.primary]
// Create and set a custom theme with these customized token sets.
let fluentTheme = FluentTheme(globalTokens: globalTokens, aliasTokens: aliasTokens)
self.view.fluentTheme = fluentTheme
```
## Overriding Component Tokens
To customize an individual component, consumers can create a subclass of the component's token class in their own code, overriding properties as needed, and provide an instance of this subclass in the control's `overrideTokens` property.
```swift
import FluentUI
class CustomCardNudgeTokens: CardNudgeTokens {
override var accentIconSize: CGFloat {
return 27
}
}
self.cardNudge.state.overrideTokens = CustomCardNudgeTokens()
```
This same custom token override can be registered to apply to all components of this type theme-wide:
```swift
view.fluentTheme.register(controlType: CardNudge.self, tokens: {
CustomCardNudgeTokens()
})
```