Tokamak icon indicating copy to clipboard operation
Tokamak copied to clipboard

Add style support

Open j-f1 opened this issue 4 years ago • 4 comments

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.

j-f1 avatar Jun 29 '20 22:06 j-f1

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.

carson-katri avatar Jun 29 '20 22:06 carson-katri

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.

MaxDesiatov avatar Jun 29 '20 22:06 MaxDesiatov

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.

carson-katri avatar Jun 29 '20 23:06 carson-katri

@j-f1 shouldn't it stay open until the rest of the styles are implemented?

MaxDesiatov avatar Jul 01 '20 18:07 MaxDesiatov