Tokamak
Tokamak copied to clipboard
Add style support
Many views support some kind of .fooStyle()
method that takes one of a variety of XFooStyle()
objects. I took a quick look and it seems like this kind of thing has not been implemented for any of the views. Ideally having one implementation of this would provide a base from which to implement similar methods for other views.
Here's what the interface looks like for ButtonStyle
:
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public protocol ButtonStyle {
associatedtype Body : SwiftUI.View
func makeBody(configuration: Self.Configuration) -> Self.Body
typealias Configuration = SwiftUI.ButtonStyleConfiguration
}
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public struct ButtonStyleConfiguration {
public struct Label : SwiftUI.View {
public typealias Body = Swift.Never
}
public let label: SwiftUI.ButtonStyleConfiguration.Label
public let isPressed: Swift.Bool
}
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
extension View {
public func buttonStyle<S>(_ style: S) -> some SwiftUI.View where S : SwiftUI.ButtonStyle
}
Seems very similar to a ViewModifier
.
I've also been thinking about CSS-specific styles that one might want to add to further customize generated styles, somewhat similar in principle to the HTML
view that allows injecting arbitrary HTML. I'm still not sure if there should be a modifier that allows adding arbitrary HTML attributes to a rendered HTML node, or specialized modifiers like cssStyle()
for specifying styles and cssClassName()
for specifying a class name.
I also had in mind something like protocol CustomCSSAttributes
which would allow any user to conform their views (or existing views provided by Tokamak) to this protocol, providing their custom global attributes. The use case for this are popular styling libraries (and obviously proprietary design systems that people may use) that have existing CSS code. For example, Semantic UI requires buttons to have ui button
classes on them:
<button class="ui button">
Button
</button>
Tokamak could allow achieving that for all buttons globally like this:
extension Button: CustomCSSAttributes {
var customAttributes: [String: String] { ["class": "ui button"] }
}
The protocol approach and the modifiers approach would not be mutually exclusive, the reasoning is that modifiers would apply tweaks only locally, while protocol conformance would be visible globally. There's some bikeshedding needed here, but overall what are your thoughts?
Don't know if creating a separate issue for this proposal would be more suitable.
I think a separate issue would be good, since this is particularly about SwiftUI compatibility, whereas that is DOM renderer specific.
Also, I don't think implementing ButtonStyle, TextFieldStyle, etc. would be very useful without Shape
being implemented first, as there would be almost no way to customize the style.
@j-f1 shouldn't it stay open until the rest of the styles are implemented?