Framework
Tokens for semantics
These tokens can be used mainly for component tokens to apply some style and configuration values ; today component tokens or components are not defined yet. They can be seen as an high level of usage with functional meanings.
Overview
🧬 Core version: 1.10.0
If we need for example to change a warning color for a button (which has its component tokens, see OUDSTokensComponent), supposing this color is defined as a semantic token, we only have to change its assigned value and all components using the semantic token won’t be impacted in their definition. In fact, semantic tokens are here to bring meaning, semantic, between raw values and components.
In addition, there are hundreds of semantics tokens which must be exposed in the end through the theme. Each semantic token “family” is declared in its dedicated Swift protocol. This protocol is then used for the tokens providers embeded inside the theme.
Because we choose to split responsabilities and objects into their own modules, we faced troubles to make possible for children themes to override properties declared in protocols and defined in extensions. That is the reason why tokens are exposed as @objc open to be available and overridable anywhere.
To keep the same semantics as the ones used in our specifications, typealias are used so as to make the links to primitive types and our logic of tokens. These type aliases are available for those who want to make their own theme.
Example with ColorSemanticTokens:
// Declare the semantic tokens
protocol ColorSemanticTokens {
var bgPrimary: ColorSemanticToken { get }
var bgSecondary: ColorSemanticToken { get }
var bgTertiary: ColorSemanticToken { get }
// ...
}
// Ensure you have a provider
open class OrangeThemeColorSemanticTokensProvider { }
// Define the semantic tokens to expose through the theme thanks to the provider
extension OrangeThemeColorSemanticTokensProvider: ColorSemanticTokens {
@objc open var bgPrimary: ColorSemanticToken { ColorRawTokens.functionalWhite }
@objc open var bgSecondary: ColorSemanticToken { OrangeBrandColorRawTokens.colorOrange200 }
@objc open var bgTertiary: ColorSemanticToken { bgSecondary }
}
// An instance of OrangeThemeColorSemanticTokensProvider will be assigned to OUDSTheme as AllColorSemanticTokensProvider
Architecture
The Multiples objects are composite class defined to pack double values for dedicated needs, like size classes management (regular or compact device modes), and also for color schemes management (light and dark modes). Such composites are not the same as the ones defined in the Figma design system, they are just utilities to handle tuple of values, without the syntax of tuples and with some helper functions.
We would like to define one class for all combinations of things depending to light and dark modes, and another for regular and compact modes. However, it implies to use Swift generics and it is not compatible with Objective-C runtime (we use through @objc keyword).
There are also several typealias values used for the semantic tokens. Indeed these aliases are here to bring clarity and meanings in the library, and also to help users (i.e. developers) to know what kind of objects they handle with the same vocabulary as the one used in Figma, and in general, in the whole design system. They can be seen as a light level of abstraction with meanings, without having to define real types with struct or class. Type aliases here point to raw tokens aliases, thus by transition they point to real types.
The semantic tokens are declared through protocols. These protocols will be then implemented by the providers in higher level (i.e. theme level like OrangeTheme).
The tokens providers are Swift class used to wrap semantic tokens definitions by implementing the protocols. We do not want to store all the semantic and component tokens in the theme, and the use of providers will improve the developer experience. It will wrap all tokens by “family” and should expose them through the suitable protocols. Type aliases are also defined to merge protocols for the same tokens groups. Thus the OUDSTheme will contain wrappers exposed and use through a subset of protocols.
// Colors are declared in two protocols: the "simple" and the "multiple"
public protocol ColorSemanticToken { ... }
public protocol ColorMultipleSemanticTokens { ... }
// These protoocols are merged in type aliase
public typealias AllColorSemanticTokensProvider = ColorSemanticTokens & ColorMultipleSemanticTokens
// For example, the provider for the colors basically is:
open class OrangeThemeColorSemanticTokensProvider { ... }
// The provider is composed by protocols containing tokens
extension OrangeThemeColorSemanticTokensProvider: ColorSemanticTokens {
@objc open var opacityTransparentLight: ColorSemanticToken { ColorRawTokens.opacityBlack0 }
@objc open var opacityTransparentDark: ColorSemanticToken { ColorRawTokens.white0 }
...
}
extension OrangeThemeColorSemanticTokensProvider: ColorMultipleSemanticTokens {
@objc open var opacityTransparent: MultipleColorSemanticToken { MultipleColorSemanticToken(light: opacityTransparentLight, dark: opacityTransparentDark) }
...
}
// The "abstract" object of theme exposes the provider through this subset of protocols
open class OUDSTheme: @unchecked Sendable {
public let colors: AllColorSemanticTokensProvider
}
// And finaly, the default theme, which can be subclassed, exposes the tokens through the provider
open class OrangeTheme: OUDSTheme, @unchecked Sendable { ... }
// e.g.: theme.colors.invisibleBlack
Semantic tokens management
Some note about composites
The tokenator is not able today to generate composites tokens, i.e. tokens which contain by definition several properties.
For example, elevation semantic token dedicated to box shadows are composed by several properties (x, y, blur, shadow). Font semantic token can be token containing several properties too (weight, size, spacing, font family). These are considered as composite tokens. They are defined in dedicated protocols and files. Thus when the tokenator generates tokens without managing composites, the file can still be used as is with generated tokens, and the composites are not erased.
Particular cases with semantic tokens
Closed semantic tokens
There are some semantic tokens of colors which must not be overridable ; this is a rule defined in the design system kit. These tokens are all repository* tokens. They are only defined at once and are considered as “closed tokens”.
Also the dimension semantic tokens are closed.
Semantic tokens with forbidden values
It is possible to have some undefined color semantic tokens. Indeed some themes can use just a smaller set of colors, thus some semantic tokens of colors are not relevant. Because Figma cannot manage “optional” tokens, and because it will make heavier the management of tokens in Swift pakcage side, the forbidden value is used. This forbidden value is in tokenator side the “transparent red”, i.e. #FF000000. But in Swift package side, this value is converted to “ouds-forbidden-color-value”, and associated documentation updated.
Important
Then, even if users use these tokens, even if not specified in theme and documentation and Figma specifications, this value won’t be successfully parsed as color and program will crash.
How to use semantic tokens
In fact, the semantic tokens are declared and gathered in Swift protocol so as to force any theme to implement them, and also to allow any theme to expose such properties wathever the implementation of the theme is, across providers. Because semantic tokens have for values raw tokens, and these raw tokens have for values primitive types, and all these tokens are declared with type aliases refering all together, you can handle a semantic token directly in your view because the final value will be used. Thus, get the theme and call the needed property with some helpers.
struct SomeView: View {
@Environment(\.theme) private var theme // Supposed you used in your root view the `OUDSThemeableView` to register the theme
@Environment(\.colorScheme) private var colorScheme
var body: some View {
Rectangle()
.frame(width: theme.sizes.iconDecorative2Xl, height: theme.sizes.iconDecorativeXl)
.foregroundColor(theme.colors.bgSecondary.color(for: colorScheme))
.shadow(elevation: theme.elevations.raised.elevation(for: colorScheme))
.padding(.bottom, theme.spaces.fixedNone)
}
/*
- The theme provides size semantic tokens "iconDecorative2Xl" and "iconDecorativeXl"
- The theme provides a color semantic token "bgSecondary" with values for light and dark scheme, and you can use the color(for:) helper
- The theme provides an elevation semantic token "raised" with values for compact and regualr size classes, and you can use the elevation(for:) helper
- The theme provides a space semantic token "fixedNone" usable as is
- Environment variables like color scheme must be retrieved through View, and then given to theme
*/
}
// Do not forget in your app to use the `OUDSThemeableView` for your theme, e.g. `OrangeTheme`
@main
struct DesignToolbox: App {
var body: some Scene {
WindowGroup {
OUDSThemeableView(theme: OrangeTheme()) {
// Your root view
...
}
}
}
}
The semantic tokens are wrapped in tokens provider acessible through the themes:
| Semantic tokens provider | Description |
|---|
| borders | For borders (width, styles, radius…) |
| colors | For colors with also meta objects combining light and dark versions) |
| colorModes | Kind of frozen and not generated tokens about management of colors |
| charts | For charts, but optional and not defined in all themes |
| effects | For effects to apply to some component like navigation bars |
| elevations | For elevations to product shadow effects |
| fonts | For fonts (weights, letter spacings, sizes, line heights…) |
| grids | For grids |
| opacities | For opacities |
| sizes | For size of elements |
| spaces | For paddings and margins |
Topics
Group
protocol BorderSemanticTokensThis is a group of semantic tokens for borders. It defines all BorderWidthSemanticToken, BorderRadiusSemanticToken and BorderStyleSemanticToken a theme must have. Any border semantic token must be declared there as providers like OUDSBorderSemanticTokensProvider will then expose them through OUDSTheme.
protocol ColorSemanticTokensThis is a group of semantic tokens for colors. It defines all ColorSemanticToken a theme must have. These tokens are then gathered inside MultipleColorSemanticToken objects defined in ColorMultipleSemanticTokens. If it possible a theme won’t have such semantic tokens of colors defined as not specified nor used in Figma. Thus the value for these tokens will be “ouds-forbidden-color-value” as returned by the tokenator. Thus if the token is still used, even if explained in the documentation it should not, this special value won’t be successfully parsed as color and the app will crash like expected.
protocol ColorModeSemanticTokensThis is a group of semantic tokens for colors modes, used for example** for background colors on surface**. It defines all ColorModeSemanticToken a theme must have for surfaced colors. These tokens are then gathered inside MultipleColorModeSemanticToken defined in ColorModeMultipleSemanticTokens.
protocol ColorMultipleSemanticTokensThis is a group of semantic tokens for colors but using MultipleColorSemanticToken.
protocol ColorModeMultipleSemanticTokensThis is a group of semantic tokens for colors modes but using MultipleColorModeSemanticToken.
protocol ColorChartSemanticTokensThis is a group of semantic tokens for color charts.
protocol ColorChartMultipleSemanticTokensThis is a group of semantic tokens for colors charts. It defines all ColorSemanticToken a theme must have for charts. These tokens are then gathered inside MultipleColorSemanticToken objects defined in ColorMultipleSemanticTokens.
protocol ColorDecorativeSemanticTokensThis is a group of semantic tokens for color decorative.
protocol EffectSemanticTokensThis is a group of semantic tokens for effects. It defines all EffectSemanticToken a theme must have. Any effect semantic token must be declared there.
protocol ElevationSemanticTokensThis is a group of semantic tokens for elevations. It defines all elevation semantic tokens a theme must have (ElevationXSemanticToken, ElevationYSemanticToken, ElevationBlurSemanticToken and ElevationColorSemanticToken). However the composite tokens (here for box shadows) are defined in ElevationCompositeSemanticTokens because the tokenator is not able to generate them yet, and they must be defined elsewhere to not be deleted. Any elevation semantic token must be declared there (except ElevationCompositeSemanticTokens)
protocol ElevationMultipleSemanticTokensThis is a group of semantic tokens for elevations but multiple so as to pack light and dark variants It wraps elevation colors as tokens.
protocol ElevationCompositeSemanticTokensThis is a group of semantic tokens for elevations, but only composite tokens. There are splitted and not declared in ElevationSemanticTokens as the tokenator tool parsing Figma JSON to Swift code is not able to manage them. Thus we need to declare them in another file to prevent them to be erased. It declares in fact box shadows effects.
protocol GridSemanticTokensThis is a group of semantic tokens for grids. It defines all GridSemanticToken a theme must have. Any grid semantic token must be declared there.
protocol OpacitySemanticTokensThis is a group of semantic tokens for opacity. It defines all OpacitySemanticToken a theme must have. Any opacity semantic token must be declared there as providers like OrangeThemeOpacitySemanticTokensProvider will then expose them through OUDSTheme.
protocol SizeSemanticTokensThis is a group of semantic tokens for sizing. It defines all SizeSemanticToken a theme must have. Any size semantic token must be declared there.
protocol SizeMultipleSemanticTokensThis is a group of semantic tokens for size but using MultipleSizeSemanticToken
protocol SpaceSemanticTokensThis is a group of semantic tokens for spacing. It defines all SpaceSemanticToken a theme must have. Any space semantic token must be declared there.
protocol SpaceMultipleSemanticTokensThis is a group of semantic tokens for spacings but using MultipleSpaceSemanticToken.
protocol FontSemanticTokensThis is a group of semantic tokens for font. It defines all font semantic tokens a theme must have (FontFamilySemanticToken, FontWeightSemanticToken, FontSizeSemanticToken, FontLineHeightSemanticToken). However the composite tokens (here the ones gathering each type of semantic token here) are defined in FontCompositeSemanticTokens because the tokenator is not able to generate them yet, and they must be defined elsewhere to not be deleted. Any font semantic token must be declared there (except FontCompositeSemanticTokens).
protocol FontCompositeSemanticTokensThis is a group of semantic tokens for fonts, but only composite tokens in the end. There are splitted and not declared in FontSemanticTokens as the tokenator tool parsing Figma JSON to Swift code is not able to manage them. Thus we need to declare them in another file to prevent them to be erased.
protocol FontMultipleSemanticTokensThis is a group of semantic tokens for fonts but using MultipleFontLetterSpacingSemanticToken for letter spacings, MultipleFontLineHeightSemanticToken for line heights and MultipleFontSizeSemanticToken for font sizes.
Classes
class MultipleColorModeSemanticTokenKind of semantic tokens which will wrap a combination of ColorModeSemanticToken depending to color scheme (i.e. light mode or dark mode). Kind of composite token with multiple values, but not named “composite” because this word is already used in the design system.
class MultipleColorSemanticTokenKind of semantic tokens which will wrap a combination of ColorSemanticToken depending to color scheme (i.e. ligh mode or dark mode). Kind of composite token with multiple values, but not named “composite” because this word is already used in the design system. Allows to gather the multiple-value tokens from Figma inside one object. If a color token exists with its value depending to the color scheme, it must be packed in such ``MultipleColorSemanticToken`
class MultipleElevationCompositeRawTokenSemantic tokens which will wrap a combination of ElevationCompositeRawToken depending to color scheme (i.e. light mode or dark mode) Kind of composite token with multiple values, but not named “composite” because this word is already used in the design system. Allows to gather the multiple-value tokens from Figma inside one object. If an elevation token exists with its value depending to the color scheme, it must be packed in such ``MultipleElevationCompositeRawToken`
class MultipleFontCompositeSemanticTokenKind of semantic tokens which will wrap a combination of FontCompositeSemanticToken depending to size classes. Kind of composite token with multiple values, but not named “composite” because this word is already used in the design system. Allows to gather the multiple-value tokens from Figma inside one object. If a font token exists with its value depending to the size class, it must be packed in such MultipleFontCompositeSemanticToken.
class MultipleFontLetterSpacingSemanticTokenKind of semantic tokens which will wrap a combination of MultipleFontLetterSpacingSemanticToken depending to size classes. Allows to gather the multiple-value tokens from Figma inside one object. If a font letter spacing token exists with its value depending to the size class (i.e. comapct or regular mode), it must be packed in such MultipleFontLetterSpacingSemanticToken
class MultipleFontLineHeightSemanticTokenKind of semantic tokens which will wrap a combination of FontLineHeightSemanticToken depending to size classes. Allows to gather the multiple-value tokens from Figma inside one object. If a font line height token exists with its value depending to the size class, it must be packed in such ``MultipleFontLineHeightSemanticToken`
class MultipleFontSizeSemanticTokenKind of semantic tokens which will wrap a combination of FontSizeSemanticToken depending to size classes. Allows to gather the multiple-value tokens from Figma inside one object. If a font size exists with its value depending to the size class, it must be packed in such MultipleFontSizeSemanticToken.
class MultipleSizeSemanticTokenKind of semantic tokens which will wrap a combination of SizeSemanticToken depending to viewports / size classes. Kind of composite token with multiple values, but not named “composite” because this word is already used in the design system. Allows to gather the multiple-value tokens from Figma inside one object. If a size token exists with its value depending to the size class, it must be packed in such MultipleSizeSemanticToken.
class MultipleSpaceSemanticTokenKind of semantic tokens which will wrap a combination of DimensionRawToken depending to size classes. Kind of composite token with multiple values, but not named “composite” because this word is already used in the design system. Allows to gather the multiple-value tokens from Figma inside one object. If a space token exists with its value depending to the size class, it must be packed in such MultipleSpaceSemanticToken.
Protocols
Structures
Type Aliases
typealias BorderRadiusSemanticTokenType alias precising BorderRadiusRawToken is used as a value of this border raw semantic token, to keep grammar clean and clear with design system grammar.
typealias BorderStyleSemanticTokenType alias precising BorderStyleRawToken is used as a value of this border style semantic token, to keep grammar clean and clear with design system grammar.
typealias BorderWidthSemanticTokenType alias precising BorderWidthRawToken is used as a value of this border width semantic token, to keep grammar clean and clear with design system grammar.
typealias ColorModeSemanticTokenBasically a color mode semantic token is a ColorModeRawToken
typealias ColorSemanticTokenBasically a color semantic token is a ColorRawToken, to keep grammar clean and clear with design system grammar.
typealias DimensionSemanticTokenBasically a semantic token for dimensions is a raw token for dimensions, to keep grammar clean and clear with design system grammar.
typealias EffectSemanticTokenBasically a semantic token for effect is a raw token for effect, to keep grammar clean and clear with design system grammar.
typealias ElevationBlurSemanticTokenBasically an elevation semantic token for blur effect is a raw token for elevation, with the same final type, to keep grammar clean and clear with design system grammar.
typealias ElevationColorSemanticTokenBasically an elevation color semantic token, used mainly for shadow colors, is a color semantic token.
typealias ElevationCompositeSemanticTokenBasically an elevationcomposite semantic token, used mainly for box shadow, is a pair of elevation composite raw tokens used depending to the color scheme. A MultipleElevationCompositeRawToken contains ElevationCompositeRawToken objects for light and dark modes, which contains ElevationRawToken and ColorRawToken values.
typealias ElevationMultipleColorSemanticTokenBasically a multiple elevation color semantic token, used mainly for shadow colors, is a multiple color semantic token.
typealias ElevationXSemanticTokenBasically an elevation semantic token for X offset is a raw token for elevation, with the same final type, to keep grammar clean and clear with design system grammar.
typealias ElevationYSemanticTokenBasically an elevation semantic token for Y Index is a raw token for elevation, with the same final type, to keep grammar clean and clear with design system grammar.
typealias FontFamilySemanticTokenThe global design system tools uses verbs of semantic token for font family, which is basically a raw token for font family
typealias FontLetterSpacingSemanticTokenThe global design system tools uses verbs of semantic token for font letter spacing, which is basically a raw token for font letter spacing
typealias FontLineHeightSemanticTokenThe global design system tools uses verbs of semantic token for font line height, which is basically a raw token for font line height
typealias FontSizeSemanticTokenThe global design system tools uses verbs of semantic token for font size, which is basically a raw token for font size
typealias FontWeightSemanticTokenThe global design system tools uses verbs of semantic token for font weight, which is basically a raw token for font weight
typealias GridSemanticTokenBasically a grid semantic token, for iOS Extra Compact, Compact or Regular values, is a GridRawToken. This word is used to keep grammar clean and clear with design system grammar.
typealias OpacitySemanticTokenBasically an opacity semantic token is an opacity raw token, to keep grammar clean and clear with design system grammar.
typealias SizeSemanticTokenBasically a size semantic token, used for width and height values, is a _ raw token, it has the same final type, to keep grammar clean and clear with design system grammar.
typealias SpaceSemanticTokenBasically a space semantic token is a _ raw token, it has the same final type, to keep grammar clean and clear with design system grammar.
Extended Modules