Skip to content

Yinnotayl/SpaceUI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SpaceUI

A custom space / sci-fi UI component library for SwiftUI apps.

Requirements

  • iOS 17+ / macOS 14+ / tvOS 17+ / watchOS 10+
  • Swift 5.9+

Installation

.package(url: "https://github.com/Yinnotayl/SpaceUI", branch: "main")

Add "SpaceUI" as a dependency to your target.

Setup

Register SpaceUI fonts once at app launch:

import SpaceUI

@main
struct MyApp: App {
    init() {
        SpaceFont.register()
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

Styles

SpaceUI components can inherit a shared style:

VStack {
    SpaceCard {
        SpaceText("Mission Control")
    }

    SpaceButton("Deploy") {
        deploy()
    }
    .spaceUIStyle(.primary(role: .confirm))
}
.spaceUIStyle(.primary)

Use scoped modifiers when one component should differ without restyling nested SpaceUI elements:

SpaceCard {
    SpaceButton("Join") {
        join()
    }
}
.spaceCardStyle(.glass(role: .confirm, highlighted: true))

Available styles:

.primary
.glass
.primary(role: .normal, highlighted: false)
.glass(role: .confirm, highlighted: true)

Scoped modifiers:

.spaceCardStyle(.glass)
.spaceListRowStyle(.glass)
.spacePanelStyle(.glass)
.spaceButtonStyle(.primary(role: .confirm))
.spaceTextFieldStyle(.glass)
.spaceChipStyle(.glass(role: .confirm))
.spaceIconButtonStyle(.glass(role: .destructive))

You can tune the shared style variables with SpaceUIStyleTokens:

ContentView()
    .spaceStyleTokens(
        SpaceUIStyleTokens(
            normalColor: .cyan,
            confirmColor: .mint,
            destructiveColor: .red
        )
    )

Typography

SpaceUI ships Orbitron and Space Grotesk variants. Display/title/action text defaults to Orbitron; subtitle/body/caption text defaults to Space Grotesk. Space Grotesk styles do not add letter tracking by default.

Semantic text styles:

SpaceLargeDisplay("HYPER THRUST")
SpaceDisplay("HOST")
SpaceDisplay2("Raider MKII")
SpaceTitle("Mission Control")
SpaceTitle2("Subsystems")
SpaceSubtitle("Prepare for high speed chaos")
SpaceText("Hull integrity nominal")
SpaceCaption("SERVERS")

Modifier forms are available too:

Text("JOIN").spaceDisplay()
Text("Tap anywhere").spaceSubtitle(.orbitronMedium, color: .white)
Text("42").spaceTextStyle(26, font: .orbitronMedium)

Compatibility aliases remain available:

.orbitron_medium
.din_alternate // deprecated alias to Space Grotesk Regular

Components

Backgrounds

ContentView()
    .spaceBackground()

ContentView()
    .spaceAnimatedBackground()

SpaceBackground is the existing static game background. SpaceAnimatedBackground layers scrolling stars and fog over it.

Buttons And Cards

SpaceCard(title: "Warp Drive", subtitle: "Nominal")
    .spaceUIStyle(.primary(role: .confirm))

SpaceButton("Launch") {
    launch()
}
.spaceUIStyle(.primary(role: .confirm, highlighted: true))

SpaceButtonTwoStep("Delete") {
    delete()
}
.spaceUIStyle(.primary(role: .destructive))

SpaceIconButton("xmark", accessibilityLabel: "Close") {
    close()
}
.spaceIconButtonStyle(.glass(role: .destructive))

Chips

SpaceChip("AI", isOn: $aiEnabled, icon: "sparkles")
    .spaceUIStyle(.glass(role: .confirm))

SpaceChip(
    isOn: $serverPublic,
    onText: "PUBLIC",
    offText: "PRIVATE",
    onIcon: "antenna.radiowaves.left.and.right",
    offIcon: "lock"
)
.spaceChipStyle(.glass(role: .normal))

SpaceChip maps isOn to the style highlight state, so active chips get the highlighted outline/glow for the inherited or scoped role.

Forms And Lists

SpaceTextField("Callsign", text: $callsign, placeholder: "Enter callsign")

SpaceSection("Servers") {
    SpaceListRow(title: "Yijue's iPad", status: "JOIN") {
        join()
    }
    .spaceUIStyle(.glass(role: .confirm))
}

SpaceListRow supports selected and disabled states for multiplayer-selector style rows:

SpaceListRow(
    title: "Server",
    status: "CONNECTING",
    selected: true,
    disabled: true
)
.spaceListRowStyle(.glass)

Split View

@State private var focusedSide: SpaceSplitSide = .right

SpaceSplitView(focusedSide: $focusedSide, dimming: true) {
    hostControls
} rightContent: {
    joinControls
}

When dimming is true, tapping the unfocused side updates focusedSide. When dimming is false, only the developer-controlled binding changes focus.

Pulse Text

SpacePulseText("Tap anywhere to begin")

Roles

SpaceUIRole controls role colors for borders, glows, and status accents:

.normal
.confirm
.destructive

Testing

CLANG_MODULE_CACHE_PATH=/private/tmp/spaceui_module_cache swift test --disable-sandbox

License

SpaceUI is available under the AGPL-3.0 license. See LICENSE for details.

About

A custom space/sci-fi UI style for SwiftUI apps

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages