Merge pull request #4 from phranck/feature/docc-documentation

Feature/docc documentation
This commit is contained in:
phranck
2026-01-30 07:47:12 +01:00
92 changed files with 595 additions and 3811 deletions
+24 -33
View File
@@ -1,57 +1,48 @@
name: Build and Deploy DocC Documentation
name: Build and Deploy DocC
on:
push:
branches:
- main
workflow_dispatch:
branches: [main]
permissions:
contents: write
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
build-and-deploy-docs:
runs-on: macos-latest
build:
runs-on: macos-15
steps:
- name: Checkout code
- name: Checkout
uses: actions/checkout@v4
- name: Check Swift version
run: swift --version
- name: Build documentation
- name: Build DocC documentation
run: |
xcrun docc convert TUIKit.docc \
--output-path ./docs
swift package --allow-writing-to-directory docs-output \
generate-documentation \
--target TUIKit \
--output-path docs-output \
--transform-for-static-hosting
- name: Commit and push documentation
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add docs/
git commit -m "docs: Generate DocC documentation" || echo "No changes to commit"
git push
- name: Add CNAME for custom domain
run: echo "tuikit.layered.work" > docs-output/CNAME
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: docs-output
deploy:
needs: build-and-deploy-docs
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: './docs'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
-52
View File
@@ -1,52 +0,0 @@
name: Build and Deploy MkDocs Documentation
on:
push:
branches:
- main
paths:
- 'docs/**'
- 'mkdocs.yml'
- '.github/workflows/docs.yml'
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install --upgrade pip
pip install mkdocs mkdocs-material
- name: Build documentation
run: mkdocs build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: 'site'
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
+2 -4
View File
@@ -7,10 +7,8 @@ DerivedData/
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
# MkDocs generated files
/site/
# Keep docs/ for documentation source files
# DocC generated output
/docs-output/
# Claude Code
.claude/
+24
View File
@@ -0,0 +1,24 @@
{
"originHash" : "d7399fa1b3074f6a5debef722dbf8a5621cd2171116ce5f4a91b6c3170b14ece",
"pins" : [
{
"identity" : "swift-docc-plugin",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swiftlang/swift-docc-plugin",
"state" : {
"revision" : "3e4f133a77e644a5812911a0513aeb7288b07d06",
"version" : "1.4.5"
}
},
{
"identity" : "swift-docc-symbolkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swiftlang/swift-docc-symbolkit",
"state" : {
"revision" : "b45d1f2ed151d057b54504d653e0da5552844e34",
"version" : "1.0.0"
}
}
],
"version" : 3
}
+3
View File
@@ -20,6 +20,9 @@ let package = Package(
targets: ["TUIKitExample"]
),
],
dependencies: [
.package(url: "https://github.com/swiftlang/swift-docc-plugin", from: "1.4.3"),
],
targets: [
.target(
name: "TUIKit"
@@ -0,0 +1,81 @@
# Architecture
Understand the layer model and rendering pipeline of TUIKit.
## Overview
TUIKit is structured in five layers, each building on the one below. This clean separation makes the framework easy to extend and maintain.
## Layer Model
### 1. App Layer
The ``App`` protocol is the entry point. It defines one or more scenes that make up your application. The internal `AppRunner` manages the main run loop, terminal setup, signal handling, and event dispatching.
```
@main → App → AppRunner → Main Loop
```
### 2. View Layer
Every UI component conforms to the ``View`` protocol. Views are composed declaratively using ``ViewBuilder``, which supports:
- Single and multiple child views (up to 10)
- Conditionals (`if`, `if-else`, `if let`)
- Loops (`for-in` via ``ForEach``)
Built-in views include ``Text``, ``Button``, ``Menu``, ``Alert``, ``Dialog``, ``Box``, ``Card``, ``Panel``, and layout primitives like ``VStack``, ``HStack``, ``ZStack``, and ``Spacer``.
### 3. Modifier Layer
View modifiers implement the ``ViewModifier`` protocol and operate at the ``FrameBuffer`` level. They transform rendered output — adding padding, borders, frames, backgrounds, or overlays.
```swift
Text("Hello")
.padding(1)
.border(.rounded)
.frame(width: 40)
```
### 4. State & Environment Layer
- **``State``** — Mutable per-view state that triggers re-renders
- **``Binding``** — Two-way connection to a value owned elsewhere
- **``Environment``** — Values propagated down the view tree
- **``AppStorage``** — Persistent key-value storage via `UserDefaults`
### 5. Rendering Layer
The rendering pipeline converts the view tree into terminal output:
1. **View tree traversal** — Each view produces a ``FrameBuffer``
2. **Modifier application** — Modifiers transform buffers
3. **ANSI rendering** — The `ANSIRenderer` converts colors and styles to escape codes
4. **Terminal output** — The ``FrameBuffer`` lines are written to the terminal
## Event Loop
TUIKit runs a synchronous event loop:
```
┌─────────────────────────┐
│ Check resize/state │
│ ↓ │
│ Render view tree │
│ ↓ │
│ Read key event │
│ ↓ │
│ Dispatch to handlers │
│ ↓ │
│ Loop │
└─────────────────────────┘
```
Key events are dispatched in order:
1. Status bar items (system and user)
2. Registered key event handlers (from `onKeyPress`)
3. Default handlers (quit, theme cycling, appearance cycling)
## Focus System
The ``FocusManager`` manages keyboard navigation between interactive elements. Views register as focusable, and the user navigates with Tab/Shift+Tab or arrow keys.
@@ -0,0 +1,107 @@
# Getting Started
Build your first terminal application with TUIKit.
## Overview
TUIKit is a Swift package that lets you create terminal user interfaces with a declarative, SwiftUI-like syntax. This guide walks you through setting up a project and building a simple app.
## Adding TUIKit to Your Project
Add TUIKit as a dependency in your `Package.swift`:
```swift
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "MyTUIApp",
platforms: [.macOS(.v10_15)],
dependencies: [
.package(url: "https://github.com/phranck/TUIKit.git", from: "0.1.0"),
],
targets: [
.executableTarget(
name: "MyTUIApp",
dependencies: ["TUIKit"]
),
]
)
```
## Creating Your First App
Create a `main.swift` file with the ``App`` protocol as your entry point:
```swift
import TUIKit
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
var body: some View {
VStack {
Text("Welcome to TUIKit!")
.bold()
.foregroundColor(.cyan)
Spacer()
Text("Press 'q' to quit")
.dim()
}
}
}
```
## Using State
Add interactivity with the ``State`` property wrapper:
```swift
struct CounterView: View {
@State var count = 0
var body: some View {
VStack {
Text("Count: \(count)")
.bold()
Button("Increment") {
count += 1
}
}
}
}
```
## One-Shot Rendering
For simple scripts that don't need a full app lifecycle, use ``renderOnce(content:)``:
```swift
import TUIKit
renderOnce {
VStack {
Text("Hello, TUIKit!")
.bold()
.foregroundColor(.green)
Divider()
Text("Version \(tuiKitVersion)")
.dim()
}
}
```
## Next Steps
- Learn about the framework's <doc:Architecture>
- Explore <doc:StateManagement> for reactive UIs
- Customize your app's look with <doc:ThemingGuide>
@@ -0,0 +1,109 @@
# State Management
Manage reactive state in your TUIKit application.
## Overview
TUIKit provides a state management system modeled after SwiftUI. When state changes, the view tree is automatically re-rendered.
## @State
Use ``State`` for simple values owned by a single view:
```swift
struct CounterView: View {
@State var count = 0
var body: some View {
VStack {
Text("Count: \(count)")
Button("Increment") {
count += 1 // Triggers re-render
}
}
}
}
```
## Binding
``Binding`` provides a two-way connection to a value owned elsewhere. Use the `$` prefix on a `@State` property to get its binding:
```swift
struct ParentView: View {
@State var selectedIndex = 0
var body: some View {
Menu(items: menuItems, selection: $selectedIndex)
}
}
```
Create constant bindings for previews or static values:
```swift
let binding = Binding.constant(42)
```
## @Environment
``Environment`` reads values propagated down the view hierarchy:
```swift
struct MyView: View {
@Environment(\.theme) var theme
@Environment(\.statusBar) var statusBar
var body: some View {
Text("Themed text")
.foregroundColor(theme.foreground)
}
}
```
### Defining Custom Environment Keys
```swift
struct MyCustomKey: EnvironmentKey {
static var defaultValue: String = "default"
}
extension EnvironmentValues {
var myCustomValue: String {
get { self[MyCustomKey.self] }
set { self[MyCustomKey.self] = newValue }
}
}
```
Inject values with the `.environment()` modifier:
```swift
ContentView()
.environment(\.myCustomValue, "custom")
```
## @AppStorage
``AppStorage`` persists values across app launches using `UserDefaults`:
```swift
struct SettingsView: View {
@AppStorage("username") var username = "Guest"
var body: some View {
Text("Hello, \(username)!")
}
}
```
## How Re-Rendering Works
TUIKit uses a single-threaded event loop. When a ``State`` value changes:
1. ``AppState/setNeedsRender()`` is called
2. The main loop detects the change
3. The entire view tree is re-rendered
4. The new ``FrameBuffer`` output is written to the terminal
This is simple and predictable — no diffing, no virtual DOM, just full re-renders on every state change.
@@ -0,0 +1,97 @@
# Theming Guide
Customize the visual appearance of your TUIKit application with themes.
## Overview
TUIKit includes a full theming system with five built-in themes inspired by classic CRT terminals. Themes define semantic colors for backgrounds, foregrounds, accents, and UI elements.
## Built-in Themes
| Theme | Struct | Inspiration |
|-------|--------|-------------|
| Green Phosphor | ``GreenPhosphorTheme`` | IBM 5151, Apple II |
| Amber Phosphor | ``AmberPhosphorTheme`` | IBM 3278, Wyse 50 |
| White Phosphor | ``WhitePhosphorTheme`` | DEC VT100, VT220 |
| Red Phosphor | ``RedPhosphorTheme`` | Military terminals |
| ncurses | ``NCursesTheme`` | Classic ncurses apps |
## Using Themes
### Via ThemeManager
Access the ``ThemeManager`` through the environment to cycle or set themes:
```swift
struct MyView: View {
@Environment(\.themeManager) var themeManager
var body: some View {
VStack {
Text("Current: \(themeManager.currentThemeName)")
Button("Next Theme") {
themeManager.cycleTheme()
}
}
}
}
```
### Via Environment
Set a theme for a view and all its descendants:
```swift
ContentView()
.theme(AmberPhosphorTheme())
```
### Theme Colors in Views
Use ``Color/theme`` to access the current theme's colors:
```swift
Text("Styled text")
.foregroundColor(.theme.foreground)
.backgroundColor(.theme.backgroundSecondary)
```
Or read the theme directly from the environment:
```swift
@Environment(\.theme) var theme
Text("Hello").foregroundColor(theme.accent)
```
## Creating Custom Themes
Implement the ``Theme`` protocol:
```swift
struct MyCustomTheme: Theme {
let id = "custom"
let name = "Custom"
let background = Color.hex(0x1A1A2E)
let foreground = Color.hex(0xE0E0E0)
let accent = Color.hex(0x00D4FF)
// ... implement remaining required properties
// Many have default implementations via Theme extension
}
```
## Theme Color Properties
The ``Theme`` protocol defines these semantic color categories:
- **Backgrounds**: `background`, `backgroundSecondary`, `backgroundTertiary`
- **Foregrounds**: `foreground`, `foregroundSecondary`, `foregroundTertiary`
- **Accents**: `accent`, `accentSecondary`
- **Semantic**: `success`, `warning`, `error`, `info`
- **UI Elements**: `border`, `borderFocused`, `separator`, `selection`, `disabled`
- **Status Bar**: `statusBarBackground`, `statusBarForeground`, `statusBarHighlight`
- **Containers**: `containerBackground`, `containerHeaderBackground`, `buttonBackground`
Many of these have default implementations that derive from the primary colors, so a minimal theme only needs to define a handful of values.
+148
View File
@@ -0,0 +1,148 @@
# ``TUIKit``
A declarative, SwiftUI-like framework for building Terminal User Interfaces in Swift.
@Metadata {
@DisplayName("TUIKit")
}
## Overview
TUIKit lets you build terminal applications using a familiar, declarative syntax inspired by SwiftUI. No ncurses, no C dependencies — pure Swift.
```swift
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
VStack {
Text("Hello, TUIKit!")
.bold()
.foregroundColor(.cyan)
Button("Press me") {
// handle action
}
}
}
}
}
```
### Key Features
- **Declarative syntax** — Build UIs with `VStack`, `HStack`, `Text`, `Button`, and more
- **SwiftUI-like API** — `@State`, `@Environment`, `@ViewBuilder`, modifiers
- **Theming system** — 5 built-in phosphor themes with full RGB color support
- **Focus management** — Keyboard-driven navigation between interactive elements
- **Status bar** — Configurable shortcut bar with context stack
- **No dependencies** — Pure Swift, no ncurses or other C libraries
- **Cross-platform** — macOS and Linux
## Topics
### Essentials
- <doc:GettingStarted>
- <doc:Architecture>
### App Structure
- ``App``
- ``Scene``
- ``WindowGroup``
### Views
- ``View``
- ``Text``
- ``Button``
- ``Menu``
- ``Alert``
- ``Dialog``
### Layout
- ``VStack``
- ``HStack``
- ``ZStack``
- ``Spacer``
- ``ForEach``
### Containers
- ``Box``
- ``Card``
- ``Panel``
- ``ContainerView``
### State Management
- <doc:StateManagement>
- ``State``
- ``Binding``
- ``AppState``
### Environment
- ``Environment``
- ``EnvironmentKey``
- ``EnvironmentValues``
- ``EnvironmentStorage``
### Theming
- <doc:ThemingGuide>
- ``Theme``
- ``ThemeManager``
- ``ThemeRegistry``
- ``ThemeColors``
- ``GreenPhosphorTheme``
- ``AmberPhosphorTheme``
- ``WhitePhosphorTheme``
- ``RedPhosphorTheme``
- ``NCursesTheme``
### Colors
- ``Color``
- ``ANSIColor``
### View Composition
- ``ViewBuilder``
- ``ViewModifier``
- ``ModifiedView``
### Appearance
- ``Appearance``
- ``AppearanceManager``
- ``BorderStyle``
### Focus System
- ``FocusManager``
### Status Bar
- ``StatusBar``
- ``StatusBarState``
- ``StatusBarItem``
- ``StatusBarItemProtocol``
- ``StatusBarStyle``
- ``StatusBarAlignment``
### Input Handling
- ``KeyEvent``
- ``QuitBehavior``
### Rendering
- ``Renderable``
- ``FrameBuffer``
- ``RenderContext``
### Persistence
- ``AppStorage``
-256
View File
@@ -1,256 +0,0 @@
# Appearance System
Learn about the 5 structural appearance styles for rendering borders and containers.
## Overview
TUIKit provides 5 appearance styles that control how borders and containers are rendered:
- **Line**: Simple ASCII lines
- **Rounded**: Rounded corners (default)
- **DoubleLine**: Double-line borders
- **Heavy**: Heavy/bold borders
- **Block**: Half-block Unicode characters for solid appearance
## Appearance Styles
### Line Appearance
Simple single-line ASCII borders:
```swift
VStack {
Text("Content")
}
.border(.line)
```
Characters used:
- Horizontal: `-`
- Vertical: `|`
- Corners: `+`
### Rounded Appearance
Rounded corners (default appearance):
```swift
VStack {
Text("Content")
}
.border(.rounded)
```
Characters used:
- Top-left: `╭`
- Top-right: `╮`
- Bottom-left: `╰`
- Bottom-right: `╯`
- Horizontal: `─`
- Vertical: `│`
### DoubleLine Appearance
Double-line borders for emphasis:
```swift
VStack {
Text("Content")
}
.border(.doubleLine)
```
Characters used:
- Top-left: `╔`
- Top-right: `╗`
- Bottom-left: `╚`
- Bottom-right: `╝`
- Horizontal: `═`
- Vertical: `║`
### Heavy Appearance
Bold/heavy borders:
```swift
VStack {
Text("Content")
}
.border(.heavy)
```
Characters used:
- Top-left: `┏`
- Top-right: `┓`
- Bottom-left: `┗`
- Bottom-right: `┛`
- Horizontal: `━`
- Vertical: `┃`
### Block Appearance
Modern half-block Unicode characters for a solid, integrated look:
```swift
VStack {
Text("Content")
}
.border(.block)
```
Special rendering:
- **Top border**: `▄` (lower half-block) with foreground = container background
- **Side borders**: `█` (full block) with foreground = container background
- **Bottom border**: `▀` (upper half-block) with foreground = container background
- **Content**: Filled with container background color
- Uses full-block characters to create solid visual edges
The block appearance creates a seamless, filled container that appears integrated with the terminal background.
## Setting Global Appearance
Use the appearance environment to set the default for all components:
```swift
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.appearance, .block)
}
}
}
```
## Cycling Appearances
The example app supports appearance cycling with the `a` key:
```swift
@main
struct ExampleApp: App {
@State private var currentAppearance: Appearance = .rounded
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.appearance, currentAppearance)
.statusBarItems {
StatusBarItem(
label: "Appearance",
shortcut: Shortcut.letter("a"),
action: {
currentAppearance = currentAppearance.next()
}
)
}
}
}
}
```
## Using Appearance with Containers
All container views respect the appearance setting:
```swift
// Using Panel with different appearances
VStack {
Panel(title: "Settings") {
Text("Configure options here")
}
.border(.rounded)
Panel(title: "Status") {
Text("System information")
}
.border(.block)
Card {
Text("Card content")
}
.border(.heavy)
}
```
## BorderStyle
Use the ``BorderStyle`` type to customize individual borders:
```swift
extension View {
func border(
_ style: BorderStyle = .default,
width: Int = 1,
color: Color = .theme.border,
appearance: Appearance = .rounded
) -> some View {
// Returns bordered view
}
}
// Custom border
Text("Custom border")
.border(.custom, width: 2, color: .theme.accent)
```
## Appearance in Components
Different components use appearance differently:
### Text with Border
```swift
Text("Bordered text")
.border(.block)
```
### Card with Appearance
```swift
Card {
Text("Content")
}
.border(.rounded)
```
### Panel with Title
```swift
Panel(title: "Title") {
Text("Content")
}
.border(.block)
```
### Alerts and Dialogs
Alerts automatically use the current appearance:
```swift
Alert(
title: "Confirm",
message: "Are you sure?",
borderColor: .theme.border,
titleColor: .theme.accent
)
```
## Best Practices
1. **Consistency**: Choose one appearance and stick with it
2. **Theme integration**: Use theme colors for borders
3. **Readability**: Ensure sufficient contrast for borders
4. **Performance**: Complex borders render efficiently
5. **Testing**: Test appearance on various terminal sizes
## Related Topics
- ``Appearance``
- ``BorderStyle``
- ``View/border(_:style:)-4xzvw``
- <doc:Theming>
- ``Panel``
- ``Card``
- ``ContainerView``
-258
View File
@@ -1,258 +0,0 @@
# Architecture Overview
Understand the architecture and design patterns that power TUIKit.
## Core Design Principles
TUIKit follows these key principles:
1. **Declarative UI**: Describe what you want, not how to build it
2. **Composability**: Build complex UIs from simple, reusable components
3. **Value Semantics**: Views are lightweight value types, not stateful objects
4. **Data Flow**: Clear, unidirectional data flow through Environment and State
5. **Pure Swift**: No external dependencies or C bindings
## The View System
### View Protocol
The `View` protocol is the foundation of TUIKit:
```swift
public protocol View {
associatedtype Body: View
@ViewBuilder var body: Body { get }
}
```
Views are **not** UI elements—they're descriptions of UI that get rendered when needed. This enables:
- Lightweight composition
- Efficient updates
- Declarative syntax
### Primitive vs Composite Views
**Primitive Views** directly render content:
- Conform to `Renderable`
- Have `body: Never`
- Examples: `Text`, `Button`, `Menu`
**Composite Views** combine other views:
- Define a `body` property
- Renderer walks the tree recursively
- Examples: `VStack`, `HStack`, `Card`
### Rendering Pipeline
1. **View Tree**: User creates view hierarchy
2. **Traversal**: Renderer walks tree depth-first
3. **Rendering**: Primitive views produce `FrameBuffer` character data
4. **Compositing**: Overlays blend on top with character-level precision
5. **Output**: Terminal renders the final buffer
## State Management Architecture
### Local State (@State)
Stored in the view itself:
```swift
@State var count: Int = 0
```
When `@State` changes, the view re-renders automatically.
### Environment (Top-Down)
Parent views pass data to children:
```swift
@Environment(\.theme) var theme
// Theme flows from App → all children
```
### Preferences (Bottom-Up)
Children can propagate values to parents (rarely used in TUIKit).
### Storage (@AppStorage, @SceneStorage)
Persistent storage via:
- **@AppStorage**: UserDefaults (macOS) or JSON file (Linux)
- **@SceneStorage**: Per-scene state restoration
## Data Flow Pattern
```
┌─────────────────────────────────────┐
│ App or Scene │
│ @AppStorage, @State, Environment │
└────────┬────────────────────────────┘
│ passes theme, data
▼
┌─────────────────────────────────────┐
│ Composite Views (VStack, etc) │
│ pass Environment to children │
└────────┬────────────────────────────┘
│ may use @State locally
▼
┌─────────────────────────────────────┐
│ Primitive Views (Text, Button) │
│ render to FrameBuffer │
└─────────────────────────────────────┘
```
## Theme and Appearance System
### Theme Protocol
Defines semantic colors:
```swift
public protocol Theme {
var background: Color { get }
var accent: Color { get }
// ... other colors
}
```
### Appearance Protocol
Defines structural styles:
```swift
public enum Appearance {
case line, rounded, doubleLine, heavy, block
}
```
Both are passed through Environment, enabling:
- Global theme switching
- Dynamic appearance changes
- Consistent styling across app
## Focus Management System
``FocusManager`` tracks which element has keyboard focus:
1. **Focus ID**: Each interactive element has a unique ID
2. **Navigation**: Tab/Shift+Tab moves focus
3. **Rendering**: Focused element shows visual indicator
4. **Events**: Keyboard events route to focused element
```swift
@Environment(\.focusManager) var focusManager
// Navigation automatically updates focusManager
// onKeyPress receives keyboard events
```
## Modifier System
Modifiers wrap views to add behavior:
```swift
extension View {
func padding(_ amount: Int) -> some View {
ModifiedView(content: self, modifier: PaddingModifier(amount))
}
}
```
Modifiers compose:
```swift
Text("Hello")
.bold() // Text → BoldView
.padding(1) // BoldView → PaddedView
.border(.rounded) // PaddedView → BorderedView
```
## Component Library
### Container Views
- `VStack`, `HStack`, `ZStack`: Layout primitives
- `Card`, `Box`, `Panel`: Styled containers
- `ContainerView`: Header/body/footer structure
### Interactive Views
- `Button`: Clickable button with focus
- `Menu`: Selection menu with keyboard
- `Alert`, `Dialog`: Modal overlays
### Structural Views
- `ForEach`: Render collections
- `Text`: Display text
- `Spacer`, `Divider`: Layout helpers
### Status Bar
- `StatusBar`: Application status bar
- `StatusBarItem`: Individual item
- `Shortcut`: Keyboard shortcut display
## Rendering Engine
### FrameBuffer
Character-level buffer for compositing:
- 2D array of characters and attributes
- Supports color, styling (bold, italic, etc.)
- Compositing for overlays
### ANSI Renderer
Converts buffer to ANSI escape codes:
- Color codes (foreground/background)
- Styling (bold, italic, underline)
- Terminal state management
### Terminal Abstraction
Platform-specific terminal handling:
- macOS: termios
- Linux: termios via libc
- Raw mode, alternate screen, signal handling
## Performance Considerations
1. **Lazy Rendering**: Only visible areas render
2. **Diff Optimization**: Only changed areas redraw
3. **Buffer Reuse**: FrameBuffer recycled across frames
4. **View Value Semantics**: Lightweight copying and discarding
## Error Handling
TUIKit uses Swift's error handling:
- Fatal errors for programmer mistakes
- Non-fatal errors for recovery scenarios
- Storage backend errors are silenced (fallback to defaults)
## Platform Support
### macOS
- Native UserDefaults for @AppStorage
- Full terminal support
- Modern Swift runtime
### Linux
- JSON file storage for @AppStorage
- glibc-based terminal support
- XDG paths for configuration
## Future Extensibility
The architecture supports:
- Custom storage backends
- Custom themes
- Custom appearances
- Custom view components
- Animation system (planned)
## Related Topics
- ``View``
- ``Theme``
- ``Appearance``
- ``FocusManager``
- ``FrameBuffer``
- <doc:Rendering>
- <doc:StateManagement>
-252
View File
@@ -1,252 +0,0 @@
# Focus Management
Understand how keyboard navigation and focus works in TUIKit.
## Overview
TUIKit provides a sophisticated focus management system that enables Tab/Shift+Tab navigation, keyboard shortcuts, and custom focus logic.
## The Focus Manager
``FocusManager`` manages which component currently has keyboard focus:
```swift
@Environment(\.focusManager) var focusManager
Button("Click me") {
// Handle click
}
.focused(focusID: "myButton")
```
## Tab Navigation
By default, all focusable elements can be navigated with Tab and Shift+Tab:
- **Tab**: Move focus to the next element
- **Shift+Tab**: Move focus to the previous element
- **Enter/Space**: Activate focused button
```swift
VStack(spacing: 1) {
Text("Navigation")
Button("First") { }
Button("Second") { }
Button("Third") { }
}
```
Users can Tab between the buttons in order.
## Focus Indicators
Focusable elements show a focus indicator when active:
```swift
Button("Focusable") {
print("Activated")
}
```
The button displays:
- A border around the element
- Visual highlight (usually arrow prefix: `▸`)
- Theme accent color
## Programmatic Focus
Set focus programmatically:
```swift
struct Settings: View {
@State private var focusedField: String?
var body: some View {
VStack(spacing: 1) {
Button("First") { focusedField = "first" }
.focused(focusID: "first", focused: focusedField == "first")
Button("Second") { focusedField = "second" }
.focused(focusID: "second", focused: focusedField == "second")
Button("Reset") { focusedField = nil }
}
}
}
```
## Keyboard Events
Handle keyboard events with `onKeyPress`:
```swift
struct App: View {
var body: some View {
VStack {
ContentView()
.onKeyPress { event in
if event.key == .character("h") && event.modifiers.contains(.ctrl) {
print("Help requested")
return true
}
return false
}
}
}
}
```
### Key Event Structure
``KeyEvent`` contains:
- **key**: The key pressed (character, arrow, enter, etc.)
- **modifiers**: Ctrl, Shift, Alt flags
- **raw**: Raw terminal escape sequence
### Special Keys
Handle special keys like arrows and function keys:
```swift
.onKeyPress { event in
switch event.key {
case .up:
print("Arrow up")
case .down:
print("Arrow down")
case .left:
print("Arrow left")
case .right:
print("Arrow right")
case .enter:
print("Enter pressed")
case .escape:
print("Escape pressed")
case .tab:
print("Tab pressed")
case .character(let char):
print("Character: \(char)")
default:
break
}
return true
}
```
## Focusable Protocol
Components conform to ``Focusable`` to support focus:
```swift
public protocol Focusable {
var focusID: String? { get }
var isFocused: Bool { get }
}
```
Button, Menu, and other interactive components automatically implement this.
## Custom Focus Logic
Create custom focus behavior:
```swift
struct CustomMenu: View {
@State private var selectedIndex: Int = 0
let items: [String]
var body: some View {
VStack(spacing: 0) {
ForEach(Array(items.enumerated()), id: \.offset) { index, item in
Text(item)
.padding(1)
.background(selectedIndex == index ? .theme.accent : .clear)
}
}
.onKeyPress { event in
switch event.key {
case .up:
selectedIndex = max(0, selectedIndex - 1)
return true
case .down:
selectedIndex = min(items.count - 1, selectedIndex + 1)
return true
default:
return false
}
}
}
}
```
## Focus in Modals
Focus works correctly with modals and overlays:
```swift
@State var showDialog: Bool = false
var body: some View {
VStack {
if showDialog {
Alert(
title: "Confirm",
message: "Continue?"
) {
VStack(spacing: 1) {
Button("Yes") { showDialog = false }
Button("No") { showDialog = false }
}
}
.modal()
}
Button("Show Dialog") { showDialog = true }
}
}
```
When a modal appears, focus automatically moves to the first focusable element in the modal.
## Best Practices
1. **Tab order**: Arrange elements logically for Tab navigation
2. **Feedback**: Always provide visual feedback for focused elements
3. **Shortcuts**: Implement keyboard shortcuts for common actions
4. **Testing**: Test focus behavior with keyboard navigation
5. **Accessibility**: Consider users with motor impairments who rely on keyboard
## Status Bar Integration
Status bar items show keyboard shortcuts:
```swift
.statusBarItems {
StatusBarItem(
label: "Help",
shortcut: Shortcut.letter("?"),
action: {
print("Show help")
}
)
StatusBarItem(
label: "Quit",
shortcut: Shortcut.letter("q"),
action: {
print("Exit app")
}
)
}
```
## Related Topics
- ``FocusManager``
- ``KeyEvent``
- ``Focusable``
- ``View/onKeyPress(_:)``
- ``StatusBar``
- ``StatusBarItem``
-180
View File
@@ -1,180 +0,0 @@
# Getting Started with TUIKit
Create your first terminal user interface in minutes.
## Installation
### Using Swift Package Manager
Add TUIKit to your `Package.swift`:
```swift
.package(url: "https://github.com/anthropics/SwiftTUI.git", from: "0.1.0")
```
Or via Xcode: File > Add Packages > Enter repository URL
## Creating Your First App
### 1. Define Your App
Every TUIKit app needs an `@main` entry point that conforms to the `App` protocol:
```swift
import TUIKit
@main
struct HelloApp: App {
var body: some Scene {
WindowGroup {
Text("Hello, TUIKit!")
}
}
}
```
### 2. Add Some Layout
Use `VStack` and `HStack` to organize your content:
```swift
@main
struct LayoutApp: App {
var body: some Scene {
WindowGroup {
VStack(spacing: 1) {
Text("Welcome")
.bold()
Text("Build terminal UIs in Swift")
Spacer()
Text("Press 'q' to quit")
.foregroundColor(.theme.foregroundSecondary)
}
.padding()
}
}
}
```
### 3. Make It Interactive
Add buttons and state to create interactive interfaces:
```swift
import TUIKit
@main
struct InteractiveApp: App {
@State var count: Int = 0
var body: some Scene {
WindowGroup {
VStack(spacing: 1) {
Text("Counter: \(count)")
.bold()
HStack(spacing: 2) {
Button("Increment") { count += 1 }
Button("Decrement") { count = max(0, count - 1) }
}
Spacer()
}
.padding()
}
}
}
```
## Running Your App
### From Command Line
```bash
swift run
```
### With a Custom Executable Name
Add to `Package.swift`:
```swift
.executableTarget(
name: "MyApp",
dependencies: [.product(name: "TUIKit", package: "SwiftTUI")]
)
```
Then run:
```bash
swift run MyApp
```
## Understanding the Basics
### Views
Everything in TUIKit is a `View`. Views are lightweight, composable units that render content to the terminal.
Common views:
- **`Text`**: Display text with optional styling
- **`Button`**: Interactive button with action handler
- **`VStack`**: Arrange views vertically
- **`HStack`**: Arrange views horizontally
- **`Spacer`**: Fill available space
### State Management
Use `@State` to make your views interactive:
```swift
@State var isVisible: Bool = true
VStack {
if isVisible {
Text("Visible")
}
Button("Toggle") { isVisible.toggle() }
}
```
### Modifiers
Customize views with modifiers:
```swift
Text("Hello")
.bold()
.foregroundColor(.theme.accent)
.padding(1)
.border(.rounded)
```
## Next Steps
- Explore the <doc:ViewHierarchy> to understand component organization
- Learn <doc:StateManagement> for complex state scenarios
- Discover <doc:Theming> to customize colors and appearance
- Check out <doc:Modifiers> for all available styling options
- Try <doc:BuildYourFirstApp> tutorial for step-by-step guidance
## Key Bindings
By default, TUIKit apps support:
- **`q`**: Quit the application
- **`t`**: Cycle through themes
- **`a`**: Cycle through appearance styles
- **`?`**: Show help
See ``KeyEvent`` for custom keyboard handling.
## Terminal Requirements
- Minimum 80x24 character terminal
- ANSI color support (256 colors recommended)
- UTF-8 encoding
- Supports: macOS Terminal, iTerm2, Kitty, and Linux terminals (gnome-terminal, konsole, etc.)
-340
View File
@@ -1,340 +0,0 @@
# View Modifiers
Learn how to use modifiers to customize the appearance and behavior of views.
## Overview
Modifiers are methods that return a modified copy of a view. Chain them together to build complex layouts and styling:
```swift
Text("Hello")
.bold()
.foregroundColor(.theme.accent)
.padding(1)
.border(.rounded)
```
## Layout Modifiers
### padding(_:)
Add padding around content:
```swift
Text("Content")
.padding() // Default 1 unit
.padding(2) // 2 units all sides
.padding(.top, 1) // 1 unit top
.padding(.horizontal, 2) // 2 units left/right
```
### frame(width:height:alignment:)
Set fixed size:
```swift
Text("Fixed")
.frame(width: 20, height: 5)
Button("Button")
.frame(width: 15)
```
### frame(minWidth:maxWidth:minHeight:maxHeight:)
Set flexible size constraints:
```swift
Text("Flexible")
.frame(minWidth: 10, maxWidth: 50)
.frame(minHeight: 3, maxHeight: 10)
Text("Fill available space")
.frame(maxWidth: .infinity, maxHeight: .infinity)
```
## Color Modifiers
### foregroundColor(_:)
Set text color:
```swift
Text("Colored")
.foregroundColor(.theme.accent)
Text("Green")
.foregroundColor(.ansi(.brightGreen))
Text("Custom")
.foregroundColor(.hex("FF5500"))
```
### background(_:)
Add background color:
```swift
Text("Background")
.background(.theme.accent)
.foregroundColor(.theme.background)
```
## Text Styling
### Bold, Italic, Underline
```swift
Text("Bold").bold()
Text("Italic").italic()
Text("Underline").underlined()
Text("Strikethrough").strikethrough()
Text("Dim").dimmed()
Text("Blinking").blinking()
Text("Inverted").inverted()
```
Combine multiple modifiers:
```swift
Text("Complex")
.bold()
.italic()
.foregroundColor(.theme.accent)
```
## Border and Structure
### border(_:)
Add borders with different styles:
```swift
Text("Bordered")
.border(.rounded)
Text("Heavy border")
.border(.heavy, width: 2)
VStack {
Text("Content")
}
.border(.block, color: .theme.accent)
```
## Overlay and Compositing
### overlay(_:)
Layer content on top:
```swift
Text("Background")
.overlay {
Text("Foreground")
}
```
### dimmed()
Reduce visual emphasis:
```swift
VStack {
Text("Normal")
Text("Dimmed")
.dimmed()
}
```
### modal()
Combine dimmed + centered overlay:
```swift
showAlert {
Alert(title: "Alert", message: "Message")
.modal()
}
```
## Event Modifiers
### onKeyPress(_:)
Handle keyboard input:
```swift
VStack {
ContentView()
}
.onKeyPress { event in
if event.key == .character("q") {
// Quit
return true
}
return false
}
```
### onAppear(_:)
Run code when view appears:
```swift
Text("Content")
.onAppear {
print("View appeared")
}
```
### onDisappear(_:)
Run code when view disappears:
```swift
Text("Content")
.onDisappear {
print("View disappearing")
}
```
### task(_:)
Run async code:
```swift
VStack {
ContentView()
}
.task {
// Fetch data
let data = try await fetchData()
}
```
## Data Flow Modifiers
### environment(_:_:)
Pass environment values to children:
```swift
VStack {
ContentView()
}
.environment(\.theme, customTheme)
```
### statusBarItems(_:)
Define status bar items:
```swift
VStack {
ContentView()
}
.statusBarItems {
StatusBarItem(
label: "Help",
shortcut: Shortcut.letter("?"),
action: { print("Help") }
)
}
```
## Combining Modifiers
Modifiers are applied in order—the order matters:
```swift
// This looks different...
Text("Order matters")
.foregroundColor(.theme.accent)
.padding(1)
.border(.rounded)
// ...than this
Text("Order matters")
.border(.rounded)
.padding(1)
.foregroundColor(.theme.accent)
```
### Creating Custom Modifiers
Create reusable modifiers:
```swift
struct PrimaryButtonStyle: ViewModifier {
func body(content: Content) -> some View {
content
.bold()
.foregroundColor(.theme.background)
.background(.theme.accent)
.padding(1)
.border(.rounded)
}
}
extension View {
func primaryButton() -> some View {
modifier(PrimaryButtonStyle())
}
}
// Usage
Button("Click") { }
.primaryButton()
```
## Common Patterns
### Centered Text
```swift
Text("Centered")
.frame(maxWidth: .infinity, alignment: .center)
```
### Full-Size Container
```swift
VStack {
ContentView()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
```
### Bordered Section
```swift
VStack(spacing: 1) {
Text("Title").bold()
ContentView()
}
.padding(1)
.border(.rounded)
```
### Button Row
```swift
HStack(spacing: 2) {
Button("OK") { }
Button("Cancel") { }
}
.frame(maxWidth: .infinity, alignment: .trailing)
```
## Related Topics
- ``View``
- ``ViewModifier``
- ``View/padding(_:)-19gu9``
- ``View/frame(width:height:alignment:)``
- ``View/border(_:style:)-4xzvw``
- ``View/background(_:)``
- ``View/foregroundColor(_:)``
- ``View/overlay(alignment:content:)``
- ``View/onKeyPress(_:)``
-259
View File
@@ -1,259 +0,0 @@
# State Management
Learn how to manage application state and data flow in TUIKit.
## Overview
TUIKit provides several mechanisms for managing state:
- **`@State`**: Local view state
- **`@Environment`**: Top-down data flow
- **`Binding`**: Two-way data binding
- **`@AppStorage`**: Persistent application settings
- **`@SceneStorage`**: Scene-specific state restoration
## @State Property Wrapper
`@State` stores local state within a view and automatically triggers re-renders when the value changes:
```swift
struct Counter: View {
@State var count: Int = 0
var body: some View {
VStack(spacing: 1) {
Text("Count: \(count)")
.bold()
HStack(spacing: 2) {
Button("Decrement") { count -= 1 }
Button("Increment") { count += 1 }
}
}
}
}
```
### Rules for @State
- Declare as `private` to prevent external modification
- Initialize with a default value
- Use only in views, not in view models
- State is destroyed when view is removed from hierarchy
```swift
struct InputForm: View {
@State private var name: String = ""
@State private var age: Int = 0
@State private var agreed: Bool = false
var body: some View {
VStack(spacing: 1) {
// View content
}
}
}
```
## Binding
A `Binding` creates a two-way connection between a view and a state variable:
```swift
struct Parent: View {
@State var isExpanded: Bool = false
var body: some View {
VStack {
Child(isExpanded: $isExpanded)
}
}
}
struct Child: View {
@Binding var isExpanded: Bool
var body: some View {
Button(isExpanded ? "Collapse" : "Expand") {
isExpanded.toggle()
}
}
}
```
Use `$` to create a binding to a state property.
### Creating Custom Bindings
Create computed bindings for complex logic:
```swift
struct FilteredList: View {
@State private var showDetails: Bool = false
var detailsBinding: Binding<Bool> {
Binding(
get: { showDetails },
set: { newValue in
if newValue {
print("Details opened")
}
showDetails = newValue
}
)
}
var body: some View {
Button("Toggle") {
detailsBinding.wrappedValue.toggle()
}
}
}
```
## @Environment and Environment Keys
Environment provides top-down data flow to all child views:
```swift
struct App: View {
var body: some View {
VStack {
ContentView()
.environment(\.theme, customTheme)
}
}
}
struct ContentView: View {
@Environment(\.theme) var theme
var body: some View {
Text("Using current theme")
.foregroundColor(theme.foreground)
}
}
```
### Custom Environment Keys
Define custom environment values:
```swift
struct UserPreferencesKey: EnvironmentKey {
static let defaultValue = UserPreferences()
}
extension EnvironmentValues {
var userPreferences: UserPreferences {
get { self[UserPreferencesKey.self] }
set { self[UserPreferencesKey.self] = newValue }
}
}
// Usage
struct App: View {
var body: some View {
VStack {
ContentView()
.environment(\.userPreferences, UserPreferences(language: "de"))
}
}
}
struct ContentView: View {
@Environment(\.userPreferences) var prefs
var body: some View {
Text("Language: \(prefs.language)")
}
}
```
## @AppStorage
`@AppStorage` persists values to storage (UserDefaults on macOS, JSON file on Linux):
```swift
struct App: View {
@AppStorage("theme") var selectedTheme: String = "green"
@AppStorage("fontSize") var fontSize: Int = 12
var body: some View {
VStack {
Text("Current theme: \(selectedTheme)")
// Settings UI
}
}
}
```
Changes to `@AppStorage` variables are automatically saved and restored across app launches.
## @SceneStorage
`@SceneStorage` preserves state for the current scene:
```swift
struct MyScene: Scene {
@SceneStorage("selectedTab") var selectedTab: String = "home"
@SceneStorage("scrollPosition") var scrollPosition: Int = 0
var body: some Scene {
WindowGroup {
VStack {
if selectedTab == "home" {
HomeView()
}
}
}
}
}
```
## Data Flow Pattern
### Recommended Pattern
1. **Local state**: Use `@State` for temporary UI state
2. **Shared state**: Use `@Environment` to pass to child views
3. **Persistent state**: Use `@AppStorage` for settings
4. **Child updates**: Use `@Binding` to let children modify parent state
```swift
@main
struct MyApp: App {
// Persistent settings
@AppStorage("theme") var theme: String = "green"
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.theme, themeForString(theme))
}
}
}
struct ContentView: View {
@Environment(\.theme) var theme
@State private var showMenu: Bool = false
var body: some View {
VStack {
if showMenu {
MenuView(showing: $showMenu)
}
}
}
}
```
## Related Topics
- ``State``
- ``Binding``
- ``@Environment``
- ``@AppStorage``
- ``@SceneStorage``
- ``EnvironmentKey``
- ``EnvironmentValues``
-261
View File
@@ -1,261 +0,0 @@
# Theming System
Customize the appearance of your application with TUIKit's flexible theming system.
## Built-in Themes
TUIKit includes 4 beautiful phosphor-style themes:
### Green Theme
Classic green phosphor aesthetic for a retro terminal feel:
```swift
.environment(\.themeManager.currentTheme, .green)
```
- **Accent**: Bright green
- **Background**: Deep dark green
- **Foreground**: Light green text
### Amber Theme
Warm amber/orange phosphor theme:
```swift
.environment(\.themeManager.currentTheme, .amber)
```
- **Accent**: Bright amber
- **Background**: Dark brown-orange
- **Foreground**: Light amber text
### White Theme
Cool white/blue-tinted theme for modern appearance:
```swift
.environment(\.themeManager.currentTheme, .white)
```
- **Accent**: Bright white
- **Background**: Deep blue-black
- **Foreground**: Light white text
### Red Theme
Bold red phosphor theme:
```swift
.environment(\.themeManager.currentTheme, .red)
```
- **Accent**: Bright red
- **Background**: Dark red-black
- **Foreground**: Light red text
## Using Themes
### Default Theme
By default, the Green theme is active:
```swift
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
```
### Switching Themes
Use the theme manager to switch themes at runtime:
```swift
struct App: View {
@Environment(\.themeManager) var themeManager
var body: some View {
VStack {
Button("Switch to Amber") {
themeManager.currentTheme = .amber
}
Button("Switch to White") {
themeManager.currentTheme = .white
}
}
}
}
```
### Accessing Theme Colors
Use `Color.theme` shorthand to access current theme colors:
```swift
VStack {
Text("This uses the theme accent color")
.foregroundColor(.theme.accent)
Text("This uses the theme foreground")
.foregroundColor(.theme.foreground)
Text("This uses secondary text color")
.foregroundColor(.theme.foregroundSecondary)
}
```
## Theme Protocol
Themes conform to the ``Theme`` protocol:
```swift
public protocol Theme {
var background: Color { get }
var containerBackground: Color { get }
var containerHeaderBackground: Color { get }
var buttonBackground: Color { get }
var statusBarBackground: Color { get }
var foreground: Color { get }
var foregroundSecondary: Color { get }
var foregroundTertiary: Color { get }
var accent: Color { get }
var border: Color { get }
var statusBarForeground: Color { get }
}
```
## Creating Custom Themes
Implement the `Theme` protocol to create custom themes:
```swift
struct CompanyTheme: Theme {
let background = Color.hex("0a0a0a")
let containerBackground = Color.hex("1a1a2e")
let containerHeaderBackground = Color.hex("16213e")
let buttonBackground = Color.hex("0f3460")
let statusBarBackground = Color.hex("0f3460")
let foreground = Color.hex("eaeaea")
let foregroundSecondary = Color.hex("999999")
let foregroundTertiary = Color.hex("666666")
let accent = Color.hex("00d4ff")
let border = Color.hex("00d4ff")
let statusBarForeground = Color.hex("666666")
}
// Use it
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.themeManager.currentTheme, CompanyTheme())
}
}
}
```
## Color System
TUIKit supports multiple color spaces:
### ANSI Colors
Use standard terminal colors:
```swift
Color.ansi(.brightGreen)
Color.ansi(.red)
```
### Hex Colors
Specify colors as hex strings or integers:
```swift
Color.hex("FF5500")
Color.hex("#FF5500")
Color.hex(0xFF5500)
```
### RGB Colors
Define colors by RGB values:
```swift
Color.rgb(red: 255, green: 85, blue: 0)
Color.rgb(red: 1.0, green: 0.33, blue: 0.0)
```
### 256-Color Palette
Use 256-color terminal palette (0-255):
```swift
Color.palette256(196)
```
### HSL Colors
Create colors using HSL (Hue, Saturation, Lightness):
```swift
Color.hsl(hue: 25, saturation: 100, lightness: 50)
```
## Color Modifiers
Adjust colors programmatically:
```swift
let baseColor = Color.hex("#FF5500")
let lighter = baseColor.lighter(by: 0.2)
let darker = baseColor.darker(by: 0.3)
let transparent = baseColor.opacity(0.5)
```
## Theme Cycling
The example app supports theme cycling with the `t` key:
```swift
@main
struct ExampleApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.statusBarItems {
StatusBarItem(
label: "Theme",
shortcut: Shortcut.letter("t"),
action: {
// Cycle themes
}
)
}
}
}
}
```
## Best Practices
1. **Use semantic colors**: Reference `Color.theme.accent` instead of hardcoding colors
2. **Test readability**: Ensure sufficient contrast in custom themes
3. **Support all modes**: Create both dark and light themed colors if needed
4. **Store preferences**: Use `@AppStorage` to remember user theme choice
5. **Provide visual feedback**: Show current theme in settings
## Related Topics
- ``Color``
- ``Theme``
- ``ThemeManager``
- <doc:Appearance>
- <doc:StateManagement>
-239
View File
@@ -1,239 +0,0 @@
# Understanding the View Hierarchy
Learn how TUIKit's declarative view model works and how to compose views effectively.
## The View Protocol
Everything in TUIKit conforms to the `View` protocol. A view is a lightweight value type that describes a piece of UI:
```swift
public protocol View {
associatedtype Body: View
@ViewBuilder var body: Body { get }
}
```
Views are **not** the rendered output—they're descriptions of UI that get rendered when needed.
### Primitive Views
Some views have `body: Never` and directly conform to `Renderable`. These render their own content:
- **`Text`**: Display text with styling
- **`Button`**: Interactive clickable element
- **`Menu`**: Selection menu with keyboard navigation
- **`Spacer`**: Occupy available space
- **`Divider`**: Horizontal or vertical separator
- **`EmptyView`**: Invisible placeholder view
### Composite Views
Most views define a `body` that combines other views:
```swift
struct MyCard: View {
var body: some View {
VStack(spacing: 1) {
Text("Title").bold()
Text("Content")
}
.border(.rounded)
}
}
```
Composite views don't render directly—the renderer walks the view tree and renders primitives.
## Container Views
### VStack (Vertical Stack)
Stack views vertically with optional spacing:
```swift
VStack(spacing: 1) {
Text("First")
Text("Second")
Text("Third")
}
```
### HStack (Horizontal Stack)
Stack views horizontally:
```swift
HStack(spacing: 2) {
Button("OK") { }
Button("Cancel") { }
}
```
### ZStack (Depth Stack)
Layer views on top of each other:
```swift
ZStack {
Text("Background")
Text("Foreground")
}
```
### ForEach
Render a collection of items:
```swift
ForEach(items) { item in
Text(item.name)
}
```
## Control Flow
### Conditionals
Use standard Swift `if` statements:
```swift
if isLoading {
Text("Loading...")
} else {
Text("Loaded!")
}
```
### Optional Values
Handle optional views:
```swift
if let name = userName {
Text("Hello, \(name)")
} else {
Text("Not logged in")
}
```
## The ViewBuilder Result Builder
`@ViewBuilder` is a result builder that enables the declarative syntax:
```swift
@ViewBuilder
var content: some View {
if condition {
Text("A")
} else {
Text("B")
}
Text("C")
}
```
It supports:
- Up to 10 children without nesting
- `if/else if/else` conditionals
- `if let` optional unwrapping
- Arrays and `ForEach`
- Nested result builders
## Type Erasure with AnyView
When you need to return different view types, use `AnyView`:
```swift
func makeView(condition: Bool) -> AnyView {
if condition {
return AnyView(Text("A"))
} else {
return AnyView(VStack { Text("B") })
}
}
```
> Note: Use `AnyView` sparingly—prefer `@ViewBuilder` when possible.
## Custom Views
Create your own reusable components:
```swift
struct CustomButton: View {
let label: String
let action: () -> Void
var body: some View {
Button(label, action: action)
.padding(1)
.border(.rounded)
}
}
// Usage
CustomButton(label: "Click me", action: {
print("Clicked")
})
```
## View Composition Pattern
Build complex UIs by composing smaller views:
```swift
struct ContentView: View {
var body: some View {
VStack(spacing: 1) {
HeaderView()
BodyView()
FooterView()
}
}
}
struct HeaderView: View {
var body: some View {
Text("Header").bold()
}
}
struct BodyView: View {
var body: some View {
Text("Content").padding(1)
}
}
struct FooterView: View {
var body: some View {
Text("Footer")
}
}
```
## View Lifetime
Views are value types—they're created, rendered, and discarded. They don't have persistent storage. Use `@State` for state that persists across renders:
```swift
struct Counter: View {
@State var count: Int = 0
var body: some View {
VStack {
Text("Count: \(count)")
Button("Increment") { count += 1 }
}
}
}
```
## Related Topics
- ``View``
- ``@ViewBuilder``
- ``VStack``
- ``HStack``
- ``ZStack``
- <doc:StateManagement>
- <doc:Modifiers>
-18
View File
@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>TUIKit</string>
<key>CFBundleIdentifier</key>
<string>com.anthropic.tuikit.documentation</string>
<key>CFBundleVersion</key>
<string>0.1.0</string>
<key>CFBundlePackageType</key>
<string>dext</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2026 Anthropic. All rights reserved.</string>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.documentation.extension</string>
</dict>
</plist>
-124
View File
@@ -1,124 +0,0 @@
# ``TUIKit``
Build beautiful, interactive terminal user interfaces in Swift.
## Overview
TUIKit is a modern Swift framework for creating sophisticated terminal user interfaces (TUIs) on macOS and Linux. It provides a declarative, SwiftUI-like API with support for themes, styling, focus management, and interactive components.
### Key Features
- **Declarative UI**: Build interfaces using Swift's result builders and view composition
- **5 Appearance Styles**: line, rounded, doubleLine, heavy, and block rendering modes
- **4 Phosphor Themes**: Green, Amber, White, and Red with customizable colors
- **Rich Components**: Text, Button, Menu, Alert, Dialog, Card, Panel, and more
- **Focus Management**: Tab/Shift+Tab navigation with keyboard shortcuts
- **State Management**: `@State`, `@Environment`, `@AppStorage`, `@SceneStorage` property wrappers
- **No Dependencies**: Pure Swift implementation for macOS 10.15+ and Linux
## Getting Started
Create your first TUIKit app in minutes:
```swift
import TUIKit
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
VStack(spacing: 1) {
Text("Welcome to TUIKit!")
.bold()
.foregroundColor(.theme.accent)
Spacer()
Button("Press me") {
print("Button pressed!")
}
Spacer()
}
.padding()
}
}
}
```
Run with: `swift run`
## Topics
### Essentials
- ``View``
- ``App``
- ``Scene``
- ``@main``
### Building Views
- <doc:ViewHierarchy>
- <doc:GettingStarted>
- ``VStack``
- ``HStack``
- ``ZStack``
- ``ForEach``
### Interactive Components
- ``Button``
- ``Menu``
- ``Alert``
- ``Dialog``
- ``Text``
### Styling & Appearance
- <doc:Theming>
- <doc:Appearance>
- ``Color``
- ``Theme``
- ``Appearance``
### Layout & Modifiers
- <doc:Modifiers>
- ``View/padding(_:)-19gu9``
- ``View/frame(width:height:alignment:)``
- ``View/border(_:style:)-4xzvw``
### State Management
- <doc:StateManagement>
- ``State``
- ``Binding``
- ``@Environment``
- ``@AppStorage``
### Advanced Topics
- <doc:Focus>
- <doc:Architecture>
- <doc:Rendering>
- ``FocusManager``
- ``KeyEvent``
### Examples
- <doc:BuildYourFirstApp>
- <doc:BuildInteractiveMenu>
- <doc:BuildThemableUI>
## Resources
- [GitHub Repository](https://github.com/anthropics/SwiftTUI)
- [Example Application](https://github.com/anthropics/SwiftTUI/tree/main/Sources/TUIKitExample)
- [Issue Tracker](https://github.com/anthropics/SwiftTUI/issues)
## Minimum Requirements
- Swift 6.0 or later
- macOS 10.15+ or Linux (glibc)
- Terminal with ANSI color support (256 colors or better)
@@ -1,375 +0,0 @@
# Building an Interactive Menu
Create a navigation menu with keyboard shortcuts and status bar hints.
@Intro(title: "Build an Interactive Menu App") {
Learn how to create a functional menu system with keyboard navigation,
selection handling, and status bar integration.
You'll build a simple settings menu that demonstrates focus management,
keyboard events, and status bar items.
}
## Overview
In this tutorial, you'll create a menu-driven application featuring:
- `Menu` component for selection
- Keyboard shortcut handling
- Status bar with hints
- Page navigation patterns
@Section(title: "Create the Menu Component") {
@ContentAndMedia {
Start with a basic menu that displays options and tracks selection.
}
@Steps {
@Step {
Create your app with a `Menu`:
```swift
import TUIKit
@main
struct MenuApp: App {
@State private var selectedOption: String = "home"
var body: some Scene {
WindowGroup {
VStack(spacing: 2) {
Text("Main Menu")
.bold()
.foregroundColor(.theme.accent)
Spacer()
Menu(
items: [
MenuItem("📄 View Profile", id: "profile"),
MenuItem("⚙️ Settings", id: "settings"),
MenuItem("💾 Save Data", id: "save"),
MenuItem("❌ Exit", id: "exit")
],
selection: $selectedOption
)
Spacer()
Text("Selected: \(selectedOption)")
.foregroundColor(.theme.foregroundSecondary)
}
.padding()
}
}
}
```
- `Menu` creates an interactive selectable list
- `$selectedOption` creates a two-way binding
- Use Tab/Arrow keys to navigate
- Press Enter to confirm selection
}
@Step {
Run the app:
```bash
swift run
```
Test navigating with Tab, arrow keys, and Enter.
The "Selected" text updates as you navigate.
}
}
}
@Section(title: "Add Page Navigation") {
@ContentAndMedia {
Create different pages that show based on menu selection.
}
@Steps {
@Step {
Add conditional pages:
```swift
@main
struct MenuApp: App {
@State private var selectedOption: String = "home"
var body: some Scene {
WindowGroup {
if selectedOption == "exit" {
VStack {
Text("Exiting...")
}
} else {
VStack(spacing: 2) {
Text("Main Menu")
.bold()
.foregroundColor(.theme.accent)
Spacer()
Menu(
items: [
MenuItem("📄 View Profile", id: "profile"),
MenuItem("⚙️ Settings", id: "settings"),
MenuItem("💾 Save Data", id: "save"),
MenuItem("❌ Exit", id: "exit")
],
selection: $selectedOption
)
Spacer()
currentPageContent
}
.padding()
}
}
}
@ViewBuilder
var currentPageContent: some View {
switch selectedOption {
case "profile":
VStack(spacing: 1) {
Text("📄 Profile Information").bold()
Text("Name: John Doe")
Text("Role: Developer")
}
case "settings":
VStack(spacing: 1) {
Text("⚙️ Application Settings").bold()
Text("Theme: Green")
Text("Language: English")
}
case "save":
Text("✓ Data saved successfully!")
.foregroundColor(.theme.success)
default:
Text("Select an option above")
}
}
}
```
The `currentPageContent` computed property shows different content
based on the selected menu item.
}
@Step {
Run and test navigation:
```bash
swift run
```
Navigate to each menu item and see the page content change.
}
}
}
@Section(title: "Add Status Bar Hints") {
@ContentAndMedia {
Add a status bar at the bottom with helpful keyboard hints.
}
@Steps {
@Step {
Add status bar items:
```swift
@main
struct MenuApp: App {
@State private var selectedOption: String = "home"
var body: some Scene {
WindowGroup {
if selectedOption == "exit" {
VStack {
Text("Exiting...")
}
} else {
VStack(spacing: 2) {
Text("Main Menu")
.bold()
.foregroundColor(.theme.accent)
Spacer()
Menu(
items: [
MenuItem("📄 View Profile", id: "profile"),
MenuItem("⚙️ Settings", id: "settings"),
MenuItem("💾 Save Data", id: "save"),
MenuItem("❌ Exit", id: "exit")
],
selection: $selectedOption
)
Spacer()
currentPageContent
}
.padding()
}
.statusBarItems {
StatusBarItem(
label: "Select",
shortcut: Shortcut.enter,
action: { }
)
StatusBarItem(
label: "Theme",
shortcut: Shortcut.letter("t"),
action: { }
)
StatusBarItem(
label: "Help",
shortcut: Shortcut.letter("?"),
action: { }
)
StatusBarItem(
label: "Quit",
shortcut: Shortcut.letter("q"),
action: { }
)
}
}
}
@ViewBuilder
var currentPageContent: some View {
switch selectedOption {
case "profile":
VStack(spacing: 1) {
Text("📄 Profile Information").bold()
Text("Name: John Doe")
Text("Role: Developer")
}
case "settings":
VStack(spacing: 1) {
Text("⚙️ Application Settings").bold()
Text("Theme: Green")
Text("Language: English")
}
case "save":
Text("✓ Data saved successfully!")
.foregroundColor(.theme.success)
default:
Text("Select an option above")
}
}
}
```
`statusBarItems` adds a bottom status bar with keyboard shortcuts.
}
@Step {
Run the app:
```bash
swift run
```
The status bar appears at the bottom showing available shortcuts.
}
}
}
@Section(title: "Add Keyboard Shortcuts") {
@ContentAndMedia {
Handle custom keyboard shortcuts to navigate directly to menu items.
}
@Steps {
@Step {
Add keyboard event handling:
```swift
.onKeyPress { event in
switch event.key {
case .character("1"):
selectedOption = "profile"
return true
case .character("2"):
selectedOption = "settings"
return true
case .character("3"):
selectedOption = "save"
return true
case .character("e"):
selectedOption = "exit"
return true
default:
return false
}
}
```
Add this modifier to your main `VStack`. Now users can:
- Press `1` to go to Profile
- Press `2` to go to Settings
- Press `3` to Save
- Press `e` to Exit
}
@Step {
Update the status bar to show these shortcuts:
```swift
.statusBarItems {
StatusBarItem(
label: "Profile",
shortcut: Shortcut.digit("1"),
action: { }
)
StatusBarItem(
label: "Settings",
shortcut: Shortcut.digit("2"),
action: { }
)
StatusBarItem(
label: "Save",
shortcut: Shortcut.digit("3"),
action: { }
)
StatusBarItem(
label: "Exit",
shortcut: Shortcut.letter("e"),
action: { }
)
}
```
}
@Step {
Test your shortcuts:
```bash
swift run
```
Press number keys to jump directly to menu items.
}
}
}
## Next Steps
You've created an interactive menu-driven application!
- Learn about <doc:Focus> for advanced focus management
- Explore <doc:StateManagement> for more complex state patterns
- Try building a <doc:BuildThemableUI> with theme switching
- Check out <doc:Appearance> for custom styling
-421
View File
@@ -1,421 +0,0 @@
# Building a Themable UI
Create an application with dynamic theme switching and persistence.
@Intro(title: "Build a Themable App") {
Learn how to integrate TUIKit's theming system into your application,
allowing users to switch between themes and persist their preference.
You'll work with the theme environment, theme manager, and storage to
create a professional themable application.
}
## Overview
In this tutorial, you'll create an app that features:
- Theme environment integration
- Dynamic theme switching
- Persisted theme preference
- Visual theme selection UI
@Section(title: "Set Up Theme Storage") {
@ContentAndMedia {
Use `@AppStorage` to remember the user's theme choice across sessions.
}
@Steps {
@Step {
Create an app that stores the selected theme:
```swift
import TUIKit
@main
struct ThemableApp: App {
@AppStorage("selectedTheme") var selectedThemeName: String = "green"
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.theme, themeForName(selectedThemeName))
}
}
func themeForName(_ name: String) -> Theme {
switch name {
case "amber":
return AmberPhosphorTheme()
case "white":
return WhitePhosphorTheme()
case "red":
return RedPhosphorTheme()
default:
return GreenPhosphorTheme()
}
}
}
struct ContentView: View {
var body: some View {
VStack(spacing: 2) {
Text("Themable Application")
.bold()
.foregroundColor(.theme.accent)
Spacer()
Text("Select a theme to customize the appearance")
.foregroundColor(.theme.foregroundSecondary)
Spacer()
}
.padding()
}
}
```
`@AppStorage("selectedTheme")` automatically persists the theme choice.
When the app restarts, it loads the saved theme.
}
@Step {
Run your app:
```bash
swift run
```
The app launches with the default Green theme.
}
}
}
@Section(title: "Create Theme Selection UI") {
@ContentAndMedia {
Display the 4 available themes and let users select one.
}
@Steps {
@Step {
Add a theme menu:
```swift
@main
struct ThemableApp: App {
@AppStorage("selectedTheme") var selectedThemeName: String = "green"
var body: some Scene {
WindowGroup {
ContentView(selectedThemeName: $selectedThemeName)
.environment(\.theme, themeForName(selectedThemeName))
}
}
func themeForName(_ name: String) -> Theme {
// ... same as before
}
}
struct ContentView: View {
@Binding var selectedThemeName: String
let themes = [
("green", "🟢 Green (Default)"),
("amber", "🟡 Amber"),
("white", "⚪ White"),
("red", "🔴 Red")
]
var body: some View {
VStack(spacing: 2) {
Text("Themable Application")
.bold()
.foregroundColor(.theme.accent)
Spacer()
Text("Select a theme:")
.bold()
Menu(
items: themes.map { id, label in
MenuItem(label, id: id)
},
selection: $selectedThemeName
)
Spacer()
Text("Current: \(themeName(selectedThemeName))")
.foregroundColor(.theme.foregroundSecondary)
Spacer()
}
.padding()
}
func themeName(_ id: String) -> String {
themes.first(where: { $0.0 == id })?.1 ?? id
}
}
```
Pass `$selectedThemeName` as a binding to allow the menu to change it.
The environment automatically updates because it depends on this value.
}
@Step {
Test theme switching:
```bash
swift run
```
Use Tab/Arrow keys to select different themes.
Notice the colors change immediately!
}
}
}
@Section(title: "Display Theme Colors") {
@ContentAndMedia {
Show a visual preview of the current theme's colors.
}
@Steps {
@Step {
Add a color preview:
```swift
struct ContentView: View {
@Binding var selectedThemeName: String
@Environment(\.theme) var theme
let themes = [
("green", "🟢 Green (Default)"),
("amber", "🟡 Amber"),
("white", "⚪ White"),
("red", "🔴 Red")
]
var body: some View {
VStack(spacing: 2) {
Text("Themable Application")
.bold()
.foregroundColor(.theme.accent)
Spacer()
Text("Select a theme:").bold()
Menu(
items: themes.map { id, label in
MenuItem(label, id: id)
},
selection: $selectedThemeName
)
Spacer()
// Color preview box
VStack(spacing: 1) {
Text("Theme Colors")
.bold()
HStack(spacing: 1) {
Text(" ").background(theme.foreground)
Text(" ").background(theme.accent)
Text(" ").background(theme.border)
Text(" ").background(theme.warning)
}
Text("Foreground | Accent | Border | Warning")
.foregroundColor(.theme.foregroundSecondary)
}
.padding(1)
.border(.rounded)
Spacer()
}
.padding()
}
func themeName(_ id: String) -> String {
themes.first(where: { $0.0 == id })?.1 ?? id
}
}
```
`@Environment(\.theme)` gives access to the current theme.
Use `theme.foreground`, `theme.accent`, etc. to access colors.
}
@Step {
Run the app:
```bash
swift run
```
Switch themes and see the color preview update.
}
}
}
@Section(title: "Add Theme Shortcuts and Status Bar") {
@ContentAndMedia {
Let users cycle themes quickly with keyboard shortcuts.
}
@Steps {
@Step {
Add quick theme cycling:
```swift
struct ContentView: View {
@Binding var selectedThemeName: String
@Environment(\.theme) var theme
let themes = [
("green", "🟢 Green (Default)"),
("amber", "🟡 Amber"),
("white", "⚪ White"),
("red", "🔴 Red")
]
let themeIds = ["green", "amber", "white", "red"]
var body: some View {
VStack(spacing: 2) {
// ... menu UI as before ...
Spacer()
}
.padding()
.onKeyPress { event in
if event.key == .character("t") {
// Cycle to next theme
if let currentIndex = themeIds.firstIndex(of: selectedThemeName) {
let nextIndex = (currentIndex + 1) % themeIds.count
selectedThemeName = themeIds[nextIndex]
}
return true
}
return false
}
.statusBarItems {
StatusBarItem(
label: "Cycle Theme",
shortcut: Shortcut.letter("t"),
action: { }
)
StatusBarItem(
label: "Help",
shortcut: Shortcut.letter("?"),
action: { }
)
StatusBarItem(
label: "Quit",
shortcut: Shortcut.letter("q"),
action: { }
)
}
}
func themeName(_ id: String) -> String {
themes.first(where: { $0.0 == id })?.1 ?? id
}
}
```
Now users can press `t` to quickly cycle through themes.
}
@Step {
Test theme cycling:
```bash
swift run
```
Press `t` repeatedly to cycle through all 4 themes.
The selection updates and the preview colors change.
}
}
}
@Section(title: "Enhance with Appearance Switching") {
@ContentAndMedia {
Add appearance style switching alongside theme switching.
}
@Steps {
@Step {
Add appearance cycling:
```swift
@main
struct ThemableApp: App {
@AppStorage("selectedTheme") var selectedThemeName: String = "green"
@AppStorage("selectedAppearance") var selectedAppearance: String = "rounded"
var body: some Scene {
WindowGroup {
ContentView(
selectedThemeName: $selectedThemeName,
selectedAppearance: $selectedAppearance
)
.environment(\.theme, themeForName(selectedThemeName))
.environment(\.appearance, appearanceForName(selectedAppearance))
}
}
func themeForName(_ name: String) -> Theme {
// ... existing code ...
}
func appearanceForName(_ name: String) -> Appearance {
switch name {
case "line":
return .line
case "doubled":
return .doubleLine
case "heavy":
return .heavy
case "block":
return .block
default:
return .rounded
}
}
}
```
Now users can customize both theme AND appearance style!
}
@Step {
The changes are automatically persisted with `@AppStorage`.
Run the app:
```bash
swift run
```
Select a theme and appearance, exit with `q`, and run again.
Your selection is remembered!
}
}
}
## Next Steps
Congratulations! You've built a fully themed, customizable application.
- Learn more about <doc:Theming> for creating custom themes
- Explore <doc:Appearance> for structural styles
- See <doc:StateManagement> for advanced state patterns
- Check the <doc:Architecture> overview for deeper understanding
-270
View File
@@ -1,270 +0,0 @@
# Building Your First App
Create a simple counter application to learn TUIKit basics.
@Intro(title: "Create Your First TUIKit App") {
Learn the fundamentals of building a terminal user interface with TUIKit
by creating a simple counter application.
You'll learn how to set up an `@main` app, use `@State` for local state,
add interactive buttons, and use basic layout with `VStack` and `HStack`.
}
## Overview
In this tutorial, you'll build a working counter app with increment/decrement buttons.
This will teach you:
- Creating an app with the `@main` attribute
- Using `VStack` and `HStack` for layout
- Handling button taps with `@State`
- Running and testing your app
@Section(title: "Create the App Entry Point") {
@ContentAndMedia {
Every TUIKit app needs an entry point decorated with `@main`.
This tells Swift to use your app as the entry point for the program.
}
@Steps {
@Step {
Create a new file called `main.swift` in your project:
```swift
import TUIKit
@main
struct CounterApp: App {
var body: some Scene {
WindowGroup {
Text("Hello, TUIKit!")
}
}
}
```
The `@main` attribute marks this as the app entry point.
`WindowGroup` represents the main window of your terminal app.
}
@Step {
Run your app with:
```bash
swift run
```
You should see "Hello, TUIKit!" displayed in the terminal.
}
}
}
@Section(title: "Add Layout and Text") {
@ContentAndMedia {
Now let's organize content with `VStack` (vertical layout).
We'll add a title and multiple text lines.
}
@Steps {
@Step {
Modify the `body` to use `VStack`:
```swift
@main
struct CounterApp: App {
var body: some Scene {
WindowGroup {
VStack(spacing: 1) {
Text("Counter App")
.bold()
Text("Simple counter to learn TUIKit")
.foregroundColor(.theme.foregroundSecondary)
Spacer()
Text("Current count: 0")
Spacer()
}
.padding()
}
}
}
```
- `VStack(spacing: 1)` arranges content vertically with 1-unit spacing
- `.bold()` makes the title bold
- `.foregroundColor()` colors text
- `Spacer()` creates flexible vertical space
- `.padding()` adds space around all edges
}
@Step {
Run the app again:
```bash
swift run
```
Now you should see a nicely formatted display with title,
description, and spacing.
}
}
}
@Section(title: "Add Interactive State") {
@ContentAndMedia {
Use `@State` to track the counter value and re-render when it changes.
This makes your app interactive!
}
@Steps {
@Step {
Add a `@State` property for the counter:
```swift
@main
struct CounterApp: App {
@State private var count: Int = 0
var body: some Scene {
WindowGroup {
VStack(spacing: 1) {
Text("Counter App")
.bold()
Text("Simple counter to learn TUIKit")
.foregroundColor(.theme.foregroundSecondary)
Spacer()
Text("Current count: \(count)")
Spacer()
}
.padding()
}
}
}
```
The `@State` property wrapper stores local state. When `count` changes,
the view automatically re-renders.
}
}
}
@Section(title: "Add Buttons") {
@ContentAndMedia {
Now add buttons to increment and decrement the counter.
Use `HStack` to arrange them horizontally.
}
@Steps {
@Step {
Add buttons using `HStack`:
```swift
@main
struct CounterApp: App {
@State private var count: Int = 0
var body: some Scene {
WindowGroup {
VStack(spacing: 1) {
Text("Counter App")
.bold()
Text("Simple counter to learn TUIKit")
.foregroundColor(.theme.foregroundSecondary)
Spacer()
Text("Current count: \(count)")
HStack(spacing: 2) {
Button("Decrement") { count -= 1 }
Button("Increment") { count += 1 }
}
Spacer()
Text("Press 'q' to quit")
.foregroundColor(.theme.foregroundTertiary)
}
.padding()
}
}
}
```
- `HStack(spacing: 2)` arranges buttons horizontally
- `Button(label) { action }` creates a clickable button
- The closure after the label runs when the button is pressed
}
@Step {
Run your app:
```bash
swift run
```
Now use Tab to navigate to the buttons and press Enter to increment/decrement.
The counter value updates in real-time!
}
}
}
@Section(title: "Test and Iterate") {
@ContentAndMedia {
Test your counter app and try making improvements.
}
@Steps {
@Step {
Test the following interactions:
- Press `Tab` to move focus to the next button
- Press `Shift+Tab` to move focus backward
- Press `Enter` when a button is focused to activate it
- Watch the counter update
- Press `q` to quit the app
- Press `t` to cycle through themes
- Press `a` to cycle through appearance styles
}
@Step {
Try these enhancements:
Add a reset button:
```swift
HStack(spacing: 2) {
Button("Decrement") { count = max(0, count - 1) }
Button("Reset") { count = 0 }
Button("Increment") { count += 1 }
}
```
Or add a border around the counter:
```swift
Text("Current count: \(count)")
.bold()
.padding(1)
.border(.rounded)
```
}
}
}
## Next Steps
Congratulations! You've built your first TUIKit app.
- Learn more about <doc:StateManagement> for complex state scenarios
- Explore <doc:Theming> to customize colors
- Try building an interactive <doc:BuildInteractiveMenu>
- Check out <doc:Modifiers> for more styling options
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
{"hierarchy":{"paths":[["doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit"]]},"identifier":{"url":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/BuildInteractiveMenu","interfaceLanguage":"swift"},"metadata":{"role":"article","roleHeading":"Article","title":"Building an Interactive Menu"},"schemaVersion":{"minor":3,"patch":0,"major":0},"kind":"article","primaryContentSections":[{"kind":"content","content":[{"anchor":"Overview","text":"Overview","level":2,"type":"heading"},{"inlineContent":[{"type":"text","text":"In this tutorial, you’ll create a menu-driven application featuring:"}],"type":"paragraph"},{"items":[{"content":[{"type":"paragraph","inlineContent":[{"type":"codeVoice","code":"Menu"},{"text":" component for selection","type":"text"}]}]},{"content":[{"inlineContent":[{"text":"Keyboard shortcut handling","type":"text"}],"type":"paragraph"}]},{"content":[{"type":"paragraph","inlineContent":[{"text":"Status bar with hints","type":"text"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"Page navigation patterns"}]}]}],"type":"unorderedList"},{"anchor":"Next-Steps","text":"Next Steps","level":2,"type":"heading"},{"inlineContent":[{"type":"text","text":"You’ve created an interactive menu-driven application!"}],"type":"paragraph"},{"items":[{"content":[{"inlineContent":[{"text":"Learn about ","type":"text"},{"type":"reference","isActive":true,"identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Focus"},{"text":" for advanced focus management","type":"text"}],"type":"paragraph"}]},{"content":[{"type":"paragraph","inlineContent":[{"text":"Explore ","type":"text"},{"identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/StateManagement","isActive":true,"type":"reference"},{"text":" for more complex state patterns","type":"text"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"Try building a "},{"identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/BuildThemableUI","type":"reference","isActive":true},{"type":"text","text":" with theme switching"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"Check out "},{"identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Appearance","type":"reference","isActive":true},{"type":"text","text":" for custom styling"}]}]}],"type":"unorderedList"}]}],"sections":[],"abstract":[{"type":"text","text":"Create a navigation menu with keyboard shortcuts and status bar hints."}],"references":{"doc://com.anthropic.tuikit.documentation/documentation/TUIKit":{"role":"collection","type":"topic","kind":"article","abstract":[],"title":"TUIKit","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit","url":"\/documentation\/tuikit"},"doc://com.anthropic.tuikit.documentation/documentation/TUIKit/BuildThemableUI":{"abstract":[{"type":"text","text":"Create an application with dynamic theme switching and persistence."}],"type":"topic","title":"Building a Themable UI","role":"article","url":"\/documentation\/tuikit\/buildthemableui","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/BuildThemableUI","kind":"article"},"doc://com.anthropic.tuikit.documentation/documentation/TUIKit/Appearance":{"url":"\/documentation\/tuikit\/appearance","title":"Appearance System","kind":"article","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Appearance","type":"topic","abstract":[{"text":"Learn about the 5 structural appearance styles for rendering borders and containers.","type":"text"}],"role":"article"},"doc://com.anthropic.tuikit.documentation/documentation/TUIKit/Focus":{"abstract":[{"text":"Understand how keyboard navigation and focus works in TUIKit.","type":"text"}],"type":"topic","role":"article","title":"Focus Management","url":"\/documentation\/tuikit\/focus","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Focus","kind":"article"},"doc://com.anthropic.tuikit.documentation/documentation/TUIKit/StateManagement":{"identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/StateManagement","kind":"article","url":"\/documentation\/tuikit\/statemanagement","abstract":[{"type":"text","text":"Learn how to manage application state and data flow in TUIKit."}],"title":"State Management","role":"article","type":"topic"}}}
@@ -1 +0,0 @@
{"hierarchy":{"paths":[["doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit"]]},"schemaVersion":{"minor":3,"major":0,"patch":0},"sections":[],"identifier":{"url":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/BuildThemableUI","interfaceLanguage":"swift"},"kind":"article","abstract":[{"type":"text","text":"Create an application with dynamic theme switching and persistence."}],"metadata":{"title":"Building a Themable UI","roleHeading":"Article","role":"article"},"primaryContentSections":[{"content":[{"type":"heading","text":"Overview","anchor":"Overview","level":2},{"type":"paragraph","inlineContent":[{"type":"text","text":"In this tutorial, you’ll create an app that features:"}]},{"type":"unorderedList","items":[{"content":[{"type":"paragraph","inlineContent":[{"text":"Theme environment integration","type":"text"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"text":"Dynamic theme switching","type":"text"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"Persisted theme preference"}]}]},{"content":[{"inlineContent":[{"text":"Visual theme selection UI","type":"text"}],"type":"paragraph"}]}]},{"type":"heading","text":"Next Steps","anchor":"Next-Steps","level":2},{"type":"paragraph","inlineContent":[{"type":"text","text":"Congratulations! You’ve built a fully themed, customizable application."}]},{"type":"unorderedList","items":[{"content":[{"inlineContent":[{"type":"text","text":"Learn more about "},{"identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Theming","type":"reference","isActive":true},{"type":"text","text":" for creating custom themes"}],"type":"paragraph"}]},{"content":[{"inlineContent":[{"text":"Explore ","type":"text"},{"isActive":true,"type":"reference","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Appearance"},{"text":" for structural styles","type":"text"}],"type":"paragraph"}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"See "},{"type":"reference","isActive":true,"identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/StateManagement"},{"type":"text","text":" for advanced state patterns"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"Check the "},{"type":"reference","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Architecture","isActive":true},{"type":"text","text":" overview for deeper understanding"}]}]}]}],"kind":"content"}],"references":{"doc://com.anthropic.tuikit.documentation/documentation/TUIKit/Architecture":{"type":"topic","kind":"article","abstract":[{"type":"text","text":"Understand the architecture and design patterns that power TUIKit."}],"url":"\/documentation\/tuikit\/architecture","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Architecture","title":"Architecture Overview","role":"article"},"doc://com.anthropic.tuikit.documentation/documentation/TUIKit":{"role":"collection","type":"topic","kind":"article","abstract":[],"title":"TUIKit","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit","url":"\/documentation\/tuikit"},"doc://com.anthropic.tuikit.documentation/documentation/TUIKit/Theming":{"title":"Theming System","type":"topic","role":"article","abstract":[{"type":"text","text":"Customize the appearance of your application with TUIKit’s flexible theming system."}],"kind":"article","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Theming","url":"\/documentation\/tuikit\/theming"},"doc://com.anthropic.tuikit.documentation/documentation/TUIKit/Appearance":{"url":"\/documentation\/tuikit\/appearance","title":"Appearance System","kind":"article","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Appearance","type":"topic","abstract":[{"text":"Learn about the 5 structural appearance styles for rendering borders and containers.","type":"text"}],"role":"article"},"doc://com.anthropic.tuikit.documentation/documentation/TUIKit/StateManagement":{"identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/StateManagement","kind":"article","url":"\/documentation\/tuikit\/statemanagement","abstract":[{"type":"text","text":"Learn how to manage application state and data flow in TUIKit."}],"title":"State Management","role":"article","type":"topic"}}}
@@ -1 +0,0 @@
{"hierarchy":{"paths":[["doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit"]]},"kind":"article","metadata":{"title":"Building Your First App","role":"article","roleHeading":"Article"},"primaryContentSections":[{"content":[{"anchor":"Overview","type":"heading","text":"Overview","level":2},{"inlineContent":[{"type":"text","text":"In this tutorial, you’ll build a working counter app with increment\/decrement buttons."},{"type":"text","text":" "},{"type":"text","text":"This will teach you:"}],"type":"paragraph"},{"type":"unorderedList","items":[{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"Creating an app with the "},{"type":"codeVoice","code":"@main"},{"type":"text","text":" attribute"}]}]},{"content":[{"inlineContent":[{"text":"Using ","type":"text"},{"type":"codeVoice","code":"VStack"},{"text":" and ","type":"text"},{"type":"codeVoice","code":"HStack"},{"text":" for layout","type":"text"}],"type":"paragraph"}]},{"content":[{"type":"paragraph","inlineContent":[{"text":"Handling button taps with ","type":"text"},{"code":"@State","type":"codeVoice"}]}]},{"content":[{"inlineContent":[{"type":"text","text":"Running and testing your app"}],"type":"paragraph"}]}]},{"anchor":"Next-Steps","type":"heading","text":"Next Steps","level":2},{"inlineContent":[{"type":"text","text":"Congratulations! You’ve built your first TUIKit app."}],"type":"paragraph"},{"type":"unorderedList","items":[{"content":[{"type":"paragraph","inlineContent":[{"text":"Learn more about ","type":"text"},{"identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/StateManagement","type":"reference","isActive":true},{"text":" for complex state scenarios","type":"text"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"text":"Explore ","type":"text"},{"identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Theming","type":"reference","isActive":true},{"text":" to customize colors","type":"text"}]}]},{"content":[{"type":"paragraph","inlineContent":[{"type":"text","text":"Try building an interactive "},{"type":"reference","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/BuildInteractiveMenu","isActive":true}]}]},{"content":[{"type":"paragraph","inlineContent":[{"text":"Check out ","type":"text"},{"isActive":true,"identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Modifiers","type":"reference"},{"text":" for more styling options","type":"text"}]}]}]}],"kind":"content"}],"schemaVersion":{"major":0,"minor":3,"patch":0},"abstract":[{"type":"text","text":"Create a simple counter application to learn TUIKit basics."}],"identifier":{"interfaceLanguage":"swift","url":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/BuildYourFirstApp"},"sections":[],"references":{"doc://com.anthropic.tuikit.documentation/documentation/TUIKit/StateManagement":{"identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/StateManagement","kind":"article","url":"\/documentation\/tuikit\/statemanagement","abstract":[{"type":"text","text":"Learn how to manage application state and data flow in TUIKit."}],"title":"State Management","role":"article","type":"topic"},"doc://com.anthropic.tuikit.documentation/documentation/TUIKit/Modifiers":{"title":"View Modifiers","type":"topic","role":"article","abstract":[{"type":"text","text":"Learn how to use modifiers to customize the appearance and behavior of views."}],"kind":"article","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Modifiers","url":"\/documentation\/tuikit\/modifiers"},"doc://com.anthropic.tuikit.documentation/documentation/TUIKit/Theming":{"title":"Theming System","type":"topic","role":"article","abstract":[{"type":"text","text":"Customize the appearance of your application with TUIKit’s flexible theming system."}],"kind":"article","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/Theming","url":"\/documentation\/tuikit\/theming"},"doc://com.anthropic.tuikit.documentation/documentation/TUIKit":{"role":"collection","type":"topic","kind":"article","abstract":[],"title":"TUIKit","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit","url":"\/documentation\/tuikit"},"doc://com.anthropic.tuikit.documentation/documentation/TUIKit/BuildInteractiveMenu":{"title":"Building an Interactive Menu","abstract":[{"type":"text","text":"Create a navigation menu with keyboard shortcuts and status bar hints."}],"role":"article","kind":"article","url":"\/documentation\/tuikit\/buildinteractivemenu","identifier":"doc:\/\/com.anthropic.tuikit.documentation\/documentation\/TUIKit\/BuildInteractiveMenu","type":"topic"}}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

@@ -1 +0,0 @@
<!doctype html><html lang="en-US" class="no-js"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><link rel="icon" href="/favicon.ico"><link rel="mask-icon" href="/favicon.svg" color="#333333"><title>Documentation</title><script>var baseUrl = "/"</script><script defer="defer" src="/js/chunk-vendors.bdb7cbba.js"></script><script defer="defer" src="/js/index.d2f6f6a9.js"></script><link href="/css/index.3a335429.css" rel="stylesheet"></head><body data-color-scheme="auto"><noscript><style>.noscript{font-family:"SF Pro Display","SF Pro Icons","Helvetica Neue",Helvetica,Arial,sans-serif;margin:92px auto 140px auto;text-align:center;width:980px}.noscript-title{color:#111;font-size:48px;font-weight:600;letter-spacing:-.003em;line-height:1.08365;margin:0 auto 54px auto;width:502px}@media only screen and (max-width:1068px){.noscript{margin:90px auto 120px auto;width:692px}.noscript-title{font-size:40px;letter-spacing:0;line-height:1.1;margin:0 auto 45px auto;width:420px}}@media only screen and (max-width:735px){.noscript{margin:45px auto 60px auto;width:87.5%}.noscript-title{font-size:32px;letter-spacing:.004em;line-height:1.125;margin:0 auto 35px auto;max-width:330px;width:auto}}#loading-placeholder{display:none}</style><div class="noscript"><h1 class="noscript-title">This page requires JavaScript.</h1><p>Please turn on JavaScript in your browser and refresh the page to view its content.</p></div></noscript><div id="app"></div></body></html>
@@ -1 +0,0 @@
<!doctype html><html lang="en-US" class="no-js"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><link rel="icon" href="/favicon.ico"><link rel="mask-icon" href="/favicon.svg" color="#333333"><title>Documentation</title><script>var baseUrl = "/"</script><script defer="defer" src="/js/chunk-vendors.bdb7cbba.js"></script><script defer="defer" src="/js/index.d2f6f6a9.js"></script><link href="/css/index.3a335429.css" rel="stylesheet"></head><body data-color-scheme="auto"><noscript><style>.noscript{font-family:"SF Pro Display","SF Pro Icons","Helvetica Neue",Helvetica,Arial,sans-serif;margin:92px auto 140px auto;text-align:center;width:980px}.noscript-title{color:#111;font-size:48px;font-weight:600;letter-spacing:-.003em;line-height:1.08365;margin:0 auto 54px auto;width:502px}@media only screen and (max-width:1068px){.noscript{margin:90px auto 120px auto;width:692px}.noscript-title{font-size:40px;letter-spacing:0;line-height:1.1;margin:0 auto 45px auto;width:420px}}@media only screen and (max-width:735px){.noscript{margin:45px auto 60px auto;width:87.5%}.noscript-title{font-size:32px;letter-spacing:.004em;line-height:1.125;margin:0 auto 35px auto;max-width:330px;width:auto}}#loading-placeholder{display:none}</style><div class="noscript"><h1 class="noscript-title">This page requires JavaScript.</h1><p>Please turn on JavaScript in your browser and refresh the page to view its content.</p></div></noscript><div id="app"></div></body></html>
@@ -1 +0,0 @@
<!doctype html><html lang="en-US" class="no-js"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><link rel="icon" href="/favicon.ico"><link rel="mask-icon" href="/favicon.svg" color="#333333"><title>Documentation</title><script>var baseUrl = "/"</script><script defer="defer" src="/js/chunk-vendors.bdb7cbba.js"></script><script defer="defer" src="/js/index.d2f6f6a9.js"></script><link href="/css/index.3a335429.css" rel="stylesheet"></head><body data-color-scheme="auto"><noscript><style>.noscript{font-family:"SF Pro Display","SF Pro Icons","Helvetica Neue",Helvetica,Arial,sans-serif;margin:92px auto 140px auto;text-align:center;width:980px}.noscript-title{color:#111;font-size:48px;font-weight:600;letter-spacing:-.003em;line-height:1.08365;margin:0 auto 54px auto;width:502px}@media only screen and (max-width:1068px){.noscript{margin:90px auto 120px auto;width:692px}.noscript-title{font-size:40px;letter-spacing:0;line-height:1.1;margin:0 auto 45px auto;width:420px}}@media only screen and (max-width:735px){.noscript{margin:45px auto 60px auto;width:87.5%}.noscript-title{font-size:32px;letter-spacing:.004em;line-height:1.125;margin:0 auto 35px auto;max-width:330px;width:auto}}#loading-placeholder{display:none}</style><div class="noscript"><h1 class="noscript-title">This page requires JavaScript.</h1><p>Please turn on JavaScript in your browser and refresh the page to view its content.</p></div></noscript><div id="app"></div></body></html>
@@ -1 +0,0 @@
<!doctype html><html lang="en-US" class="no-js"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><link rel="icon" href="/favicon.ico"><link rel="mask-icon" href="/favicon.svg" color="#333333"><title>Documentation</title><script>var baseUrl = "/"</script><script defer="defer" src="/js/chunk-vendors.bdb7cbba.js"></script><script defer="defer" src="/js/index.d2f6f6a9.js"></script><link href="/css/index.3a335429.css" rel="stylesheet"></head><body data-color-scheme="auto"><noscript><style>.noscript{font-family:"SF Pro Display","SF Pro Icons","Helvetica Neue",Helvetica,Arial,sans-serif;margin:92px auto 140px auto;text-align:center;width:980px}.noscript-title{color:#111;font-size:48px;font-weight:600;letter-spacing:-.003em;line-height:1.08365;margin:0 auto 54px auto;width:502px}@media only screen and (max-width:1068px){.noscript{margin:90px auto 120px auto;width:692px}.noscript-title{font-size:40px;letter-spacing:0;line-height:1.1;margin:0 auto 45px auto;width:420px}}@media only screen and (max-width:735px){.noscript{margin:45px auto 60px auto;width:87.5%}.noscript-title{font-size:32px;letter-spacing:.004em;line-height:1.125;margin:0 auto 35px auto;max-width:330px;width:auto}}#loading-placeholder{display:none}</style><div class="noscript"><h1 class="noscript-title">This page requires JavaScript.</h1><p>Please turn on JavaScript in your browser and refresh the page to view its content.</p></div></noscript><div id="app"></div></body></html>
@@ -1 +0,0 @@
<!doctype html><html lang="en-US" class="no-js"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><link rel="icon" href="/favicon.ico"><link rel="mask-icon" href="/favicon.svg" color="#333333"><title>Documentation</title><script>var baseUrl = "/"</script><script defer="defer" src="/js/chunk-vendors.bdb7cbba.js"></script><script defer="defer" src="/js/index.d2f6f6a9.js"></script><link href="/css/index.3a335429.css" rel="stylesheet"></head><body data-color-scheme="auto"><noscript><style>.noscript{font-family:"SF Pro Display","SF Pro Icons","Helvetica Neue",Helvetica,Arial,sans-serif;margin:92px auto 140px auto;text-align:center;width:980px}.noscript-title{color:#111;font-size:48px;font-weight:600;letter-spacing:-.003em;line-height:1.08365;margin:0 auto 54px auto;width:502px}@media only screen and (max-width:1068px){.noscript{margin:90px auto 120px auto;width:692px}.noscript-title{font-size:40px;letter-spacing:0;line-height:1.1;margin:0 auto 45px auto;width:420px}}@media only screen and (max-width:735px){.noscript{margin:45px auto 60px auto;width:87.5%}.noscript-title{font-size:32px;letter-spacing:.004em;line-height:1.125;margin:0 auto 35px auto;max-width:330px;width:auto}}#loading-placeholder{display:none}</style><div class="noscript"><h1 class="noscript-title">This page requires JavaScript.</h1><p>Please turn on JavaScript in your browser and refresh the page to view its content.</p></div></noscript><div id="app"></div></body></html>
@@ -1 +0,0 @@
<!doctype html><html lang="en-US" class="no-js"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><link rel="icon" href="/favicon.ico"><link rel="mask-icon" href="/favicon.svg" color="#333333"><title>Documentation</title><script>var baseUrl = "/"</script><script defer="defer" src="/js/chunk-vendors.bdb7cbba.js"></script><script defer="defer" src="/js/index.d2f6f6a9.js"></script><link href="/css/index.3a335429.css" rel="stylesheet"></head><body data-color-scheme="auto"><noscript><style>.noscript{font-family:"SF Pro Display","SF Pro Icons","Helvetica Neue",Helvetica,Arial,sans-serif;margin:92px auto 140px auto;text-align:center;width:980px}.noscript-title{color:#111;font-size:48px;font-weight:600;letter-spacing:-.003em;line-height:1.08365;margin:0 auto 54px auto;width:502px}@media only screen and (max-width:1068px){.noscript{margin:90px auto 120px auto;width:692px}.noscript-title{font-size:40px;letter-spacing:0;line-height:1.1;margin:0 auto 45px auto;width:420px}}@media only screen and (max-width:735px){.noscript{margin:45px auto 60px auto;width:87.5%}.noscript-title{font-size:32px;letter-spacing:.004em;line-height:1.125;margin:0 auto 35px auto;max-width:330px;width:auto}}#loading-placeholder{display:none}</style><div class="noscript"><h1 class="noscript-title">This page requires JavaScript.</h1><p>Please turn on JavaScript in your browser and refresh the page to view its content.</p></div></noscript><div id="app"></div></body></html>
@@ -1 +0,0 @@
<!doctype html><html lang="en-US" class="no-js"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><link rel="icon" href="/favicon.ico"><link rel="mask-icon" href="/favicon.svg" color="#333333"><title>Documentation</title><script>var baseUrl = "/"</script><script defer="defer" src="/js/chunk-vendors.bdb7cbba.js"></script><script defer="defer" src="/js/index.d2f6f6a9.js"></script><link href="/css/index.3a335429.css" rel="stylesheet"></head><body data-color-scheme="auto"><noscript><style>.noscript{font-family:"SF Pro Display","SF Pro Icons","Helvetica Neue",Helvetica,Arial,sans-serif;margin:92px auto 140px auto;text-align:center;width:980px}.noscript-title{color:#111;font-size:48px;font-weight:600;letter-spacing:-.003em;line-height:1.08365;margin:0 auto 54px auto;width:502px}@media only screen and (max-width:1068px){.noscript{margin:90px auto 120px auto;width:692px}.noscript-title{font-size:40px;letter-spacing:0;line-height:1.1;margin:0 auto 45px auto;width:420px}}@media only screen and (max-width:735px){.noscript{margin:45px auto 60px auto;width:87.5%}.noscript-title{font-size:32px;letter-spacing:.004em;line-height:1.125;margin:0 auto 35px auto;max-width:330px;width:auto}}#loading-placeholder{display:none}</style><div class="noscript"><h1 class="noscript-title">This page requires JavaScript.</h1><p>Please turn on JavaScript in your browser and refresh the page to view its content.</p></div></noscript><div id="app"></div></body></html>
-1
View File
@@ -1 +0,0 @@
<!doctype html><html lang="en-US" class="no-js"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><link rel="icon" href="/favicon.ico"><link rel="mask-icon" href="/favicon.svg" color="#333333"><title>Documentation</title><script>var baseUrl = "/"</script><script defer="defer" src="/js/chunk-vendors.bdb7cbba.js"></script><script defer="defer" src="/js/index.d2f6f6a9.js"></script><link href="/css/index.3a335429.css" rel="stylesheet"></head><body data-color-scheme="auto"><noscript><style>.noscript{font-family:"SF Pro Display","SF Pro Icons","Helvetica Neue",Helvetica,Arial,sans-serif;margin:92px auto 140px auto;text-align:center;width:980px}.noscript-title{color:#111;font-size:48px;font-weight:600;letter-spacing:-.003em;line-height:1.08365;margin:0 auto 54px auto;width:502px}@media only screen and (max-width:1068px){.noscript{margin:90px auto 120px auto;width:692px}.noscript-title{font-size:40px;letter-spacing:0;line-height:1.1;margin:0 auto 45px auto;width:420px}}@media only screen and (max-width:735px){.noscript{margin:45px auto 60px auto;width:87.5%}.noscript-title{font-size:32px;letter-spacing:.004em;line-height:1.125;margin:0 auto 35px auto;max-width:330px;width:auto}}#loading-placeholder{display:none}</style><div class="noscript"><h1 class="noscript-title">This page requires JavaScript.</h1><p>Please turn on JavaScript in your browser and refresh the page to view its content.</p></div></noscript><div id="app"></div></body></html>
@@ -1 +0,0 @@
<!doctype html><html lang="en-US" class="no-js"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><link rel="icon" href="/favicon.ico"><link rel="mask-icon" href="/favicon.svg" color="#333333"><title>Documentation</title><script>var baseUrl = "/"</script><script defer="defer" src="/js/chunk-vendors.bdb7cbba.js"></script><script defer="defer" src="/js/index.d2f6f6a9.js"></script><link href="/css/index.3a335429.css" rel="stylesheet"></head><body data-color-scheme="auto"><noscript><style>.noscript{font-family:"SF Pro Display","SF Pro Icons","Helvetica Neue",Helvetica,Arial,sans-serif;margin:92px auto 140px auto;text-align:center;width:980px}.noscript-title{color:#111;font-size:48px;font-weight:600;letter-spacing:-.003em;line-height:1.08365;margin:0 auto 54px auto;width:502px}@media only screen and (max-width:1068px){.noscript{margin:90px auto 120px auto;width:692px}.noscript-title{font-size:40px;letter-spacing:0;line-height:1.1;margin:0 auto 45px auto;width:420px}}@media only screen and (max-width:735px){.noscript{margin:45px auto 60px auto;width:87.5%}.noscript-title{font-size:32px;letter-spacing:.004em;line-height:1.125;margin:0 auto 35px auto;max-width:330px;width:auto}}#loading-placeholder{display:none}</style><div class="noscript"><h1 class="noscript-title">This page requires JavaScript.</h1><p>Please turn on JavaScript in your browser and refresh the page to view its content.</p></div></noscript><div id="app"></div></body></html>
@@ -1 +0,0 @@
<!doctype html><html lang="en-US" class="no-js"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><link rel="icon" href="/favicon.ico"><link rel="mask-icon" href="/favicon.svg" color="#333333"><title>Documentation</title><script>var baseUrl = "/"</script><script defer="defer" src="/js/chunk-vendors.bdb7cbba.js"></script><script defer="defer" src="/js/index.d2f6f6a9.js"></script><link href="/css/index.3a335429.css" rel="stylesheet"></head><body data-color-scheme="auto"><noscript><style>.noscript{font-family:"SF Pro Display","SF Pro Icons","Helvetica Neue",Helvetica,Arial,sans-serif;margin:92px auto 140px auto;text-align:center;width:980px}.noscript-title{color:#111;font-size:48px;font-weight:600;letter-spacing:-.003em;line-height:1.08365;margin:0 auto 54px auto;width:502px}@media only screen and (max-width:1068px){.noscript{margin:90px auto 120px auto;width:692px}.noscript-title{font-size:40px;letter-spacing:0;line-height:1.1;margin:0 auto 45px auto;width:420px}}@media only screen and (max-width:735px){.noscript{margin:45px auto 60px auto;width:87.5%}.noscript-title{font-size:32px;letter-spacing:.004em;line-height:1.125;margin:0 auto 35px auto;max-width:330px;width:auto}}#loading-placeholder{display:none}</style><div class="noscript"><h1 class="noscript-title">This page requires JavaScript.</h1><p>Please turn on JavaScript in your browser and refresh the page to view its content.</p></div></noscript><div id="app"></div></body></html>
@@ -1 +0,0 @@
<!doctype html><html lang="en-US" class="no-js"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><link rel="icon" href="/favicon.ico"><link rel="mask-icon" href="/favicon.svg" color="#333333"><title>Documentation</title><script>var baseUrl = "/"</script><script defer="defer" src="/js/chunk-vendors.bdb7cbba.js"></script><script defer="defer" src="/js/index.d2f6f6a9.js"></script><link href="/css/index.3a335429.css" rel="stylesheet"></head><body data-color-scheme="auto"><noscript><style>.noscript{font-family:"SF Pro Display","SF Pro Icons","Helvetica Neue",Helvetica,Arial,sans-serif;margin:92px auto 140px auto;text-align:center;width:980px}.noscript-title{color:#111;font-size:48px;font-weight:600;letter-spacing:-.003em;line-height:1.08365;margin:0 auto 54px auto;width:502px}@media only screen and (max-width:1068px){.noscript{margin:90px auto 120px auto;width:692px}.noscript-title{font-size:40px;letter-spacing:0;line-height:1.1;margin:0 auto 45px auto;width:420px}}@media only screen and (max-width:735px){.noscript{margin:45px auto 60px auto;width:87.5%}.noscript-title{font-size:32px;letter-spacing:.004em;line-height:1.125;margin:0 auto 35px auto;max-width:330px;width:auto}}#loading-placeholder{display:none}</style><div class="noscript"><h1 class="noscript-title">This page requires JavaScript.</h1><p>Please turn on JavaScript in your browser and refresh the page to view its content.</p></div></noscript><div id="app"></div></body></html>
@@ -1 +0,0 @@
<!doctype html><html lang="en-US" class="no-js"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><link rel="icon" href="/favicon.ico"><link rel="mask-icon" href="/favicon.svg" color="#333333"><title>Documentation</title><script>var baseUrl = "/"</script><script defer="defer" src="/js/chunk-vendors.bdb7cbba.js"></script><script defer="defer" src="/js/index.d2f6f6a9.js"></script><link href="/css/index.3a335429.css" rel="stylesheet"></head><body data-color-scheme="auto"><noscript><style>.noscript{font-family:"SF Pro Display","SF Pro Icons","Helvetica Neue",Helvetica,Arial,sans-serif;margin:92px auto 140px auto;text-align:center;width:980px}.noscript-title{color:#111;font-size:48px;font-weight:600;letter-spacing:-.003em;line-height:1.08365;margin:0 auto 54px auto;width:502px}@media only screen and (max-width:1068px){.noscript{margin:90px auto 120px auto;width:692px}.noscript-title{font-size:40px;letter-spacing:0;line-height:1.1;margin:0 auto 45px auto;width:420px}}@media only screen and (max-width:735px){.noscript{margin:45px auto 60px auto;width:87.5%}.noscript-title{font-size:32px;letter-spacing:.004em;line-height:1.125;margin:0 auto 35px auto;max-width:330px;width:auto}}#loading-placeholder{display:none}</style><div class="noscript"><h1 class="noscript-title">This page requires JavaScript.</h1><p>Please turn on JavaScript in your browser and refresh the page to view its content.</p></div></noscript><div id="app"></div></body></html>
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

-11
View File
@@ -1,11 +0,0 @@
<!--
This source file is part of the Swift.org open source project
Copyright (c) 2021 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See https://swift.org/LICENSE.txt for license information
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
-->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25"><path d="M12.5.5a12,12,0,1,0,12,12A12,12,0,0,0,12.5.5ZM1.525,13H6.014a20.83,20.83,0,0,0,.469,4.031h-4A10.924,10.924,0,0,1,1.525,13ZM13,6.969V1.552c1.734.339,3.32,2.417,4.222,5.417Zm4.49,1a19.808,19.808,0,0,1,.5,4.031H13V7.969ZM12,1.552V6.969H7.778C8.68,3.969,10.266,1.891,12,1.552Zm0,6.417V12H7.013a19.808,19.808,0,0,1,.5-4.031ZM6.014,12H1.525a10.924,10.924,0,0,1,.96-4.031h4A20.83,20.83,0,0,0,6.014,12Zm1,1H12v4.031H7.51A19.808,19.808,0,0,1,7.013,13ZM12,18.031v5.417c-1.734-.339-3.32-2.417-4.222-5.417Zm1,5.417V18.031h4.222C16.32,21.031,14.734,23.109,13,23.448Zm0-6.417V13h4.987a19.808,19.808,0,0,1-.5,4.031ZM18.986,13h4.489a10.924,10.924,0,0,1-.96,4.031h-4A20.83,20.83,0,0,0,18.986,13Zm0-1a20.83,20.83,0,0,0-.469-4.031h4A10.924,10.924,0,0,1,23.475,12ZM22,6.969H18.265A11.6,11.6,0,0,0,15.6,1.951,11.007,11.007,0,0,1,22,6.969ZM9.4,1.951A11.6,11.6,0,0,0,6.735,6.969H3A11.007,11.007,0,0,1,9.4,1.951ZM3,18.031H6.735A11.6,11.6,0,0,0,9.4,23.049,11.007,11.007,0,0,1,3,18.031Zm12.6,5.018a11.6,11.6,0,0,0,2.665-5.018H22A11.007,11.007,0,0,1,15.6,23.049Z" fill-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

-1
View File
@@ -1 +0,0 @@
<!doctype html><html lang="en-US" class="no-js"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><link rel="icon" href="/favicon.ico"><link rel="mask-icon" href="/favicon.svg" color="#333333"><title>Documentation</title><script>var baseUrl = "/"</script><script defer="defer" src="/js/chunk-vendors.bdb7cbba.js"></script><script defer="defer" src="/js/index.d2f6f6a9.js"></script><link href="/css/index.3a335429.css" rel="stylesheet"></head><body data-color-scheme="auto"><noscript><style>.noscript{font-family:"SF Pro Display","SF Pro Icons","Helvetica Neue",Helvetica,Arial,sans-serif;margin:92px auto 140px auto;text-align:center;width:980px}.noscript-title{color:#111;font-size:48px;font-weight:600;letter-spacing:-.003em;line-height:1.08365;margin:0 auto 54px auto;width:502px}@media only screen and (max-width:1068px){.noscript{margin:90px auto 120px auto;width:692px}.noscript-title{font-size:40px;letter-spacing:0;line-height:1.1;margin:0 auto 45px auto;width:420px}}@media only screen and (max-width:735px){.noscript{margin:45px auto 60px auto;width:87.5%}.noscript-title{font-size:32px;letter-spacing:.004em;line-height:1.125;margin:0 auto 35px auto;max-width:330px;width:auto}}#loading-placeholder{display:none}</style><div class="noscript"><h1 class="noscript-title">This page requires JavaScript.</h1><p>Please turn on JavaScript in your browser and refresh the page to view its content.</p></div></noscript><div id="app"></div></body></html>
-1
View File
@@ -1 +0,0 @@
{"includedArchiveIdentifiers":["com.anthropic.tuikit.documentation"],"interfaceLanguages":{"swift":[{"children":[{"title":"Articles","type":"groupMarker"},{"path":"\/documentation\/tuikit\/appearance","title":"Appearance System","type":"article"},{"path":"\/documentation\/tuikit\/architecture","title":"Architecture Overview","type":"article"},{"path":"\/documentation\/tuikit\/focus","title":"Focus Management","type":"article"},{"path":"\/documentation\/tuikit\/gettingstarted","title":"Getting Started with TUIKit","type":"article"},{"path":"\/documentation\/tuikit\/modifiers","title":"View Modifiers","type":"article"},{"path":"\/documentation\/tuikit\/statemanagement","title":"State Management","type":"article"},{"path":"\/documentation\/tuikit\/theming","title":"Theming System","type":"article"},{"path":"\/documentation\/tuikit\/viewhierarchy","title":"Understanding the View Hierarchy","type":"article"},{"path":"\/documentation\/tuikit\/buildinteractivemenu","title":"Building an Interactive Menu","type":"article"},{"path":"\/documentation\/tuikit\/buildthemableui","title":"Building a Themable UI","type":"article"},{"path":"\/documentation\/tuikit\/buildyourfirstapp","title":"Building Your First App","type":"article"}],"path":"\/documentation\/tuikit","title":"TUIKit","type":"module"}]},"schemaVersion":{"major":0,"minor":1,"patch":2}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-10
View File
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[393],{8780:function(e){function s(e){const s=e.regex,t={},n={begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]};Object.assign(t,{className:"variable",variants:[{begin:s.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},n]});const a={className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},i={begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,className:"string"})]}},c={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,t,a]};a.contains.push(c);const o={className:"",begin:/\\"/},r={className:"string",begin:/'/,end:/'/},l={begin:/\$\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t]},d=["fish","bash","zsh","sh","csh","ksh","tcsh","dash","scsh"],p=e.SHEBANG({binary:`(${d.join("|")})`,relevance:10}),m={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0},u=["if","then","else","elif","fi","for","while","in","do","done","case","esac","function"],h=["true","false"],b={match:/(\/[a-z._-]+)+/},f=["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset"],g=["alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias"],w=["autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp"],k=["chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"];return{name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z._-]+\b/,keyword:u,literal:h,built_in:[...f,...g,"set","shopt",...w,...k]},contains:[p,e.SHEBANG(),m,l,e.HASH_COMMENT_MODE,i,b,c,o,r,t]}}e.exports=s}}]);
-10
View File
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[546],{612:function(e){function n(e){const n=e.regex,s=e.COMMENT("//","$",{contains:[{begin:/\\\n/}]}),t="decltype\\(auto\\)",a="[a-zA-Z_]\\w*::",r="<[^<>]+>",i="("+t+"|"+n.optional(a)+"[a-zA-Z_]\\w*"+n.optional(r)+")",l={className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{match:/\batomic_[a-z]{3,6}\b/}]},c="\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)",o={className:"string",variants:[{begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:"(u8?|U|L)?'("+c+"|.)",end:"'",illegal:"."},e.END_SAME_AS_BEGIN({begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},d={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},u={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},e.inherit(o,{className:"string"}),{className:"string",begin:/<.*?>/},s,e.C_BLOCK_COMMENT_MODE]},_={className:"title",begin:n.optional(a)+e.IDENT_RE,relevance:0},g=n.optional(a)+e.IDENT_RE+"\\s*\\(",p=["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"],m=["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"],f={keyword:p,type:m,literal:"true false NULL",built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr"},b=[u,l,s,e.C_BLOCK_COMMENT_MODE,d,o],w={variants:[{begin:/=/,end:/;/},{begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],keywords:f,contains:b.concat([{begin:/\(/,end:/\)/,keywords:f,contains:b.concat(["self"]),relevance:0}]),relevance:0},y={begin:"("+i+"[\\*&\\s]+)+"+g,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:f,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:t,keywords:f,relevance:0},{begin:g,returnBegin:!0,contains:[e.inherit(_,{className:"title.function"})],relevance:0},{relevance:0,match:/,/},{className:"params",begin:/\(/,end:/\)/,keywords:f,relevance:0,contains:[s,e.C_BLOCK_COMMENT_MODE,o,d,l,{begin:/\(/,end:/\)/,keywords:f,relevance:0,contains:["self",s,e.C_BLOCK_COMMENT_MODE,o,d,l]}]},l,s,e.C_BLOCK_COMMENT_MODE,u]};return{name:"C",aliases:["h"],keywords:f,disableAutodetect:!0,illegal:"</",contains:[].concat(w,y,b,[u,{begin:e.IDENT_RE+"::",keywords:f},{className:"class",beginKeywords:"enum class struct union",end:/[{;:<>=]/,contains:[{beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:u,strings:o,keywords:f}}}e.exports=n}}]);
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
"use strict";(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[642],{2003:function(e,n,a){function i(e){const n=e.regex,a={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml",relevance:0},i={begin:"^[-\\*]{3,}",end:"$"},s={className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))",contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},c={className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",end:"\\s+",excludeEnd:!0},t={begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]},d=/[A-Za-z][A-Za-z0-9+.-]*/,l={variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/,relevance:2},{begin:n.concat(/\[.+?\]\(/,d,/:\/\/.*?\)/),relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/},{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0,returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0}]},g={className:"strong",contains:[],variants:[{begin:/_{2}/,end:/_{2}/},{begin:/\*{2}/,end:/\*{2}/}]},r={className:"emphasis",contains:[],variants:[{begin:/\*(?!\*)/,end:/\*/},{begin:/_(?!_)/,end:/_/,relevance:0}]};g.contains.push(r),r.contains.push(g);let o=[a,l];g.contains=g.contains.concat(o),r.contains=r.contains.concat(o),o=o.concat(g,r);const b={className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:o},{begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",contains:o}]}]},u={className:"quote",begin:"^>\\s+",contains:o,end:"$"};return{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[b,a,c,g,r,u,s,i,l,t]}}a.r(n),a.d(n,{default:function(){return l}});const s={begin:"<doc:",end:">",returnBegin:!0,contains:[{className:"link",begin:"doc:",end:">",excludeEnd:!0}]},c={className:"link",begin:/`{2}(?!`)/,end:/`{2}(?!`)/,excludeBegin:!0,excludeEnd:!0},t={begin:"^>\\s+[Note:|Tip:|Important:|Experiment:|Warning:]",end:"$",returnBegin:!0,contains:[{className:"quote",begin:"^>",end:"\\s+"},{className:"type",begin:"Note|Tip|Important|Experiment|Warning",end:":"},{className:"quote",begin:".*",end:"$",endsParent:!0}]},d={begin:"@",end:"[{\\)\\s]",returnBegin:!0,contains:[{className:"title",begin:"@",end:"[\\s+(]",excludeEnd:!0},{begin:":",end:"[,\\)\n\t]",excludeBegin:!0,keywords:{literal:"true false null undefined"},contains:[{className:"number",begin:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",endsWithParent:!0,excludeEnd:!0},{className:"string",variants:[{begin:/"""/,end:/"""/},{begin:/"/,end:/"/}],endsParent:!0},{className:"link",begin:"http|https",endsWithParent:!0,excludeEnd:!0}]}]};function l(e){const n=i(e),a=n.contains.find((({className:e})=>"code"===e));a.variants=a.variants.filter((({begin:e})=>!e.includes("( {4}|\\t)")));const l=[...n.contains.filter((({className:e})=>"code"!==e)),a];return{...n,contains:[c,s,t,d,...l]}}}}]);
File diff suppressed because one or more lines are too long
-10
View File
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[213],{7731:function(e){function n(e){const n=e.regex;return{name:"Diff",aliases:["patch"],contains:[{className:"meta",relevance:10,match:n.either(/^@@ +-\d+,\d+ +\+\d+,\d+ +@@/,/^\*\*\* +\d+,\d+ +\*\*\*\*$/,/^--- +\d+,\d+ +----$/)},{className:"comment",variants:[{begin:n.either(/Index: /,/^index/,/={3,}/,/^-{3}/,/^\*{3} /,/^\+{3}/,/^diff --git/),end:/$/},{match:/^\*{15}$/}]},{className:"addition",begin:/^\+/,end:/$/},{className:"deletion",begin:/^-/,end:/$/},{className:"addition",begin:/^!/,end:/$/}]}}e.exports=n}}]);
-10
View File
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[878],{8937:function(e){function n(e){const n=e.regex,a="HTTP/(2|1\\.[01])",s=/[A-Za-z][A-Za-z0-9-]*/,t={className:"attribute",begin:n.concat("^",s,"(?=\\:\\s)"),starts:{contains:[{className:"punctuation",begin:/: /,relevance:0,starts:{end:"$",relevance:0}}]}},i=[t,{begin:"\\n\\n",starts:{subLanguage:[],endsWithParent:!0}}];return{name:"HTTP",aliases:["https"],illegal:/\S/,contains:[{begin:"^(?="+a+" \\d{3})",end:/$/,contains:[{className:"meta",begin:a},{className:"number",begin:"\\b\\d{3}\\b"}],starts:{end:/\b\B/,illegal:/\S/,contains:i}},{begin:"(?=^[A-Z]+ (.*?) "+a+"$)",end:/$/,contains:[{className:"string",begin:" ",end:" ",excludeBegin:!0,excludeEnd:!0},{className:"meta",begin:a},{className:"keyword",begin:"[A-Z]+"}],starts:{end:/\b\B/,illegal:/\S/,contains:i}},e.inherit(t,{relevance:0})]}}e.exports=n}}]);
-10
View File
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[788],{8257:function(e){var n="[0-9](_*[0-9])*",a=`\\.(${n})`,s="[0-9a-fA-F](_*[0-9a-fA-F])*",t={className:"number",variants:[{begin:`(\\b(${n})((${a})|\\.)?|(${a}))[eE][+-]?(${n})[fFdD]?\\b`},{begin:`\\b(${n})((${a})[fFdD]?\\b|\\.([fFdD]\\b)?)`},{begin:`(${a})[fFdD]?\\b`},{begin:`\\b(${n})[fFdD]\\b`},{begin:`\\b0[xX]((${s})\\.?|(${s})?\\.(${s}))[pP][+-]?(${n})[fFdD]?\\b`},{begin:"\\b(0|[1-9](_*[0-9])*)[lL]?\\b"},{begin:`\\b0[xX](${s})[lL]?\\b`},{begin:"\\b0(_*[0-7])*[lL]?\\b"},{begin:"\\b0[bB][01](_*[01])*[lL]?\\b"}],relevance:0};function i(e,n,a){return-1===a?"":e.replace(n,(s=>i(e,n,a-1)))}function r(e){e.regex;const n="[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",a=n+i("(?:<"+n+"~~~(?:\\s*,\\s*"+n+"~~~)*>)?",/~~~/g,2),s=["synchronized","abstract","private","var","static","if","const ","for","while","strictfp","finally","protected","import","native","final","void","enum","else","break","transient","catch","instanceof","volatile","case","assert","package","default","public","try","switch","continue","throws","protected","public","private","module","requires","exports","do"],r=["super","this"],c=["false","true","null"],l=["char","boolean","long","float","int","byte","short","double"],b={keyword:s,literal:c,type:l,built_in:r},o={className:"meta",begin:"@"+n,contains:[{begin:/\(/,end:/\)/,contains:["self"]}]},_={className:"params",begin:/\(/,end:/\)/,keywords:b,relevance:0,contains:[e.C_BLOCK_COMMENT_MODE],endsParent:!0};return{name:"Java",aliases:["jsp"],keywords:b,illegal:/<\/|#/,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),{begin:/import java\.[a-z]+\./,keywords:"import",relevance:2},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{begin:/"""/,end:/"""/,className:"string",contains:[e.BACKSLASH_ESCAPE]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{match:[/\b(?:class|interface|enum|extends|implements|new)/,/\s+/,n],className:{1:"keyword",3:"title.class"}},{begin:[n,/\s+/,n,/\s+/,/=/],className:{1:"type",3:"variable",5:"operator"}},{begin:[/record/,/\s+/,n],className:{1:"keyword",3:"title.class"},contains:[_,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"new throw return else",relevance:0},{begin:["(?:"+a+"\\s+)",e.UNDERSCORE_IDENT_RE,/\s*(?=\()/],className:{2:"title.function"},keywords:b,contains:[{className:"params",begin:/\(/,end:/\)/,keywords:b,relevance:0,contains:[o,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,t,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},t,o]}}e.exports=r}}]);
File diff suppressed because one or more lines are too long
-10
View File
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[82],{14:function(e){function n(e){const n={className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/,relevance:1.01},c={match:/[{}[\],:]/,className:"punctuation",relevance:0},a={beginKeywords:["true","false","null"].join(" ")};return{name:"JSON",contains:[n,c,e.QUOTE_STRING_MODE,a,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],illegal:"\\S"}}e.exports=n}}]);
-10
View File
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[133],{4972:function(e){function n(e){const n=e.regex,a=/([-a-zA-Z$._][\w$.-]*)/,t={className:"type",begin:/\bi\d+(?=\s|\b)/},i={className:"operator",relevance:0,begin:/=/},c={className:"punctuation",relevance:0,begin:/,/},l={className:"number",variants:[{begin:/0[xX][a-fA-F0-9]+/},{begin:/-?\d+(?:[.]\d+)?(?:[eE][-+]?\d+(?:[.]\d+)?)?/}],relevance:0},r={className:"symbol",variants:[{begin:/^\s*[a-z]+:/}],relevance:0},s={className:"variable",variants:[{begin:n.concat(/%/,a)},{begin:/%\d+/},{begin:/#\d+/}]},o={className:"title",variants:[{begin:n.concat(/@/,a)},{begin:/@\d+/},{begin:n.concat(/!/,a)},{begin:n.concat(/!\d+/,a)},{begin:/!\d+/}]};return{name:"LLVM IR",keywords:"begin end true false declare define global constant private linker_private internal available_externally linkonce linkonce_odr weak weak_odr appending dllimport dllexport common default hidden protected extern_weak external thread_local zeroinitializer undef null to tail target triple datalayout volatile nuw nsw nnan ninf nsz arcp fast exact inbounds align addrspace section alias module asm sideeffect gc dbg linker_private_weak attributes blockaddress initialexec localdynamic localexec prefix unnamed_addr ccc fastcc coldcc x86_stdcallcc x86_fastcallcc arm_apcscc arm_aapcscc arm_aapcs_vfpcc ptx_device ptx_kernel intel_ocl_bicc msp430_intrcc spir_func spir_kernel x86_64_sysvcc x86_64_win64cc x86_thiscallcc cc c signext zeroext inreg sret nounwind noreturn noalias nocapture byval nest readnone readonly inlinehint noinline alwaysinline optsize ssp sspreq noredzone noimplicitfloat naked builtin cold nobuiltin noduplicate nonlazybind optnone returns_twice sanitize_address sanitize_memory sanitize_thread sspstrong uwtable returned type opaque eq ne slt sgt sle sge ult ugt ule uge oeq one olt ogt ole oge ord uno ueq une x acq_rel acquire alignstack atomic catch cleanup filter inteldialect max min monotonic nand personality release seq_cst singlethread umax umin unordered xchg add fadd sub fsub mul fmul udiv sdiv fdiv urem srem frem shl lshr ashr and or xor icmp fcmp phi call trunc zext sext fptrunc fpext uitofp sitofp fptoui fptosi inttoptr ptrtoint bitcast addrspacecast select va_arg ret br switch invoke unwind unreachable indirectbr landingpad resume malloc alloca free load store getelementptr extractelement insertelement shufflevector getresult extractvalue insertvalue atomicrmw cmpxchg fence argmemonly double",contains:[t,e.COMMENT(/;\s*$/,null,{relevance:0}),e.COMMENT(/;/,/$/),e.QUOTE_STRING_MODE,{className:"string",variants:[{begin:/"/,end:/[^\\]"/}]},o,c,i,s,r,l]}}e.exports=n}}]);
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[113],{1312:function(e){function n(e){const n=e.regex,a={begin:/<\/?[A-Za-z_]/,end:">",subLanguage:"xml",relevance:0},i={begin:"^[-\\*]{3,}",end:"$"},c={className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))",contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},s={className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",end:"\\s+",excludeEnd:!0},t={begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]},d=/[A-Za-z][A-Za-z0-9+.-]*/,l={variants:[{begin:/\[.+?\]\[.*?\]/,relevance:0},{begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/,relevance:2},{begin:n.concat(/\[.+?\]\(/,d,/:\/\/.*?\)/),relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/},{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0,returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0}]},g={className:"strong",contains:[],variants:[{begin:/_{2}/,end:/_{2}/},{begin:/\*{2}/,end:/\*{2}/}]},b={className:"emphasis",contains:[],variants:[{begin:/\*(?!\*)/,end:/\*/},{begin:/_(?!_)/,end:/_/,relevance:0}]};g.contains.push(b),b.contains.push(g);let o=[a,l];g.contains=g.contains.concat(o),b.contains=b.contains.concat(o),o=o.concat(g,b);const r={className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:o},{begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",contains:o}]}]},u={className:"quote",begin:"^>\\s+",contains:o,end:"$"};return{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[r,a,s,g,b,u,c,i,l,t]}}e.exports=n}}]);
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[637],{2446:function(e){function n(e){const n={className:"built_in",begin:"\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+"},_=/[a-zA-Z@][a-zA-Z0-9_]*/,i=["int","float","while","char","export","sizeof","typedef","const","struct","for","union","unsigned","long","volatile","static","bool","mutable","if","do","return","goto","void","enum","else","break","extern","asm","case","short","default","double","register","explicit","signed","typename","this","switch","continue","wchar_t","inline","readonly","assign","readwrite","self","@synchronized","id","typeof","nonatomic","super","unichar","IBOutlet","IBAction","strong","weak","copy","in","out","inout","bycopy","byref","oneway","__strong","__weak","__block","__autoreleasing","@private","@protected","@public","@try","@property","@end","@throw","@catch","@finally","@autoreleasepool","@synthesize","@dynamic","@selector","@optional","@required","@encode","@package","@import","@defs","@compatibility_alias","__bridge","__bridge_transfer","__bridge_retained","__bridge_retain","__covariant","__contravariant","__kindof","_Nonnull","_Nullable","_Null_unspecified","__FUNCTION__","__PRETTY_FUNCTION__","__attribute__","getter","setter","retain","unsafe_unretained","nonnull","nullable","null_unspecified","null_resettable","class","instancetype","NS_DESIGNATED_INITIALIZER","NS_UNAVAILABLE","NS_REQUIRES_SUPER","NS_RETURNS_INNER_POINTER","NS_INLINE","NS_AVAILABLE","NS_DEPRECATED","NS_ENUM","NS_OPTIONS","NS_SWIFT_UNAVAILABLE","NS_ASSUME_NONNULL_BEGIN","NS_ASSUME_NONNULL_END","NS_REFINED_FOR_SWIFT","NS_SWIFT_NAME","NS_SWIFT_NOTHROW","NS_DURING","NS_HANDLER","NS_ENDHANDLER","NS_VALUERETURN","NS_VOIDRETURN"],t=["false","true","FALSE","TRUE","nil","YES","NO","NULL"],a=["BOOL","dispatch_once_t","dispatch_queue_t","dispatch_sync","dispatch_async","dispatch_once"],r={$pattern:_,keyword:i,literal:t,built_in:a},s={$pattern:_,keyword:["@interface","@class","@protocol","@implementation"]};return{name:"Objective-C",aliases:["mm","objc","obj-c","obj-c++","objective-c++"],keywords:r,illegal:"</",contains:[n,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.C_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{className:"string",variants:[{begin:'@"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]}]},{className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{keyword:"if else elif endif define undef warning error line pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),{className:"string",begin:/<.*?>/,end:/$/,illegal:"\\n"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class",begin:"("+s.keyword.join("|")+")\\b",end:/(\{|$)/,excludeEnd:!0,keywords:s,contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE,relevance:0}]}}e.exports=n}}]);
-10
View File
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[645],{2482:function(e){function n(e){const n=e.regex,t=["abs","accept","alarm","and","atan2","bind","binmode","bless","break","caller","chdir","chmod","chomp","chop","chown","chr","chroot","close","closedir","connect","continue","cos","crypt","dbmclose","dbmopen","defined","delete","die","do","dump","each","else","elsif","endgrent","endhostent","endnetent","endprotoent","endpwent","endservent","eof","eval","exec","exists","exit","exp","fcntl","fileno","flock","for","foreach","fork","format","formline","getc","getgrent","getgrgid","getgrnam","gethostbyaddr","gethostbyname","gethostent","getlogin","getnetbyaddr","getnetbyname","getnetent","getpeername","getpgrp","getpriority","getprotobyname","getprotobynumber","getprotoent","getpwent","getpwnam","getpwuid","getservbyname","getservbyport","getservent","getsockname","getsockopt","given","glob","gmtime","goto","grep","gt","hex","if","index","int","ioctl","join","keys","kill","last","lc","lcfirst","length","link","listen","local","localtime","log","lstat","lt","ma","map","mkdir","msgctl","msgget","msgrcv","msgsnd","my","ne","next","no","not","oct","open","opendir","or","ord","our","pack","package","pipe","pop","pos","print","printf","prototype","push","q|0","qq","quotemeta","qw","qx","rand","read","readdir","readline","readlink","readpipe","recv","redo","ref","rename","require","reset","return","reverse","rewinddir","rindex","rmdir","say","scalar","seek","seekdir","select","semctl","semget","semop","send","setgrent","sethostent","setnetent","setpgrp","setpriority","setprotoent","setpwent","setservent","setsockopt","shift","shmctl","shmget","shmread","shmwrite","shutdown","sin","sleep","socket","socketpair","sort","splice","split","sprintf","sqrt","srand","stat","state","study","sub","substr","symlink","syscall","sysopen","sysread","sysseek","system","syswrite","tell","telldir","tie","tied","time","times","tr","truncate","uc","ucfirst","umask","undef","unless","unlink","unpack","unshift","untie","until","use","utime","values","vec","wait","waitpid","wantarray","warn","when","while","write","x|0","xor","y|0"],r=/[dualxmsipngr]{0,12}/,s={$pattern:/[\w.]+/,keyword:t.join(" ")},i={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:s},a={begin:/->\{/,end:/\}/},c={variants:[{begin:/\$\d/},{begin:n.concat(/[$%@](\^\w\b|#\w+(::\w+)*|\{\w+\}|\w+(::\w*)*)/,"(?![A-Za-z])(?![@$%])")},{begin:/[$%@][^\s\w{]/,relevance:0}]},o=[e.BACKSLASH_ESCAPE,i,c],g=[/!/,/\//,/\|/,/\?/,/'/,/"/,/#/],l=(e,t,s="\\1")=>{const i="\\1"===s?s:n.concat(s,t);return n.concat(n.concat("(?:",e,")"),t,/(?:\\.|[^\\\/])*?/,i,/(?:\\.|[^\\\/])*?/,s,r)},d=(e,t,s)=>n.concat(n.concat("(?:",e,")"),t,/(?:\\.|[^\\\/])*?/,s,r),p=[c,e.HASH_COMMENT_MODE,e.COMMENT(/^=\w/,/=cut/,{endsWithParent:!0}),a,{className:"string",contains:o,variants:[{begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[",end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*<",end:">",relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'",contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE]},{begin:/\{\w+\}/,relevance:0},{begin:"-?\\w+\\s*=>",relevance:0}]},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*",keywords:"split return print reverse grep",relevance:0,contains:[e.HASH_COMMENT_MODE,{className:"regexp",variants:[{begin:l("s|tr|y",n.either(...g,{capture:!0}))},{begin:l("s|tr|y","\\(","\\)")},{begin:l("s|tr|y","\\[","\\]")},{begin:l("s|tr|y","\\{","\\}")}],relevance:2},{className:"regexp",variants:[{begin:/(m|qr)\/\//,relevance:0},{begin:d("(?:m|qr)?",/\//,/\//)},{begin:d("m|qr",n.either(...g,{capture:!0}),/\1/)},{begin:d("m|qr",/\(/,/\)/)},{begin:d("m|qr",/\[/,/\]/)},{begin:d("m|qr",/\{/,/\}/)}]}]},{className:"function",beginKeywords:"sub",end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$",subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}]}];return i.contains=p,a.contains=p,{name:"Perl",aliases:["pl","pm"],keywords:s,contains:p}}e.exports=n}}]);
-10
View File
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[596],{2656:function(e){function r(e){const r={className:"variable",begin:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*(?![A-Za-z0-9])(?![$])"},t={className:"meta",variants:[{begin:/<\?php/,relevance:10},{begin:/<\?[=]?/},{begin:/\?>/}]},a={className:"subst",variants:[{begin:/\$\w+/},{begin:/\{\$/,end:/\}/}]},n=e.inherit(e.APOS_STRING_MODE,{illegal:null}),i=e.inherit(e.QUOTE_STRING_MODE,{illegal:null,contains:e.QUOTE_STRING_MODE.contains.concat(a)}),o=e.END_SAME_AS_BEGIN({begin:/<<<[ \t]*(\w+)\n/,end:/[ \t]*(\w+)\b/,contains:e.QUOTE_STRING_MODE.contains.concat(a)}),l={className:"string",contains:[e.BACKSLASH_ESCAPE,t],variants:[e.inherit(n,{begin:"b'",end:"'"}),e.inherit(i,{begin:'b"',end:'"'}),i,n,o]},c={className:"number",variants:[{begin:"\\b0b[01]+(?:_[01]+)*\\b"},{begin:"\\b0o[0-7]+(?:_[0-7]+)*\\b"},{begin:"\\b0x[\\da-f]+(?:_[\\da-f]+)*\\b"},{begin:"(?:\\b\\d+(?:_\\d+)*(\\.(?:\\d+(?:_\\d+)*))?|\\B\\.\\d+)(?:e[+-]?\\d+)?"}],relevance:0},s={keyword:"__CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__ die echo exit include include_once print require require_once array abstract and as binary bool boolean break callable case catch class clone const continue declare default do double else elseif empty enddeclare endfor endforeach endif endswitch endwhile enum eval extends final finally float for foreach from global goto if implements instanceof insteadof int integer interface isset iterable list match|0 mixed new object or private protected public real return string switch throw trait try unset use var void while xor yield",literal:"false null true",built_in:"Error|0 AppendIterator ArgumentCountError ArithmeticError ArrayIterator ArrayObject AssertionError BadFunctionCallException BadMethodCallException CachingIterator CallbackFilterIterator CompileError Countable DirectoryIterator DivisionByZeroError DomainException EmptyIterator ErrorException Exception FilesystemIterator FilterIterator GlobIterator InfiniteIterator InvalidArgumentException IteratorIterator LengthException LimitIterator LogicException MultipleIterator NoRewindIterator OutOfBoundsException OutOfRangeException OuterIterator OverflowException ParentIterator ParseError RangeException RecursiveArrayIterator RecursiveCachingIterator RecursiveCallbackFilterIterator RecursiveDirectoryIterator RecursiveFilterIterator RecursiveIterator RecursiveIteratorIterator RecursiveRegexIterator RecursiveTreeIterator RegexIterator RuntimeException SeekableIterator SplDoublyLinkedList SplFileInfo SplFileObject SplFixedArray SplHeap SplMaxHeap SplMinHeap SplObjectStorage SplObserver SplObserver SplPriorityQueue SplQueue SplStack SplSubject SplSubject SplTempFileObject TypeError UnderflowException UnexpectedValueException UnhandledMatchError ArrayAccess Closure Generator Iterator IteratorAggregate Serializable Stringable Throwable Traversable WeakReference WeakMap Directory __PHP_Incomplete_Class parent php_user_filter self static stdClass"};return{case_insensitive:!0,keywords:s,contains:[e.HASH_COMMENT_MODE,e.COMMENT("//","$",{contains:[t]}),e.COMMENT("/\\*","\\*/",{contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.COMMENT("__halt_compiler.+?;",!1,{endsWithParent:!0,keywords:"__halt_compiler"}),t,{className:"keyword",begin:/\$this\b/},r,{begin:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{className:"function",relevance:0,beginKeywords:"fn function",end:/[;{]/,excludeEnd:!0,illegal:"[$%\\[]",contains:[{beginKeywords:"use"},e.UNDERSCORE_TITLE_MODE,{begin:"=>",endsParent:!0},{className:"params",begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:s,contains:["self",r,e.C_BLOCK_COMMENT_MODE,l,c]}]},{className:"class",variants:[{beginKeywords:"enum",illegal:/[($"]/},{beginKeywords:"class interface trait",illegal:/[:($"]/}],relevance:0,end:/\{/,excludeEnd:!0,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"namespace",relevance:0,end:";",illegal:/[.']/,contains:[e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"use",relevance:0,end:";",contains:[e.UNDERSCORE_TITLE_MODE]},l,c]}}e.exports=r}}]);
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[435],{8245:function(e){function n(e){const n=e.regex,a=/[\p{XID_Start}_]\p{XID_Continue}*/u,i=["and","as","assert","async","await","break","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","nonlocal|10","not","or","pass","raise","return","try","while","with","yield"],s=["__import__","abs","all","any","ascii","bin","bool","breakpoint","bytearray","bytes","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","exec","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","print","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip"],t=["__debug__","Ellipsis","False","None","NotImplemented","True"],r=["Any","Callable","Coroutine","Dict","List","Literal","Generic","Optional","Sequence","Set","Tuple","Type","Union"],l={$pattern:/[A-Za-z]\w+|__\w+__/,keyword:i,built_in:s,literal:t,type:r},b={className:"meta",begin:/^(>>>|\.\.\.) /},o={className:"subst",begin:/\{/,end:/\}/,keywords:l,illegal:/#/},c={begin:/\{\{/,relevance:0},d={className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,b],relevance:10},{begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,b],relevance:10},{begin:/([fF][rR]|[rR][fF]|[fF])'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,b,c,o]},{begin:/([fF][rR]|[rR][fF]|[fF])"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,b,c,o]},{begin:/([uU]|[rR])'/,end:/'/,relevance:10},{begin:/([uU]|[rR])"/,end:/"/,relevance:10},{begin:/([bB]|[bB][rR]|[rR][bB])'/,end:/'/},{begin:/([bB]|[bB][rR]|[rR][bB])"/,end:/"/},{begin:/([fF][rR]|[rR][fF]|[fF])'/,end:/'/,contains:[e.BACKSLASH_ESCAPE,c,o]},{begin:/([fF][rR]|[rR][fF]|[fF])"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,c,o]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},p="[0-9](_?[0-9])*",_=`(\\b(${p}))?\\.(${p})|\\b(${p})\\.`,g={className:"number",relevance:0,variants:[{begin:`(\\b(${p})|(${_}))[eE][+-]?(${p})[jJ]?\\b`},{begin:`(${_})[jJ]?`},{begin:"\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?\\b"},{begin:"\\b0[bB](_?[01])+[lL]?\\b"},{begin:"\\b0[oO](_?[0-7])+[lL]?\\b"},{begin:"\\b0[xX](_?[0-9a-fA-F])+[lL]?\\b"},{begin:`\\b(${p})[jJ]\\b`}]},m={className:"comment",begin:n.lookahead(/# type:/),end:/$/,keywords:l,contains:[{begin:/# type:/},{begin:/#/,end:/\b\B/,endsWithParent:!0}]},f={className:"params",variants:[{className:"",begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:l,contains:["self",b,g,d,e.HASH_COMMENT_MODE]}]};return o.contains=[d,g,b],{name:"Python",aliases:["py","gyp","ipython"],unicodeRegex:!0,keywords:l,illegal:/(<\/|->|\?)|=>/,contains:[b,g,{begin:/\bself\b/},{beginKeywords:"if",relevance:0},d,m,e.HASH_COMMENT_MODE,{match:[/def/,/\s+/,a],scope:{1:"keyword",3:"title.function"},contains:[f]},{variants:[{match:[/class/,/\s+/,a,/\s*/,/\(\s*/,a,/\s*\)/]},{match:[/class/,/\s+/,a]}],scope:{1:"keyword",3:"title.class",6:"title.class.inherited"}},{className:"meta",begin:/^[\t ]*@/,end:/(?=#)|$/,contains:[g,f,d]}]}}e.exports=n}}]);
-10
View File
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[623],{7905:function(e){function n(e){const n=e.regex,a="([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)",i={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor __FILE__",built_in:"proc lambda",literal:"true false nil"},s={className:"doctag",begin:"@[A-Za-z]+"},c={begin:"#<",end:">"},b=[e.COMMENT("#","$",{contains:[s]}),e.COMMENT("^=begin","^=end",{contains:[s],relevance:10}),e.COMMENT("^__END__","\\n$")],r={className:"subst",begin:/#\{/,end:/\}/,keywords:i},d={className:"string",contains:[e.BACKSLASH_ESCAPE,r],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{begin:/%[qQwWx]?\(/,end:/\)/},{begin:/%[qQwWx]?\[/,end:/\]/},{begin:/%[qQwWx]?\{/,end:/\}/},{begin:/%[qQwWx]?</,end:/>/},{begin:/%[qQwWx]?\//,end:/\//},{begin:/%[qQwWx]?%/,end:/%/},{begin:/%[qQwWx]?-/,end:/-/},{begin:/%[qQwWx]?\|/,end:/\|/},{begin:/\B\?(\\\d{1,3})/},{begin:/\B\?(\\x[A-Fa-f0-9]{1,2})/},{begin:/\B\?(\\u\{?[A-Fa-f0-9]{1,6}\}?)/},{begin:/\B\?(\\M-\\C-|\\M-\\c|\\c\\M-|\\M-|\\C-\\M-)[\x20-\x7e]/},{begin:/\B\?\\(c|C-)[\x20-\x7e]/},{begin:/\B\?\\?\S/},{begin:n.concat(/<<[-~]?'?/,n.lookahead(/(\w+)(?=\W)[^\n]*\n(?:[^\n]*\n)*?\s*\1\b/)),contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,contains:[e.BACKSLASH_ESCAPE,r]})]}]},t="[1-9](_?[0-9])*|0",l="[0-9](_?[0-9])*",o={className:"number",relevance:0,variants:[{begin:`\\b(${t})(\\.(${l}))?([eE][+-]?(${l})|r)?i?\\b`},{begin:"\\b0[dD][0-9](_?[0-9])*r?i?\\b"},{begin:"\\b0[bB][0-1](_?[0-1])*r?i?\\b"},{begin:"\\b0[oO][0-7](_?[0-7])*r?i?\\b"},{begin:"\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"},{begin:"\\b0(_?[0-7])+r?i?\\b"}]},g={className:"params",begin:"\\(",end:"\\)",endsParent:!0,keywords:i},_=[d,{className:"class",beginKeywords:"class module",end:"$|;",illegal:/=/,contains:[e.inherit(e.TITLE_MODE,{begin:"[A-Za-z_]\\w*(::\\w+)*(\\?|!)?"}),{begin:"<\\s*",contains:[{begin:"("+e.IDENT_RE+"::)?"+e.IDENT_RE,relevance:0}]}].concat(b)},{className:"function",begin:n.concat(/def\s+/,n.lookahead(a+"\\s*(\\(|;|$)")),relevance:0,keywords:"def",end:"$|;",contains:[e.inherit(e.TITLE_MODE,{begin:a}),g].concat(b)},{begin:e.IDENT_RE+"::"},{className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"(!|\\?)?:",relevance:0},{className:"symbol",begin:":(?!\\s)",contains:[d,{begin:a}],relevance:0},o,{className:"variable",begin:"(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])(?![A-Za-z])(?![@$?'])"},{className:"params",begin:/\|/,end:/\|/,relevance:0,keywords:i},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*",keywords:"unless",contains:[{className:"regexp",contains:[e.BACKSLASH_ESCAPE,r],illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:/%r\{/,end:/\}[a-z]*/},{begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}].concat(c,b),relevance:0}].concat(c,b);r.contains=_,g.contains=_;const E="[>?]>",w="[\\w#]+\\(\\w+\\):\\d+:\\d+>",u="(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>",N=[{begin:/^\s*=>/,starts:{end:"$",contains:_}},{className:"meta",begin:"^("+E+"|"+w+"|"+u+")(?=[ ])",starts:{end:"$",contains:_}}];return b.unshift(c),{name:"Ruby",aliases:["rb","gemspec","podspec","thor","irb"],keywords:i,illegal:/\/\*/,contains:[e.SHEBANG({binary:"ruby"})].concat(N).concat(b).concat(_)}}e.exports=n}}]);
File diff suppressed because one or more lines are too long
-10
View File
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[176],{7874:function(s){function e(s){return{name:"Shell Session",aliases:["console","shellsession"],contains:[{className:"meta",begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/,subLanguage:"bash"}}]}}s.exports=e}}]);
File diff suppressed because one or more lines are too long
-10
View File
@@ -1,10 +0,0 @@
/*!
* This source file is part of the Swift.org open source project
*
* Copyright (c) 2021 Apple Inc. and the Swift project authors
* Licensed under Apache License v2.0 with Runtime Library Exception
*
* See https://swift.org/LICENSE.txt for license information
* See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
(self["webpackChunkswift_docc_render"]=self["webpackChunkswift_docc_render"]||[]).push([[490],{4610:function(e){function n(e){const n=e.regex,a=n.concat(/[A-Z_]/,n.optional(/[A-Z0-9_.-]*:/),/[A-Z0-9_.-]*/),s=/[A-Za-z0-9._:-]+/,t={className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},c={begin:/\s/,contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},i=e.inherit(c,{begin:/\(/,end:/\)/}),l=e.inherit(e.APOS_STRING_MODE,{className:"string"}),r=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),g={endsWithParent:!0,illegal:/</,relevance:0,contains:[{className:"attr",begin:s,relevance:0},{begin:/=\s*/,relevance:0,contains:[{className:"string",endsParent:!0,variants:[{begin:/"/,end:/"/,contains:[t]},{begin:/'/,end:/'/,contains:[t]},{begin:/[^\s"'=<>`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin:/<![a-z]/,end:/>/,relevance:10,contains:[c,r,l,i,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin:/<![a-z]/,end:/>/,contains:[c,i,r,l]}]}]},e.COMMENT(/<!--/,/-->/,{relevance:10}),{begin:/<!\[CDATA\[/,end:/\]\]>/,relevance:10},t,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:/<style(?=\s|>)/,end:/>/,keywords:{name:"style"},contains:[g],starts:{end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:/<script(?=\s|>)/,end:/>/,keywords:{name:"script"},contains:[g],starts:{end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:/<>|<\/>/},{className:"tag",begin:n.concat(/</,n.lookahead(n.concat(a,n.either(/\/>/,/>/,/\s/)))),end:/\/?>/,contains:[{className:"name",begin:a,relevance:0,starts:g}]},{className:"tag",begin:n.concat(/<\//,n.lookahead(n.concat(a,/>/))),contains:[{className:"name",begin:a,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}}e.exports=n}}]);
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
{"schemaVersion":{"major":0,"patch":0,"minor":1},"bundleDisplayName":"TUIKit","bundleID":"com.anthropic.tuikit.documentation"}
-52
View File
@@ -1,52 +0,0 @@
site_name: TUIKit Documentation
site_description: A declarative, SwiftUI-like framework for building Terminal User Interfaces in Swift
site_url: https://docs-tuikit.layered.work/
theme:
name: material
language: en
palette:
- media: "(prefers-color-scheme: light)"
scheme: default
primary: emerald
accent: indigo
toggle:
icon: material/lightbulb-outline
name: Switch to dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: green
accent: indigo
toggle:
icon: material/lightbulb
name: Switch to light mode
features:
- navigation.instant
- navigation.tracking
- navigation.tabs
- navigation.top
- search.suggest
- search.highlight
- content.code.copy
- toc.follow
plugins:
- search
nav:
- Home: index.md
- Getting Started: getting-started.md
- API Reference:
- TUIKit: api/tuikit.md
- Contributing: contributing.md
markdown_extensions:
- pymdownx.highlight:
use_pygments: true
- pymdownx.superfences
- pymdownx.snippets
- pymdownx.tabbed:
alternate_style: true
- admonition
- attr_list
- md_in_html