-
-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Easily access DOM from Views #231
Comments
What about a React-style API where you have an struct ContentView: View {
@Ref var button: JSObjectRef!
var body: some View {
Button("Hello, world!") {
self.button.textContent.string! = "Clicked!"
}.ref($button)
}
} |
That is good for accessing elements inside Tokamak, but you may also want to access outside elements too. Maybe |
If have something like struct ContentView: View {
var body: some View {
Button("Click me!") { ... }
.domId("myButton")
.onAppear { document.querySelector!("#myButton").type = "submit" }
}
} And then, would we want to have specialized struct ContentView: View {
var body: some View {
Button("Click me!") { ... }
.domAttributes(["id": "myButton"])
.onAppear { document.querySelector!("#myButton").type = "submit" }
}
} |
I'd say the So maybe we'd have:
|
If we had some sort of typed DOM access, it could be implemented with It would probably be good to have different handling of attributes (changed with For clarity and to avoid any possibility of conflict, how about tagging DOM-only APIs by prefixing them with |
Something like |
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.
This is just an empty API at the moment. I hope it can be implemented purely in the `deferredBody` of `GeometryReader` with [the ResizeObserver API](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) without requiring any tweaks in the `Renderer` protocol or the reconciler. Seems like I need the `domRef` modifier that writes `JSObjectRef` to a given binding working first, as discussed in #231.
Is there any current workaround for the second point except using |
Can you elaborate please? What's your use case? |
I just want to create a |
I think the safest way is to use This reasoning is similar to what SwiftUI does on Apple platforms: you can access underlying |
While true, considering the non-Apple renderers have non-standardized appearance, it seems reasonable that there would be a simple system in place to apply view modifications per system/OS, such as: func platform() -> Platform {
#if os(WASM)
return .wasm
#endif
#if os(macOS)
return .mac
#endif
// ...
}
public extension View {
func customPlatform(_ map: [Platform: (Self) -> AnyView]) -> some View {
let test = map[platform()]?(self)
return test ?? AnyView(self)
}
} This allows inline custom styling or even custom components to be rendered without having to clutter user code with preprocessor directives, and allows for providing var body: some View {
Button("Button")
.customPlatform([.mac: { view in
view.padding()
},
.wasm: { view in
view.domAttributes(["id": "foo"])
}])
} |
The following additions can be made to TokamakDOM:
@Ref
property wrapper for accessing DOM nodes inside TokamakdomAttributes
modifier for setting arbitrary values on DOM nodesThe text was updated successfully, but these errors were encountered: