Skip to content

Instantly share code, notes, and snippets.

@vi4m
Created October 29, 2020 14:59
Show Gist options
  • Save vi4m/300dffe461811aa96dae210929ddb5e5 to your computer and use it in GitHub Desktop.
Save vi4m/300dffe461811aa96dae210929ddb5e5 to your computer and use it in GitHub Desktop.
import TokamakShim
import JavaScriptKit
public let window = JSObject.global.window.object!
public let location = JSObject.global.location.object!
struct TokamakApp: App {
var body: some Scene {
WindowGroup("Tokamak App") {
ContentView()
}
}
}
struct Menu: View {
var body: some View {
VStack() {
Button("Add") {
navigate(to: "Add")
}.padding()
Button("List") {
navigate(to: "List")
}.padding()
}
}
}
struct Table: View {
public var body: some View {
VStack {
ForEach((1...10).reversed(), id: \.self) {
Text("\($0)…")
}
}.background(Color.yellow)
}
}
struct Add: View {
public var body: some View {
VStack {
Text("Add")
}.background(Color.red)
}
}
func navigate(to: String) {
location.hash = JSValue(stringLiteral: to)
}
public final class HashState: ObservableObject {
var onHashChange: JSClosure!
@Published var currentHash = location.hash.string!
init() {
let onHashChange = JSClosure { [weak self] _ in
self?.currentHash = location.hash.string!
}
window.onhashchange = .function(onHashChange)
self.onHashChange = onHashChange
}
deinit {
window.onhashchange = .undefined
onHashChange.release()
}
}
struct ContentView: View {
@StateObject private var hashState = HashState()
var body: some View {
HStack {
Menu()
Text("begin")
switch(hashState.currentHash) {
case "#List": Table()
case "#Add": Add()
default: Text("default")
}
Text("end")
}
}
}
// @main attribute is not supported in SwiftPM apps.
// See https://bugs.swift.org/browse/SR-12683 for more details.
TokamakApp.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment