In my sample SwiftUI design system, we are implementing a struct that conforms to the ButtonStyle protocol (screenshot 1):
The protocol method makeBody(configuration: Configuration) is the key here. Configuration contains the labelproperty, of type ButtonStyleConfiguration.Label. This is the label you initialise inside the basic SwiftUI button:
Button(label: <#T##() -> Label#>, action: <#T##() -> Void#>)
Our implementation of makeBody returns a view that wraps the original label, allowing us to apply styling to the view with colour, sizing, background, opacity, shadows, gradients, animation, or anything else we choose.
This ButtonLabelContent is a shared generic view (we also use it in the other design system!) that configures the arrangement of the button label view alongside any icon we may want to include. (screenshot 2)
ButtonColor, ButtonSize, and ButtonIcon are some simple enums, also shared between the twin design systems. They use a neat switching approach over each property, while including the ability to configure custom sizes, colours, or icons using enum associated values. (screenshot 3)
Read “The SwiftUI Design System War: Composition vs Progressive Disclosure” 🎨
blog.jacobstechtavern.com/p/…