Bedrock/README.md
Matt Bruce fa7d848f52 Initial commit: Bedrock design system and UI component library
- Design system: spacing, typography, colors, animations, opacity, shadows
- Protocol-based color theming (AppColorTheme)
- Settings UI components: toggles, pickers, selection indicators
- Sound and haptic feedback manager (generic AppSound protocol)
- Onboarding state management
- Cloud sync manager (PersistableData protocol)
- Visual effects: ConfettiView, PulsingModifier
- Debug utilities: DebugBorderModifier
- Device information utilities (cross-platform)
- Unit tests for design constants
2026-01-02 11:58:30 -06:00

5.5 KiB

Bedrock

A foundational design system and UI component library for building consistent, beautiful SwiftUI applications.

Overview

Bedrock is designed to be the foundation upon which apps are built, providing:

  • Design System: Consistent spacing, typography, and animations
  • Color Protocols: Define consistent color naming with custom palettes per app
  • Settings Components: Ready-to-use toggle, picker, and selector views
  • Utilities: Common helpers for device detection, debugging, and more

Installation

Add Bedrock as a dependency in your Package.swift:

dependencies: [
    .package(path: "../Bedrock")
]

Then add it to your target:

.target(
    name: "YourApp",
    dependencies: ["Bedrock"]
)

Usage

Design Constants

Use the Design enum for consistent spacing, sizing, and styling:

import Bedrock

struct MyView: View {
    var body: some View {
        VStack(spacing: Design.Spacing.medium) {
            Text("Hello")
                .font(.system(size: Design.BaseFontSize.title))
                .padding(Design.Spacing.large)
            
            Button("Tap Me") { }
                .clipShape(.rect(cornerRadius: Design.CornerRadius.medium))
        }
    }
}

Color System

Bedrock provides a protocol-based color system that enforces consistent naming while allowing apps to define their own palettes.

Using Default Colors

Bedrock includes neutral default colors that work out of the box:

Text("Primary Text")
    .foregroundStyle(Color.Text.primary)

Text("Secondary Text")
    .foregroundStyle(Color.Text.secondary)

VStack { }
    .background(Color.Surface.primary)

Creating Custom Color Themes

Apps can define custom color palettes by conforming to the color protocols:

// In CasinoKit - define casino-themed accent colors
public enum CasinoAccentColors: AccentColorProvider {
    public static let primary = Color(red: 0.9, green: 0.75, blue: 0.3)   // Gold
    public static let light = Color(red: 1.0, green: 0.85, blue: 0.4)
    public static let dark = Color(red: 0.7, green: 0.55, blue: 0.2)
    public static let secondary = Color(red: 0.2, green: 0.7, blue: 0.7) // Teal
}

// Create a complete theme
public enum CasinoTheme: AppColorTheme {
    public typealias Surface = CasinoSurfaceColors
    public typealias Text = DefaultTextColors        // Reuse Bedrock defaults
    public typealias Accent = CasinoAccentColors     // Custom gold accents
    public typealias Button = CasinoButtonColors
    public typealias Status = DefaultStatusColors    // Reuse Bedrock defaults
    public typealias Border = DefaultBorderColors
    public typealias Interactive = DefaultInteractiveColors
}

// Use in views
Button("Deal") { }
    .background(CasinoTheme.Accent.primary)

Available Color Protocols

Protocol Properties
SurfaceColorProvider primary, secondary, tertiary, overlay, card, groupedFill, sectionFill
TextColorProvider primary, secondary, tertiary, disabled, placeholder, inverse
AccentColorProvider primary, light, dark, secondary
ButtonColorProvider primaryLight, primaryDark, secondary, destructive, cancelText
StatusColorProvider success, warning, error, info
BorderColorProvider subtle, standard, emphasized, selected
InteractiveColorProvider selected, hover, pressed, focus

Settings Components

Ready-to-use settings UI components:

// Toggle with title and subtitle
SettingsToggle(
    title: "Notifications",
    subtitle: "Receive push notifications",
    isOn: $notificationsEnabled
)

// Volume slider
VolumePicker(label: "Volume", volume: $soundVolume)

// Segmented picker
SegmentedPicker(
    title: "Theme",
    options: [("Light", "light"), ("Dark", "dark"), ("Auto", "auto")],
    selection: $theme
)

// Selectable row
SelectableRow(
    title: "Premium Plan",
    subtitle: "Unlock all features",
    isSelected: plan == .premium,
    badge: { BadgePill(text: "$9.99", isSelected: plan == .premium) },
    action: { plan = .premium }
)

Device Detection

Adapt your UI based on device characteristics:

if DeviceInfo.isPad {
    SidebarView()
} else {
    TabBarView()
}

Design System Reference

Spacing

Name Value Usage
xxxSmall 1pt Hairline spacing
xxSmall 2pt Minimal spacing
xSmall 4pt Tight spacing
small 8pt Compact spacing
medium 12pt Default spacing
large 16pt Comfortable spacing
xLarge 20pt Generous spacing
xxLarge 24pt Section spacing
xxxLarge 32pt Large section spacing

Opacity

Name Value Usage
verySubtle 0.05 Barely visible
subtle 0.1 Subtle backgrounds
hint 0.2 Hints and disabled states
light 0.3 Light overlays
medium 0.5 Medium emphasis
strong 0.7 Strong emphasis
heavy 0.8 Heavy overlays
almostFull 0.9 Nearly opaque

Default Colors

Default colors use a neutral blue accent. Apps should define custom themes for branding:

Category Purpose
Color.Surface.* Background colors
Color.Text.* Text colors
Color.Accent.* Accent/highlight colors (default: blue)
Color.Button.* Button colors
Color.Status.* Success/warning/error colors
Color.Border.* Border and divider colors
Color.Interactive.* Interactive state colors

Requirements

  • iOS 18.0+
  • macOS 15.0+
  • Swift 6.0+