Commit Graph

32 Commits

Author SHA1 Message Date
Max Desiatov 637fdec44c
Convert Environment/Object/Values to classes 2021-02-13 20:42:27 +00:00
Max Desiatov 192c43b140
Refactor environment injection, add a test (#371)
* Add a test for environment injection

We had some issues in this code area previously and I'm thinking of refactoring it in attempt to fix #367. Would be great to increase the test coverage here before further refactoring.

* Update copyright years in `MountedElement.swift`

* Update copyright years in the rest of the files
2021-01-25 11:39:09 +00:00
Carson Katri 9d347f49f3
Add Preferences (#307)
This adds the `PreferenceKey` protocol and related modifiers.

* Initial PreferenceKey implementation

* Don't send default value to match SwiftUI behavior

* Add CustomDebugStringConvertible conformance to Color

* PR fixes

* Fix onAppear and preference modification calls

* Attempt macOS build fix

* Fix <background/overlay>PreferenceValue

* Implement/revise transformPreference

* Fix linter warnings, apply SwiftFormat

Co-authored-by: Max Desiatov <max@desiatov.com>
2020-12-04 11:19:14 +00:00
Max Desiatov 05465be93d
Use `JSScheduler` from `OpenCombineJS` package (#304)
Now that OpenCombineJS had its first release, we can rely on its `JSScheduler` implementation.
2020-11-26 09:01:54 +00:00
Max Desiatov 3451d9ea12
Pass sibling to `Renderer.mount`, fix update order (#301)
Resolves, but adds no tests cases to the test suite for #294. See the issue for the detailed description of the problem.

I will add end-to-end tests for this in future PRs.

I've tested these cases manually so far:

```swift
struct Choice: View {
  @State private var choice = false

  var body: some View {
    HStack {
      Button("Trigger") {
        choice.toggle()
      }
      if choice {
        Group {
          Text("true")
          Text("true")
        }
      } else {
        VStack {
          Text("false")
        }
      }
      Text("end")
    }
  }
}
```

Note the `Group` view with multiple children in this one, it uncovered required checks for `GroupView` conformance.

Also tested these more simple cases:

```swift
struct Choice: View {
  @State private var choice = false

  var body: some View {
    HStack {
      Button("Trigger") {
        choice.toggle()
      }
      if choice {
        Group {
          // single child
          Text("true")
        }
      } else {
        VStack {
          Text("false")
        }
      }
      Text("end")
    }
  }
}
```

and

```swift
struct Choice: View {
  @State private var choice = false

  var body: some View {
    HStack {
      Button("Trigger") {
        choice.toggle()
      }
      if choice {
        // single child, no nesting
        Text("true")
      } else {
        VStack {
          Text("false")
        }
      }
      Text("end")
    }
  }
}
```
2020-11-11 19:34:45 +00:00
Max Desiatov ee0006a6a3
Fix compatibility with JavaScriptKit 0.7 (#281)
This PR requires `carton` 0.6.0 that you can install from Homebrew as usual.

To cleanly manage scheduler closures, new `JSScheduler` class is introduced that conforms to OpenCombine's `Scheduler` protocol. I think it will be moved to OpenCombineJS in the future.

* Fix compatibility with JavaScriptKit 0.7

* Formatting update

* Specify `carton` 0.6.0 as a requirement

* Optimize immediate schedule function

* Update formatting
2020-09-30 10:17:19 +01:00
Max Desiatov b93be40a19
Add `_targetRef` and `_domRef` modifiers (#240)
Resolves partially #231. `_targetRef` is a modifier that can be used by any renderer, while `_domRef` is an adaptation of that for `DOMRenderer`. Both are underscored as they are not available in SwiftUI, and also their stability is currently not so well known to us, we may consider changing this API in the future.

Example use:

```swift
struct DOMRefDemo: View {
  @State var button: JSObjectRef?

  var body: some View {
    Button("Click me") {
      button?.innerHTML = "This text was set directly through a DOM reference"
    }._domRef($button)
  }
}
```

I've also fixed all known line length warnings in this PR.
2020-08-02 22:01:38 +01:00
Max Desiatov c7b5e75e1a
Add `ColorScheme` environment (#136)
You can see the dark scheme environment text representation updated in `EnvironmentDemo`. I suggest adding default dark mode styles in a separate PR, I've created #237 as a reminder for that.
2020-08-02 18:55:35 +01:00
Carson Katri 4c654da456
Add Static HTML Renderer and Documentation (#204) 2020-08-01 16:27:12 -04:00
Max Desiatov fbb893739b
Fix tests, move DefaultButtonStyle to TokamakCore (#234)
Merging #214 broke the tests. Also, `DefaultButtonStyle` seems to be trivial enough to be shared through `TokamakCore` between all renderers.
2020-08-01 20:07:10 +01:00
Max Desiatov 40804d4542
Remove `DefaultApp`, make `DOMRenderer` internal (#227)
Removes the `View`-based initializer of `DOMRenderer` which no longer leaves any `public` initializers on it, means we can make it fully internal. `DOMNode` is now internal too, which is great as it was an implementation detail anyway. Corollary, `DefaultApp` is no longer needed.

`Target` was cleaned up is it doesn't need to hold `App` or `Scene` values, now it's just a simple protocol.

I've updated `README.md` to show usage of the `App` protocol in the basic example.

Closes #224.
2020-08-01 18:46:59 +01:00
Max Desiatov e37d13017c
Add basic `ButtonStyle` implementation (#214)
This based off the `buttonstyles` branch by @Outcue.

Initially it didn't work because mounted host views didn't propagate their environment on updates. This is now fixed by adding `updateEnvironment` function on `MountedElement` base class and calling it in the initializer. Manual environment updates are no longer needed in `makeMounted...` factory functions. `makeMountedApp` is no longer needed at all and `MountedApp` initializer can be used directly then.
2020-08-01 18:46:34 +01:00
Max Desiatov 7c6b1812ae
Add `DefaultApp` type to simplify `DOMRenderer.init` (#217)
This means that the `View` initializer of `DOMRenderer` now can delegate to the `App` initializer by creating a wrapping `DefaultApp`. It would simplify https://github.com/swiftwasm/Tokamak/pull/136 for me, where I no longer need to implement color scheme observation for these two different codepaths separately.
2020-07-29 09:26:08 +01:00
Max Desiatov f5af009db2
Unify code of `MountedApp`/`MountedCompositeView` (#219)
We currently have the reconciler code duplicated in these types. I also have a draft `MountedScene` implementation, which most probably would rely on the same reconcilliation algorithm. In this PR it's made generic and can be shared across these types of mounted elements.
2020-07-28 18:01:29 +01:00
Max Desiatov 66248448ab
Generalize style and environment in `DOMRenderer` (#215)
Moves `DOMNode` to a separate file and reduces style and environment duplication in overloaded `DOMRenderer` initializers.
2020-07-27 09:36:08 +01:00
Carson Katri 2b93f37d64
Add SwiftUI App Lifecycle (#195) 2020-07-22 16:57:33 -04:00
Jed Fox f0e2b054dc
Add Toggle implementation (#159)
* Fix Button.body

* Add support for renderers customizing default environment values

* Add ParentView conformances

* Add Toggle

* long lines

* Update Path.swift

* Update Path.swift

* Update Sources/TokamakDOM/DOMRenderer.swift

Co-authored-by: Max Desiatov <max@desiatov.com>

* bodyBuild → bodyClosure

* Update progress.md

* Update progress.md, implement Toggle(_ configuration: ToggleStyleConfiguration)

* Fix demo on native

* Hopefully fix issue

* Hopefully fix issue for real

* maybe this will work

* Update ToggleDemo.swift

* AnyToggleStyle → _AnyToggleStyle

* Fix remaining AnyToggleStyle

* Clean up unnecessary files

* Move typealias to Core.swift

* Revert change to ListDemo, remove unused let

Co-authored-by: Max Desiatov <max@desiatov.com>
2020-07-20 18:21:32 -04:00
Carson Katri 1f2203d652
Allow modified views to fill their parent if a child requires it (#165)
* Allow modified views to fill their parent if a child requires it

* Rename orderDependent to isOrderDependent
2020-07-07 10:25:46 -04:00
Carson Katri 98a107f7fe
Add ScrollView (#128)
* Add ScrollView
* Root styles for ScrollView and Stack
2020-06-30 12:29:06 -04:00
Carson Katri e40a701752
Add Spacer support (#122)
1. If a Stack has a Spacer as a child, we need to fill the width or height of the parent so the Spacer's flex-grow: 1; works.
2. If a Stack has a child Stack along the cross axis (HStack with a nested VStack and vice vera) we need to fill the cross axis
3. If a Stack has a child Stack along the same axis (HStack with a nested HStack) we need to fill the axis.
2020-06-30 09:31:25 -04:00
Max Desiatov 9bed8e0cb8
Update DOM node properties and listeners on renderer update (#117)
* Update DOM properties and listeners on renderer update

* Fix listeners not passed in EmptyView init
2020-06-29 00:09:28 +01:00
Max Desiatov 735251fb13
Rename Tokamak module to TokamakCore 2020-06-23 11:47:54 +01:00
Max Desiatov 83730ca55a
Revert "Add separate TokamakHTML module"
This reverts commit 498f033a43.
2020-06-23 11:31:27 +01:00
Max Desiatov 498f033a43
Add separate TokamakHTML module 2020-06-22 23:01:11 +01:00
Max Desiatov 57fd08ab4e
Update JavaScriptKit, refine example Counter code 2020-06-20 00:59:03 +01:00
Max Desiatov 72c64601f4
Fix children not unmounted in DOMRenderer 2020-06-19 21:58:15 +01:00
Max Desiatov 3accd32b5b
Fix early deallocation of root ref, refine Counter 2020-06-19 01:34:54 +01:00
Max Desiatov 61baa5e1d4
Add license headers, add example code to README.md 2020-06-18 14:50:54 +01:00
Max Desiatov 0aa1fb5d15
Implement DOMRenderer updates, Counter now works 2020-06-18 00:03:19 +01:00
Max Desiatov 76de3eab74
Implement simple DOM updates 2020-06-17 21:50:22 +01:00
Max Desiatov 426bb999c5
Add basic DOM renderer 2020-06-17 00:58:10 +01:00
Max Desiatov ca0c96fffb
Remove references to components and nodes 2020-04-11 23:31:05 +01:00