Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
113660a7f9
commit
92e6de53c5
@ -6,11 +6,45 @@ This guide documents the typography and text styling system in Bedrock.
|
|||||||
|
|
||||||
The typography system consists of:
|
The typography system consists of:
|
||||||
|
|
||||||
1. **`Typography` enum** - All font definitions with explicit naming
|
1. **`Theme`** - Global theme registration for all color providers
|
||||||
2. **`TextEmphasis` enum** - Semantic text colors
|
2. **`Typography` enum** - All font definitions with explicit naming
|
||||||
3. **`StyledLabel`** - Simple text component combining typography + emphasis
|
3. **`TextEmphasis` enum** - Semantic text colors
|
||||||
4. **`IconLabel`** - Icon + text component
|
4. **`StyledLabel`** - Simple text component combining typography + emphasis
|
||||||
5. **`.typography()` modifier** - View extension for applying fonts
|
5. **`IconLabel`** - Icon + text component
|
||||||
|
6. **`.typography()` modifier** - View extension for applying fonts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## App Setup
|
||||||
|
|
||||||
|
Register your app's theme once at launch:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// In App.init()
|
||||||
|
Theme.register(
|
||||||
|
text: AppTextColors.self,
|
||||||
|
surface: AppSurface.self,
|
||||||
|
accent: AppAccent.self,
|
||||||
|
status: AppStatus.self
|
||||||
|
)
|
||||||
|
Theme.register(border: AppBorder.self) // Optional
|
||||||
|
```
|
||||||
|
|
||||||
|
This enables Bedrock components to use your app's colors automatically.
|
||||||
|
|
||||||
|
### Using Theme Colors
|
||||||
|
|
||||||
|
After registration, use `Theme.*` to access your registered colors:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
// In Bedrock components (automatic via TextEmphasis)
|
||||||
|
StyledLabel("Title", .heading) // Uses Theme.Text.primary
|
||||||
|
|
||||||
|
// Direct access when needed
|
||||||
|
let bgColor = Theme.Surface.card
|
||||||
|
let accentColor = Theme.Accent.primary
|
||||||
|
let successColor = Theme.Status.success
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -50,65 +84,73 @@ All fonts are defined in the `Typography` enum. Each case name explicitly descri
|
|||||||
| | `.caption2` | caption2 |
|
| | `.caption2` | caption2 |
|
||||||
| | `.caption2Emphasis` | caption2.weight(.semibold) |
|
| | `.caption2Emphasis` | caption2.weight(.semibold) |
|
||||||
|
|
||||||
### Usage
|
|
||||||
|
|
||||||
```swift
|
|
||||||
// Using the .typography() modifier (preferred)
|
|
||||||
Text("Hello")
|
|
||||||
.typography(.heading)
|
|
||||||
|
|
||||||
// Using .font() directly
|
|
||||||
Text("Hello")
|
|
||||||
.font(Typography.heading.font)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## TextEmphasis Enum
|
## TextEmphasis Enum
|
||||||
|
|
||||||
Semantic text colors that work with any theme:
|
Semantic text colors resolved from the registered `TextTheme`:
|
||||||
|
|
||||||
| Emphasis | Description |
|
| Emphasis | Description |
|
||||||
|----------|-------------|
|
|----------|-------------|
|
||||||
| `.primary` | Main text color |
|
| `.primary` | Main text color (default) |
|
||||||
| `.secondary` | Supporting text |
|
| `.secondary` | Supporting text |
|
||||||
| `.tertiary` | Subtle/hint text |
|
| `.tertiary` | Subtle/hint text |
|
||||||
| `.disabled` | Disabled state |
|
| `.disabled` | Disabled state |
|
||||||
| `.inverse` | Contrasting backgrounds |
|
| `.inverse` | Contrasting backgrounds |
|
||||||
| `.custom(Color)` | Custom color override |
|
| `.custom(Color)` | Custom color override |
|
||||||
|
|
||||||
### Usage
|
### When to Use `.custom()`
|
||||||
|
|
||||||
|
Only use `.custom()` for colors that aren't text colors:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
// With StyledLabel
|
// ✅ Semantic text colors - use the emphasis value directly
|
||||||
StyledLabel("Title", .heading, emphasis: .primary)
|
StyledLabel("Title", .heading) // .primary is default
|
||||||
StyledLabel("Subtitle", .subheading, emphasis: .secondary)
|
StyledLabel("Subtitle", .subheading, emphasis: .secondary)
|
||||||
StyledLabel("Custom", .body, emphasis: .custom(.red))
|
StyledLabel("Hint", .caption, emphasis: .tertiary)
|
||||||
|
|
||||||
// With custom theme colors
|
// ✅ Use .custom() for non-text colors
|
||||||
StyledLabel("Title", .heading, emphasis: .custom(AppTextColors.primary))
|
StyledLabel("Success!", .heading, emphasis: .custom(AppStatus.success))
|
||||||
|
StyledLabel("Arc 3", .caption, emphasis: .custom(AppAccent.primary))
|
||||||
|
|
||||||
|
// ✅ Use .custom() for conditional colors
|
||||||
|
StyledLabel(text, .body, emphasis: .custom(isActive ? AppStatus.success : AppTextColors.tertiary))
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## StyledLabel Component
|
## StyledLabel Component
|
||||||
|
|
||||||
A single component for all styled text. Replaces the old `TitleLabel`, `BodyLabel`, `CaptionLabel`.
|
A single component for all styled text:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
StyledLabel(_ text: String, _ typography: Typography = .body, emphasis: TextEmphasis = .primary)
|
StyledLabel(
|
||||||
|
_ text: String,
|
||||||
|
_ typography: Typography = .body,
|
||||||
|
emphasis: TextEmphasis = .primary,
|
||||||
|
alignment: TextAlignment? = nil,
|
||||||
|
lineLimit: Int? = nil
|
||||||
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
// Simple usage
|
// Simple - uses registered theme's primary color
|
||||||
StyledLabel("Morning Ritual", .heading)
|
StyledLabel("Morning Ritual", .heading)
|
||||||
StyledLabel("Day 6 of 28", .caption, emphasis: .secondary)
|
StyledLabel("Day 6 of 28", .caption, emphasis: .secondary)
|
||||||
|
|
||||||
// With custom theme colors
|
// With alignment and line limit
|
||||||
StyledLabel("Title", .heading, emphasis: .custom(AppTextColors.primary))
|
StyledLabel("Centered text", .body, alignment: .center)
|
||||||
StyledLabel("Subtitle", .subheading, emphasis: .custom(AppTextColors.secondary))
|
StyledLabel("One line", .caption, emphasis: .tertiary, lineLimit: 1)
|
||||||
|
|
||||||
|
// In buttons
|
||||||
|
Button(action: onContinue) {
|
||||||
|
StyledLabel("Continue", .heading, emphasis: .inverse)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.frame(height: 50)
|
||||||
|
.background(AppAccent.primary)
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -126,6 +168,7 @@ IconLabel(_ icon: String, _ text: String, _ typography: Typography = .body, emph
|
|||||||
```swift
|
```swift
|
||||||
IconLabel("bell.fill", "Notifications", .subheading)
|
IconLabel("bell.fill", "Notifications", .subheading)
|
||||||
IconLabel("star.fill", "Favorites", .body, emphasis: .secondary)
|
IconLabel("star.fill", "Favorites", .body, emphasis: .secondary)
|
||||||
|
IconLabel("flame.fill", "5-day streak", .caption, emphasis: .custom(AppStatus.success))
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@ -134,34 +177,20 @@ IconLabel("star.fill", "Favorites", .body, emphasis: .secondary)
|
|||||||
|
|
||||||
### Use StyledLabel (Preferred)
|
### Use StyledLabel (Preferred)
|
||||||
|
|
||||||
Use `StyledLabel` for the vast majority of text:
|
Use `StyledLabel` for 95% of text:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
// Simple text
|
|
||||||
StyledLabel("Settings", .subheadingEmphasis)
|
StyledLabel("Settings", .subheadingEmphasis)
|
||||||
StyledLabel("Description", .subheading, emphasis: .secondary)
|
StyledLabel("Description", .subheading, emphasis: .secondary)
|
||||||
|
StyledLabel("Centered", .body, alignment: .center)
|
||||||
// With multiline alignment
|
|
||||||
StyledLabel("Centered text", .body, emphasis: .primary, alignment: .center)
|
|
||||||
|
|
||||||
// With line limit
|
|
||||||
StyledLabel("One line only", .caption, emphasis: .secondary, lineLimit: 1)
|
|
||||||
|
|
||||||
// In buttons (put frame modifiers outside)
|
|
||||||
Button(action: onContinue) {
|
|
||||||
StyledLabel("Continue", .heading, emphasis: .custom(AppTextColors.inverse))
|
|
||||||
.frame(maxWidth: .infinity)
|
|
||||||
.frame(height: 50)
|
|
||||||
.background(AppAccent.primary)
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Use Text() with .typography() (Rare Exceptions)
|
### Use Text() with .typography() (Rare Exceptions)
|
||||||
|
|
||||||
Only use `Text()` when you genuinely need modifiers that `StyledLabel` doesn't support:
|
Only when you need modifiers `StyledLabel` doesn't support:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
// Font design variants (rounded, etc.)
|
// Font design variants
|
||||||
Text(formattedValue)
|
Text(formattedValue)
|
||||||
.typography(.subheadingEmphasis)
|
.typography(.subheadingEmphasis)
|
||||||
.fontDesign(.rounded)
|
.fontDesign(.rounded)
|
||||||
@ -173,24 +202,18 @@ TextField("Placeholder", text: $value)
|
|||||||
// Inside special view builders (like Charts AxisValueLabel)
|
// Inside special view builders (like Charts AxisValueLabel)
|
||||||
AxisValueLabel {
|
AxisValueLabel {
|
||||||
Text("\(value)%")
|
Text("\(value)%")
|
||||||
.font(Typography.caption2.font) // .typography() won't work here
|
.font(Typography.caption2.font)
|
||||||
.foregroundStyle(color)
|
.foregroundStyle(color)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Never Use Raw `.font()` with System Fonts
|
### Never Use Raw `.font()` with System Fonts
|
||||||
|
|
||||||
Instead of:
|
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
// BAD
|
// ❌ BAD
|
||||||
Text("Title").font(.headline)
|
Text("Title").font(.headline)
|
||||||
```
|
|
||||||
|
|
||||||
Use:
|
// ✅ GOOD
|
||||||
|
|
||||||
```swift
|
|
||||||
// GOOD
|
|
||||||
StyledLabel("Title", .heading)
|
StyledLabel("Title", .heading)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -203,23 +226,17 @@ StyledLabel("Title", .heading)
|
|||||||
```swift
|
```swift
|
||||||
// OLD: Design.Typography
|
// OLD: Design.Typography
|
||||||
Text("Title").font(Design.Typography.headline)
|
Text("Title").font(Design.Typography.headline)
|
||||||
Text("Body").font(Design.Typography.body)
|
|
||||||
Text("Caption").font(Design.Typography.caption)
|
|
||||||
|
|
||||||
// NEW: Typography enum
|
// NEW: StyledLabel
|
||||||
Text("Title").typography(.heading)
|
StyledLabel("Title", .heading)
|
||||||
Text("Body").typography(.subheading)
|
|
||||||
Text("Caption").typography(.caption)
|
|
||||||
|
|
||||||
// OLD: Multiple Label components
|
// OLD: Multiple Label components
|
||||||
TitleLabel("Title", style: .headline, color: .white)
|
TitleLabel("Title", style: .headline, color: .white)
|
||||||
BodyLabel("Body", emphasis: .secondary)
|
BodyLabel("Body", emphasis: .secondary)
|
||||||
CaptionLabel("Caption")
|
|
||||||
|
|
||||||
// NEW: Single StyledLabel
|
// NEW: Single StyledLabel
|
||||||
StyledLabel("Title", .heading, emphasis: .custom(.white))
|
StyledLabel("Title", .heading, emphasis: .inverse)
|
||||||
StyledLabel("Body", .subheading, emphasis: .secondary)
|
StyledLabel("Body", .subheading, emphasis: .secondary)
|
||||||
StyledLabel("Caption", .caption, emphasis: .secondary)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Mapping Table
|
### Mapping Table
|
||||||
@ -237,8 +254,6 @@ StyledLabel("Caption", .caption, emphasis: .secondary)
|
|||||||
| `.caption` | `.caption` |
|
| `.caption` | `.caption` |
|
||||||
| `.captionMedium` | `.captionEmphasis` |
|
| `.captionMedium` | `.captionEmphasis` |
|
||||||
| `.captionSmall` | `.caption2` |
|
| `.captionSmall` | `.caption2` |
|
||||||
| `.settingsTitle` | `.subheadingEmphasis` |
|
|
||||||
| `.sectionHeader` | `.captionEmphasis` |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -2,25 +2,36 @@
|
|||||||
// TextEmphasis.swift
|
// TextEmphasis.swift
|
||||||
// Bedrock
|
// Bedrock
|
||||||
//
|
//
|
||||||
// Semantic text color emphasis levels that work with any TextColorProvider theme.
|
// Semantic text color emphasis levels.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
// MARK: - Text Emphasis
|
||||||
|
|
||||||
/// Semantic text color emphasis levels.
|
/// Semantic text color emphasis levels.
|
||||||
///
|
///
|
||||||
/// Use `TextEmphasis` to specify text color semantically rather than with explicit colors.
|
/// Use `TextEmphasis` to specify text color semantically. Colors are resolved
|
||||||
/// The actual color is resolved from the app's registered `TextColorProvider`.
|
/// from the globally registered `Theme`.
|
||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
///
|
///
|
||||||
/// ```swift
|
/// ```swift
|
||||||
/// StyledLabel("Primary text", .body, emphasis: .primary)
|
/// // Register your theme once at app launch
|
||||||
|
/// Theme.register(
|
||||||
|
/// text: AppTextColors.self,
|
||||||
|
/// surface: AppSurface.self,
|
||||||
|
/// accent: AppAccent.self,
|
||||||
|
/// status: AppStatus.self
|
||||||
|
/// )
|
||||||
|
///
|
||||||
|
/// // Then use emphasis levels directly
|
||||||
|
/// StyledLabel("Primary text", .body) // uses .primary
|
||||||
/// StyledLabel("Secondary text", .caption, emphasis: .secondary)
|
/// StyledLabel("Secondary text", .caption, emphasis: .secondary)
|
||||||
/// StyledLabel("Custom color", .heading, emphasis: .custom(.red))
|
/// StyledLabel("Custom color", .heading, emphasis: .custom(.red))
|
||||||
/// ```
|
/// ```
|
||||||
public enum TextEmphasis: Sendable {
|
public enum TextEmphasis: Sendable {
|
||||||
/// Primary text color (highest emphasis).
|
/// Primary text color (highest emphasis). Default.
|
||||||
case primary
|
case primary
|
||||||
/// Secondary text color (medium emphasis).
|
/// Secondary text color (medium emphasis).
|
||||||
case secondary
|
case secondary
|
||||||
@ -30,31 +41,24 @@ public enum TextEmphasis: Sendable {
|
|||||||
case disabled
|
case disabled
|
||||||
/// Inverse text color (for contrasting backgrounds).
|
/// Inverse text color (for contrasting backgrounds).
|
||||||
case inverse
|
case inverse
|
||||||
/// Custom color override.
|
/// Custom color override for one-off cases.
|
||||||
case custom(Color)
|
case custom(Color)
|
||||||
|
|
||||||
/// Resolves the color from a specific TextColorProvider.
|
/// Resolves the color from the globally registered Theme.
|
||||||
///
|
public var color: Color {
|
||||||
/// Use this when you need to explicitly specify which theme to use:
|
|
||||||
/// ```swift
|
|
||||||
/// emphasis.color(from: MyAppTextColors.self)
|
|
||||||
/// ```
|
|
||||||
public func color<T: TextColorProvider>(from provider: T.Type) -> Color {
|
|
||||||
switch self {
|
switch self {
|
||||||
case .primary: provider.primary
|
case .primary: Theme.Text.primary
|
||||||
case .secondary: provider.secondary
|
case .secondary: Theme.Text.secondary
|
||||||
case .tertiary: provider.tertiary
|
case .tertiary: Theme.Text.tertiary
|
||||||
case .disabled: provider.disabled
|
case .disabled: Theme.Text.disabled
|
||||||
case .inverse: provider.inverse
|
case .inverse: Theme.Text.inverse
|
||||||
case .custom(let color): color
|
case .custom(let color): color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolves the color from the default TextColorProvider.
|
|
||||||
///
|
|
||||||
/// This uses `Color.TextColors` (the default Bedrock text colors).
|
|
||||||
/// Apps with custom themes should use `color(from:)` instead.
|
|
||||||
public var color: Color {
|
|
||||||
color(from: DefaultTextColors.self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Deprecated TextTheme
|
||||||
|
|
||||||
|
/// Deprecated: Use `Theme` instead.
|
||||||
|
@available(*, deprecated, renamed: "Theme", message: "Use Theme.register() instead")
|
||||||
|
public typealias TextTheme = Theme
|
||||||
|
|||||||
124
Sources/Bedrock/Theme/Theme.swift
Normal file
124
Sources/Bedrock/Theme/Theme.swift
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
//
|
||||||
|
// Theme.swift
|
||||||
|
// Bedrock
|
||||||
|
//
|
||||||
|
// Global theme registration for Bedrock components.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
// MARK: - Global Theme Registration
|
||||||
|
|
||||||
|
/// Global theme provider for Bedrock components.
|
||||||
|
///
|
||||||
|
/// Register your app's theme once at launch to enable semantic colors
|
||||||
|
/// in `StyledLabel`, `IconLabel`, and other Bedrock components.
|
||||||
|
///
|
||||||
|
/// ## Usage
|
||||||
|
///
|
||||||
|
/// ```swift
|
||||||
|
/// // In App.init()
|
||||||
|
/// Theme.register(
|
||||||
|
/// text: AppTextColors.self,
|
||||||
|
/// surface: AppSurface.self,
|
||||||
|
/// accent: AppAccent.self,
|
||||||
|
/// status: AppStatus.self
|
||||||
|
/// )
|
||||||
|
///
|
||||||
|
/// // Then use semantic emphasis directly
|
||||||
|
/// StyledLabel("Title", .heading) // uses Theme.Text.primary
|
||||||
|
/// StyledLabel("Subtitle", .subheading, emphasis: .secondary) // uses Theme.Text.secondary
|
||||||
|
/// ```
|
||||||
|
public enum Theme {
|
||||||
|
// MARK: - Registered Providers
|
||||||
|
|
||||||
|
// Set once at app launch, read-only thereafter
|
||||||
|
nonisolated(unsafe) private static var _text: any TextColorProvider.Type = DefaultTextColors.self
|
||||||
|
nonisolated(unsafe) private static var _surface: any SurfaceColorProvider.Type = DefaultSurfaceColors.self
|
||||||
|
nonisolated(unsafe) private static var _accent: any AccentColorProvider.Type = DefaultAccentColors.self
|
||||||
|
nonisolated(unsafe) private static var _status: any StatusColorProvider.Type = DefaultStatusColors.self
|
||||||
|
nonisolated(unsafe) private static var _border: any BorderColorProvider.Type = DefaultBorderColors.self
|
||||||
|
|
||||||
|
// MARK: - Registration
|
||||||
|
|
||||||
|
/// Registers custom color providers for the app.
|
||||||
|
///
|
||||||
|
/// Call this once at app launch:
|
||||||
|
/// ```swift
|
||||||
|
/// Theme.register(
|
||||||
|
/// text: AppTextColors.self,
|
||||||
|
/// surface: AppSurface.self,
|
||||||
|
/// accent: AppAccent.self,
|
||||||
|
/// status: AppStatus.self
|
||||||
|
/// )
|
||||||
|
/// ```
|
||||||
|
public static func register<T: TextColorProvider, S: SurfaceColorProvider, A: AccentColorProvider, St: StatusColorProvider>(
|
||||||
|
text: T.Type,
|
||||||
|
surface: S.Type,
|
||||||
|
accent: A.Type,
|
||||||
|
status: St.Type
|
||||||
|
) {
|
||||||
|
_text = text
|
||||||
|
_surface = surface
|
||||||
|
_accent = accent
|
||||||
|
_status = status
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Registers a border color provider (optional).
|
||||||
|
public static func register<B: BorderColorProvider>(border: B.Type) {
|
||||||
|
_border = border
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Text Colors
|
||||||
|
|
||||||
|
/// Registered text color provider.
|
||||||
|
public enum Text {
|
||||||
|
public static var primary: Color { _text.primary }
|
||||||
|
public static var secondary: Color { _text.secondary }
|
||||||
|
public static var tertiary: Color { _text.tertiary }
|
||||||
|
public static var disabled: Color { _text.disabled }
|
||||||
|
public static var inverse: Color { _text.inverse }
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Surface Colors
|
||||||
|
|
||||||
|
/// Registered surface color provider.
|
||||||
|
public enum Surface {
|
||||||
|
public static var primary: Color { _surface.primary }
|
||||||
|
public static var secondary: Color { _surface.secondary }
|
||||||
|
public static var tertiary: Color { _surface.tertiary }
|
||||||
|
public static var card: Color { _surface.card }
|
||||||
|
public static var overlay: Color { _surface.overlay }
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Accent Colors
|
||||||
|
|
||||||
|
/// Registered accent color provider.
|
||||||
|
public enum Accent {
|
||||||
|
public static var primary: Color { _accent.primary }
|
||||||
|
public static var light: Color { _accent.light }
|
||||||
|
public static var dark: Color { _accent.dark }
|
||||||
|
public static var secondary: Color { _accent.secondary }
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Status Colors
|
||||||
|
|
||||||
|
/// Registered status color provider.
|
||||||
|
public enum Status {
|
||||||
|
public static var success: Color { _status.success }
|
||||||
|
public static var warning: Color { _status.warning }
|
||||||
|
public static var error: Color { _status.error }
|
||||||
|
public static var info: Color { _status.info }
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Border Colors
|
||||||
|
|
||||||
|
/// Registered border color provider.
|
||||||
|
public enum Border {
|
||||||
|
public static var subtle: Color { _border.subtle }
|
||||||
|
public static var standard: Color { _border.standard }
|
||||||
|
public static var emphasized: Color { _border.emphasized }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Default providers are defined in Colors.swift
|
||||||
Loading…
Reference in New Issue
Block a user