Go to file
Max Desiatov 0e910756c0
Allow refactor PR labels in label.yml
2020-06-30 16:01:14 +01:00
.github Allow refactor PR labels in label.yml 2020-06-30 16:01:14 +01:00
.vscode Add basic DOM renderer 2020-06-17 00:58:10 +01:00
Sources Add Spacer support (#122) 2020-06-30 09:31:25 -04:00
Tests Rename Tokamak module to TokamakCore 2020-06-23 11:47:54 +01:00
docs Add Spacer support (#122) 2020-06-30 09:31:25 -04:00
.editorconfig Link statically in example Podfile, add .editorconfig 2019-01-02 09:07:05 +00:00
.gitignore Add TextField, SecureField, and a progress document (#116) 2020-06-29 17:52:22 +01:00
.pre-commit-config.yaml Add Binding property wrapper, remove unused code (#106) 2020-04-07 15:26:42 +01:00
.swift-version Implement DOMRenderer updates, Counter now works 2020-06-18 00:03:19 +01:00
.swiftformat Update .swiftformat and project formatting 2020-05-04 18:06:55 +01:00
.swiftlint.yml Update .swiftlint.yml 2020-06-28 22:51:59 +01:00
Brewfile Add Binding property wrapper, remove unused code (#106) 2020-04-07 15:26:42 +01:00
CHANGELOG.md Add version 0.2.0 to CHANGELOG.md 2020-06-18 12:29:50 +01:00
CODE_OF_CONDUCT.md Update links and emails for tokamak.dev domain 2019-03-12 11:44:35 +00:00
Dangerfile.swift Re-enable linting with Danger (#124) 2020-06-30 13:39:56 +01:00
LICENSE Change LICENSE to Apache 2.0 2018-12-01 20:47:31 +00:00
Package.resolved Use the latest JavaScriptKit dependency to fix RC 2020-06-21 22:32:50 +01:00
Package.swift Remove TokamakTestRenderer product (for now) 2020-06-23 12:07:00 +01:00
README.md Link to the progress doc from README.md 2020-06-29 18:00:17 +01:00
codecov.sh Migrate CI to GitHub Actions, test on Linux 2020-06-10 18:26:43 +01:00
codecov.yml Add xcodebuild exit status to travis (#93) 2019-05-14 15:00:26 +03:00
test.sh Migrate CI to GitHub Actions, test on Linux 2020-06-10 18:26:43 +01:00

README.md

Tokamak

SwiftUI-compatible framework for building browser apps with WebAssembly

CI status

At the moment Tokamak implements a very basic subset of SwiftUI. Its DOM renderer supports a few view types and modifiers (you can check the current list in the progress document), and a new HTML view for constructing arbitrary HTML. The long-term goal of Tokamak is to implement as much of SwiftUI API as possible and to provide a few more helpful additions that simplify HTML and CSS interactions.

If there's some SwiftUI API that's missing but you'd like to use it, please review the existing issues and PRs to get more details about the current status, or create a new issue to let us prioritize the development based on the demand. We also try to make the development of views and modifiers easier (with the help from the HTML view, see the example below), so pull requests are very welcome! Don't forget to check the "Contributing" section first.

Getting started

Tokamak relies on carton as a primary build tool. Please follow installation instructions for carton first.

After carton is successfully installed, type carton dev --product TokamakDemo in the root directory of the cloned Tokamak repository. This will build the demo project and its dependencies and launch a development HTTP server. You can then open http://127.0.0.1:8080/ in your browser to interact with the demo.

Example code

Tokamak API attempts to resemble SwiftUI API as much as possible. The main difference is that you add import TokamakDOM instead of import SwiftUI in your files:

import TokamakDOM

struct Counter: View {
  @State var count: Int
  let limit: Int

  var body: some View {
    count < limit ?
      AnyView(
        VStack {
          Button("Increment") { count += 1 }
          Text("\(count)")
        }
      ) : AnyView(
        VStack { Text("Limit exceeded") } }
      )
  }
}

You can then render your view in any DOM node captured with JavaScriptKit, just pass it as an argument to the DOMRenderer initializer together with your view:

import JavaScriptKit
import TokamakDOM

let document = JSObjectRef.global.document.object!

let divElement = document.createElement!("div").object!
let renderer = DOMRenderer(Counter(count: 5, limit: 15), divElement)

let body = document.body.object!
_ = body.appendChild!(divElement)

Arbitrary HTML

With the HTML view you can also render any HTML you want, including inline SVG:

struct SVGCircle: View {
  var body: some View {
    HTML("svg", ["width": "100", "height": "100"]) {
      HTML("circle", [
        "cx": "50", "cy": "50", "r": "40",
        "stroke": "green", "stroke-width": "4", "fill": "yellow",
      ])
    }
  }
}

Arbitrary styles and scripts

While JavaScriptKit is a great option for occasional interactions with JavaScript, sometimes you need to inject arbitrary scripts or styles, which can be done through direct DOM access:

_ = document.head.object!.insertAdjacentHTML!("beforeend", #"""
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
"""#)
_ = document.head.object!.insertAdjacentHTML!("beforeend", #"""
<link
  rel="stylesheet"
  href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css">
"""#)

This way both Semantic UI styles and moment.js localized date formatting (or any arbitrary style/script/font added that way) are available in your app.

Acknowledgments

Contributing

Sponsorship

If this library saved you any amount of time or money, please consider sponsoring the work of its maintainer. While some of the sponsorship tiers give you priority support or even consulting time, any amount is appreciated and helps in maintaining the project.

Coding Style

This project uses SwiftFormat and SwiftLint to enforce formatting and coding style. We encourage you to run SwiftFormat within a local clone of the repository in whatever way works best for you either manually or automatically via an Xcode extension, build phase or git pre-commit hook etc.

To guarantee that these tools run before you commit your changes on macOS, you're encouraged to run this once to set up the pre-commit hook:

brew bundle # installs SwiftLint, SwiftFormat and pre-commit
pre-commit install # installs pre-commit hook to run checks before you commit

Refer to the pre-commit documentation page for more details and installation instructions for other platforms.

SwiftFormat and SwiftLint also run on CI for every PR and thus a CI build can fail with inconsistent formatting or style. We require CI builds to pass for all PRs before merging.

Code of Conduct

This project adheres to the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to conduct@tokamak.dev.

Maintainers

Max Desiatov, Carson Katri.

License

Tokamak is available under the Apache 2.0 license. See the LICENSE file for more info.